@qduc/term2 0.8.0 → 0.9.0
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 +397 -0
- package/dist/agent.d.ts +1 -9
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +2 -127
- package/dist/agent.js.map +1 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +21 -12
- package/dist/app.js.map +1 -1
- package/dist/commands/effort-command.d.ts +2 -2
- package/dist/commands/effort-command.d.ts.map +1 -1
- package/dist/commands/effort-command.js +3 -3
- package/dist/commands/effort-command.js.map +1 -1
- package/dist/commands/guarded-settings-command.d.ts +2 -2
- package/dist/commands/guarded-settings-command.d.ts.map +1 -1
- package/dist/commands/guarded-settings-command.js +2 -2
- package/dist/commands/guarded-settings-command.js.map +1 -1
- package/dist/commands/model-command.d.ts +2 -2
- package/dist/commands/model-command.d.ts.map +1 -1
- package/dist/commands/model-command.js +2 -2
- package/dist/commands/model-command.js.map +1 -1
- package/dist/commands/skills-command.d.ts +1 -1
- package/dist/commands/skills-command.d.ts.map +1 -1
- package/dist/commands/skills-command.js +1 -1
- package/dist/commands/skills-command.js.map +1 -1
- package/dist/commands/undo-command.d.ts +2 -2
- package/dist/commands/undo-command.d.ts.map +1 -1
- package/dist/commands/undo-command.js +2 -2
- package/dist/commands/undo-command.js.map +1 -1
- package/dist/components/Input/insertions.d.ts +2 -0
- package/dist/components/Input/insertions.d.ts.map +1 -1
- package/dist/components/Input/insertions.js +6 -3
- package/dist/components/Input/insertions.js.map +1 -1
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +26 -12
- package/dist/components/InputBox.js.map +1 -1
- package/dist/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/components/MarkdownRenderer.js +2 -1
- package/dist/components/MarkdownRenderer.js.map +1 -1
- package/dist/components/layout/BottomArea.d.ts.map +1 -1
- package/dist/components/layout/BottomArea.js +2 -0
- package/dist/components/layout/BottomArea.js.map +1 -1
- package/dist/components/layout/DiffView.d.ts.map +1 -1
- package/dist/components/layout/DiffView.js +33 -26
- package/dist/components/layout/DiffView.js.map +1 -1
- package/dist/components/layout/StatusBar.d.ts.map +1 -1
- package/dist/components/layout/StatusBar.js +6 -3
- package/dist/components/layout/StatusBar.js.map +1 -1
- package/dist/components/message/CommandMessage.d.ts.map +1 -1
- package/dist/components/message/CommandMessage.js +6 -4
- package/dist/components/message/CommandMessage.js.map +1 -1
- package/dist/components/message/command-message-helpers.d.ts +1 -1
- package/dist/components/message/command-message-helpers.d.ts.map +1 -1
- package/dist/components/message/command-message-helpers.js +8 -7
- package/dist/components/message/command-message-helpers.js.map +1 -1
- package/dist/components/prompt/ApprovalPrompt.d.ts.map +1 -1
- package/dist/components/prompt/ApprovalPrompt.js +101 -14
- package/dist/components/prompt/ApprovalPrompt.js.map +1 -1
- package/dist/context/InputContext.d.ts +4 -0
- package/dist/context/InputContext.d.ts.map +1 -1
- package/dist/context/InputContext.js +5 -1
- package/dist/context/InputContext.js.map +1 -1
- package/dist/contracts/conversation.d.ts +22 -0
- package/dist/contracts/conversation.d.ts.map +1 -1
- package/dist/contracts/conversation.js +11 -1
- package/dist/contracts/conversation.js.map +1 -1
- package/dist/hooks/use-app-commands.d.ts +2 -2
- package/dist/hooks/use-app-commands.d.ts.map +1 -1
- package/dist/hooks/use-app-commands.js +7 -7
- package/dist/hooks/use-app-commands.js.map +1 -1
- package/dist/hooks/use-conversation.d.ts.map +1 -1
- package/dist/hooks/use-conversation.js +13 -8
- package/dist/hooks/use-conversation.js.map +1 -1
- package/dist/hooks/use-handoff-flow.d.ts +3 -2
- package/dist/hooks/use-handoff-flow.d.ts.map +1 -1
- package/dist/hooks/use-handoff-flow.js +28 -18
- package/dist/hooks/use-handoff-flow.js.map +1 -1
- package/dist/hooks/use-mode-handlers.js +1 -2
- package/dist/hooks/use-mode-handlers.js.map +1 -1
- package/dist/hooks/use-model-selection.d.ts.map +1 -1
- package/dist/hooks/use-model-selection.js +6 -2
- package/dist/hooks/use-model-selection.js.map +1 -1
- package/dist/hooks/use-path-completion.d.ts.map +1 -1
- package/dist/hooks/use-path-completion.js +4 -2
- package/dist/hooks/use-path-completion.js.map +1 -1
- package/dist/hooks/use-pending-turn-guards.d.ts +2 -2
- package/dist/hooks/use-pending-turn-guards.d.ts.map +1 -1
- package/dist/hooks/use-pending-turn-guards.js +8 -8
- package/dist/hooks/use-pending-turn-guards.js.map +1 -1
- package/dist/hooks/use-provider-selection.js +19 -18
- package/dist/hooks/use-provider-selection.js.map +1 -1
- package/dist/hooks/use-selection.d.ts.map +1 -1
- package/dist/hooks/use-selection.js +5 -1
- package/dist/hooks/use-selection.js.map +1 -1
- package/dist/hooks/use-setting.d.ts.map +1 -1
- package/dist/hooks/use-setting.js +3 -5
- package/dist/hooks/use-setting.js.map +1 -1
- package/dist/hooks/use-settings-completion.d.ts.map +1 -1
- package/dist/hooks/use-settings-completion.js +19 -7
- package/dist/hooks/use-settings-completion.js.map +1 -1
- package/dist/hooks/use-settings-value-completion.d.ts.map +1 -1
- package/dist/hooks/use-settings-value-completion.js +13 -2
- package/dist/hooks/use-settings-value-completion.js.map +1 -1
- package/dist/hooks/use-shell-mode.d.ts +2 -2
- package/dist/hooks/use-shell-mode.d.ts.map +1 -1
- package/dist/hooks/use-shell-mode.js +5 -3
- package/dist/hooks/use-shell-mode.js.map +1 -1
- package/dist/hooks/use-skill-selection.js +3 -3
- package/dist/hooks/use-skill-selection.js.map +1 -1
- package/dist/hooks/use-slash-commands.js +3 -3
- package/dist/hooks/use-slash-commands.js.map +1 -1
- package/dist/hooks/use-terminal-width.js +2 -2
- package/dist/hooks/use-terminal-width.js.map +1 -1
- package/dist/hooks/use-undo-selection.d.ts.map +1 -1
- package/dist/hooks/use-undo-selection.js +3 -1
- package/dist/hooks/use-undo-selection.js.map +1 -1
- package/dist/lib/agent-chat-service.js +2 -2
- package/dist/lib/agent-chat-service.js.map +1 -1
- package/dist/lib/agent-run-orchestrator.js +1 -1
- package/dist/lib/agent-run-orchestrator.js.map +1 -1
- package/dist/lib/subagent-bridge.d.ts.map +1 -1
- package/dist/lib/subagent-bridge.js +15 -3
- package/dist/lib/subagent-bridge.js.map +1 -1
- package/dist/non-interactive.d.ts.map +1 -1
- package/dist/non-interactive.js +0 -2
- package/dist/non-interactive.js.map +1 -1
- package/dist/prompts/anthropic.md +1 -0
- package/dist/prompts/codex.md +1 -0
- package/dist/prompts/gpt-5-modern.md +1 -0
- package/dist/prompts/gpt-5.5.md +1 -0
- package/dist/prompts/kimi.md +3 -1
- package/dist/prompts/prompt-constructor.js +2 -2
- package/dist/prompts/prompt-constructor.js.map +1 -1
- package/dist/prompts/prompt-constructor.ts +2 -2
- package/dist/prompts/subagent-delegation.js +1 -1
- package/dist/prompts/subagent-delegation.ts +1 -1
- package/dist/providers/codex-responses-model.d.ts.map +1 -1
- package/dist/providers/codex-responses-model.js +4 -3
- package/dist/providers/codex-responses-model.js.map +1 -1
- package/dist/providers/openai-compatible-middleware.js +1 -1
- package/dist/providers/openai-compatible-middleware.js.map +1 -1
- package/dist/providers/openai-compatible.provider.js +1 -1
- package/dist/providers/openai-compatible.provider.js.map +1 -1
- package/dist/scripts/eval-auto-approval/runner.js +1 -1
- package/dist/scripts/eval-auto-approval/runner.js.map +1 -1
- package/dist/services/approval/approval-flow-coordinator.d.ts.map +1 -1
- package/dist/services/approval/approval-flow-coordinator.js +41 -1
- package/dist/services/approval/approval-flow-coordinator.js.map +1 -1
- package/dist/services/approval/shell-sandbox-approval.d.ts +2 -0
- package/dist/services/approval/shell-sandbox-approval.d.ts.map +1 -0
- package/dist/services/approval/shell-sandbox-approval.js +7 -0
- package/dist/services/approval/shell-sandbox-approval.js.map +1 -0
- package/dist/services/approval/tool-approval-batch-coordinator.d.ts.map +1 -1
- package/dist/services/approval/tool-approval-batch-coordinator.js +4 -2
- package/dist/services/approval/tool-approval-batch-coordinator.js.map +1 -1
- package/dist/services/conversation/conversation-replay.js +1 -1
- package/dist/services/conversation/conversation-replay.js.map +1 -1
- package/dist/services/conversation/conversation-result-builder.d.ts +2 -0
- package/dist/services/conversation/conversation-result-builder.d.ts.map +1 -1
- package/dist/services/conversation/conversation-result-builder.js +31 -2
- package/dist/services/conversation/conversation-result-builder.js.map +1 -1
- package/dist/services/logging/logging-service.js +2 -2
- package/dist/services/logging/logging-service.js.map +1 -1
- package/dist/services/rtk-service.d.ts.map +1 -1
- package/dist/services/rtk-service.js +6 -2
- package/dist/services/rtk-service.js.map +1 -1
- package/dist/services/session/session-input-planner.d.ts.map +1 -1
- package/dist/services/session/session-input-planner.js +22 -2
- package/dist/services/session/session-input-planner.js.map +1 -1
- package/dist/services/session/session-tool-tracker.d.ts +13 -0
- package/dist/services/session/session-tool-tracker.d.ts.map +1 -1
- package/dist/services/session/session-tool-tracker.js +18 -3
- package/dist/services/session/session-tool-tracker.js.map +1 -1
- package/dist/services/session/test-helpers/conversation-session-fixtures.d.ts +12 -0
- package/dist/services/session/test-helpers/conversation-session-fixtures.d.ts.map +1 -0
- package/dist/services/session/test-helpers/conversation-session-fixtures.js +29 -0
- package/dist/services/session/test-helpers/conversation-session-fixtures.js.map +1 -0
- package/dist/services/settings/settings-merger.d.ts.map +1 -1
- package/dist/services/settings/settings-merger.js +7 -5
- package/dist/services/settings/settings-merger.js.map +1 -1
- package/dist/services/settings/settings-persistence.js +1 -1
- package/dist/services/settings/settings-persistence.js.map +1 -1
- package/dist/services/settings/settings-schema.d.ts +25 -0
- package/dist/services/settings/settings-schema.d.ts.map +1 -1
- package/dist/services/settings/settings-schema.js +23 -2
- package/dist/services/settings/settings-schema.js.map +1 -1
- package/dist/services/settings/settings-sources.d.ts.map +1 -1
- package/dist/services/settings/settings-sources.js +5 -0
- package/dist/services/settings/settings-sources.js.map +1 -1
- package/dist/services/skills/skills-service.d.ts.map +1 -1
- package/dist/services/skills/skills-service.js +3 -10
- package/dist/services/skills/skills-service.js.map +1 -1
- package/dist/services/subagents/role-loader.js +3 -3
- package/dist/services/subagents/role-loader.js.map +1 -1
- package/dist/services/subagents/test-helpers/subagent-manager-fixtures.d.ts +35 -0
- package/dist/services/subagents/test-helpers/subagent-manager-fixtures.d.ts.map +1 -0
- package/dist/services/subagents/test-helpers/subagent-manager-fixtures.js +174 -0
- package/dist/services/subagents/test-helpers/subagent-manager-fixtures.js.map +1 -0
- package/dist/services/subagents/tool-policy.d.ts.map +1 -1
- package/dist/services/subagents/tool-policy.js +18 -0
- package/dist/services/subagents/tool-policy.js.map +1 -1
- package/dist/services/tool-execution-ledger.d.ts +41 -0
- package/dist/services/tool-execution-ledger.d.ts.map +1 -1
- package/dist/services/tool-execution-ledger.js +113 -0
- package/dist/services/tool-execution-ledger.js.map +1 -1
- package/dist/tools/agent/activate-skill.js +1 -1
- package/dist/tools/agent/activate-skill.js.map +1 -1
- package/dist/tools/agent/ask-user.d.ts.map +1 -1
- package/dist/tools/agent/ask-user.js +4 -15
- package/dist/tools/agent/ask-user.js.map +1 -1
- package/dist/tools/agent/run-subagent.d.ts.map +1 -1
- package/dist/tools/agent/run-subagent.js +2 -5
- package/dist/tools/agent/run-subagent.js.map +1 -1
- package/dist/tools/file/apply-patch.js +2 -2
- package/dist/tools/file/apply-patch.js.map +1 -1
- package/dist/tools/file/create-file.d.ts.map +1 -1
- package/dist/tools/file/create-file.js +2 -5
- package/dist/tools/file/create-file.js.map +1 -1
- package/dist/tools/file/find-files.d.ts.map +1 -1
- package/dist/tools/file/find-files.js +21 -18
- package/dist/tools/file/find-files.js.map +1 -1
- package/dist/tools/file/read-file.d.ts.map +1 -1
- package/dist/tools/file/read-file.js +17 -3
- package/dist/tools/file/read-file.js.map +1 -1
- package/dist/tools/file/search-replace.d.ts.map +1 -1
- package/dist/tools/file/search-replace.js +2 -3
- package/dist/tools/file/search-replace.js.map +1 -1
- package/dist/tools/format-helpers.js +0 -2
- package/dist/tools/format-helpers.js.map +1 -1
- package/dist/tools/languages/csharp.js +1 -1
- package/dist/tools/languages/csharp.js.map +1 -1
- package/dist/tools/languages/java.js +1 -1
- package/dist/tools/languages/java.js.map +1 -1
- package/dist/tools/system/code-context.d.ts.map +1 -1
- package/dist/tools/system/code-context.js +28 -10
- package/dist/tools/system/code-context.js.map +1 -1
- package/dist/tools/system/grep.d.ts.map +1 -1
- package/dist/tools/system/grep.js +6 -14
- package/dist/tools/system/grep.js.map +1 -1
- package/dist/tools/system/shell.d.ts +9 -1
- package/dist/tools/system/shell.d.ts.map +1 -1
- package/dist/tools/system/shell.js +115 -7
- package/dist/tools/system/shell.js.map +1 -1
- package/dist/tools/utils.d.ts +4 -0
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +13 -0
- package/dist/tools/utils.js.map +1 -1
- package/dist/tools/web/web-fetch.js +1 -1
- package/dist/tools/web/web-fetch.js.map +1 -1
- package/dist/utils/conversation/conversation-event-handler.js +1 -1
- package/dist/utils/conversation/conversation-event-handler.js.map +1 -1
- package/dist/utils/conversation/test-helpers/event-handler-fixtures.d.ts +31 -0
- package/dist/utils/conversation/test-helpers/event-handler-fixtures.d.ts.map +1 -0
- package/dist/utils/conversation/test-helpers/event-handler-fixtures.js +42 -0
- package/dist/utils/conversation/test-helpers/event-handler-fixtures.js.map +1 -0
- package/dist/utils/output/output-trim.d.ts +1 -1
- package/dist/utils/output/output-trim.js +1 -1
- package/dist/utils/project-tree.d.ts +7 -12
- package/dist/utils/project-tree.d.ts.map +1 -1
- package/dist/utils/project-tree.js +184 -83
- package/dist/utils/project-tree.js.map +1 -1
- package/dist/utils/settings-command.d.ts +2 -2
- package/dist/utils/settings-command.d.ts.map +1 -1
- package/dist/utils/settings-command.js +2 -2
- package/dist/utils/settings-command.js.map +1 -1
- package/dist/utils/shell/command-safety/find-helpers.js +1 -1
- package/dist/utils/shell/command-safety/find-helpers.js.map +1 -1
- package/dist/utils/shell/command-safety/handlers/git-handler.js +1 -1
- package/dist/utils/shell/command-safety/handlers/git-handler.js.map +1 -1
- package/dist/utils/shell/execute-shell.d.ts +2 -0
- package/dist/utils/shell/execute-shell.d.ts.map +1 -1
- package/dist/utils/shell/execute-shell.js +9 -6
- package/dist/utils/shell/execute-shell.js.map +1 -1
- package/dist/utils/shell/sandbox/denied-read-detector.d.ts +39 -0
- package/dist/utils/shell/sandbox/denied-read-detector.d.ts.map +1 -0
- package/dist/utils/shell/sandbox/denied-read-detector.js +250 -0
- package/dist/utils/shell/sandbox/denied-read-detector.js.map +1 -0
- package/dist/utils/shell/sandbox/denied-read-stores.d.ts +74 -0
- package/dist/utils/shell/sandbox/denied-read-stores.d.ts.map +1 -0
- package/dist/utils/shell/sandbox/denied-read-stores.js +166 -0
- package/dist/utils/shell/sandbox/denied-read-stores.js.map +1 -0
- package/dist/utils/shell/sandbox/sandbox-env.d.ts +3 -0
- package/dist/utils/shell/sandbox/sandbox-env.d.ts.map +1 -0
- package/dist/utils/shell/sandbox/sandbox-env.js +31 -0
- package/dist/utils/shell/sandbox/sandbox-env.js.map +1 -0
- package/dist/utils/shell/sandbox/sandbox-policy.d.ts +41 -0
- package/dist/utils/shell/sandbox/sandbox-policy.d.ts.map +1 -0
- package/dist/utils/shell/sandbox/sandbox-policy.js +217 -0
- package/dist/utils/shell/sandbox/sandbox-policy.js.map +1 -0
- package/dist/utils/shell/sandbox/shell-sandbox-runner.d.ts +18 -0
- package/dist/utils/shell/sandbox/shell-sandbox-runner.d.ts.map +1 -0
- package/dist/utils/shell/sandbox/shell-sandbox-runner.js +58 -0
- package/dist/utils/shell/sandbox/shell-sandbox-runner.js.map +1 -0
- package/dist/utils/shell/shell-output.d.ts.map +1 -1
- package/dist/utils/shell/shell-output.js +8 -6
- package/dist/utils/shell/shell-output.js.map +1 -1
- package/dist/utils/shell/temp-dir.d.ts +2 -0
- package/dist/utils/shell/temp-dir.d.ts.map +1 -0
- package/dist/utils/shell/temp-dir.js +38 -0
- package/dist/utils/shell/temp-dir.js.map +1 -0
- package/dist/utils/skill-discovery-paths.d.ts +5 -0
- package/dist/utils/skill-discovery-paths.d.ts.map +1 -0
- package/dist/utils/skill-discovery-paths.js +18 -0
- package/dist/utils/skill-discovery-paths.js.map +1 -0
- package/package.json +10 -16
- package/readme.md +0 -887
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* In-memory, session-scoped store of denied-read info keyed by normalized command string.
|
|
5
|
+
*
|
|
6
|
+
* Lifecycle of an entry:
|
|
7
|
+
* 1. `execute` detects a denied read → `record(command, info)`.
|
|
8
|
+
* 2. The agent retries the same command; the approval-result builder calls `consume(command)` → returns the info
|
|
9
|
+
* (so the approval gate fires), then `stageForDescriptor(command, info)` re-stages it so the
|
|
10
|
+
* approval-result builder can attach `deniedRead` metadata to the ApprovalDescriptor.
|
|
11
|
+
* 3. `consumeStaged(command)` is called by the approval flow to set the retry override and clear.
|
|
12
|
+
*/
|
|
13
|
+
export class DeniedReadStore {
|
|
14
|
+
#byCommand = new Map();
|
|
15
|
+
#stagedByDescriptorKey = new Map();
|
|
16
|
+
record(command, info) {
|
|
17
|
+
this.#byCommand.set(command, info);
|
|
18
|
+
}
|
|
19
|
+
consume(command) {
|
|
20
|
+
const info = this.#byCommand.get(command);
|
|
21
|
+
if (info) {
|
|
22
|
+
this.#byCommand.delete(command);
|
|
23
|
+
return info;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
peek(command) {
|
|
28
|
+
return this.#byCommand.get(command) ?? null;
|
|
29
|
+
}
|
|
30
|
+
has(command) {
|
|
31
|
+
return this.#byCommand.has(command);
|
|
32
|
+
}
|
|
33
|
+
stageForDescriptor(descriptorKey, info) {
|
|
34
|
+
this.#stagedByDescriptorKey.set(descriptorKey, info);
|
|
35
|
+
}
|
|
36
|
+
consumeStaged(descriptorKey) {
|
|
37
|
+
const info = this.#stagedByDescriptorKey.get(descriptorKey);
|
|
38
|
+
if (info) {
|
|
39
|
+
this.#stagedByDescriptorKey.delete(descriptorKey);
|
|
40
|
+
return info;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
clear() {
|
|
45
|
+
this.#byCommand.clear();
|
|
46
|
+
this.#stagedByDescriptorKey.clear();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* In-memory, per-command store of execution overrides. Set at approval-decision time;
|
|
51
|
+
* consumed and cleared by `execute` when the SDK resumes the approved tool call.
|
|
52
|
+
*/
|
|
53
|
+
export class ExecutionOverrideStore {
|
|
54
|
+
#byCommand = new Map();
|
|
55
|
+
set(command, override) {
|
|
56
|
+
this.#byCommand.set(command, override);
|
|
57
|
+
}
|
|
58
|
+
consume(command) {
|
|
59
|
+
const override = this.#byCommand.get(command);
|
|
60
|
+
if (override) {
|
|
61
|
+
this.#byCommand.delete(command);
|
|
62
|
+
return override;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
clear() {
|
|
67
|
+
this.#byCommand.clear();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const PROJECT_CONFIG_DIR = '.term2';
|
|
71
|
+
const PROJECT_CONFIG_FILE = 'sandbox-allow-paths.json';
|
|
72
|
+
/**
|
|
73
|
+
* Persistent, project-scoped store of remembered allow-read paths.
|
|
74
|
+
* Stored at `<workspaceRoot>/.term2/sandbox-allow-paths.json`.
|
|
75
|
+
*
|
|
76
|
+
* Paths are realpath-normalized and deduplicated before persistence.
|
|
77
|
+
* A separate, dedicated store (not the global settings system) so that remembered
|
|
78
|
+
* paths stay scoped to the workspace where they were approved.
|
|
79
|
+
*/
|
|
80
|
+
export class ProjectSandboxAllowReadStore {
|
|
81
|
+
#workspaceRoot;
|
|
82
|
+
#log;
|
|
83
|
+
#fs;
|
|
84
|
+
constructor(workspaceRoot, fsImpl, log) {
|
|
85
|
+
this.#workspaceRoot = workspaceRoot;
|
|
86
|
+
this.#fs = fsImpl ?? fs;
|
|
87
|
+
this.#log = log;
|
|
88
|
+
}
|
|
89
|
+
get #configPath() {
|
|
90
|
+
return path.join(this.#workspaceRoot, PROJECT_CONFIG_DIR, PROJECT_CONFIG_FILE);
|
|
91
|
+
}
|
|
92
|
+
load() {
|
|
93
|
+
try {
|
|
94
|
+
if (!this.#fs.existsSync(this.#configPath))
|
|
95
|
+
return [];
|
|
96
|
+
const raw = this.#fs.readFileSync(this.#configPath, 'utf8');
|
|
97
|
+
const parsed = JSON.parse(raw);
|
|
98
|
+
if (!parsed || !Array.isArray(parsed.allowReadExtra))
|
|
99
|
+
return [];
|
|
100
|
+
return this.#normalize(parsed.allowReadExtra);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
// Corrupt or unreadable config: fail safe with an empty list.
|
|
104
|
+
this.#log?.warn('Failed to read project sandbox-allow-paths; returning empty list', {
|
|
105
|
+
error: error instanceof Error ? error.message : String(error),
|
|
106
|
+
});
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
append(filePath) {
|
|
111
|
+
const normalized = this.#normalizeOne(filePath);
|
|
112
|
+
const current = this.load();
|
|
113
|
+
if (current.includes(normalized))
|
|
114
|
+
return;
|
|
115
|
+
const next = [...current, normalized];
|
|
116
|
+
this.#write(next);
|
|
117
|
+
}
|
|
118
|
+
#write(paths) {
|
|
119
|
+
const dir = path.dirname(this.#configPath);
|
|
120
|
+
this.#fs.mkdirSync(dir, { recursive: true });
|
|
121
|
+
const payload = { version: 1, allowReadExtra: paths };
|
|
122
|
+
this.#fs.writeFileSync(this.#configPath, JSON.stringify(payload, null, 2) + '\n', 'utf8');
|
|
123
|
+
}
|
|
124
|
+
#normalize(paths) {
|
|
125
|
+
return Array.from(new Set(paths.map((p) => this.#normalizeOne(p))));
|
|
126
|
+
}
|
|
127
|
+
#normalizeOne(filePath) {
|
|
128
|
+
try {
|
|
129
|
+
return this.#fs.realpathSync(filePath);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return path.resolve(filePath);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Module-level singletons shared between the shell tool and the approval flow.
|
|
138
|
+
* A conversation is single-threaded in this CLI, so entries are consumed in order.
|
|
139
|
+
* Each entry is one-shot (consumed on use), so no cross-turn contamination occurs.
|
|
140
|
+
*/
|
|
141
|
+
export const deniedReadStore = new DeniedReadStore();
|
|
142
|
+
export const executionOverrideStore = new ExecutionOverrideStore();
|
|
143
|
+
let projectAllowReadStore = null;
|
|
144
|
+
let projectAllowReadStoreRoot = null;
|
|
145
|
+
/**
|
|
146
|
+
* Returns the project-scoped allow-read store for the given workspace root.
|
|
147
|
+
* The store is lazily created and re-created if the workspace root changes
|
|
148
|
+
* (unlikely in practice — the launch cwd is stable for the process).
|
|
149
|
+
*/
|
|
150
|
+
export function getProjectAllowReadStore(workspaceRoot) {
|
|
151
|
+
if (!projectAllowReadStore || projectAllowReadStoreRoot !== workspaceRoot) {
|
|
152
|
+
projectAllowReadStore = new ProjectSandboxAllowReadStore(workspaceRoot);
|
|
153
|
+
projectAllowReadStoreRoot = workspaceRoot;
|
|
154
|
+
}
|
|
155
|
+
return projectAllowReadStore;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Test-only: reset all module-level singletons. Not for production use.
|
|
159
|
+
*/
|
|
160
|
+
export function resetSandboxDeniedReadStoresForTest() {
|
|
161
|
+
deniedReadStore.clear();
|
|
162
|
+
executionOverrideStore.clear();
|
|
163
|
+
projectAllowReadStore = null;
|
|
164
|
+
projectAllowReadStoreRoot = null;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=denied-read-stores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"denied-read-stores.js","sourceRoot":"","sources":["../../../../source/utils/shell/sandbox/denied-read-stores.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-env.d.ts","sourceRoot":"","sources":["../../../../source/utils/shell/sandbox/sandbox-env.ts"],"names":[],"mappings":"AAMA,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAehD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAAC,UAAU,CAanG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const ALLOWED_EXACT_KEYS = new Set(['PATH', 'SHELL', 'TMPDIR', 'TEMP', 'TMP', 'TERM', 'HOME']);
|
|
2
|
+
function isAllowedKey(key) {
|
|
3
|
+
return ALLOWED_EXACT_KEYS.has(key) || key === 'LANG' || key.startsWith('LC_');
|
|
4
|
+
}
|
|
5
|
+
export function isSecretKey(key) {
|
|
6
|
+
return (/(^|_)API_KEY$/.test(key) ||
|
|
7
|
+
/(^|_)TOKEN$/.test(key) ||
|
|
8
|
+
/(^|_)SECRET$/.test(key) ||
|
|
9
|
+
key.startsWith('AWS_') ||
|
|
10
|
+
key.startsWith('GOOGLE_') ||
|
|
11
|
+
key.startsWith('GCP_') ||
|
|
12
|
+
key.startsWith('AZURE_') ||
|
|
13
|
+
key.startsWith('OPENAI_') ||
|
|
14
|
+
key.startsWith('ANTHROPIC_') ||
|
|
15
|
+
key === 'GITHUB_TOKEN' ||
|
|
16
|
+
key === 'SSH_AUTH_SOCK' ||
|
|
17
|
+
key === 'SSH_AGENT_PID');
|
|
18
|
+
}
|
|
19
|
+
export function createSandboxEnvironment(source = process.env) {
|
|
20
|
+
const env = {};
|
|
21
|
+
for (const [key, value] of Object.entries(source)) {
|
|
22
|
+
// Layer-1a backstop: redundant while the allowlist stays tiny; do not remove.
|
|
23
|
+
// It is the last line of defense inside Layer 1 if a secret-shaped key is ever allowlisted.
|
|
24
|
+
if (value === undefined || isSecretKey(key) || !isAllowedKey(key)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
env[key] = value;
|
|
28
|
+
}
|
|
29
|
+
return env;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=sandbox-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-env.js","sourceRoot":"","sources":["../../../../source/utils/shell/sandbox/sandbox-env.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/F,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,CACL,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;QACzB,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;QACxB,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QACtB,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QACzB,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QACtB,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;QACxB,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QACzB,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC;QAC5B,GAAG,KAAK,cAAc;QACtB,GAAG,KAAK,eAAe;QACvB,GAAG,KAAK,eAAe,CACxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,SAA4B,OAAO,CAAC,GAAG;IAC9E,MAAM,GAAG,GAAsB,EAAE,CAAC;IAElC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,8EAA8E;QAC9E,4FAA4F;QAC5F,IAAI,KAAK,KAAK,SAAS,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAClE,SAAS;QACX,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { SandboxRuntimeConfig } from '@anthropic-ai/sandbox-runtime';
|
|
2
|
+
export type SandboxReadPolicy = 'standard' | 'strict';
|
|
3
|
+
export type ShellSandboxMode = 'default' | 'unsandboxed';
|
|
4
|
+
export type SandboxAvailability = {
|
|
5
|
+
type: 'available';
|
|
6
|
+
} | {
|
|
7
|
+
type: 'disabled';
|
|
8
|
+
} | {
|
|
9
|
+
type: 'unsupported_platform';
|
|
10
|
+
reason: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'missing_dependency';
|
|
13
|
+
reason: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'initialization_failed';
|
|
16
|
+
reason: string;
|
|
17
|
+
};
|
|
18
|
+
export interface ShellSandboxRunner {
|
|
19
|
+
availability(): Promise<SandboxAvailability>;
|
|
20
|
+
wrap(command: string, options: {
|
|
21
|
+
cwd: string;
|
|
22
|
+
config?: SandboxRuntimeConfig;
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
command: string;
|
|
26
|
+
diagnostics?: string[];
|
|
27
|
+
}>;
|
|
28
|
+
cleanupAfterCommand?(): void | Promise<void>;
|
|
29
|
+
annotateFailure(command: string, stderr: string): string;
|
|
30
|
+
}
|
|
31
|
+
export interface CreateSandboxRuntimeConfigOptions {
|
|
32
|
+
readPolicy?: SandboxReadPolicy;
|
|
33
|
+
allowReadExtra?: string[];
|
|
34
|
+
cwd?: string;
|
|
35
|
+
env?: NodeJS.ProcessEnv;
|
|
36
|
+
onProtectedFiltered?: (filtered: readonly string[]) => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function isPathProtected(target: string, home: string): boolean;
|
|
39
|
+
export declare function createSandboxRuntimeConfig(options?: CreateSandboxRuntimeConfigOptions): SandboxRuntimeConfig;
|
|
40
|
+
export declare const SANDBOX_ESCAPE_INSTRUCTION = "Sandbox blocked this command. To request a one-shot escape, call shell again with sandbox=\"unsandboxed\"; user approval will be required.";
|
|
41
|
+
//# sourceMappingURL=sandbox-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-policy.d.ts","sourceRoot":"","sources":["../../../../source/utils/shell/sandbox/sandbox-policy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAI1E,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEtD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzD,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,YAAY,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC7C,IAAI,CACF,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,oBAAoB,CAAC;QAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACxD,mBAAmB,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1D;AAED,MAAM,WAAW,iCAAiC;IAChD,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7D;AAoFD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CA0BrE;AAED,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,iCAAsC,GAAG,oBAAoB,CA6GhH;AAED,eAAO,MAAM,0BAA0B,+IACqG,CAAC"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { SANDBOX_TEMP_DIR } from '../temp-dir.js';
|
|
5
|
+
import { isSecretKey } from './sandbox-env.js';
|
|
6
|
+
// Paths the sandbox must never allow writing to, regardless of where term2
|
|
7
|
+
// was launched from. Two classes:
|
|
8
|
+
// - EXACT: only when cwd (resolved) is exactly the path
|
|
9
|
+
// - SUBTREE: when cwd (resolved) is the path or any descendant
|
|
10
|
+
// Both Linux and macOS paths are listed; the runtime drops non-existent paths
|
|
11
|
+
// per platform. This list is hardcoded on purpose: it is the floor of what
|
|
12
|
+
// "do not destroy the user's system" means, and giving users a setting to
|
|
13
|
+
// weaken it would defeat the point. See docs/sandbox-filesystem-read-hardening.md.
|
|
14
|
+
const EXACT_PROTECTED_WRITE_PATHS = [
|
|
15
|
+
'$HOME', // resolved via os.homedir() at use time
|
|
16
|
+
'/root',
|
|
17
|
+
'/var',
|
|
18
|
+
'/private/var',
|
|
19
|
+
'/mnt',
|
|
20
|
+
'/media',
|
|
21
|
+
'/srv',
|
|
22
|
+
'/opt',
|
|
23
|
+
];
|
|
24
|
+
const SUBTREE_PROTECTED_WRITE_PATHS = [
|
|
25
|
+
'/etc',
|
|
26
|
+
'/private/etc',
|
|
27
|
+
'/boot',
|
|
28
|
+
'/usr',
|
|
29
|
+
'/bin',
|
|
30
|
+
'/sbin',
|
|
31
|
+
'/lib',
|
|
32
|
+
'/lib64',
|
|
33
|
+
'/proc',
|
|
34
|
+
'/sys',
|
|
35
|
+
'/dev',
|
|
36
|
+
'/Library',
|
|
37
|
+
'/System',
|
|
38
|
+
'/System/Library',
|
|
39
|
+
];
|
|
40
|
+
// Common dev locations are intentionally NOT protected:
|
|
41
|
+
// /usr/local, /opt/homebrew, /tmp, /private/tmp
|
|
42
|
+
// These host Homebrew, local builds, temp worktrees, and cache dirs.
|
|
43
|
+
// Blocking them would break normal development workflows.
|
|
44
|
+
//
|
|
45
|
+
// Writable carve-outs that sit *inside* a SUBTREE-protected path. Without
|
|
46
|
+
// this, the `/usr` subtree guard below would remove `/usr/local` (and
|
|
47
|
+
// descendants like `/usr/local/src`) from allowWrite, contradicting the
|
|
48
|
+
// documented exception above. Checked before subtree protection.
|
|
49
|
+
const WRITABLE_SUBTREE_EXCEPTIONS = ['/usr/local'];
|
|
50
|
+
function expandHomePath(filePath, home) {
|
|
51
|
+
if (filePath === '~') {
|
|
52
|
+
return home;
|
|
53
|
+
}
|
|
54
|
+
if (filePath.startsWith('~/')) {
|
|
55
|
+
return path.join(home, filePath.slice(2));
|
|
56
|
+
}
|
|
57
|
+
return filePath;
|
|
58
|
+
}
|
|
59
|
+
function resolveCurrentRuntimeRoot(home) {
|
|
60
|
+
try {
|
|
61
|
+
const realExecPath = fs.realpathSync(process.execPath);
|
|
62
|
+
if (!realExecPath.startsWith(`${home}${path.sep}`)) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
return path.dirname(path.dirname(realExecPath));
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Normalize $HOME the same way workspaceRoot is (realpathSync) so the exact
|
|
72
|
+
// home guard still fires when os.homedir() is a symlink path and the launch
|
|
73
|
+
// cwd is $HOME: workspaceRoot becomes the real path while a bare
|
|
74
|
+
// path.resolve(home) would stay the symlink path. Best-effort: fall back to
|
|
75
|
+
// path.resolve when the home directory cannot be resolved.
|
|
76
|
+
function resolveHomePath(home) {
|
|
77
|
+
try {
|
|
78
|
+
return fs.realpathSync(home);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return path.resolve(home);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export function isPathProtected(target, home) {
|
|
85
|
+
const resolved = path.resolve(target);
|
|
86
|
+
const resolvedHome = resolveHomePath(home);
|
|
87
|
+
for (const protectedPath of EXACT_PROTECTED_WRITE_PATHS) {
|
|
88
|
+
if (resolved === path.resolve(protectedPath === '$HOME' ? resolvedHome : protectedPath)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Writable carve-outs inside a subtree-protected path take precedence over
|
|
93
|
+
// subtree protection so documented exceptions (e.g. /usr/local) stay writable.
|
|
94
|
+
for (const exceptionPath of WRITABLE_SUBTREE_EXCEPTIONS) {
|
|
95
|
+
const resolvedException = path.resolve(exceptionPath);
|
|
96
|
+
if (resolved === resolvedException || resolved.startsWith(resolvedException + path.sep)) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const protectedPath of SUBTREE_PROTECTED_WRITE_PATHS) {
|
|
101
|
+
const resolvedProtected = path.resolve(protectedPath);
|
|
102
|
+
if (resolved === resolvedProtected)
|
|
103
|
+
return true;
|
|
104
|
+
if (resolved.startsWith(resolvedProtected + path.sep))
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
export function createSandboxRuntimeConfig(options = {}) {
|
|
110
|
+
const home = os.homedir();
|
|
111
|
+
const readPolicy = options.readPolicy ?? 'standard';
|
|
112
|
+
const workspaceRoot = fs.realpathSync(options.cwd ?? process.cwd());
|
|
113
|
+
const tmpDir = SANDBOX_TEMP_DIR;
|
|
114
|
+
const appCacheDir = path.join(home, '.cache', 'term2-nodejs');
|
|
115
|
+
const rtkConfigDir = path.join(home, '.config', 'rtk');
|
|
116
|
+
const rtkDataDir = path.join(home, '.local', 'share', 'rtk');
|
|
117
|
+
const safeHomeReadPaths = [
|
|
118
|
+
path.join(home, '.gitconfig'),
|
|
119
|
+
path.join(home, '.config', 'git'),
|
|
120
|
+
path.join(home, '.npm'),
|
|
121
|
+
path.join(home, 'Library', 'pnpm'),
|
|
122
|
+
path.join(home, '.local', 'share', 'pnpm'),
|
|
123
|
+
path.join(home, '.pnpm-store'),
|
|
124
|
+
resolveCurrentRuntimeRoot(home),
|
|
125
|
+
].filter((filePath) => Boolean(filePath));
|
|
126
|
+
const credentialFiles = [
|
|
127
|
+
path.join(home, '.ssh'),
|
|
128
|
+
path.join(home, '.aws'),
|
|
129
|
+
path.join(home, '.azure'),
|
|
130
|
+
path.join(home, '.config', 'gcloud'),
|
|
131
|
+
path.join(home, '.docker'),
|
|
132
|
+
path.join(home, '.netrc'),
|
|
133
|
+
path.join(home, '.git-credentials'),
|
|
134
|
+
path.join(home, '.bash_history'),
|
|
135
|
+
path.join(home, '.zsh_history'),
|
|
136
|
+
path.join(home, '.npmrc'),
|
|
137
|
+
path.join(home, '.pypirc'),
|
|
138
|
+
path.join(home, '.kube'),
|
|
139
|
+
path.join(home, '.gnupg'),
|
|
140
|
+
path.join(home, '.config', 'gh'),
|
|
141
|
+
path.join(home, '.gem'),
|
|
142
|
+
path.join(home, '.gemrc'),
|
|
143
|
+
path.join(home, '.config', 'hub'),
|
|
144
|
+
path.join(home, '.docker', 'config.json'),
|
|
145
|
+
];
|
|
146
|
+
const defaultCredentialEnvVars = [
|
|
147
|
+
'AWS_ACCESS_KEY_ID',
|
|
148
|
+
'AWS_SECRET_ACCESS_KEY',
|
|
149
|
+
'AWS_SESSION_TOKEN',
|
|
150
|
+
'GOOGLE_APPLICATION_CREDENTIALS',
|
|
151
|
+
'GITHUB_TOKEN',
|
|
152
|
+
'OPENAI_API_KEY',
|
|
153
|
+
'ANTHROPIC_API_KEY',
|
|
154
|
+
'SSH_AUTH_SOCK',
|
|
155
|
+
'SSH_AGENT_PID',
|
|
156
|
+
];
|
|
157
|
+
// Env protection layering (see docs/sandbox-filesystem-read-hardening.md §5):
|
|
158
|
+
// Layer 1 (authoritative): createSandboxEnvironment() in sandbox-env.ts drops every env
|
|
159
|
+
// key not on a tiny allowlist of known-safe values (PATH, SHELL, TMPDIR, locale, …).
|
|
160
|
+
// Secrets never reach the child because they are not allowlisted, not because we named them.
|
|
161
|
+
// Layer 2 (defense-in-depth): credentials.envVars below unsets the same keys at the sandbox
|
|
162
|
+
// runtime level (bwrap --unsetenv / Seatbelt -u). It is intentionally small and
|
|
163
|
+
// auto-populated from the live env via isSecretKey so it stays exhaustive without hardcoding.
|
|
164
|
+
// It earns its keep only if Layer 1 ever regresses; do not treat it as the primary gate.
|
|
165
|
+
const presentSecretEnvVars = Object.keys(options.env ?? process.env).filter(isSecretKey);
|
|
166
|
+
const credentialEnvVars = Array.from(new Set([...defaultCredentialEnvVars, ...presentSecretEnvVars]));
|
|
167
|
+
const allowReadExtra = (options.allowReadExtra ?? []).map((filePath) => expandHomePath(filePath, home));
|
|
168
|
+
const denyRead = readPolicy === 'strict' ? [home, '/etc', '/var', '/root', '/private/var'] : credentialFiles;
|
|
169
|
+
const allowRead = readPolicy === 'strict'
|
|
170
|
+
? [
|
|
171
|
+
workspaceRoot,
|
|
172
|
+
tmpDir,
|
|
173
|
+
appCacheDir,
|
|
174
|
+
rtkConfigDir,
|
|
175
|
+
rtkDataDir,
|
|
176
|
+
...safeHomeReadPaths,
|
|
177
|
+
...allowReadExtra,
|
|
178
|
+
'/usr',
|
|
179
|
+
'/bin',
|
|
180
|
+
'/sbin',
|
|
181
|
+
'/lib',
|
|
182
|
+
'/lib64',
|
|
183
|
+
'/opt',
|
|
184
|
+
'/Library',
|
|
185
|
+
'/System/Library',
|
|
186
|
+
'/usr/local',
|
|
187
|
+
'/opt/homebrew',
|
|
188
|
+
]
|
|
189
|
+
: undefined;
|
|
190
|
+
const rawAllowWrite = [workspaceRoot, tmpDir];
|
|
191
|
+
const protectedFiltered = rawAllowWrite.filter((p) => isPathProtected(p, home));
|
|
192
|
+
const allowWrite = rawAllowWrite.filter((p) => !isPathProtected(p, home));
|
|
193
|
+
if (protectedFiltered.length > 0) {
|
|
194
|
+
options.onProtectedFiltered?.(protectedFiltered);
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
network: {
|
|
198
|
+
allowedDomains: [],
|
|
199
|
+
deniedDomains: ['*'],
|
|
200
|
+
strictAllowlist: true,
|
|
201
|
+
allowLocalBinding: false,
|
|
202
|
+
},
|
|
203
|
+
filesystem: {
|
|
204
|
+
denyRead,
|
|
205
|
+
...(allowRead ? { allowRead } : {}),
|
|
206
|
+
allowWrite,
|
|
207
|
+
denyWrite: [],
|
|
208
|
+
allowGitConfig: true,
|
|
209
|
+
},
|
|
210
|
+
credentials: {
|
|
211
|
+
files: credentialFiles.map((filePath) => ({ path: filePath, mode: 'deny' })),
|
|
212
|
+
envVars: credentialEnvVars.map((name) => ({ name, mode: 'deny' })),
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
export const SANDBOX_ESCAPE_INSTRUCTION = 'Sandbox blocked this command. To request a one-shot escape, call shell again with sandbox="unsandboxed"; user approval will be required.';
|
|
217
|
+
//# sourceMappingURL=sandbox-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-policy.js","sourceRoot":"","sources":["../../../../source/utils/shell/sandbox/sandbox-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SandboxRuntimeConfig } from '@anthropic-ai/sandbox-runtime';
|
|
2
|
+
import { type SandboxAvailability, type ShellSandboxRunner } from './sandbox-policy.js';
|
|
3
|
+
export declare class AnthropicShellSandboxRunner implements ShellSandboxRunner {
|
|
4
|
+
#private;
|
|
5
|
+
availability(): Promise<SandboxAvailability>;
|
|
6
|
+
wrap(command: string, options: {
|
|
7
|
+
cwd: string;
|
|
8
|
+
config?: SandboxRuntimeConfig;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
command: string;
|
|
12
|
+
diagnostics?: string[];
|
|
13
|
+
}>;
|
|
14
|
+
cleanupAfterCommand(): void;
|
|
15
|
+
annotateFailure(command: string, stderr: string): string;
|
|
16
|
+
}
|
|
17
|
+
export declare function getDefaultShellSandboxRunner(): ShellSandboxRunner;
|
|
18
|
+
//# sourceMappingURL=shell-sandbox-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-sandbox-runner.d.ts","sourceRoot":"","sources":["../../../../source/utils/shell/sandbox/shell-sandbox-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,OAAO,EAA8B,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEpH,qBAAa,2BAA4B,YAAW,kBAAkB;;IAI9D,YAAY,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAiB5C,IAAI,CACR,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,oBAAoB,CAAC;QAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAOvD,mBAAmB,IAAI,IAAI;IAI3B,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;CAwBzD;AAID,wBAAgB,4BAA4B,IAAI,kBAAkB,CAGjE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
|
|
2
|
+
import { SANDBOX_TEMP_DIR } from '../temp-dir.js';
|
|
3
|
+
import { createSandboxRuntimeConfig } from './sandbox-policy.js';
|
|
4
|
+
export class AnthropicShellSandboxRunner {
|
|
5
|
+
#initializedForKey;
|
|
6
|
+
#initializationFailure;
|
|
7
|
+
async availability() {
|
|
8
|
+
if (!SandboxManager.isSupportedPlatform()) {
|
|
9
|
+
return { type: 'unsupported_platform', reason: 'Sandbox runtime does not support this platform.' };
|
|
10
|
+
}
|
|
11
|
+
const dependencyCheck = SandboxManager.checkDependencies();
|
|
12
|
+
if (dependencyCheck.errors.length > 0) {
|
|
13
|
+
return { type: 'missing_dependency', reason: dependencyCheck.errors.join('; ') };
|
|
14
|
+
}
|
|
15
|
+
if (this.#initializationFailure) {
|
|
16
|
+
return this.#initializationFailure;
|
|
17
|
+
}
|
|
18
|
+
return { type: 'available' };
|
|
19
|
+
}
|
|
20
|
+
async wrap(command, options) {
|
|
21
|
+
await this.#initialize(options.cwd, options.config);
|
|
22
|
+
const wrapped = await SandboxManager.wrapWithSandbox(command, undefined, undefined, options.signal);
|
|
23
|
+
const diagnostics = SandboxManager.getLinuxGlobPatternWarnings?.() ?? [];
|
|
24
|
+
return { command: wrapped, diagnostics };
|
|
25
|
+
}
|
|
26
|
+
cleanupAfterCommand() {
|
|
27
|
+
SandboxManager.cleanupAfterCommand();
|
|
28
|
+
}
|
|
29
|
+
annotateFailure(command, stderr) {
|
|
30
|
+
return SandboxManager.annotateStderrWithSandboxFailures(command, stderr);
|
|
31
|
+
}
|
|
32
|
+
async #initialize(cwd, config = createSandboxRuntimeConfig({ cwd })) {
|
|
33
|
+
const initializationKey = JSON.stringify({ cwd, config });
|
|
34
|
+
if (this.#initializedForKey === initializationKey) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
if (this.#initializedForKey) {
|
|
39
|
+
await SandboxManager.reset();
|
|
40
|
+
}
|
|
41
|
+
process.env.CLAUDE_CODE_TMPDIR = SANDBOX_TEMP_DIR;
|
|
42
|
+
await SandboxManager.initialize(config);
|
|
43
|
+
this.#initializedForKey = initializationKey;
|
|
44
|
+
this.#initializationFailure = undefined;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
48
|
+
this.#initializationFailure = { type: 'initialization_failed', reason };
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let defaultRunner;
|
|
54
|
+
export function getDefaultShellSandboxRunner() {
|
|
55
|
+
defaultRunner ??= new AnthropicShellSandboxRunner();
|
|
56
|
+
return defaultRunner;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=shell-sandbox-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-sandbox-runner.js","sourceRoot":"","sources":["../../../../source/utils/shell/sandbox/shell-sandbox-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-output.d.ts","sourceRoot":"","sources":["../../../source/utils/shell/shell-output.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shell-output.d.ts","sourceRoot":"","sources":["../../../source/utils/shell/shell-output.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAyCD,wBAAsB,0BAA0B,CAAC,EAC/C,OAAO,EACP,GAAG,EACH,MAAM,EACN,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,UAAU,GACX,EAAE,gCAAgC,GAAG,OAAO,CAAC,gCAAgC,CAAC,CA0B9E"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { mkdtemp, writeFile } from 'fs/promises';
|
|
2
|
+
import { randomBytes } from 'crypto';
|
|
2
3
|
import os from 'os';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import { trimOutput } from '../output/output-trim.js';
|
|
5
|
-
const TRUNCATED_NOTE_PREFIX = 'Full
|
|
6
|
+
const TRUNCATED_NOTE_PREFIX = 'Full output saved to';
|
|
7
|
+
let shellOutputTempDirPromise;
|
|
6
8
|
function buildArtifactContents(params) {
|
|
7
9
|
const statusLine = params.timedOut ? 'timeout' : `exit ${params.exitCode ?? 'null'}`;
|
|
8
10
|
return [
|
|
@@ -21,8 +23,10 @@ function buildArtifactContents(params) {
|
|
|
21
23
|
].join('\n');
|
|
22
24
|
}
|
|
23
25
|
async function saveShellOutputArtifact(contents) {
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
+
shellOutputTempDirPromise ??= mkdtemp(path.join(os.tmpdir(), 'term2-shell-output-'));
|
|
27
|
+
const tempDir = await shellOutputTempDirPromise;
|
|
28
|
+
const suffix = randomBytes(3).toString('hex');
|
|
29
|
+
const artifactPath = path.join(tempDir, `output-${suffix}.txt`);
|
|
26
30
|
await writeFile(artifactPath, contents, 'utf8');
|
|
27
31
|
return artifactPath;
|
|
28
32
|
}
|
|
@@ -41,9 +45,7 @@ export async function formatShellExecutionOutput({ command, cwd, stdout, stderr,
|
|
|
41
45
|
if (stdoutTruncated || stderrTruncated) {
|
|
42
46
|
artifactPath = await saveShellOutputArtifact(buildArtifactContents({ command, cwd, stdout, stderr, exitCode, timedOut, durationMs }));
|
|
43
47
|
}
|
|
44
|
-
const truncationNote = artifactPath
|
|
45
|
-
? `${TRUNCATED_NOTE_PREFIX} \`${artifactPath}\`. Search that file for what you need instead of rerunning the command or changing the filter criteria with a \`| grep\` pipeline.`
|
|
46
|
-
: '';
|
|
48
|
+
const truncationNote = artifactPath ? `${TRUNCATED_NOTE_PREFIX} \`${artifactPath}\`` : '';
|
|
47
49
|
return {
|
|
48
50
|
text: [statusLine, runtimeLine, combinedOutput, emptyOutputNote, truncationNote].filter(Boolean).join('\n'),
|
|
49
51
|
truncated: Boolean(artifactPath),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-output.js","sourceRoot":"","sources":["../../../source/utils/shell/shell-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAmBtD,MAAM,qBAAqB,GAAG,
|
|
1
|
+
{"version":3,"file":"shell-output.js","sourceRoot":"","sources":["../../../source/utils/shell/shell-output.ts"],"names":[],"mappings":"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"}
|