feat: add quick install templates and index status to CLI hooks and home locales

feat: enhance MCP manager with interactive question feature and update locales

feat: implement tags and available models management in settings page

fix: improve process termination logic in stop command for React frontend

fix: update view command to default to 'js' frontend

feat: add Recommended MCP Wizard component for dynamic server configuration
This commit is contained in:
catlog22
2026-02-04 15:24:34 +08:00
parent 341331325c
commit 8454ae4f41
24 changed files with 1186 additions and 727 deletions

View File

@@ -35,10 +35,17 @@ async function findProcessOnPort(port: number): Promise<string | null> {
*/
async function killProcess(pid: string): Promise<boolean> {
try {
await execAsync(`taskkill /PID ${pid} /F`);
// Use PowerShell to avoid Git Bash path expansion issues with /PID
await execAsync(`powershell -Command "Stop-Process -Id ${pid} -Force -ErrorAction Stop"`);
return true;
} catch {
return false;
// Fallback to taskkill via cmd
try {
await execAsync(`cmd /c "taskkill /PID ${pid} /F"`);
return true;
} catch {
return false;
}
}
}
@@ -52,7 +59,7 @@ export async function stopCommand(options: StopOptions): Promise<void> {
const force = options.force || false;
console.log(chalk.blue.bold('\n CCW Dashboard\n'));
console.log(chalk.gray(` Checking server on port ${port}...`));
console.log(chalk.gray(` Checking server on port ${port} and ${reactPort}...`));
try {
// Try graceful shutdown via API first
@@ -139,11 +146,18 @@ export async function stopCommand(options: StopOptions): Promise<void> {
console.log(chalk.green(' Main server killed successfully!'));
// Also try to kill React frontend
console.log(chalk.gray(` Checking React frontend on port ${reactPort}...`));
const reactPid = await findProcessOnPort(reactPort);
if (reactPid) {
console.log(chalk.cyan(` Cleaning up React frontend on port ${reactPort}...`));
await killProcess(reactPid);
console.log(chalk.green(' React frontend stopped!'));
console.log(chalk.cyan(` Cleaning up React frontend (PID: ${reactPid})...`));
const reactKilled = await killProcess(reactPid);
if (reactKilled) {
console.log(chalk.green(' React frontend stopped!'));
} else {
console.log(chalk.yellow(' Failed to stop React frontend'));
}
} else {
console.log(chalk.gray(' No React frontend running'));
}
console.log(chalk.green.bold('\n All processes stopped successfully!\n'));
@@ -153,6 +167,12 @@ export async function stopCommand(options: StopOptions): Promise<void> {
process.exit(1);
}
} else {
// Also check React frontend port
const reactPid = await findProcessOnPort(reactPort);
if (reactPid) {
console.log(chalk.yellow(` React frontend running on port ${reactPort} (PID: ${reactPid})`));
}
console.log(chalk.gray(`\n This is not a CCW server. Use --force to kill it:`));
console.log(chalk.white(` ccw stop --force\n`));
process.exit(0);

View File

@@ -78,7 +78,7 @@ export async function viewCommand(options: ViewOptions): Promise<void> {
const host = options.host || '127.0.0.1';
const browserHost = host === '0.0.0.0' || host === '::' ? 'localhost' : host;
// --new flag is shorthand for --frontend react
const frontend = options.new ? 'react' : (options.frontend || 'both');
const frontend = options.new ? 'react' : (options.frontend || 'js');
// Resolve workspace path
let workspacePath = process.cwd();

View File

@@ -8,6 +8,8 @@ const CCW_MCP_TOOLS = [
{ name: 'edit_file', desc: 'Edit/replace content', core: true },
{ name: 'read_file', desc: 'Read file contents', core: true },
{ name: 'core_memory', desc: 'Core memory management', core: true },
// Optional tools
{ name: 'ask_question', desc: 'Interactive questions (A2UI)', core: false },
];
// Get currently enabled tools from installed config (Claude)