Files
qwen-code/packages/cli/src/ui/commands/initCommand.ts

135 lines
5.4 KiB
TypeScript

/**
* @license
* Copyright 2025 Qwen
* SPDX-License-Identifier: Apache-2.0
*/
import * as fs from 'node:fs';
import * as path from 'node:path';
import type {
CommandContext,
SlashCommand,
SlashCommandActionReturn,
} from './types.js';
import { getCurrentGeminiMdFilename } from '@qwen-code/qwen-code-core';
import { CommandKind } from './types.js';
import { Text } from 'ink';
import React from 'react';
import { t } from '../../i18n/index.js';
export const initCommand: SlashCommand = {
name: 'init',
get description() {
return t('Analyzes the project and creates a tailored QWEN.md file.');
},
kind: CommandKind.BUILT_IN,
action: async (
context: CommandContext,
_args: string,
): Promise<SlashCommandActionReturn> => {
if (!context.services.config) {
return {
type: 'message',
messageType: 'error',
content: t('Configuration not available.'),
};
}
const targetDir = context.services.config.getTargetDir();
const contextFileName = getCurrentGeminiMdFilename();
const contextFilePath = path.join(targetDir, contextFileName);
try {
if (fs.existsSync(contextFilePath)) {
// If file exists but is empty (or whitespace), continue to initialize
try {
const existing = fs.readFileSync(contextFilePath, 'utf8');
if (existing && existing.trim().length > 0) {
// File exists and has content - ask for confirmation to overwrite
if (!context.overwriteConfirmed) {
return {
type: 'confirm_action',
// TODO: Move to .tsx file to use JSX syntax instead of React.createElement
// For now, using React.createElement to maintain .ts compatibility for PR review
prompt: React.createElement(
Text,
null,
`A ${contextFileName} file already exists in this directory. Do you want to regenerate it?`,
),
originalInvocation: {
raw: context.invocation?.raw || '/init',
},
};
}
// User confirmed overwrite, continue with regeneration
}
} catch {
// If we fail to read, conservatively proceed to (re)create the file
}
}
// Ensure an empty context file exists before prompting the model to populate it
try {
fs.writeFileSync(contextFilePath, '', 'utf8');
context.ui.addItem(
{
type: 'info',
text: `Empty ${contextFileName} created. Now analyzing the project to populate it.`,
},
Date.now(),
);
} catch (err) {
return {
type: 'message',
messageType: 'error',
content: `Failed to create ${contextFileName}: ${err instanceof Error ? err.message : String(err)}`,
};
}
} catch (error) {
return {
type: 'message',
messageType: 'error',
content: `Unexpected error preparing ${contextFileName}: ${error instanceof Error ? error.message : String(error)}`,
};
}
return {
type: 'submit_prompt',
content: `
You are Qwen Code, an interactive CLI agent. Analyze the current directory and generate a comprehensive ${contextFileName} file to be used as instructional context for future interactions.
**Analysis Process:**
1. **Initial Exploration:**
* Start by listing the files and directories to get a high-level overview of the structure.
* Read the README file (e.g., \`README.md\`, \`README.txt\`) if it exists. This is often the best place to start.
2. **Iterative Deep Dive (up to 10 files):**
* Based on your initial findings, select a few files that seem most important (e.g., configuration files, main source files, documentation).
* Read them. As you learn more, refine your understanding and decide which files to read next. You don't need to decide all 10 files at once. Let your discoveries guide your exploration.
3. **Identify Project Type:**
* **Code Project:** Look for clues like \`package.json\`, \`requirements.txt\`, \`pom.xml\`, \`go.mod\`, \`Cargo.toml\`, \`build.gradle\`, or a \`src\` directory. If you find them, this is likely a software project.
* **Non-Code Project:** If you don't find code-related files, this might be a directory for documentation, research papers, notes, or something else.
**${contextFileName} Content Generation:**
**For a Code Project:**
* **Project Overview:** Write a clear and concise summary of the project's purpose, main technologies, and architecture.
* **Building and Running:** Document the key commands for building, running, and testing the project. Infer these from the files you've read (e.g., \`scripts\` in \`package.json\`, \`Makefile\`, etc.). If you can't find explicit commands, provide a placeholder with a TODO.
* **Development Conventions:** Describe any coding styles, testing practices, or contribution guidelines you can infer from the codebase.
**For a Non-Code Project:**
* **Directory Overview:** Describe the purpose and contents of the directory. What is it for? What kind of information does it hold?
* **Key Files:** List the most important files and briefly explain what they contain.
* **Usage:** Explain how the contents of this directory are intended to be used.
**Final Output:**
Write the complete content to the \`${contextFileName}\` file. The output must be well-formatted Markdown.
`,
};
},
};