@phuetz/code-buddy 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +228 -13
- package/dist/agent/architect-mode.d.ts +11 -0
- package/dist/agent/architect-mode.js +133 -25
- package/dist/agent/architect-mode.js.map +1 -1
- package/dist/agent/codebuddy-agent.d.ts +24 -0
- package/dist/agent/codebuddy-agent.js +118 -16
- package/dist/agent/codebuddy-agent.js.map +1 -1
- package/dist/agent/execution/agent-executor.d.ts +9 -0
- package/dist/agent/execution/agent-executor.js +62 -1
- package/dist/agent/execution/agent-executor.js.map +1 -1
- package/dist/agent/message-queue.d.ts +77 -0
- package/dist/agent/message-queue.js +116 -0
- package/dist/agent/message-queue.js.map +1 -0
- package/dist/agent/middleware/auto-observation.d.ts +37 -0
- package/dist/agent/middleware/auto-observation.js +231 -0
- package/dist/agent/middleware/auto-observation.js.map +1 -0
- package/dist/agent/middleware/index.d.ts +2 -0
- package/dist/agent/middleware/index.js +1 -0
- package/dist/agent/middleware/index.js.map +1 -1
- package/dist/agent/tool-handler.js +3 -2
- package/dist/agent/tool-handler.js.map +1 -1
- package/dist/agent/turn-diff-tracker.js +3 -0
- package/dist/agent/turn-diff-tracker.js.map +1 -1
- package/dist/agent/types.d.ts +7 -2
- package/dist/analytics/budget-alerts.d.ts +81 -0
- package/dist/analytics/budget-alerts.js +126 -0
- package/dist/analytics/budget-alerts.js.map +1 -0
- package/dist/analytics/cost-predictor.d.ts +79 -0
- package/dist/analytics/cost-predictor.js +150 -0
- package/dist/analytics/cost-predictor.js.map +1 -0
- package/dist/analytics/index.d.ts +2 -0
- package/dist/analytics/index.js +2 -0
- package/dist/analytics/index.js.map +1 -1
- package/dist/auth/profile-manager.d.ts +205 -0
- package/dist/auth/profile-manager.js +484 -0
- package/dist/auth/profile-manager.js.map +1 -0
- package/dist/browser-automation/browser-manager.d.ts +79 -1
- package/dist/browser-automation/browser-manager.js +265 -2
- package/dist/browser-automation/browser-manager.js.map +1 -1
- package/dist/browser-automation/profile-manager.d.ts +32 -0
- package/dist/browser-automation/profile-manager.js +83 -0
- package/dist/browser-automation/profile-manager.js.map +1 -0
- package/dist/browser-automation/route-interceptor.d.ts +29 -0
- package/dist/browser-automation/route-interceptor.js +103 -0
- package/dist/browser-automation/route-interceptor.js.map +1 -0
- package/dist/browser-automation/screenshot-annotator.d.ts +23 -0
- package/dist/browser-automation/screenshot-annotator.js +86 -0
- package/dist/browser-automation/screenshot-annotator.js.map +1 -0
- package/dist/browser-automation/types.d.ts +47 -0
- package/dist/cache/llm-response-cache.js +3 -0
- package/dist/cache/llm-response-cache.js.map +1 -1
- package/dist/canvas/canvas-server.js +4 -3
- package/dist/canvas/canvas-server.js.map +1 -1
- package/dist/channels/discord/client.d.ts +2 -1
- package/dist/channels/discord/client.js +28 -16
- package/dist/channels/discord/client.js.map +1 -1
- package/dist/channels/dm-pairing.js +6 -3
- package/dist/channels/dm-pairing.js.map +1 -1
- package/dist/channels/google-chat/index.d.ts +210 -0
- package/dist/channels/google-chat/index.js +505 -0
- package/dist/channels/google-chat/index.js.map +1 -0
- package/dist/channels/group-security.d.ts +182 -0
- package/dist/channels/group-security.js +407 -0
- package/dist/channels/group-security.js.map +1 -0
- package/dist/channels/index.d.ts +17 -1
- package/dist/channels/index.js +16 -0
- package/dist/channels/index.js.map +1 -1
- package/dist/channels/matrix/index.d.ts +181 -0
- package/dist/channels/matrix/index.js +643 -0
- package/dist/channels/matrix/index.js.map +1 -0
- package/dist/channels/offline-queue.d.ts +92 -0
- package/dist/channels/offline-queue.js +112 -0
- package/dist/channels/offline-queue.js.map +1 -0
- package/dist/channels/reconnection-manager.d.ts +117 -0
- package/dist/channels/reconnection-manager.js +171 -0
- package/dist/channels/reconnection-manager.js.map +1 -0
- package/dist/channels/signal/index.d.ts +184 -0
- package/dist/channels/signal/index.js +488 -0
- package/dist/channels/signal/index.js.map +1 -0
- package/dist/channels/slack/client.d.ts +2 -1
- package/dist/channels/slack/client.js +30 -15
- package/dist/channels/slack/client.js.map +1 -1
- package/dist/channels/teams/index.d.ts +196 -0
- package/dist/channels/teams/index.js +477 -0
- package/dist/channels/teams/index.js.map +1 -0
- package/dist/channels/telegram/client.d.ts +3 -1
- package/dist/channels/telegram/client.js +29 -2
- package/dist/channels/telegram/client.js.map +1 -1
- package/dist/channels/webchat/index.d.ts +103 -0
- package/dist/channels/webchat/index.js +697 -0
- package/dist/channels/webchat/index.js.map +1 -0
- package/dist/channels/whatsapp/index.d.ts +105 -0
- package/dist/channels/whatsapp/index.js +533 -0
- package/dist/channels/whatsapp/index.js.map +1 -0
- package/dist/codebuddy/client.js +11 -5
- package/dist/codebuddy/client.js.map +1 -1
- package/dist/codebuddy/tool-definitions/advanced-tools.d.ts +1 -0
- package/dist/codebuddy/tool-definitions/advanced-tools.js +103 -3
- package/dist/codebuddy/tool-definitions/advanced-tools.js.map +1 -1
- package/dist/codebuddy/tool-definitions/index.d.ts +1 -1
- package/dist/codebuddy/tool-definitions/index.js +1 -1
- package/dist/codebuddy/tool-definitions/index.js.map +1 -1
- package/dist/codebuddy/tools.js +3 -1
- package/dist/codebuddy/tools.js.map +1 -1
- package/dist/commands/cli/config-command.d.ts +8 -0
- package/dist/commands/cli/config-command.js +90 -0
- package/dist/commands/cli/config-command.js.map +1 -0
- package/dist/commands/cli/openclaw-commands.d.ts +12 -0
- package/dist/commands/cli/openclaw-commands.js +446 -0
- package/dist/commands/cli/openclaw-commands.js.map +1 -0
- package/dist/commands/cli/utility-commands.js +30 -0
- package/dist/commands/cli/utility-commands.js.map +1 -1
- package/dist/commands/client-dispatcher.js +22 -2
- package/dist/commands/client-dispatcher.js.map +1 -1
- package/dist/commands/enhanced-command-handler.js +21 -2
- package/dist/commands/enhanced-command-handler.js.map +1 -1
- package/dist/commands/handlers/extra-handlers.d.ts +30 -0
- package/dist/commands/handlers/extra-handlers.js +547 -0
- package/dist/commands/handlers/extra-handlers.js.map +1 -0
- package/dist/commands/handlers/index.d.ts +1 -0
- package/dist/commands/handlers/index.js +2 -0
- package/dist/commands/handlers/index.js.map +1 -1
- package/dist/commands/slash/builtin-commands.js +41 -34
- package/dist/commands/slash/builtin-commands.js.map +1 -1
- package/dist/config/env-schema.d.ts +58 -0
- package/dist/config/env-schema.js +789 -0
- package/dist/config/env-schema.js.map +1 -0
- package/dist/config/feature-flags.js +2 -1
- package/dist/config/feature-flags.js.map +1 -1
- package/dist/context/bootstrap-loader.d.ts +48 -0
- package/dist/context/bootstrap-loader.js +123 -0
- package/dist/context/bootstrap-loader.js.map +1 -0
- package/dist/context/codebase-rag/chunker.js +2 -2
- package/dist/context/codebase-rag/chunker.js.map +1 -1
- package/dist/copilot/copilot-proxy.d.ts +15 -1
- package/dist/copilot/copilot-proxy.js +92 -23
- package/dist/copilot/copilot-proxy.js.map +1 -1
- package/dist/daemon/health-monitor.js +11 -7
- package/dist/daemon/health-monitor.js.map +1 -1
- package/dist/daemon/heartbeat.d.ts +112 -0
- package/dist/daemon/heartbeat.js +339 -0
- package/dist/daemon/heartbeat.js.map +1 -0
- package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
- package/dist/desktop-automation/smart-snapshot.js +38 -0
- package/dist/desktop-automation/smart-snapshot.js.map +1 -1
- package/dist/extensions/extension-loader.js +4 -0
- package/dist/extensions/extension-loader.js.map +1 -1
- package/dist/identity/identity-manager.d.ts +95 -0
- package/dist/identity/identity-manager.js +242 -0
- package/dist/identity/identity-manager.js.map +1 -0
- package/dist/index.js +147 -17
- package/dist/index.js.map +1 -1
- package/dist/input/text-to-speech.js +4 -2
- package/dist/input/text-to-speech.js.map +1 -1
- package/dist/input/voice-control.js +5 -3
- package/dist/input/voice-control.js.map +1 -1
- package/dist/integrations/github-integration.js +1 -1
- package/dist/integrations/github-integration.js.map +1 -1
- package/dist/orchestration/orchestrator.js +3 -0
- package/dist/orchestration/orchestrator.js.map +1 -1
- package/dist/persistence/conversation-branches.js +2 -1
- package/dist/persistence/conversation-branches.js.map +1 -1
- package/dist/persistence/session-store.d.ts +1 -1
- package/dist/persistence/session-store.js +1 -1
- package/dist/persistence/session-store.js.map +1 -1
- package/dist/plugins/plugin-system.js +5 -2
- package/dist/plugins/plugin-system.js.map +1 -1
- package/dist/providers/gemini-provider.js +6 -4
- package/dist/providers/gemini-provider.js.map +1 -1
- package/dist/providers/local-llm-provider.js +8 -0
- package/dist/providers/local-llm-provider.js.map +1 -1
- package/dist/sandbox/auto-sandbox.d.ts +59 -0
- package/dist/sandbox/auto-sandbox.js +145 -0
- package/dist/sandbox/auto-sandbox.js.map +1 -0
- package/dist/scheduler/cron-scheduler.js +2 -0
- package/dist/scheduler/cron-scheduler.js.map +1 -1
- package/dist/scheduler/scheduler.js +11 -2
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/security/audit-logger.d.ts +127 -0
- package/dist/security/audit-logger.js +194 -0
- package/dist/security/audit-logger.js.map +1 -0
- package/dist/security/bash-allowlist/allowlist-store.js +3 -2
- package/dist/security/bash-allowlist/allowlist-store.js.map +1 -1
- package/dist/security/bash-parser.js +0 -2
- package/dist/security/bash-parser.js.map +1 -1
- package/dist/security/code-validator.d.ts +51 -0
- package/dist/security/code-validator.js +185 -0
- package/dist/security/code-validator.js.map +1 -0
- package/dist/security/dangerous-patterns.d.ts +68 -0
- package/dist/security/dangerous-patterns.js +218 -0
- package/dist/security/dangerous-patterns.js.map +1 -0
- package/dist/security/remote-approval.d.ts +65 -0
- package/dist/security/remote-approval.js +138 -0
- package/dist/security/remote-approval.js.map +1 -0
- package/dist/security/security-audit.d.ts +7 -0
- package/dist/security/security-audit.js +23 -0
- package/dist/security/security-audit.js.map +1 -1
- package/dist/security/syntax-validator.d.ts +17 -0
- package/dist/security/syntax-validator.js +292 -0
- package/dist/security/syntax-validator.js.map +1 -0
- package/dist/server/index.js +277 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware/logging.js +9 -1
- package/dist/server/middleware/logging.js.map +1 -1
- package/dist/server/routes/memory.js +4 -1
- package/dist/server/routes/memory.js.map +1 -1
- package/dist/server/routes/metrics.js +1 -1
- package/dist/server/routes/metrics.js.map +1 -1
- package/dist/server/routes/sessions.js +5 -4
- package/dist/server/routes/sessions.js.map +1 -1
- package/dist/server/websocket/handler.js +8 -2
- package/dist/server/websocket/handler.js.map +1 -1
- package/dist/services/prompt-builder.js +16 -0
- package/dist/services/prompt-builder.js.map +1 -1
- package/dist/skills/hub.d.ts +231 -0
- package/dist/skills/hub.js +694 -0
- package/dist/skills/hub.js.map +1 -0
- package/dist/skills/skill-loader.js +1 -1
- package/dist/skills/skill-loader.js.map +1 -1
- package/dist/skills/skill-manager.js +2 -1
- package/dist/skills/skill-manager.js.map +1 -1
- package/dist/skills/skill-registry.js +4 -0
- package/dist/skills/skill-registry.js.map +1 -1
- package/dist/talk-mode/providers/audioreader-tts.js +1 -0
- package/dist/talk-mode/providers/audioreader-tts.js.map +1 -1
- package/dist/tools/apply-patch.d.ts +1 -0
- package/dist/tools/apply-patch.js +66 -12
- package/dist/tools/apply-patch.js.map +1 -1
- package/dist/tools/bash/bash-tool.d.ts +123 -0
- package/dist/tools/bash/bash-tool.js +549 -0
- package/dist/tools/bash/bash-tool.js.map +1 -0
- package/dist/tools/bash/command-validator.d.ts +49 -0
- package/dist/tools/bash/command-validator.js +223 -0
- package/dist/tools/bash/command-validator.js.map +1 -0
- package/dist/tools/bash/index.d.ts +7 -0
- package/dist/tools/bash/index.js +8 -0
- package/dist/tools/bash/index.js.map +1 -0
- package/dist/tools/bash/security-patterns.d.ts +44 -0
- package/dist/tools/bash/security-patterns.js +234 -0
- package/dist/tools/bash/security-patterns.js.map +1 -0
- package/dist/tools/bash/streaming-executor.d.ts +23 -0
- package/dist/tools/bash/streaming-executor.js +134 -0
- package/dist/tools/bash/streaming-executor.js.map +1 -0
- package/dist/tools/bash.js +5 -3
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/code-formatter.js +41 -27
- package/dist/tools/code-formatter.js.map +1 -1
- package/dist/tools/code-review.js +1 -1
- package/dist/tools/code-review.js.map +1 -1
- package/dist/tools/computer-control-tool.js +21 -0
- package/dist/tools/computer-control-tool.js.map +1 -1
- package/dist/tools/document-tool.js +3 -2
- package/dist/tools/document-tool.js.map +1 -1
- package/dist/tools/git-tool.d.ts +45 -0
- package/dist/tools/git-tool.js +224 -2
- package/dist/tools/git-tool.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/morph-editor.js +1 -0
- package/dist/tools/morph-editor.js.map +1 -1
- package/dist/tools/multi-edit.js +31 -3
- package/dist/tools/multi-edit.js.map +1 -1
- package/dist/tools/notebook-tool.js +8 -2
- package/dist/tools/notebook-tool.js.map +1 -1
- package/dist/tools/process-tool.d.ts +69 -0
- package/dist/tools/process-tool.js +222 -0
- package/dist/tools/process-tool.js.map +1 -0
- package/dist/tools/registry/git-tools.d.ts +32 -0
- package/dist/tools/registry/git-tools.js +211 -0
- package/dist/tools/registry/git-tools.js.map +1 -0
- package/dist/tools/registry/index.d.ts +2 -0
- package/dist/tools/registry/index.js +8 -0
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/registry/misc-tools.d.ts +32 -4
- package/dist/tools/registry/misc-tools.js +230 -90
- package/dist/tools/registry/misc-tools.js.map +1 -1
- package/dist/tools/registry/process-tools.d.ts +20 -0
- package/dist/tools/registry/process-tools.js +141 -0
- package/dist/tools/registry/process-tools.js.map +1 -0
- package/dist/tools/registry/types.d.ts +2 -0
- package/dist/tools/search.js +4 -2
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/video-tool.js +30 -14
- package/dist/tools/video-tool.js.map +1 -1
- package/dist/tools/web-search.js +4 -1
- package/dist/tools/web-search.js.map +1 -1
- package/dist/ui/components/ChatInterface.js +9 -0
- package/dist/ui/components/ChatInterface.js.map +1 -1
- package/dist/utils/autonomy-manager.js +3 -2
- package/dist/utils/autonomy-manager.js.map +1 -1
- package/dist/utils/config-validation/schema.d.ts +15 -15
- package/dist/utils/confirmation-service.d.ts +16 -0
- package/dist/utils/confirmation-service.js +37 -3
- package/dist/utils/confirmation-service.js.map +1 -1
- package/dist/utils/custom-instructions.js +2 -1
- package/dist/utils/custom-instructions.js.map +1 -1
- package/dist/utils/diff-generator.js +3 -1
- package/dist/utils/diff-generator.js.map +1 -1
- package/dist/utils/graceful-shutdown.js +9 -9
- package/dist/utils/graceful-shutdown.js.map +1 -1
- package/dist/utils/head-tail-truncation.d.ts +18 -0
- package/dist/utils/head-tail-truncation.js +127 -0
- package/dist/utils/head-tail-truncation.js.map +1 -1
- package/dist/utils/history-manager.js +3 -2
- package/dist/utils/history-manager.js.map +1 -1
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +18 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/performance.js +16 -15
- package/dist/utils/performance.js.map +1 -1
- package/dist/utils/stream-helpers.js +4 -2
- package/dist/utils/stream-helpers.js.map +1 -1
- package/dist/utils/update-notifier.js +2 -1
- package/dist/utils/update-notifier.js.map +1 -1
- package/dist/workflows/pipeline.d.ts +54 -1
- package/dist/workflows/pipeline.js +128 -7
- package/dist/workflows/pipeline.js.map +1 -1
- package/dist/workflows/step-manager.js +2 -1
- package/dist/workflows/step-manager.js.map +1 -1
- package/package.json +6 -3
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BashTool - Main coordinator class for shell command execution.
|
|
3
|
+
*
|
|
4
|
+
* Executes shell commands with comprehensive security measures:
|
|
5
|
+
* - Blocked dangerous patterns (rm -rf /, fork bombs, etc.)
|
|
6
|
+
* - Protected paths (~/.ssh, ~/.aws, /etc/shadow, etc.)
|
|
7
|
+
* - User confirmation for commands (unless session-approved)
|
|
8
|
+
* - Self-healing: automatic error recovery for common failures
|
|
9
|
+
* - Process isolation via spawn with process group management
|
|
10
|
+
* - Graceful termination with SIGTERM before SIGKILL
|
|
11
|
+
*
|
|
12
|
+
* Security modes are controlled by SandboxManager configuration.
|
|
13
|
+
* Self-healing can be disabled via --no-self-heal flag.
|
|
14
|
+
*/
|
|
15
|
+
import { spawn } from 'child_process';
|
|
16
|
+
import { ConfirmationService } from '../../utils/confirmation-service.js';
|
|
17
|
+
import { getSandboxManager } from '../../security/sandbox.js';
|
|
18
|
+
import { getSelfHealingEngine } from '../../utils/self-healing.js';
|
|
19
|
+
import { parseTestOutput, isLikelyTestOutput } from '../../utils/test-output-parser.js';
|
|
20
|
+
import { registerDisposable } from '../../utils/disposable.js';
|
|
21
|
+
import { bashToolSchemas, validateWithSchema, validateCommand as validateCommandSafety, sanitizeForShell } from '../../utils/input-validator.js';
|
|
22
|
+
import { rgPath } from '@vscode/ripgrep';
|
|
23
|
+
import { validateCommand, getFilteredEnv } from './command-validator.js';
|
|
24
|
+
import { executeStreaming as executeStreamingImpl } from './streaming-executor.js';
|
|
25
|
+
import { parseBashCommand } from '../../security/bash-parser.js';
|
|
26
|
+
import { getCheckpointManager } from '../../checkpoints/checkpoint-manager.js';
|
|
27
|
+
import { auditLogger } from '../../security/audit-logger.js';
|
|
28
|
+
export class BashTool {
|
|
29
|
+
currentDirectory = process.cwd();
|
|
30
|
+
confirmationService = ConfirmationService.getInstance();
|
|
31
|
+
sandboxManager = getSandboxManager();
|
|
32
|
+
selfHealingEngine = getSelfHealingEngine();
|
|
33
|
+
selfHealingEnabled = true;
|
|
34
|
+
runningProcesses = new Set();
|
|
35
|
+
constructor() {
|
|
36
|
+
registerDisposable(this);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Clean up resources - kill any running processes
|
|
40
|
+
*/
|
|
41
|
+
dispose() {
|
|
42
|
+
for (const proc of this.runningProcesses) {
|
|
43
|
+
try {
|
|
44
|
+
proc.kill('SIGTERM');
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Process may already be dead
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
this.runningProcesses.clear();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validate command for dangerous patterns (delegates to command-validator)
|
|
54
|
+
*
|
|
55
|
+
* Security checks performed (in order):
|
|
56
|
+
* 1. Control characters - blocks terminal manipulation
|
|
57
|
+
* 2. ANSI escape sequences - blocks display manipulation
|
|
58
|
+
* 3. Shell bypass features - blocks process substitution, here-strings, etc.
|
|
59
|
+
* 4. Base command blocklist - blocks known dangerous commands
|
|
60
|
+
* 5. Blocked command patterns - blocks known dangerous patterns
|
|
61
|
+
* 6. Protected paths - blocks access to sensitive directories
|
|
62
|
+
* 7. Sandbox manager validation - additional runtime checks
|
|
63
|
+
*/
|
|
64
|
+
validateCommand(command) {
|
|
65
|
+
// Run static validation checks
|
|
66
|
+
const staticValidation = validateCommand(command);
|
|
67
|
+
if (!staticValidation.valid) {
|
|
68
|
+
return staticValidation;
|
|
69
|
+
}
|
|
70
|
+
// Also use sandbox manager validation
|
|
71
|
+
const sandboxValidation = this.sandboxManager.validateCommand(command);
|
|
72
|
+
if (!sandboxValidation.valid) {
|
|
73
|
+
return sandboxValidation;
|
|
74
|
+
}
|
|
75
|
+
return { valid: true };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Execute a command with streaming output.
|
|
79
|
+
* Yields each line of stdout/stderr as it arrives.
|
|
80
|
+
* Validates and confirms the command before execution.
|
|
81
|
+
*/
|
|
82
|
+
async *executeStreaming(command, timeout = 30000) {
|
|
83
|
+
return yield* executeStreamingImpl(command, timeout, {
|
|
84
|
+
getCurrentDirectory: () => this.currentDirectory,
|
|
85
|
+
getSandboxManager: () => this.sandboxManager,
|
|
86
|
+
getRunningProcesses: () => this.runningProcesses,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Execute a command using spawn with process group isolation (safer than exec)
|
|
91
|
+
* Inspired by mistral-vibe's robust process handling
|
|
92
|
+
*/
|
|
93
|
+
executeWithSpawn(command, options) {
|
|
94
|
+
return new Promise((resolve) => {
|
|
95
|
+
let stdout = '';
|
|
96
|
+
let stderr = '';
|
|
97
|
+
let timedOut = false;
|
|
98
|
+
const isWindows = process.platform === 'win32';
|
|
99
|
+
// Start with filtered environment (only safe vars, no secrets)
|
|
100
|
+
const filteredEnv = getFilteredEnv();
|
|
101
|
+
// Controlled environment variables for deterministic output
|
|
102
|
+
const controlledEnv = {
|
|
103
|
+
...filteredEnv,
|
|
104
|
+
// Disable history to prevent command logging
|
|
105
|
+
HISTFILE: '/dev/null',
|
|
106
|
+
HISTSIZE: '0',
|
|
107
|
+
// CI mode for consistent behavior
|
|
108
|
+
CI: 'true',
|
|
109
|
+
// Disable color output for clean parsing
|
|
110
|
+
NO_COLOR: '1',
|
|
111
|
+
TERM: 'dumb',
|
|
112
|
+
// Disable TTY for non-interactive mode
|
|
113
|
+
NO_TTY: '1',
|
|
114
|
+
// Disable interactive features
|
|
115
|
+
GIT_TERMINAL_PROMPT: '0',
|
|
116
|
+
NPM_CONFIG_YES: 'true',
|
|
117
|
+
YARN_ENABLE_PROGRESS_BARS: 'false',
|
|
118
|
+
// Locale settings for consistent encoding
|
|
119
|
+
LC_ALL: 'C.UTF-8',
|
|
120
|
+
LANG: 'C.UTF-8',
|
|
121
|
+
PYTHONIOENCODING: 'utf-8',
|
|
122
|
+
// Force non-interactive for common tools
|
|
123
|
+
DEBIAN_FRONTEND: 'noninteractive',
|
|
124
|
+
};
|
|
125
|
+
const spawnOptions = {
|
|
126
|
+
// IMPORTANT: shell must be false when using bash -c
|
|
127
|
+
// Using shell: true with bash -c creates double-shell that breaks commands
|
|
128
|
+
shell: false,
|
|
129
|
+
cwd: options.cwd,
|
|
130
|
+
env: controlledEnv,
|
|
131
|
+
// Process group isolation on Unix (allows killing entire process tree)
|
|
132
|
+
detached: !isWindows,
|
|
133
|
+
// Don't inherit stdin - commands should be non-interactive
|
|
134
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
135
|
+
};
|
|
136
|
+
const proc = spawn('bash', ['-c', command], spawnOptions);
|
|
137
|
+
// Store process group ID for cleanup
|
|
138
|
+
const pgid = proc.pid;
|
|
139
|
+
// Graceful termination: SIGTERM first, then SIGKILL after grace period
|
|
140
|
+
const gracePeriod = 3000; // 3 seconds grace period
|
|
141
|
+
let gracefulTerminationTimer = null;
|
|
142
|
+
const killProcess = (signal = 'SIGKILL') => {
|
|
143
|
+
try {
|
|
144
|
+
if (!isWindows && pgid) {
|
|
145
|
+
// Kill the entire process group
|
|
146
|
+
process.kill(-pgid, signal);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
proc.kill(signal);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Process may have already exited
|
|
154
|
+
try {
|
|
155
|
+
proc.kill('SIGKILL');
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Ignore - process is already gone
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const timer = setTimeout(() => {
|
|
163
|
+
timedOut = true;
|
|
164
|
+
// Try graceful termination first (SIGTERM)
|
|
165
|
+
killProcess('SIGTERM');
|
|
166
|
+
// If still running after grace period, force kill
|
|
167
|
+
gracefulTerminationTimer = setTimeout(() => {
|
|
168
|
+
killProcess('SIGKILL');
|
|
169
|
+
}, gracePeriod);
|
|
170
|
+
}, options.timeout);
|
|
171
|
+
const maxBuffer = 1024 * 1024; // 1MB limit
|
|
172
|
+
proc.stdout?.on('data', (data) => {
|
|
173
|
+
const chunk = data.toString();
|
|
174
|
+
if (stdout.length + chunk.length <= maxBuffer) {
|
|
175
|
+
stdout += chunk;
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
proc.stderr?.on('data', (data) => {
|
|
179
|
+
const chunk = data.toString();
|
|
180
|
+
if (stderr.length + chunk.length <= maxBuffer) {
|
|
181
|
+
stderr += chunk;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
proc.on('close', (exitCode) => {
|
|
185
|
+
clearTimeout(timer);
|
|
186
|
+
if (gracefulTerminationTimer) {
|
|
187
|
+
clearTimeout(gracefulTerminationTimer);
|
|
188
|
+
}
|
|
189
|
+
if (timedOut) {
|
|
190
|
+
resolve({
|
|
191
|
+
stdout: stdout.trim(),
|
|
192
|
+
stderr: 'Command timed out (graceful termination attempted)',
|
|
193
|
+
exitCode: 124
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
resolve({
|
|
198
|
+
stdout: stdout.trim(),
|
|
199
|
+
stderr: stderr.trim(),
|
|
200
|
+
exitCode: exitCode ?? 1
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
proc.on('error', (error) => {
|
|
205
|
+
clearTimeout(timer);
|
|
206
|
+
if (gracefulTerminationTimer) {
|
|
207
|
+
clearTimeout(gracefulTerminationTimer);
|
|
208
|
+
}
|
|
209
|
+
resolve({
|
|
210
|
+
stdout: '',
|
|
211
|
+
stderr: error.message,
|
|
212
|
+
exitCode: 1
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Execute a shell command
|
|
219
|
+
*
|
|
220
|
+
* Validates command safety, requests user confirmation, and executes
|
|
221
|
+
* via spawn with process isolation. Failed commands trigger self-healing
|
|
222
|
+
* attempts if enabled.
|
|
223
|
+
*
|
|
224
|
+
* Special handling for `cd` commands to update working directory state.
|
|
225
|
+
*
|
|
226
|
+
* @param command - Shell command to execute
|
|
227
|
+
* @param timeout - Maximum execution time in ms (default: 30000)
|
|
228
|
+
* @returns Command output or error message; test output is parsed and structured
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* // Simple command
|
|
232
|
+
* await bash.execute('ls -la');
|
|
233
|
+
*
|
|
234
|
+
* // With custom timeout (2 minutes)
|
|
235
|
+
* await bash.execute('npm install', 120000);
|
|
236
|
+
*/
|
|
237
|
+
async execute(command, timeout = 30000) {
|
|
238
|
+
try {
|
|
239
|
+
// Validate input with schema (enhanced validation)
|
|
240
|
+
const schemaValidation = validateWithSchema(bashToolSchemas.execute, { command, timeout }, 'execute');
|
|
241
|
+
if (!schemaValidation.valid) {
|
|
242
|
+
return {
|
|
243
|
+
success: false,
|
|
244
|
+
error: `Invalid input: ${schemaValidation.error}`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// Additional command safety validation
|
|
248
|
+
const commandSafetyValidation = validateCommandSafety(command);
|
|
249
|
+
if (!commandSafetyValidation.valid) {
|
|
250
|
+
return {
|
|
251
|
+
success: false,
|
|
252
|
+
error: `Command blocked: ${commandSafetyValidation.error}`,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
// Validate command before any execution (legacy validation)
|
|
256
|
+
const validation = this.validateCommand(command);
|
|
257
|
+
if (!validation.valid) {
|
|
258
|
+
return {
|
|
259
|
+
success: false,
|
|
260
|
+
error: `Command blocked: ${validation.reason}`,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
// Check if user has already accepted bash commands for this session
|
|
264
|
+
const sessionFlags = this.confirmationService.getSessionFlags();
|
|
265
|
+
if (!sessionFlags.bashCommands && !sessionFlags.allOperations) {
|
|
266
|
+
// Request confirmation showing the command
|
|
267
|
+
const confirmationResult = await this.confirmationService.requestConfirmation({
|
|
268
|
+
operation: 'Run bash command',
|
|
269
|
+
filename: command,
|
|
270
|
+
showVSCodeOpen: false,
|
|
271
|
+
content: `Command: ${command}\nWorking directory: ${this.currentDirectory}`,
|
|
272
|
+
}, 'bash');
|
|
273
|
+
if (!confirmationResult.confirmed) {
|
|
274
|
+
return {
|
|
275
|
+
success: false,
|
|
276
|
+
error: confirmationResult.feedback || 'Command execution cancelled by user',
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Checkpoint files targeted by destructive commands (rm, mv, etc.)
|
|
281
|
+
this.checkpointDestructiveTargets(command);
|
|
282
|
+
// Handle cd command separately
|
|
283
|
+
if (command.startsWith('cd ')) {
|
|
284
|
+
const newDir = command.substring(3).trim();
|
|
285
|
+
// Remove quotes if present
|
|
286
|
+
const cleanDir = newDir.replace(/^["']|["']$/g, '');
|
|
287
|
+
try {
|
|
288
|
+
process.chdir(cleanDir);
|
|
289
|
+
this.currentDirectory = process.cwd();
|
|
290
|
+
return {
|
|
291
|
+
success: true,
|
|
292
|
+
output: `Changed directory to: ${this.currentDirectory}`,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
297
|
+
return {
|
|
298
|
+
success: false,
|
|
299
|
+
error: `Cannot change directory: ${errorMessage}`,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Execute using spawn (safer than exec)
|
|
304
|
+
const result = await this.executeWithSpawn(command, {
|
|
305
|
+
timeout,
|
|
306
|
+
cwd: this.currentDirectory,
|
|
307
|
+
});
|
|
308
|
+
if (result.exitCode !== 0) {
|
|
309
|
+
const errorMessage = result.stderr || `Command exited with code ${result.exitCode}`;
|
|
310
|
+
// Attempt self-healing if enabled
|
|
311
|
+
if (this.selfHealingEnabled) {
|
|
312
|
+
const healingResult = await this.selfHealingEngine.attemptHealing(command, errorMessage, async (fixCmd) => {
|
|
313
|
+
// Execute fix command without self-healing to avoid recursion
|
|
314
|
+
const fixResult = await this.executeWithSpawn(fixCmd, {
|
|
315
|
+
timeout: timeout * 2, // Give more time for fix commands
|
|
316
|
+
cwd: this.currentDirectory,
|
|
317
|
+
});
|
|
318
|
+
if (fixResult.exitCode === 0) {
|
|
319
|
+
return {
|
|
320
|
+
success: true,
|
|
321
|
+
output: fixResult.stdout || 'Fix applied successfully',
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
success: false,
|
|
326
|
+
error: fixResult.stderr || `Fix failed with code ${fixResult.exitCode}`,
|
|
327
|
+
};
|
|
328
|
+
});
|
|
329
|
+
if (healingResult.success && healingResult.finalResult) {
|
|
330
|
+
return {
|
|
331
|
+
success: true,
|
|
332
|
+
output: `🔧 Self-healed after ${healingResult.attempts.length} attempt(s)\n` +
|
|
333
|
+
`Fix applied: ${healingResult.fixedCommand}\n\n` +
|
|
334
|
+
(healingResult.finalResult.output || 'Success'),
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
// If healing failed, return original error with healing info
|
|
338
|
+
if (healingResult.attempts.length > 0) {
|
|
339
|
+
return {
|
|
340
|
+
success: false,
|
|
341
|
+
error: `${errorMessage}\n\n🔧 Self-healing attempted ${healingResult.attempts.length} fix(es) but failed.`,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
success: false,
|
|
347
|
+
error: errorMessage,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
const output = result.stdout + (result.stderr ? `\nSTDERR: ${result.stderr}` : '');
|
|
351
|
+
const trimmedOutput = output.trim() || 'Command executed successfully (no output)';
|
|
352
|
+
// Check if this looks like test output and enrich it
|
|
353
|
+
if (isLikelyTestOutput(trimmedOutput)) {
|
|
354
|
+
const parsed = parseTestOutput(trimmedOutput);
|
|
355
|
+
if (parsed.isTestOutput && parsed.data) {
|
|
356
|
+
// Return structured test data as JSON for the renderer
|
|
357
|
+
return {
|
|
358
|
+
success: true,
|
|
359
|
+
output: JSON.stringify(parsed.data),
|
|
360
|
+
data: { type: 'test-results', framework: parsed.data.framework },
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
success: true,
|
|
366
|
+
output: trimmedOutput,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
371
|
+
return {
|
|
372
|
+
success: false,
|
|
373
|
+
error: `Command failed: ${errorMessage}`,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Checkpoint files that would be affected by destructive commands.
|
|
379
|
+
* Parses command arguments to identify file targets of rm, mv, etc.
|
|
380
|
+
*/
|
|
381
|
+
checkpointDestructiveTargets(command) {
|
|
382
|
+
const DESTRUCTIVE_CMDS = new Set(['rm', 'mv', 'cp', 'truncate']);
|
|
383
|
+
try {
|
|
384
|
+
const parsed = parseBashCommand(command);
|
|
385
|
+
const checkpointMgr = getCheckpointManager();
|
|
386
|
+
for (const cmd of parsed.commands) {
|
|
387
|
+
if (DESTRUCTIVE_CMDS.has(cmd.command)) {
|
|
388
|
+
// Extract file arguments (skip flags starting with -)
|
|
389
|
+
const fileArgs = cmd.args.filter(a => !a.startsWith('-'));
|
|
390
|
+
for (const fileArg of fileArgs) {
|
|
391
|
+
const resolved = fileArg.startsWith('/')
|
|
392
|
+
? fileArg
|
|
393
|
+
: `${this.currentDirectory}/${fileArg}`;
|
|
394
|
+
try {
|
|
395
|
+
checkpointMgr.checkpointBeforeEdit(resolved);
|
|
396
|
+
auditLogger.logFileOperation({
|
|
397
|
+
action: 'file_edit',
|
|
398
|
+
target: resolved,
|
|
399
|
+
decision: 'allow',
|
|
400
|
+
source: 'bash-checkpoint',
|
|
401
|
+
details: `Pre-checkpoint before ${cmd.command}`,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
// File might not exist or not be readable — skip
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
// Parsing failed — skip checkpointing (command already validated)
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Enable or disable self-healing
|
|
417
|
+
*/
|
|
418
|
+
setSelfHealing(enabled) {
|
|
419
|
+
this.selfHealingEnabled = enabled;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Check if self-healing is enabled
|
|
423
|
+
*/
|
|
424
|
+
isSelfHealingEnabled() {
|
|
425
|
+
return this.selfHealingEnabled;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Get self-healing engine for configuration
|
|
429
|
+
*/
|
|
430
|
+
getSelfHealingEngine() {
|
|
431
|
+
return this.selfHealingEngine;
|
|
432
|
+
}
|
|
433
|
+
getCurrentDirectory() {
|
|
434
|
+
return this.currentDirectory;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Escape shell argument to prevent command injection
|
|
438
|
+
*/
|
|
439
|
+
escapeShellArg(arg) {
|
|
440
|
+
// Use single quotes and escape any single quotes in the string
|
|
441
|
+
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* List files in a directory (wrapper for `ls -la`)
|
|
445
|
+
*
|
|
446
|
+
* @param directory - Directory path to list (default: current directory)
|
|
447
|
+
* @returns Formatted directory listing or error
|
|
448
|
+
*/
|
|
449
|
+
async listFiles(directory = '.') {
|
|
450
|
+
// Validate input with schema
|
|
451
|
+
const validation = validateWithSchema(bashToolSchemas.listFiles, { directory }, 'listFiles');
|
|
452
|
+
if (!validation.valid) {
|
|
453
|
+
return {
|
|
454
|
+
success: false,
|
|
455
|
+
error: `Invalid input: ${validation.error}`,
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
const safeDir = sanitizeForShell(directory);
|
|
459
|
+
return this.execute(`ls -la ${safeDir}`);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Find files matching a pattern (wrapper for `find -name -type f`)
|
|
463
|
+
*
|
|
464
|
+
* @param pattern - Glob pattern to match (e.g., "*.ts", "package.json")
|
|
465
|
+
* @param directory - Directory to search in (default: current directory)
|
|
466
|
+
* @returns List of matching file paths or error
|
|
467
|
+
*/
|
|
468
|
+
async findFiles(pattern, directory = '.') {
|
|
469
|
+
// Validate input with schema
|
|
470
|
+
const validation = validateWithSchema(bashToolSchemas.findFiles, { pattern, directory }, 'findFiles');
|
|
471
|
+
if (!validation.valid) {
|
|
472
|
+
return {
|
|
473
|
+
success: false,
|
|
474
|
+
error: `Invalid input: ${validation.error}`,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
const safeDir = sanitizeForShell(directory);
|
|
478
|
+
const safePattern = sanitizeForShell(pattern);
|
|
479
|
+
return this.execute(`find ${safeDir} -name ${safePattern} -type f`);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Search for a pattern in files using ripgrep
|
|
483
|
+
*
|
|
484
|
+
* Uses @vscode/ripgrep for ultra-fast searching. Results are limited
|
|
485
|
+
* to 100 matches for performance.
|
|
486
|
+
*
|
|
487
|
+
* @param pattern - Regex pattern to search for
|
|
488
|
+
* @param files - File or directory to search in (default: current directory)
|
|
489
|
+
* @returns Matching lines with file paths and line numbers, or error
|
|
490
|
+
*/
|
|
491
|
+
async grep(pattern, files = '.') {
|
|
492
|
+
// Validate input with schema
|
|
493
|
+
const validation = validateWithSchema(bashToolSchemas.grep, { pattern, files }, 'grep');
|
|
494
|
+
if (!validation.valid) {
|
|
495
|
+
return {
|
|
496
|
+
success: false,
|
|
497
|
+
error: `Invalid input: ${validation.error}`,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
// Use ripgrep for ultra-fast searching
|
|
501
|
+
return new Promise((resolve) => {
|
|
502
|
+
const args = [
|
|
503
|
+
'--no-heading',
|
|
504
|
+
'--line-number',
|
|
505
|
+
'--color', 'never',
|
|
506
|
+
'--max-count', '100', // Limit results for performance
|
|
507
|
+
pattern,
|
|
508
|
+
files
|
|
509
|
+
];
|
|
510
|
+
const rg = spawn(rgPath, args, {
|
|
511
|
+
cwd: this.currentDirectory,
|
|
512
|
+
env: getFilteredEnv(),
|
|
513
|
+
});
|
|
514
|
+
let stdout = '';
|
|
515
|
+
let stderr = '';
|
|
516
|
+
rg.stdout?.on('data', (data) => {
|
|
517
|
+
if (stdout.length < 5_000_000)
|
|
518
|
+
stdout += data.toString();
|
|
519
|
+
});
|
|
520
|
+
rg.stderr?.on('data', (data) => {
|
|
521
|
+
if (stderr.length < 100_000)
|
|
522
|
+
stderr += data.toString();
|
|
523
|
+
});
|
|
524
|
+
rg.on('close', (code) => {
|
|
525
|
+
// ripgrep returns 1 if no matches found (not an error)
|
|
526
|
+
if (code === 0 || code === 1) {
|
|
527
|
+
resolve({
|
|
528
|
+
success: true,
|
|
529
|
+
output: stdout || 'No matches found',
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
resolve({
|
|
534
|
+
success: false,
|
|
535
|
+
error: stderr || `ripgrep exited with code ${code}`,
|
|
536
|
+
output: stdout,
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
rg.on('error', (error) => {
|
|
541
|
+
resolve({
|
|
542
|
+
success: false,
|
|
543
|
+
error: `ripgrep error: ${error.message}`,
|
|
544
|
+
});
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=bash-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-tool.js","sourceRoot":"","sources":["../../../src/tools/bash/bash-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command validation and environment filtering for BashTool.
|
|
3
|
+
*
|
|
4
|
+
* Contains:
|
|
5
|
+
* - extractBaseCommand: Parses the base command from a shell string
|
|
6
|
+
* - hasShellBypassFeatures: Detects shell features that could bypass validation
|
|
7
|
+
* - validateCommand: Full security validation pipeline
|
|
8
|
+
* - getFilteredEnv: Environment variable filtering for child processes
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Extract the base command from a command string
|
|
12
|
+
* Handles paths, env var prefixes, and common shell constructs
|
|
13
|
+
*/
|
|
14
|
+
export declare function extractBaseCommand(command: string): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Check if command uses shell features that could bypass validation
|
|
17
|
+
*/
|
|
18
|
+
export declare function hasShellBypassFeatures(command: string): {
|
|
19
|
+
bypass: boolean;
|
|
20
|
+
reason?: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Validate command for dangerous patterns
|
|
24
|
+
*
|
|
25
|
+
* Security checks performed (in order):
|
|
26
|
+
* 1. Control characters - blocks terminal manipulation
|
|
27
|
+
* 2. ANSI escape sequences - blocks display manipulation
|
|
28
|
+
* 3. Shell bypass features - blocks process substitution, here-strings, etc.
|
|
29
|
+
* 4. Base command blocklist - blocks known dangerous commands
|
|
30
|
+
* 5. Blocked command patterns - blocks known dangerous patterns
|
|
31
|
+
* 6. Protected paths - blocks access to sensitive directories
|
|
32
|
+
*
|
|
33
|
+
* Note: Sandbox manager validation is performed separately by the caller
|
|
34
|
+
* since it requires instance state.
|
|
35
|
+
*/
|
|
36
|
+
export declare function validateCommand(command: string): {
|
|
37
|
+
valid: boolean;
|
|
38
|
+
reason?: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Filter environment variables to only include safe ones
|
|
42
|
+
* This prevents credential leakage to child processes
|
|
43
|
+
*
|
|
44
|
+
* Security measures:
|
|
45
|
+
* - Only allowlisted variable names are passed through
|
|
46
|
+
* - Values containing shell metacharacters are sanitized
|
|
47
|
+
* - Values that look like secrets are excluded
|
|
48
|
+
*/
|
|
49
|
+
export declare function getFilteredEnv(): Record<string, string>;
|