@cjhyy/code-shell-core 0.5.0-rc.2 → 0.6.0-rc.2
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 +13 -10
- package/dist/agent/agent-definition-registry.d.ts +3 -0
- package/dist/agent/agent-definition-registry.js +3 -1
- package/dist/agent/agent-definition.d.ts +15 -0
- package/dist/agent/agent-definition.js +27 -3
- package/dist/arena/context/context-tools.js +47 -4
- package/dist/arena/ledger.js +9 -1
- package/dist/arena/strategies/utils.d.ts +1 -4
- package/dist/arena/strategies/utils.js +7 -84
- package/dist/automation/cron-expr.d.ts +10 -0
- package/dist/automation/cron-expr.js +23 -5
- package/dist/automation/runner.d.ts +21 -4
- package/dist/automation/runner.js +48 -12
- package/dist/automation/scheduler.d.ts +38 -0
- package/dist/automation/scheduler.js +89 -12
- package/dist/automation/store.js +5 -2
- package/dist/capability-control/disabled-lists.d.ts +25 -0
- package/dist/capability-control/disabled-lists.js +57 -0
- package/dist/capability-control/overlay.d.ts +15 -0
- package/dist/capability-control/overlay.js +27 -0
- package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
- package/dist/cc-orchestrator/agent-adapter.js +133 -0
- package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
- package/dist/cc-orchestrator/cc-capability.js +53 -0
- package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
- package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
- package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
- package/dist/cc-orchestrator/codex-session-history.js +187 -0
- package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
- package/dist/cc-orchestrator/external-agent-changes.js +214 -0
- package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
- package/dist/cc-orchestrator/external-agent-driver.js +69 -0
- package/dist/cc-orchestrator/index.d.ts +8 -0
- package/dist/cc-orchestrator/index.js +8 -0
- package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
- package/dist/cc-orchestrator/relevance-judge.js +29 -0
- package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
- package/dist/cc-orchestrator/session-discovery.js +125 -0
- package/dist/cc-orchestrator/session-history.d.ts +19 -0
- package/dist/cc-orchestrator/session-history.js +67 -0
- package/dist/cli/agent-server-stdio.d.ts +15 -1
- package/dist/cli/agent-server-stdio.js +115 -17
- package/dist/cli/agent-server-tcp.js +40 -26
- package/dist/context/compaction.d.ts +56 -0
- package/dist/context/compaction.js +186 -0
- package/dist/context/manager.js +25 -4
- package/dist/cost-tracker.js +5 -61
- package/dist/credentials/cipher.d.ts +49 -0
- package/dist/credentials/cipher.js +45 -0
- package/dist/credentials/cookie-jar.d.ts +24 -0
- package/dist/credentials/cookie-jar.js +40 -0
- package/dist/credentials/index.d.ts +7 -0
- package/dist/credentials/index.js +5 -0
- package/dist/credentials/inject-credential-tool.d.ts +20 -0
- package/dist/credentials/inject-credential-tool.js +130 -0
- package/dist/credentials/store.d.ts +72 -0
- package/dist/credentials/store.js +184 -0
- package/dist/credentials/types.d.ts +56 -0
- package/dist/credentials/use-credential-tool.d.ts +29 -0
- package/dist/credentials/use-credential-tool.js +205 -0
- package/dist/credentials/use-gate.d.ts +56 -0
- package/dist/credentials/use-gate.js +52 -0
- package/dist/data/model-metadata.d.ts +77 -0
- package/dist/data/model-metadata.js +56 -0
- package/dist/data/model-metadata.json +216 -0
- package/dist/data/openrouter-models.d.ts +18 -7
- package/dist/data/openrouter-models.js +35 -8
- package/dist/engine/aux-key.d.ts +10 -0
- package/dist/engine/aux-key.js +11 -0
- package/dist/engine/dynamic-tool-defs.d.ts +19 -0
- package/dist/engine/dynamic-tool-defs.js +36 -0
- package/dist/engine/engine.d.ts +267 -138
- package/dist/engine/engine.js +957 -191
- package/dist/engine/friendly-error.d.ts +18 -0
- package/dist/engine/friendly-error.js +63 -0
- package/dist/engine/goal.d.ts +145 -0
- package/dist/engine/goal.js +144 -0
- package/dist/engine/image-policy.d.ts +13 -0
- package/dist/engine/image-policy.js +24 -0
- package/dist/engine/model-connections-pool.d.ts +17 -0
- package/dist/engine/model-connections-pool.js +66 -0
- package/dist/engine/model-facade.d.ts +10 -0
- package/dist/engine/model-facade.js +25 -0
- package/dist/engine/patch-orphaned-tools.js +3 -0
- package/dist/engine/resolve-llm-config.d.ts +16 -0
- package/dist/engine/resolve-llm-config.js +44 -0
- package/dist/engine/runtime.js +2 -1
- package/dist/engine/sandbox-cache-key.d.ts +10 -0
- package/dist/engine/sandbox-cache-key.js +9 -0
- package/dist/engine/sandbox-config.d.ts +31 -0
- package/dist/engine/sandbox-config.js +38 -0
- package/dist/engine/session-usage.d.ts +19 -0
- package/dist/engine/session-usage.js +25 -0
- package/dist/engine/steer-queue.d.ts +32 -0
- package/dist/engine/steer-queue.js +26 -0
- package/dist/engine/streaming-tool-queue.d.ts +12 -0
- package/dist/engine/streaming-tool-queue.js +50 -10
- package/dist/engine/turn-loop.d.ts +67 -3
- package/dist/engine/turn-loop.js +292 -41
- package/dist/engine/types.d.ts +175 -0
- package/dist/engine/types.js +13 -0
- package/dist/external-agents/config.d.ts +2 -0
- package/dist/external-agents/config.js +15 -0
- package/dist/external-agents/types.d.ts +31 -0
- package/dist/external-agents/types.js +1 -0
- package/dist/git/utils.js +11 -6
- package/dist/git/worktree.d.ts +48 -0
- package/dist/git/worktree.js +86 -10
- package/dist/hooks/goal-stop-hook.d.ts +28 -0
- package/dist/hooks/goal-stop-hook.js +186 -9
- package/dist/hooks/registry.d.ts +8 -0
- package/dist/hooks/registry.js +19 -0
- package/dist/hooks/shell-runner.js +10 -21
- package/dist/index.d.ts +49 -6
- package/dist/index.js +60 -4
- package/dist/llm/capabilities/param-specs.d.ts +14 -0
- package/dist/llm/capabilities/param-specs.js +62 -0
- package/dist/llm/capabilities/rules.js +4 -0
- package/dist/llm/capabilities/types.d.ts +10 -0
- package/dist/llm/client-base.d.ts +28 -1
- package/dist/llm/client-base.js +119 -13
- package/dist/llm/model-cache.js +4 -2
- package/dist/llm/model-pool.d.ts +14 -0
- package/dist/llm/model-pool.js +13 -0
- package/dist/llm/provider-auth.d.ts +41 -0
- package/dist/llm/provider-auth.js +76 -0
- package/dist/llm/provider-catalog.d.ts +4 -0
- package/dist/llm/providers/anthropic.js +64 -14
- package/dist/llm/providers/openai.d.ts +36 -0
- package/dist/llm/providers/openai.js +257 -51
- package/dist/llm/reasoning-setting.d.ts +3 -3
- package/dist/llm/reasoning-setting.js +9 -1
- package/dist/llm/stream-watchdog.js +5 -1
- package/dist/llm/token-counter.js +9 -2
- package/dist/llm/types.d.ts +4 -0
- package/dist/logging/sanitize-messages.js +22 -0
- package/dist/lsp/manager.d.ts +1 -1
- package/dist/lsp/manager.js +40 -10
- package/dist/model-catalog/builtin.d.ts +12 -0
- package/dist/model-catalog/builtin.js +407 -0
- package/dist/model-catalog/gen-connections.d.ts +20 -0
- package/dist/model-catalog/gen-connections.js +28 -0
- package/dist/model-catalog/index.d.ts +41 -0
- package/dist/model-catalog/index.js +90 -0
- package/dist/model-catalog/params.d.ts +20 -0
- package/dist/model-catalog/params.js +45 -0
- package/dist/model-catalog/resolve.d.ts +48 -0
- package/dist/model-catalog/resolve.js +33 -0
- package/dist/model-catalog/save-entry.d.ts +32 -0
- package/dist/model-catalog/save-entry.js +104 -0
- package/dist/model-catalog/types.d.ts +561 -0
- package/dist/model-catalog/types.js +93 -0
- package/dist/model-catalog/upsert.d.ts +9 -0
- package/dist/model-catalog/upsert.js +8 -0
- package/dist/onboarding.d.ts +12 -82
- package/dist/onboarding.js +61 -326
- package/dist/plugins/gitOps.d.ts +19 -0
- package/dist/plugins/gitOps.js +73 -4
- package/dist/plugins/installer/checkUpdate.d.ts +16 -0
- package/dist/plugins/installer/checkUpdate.js +32 -0
- package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
- package/dist/plugins/installer/codex/convertCommands.js +46 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +5 -2
- package/dist/plugins/installer/codex/convertMcp.js +45 -5
- package/dist/plugins/installer/install.js +25 -1
- package/dist/plugins/installer/installFromArchive.d.ts +43 -0
- package/dist/plugins/installer/installFromArchive.js +134 -0
- package/dist/plugins/installer/installFromSource.js +8 -2
- package/dist/plugins/installer/loadPluginAgents.js +6 -2
- package/dist/plugins/installer/loadPluginMcp.d.ts +9 -2
- package/dist/plugins/installer/loadPluginMcp.js +35 -2
- package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
- package/dist/plugins/installer/pruneDisabled.js +73 -0
- package/dist/plugins/installer/types.d.ts +5 -2
- package/dist/plugins/installer/types.js +1 -0
- package/dist/plugins/installer/uninstall.js +4 -0
- package/dist/plugins/installer/unzip.d.ts +14 -0
- package/dist/plugins/installer/unzip.js +82 -0
- package/dist/plugins/installer/update.d.ts +14 -0
- package/dist/plugins/installer/update.js +53 -21
- package/dist/plugins/loadPluginHooks.d.ts +47 -1
- package/dist/plugins/loadPluginHooks.js +73 -1
- package/dist/plugins/marketplaceManager.d.ts +7 -0
- package/dist/plugins/marketplaceManager.js +20 -0
- package/dist/plugins/pluginCommandHook.js +4 -18
- package/dist/plugins/pluginContent.d.ts +30 -0
- package/dist/plugins/pluginContent.js +83 -0
- package/dist/plugins/pluginInstaller.d.ts +13 -0
- package/dist/plugins/pluginInstaller.js +42 -8
- package/dist/plugins/schemas.js +1 -0
- package/dist/plugins/types.d.ts +6 -0
- package/dist/preset/index.d.ts +7 -1
- package/dist/preset/index.js +96 -6
- package/dist/product/types.d.ts +1 -1
- package/dist/prompt/composer.d.ts +27 -0
- package/dist/prompt/composer.js +67 -21
- package/dist/prompt/instruction-scanner.js +5 -3
- package/dist/prompt/section-loader.js +1 -0
- package/dist/prompt/sections/base.md +1 -0
- package/dist/prompt/sections/browser.md +10 -0
- package/dist/prompt/sections/coding.md +4 -0
- package/dist/protocol/chat-session-manager.d.ts +8 -2
- package/dist/protocol/chat-session-manager.js +36 -0
- package/dist/protocol/chat-session.d.ts +65 -0
- package/dist/protocol/chat-session.js +94 -2
- package/dist/protocol/client.d.ts +27 -0
- package/dist/protocol/client.js +38 -0
- package/dist/protocol/server.d.ts +112 -0
- package/dist/protocol/server.js +586 -16
- package/dist/protocol/transport.js +3 -2
- package/dist/protocol/types.d.ts +46 -0
- package/dist/protocol/types.js +16 -0
- package/dist/quota/credentials.d.ts +3 -0
- package/dist/quota/credentials.js +80 -0
- package/dist/quota/index.d.ts +36 -0
- package/dist/quota/index.js +155 -0
- package/dist/quota/types.d.ts +48 -0
- package/dist/quota/types.js +13 -0
- package/dist/review/review-prompt.d.ts +28 -0
- package/dist/review/review-prompt.js +81 -0
- package/dist/run/FileRunStore.js +8 -3
- package/dist/run/RunApprovalBackend.js +25 -5
- package/dist/run/RunManager.d.ts +12 -0
- package/dist/run/RunManager.js +35 -0
- package/dist/run/factory.d.ts +1 -1
- package/dist/runtime/background-shell.d.ts +139 -0
- package/dist/runtime/background-shell.js +495 -0
- package/dist/runtime/output-clean.d.ts +24 -0
- package/dist/runtime/output-clean.js +41 -0
- package/dist/runtime/ring-file.d.ts +64 -0
- package/dist/runtime/ring-file.js +174 -0
- package/dist/runtime/safe-spawn.js +15 -34
- package/dist/runtime/spawn-common.d.ts +148 -0
- package/dist/runtime/spawn-common.js +303 -0
- package/dist/runtime/truncate-output.d.ts +22 -0
- package/dist/runtime/truncate-output.js +49 -0
- package/dist/runtime/utf8-cut.d.ts +11 -0
- package/dist/runtime/utf8-cut.js +23 -0
- package/dist/services/auto-dream.d.ts +4 -0
- package/dist/services/auto-dream.js +26 -26
- package/dist/services/diagnostics.d.ts +1 -2
- package/dist/services/diagnostics.js +12 -7
- package/dist/services/extract-memories.d.ts +14 -1
- package/dist/services/extract-memories.js +45 -6
- package/dist/services/memory-orchestrator.d.ts +21 -0
- package/dist/services/memory-orchestrator.js +125 -50
- package/dist/services/session-memory.js +24 -12
- package/dist/session/file-history.d.ts +124 -1
- package/dist/session/file-history.js +222 -6
- package/dist/session/memory.d.ts +116 -2
- package/dist/session/memory.js +250 -28
- package/dist/session/session-manager.d.ts +40 -0
- package/dist/session/session-manager.js +113 -3
- package/dist/session/simple-diff.d.ts +23 -0
- package/dist/session/simple-diff.js +84 -0
- package/dist/session/transcript.d.ts +25 -1
- package/dist/session/transcript.js +35 -2
- package/dist/session/undo-target.d.ts +67 -0
- package/dist/session/undo-target.js +144 -0
- package/dist/settings/disk-defaults.d.ts +9 -2
- package/dist/settings/disk-defaults.js +11 -2
- package/dist/settings/feature-flags.d.ts +64 -0
- package/dist/settings/feature-flags.js +61 -0
- package/dist/settings/manager.d.ts +68 -1
- package/dist/settings/manager.js +266 -29
- package/dist/settings/migrate-config.d.ts +45 -0
- package/dist/settings/migrate-config.js +125 -0
- package/dist/settings/schema-export.d.ts +25 -0
- package/dist/settings/schema-export.js +38 -0
- package/dist/settings/schema.d.ts +1186 -771
- package/dist/settings/schema.js +268 -97
- package/dist/skills/scanner.d.ts +9 -0
- package/dist/skills/scanner.js +30 -2
- package/dist/stt/resolve-transcribe.d.ts +31 -0
- package/dist/stt/resolve-transcribe.js +108 -0
- package/dist/stt/transcribe.d.ts +51 -0
- package/dist/stt/transcribe.js +65 -0
- package/dist/tool-system/browser-bridge.d.ts +226 -0
- package/dist/tool-system/browser-bridge.js +163 -0
- package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
- package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
- package/dist/tool-system/builtin/agent-notifications.js +9 -3
- package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
- package/dist/tool-system/builtin/agent-output-file.js +72 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +12 -0
- package/dist/tool-system/builtin/agent-registry.js +8 -0
- package/dist/tool-system/builtin/agent.d.ts +21 -1
- package/dist/tool-system/builtin/agent.js +489 -42
- package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
- package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
- package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
- package/dist/tool-system/builtin/apply-patch/index.js +0 -15
- package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
- package/dist/tool-system/builtin/background-jobs.js +124 -0
- package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
- package/dist/tool-system/builtin/background-shell-tools.js +108 -0
- package/dist/tool-system/builtin/background-work.d.ts +67 -0
- package/dist/tool-system/builtin/background-work.js +86 -0
- package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
- package/dist/tool-system/builtin/bash-output-style.js +40 -0
- package/dist/tool-system/builtin/bash.d.ts +5 -2
- package/dist/tool-system/builtin/bash.js +98 -62
- package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
- package/dist/tool-system/builtin/browser-tools.js +312 -0
- package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
- package/dist/tool-system/builtin/cancel-goal.js +64 -0
- package/dist/tool-system/builtin/check-quota.d.ts +15 -0
- package/dist/tool-system/builtin/check-quota.js +34 -0
- package/dist/tool-system/builtin/config.js +7 -0
- package/dist/tool-system/builtin/cron.d.ts +7 -0
- package/dist/tool-system/builtin/cron.js +55 -3
- package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
- package/dist/tool-system/builtin/drive-claude-code.js +157 -0
- package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
- package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
- package/dist/tool-system/builtin/edit.js +20 -16
- package/dist/tool-system/builtin/eol.d.ts +29 -0
- package/dist/tool-system/builtin/eol.js +37 -0
- package/dist/tool-system/builtin/file-cache.d.ts +6 -0
- package/dist/tool-system/builtin/file-cache.js +8 -0
- package/dist/tool-system/builtin/generate-image.d.ts +35 -0
- package/dist/tool-system/builtin/generate-image.js +278 -50
- package/dist/tool-system/builtin/generate-video.d.ts +55 -0
- package/dist/tool-system/builtin/generate-video.js +361 -0
- package/dist/tool-system/builtin/glob.js +0 -7
- package/dist/tool-system/builtin/grep.js +6 -8
- package/dist/tool-system/builtin/image-providers.d.ts +86 -0
- package/dist/tool-system/builtin/image-providers.js +190 -0
- package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
- package/dist/tool-system/builtin/image-uploader.js +74 -0
- package/dist/tool-system/builtin/index.d.ts +7 -1
- package/dist/tool-system/builtin/index.js +249 -25
- package/dist/tool-system/builtin/mcp-tools.js +23 -3
- package/dist/tool-system/builtin/memory.js +45 -7
- package/dist/tool-system/builtin/notebook-edit.js +0 -7
- package/dist/tool-system/builtin/powershell.js +4 -1
- package/dist/tool-system/builtin/read.js +10 -10
- package/dist/tool-system/builtin/repl.js +4 -1
- package/dist/tool-system/builtin/skill.js +9 -0
- package/dist/tool-system/builtin/sleep.js +3 -2
- package/dist/tool-system/builtin/tool-search.js +25 -7
- package/dist/tool-system/builtin/video-providers.d.ts +154 -0
- package/dist/tool-system/builtin/video-providers.js +235 -0
- package/dist/tool-system/builtin/web-fetch.js +12 -2
- package/dist/tool-system/builtin/web-search.js +21 -7
- package/dist/tool-system/builtin/worktree.d.ts +2 -1
- package/dist/tool-system/builtin/worktree.js +31 -4
- package/dist/tool-system/builtin/write.js +0 -6
- package/dist/tool-system/context.d.ts +154 -6
- package/dist/tool-system/executor.d.ts +3 -1
- package/dist/tool-system/executor.js +172 -88
- package/dist/tool-system/investigation-guard.js +1 -1
- package/dist/tool-system/mcp-manager.d.ts +42 -4
- package/dist/tool-system/mcp-manager.js +186 -20
- package/dist/tool-system/path-policy.d.ts +5 -0
- package/dist/tool-system/path-policy.js +307 -8
- package/dist/tool-system/permission.d.ts +36 -1
- package/dist/tool-system/permission.js +281 -69
- package/dist/tool-system/plan-mode-allowlist.d.ts +13 -2
- package/dist/tool-system/plan-mode-allowlist.js +24 -2
- package/dist/tool-system/registry.d.ts +1 -0
- package/dist/tool-system/registry.js +16 -2
- package/dist/tool-system/sandbox/index.d.ts +8 -0
- package/dist/tool-system/sandbox/index.js +7 -2
- package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
- package/dist/tool-system/validate-tool-metadata.js +63 -0
- package/dist/types.d.ts +217 -6
- package/dist/updater.js +20 -9
- package/dist/utils/envUtils.d.ts +0 -9
- package/dist/utils/envUtils.js +3 -28
- package/dist/utils/exec.d.ts +40 -0
- package/dist/utils/exec.js +144 -0
- package/dist/utils/json.d.ts +12 -0
- package/dist/utils/json.js +92 -0
- package/dist/utils/theme.d.ts +1 -1
- package/dist/utils/theme.js +1 -1
- package/dist/utils/toolDisplay.js +0 -1
- package/package.json +13 -7
- package/dist/agent/coordinator.d.ts +0 -49
- package/dist/agent/coordinator.js +0 -77
- package/dist/settings/manager.test.js +0 -73
- package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
- package/dist/tool-system/builtin/remote-trigger.js +0 -54
- package/dist/tool-system/builtin/send-message.d.ts +0 -6
- package/dist/tool-system/builtin/send-message.js +0 -47
- /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
|
@@ -29,9 +29,10 @@
|
|
|
29
29
|
* approval round-trip; it is not an authority to write anywhere on disk.
|
|
30
30
|
* Callers must consult classifyPath before honoring acceptEdits.
|
|
31
31
|
*/
|
|
32
|
-
import { realpathSync } from "node:fs";
|
|
32
|
+
import { realpathSync, existsSync, readFileSync, writeFileSync, mkdirSync, renameSync, } from "node:fs";
|
|
33
33
|
import { homedir } from "node:os";
|
|
34
|
-
import {
|
|
34
|
+
import { randomUUID } from "node:crypto";
|
|
35
|
+
import { dirname, isAbsolute, join, resolve as resolvePath, sep } from "node:path";
|
|
35
36
|
/**
|
|
36
37
|
* Default sensitive path patterns. These are evaluated AFTER home-expansion
|
|
37
38
|
* and resolution, so a literal "$HOME/.ssh" and a symlink at /tmp/x → ~/.ssh
|
|
@@ -54,16 +55,39 @@ const SENSITIVE_DIR_PATTERNS = [
|
|
|
54
55
|
* Files that are sensitive regardless of where they live: an `.env` next to
|
|
55
56
|
* the code, an `id_rsa` in a random folder, etc.
|
|
56
57
|
*/
|
|
58
|
+
// Data/config extensions a credential FILE typically carries. Deliberately
|
|
59
|
+
// excludes source-code extensions (.ts/.tsx/.js/.py/.go/.rs/…) so a code file
|
|
60
|
+
// whose NAME happens to contain a secret-y word is never treated as a secret.
|
|
61
|
+
const SECRET_DATA_EXT = String.raw `(json|ya?ml|txt|ini|conf|cfg|toml|xml|properties|env|key|secret)`;
|
|
57
62
|
const SENSITIVE_FILE_PATTERNS = [
|
|
58
63
|
/^\.env(\..+)?$/i, // .env, .env.local, .env.production, …
|
|
59
64
|
/^id_(rsa|dsa|ecdsa|ed25519)(\.pub)?$/i,
|
|
60
65
|
/\.pem$/i,
|
|
61
66
|
/\.p12$/i,
|
|
62
67
|
/\.pfx$/i,
|
|
63
|
-
/
|
|
64
|
-
/
|
|
65
|
-
/
|
|
66
|
-
|
|
68
|
+
// Credential/secret ARTIFACT files: the secret word is the dominant stem AND
|
|
69
|
+
// the file carries a data/config extension (or none). This still catches
|
|
70
|
+
// credentials.json / secrets.yaml / auth.json / token.txt / api-secret.conf,
|
|
71
|
+
// but NOT source files like authController.ts, token-counter.ts,
|
|
72
|
+
// oauth-handler.ts whose code extension excludes them.
|
|
73
|
+
//
|
|
74
|
+
// Was previously bare substrings (/auth/i, /token/i, …) tested against the
|
|
75
|
+
// basename, which denied WRITES to any code file containing those words —
|
|
76
|
+
// breaking the agent's ability to edit ordinary auth/token source. See
|
|
77
|
+
// path-policy-sensitive-file.test.ts.
|
|
78
|
+
new RegExp(String.raw `^[^/]*\b(secrets?|credentials?|auth|token|apikey|api[-_]?key)\b[^/]*\.${SECRET_DATA_EXT}$`, "i"),
|
|
79
|
+
// Bare (extensionless) credential files: `secret`, `credentials`, `token`.
|
|
80
|
+
/^(secrets?|credentials?|token)$/i,
|
|
81
|
+
// Well-known credential files matched by EXACT name (anchored both ends, so
|
|
82
|
+
// npmrc-helper.ts / git-credentials.md stay writable). These carry no
|
|
83
|
+
// secret-y stem and aren't .env/.pem, so the patterns above miss them, yet
|
|
84
|
+
// they routinely hold auth tokens / passwords:
|
|
85
|
+
// .git-credentials (git creds), .npmrc (_authToken), .netrc (login creds),
|
|
86
|
+
// .pgpass (postgres passwords).
|
|
87
|
+
/^\.git-credentials$/i,
|
|
88
|
+
/^\.npmrc$/i,
|
|
89
|
+
/^\.netrc$/i,
|
|
90
|
+
/^\.pgpass$/i,
|
|
67
91
|
];
|
|
68
92
|
const ENV_DISABLE = "CODESHELL_PATH_POLICY";
|
|
69
93
|
let warnedDisabled = false;
|
|
@@ -79,6 +103,175 @@ function expandTilde(p) {
|
|
|
79
103
|
}
|
|
80
104
|
return p;
|
|
81
105
|
}
|
|
106
|
+
/** sessionId → set of approved directory grants (prefix + operation). */
|
|
107
|
+
const sessionPathGrants = new Map();
|
|
108
|
+
/** True if a grant for `grantOp` authorizes an operation of `wantOp`. */
|
|
109
|
+
function grantCoversOp(grantOp, wantOp) {
|
|
110
|
+
// write ⊇ {read, write}; read ⊇ {read}.
|
|
111
|
+
return grantOp === "write" || grantOp === wantOp;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Normalize a path for comparison. Windows file systems are case-INsensitive,
|
|
115
|
+
* so `C:\Users\Admin\.ssh` and `c:\users\admin\.ssh` are the same path — a
|
|
116
|
+
* case-sensitive `startsWith` would let a sensitive-path or workspace-boundary
|
|
117
|
+
* check be bypassed by varying case (or just fail to match a legit prefix).
|
|
118
|
+
* Lowercase on win32 only; POSIX stays exact (macOS APFS can be case-sensitive,
|
|
119
|
+
* and the existing contract is case-sensitive there).
|
|
120
|
+
*/
|
|
121
|
+
function normPath(p) {
|
|
122
|
+
return process.platform === "win32" ? p.toLowerCase() : p;
|
|
123
|
+
}
|
|
124
|
+
/** Normalize a directory to an absolute prefix ending in `sep` for prefix tests. */
|
|
125
|
+
function dirPrefix(absPath) {
|
|
126
|
+
const d = absPath.endsWith(sep) ? absPath : absPath + sep;
|
|
127
|
+
return d;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* True if `resolved` sits inside any grant whose prefix covers it AND whose
|
|
131
|
+
* operation authorizes `operation` (write grants cover reads; read grants do
|
|
132
|
+
* not cover writes).
|
|
133
|
+
*/
|
|
134
|
+
function coveredBy(grants, resolved, operation) {
|
|
135
|
+
const target = normPath(resolved.endsWith(sep) ? resolved : resolved + sep);
|
|
136
|
+
for (const g of grants) {
|
|
137
|
+
if (!grantCoversOp(g.op, operation))
|
|
138
|
+
continue;
|
|
139
|
+
const gn = normPath(g.prefix);
|
|
140
|
+
if (target === gn || target.startsWith(gn))
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Read persisted project grants. Two on-disk shapes are accepted:
|
|
147
|
+
* - legacy bare string "/dir/" → interpreted as a READ-only grant
|
|
148
|
+
* (conservative: pre-fix entries were written without an operation, and we
|
|
149
|
+
* must not retroactively treat them as write authority).
|
|
150
|
+
* - object { path: "/dir/", op: "write" } → operation as stored.
|
|
151
|
+
*/
|
|
152
|
+
function projectPathGrants(cwd) {
|
|
153
|
+
const file = join(cwd, ".code-shell", "settings.local.json");
|
|
154
|
+
if (!existsSync(file))
|
|
155
|
+
return [];
|
|
156
|
+
try {
|
|
157
|
+
const s = JSON.parse(readFileSync(file, "utf-8"));
|
|
158
|
+
if (!Array.isArray(s.pathApprovals))
|
|
159
|
+
return [];
|
|
160
|
+
const out = [];
|
|
161
|
+
for (const entry of s.pathApprovals) {
|
|
162
|
+
if (typeof entry === "string") {
|
|
163
|
+
out.push({ prefix: entry, op: "read" });
|
|
164
|
+
}
|
|
165
|
+
else if (entry &&
|
|
166
|
+
typeof entry === "object" &&
|
|
167
|
+
typeof entry.path === "string") {
|
|
168
|
+
const op = entry.op === "write" ? "write" : "read";
|
|
169
|
+
out.push({ prefix: entry.path, op });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return [];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Has the user already approved `operation` on a directory covering `resolved`? */
|
|
179
|
+
function isPathPreApproved(resolved, operation, cwd, sessionId) {
|
|
180
|
+
if (sessionId) {
|
|
181
|
+
const s = sessionPathGrants.get(sessionId);
|
|
182
|
+
if (s && coveredBy(s, resolved, operation))
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
return coveredBy(projectPathGrants(cwd), resolved, operation);
|
|
186
|
+
}
|
|
187
|
+
function storedPrefix(g) {
|
|
188
|
+
return typeof g === "string" ? g : g.path;
|
|
189
|
+
}
|
|
190
|
+
function storedOp(g) {
|
|
191
|
+
return typeof g === "string" ? "read" : g.op;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Record a session/project grant for the DIRECTORY containing `resolved`,
|
|
195
|
+
* tagged with the OPERATION the user approved. A write grant subsumes read,
|
|
196
|
+
* so granting write where a read grant already exists upgrades it.
|
|
197
|
+
*/
|
|
198
|
+
function recordPathApproval(scope, resolved, operation, cwd, sessionId) {
|
|
199
|
+
if (scope === "once")
|
|
200
|
+
return;
|
|
201
|
+
const prefix = dirPrefix(dirname(resolved));
|
|
202
|
+
if (scope === "session") {
|
|
203
|
+
if (!sessionId)
|
|
204
|
+
return;
|
|
205
|
+
let s = sessionPathGrants.get(sessionId);
|
|
206
|
+
if (!s) {
|
|
207
|
+
s = new Set();
|
|
208
|
+
sessionPathGrants.set(sessionId, s);
|
|
209
|
+
}
|
|
210
|
+
// Drop a weaker (read) grant for the same prefix when upgrading to write,
|
|
211
|
+
// and skip adding a redundant read when a write grant already covers it.
|
|
212
|
+
for (const g of s) {
|
|
213
|
+
if (g.prefix !== prefix)
|
|
214
|
+
continue;
|
|
215
|
+
if (grantCoversOp(g.op, operation))
|
|
216
|
+
return; // already covered
|
|
217
|
+
if (operation === "write" && g.op === "read")
|
|
218
|
+
s.delete(g); // upgrade
|
|
219
|
+
}
|
|
220
|
+
s.add({ prefix, op: operation });
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// project: persist to settings.local.json (atomic, idempotent).
|
|
224
|
+
const dir = join(cwd, ".code-shell");
|
|
225
|
+
const file = join(dir, "settings.local.json");
|
|
226
|
+
try {
|
|
227
|
+
// Don't resurrect a deleted project root: a recursive mkdir of
|
|
228
|
+
// <cwd>/.code-shell recreates `cwd` itself as an empty shell when cwd is
|
|
229
|
+
// gone. Persistence here is best-effort, so skip when the root is missing.
|
|
230
|
+
if (!existsSync(cwd))
|
|
231
|
+
return;
|
|
232
|
+
if (!existsSync(dir))
|
|
233
|
+
mkdirSync(dir, { recursive: true });
|
|
234
|
+
let settings = {};
|
|
235
|
+
if (existsSync(file)) {
|
|
236
|
+
try {
|
|
237
|
+
settings = JSON.parse(readFileSync(file, "utf-8"));
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
/* start fresh on parse error */
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (!Array.isArray(settings.pathApprovals))
|
|
244
|
+
settings.pathApprovals = [];
|
|
245
|
+
const existing = settings.pathApprovals.find((g) => storedPrefix(g) === prefix);
|
|
246
|
+
if (existing) {
|
|
247
|
+
// Already covered (read-or-better matching the request)? Nothing to do.
|
|
248
|
+
if (grantCoversOp(storedOp(existing), operation))
|
|
249
|
+
return;
|
|
250
|
+
// Upgrade read → write in place.
|
|
251
|
+
if (operation === "write") {
|
|
252
|
+
settings.pathApprovals = settings.pathApprovals.map((g) => storedPrefix(g) === prefix ? { path: prefix, op: "write" } : g);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
settings.pathApprovals.push({ path: prefix, op: operation });
|
|
260
|
+
}
|
|
261
|
+
// randomUUID() guards against temp-name collisions between writers in
|
|
262
|
+
// the same millisecond; the rename keeps the swap atomic.
|
|
263
|
+
const tmp = `${file}.${randomUUID()}.tmp`;
|
|
264
|
+
writeFileSync(tmp, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
265
|
+
renameSync(tmp, file);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Persistence is best-effort; an unwritable disk must not break the op.
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/** Test seam: clear the in-memory session grants. */
|
|
272
|
+
export function _resetSessionPathGrants() {
|
|
273
|
+
sessionPathGrants.clear();
|
|
274
|
+
}
|
|
82
275
|
/**
|
|
83
276
|
* Best-effort resolution. realpath fails when the path doesn't exist yet —
|
|
84
277
|
* the common case for Write creating a new file. We walk up to the nearest
|
|
@@ -117,8 +310,10 @@ function safeRealpath(p) {
|
|
|
117
310
|
return abs;
|
|
118
311
|
}
|
|
119
312
|
function isInsideDir(child, parent) {
|
|
120
|
-
const
|
|
121
|
-
|
|
313
|
+
const c = normPath(child);
|
|
314
|
+
const par = normPath(parent);
|
|
315
|
+
const p = par.endsWith(sep) ? par : par + sep;
|
|
316
|
+
return c === par || c.startsWith(p);
|
|
122
317
|
}
|
|
123
318
|
/**
|
|
124
319
|
* Returns the matching sensitive-dir entry (with the user's home prefix) if
|
|
@@ -269,6 +464,110 @@ export function enforcePathPolicy(filePath, operation, workspaceRoot) {
|
|
|
269
464
|
return `Error: path requires approval — ${c.reason}. Path: ${c.resolvedPath}. ` +
|
|
270
465
|
`Set CODESHELL_PATH_POLICY=off to disable enforcement during a rollback.`;
|
|
271
466
|
}
|
|
467
|
+
export async function enforcePathPolicyWithApproval(filePath, operation, ctx) {
|
|
468
|
+
if (ctx?.cwd === undefined)
|
|
469
|
+
return null;
|
|
470
|
+
// bypassPermissions ("完全访问") skips the path-approval layer entirely,
|
|
471
|
+
// matching the tool-permission backend and CC (bypass skips ALL checks,
|
|
472
|
+
// including path validation). This is what makes "完全访问" actually mean
|
|
473
|
+
// full access — previously path policy ran regardless of mode, so a user
|
|
474
|
+
// who chose full access still got prompted for project-external reads.
|
|
475
|
+
if (ctx.permissionMode === "bypassPermissions")
|
|
476
|
+
return null;
|
|
477
|
+
const c = classifyPath(filePath, { workspaceRoot: ctx.cwd, operation });
|
|
478
|
+
if (c.decision === "allow")
|
|
479
|
+
return null;
|
|
480
|
+
if (c.decision === "deny") {
|
|
481
|
+
return `Error: blocked by path policy — ${c.reason}. Path: ${c.resolvedPath}`;
|
|
482
|
+
}
|
|
483
|
+
if (operation === "write" && ctx.planMode) {
|
|
484
|
+
return `Error: blocked by path policy — ${c.reason}. Path: ${c.resolvedPath}. ` +
|
|
485
|
+
`Plan mode does not allow file writes.`;
|
|
486
|
+
}
|
|
487
|
+
// Already approved this directory for this OPERATION (this session or
|
|
488
|
+
// persisted for the project)? Proceed without re-prompting — this is the fix
|
|
489
|
+
// for "I keep having to click allow for the same folder". A read grant does
|
|
490
|
+
// NOT cover a write; a write grant covers both.
|
|
491
|
+
if (isPathPreApproved(c.resolvedPath, operation, ctx.cwd, ctx.sessionId))
|
|
492
|
+
return null;
|
|
493
|
+
if (!ctx.askUser) {
|
|
494
|
+
return `Error: path requires approval — ${c.reason}. Path: ${c.resolvedPath}. ` +
|
|
495
|
+
`No interactive approval UI is available in this run.`;
|
|
496
|
+
}
|
|
497
|
+
// Serialize concurrent asks (per session) and RE-CHECK grants when our turn
|
|
498
|
+
// comes. Parallel tools hitting the same not-yet-approved directory all pass
|
|
499
|
+
// the pre-approved check above before the first grant lands, so each used to
|
|
500
|
+
// queue its own card — the user got a burst of identical 路径权限 prompts.
|
|
501
|
+
// Now the first "本目录允许" answer silently absorbs the queued rest.
|
|
502
|
+
const chainKey = ctx.sessionId ?? "__global__";
|
|
503
|
+
const prevTurn = askChains.get(chainKey) ?? Promise.resolve();
|
|
504
|
+
let release;
|
|
505
|
+
askChains.set(chainKey, new Promise((r) => (release = r)));
|
|
506
|
+
try {
|
|
507
|
+
await prevTurn;
|
|
508
|
+
if (isPathPreApproved(c.resolvedPath, operation, ctx.cwd, ctx.sessionId))
|
|
509
|
+
return null;
|
|
510
|
+
return await promptForPathApproval(c, operation, ctx);
|
|
511
|
+
}
|
|
512
|
+
finally {
|
|
513
|
+
release();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/** The actual interactive ask — split out so the serialized section reads flat.
|
|
517
|
+
* Caller has already verified ctx.askUser and ctx.cwd are present. */
|
|
518
|
+
async function promptForPathApproval(c, operation, ctx) {
|
|
519
|
+
// Title by the ACTUAL reason, not always "工作区外": a sensitive file
|
|
520
|
+
// (e.g. ~/.ssh, .env) can sit INSIDE the workspace, so the old fixed
|
|
521
|
+
// "工作区外路径" header was misleading for sensitive-path asks.
|
|
522
|
+
const isSensitive = c.reason.startsWith("sensitive");
|
|
523
|
+
const what = operation === "read" ? "读取" : "写入";
|
|
524
|
+
const title = isSensitive
|
|
525
|
+
? `工具想${what}敏感文件`
|
|
526
|
+
: `工具想${what}工作区外路径`;
|
|
527
|
+
const header = isSensitive ? "敏感文件权限" : "路径权限";
|
|
528
|
+
// Scope options carry remembered grants for the directory of this path, so
|
|
529
|
+
// the same folder isn't re-prompted. Labels are matched by exact string
|
|
530
|
+
// (the ask is optionsOnly — no free-text box that could silently fail to
|
|
531
|
+
// match). 仅本次 carries no memory.
|
|
532
|
+
const grantDir = dirname(c.resolvedPath);
|
|
533
|
+
const ALLOW_ONCE = "允许本次";
|
|
534
|
+
const ALLOW_SESSION = "本目录本会话允许";
|
|
535
|
+
const ALLOW_PROJECT = "本目录本项目允许";
|
|
536
|
+
const answer = (await ctx.askUser(`${title}:\n${c.resolvedPath}\n\n原因:${c.reason}\n是否允许本次操作?`, {
|
|
537
|
+
header,
|
|
538
|
+
options: [
|
|
539
|
+
{ label: ALLOW_ONCE, description: "仅允许当前这一次文件操作继续执行", tone: "ok" },
|
|
540
|
+
{
|
|
541
|
+
label: ALLOW_SESSION,
|
|
542
|
+
description: `本会话内不再询问 ${grantDir} 下的文件`,
|
|
543
|
+
tone: "ok",
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
label: ALLOW_PROJECT,
|
|
547
|
+
description: `永久允许 ${grantDir} 下的文件(写入 .code-shell/settings.local.json)`,
|
|
548
|
+
tone: "ok",
|
|
549
|
+
},
|
|
550
|
+
{ label: "拒绝", description: "阻止当前文件操作", tone: "danger" },
|
|
551
|
+
],
|
|
552
|
+
// Closed-set decision: no free-text "其它…" box. The answer is matched
|
|
553
|
+
// against the labels below by exact string, so a typed answer must not
|
|
554
|
+
// be allowed (it could never match and would silently deny).
|
|
555
|
+
optionsOnly: true,
|
|
556
|
+
})).trim();
|
|
557
|
+
if (answer === ALLOW_ONCE)
|
|
558
|
+
return null;
|
|
559
|
+
if (answer === ALLOW_SESSION) {
|
|
560
|
+
recordPathApproval("session", c.resolvedPath, operation, ctx.cwd, ctx.sessionId);
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
if (answer === ALLOW_PROJECT) {
|
|
564
|
+
recordPathApproval("project", c.resolvedPath, operation, ctx.cwd, ctx.sessionId);
|
|
565
|
+
return null;
|
|
566
|
+
}
|
|
567
|
+
return `Error: path approval denied by user — ${c.reason}. Path: ${c.resolvedPath}`;
|
|
568
|
+
}
|
|
569
|
+
/** Per-session prompt chains for enforcePathPolicyWithApproval (see comment there). */
|
|
570
|
+
const askChains = new Map();
|
|
272
571
|
/**
|
|
273
572
|
* Internal: reset the "disabled warning" latch. Tests flip the env var
|
|
274
573
|
* between cases and need each one to be able to re-trigger the warning.
|
|
@@ -34,11 +34,13 @@ export declare class AutoApprovalBackend implements ApprovalBackend {
|
|
|
34
34
|
* the next time the user opens the project.
|
|
35
35
|
*/
|
|
36
36
|
export declare class InteractiveApprovalBackend implements ApprovalBackend {
|
|
37
|
-
private
|
|
37
|
+
private sessionAllowRules;
|
|
38
|
+
private sessionDenyRules;
|
|
38
39
|
private promptFn;
|
|
39
40
|
private cwd;
|
|
40
41
|
private savedProjectRules;
|
|
41
42
|
private onProjectRules;
|
|
43
|
+
private promptTurn;
|
|
42
44
|
setPromptFn(fn: (request: ApprovalRequest) => Promise<ApprovalResult>): void;
|
|
43
45
|
/**
|
|
44
46
|
* Has someone installed a real prompt callback? Engine consults this
|
|
@@ -58,10 +60,43 @@ export declare class InteractiveApprovalBackend implements ApprovalBackend {
|
|
|
58
60
|
*/
|
|
59
61
|
setOnProjectRules(fn: (rules: PermissionRule[]) => void): void;
|
|
60
62
|
requestApproval(req: ApprovalRequest): Promise<ApprovalResult>;
|
|
63
|
+
/** Session-rule lookup — operation-scoped (see sessionAllowRules doc). Deny
|
|
64
|
+
* wins over allow if both somehow match (conservative). Null = no rule. */
|
|
65
|
+
private checkSessionRules;
|
|
66
|
+
/** The actual interactive ask + rule recording (runs inside the prompt turn). */
|
|
67
|
+
private promptAndRecord;
|
|
61
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Build the `file_path` argsPattern that narrows a remembered file-tool grant
|
|
71
|
+
* to a path scope. Pure: takes an ALREADY-RESOLVED absolute path (the caller
|
|
72
|
+
* normalizes against cwd so `../` can't slip past the prefix) and the scope.
|
|
73
|
+
*
|
|
74
|
+
* "file" → `^<esc(abs)>$` only this exact file
|
|
75
|
+
* "dir" → `^<esc(dir(abs))>/` this file's directory + subdirectories
|
|
76
|
+
* "tool" → null no narrowing (tool-wide; legacy behavior)
|
|
77
|
+
*
|
|
78
|
+
* The dir form keeps a trailing slash so `/repo/src/` can't match a sibling
|
|
79
|
+
* like `/repo/src-secret/x.ts`. Regex metacharacters in the path are escaped.
|
|
80
|
+
*/
|
|
81
|
+
export declare function pathRuleArgsPattern(absPath: string, scope: "file" | "dir" | "tool"): {
|
|
82
|
+
file_path: string;
|
|
83
|
+
} | null;
|
|
84
|
+
/**
|
|
85
|
+
* Does `rule` match this tool call? Shared by the {@link PermissionClassifier}
|
|
86
|
+
* (project/user rules) and {@link InteractiveApprovalBackend}'s session cache
|
|
87
|
+
* so the two never diverge on what "the same operation" means. Handles the
|
|
88
|
+
* JSON round-trip where a persisted RegExp comes back as a string.
|
|
89
|
+
*/
|
|
90
|
+
export declare function ruleMatches(rule: PermissionRule, toolName: string, args: Record<string, unknown>): boolean;
|
|
62
91
|
export declare function getInteractiveApprovalBackend(): InteractiveApprovalBackend;
|
|
63
92
|
export declare function setInteractiveApprovalFn(fn: (request: ApprovalRequest) => Promise<ApprovalResult>): void;
|
|
64
93
|
type BashSafetyLevel = "safe-read" | "safe-write" | "unsafe" | "dangerous";
|
|
94
|
+
/**
|
|
95
|
+
* True when an otherwise-safe-read shell segment must be downgraded to `unsafe`
|
|
96
|
+
* because it dumps the environment or reads a sensitive credential/secret path.
|
|
97
|
+
* Exported for direct unit testing of the predicate.
|
|
98
|
+
*/
|
|
99
|
+
export declare function segmentIsSensitiveRead(segment: string): boolean;
|
|
65
100
|
export declare function classifyBashCommand(command: string): BashSafetyLevel;
|
|
66
101
|
export declare class DenialTracker {
|
|
67
102
|
private denials;
|