summaryrefslogtreecommitdiff
path: root/packages/cli/src/services/FileCommandLoader.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/services/FileCommandLoader.ts')
-rw-r--r--packages/cli/src/services/FileCommandLoader.ts46
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;
+ }
},
};
}