mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
feat: Add --to-file option to ccw cli for saving output to files
Adds support for saving CLI execution output directly to files with the following features: - Support for relative paths: --to-file output.txt - Support for nested directories: --to-file results/analysis/output.txt (auto-creates directories) - Support for absolute paths: --to-file /tmp/output.txt or --to-file D:/results/output.txt - Works in both streaming and non-streaming modes - Automatically creates parent directories if they don't exist - Proper error handling with user-friendly messages - Shows file save location in completion feedback Implementation details: - Updated CLI option parser in ccw/src/cli.ts - Added toFile parameter to CliExecOptions interface - Implemented file saving logic in execAction() for both streaming and non-streaming modes - Updated HTTP API endpoint /api/cli/execute to support toFile parameter - All changes are backward compatible Testing: - Tested with relative paths (single and nested directories) - Tested with absolute paths (Windows and Unix style) - Tested with streaming mode - All tests passed successfully
This commit is contained in:
@@ -605,7 +605,7 @@ export async function handleCliRoutes(ctx: RouteContext): Promise<boolean> {
|
||||
// API: Execute CLI Tool
|
||||
if (pathname === '/api/cli/execute' && req.method === 'POST') {
|
||||
handlePostRequest(req, res, async (body) => {
|
||||
const { tool, prompt, mode, format, model, dir, includeDirs, timeout, smartContext, parentExecutionId, category } = body as any;
|
||||
const { tool, prompt, mode, format, model, dir, includeDirs, timeout, smartContext, parentExecutionId, category, toFile } = body as any;
|
||||
|
||||
if (!tool || !prompt) {
|
||||
return { error: 'tool and prompt are required', status: 400 };
|
||||
@@ -696,6 +696,21 @@ export async function handleCliRoutes(ctx: RouteContext): Promise<boolean> {
|
||||
console.log(`[ActiveExec] Direct execution ${executionId} marked as ${activeExec.status}, retained for ${EXECUTION_RETENTION_MS / 1000}s`);
|
||||
}
|
||||
|
||||
// Save output to file if --to-file is specified
|
||||
if (toFile && result.stdout) {
|
||||
try {
|
||||
const { writeFileSync, mkdirSync } = await import('fs');
|
||||
const { dirname, resolve } = await import('path');
|
||||
const filePath = resolve(dir || initialPath, toFile);
|
||||
const dirPath = dirname(filePath);
|
||||
mkdirSync(dirPath, { recursive: true });
|
||||
writeFileSync(filePath, result.stdout, 'utf8');
|
||||
console.log(`[API] Output saved to: ${filePath}`);
|
||||
} catch (err) {
|
||||
console.warn(`[API] Failed to save output to file: ${(err as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Broadcast completion
|
||||
broadcastToClients({
|
||||
type: 'CLI_EXECUTION_COMPLETED',
|
||||
|
||||
Reference in New Issue
Block a user