diff options
| author | Abhi <[email protected]> | 2025-07-27 02:00:26 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-27 06:00:26 +0000 |
| commit | 576cebc9282cfbe57d45321105d72cc61597ce9b (patch) | |
| tree | 374dd97245761fe5c40ee87a9b4d5674a26344cf /packages/cli/src/services/FileCommandLoader.ts | |
| parent | 9e61b3510c0cd7f333f40f68e87d981aff19aab1 (diff) | |
feat: Add Shell Command Execution to Custom Commands (#4917)
Diffstat (limited to 'packages/cli/src/services/FileCommandLoader.ts')
| -rw-r--r-- | packages/cli/src/services/FileCommandLoader.ts | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/packages/cli/src/services/FileCommandLoader.ts b/packages/cli/src/services/FileCommandLoader.ts index 23d5af19..c96acead 100644 --- a/packages/cli/src/services/FileCommandLoader.ts +++ b/packages/cli/src/services/FileCommandLoader.ts @@ -19,7 +19,7 @@ import { CommandContext, CommandKind, SlashCommand, - SubmitPromptActionReturn, + SlashCommandActionReturn, } from '../ui/commands/types.js'; import { DefaultArgumentProcessor, @@ -28,7 +28,12 @@ import { import { IPromptProcessor, SHORTHAND_ARGS_PLACEHOLDER, + SHELL_INJECTION_TRIGGER, } from './prompt-processors/types.js'; +import { + ConfirmationRequiredError, + ShellProcessor, +} from './prompt-processors/shellProcessor.js'; /** * Defines the Zod schema for a command definition file. This serves as the @@ -172,6 +177,11 @@ export class FileCommandLoader implements ICommandLoader { const processors: IPromptProcessor[] = []; + // Add the Shell Processor if needed. + if (validDef.prompt.includes(SHELL_INJECTION_TRIGGER)) { + processors.push(new ShellProcessor(commandName)); + } + // The presence of '{{args}}' is the switch that determines the behavior. if (validDef.prompt.includes(SHORTHAND_ARGS_PLACEHOLDER)) { processors.push(new ShorthandArgumentProcessor()); @@ -188,7 +198,7 @@ export class FileCommandLoader implements ICommandLoader { action: async ( context: CommandContext, _args: string, - ): Promise<SubmitPromptActionReturn> => { + ): Promise<SlashCommandActionReturn> => { if (!context.invocation) { console.error( `[FileCommandLoader] Critical error: Command '${commandName}' was executed without invocation context.`, @@ -199,15 +209,31 @@ export class FileCommandLoader implements ICommandLoader { }; } - let processedPrompt = validDef.prompt; - for (const processor of processors) { - processedPrompt = await processor.process(processedPrompt, context); - } + try { + let processedPrompt = validDef.prompt; + for (const processor of processors) { + processedPrompt = await processor.process(processedPrompt, context); + } - return { - type: 'submit_prompt', - content: processedPrompt, - }; + return { + type: 'submit_prompt', + content: processedPrompt, + }; + } catch (e) { + // Check if it's our specific error type + if (e instanceof ConfirmationRequiredError) { + // Halt and request confirmation from the UI layer. + return { + type: 'confirm_shell_commands', + commandsToConfirm: e.commandsToConfirm, + originalInvocation: { + raw: context.invocation.raw, + }, + }; + } + // Re-throw other errors to be handled by the global error handler. + throw e; + } }, }; } |
