diff options
| author | Olcan <[email protected]> | 2025-04-25 14:05:58 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-04-25 14:05:58 -0700 |
| commit | 7087c0508ea9260abaa31b0cd8f206d3b11cf21b (patch) | |
| tree | 748adf1d30936ec421306bf4ad3664728011269d /packages/server/src/tools/shell.ts | |
| parent | 1a64268bb058049d94a9265c839265607606ec88 (diff) | |
more consistent confirmations, TODO to improve write confirmations, drop "description" from execution confirmation, add confirmation to new (still dummy) shell tool (#176)
Diffstat (limited to 'packages/server/src/tools/shell.ts')
| -rw-r--r-- | packages/server/src/tools/shell.ts | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/packages/server/src/tools/shell.ts b/packages/server/src/tools/shell.ts index 7af6e703..bf4cf810 100644 --- a/packages/server/src/tools/shell.ts +++ b/packages/server/src/tools/shell.ts @@ -4,10 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -import path from 'path'; import fs from 'fs'; import { Config } from '../config/config.js'; -import { BaseTool, ToolResult } from './tools.js'; +import { + BaseTool, + ToolResult, + ToolCallConfirmationDetails, + ToolExecuteConfirmationDetails, + ToolConfirmationOutcome, +} from './tools.js'; import toolParameterSchema from './shell.json' with { type: 'json' }; export interface ShellToolParams { @@ -17,10 +22,11 @@ export interface ShellToolParams { export class ShellTool extends BaseTool<ShellToolParams, ToolResult> { static Name: string = 'execute_bash_command'; - private readonly rootDirectory: string; private readonly config: Config; + private cwd: string; + private whitelist: Set<string> = new Set(); - constructor(rootDirectory: string, config: Config) { + constructor(config: Config) { const toolDisplayName = 'Shell'; const descriptionUrl = new URL('shell.md', import.meta.url); const toolDescription = fs.readFileSync(descriptionUrl, 'utf-8'); @@ -31,7 +37,41 @@ export class ShellTool extends BaseTool<ShellToolParams, ToolResult> { toolParameterSchema, ); this.config = config; - this.rootDirectory = path.resolve(rootDirectory); + this.cwd = config.getTargetDir(); + } + + getDescription(params: ShellToolParams): string { + return params.description || `Execute \`${params.command}\` in ${this.cwd}`; + } + + validateToolParams(_params: ShellToolParams): string | null { + // TODO: validate the command here + return null; + } + + async shouldConfirmExecute( + params: ShellToolParams, + ): Promise<ToolCallConfirmationDetails | false> { + const rootCommand = + params.command + .trim() + .split(/[\s;&&|]+/)[0] + ?.split(/[/\\]/) + .pop() || 'unknown'; + if (this.whitelist.has(rootCommand)) { + return false; + } + const confirmationDetails: ToolExecuteConfirmationDetails = { + title: 'Confirm Shell Command', + command: params.command, + rootCommand, + onConfirm: async (outcome: ToolConfirmationOutcome) => { + if (outcome === ToolConfirmationOutcome.ProceedAlways) { + this.whitelist.add(rootCommand); + } + }, + }; + return confirmationDetails; } async execute(_params: ShellToolParams): Promise<ToolResult> { |
