From 7750ec99a8b6c6cc832f66f19b7ea29ca8b63c6c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 25 Mar 2025 15:21:43 -0400 Subject: [PATCH 1/2] feat: add support for combining file input and interactive prompts --- packages/cli/README.md | 3 +++ packages/cli/src/commands/$default.ts | 30 +++++++++++++++++++++------ packages/cli/src/options.ts | 5 +++-- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/cli/README.md b/packages/cli/README.md index 40217c8..2ade744 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -33,6 +33,9 @@ mycoder "Implement a React component that displays a list of items" # Run with a prompt from a file mycoder -f prompt.txt +# Combine file input with interactive prompts +mycoder -f prompt.txt -i + # Disable user prompts for fully automated sessions mycoder --userPrompt false "Generate a basic Express.js server" diff --git a/packages/cli/src/commands/$default.ts b/packages/cli/src/commands/$default.ts index 2b9cfe0..fba7626 100644 --- a/packages/cli/src/commands/$default.ts +++ b/packages/cli/src/commands/$default.ts @@ -246,18 +246,36 @@ export const command: CommandModule = { const config = await loadConfig(argvConfig); let prompt: string | undefined; + // Initialize prompt variable + let fileContent: string | undefined; + let interactiveContent: string | undefined; + // If promptFile is specified, read from file if (argv.file) { - prompt = await fs.readFile(argv.file, 'utf-8'); + fileContent = await fs.readFile(argv.file, 'utf-8'); } // If interactive mode if (argv.interactive) { - prompt = await userPrompt( - "Type your request below or 'help' for usage information. Use Ctrl+C to exit.", - ); - } else if (!prompt) { - // Use command line prompt if provided + // If we already have file content, let the user know + const promptMessage = fileContent + ? "File content loaded. Add additional instructions below or 'help' for usage information. Use Ctrl+C to exit." + : "Type your request below or 'help' for usage information. Use Ctrl+C to exit."; + + interactiveContent = await userPrompt(promptMessage); + } + + // Combine inputs or use individual ones + if (fileContent && interactiveContent) { + // Combine both inputs with a separator + prompt = `${fileContent}\n\n--- Additional instructions ---\n\n${interactiveContent}`; + console.log('Combined file content with interactive input.'); + } else if (fileContent) { + prompt = fileContent; + } else if (interactiveContent) { + prompt = interactiveContent; + } else if (argv.prompt) { + // Use command line prompt if provided and no other input method was used prompt = argv.prompt; } diff --git a/packages/cli/src/options.ts b/packages/cli/src/options.ts index e0627c4..11b1a8c 100644 --- a/packages/cli/src/options.ts +++ b/packages/cli/src/options.ts @@ -52,13 +52,14 @@ export const sharedOptions = { type: 'boolean', alias: 'i', description: - 'Run in interactive mode, asking for prompts and enabling corrections during execution (use Ctrl+M to send corrections)', + 'Run in interactive mode, asking for prompts and enabling corrections during execution (use Ctrl+M to send corrections). Can be combined with -f/--file to append interactive input to file content.', default: false, } as const, file: { type: 'string', alias: 'f', - description: 'Read prompt from a file', + description: + 'Read prompt from a file (can be combined with -i/--interactive)', } as const, tokenUsage: { type: 'boolean', From 3cae6a21c40c9951ca207d6d86b2b36ca2abbaeb Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 25 Mar 2025 15:30:00 -0400 Subject: [PATCH 2/2] chore: improve start-up sequence --- packages/cli/src/commands/$default.ts | 63 +++++++++++++++++---------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/packages/cli/src/commands/$default.ts b/packages/cli/src/commands/$default.ts index fba7626..5ecaadb 100644 --- a/packages/cli/src/commands/$default.ts +++ b/packages/cli/src/commands/$default.ts @@ -231,6 +231,12 @@ export async function executePrompt( ); } +type PromptSource = { + type: 'user' | 'file'; + source: string; + content: string; +}; + export const command: CommandModule = { command: '* [prompt]', describe: 'Execute a prompt or start interactive mode', @@ -244,39 +250,50 @@ export const command: CommandModule = { // Get configuration for model provider and name const argvConfig = getConfigFromArgv(argv); const config = await loadConfig(argvConfig); - let prompt: string | undefined; // Initialize prompt variable - let fileContent: string | undefined; - let interactiveContent: string | undefined; - + const prompts: PromptSource[] = []; + + // If prompt is specified, use it as inline prompt + if (argv.prompt) { + prompts.push({ + type: 'user', + source: 'command line', + content: argv.prompt, + }); + } // If promptFile is specified, read from file if (argv.file) { - fileContent = await fs.readFile(argv.file, 'utf-8'); + prompts.push({ + type: 'file', + source: argv.file, + content: await fs.readFile(argv.file, 'utf-8'), + }); } - // If interactive mode if (argv.interactive) { // If we already have file content, let the user know - const promptMessage = fileContent - ? "File content loaded. Add additional instructions below or 'help' for usage information. Use Ctrl+C to exit." - : "Type your request below or 'help' for usage information. Use Ctrl+C to exit."; - - interactiveContent = await userPrompt(promptMessage); + const promptMessage = + (prompts.length > 0 + ? 'Add additional instructions' + : 'Enter your request') + + " below or 'help' for usage information. Use Ctrl+C to exit."; + const interactiveContent = await userPrompt(promptMessage); + + prompts.push({ + type: 'user', + source: 'interactive', + content: interactiveContent, + }); } - // Combine inputs or use individual ones - if (fileContent && interactiveContent) { - // Combine both inputs with a separator - prompt = `${fileContent}\n\n--- Additional instructions ---\n\n${interactiveContent}`; - console.log('Combined file content with interactive input.'); - } else if (fileContent) { - prompt = fileContent; - } else if (interactiveContent) { - prompt = interactiveContent; - } else if (argv.prompt) { - // Use command line prompt if provided and no other input method was used - prompt = argv.prompt; + let prompt = ''; + for (const promptSource of prompts) { + if (promptSource.type === 'user') { + prompt += `--- ${promptSource.source} ---\n\n${promptSource.content}\n\n`; + } else if (promptSource.type === 'file') { + prompt += `--- contents of ${promptSource.source} ---\n\n${promptSource.content}\n\n`; + } } if (!prompt) {