one-code-extension 0.4.0 → 0.5.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 +219 -219
- package/agents/general-purpose.md +2 -2
- package/docs/guide/README.md +2 -1
- package/docs/guide/bring-your-claude-code-setup.md +60 -9
- package/docs/guide/configuration.md +48 -14
- package/docs/guide/differences-from-claude-code.md +32 -23
- package/docs/guide/doctor.md +20 -13
- package/docs/guide/hooks.md +18 -3
- package/docs/guide/installation.md +27 -4
- package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
- package/docs/guide/providers-and-models.md +137 -54
- package/docs/guide/reference.md +27 -15
- package/docs/guide/sessions-and-context.md +69 -16
- package/docs/guide/skills-plugins-and-mcp.md +57 -20
- package/docs/guide/subagents-and-workflows.md +95 -29
- package/docs/guide/tasks-and-background-work.md +101 -26
- package/docs/guide/terminal-interface.md +24 -12
- package/docs/guide/tools.md +46 -5
- package/docs/guide/troubleshooting.md +13 -9
- package/docs/guide/windows.md +66 -34
- package/extensions/artifacts/gallery.ts +227 -0
- package/extensions/artifacts/index.ts +288 -0
- package/extensions/artifacts/store.ts +570 -0
- package/extensions/artifacts/viewer.ts +199 -0
- package/extensions/ask-user/description.ts +67 -0
- package/extensions/ask-user/dialogs.ts +80 -0
- package/extensions/ask-user/index.ts +37 -33
- package/extensions/ask-user/questions.ts +32 -7
- package/extensions/ask-user/widget.ts +45 -25
- package/extensions/auto-mode/actions.ts +6 -0
- package/extensions/auto-mode/cache.ts +88 -0
- package/extensions/auto-mode/classifier-prompt.ts +5 -4
- package/extensions/auto-mode/classifier.ts +290 -65
- package/extensions/auto-mode/config.ts +72 -20
- package/extensions/auto-mode/decision-log.ts +2 -0
- package/extensions/auto-mode/defaults.ts +1 -1
- package/extensions/auto-mode/denials.ts +123 -0
- package/extensions/auto-mode/git-checkout-programs.ts +187 -0
- package/extensions/auto-mode/git-status-meta.ts +159 -0
- package/extensions/auto-mode/history.ts +189 -0
- package/extensions/auto-mode/instructions.ts +58 -52
- package/extensions/auto-mode/model-select.ts +159 -134
- package/extensions/auto-mode/paths.ts +57 -5
- package/extensions/auto-mode/pause.ts +57 -2
- package/extensions/auto-mode/prompt.ts +37 -21
- package/extensions/auto-mode/read-only-options.ts +724 -0
- package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
- package/extensions/auto-mode/rules.ts +18 -1
- package/extensions/auto-mode/safety-floor.ts +361 -18
- package/extensions/auto-mode/setup-run.ts +20 -14
- package/extensions/auto-mode/shell-analysis.ts +764 -490
- package/extensions/auto-mode/shell-parse.ts +885 -0
- package/extensions/auto-mode/system-note.ts +33 -0
- package/extensions/auto-mode/transcript.ts +80 -51
- package/extensions/background/cron.ts +515 -0
- package/extensions/background/index.ts +514 -236
- package/extensions/background/loop-fire.ts +136 -0
- package/extensions/background/loop-preamble.ts +59 -0
- package/extensions/background/loop-skill.ts +163 -0
- package/extensions/background/monitor-batch.ts +53 -0
- package/extensions/background/noop-fold.ts +128 -0
- package/extensions/background/switch-guard.ts +52 -0
- package/extensions/background/wakeup.ts +159 -55
- package/extensions/bash/background.ts +53 -17
- package/extensions/bash/child.ts +7 -0
- package/extensions/bash/description.ts +188 -0
- package/extensions/bash/guards.ts +15 -67
- package/extensions/bash/index.ts +88 -35
- package/extensions/branding/compaction-keep.ts +63 -0
- package/extensions/branding/declined.ts +22 -0
- package/extensions/branding/index.ts +133 -9
- package/extensions/branding/prompt-editor.ts +53 -6
- package/extensions/branding/queued-edit.ts +31 -0
- package/extensions/branding/replaced-builtins.ts +68 -0
- package/extensions/branding/startup.ts +33 -71
- package/extensions/btw/index.ts +229 -71
- package/extensions/btw/panel.ts +228 -100
- package/extensions/btw/prompt.ts +41 -4
- package/extensions/claude-compat/index.ts +7 -11
- package/extensions/claude-context/index.ts +446 -58
- package/extensions/compaction/cut.ts +157 -0
- package/extensions/compaction/index.ts +216 -75
- package/extensions/compaction/kept-thinking.ts +62 -0
- package/extensions/compaction/prompt.ts +15 -12
- package/extensions/context-budget/index.ts +24 -5
- package/extensions/context-management/index.ts +25 -0
- package/extensions/doctor/build.ts +59 -8
- package/extensions/doctor/builtins.ts +84 -0
- package/extensions/doctor/cli.ts +7 -1
- package/extensions/doctor/compat.ts +88 -23
- package/extensions/doctor/dependencies.ts +41 -5
- package/extensions/doctor/fix-prompt.ts +9 -2
- package/extensions/doctor/index.ts +102 -58
- package/extensions/doctor/models.ts +102 -63
- package/extensions/doctor/presets.ts +42 -27
- package/extensions/doctor/report.ts +19 -2
- package/extensions/doctor/viewer.ts +49 -27
- package/extensions/effort/index.ts +72 -19
- package/extensions/effort/settings.ts +21 -0
- package/extensions/effort/slider.ts +24 -20
- package/extensions/exit/index.ts +32 -1
- package/extensions/file-tracker/index.ts +337 -26
- package/extensions/file-tracker/replay.ts +96 -10
- package/extensions/file-tracker/restore.ts +63 -0
- package/extensions/file-tracker/results.ts +66 -0
- package/extensions/file-tracker/shell-reads.ts +211 -0
- package/extensions/file-tracker/tracker.ts +32 -15
- package/extensions/footer/footer-line.ts +45 -24
- package/extensions/footer/index.ts +47 -2
- package/extensions/footer/pr.ts +34 -5
- package/extensions/hooks/compaction.ts +7 -0
- package/extensions/hooks/executor.ts +32 -30
- package/extensions/hooks/index.ts +198 -31
- package/extensions/hooks/matcher.ts +3 -0
- package/extensions/hooks/protocol.ts +41 -3
- package/extensions/hooks/settings.ts +50 -19
- package/extensions/hooks/subagent-bridge.ts +2 -0
- package/extensions/hooks/trust.ts +13 -5
- package/extensions/idle-compact/index.ts +119 -0
- package/extensions/idle-compact/policy.ts +143 -0
- package/extensions/init/index.ts +11 -10
- package/extensions/init/prompt.ts +25 -32
- package/extensions/interrupted/index.ts +13 -1
- package/extensions/kept-thinking/index.ts +27 -0
- package/extensions/lib/agent-cron.ts +130 -0
- package/extensions/lib/agent-loader.ts +15 -1
- package/extensions/lib/agent-view.ts +85 -0
- package/extensions/lib/anthropic-payload.ts +82 -1
- package/extensions/lib/anthropic-server-call.ts +230 -0
- package/extensions/lib/anthropic-server-tools.ts +485 -0
- package/extensions/lib/app-launch.mjs +94 -0
- package/extensions/lib/argument-hints.ts +190 -0
- package/extensions/lib/atomic-write.ts +6 -2
- package/extensions/lib/auto-memory.ts +75 -0
- package/extensions/lib/bash-parser.ts +84 -0
- package/extensions/lib/btw-fork.ts +93 -0
- package/extensions/lib/child-extensions.ts +42 -0
- package/extensions/lib/child-writes.ts +45 -0
- package/extensions/lib/claude-context.ts +515 -100
- package/extensions/lib/claude-external-includes.ts +68 -0
- package/extensions/lib/claude-id.ts +22 -0
- package/extensions/lib/claude-rules.ts +323 -0
- package/extensions/lib/claude-settings.ts +76 -4
- package/extensions/lib/compaction-boundary.ts +36 -0
- package/extensions/lib/compaction-keep.mjs +83 -0
- package/extensions/lib/config-mode.ts +112 -0
- package/extensions/lib/consent-dialogs.ts +63 -0
- package/extensions/lib/consent-preview.ts +5 -1
- package/extensions/lib/consent-stores.ts +48 -0
- package/extensions/lib/context-facts.ts +78 -0
- package/extensions/lib/context-stack.ts +81 -0
- package/extensions/lib/deferred.ts +219 -25
- package/extensions/lib/dock-rows.ts +60 -0
- package/extensions/lib/empty-tool-result.ts +27 -0
- package/extensions/lib/environment-block.ts +76 -0
- package/extensions/lib/fetch-timeout.ts +24 -6
- package/extensions/{system-prompt → lib}/git-status.ts +51 -13
- package/extensions/lib/git.ts +75 -13
- package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
- package/extensions/lib/grammars/README.md +2 -0
- package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
- package/extensions/lib/guide-docs.ts +45 -0
- package/extensions/lib/headless-output.ts +46 -0
- package/extensions/lib/hook-gate.ts +7 -7
- package/extensions/lib/interrupt.ts +20 -4
- package/extensions/lib/key-input.ts +455 -0
- package/extensions/lib/keys.ts +14 -1
- package/extensions/lib/local-command.ts +47 -13
- package/extensions/lib/mcp-overrides.ts +1 -1
- package/extensions/lib/mcp-share.ts +46 -0
- package/extensions/lib/memory-content.ts +146 -0
- package/extensions/lib/memory-index.ts +18 -0
- package/extensions/lib/memory.ts +134 -123
- package/extensions/lib/model-catalog/huggingface.json +174 -0
- package/extensions/lib/model-catalog/models-dev.json +18297 -0
- package/extensions/lib/model-catalog/openrouter.json +5252 -0
- package/extensions/lib/model-catalog-data.ts +513 -0
- package/extensions/lib/model-catalog.ts +462 -0
- package/extensions/lib/model-choice-warnings.ts +137 -0
- package/extensions/lib/model-pairings.ts +152 -0
- package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
- package/extensions/lib/model-policy.ts +112 -15
- package/extensions/lib/model-tier.ts +283 -355
- package/extensions/lib/model-unusable.ts +1 -1
- package/extensions/lib/newer-model.ts +100 -0
- package/extensions/lib/notices.ts +87 -0
- package/extensions/lib/notifications.ts +308 -64
- package/extensions/lib/one-code-settings.ts +74 -8
- package/extensions/lib/open-browser.ts +63 -0
- package/extensions/lib/openrouter-generation.ts +94 -0
- package/extensions/lib/operation-deadline.ts +30 -0
- package/extensions/lib/original-command.ts +4 -4
- package/extensions/lib/package-version.ts +1 -1
- package/extensions/lib/panel-focus.ts +134 -0
- package/extensions/lib/paths.ts +17 -2
- package/extensions/lib/permission-gate.ts +72 -6
- package/extensions/lib/persisted-output.ts +60 -8
- package/extensions/lib/pi-ai-estimate.ts +19 -3
- package/extensions/lib/pi-version.ts +21 -2
- package/extensions/lib/plan-mode-channels.ts +20 -5
- package/extensions/lib/plugins.ts +26 -17
- package/extensions/lib/powershell-parse-script.ts +208 -0
- package/extensions/lib/powershell-parser.ts +344 -0
- package/extensions/lib/process-tree.ts +131 -8
- package/extensions/lib/prompt-options.ts +82 -0
- package/extensions/lib/queued-delivery.ts +44 -0
- package/extensions/lib/reminders.ts +364 -58
- package/extensions/lib/replaced-builtins.mjs +199 -0
- package/extensions/lib/replay-call.ts +70 -0
- package/extensions/lib/request-replay.ts +439 -0
- package/extensions/lib/scratchpad.ts +81 -14
- package/extensions/lib/send-now-channel.ts +7 -0
- package/extensions/lib/session-model-tier.ts +51 -0
- package/extensions/lib/session-work.ts +64 -0
- package/extensions/lib/settings-channels.ts +4 -4
- package/extensions/lib/shell-exit-semantics.ts +170 -0
- package/extensions/lib/shell-quote.ts +11 -0
- package/extensions/lib/shell-result.ts +70 -0
- package/extensions/lib/shell-spawn.ts +70 -6
- package/extensions/lib/shell-tool.ts +75 -25
- package/extensions/lib/side-call-cache.ts +124 -0
- package/extensions/lib/side-call-run.ts +96 -0
- package/extensions/lib/side-call-usage.ts +38 -0
- package/extensions/lib/side-call.ts +13 -1
- package/extensions/lib/single-flight.ts +18 -0
- package/extensions/lib/skill-body.ts +42 -0
- package/extensions/lib/skill-scan.ts +63 -24
- package/extensions/lib/spill-file.ts +140 -0
- package/extensions/lib/subagent-handback.ts +113 -0
- package/extensions/lib/system-role.ts +156 -0
- package/extensions/lib/terminal-text.ts +114 -0
- package/extensions/lib/text-width.ts +47 -16
- package/extensions/lib/timer-ops.ts +20 -0
- package/extensions/lib/tool-additions.ts +149 -0
- package/extensions/lib/tool-call-corruption.ts +134 -0
- package/extensions/lib/tool-path.ts +66 -0
- package/extensions/lib/tool-variants.ts +69 -0
- package/extensions/lib/tui-render.ts +255 -27
- package/extensions/lib/turn-budget-layout.ts +143 -0
- package/extensions/lib/update-check.mjs +15 -2
- package/extensions/lib/usage-bus.ts +1 -1
- package/extensions/lib/user-denial.ts +38 -0
- package/extensions/lib/workspace-channel.ts +16 -0
- package/extensions/lib/worktree-channel.ts +31 -3
- package/extensions/lib/worktree-isolation.ts +40 -10
- package/extensions/lsp/client.ts +8 -9
- package/extensions/lsp/index.ts +70 -4
- package/extensions/lsp/keep-alive.ts +1 -1
- package/extensions/lsp/trust.ts +119 -0
- package/extensions/lsp/watcher.ts +1 -1
- package/extensions/mcp/announce.ts +87 -5
- package/extensions/mcp/client.ts +161 -48
- package/extensions/mcp/config.ts +132 -8
- package/extensions/mcp/discovery.ts +19 -0
- package/extensions/mcp/index.ts +209 -71
- package/extensions/mcp/oauth/browser.ts +38 -17
- package/extensions/mcp/oauth/flow.ts +25 -17
- package/extensions/mcp/oauth/provider.ts +14 -8
- package/extensions/mcp/oauth/store.ts +34 -16
- package/extensions/mcp/panel/keys.ts +12 -11
- package/extensions/mcp/panel/render.ts +9 -6
- package/extensions/mcp/schema.ts +104 -5
- package/extensions/mcp/trust.ts +151 -67
- package/extensions/memory/entries.ts +23 -14
- package/extensions/memory/index.ts +134 -28
- package/extensions/memory/open-external.ts +33 -18
- package/extensions/memory/panel.ts +135 -26
- package/extensions/newer-model/index.ts +31 -0
- package/extensions/notebook/description.ts +18 -0
- package/extensions/notebook/index.ts +6 -5
- package/extensions/notebook/notebook.ts +1 -1
- package/extensions/permissions/index.ts +1300 -381
- package/extensions/permissions/matcher.ts +425 -74
- package/extensions/permissions/modes.ts +6 -4
- package/extensions/permissions/panel/host.ts +130 -0
- package/extensions/permissions/panel/keys.ts +48 -0
- package/extensions/permissions/panel/render.ts +450 -0
- package/extensions/permissions/panel/state.ts +550 -0
- package/extensions/permissions/powershell-cmdlets.ts +198 -0
- package/extensions/permissions/powershell-paths.ts +197 -0
- package/extensions/permissions/powershell-rules.ts +207 -280
- package/extensions/permissions/powershell-tree.ts +557 -0
- package/extensions/permissions/project-trust.ts +27 -11
- package/extensions/permissions/protected-paths.ts +14 -2
- package/extensions/permissions/session-grant.ts +6 -0
- package/extensions/permissions/settings.ts +166 -31
- package/extensions/permissions/subagent-gate.ts +25 -0
- package/extensions/permissions/workspace.ts +78 -0
- package/extensions/plan-mode/index.ts +156 -69
- package/extensions/plan-mode/reminder.ts +89 -21
- package/extensions/plan-mode/texts.ts +177 -0
- package/extensions/plan-mode/viewer.ts +92 -27
- package/extensions/plugins/counts.ts +3 -3
- package/extensions/plugins/index.ts +61 -46
- package/extensions/plugins/install/install.ts +16 -0
- package/extensions/plugins/marketplace/sync.ts +9 -3
- package/extensions/plugins/marketplace/types.ts +3 -1
- package/extensions/plugins/panel/keys.ts +21 -24
- package/extensions/plugins/panel/render.ts +12 -6
- package/extensions/plugins/shell-expand.ts +107 -0
- package/extensions/plugins/template.ts +32 -15
- package/extensions/powershell/child.ts +7 -0
- package/extensions/powershell/description.ts +38 -6
- package/extensions/powershell/guards.ts +1 -1
- package/extensions/powershell/index.ts +12 -7
- package/extensions/recap/index.ts +65 -60
- package/extensions/recap/prompt.ts +2 -2
- package/extensions/recap/scheduler.ts +3 -5
- package/extensions/search-tools/grep-merge.ts +39 -0
- package/extensions/search-tools/index.ts +0 -0
- package/extensions/send-now/chord.ts +62 -0
- package/extensions/send-now/index.ts +133 -0
- package/extensions/session-title/index.ts +3 -0
- package/extensions/session-title/title.ts +4 -1
- package/extensions/skill/code-review.ts +97 -0
- package/extensions/skill/index.ts +421 -101
- package/extensions/skill/invoke.ts +128 -18
- package/extensions/skill/listing.ts +133 -9
- package/extensions/skill/panel/keys.ts +15 -16
- package/extensions/skill/panel/render.ts +5 -2
- package/extensions/skill/panel/state.ts +12 -1
- package/extensions/subagents/agent-args.ts +39 -0
- package/extensions/subagents/agent-description.ts +132 -0
- package/extensions/subagents/agents.ts +116 -23
- package/extensions/subagents/announce.ts +69 -0
- package/extensions/subagents/default-model.ts +2 -3
- package/extensions/subagents/delegation-steer.ts +4 -4
- package/extensions/subagents/fork-cache.ts +76 -0
- package/extensions/subagents/guide-agent.ts +189 -0
- package/extensions/subagents/hand-back-review.ts +3 -0
- package/extensions/subagents/index.ts +1493 -824
- package/extensions/subagents/live-runs.ts +26 -6
- package/extensions/subagents/model-select.ts +38 -25
- package/extensions/subagents/outcome.ts +2 -2
- package/extensions/subagents/panel-keys.ts +73 -31
- package/extensions/subagents/panel-render.ts +120 -96
- package/extensions/subagents/panel-widget.ts +60 -89
- package/extensions/subagents/runner.ts +108 -80
- package/extensions/subagents/runs.ts +39 -5
- package/extensions/subagents/send-to-main-tool.ts +1 -1
- package/extensions/subagents/session-turns.ts +32 -8
- package/extensions/subagents/shell-panel.ts +36 -178
- package/extensions/subagents/tasks-dialog.ts +170 -0
- package/extensions/subagents/viewport-mirror.ts +95 -0
- package/extensions/subagents/worktree.ts +57 -13
- package/extensions/system-prompt/environment.ts +19 -19
- package/extensions/system-prompt/idle-turn.ts +65 -0
- package/extensions/system-prompt/index.ts +131 -47
- package/extensions/system-prompt/template.ts +24 -50
- package/extensions/system-prompt/tiers/common.ts +23 -64
- package/extensions/system-prompt/tiers/frontier.ts +32 -11
- package/extensions/system-prompt/tiers/low.ts +67 -45
- package/extensions/system-prompt/tiers/mid.ts +96 -38
- package/extensions/system-reminder/index.ts +175 -13
- package/extensions/tasks/descriptions.ts +190 -0
- package/extensions/tasks/index.ts +120 -41
- package/extensions/tasks/store.ts +83 -16
- package/extensions/tool-call-corruption/child.ts +7 -0
- package/extensions/tool-call-corruption/index.ts +237 -0
- package/extensions/tool-search/announce.ts +16 -0
- package/extensions/tool-search/index.ts +189 -41
- package/extensions/tool-style/index.ts +68 -10
- package/extensions/tool-style/write-description.ts +40 -0
- package/extensions/tool-style/write-render.ts +237 -0
- package/extensions/turn-duration/index.ts +7 -3
- package/extensions/turn-duration/line.ts +47 -4
- package/extensions/web/backends.ts +6 -9
- package/extensions/web/description.ts +50 -0
- package/extensions/web/index.ts +118 -53
- package/extensions/web/native-call.ts +15 -0
- package/extensions/web/native-results.ts +41 -0
- package/extensions/web-fetch/description.ts +42 -0
- package/extensions/web-fetch/extract.ts +53 -6
- package/extensions/web-fetch/index.ts +125 -76
- package/extensions/web-fetch/page-content.ts +19 -0
- package/extensions/web-fetch/response.ts +49 -0
- package/extensions/web-fetch/summarize.ts +9 -10
- package/extensions/workflow/agent-session.ts +105 -18
- package/extensions/workflow/args.ts +24 -0
- package/extensions/workflow/description.ts +67 -0
- package/extensions/workflow/globals.ts +17 -3
- package/extensions/workflow/index.ts +145 -162
- package/extensions/workflow/records.ts +1 -0
- package/extensions/workflow/run-manager.ts +29 -6
- package/extensions/workflow/saved-workflows.ts +3 -2
- package/extensions/workflow/types.ts +22 -1
- package/extensions/workflow/viewer.ts +54 -24
- package/extensions/workflow/widget.ts +20 -0
- package/extensions/worktree/descriptions.ts +91 -0
- package/extensions/worktree/guards.ts +316 -54
- package/extensions/worktree/index.ts +121 -39
- package/extensions/worktree/powershell-guards.ts +167 -0
- package/extensions/worktree/rewrite.ts +14 -16
- package/package.json +19 -7
- package/skills/artifact-design/SKILL.md +85 -0
- package/skills/code-review/SKILL.md +20 -20
- package/skills/code-review/cells/arguments-and-flags.md +19 -0
- package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
- package/skills/code-review/cells/high-8-inline.md +122 -0
- package/skills/code-review/cells/low-1-pass-max4.md +27 -0
- package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
- package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
- package/skills/code-review/cells/medium-3x5-verify.md +132 -0
- package/skills/code-review/cells/minimal-prompt.md +32 -0
- package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
- package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
- package/skills/fewer-permission-prompts/SKILL.md +1 -1
- package/skills/loop/SKILL.md +11 -0
- package/skills/security-review/SKILL.md +2 -5
- package/skills/simplify/SKILL.md +7 -5
- package/skills/workflow-authoring/SKILL.md +143 -0
- package/themes/onecode-light.json +1 -1
- package/themes/onecode.json +1 -1
- package/types/app.d.ts +58 -0
- package/types/community-packages.d.ts +26 -1
- package/extensions/auto-mode/recoverability.ts +0 -229
- package/extensions/lib/capability-index.ts +0 -466
- package/extensions/lib/model-facts.generated.json +0 -2675
- package/extensions/lib/model-facts.ts +0 -162
|
@@ -18,14 +18,11 @@
|
|
|
18
18
|
* Unknown keys in the files are preserved on write.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
readSettingsForWrite,
|
|
27
|
-
writeSettings,
|
|
28
|
-
} from "../lib/one-code-settings.ts";
|
|
21
|
+
import { readSettingsFile as readClaudeSettingsFile, type SettingsSource, settingsPaths, settingsSources } from "../lib/claude-settings.ts";
|
|
22
|
+
import { readSettingsForWrite, writeSettings } from "../lib/one-code-settings.ts";
|
|
23
|
+
import { resolve } from "node:path";
|
|
24
|
+
import { claudeSourcesOn } from "../lib/config-mode.ts";
|
|
25
|
+
import { expandTilde } from "../lib/paths.ts";
|
|
29
26
|
import type { PermissionMode } from "./matcher.ts";
|
|
30
27
|
|
|
31
28
|
export { settingsPaths };
|
|
@@ -51,6 +48,12 @@ export interface PermissionSettings {
|
|
|
51
48
|
* may set it — the repo included.
|
|
52
49
|
*/
|
|
53
50
|
disableBypassPermissionsMode?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Claude Code's `permissions.blockReadsOutsideWorkingDirectories: true` seen
|
|
53
|
+
* in any source: the read tools refuse a path outside the working
|
|
54
|
+
* directories, in every mode. A restriction, so every scope may set it.
|
|
55
|
+
*/
|
|
56
|
+
blockReadsOutsideWorkingDirectories?: boolean;
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
interface ClaudeSettingsFile {
|
|
@@ -58,8 +61,10 @@ interface ClaudeSettingsFile {
|
|
|
58
61
|
allow?: string[];
|
|
59
62
|
deny?: string[];
|
|
60
63
|
ask?: string[];
|
|
64
|
+
additionalDirectories?: string[];
|
|
61
65
|
defaultMode?: string;
|
|
62
66
|
disableBypassPermissionsMode?: string;
|
|
67
|
+
blockReadsOutsideWorkingDirectories?: boolean;
|
|
63
68
|
};
|
|
64
69
|
[key: string]: unknown;
|
|
65
70
|
}
|
|
@@ -101,34 +106,28 @@ function readSettingsFile(path: string): ClaudeSettingsFile | undefined {
|
|
|
101
106
|
}
|
|
102
107
|
|
|
103
108
|
export function loadPermissionSettings(cwd: string, home: string): PermissionSettings {
|
|
104
|
-
const paths = settingsPaths(cwd, home);
|
|
105
109
|
const merged: PermissionSettings = { allow: [], projectAllow: [], deny: [], ask: [] };
|
|
106
|
-
|
|
107
|
-
// One Code
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
const oneCodeProject = oneCodeProjectSettingsPath(cwd, home);
|
|
114
|
-
|
|
115
|
-
// Managed settings last: Claude Code's organisation policy outranks every
|
|
116
|
-
// user/project file, for rules and for defaultMode alike (review P14).
|
|
117
|
-
const managed = managedSettingsPaths();
|
|
118
|
-
for (const path of [paths.user, oneCodeGlobal, paths.project, paths.local, oneCodeProject, ...managed]) {
|
|
110
|
+
// `defaultMode` comes from the user-scope file Claude Code's keys live in
|
|
111
|
+
// (`~/.claude/settings.json`, or One Code's own in independent mode,
|
|
112
|
+
// lib/config-mode.ts), project files and managed settings. One Code's other
|
|
113
|
+
// file only adds the rules it records (via /allow, the auto-mode setup),
|
|
114
|
+
// keeping the auto-mode reasoning to one place.
|
|
115
|
+
const userScope = claudeSourcesOn() ? "claude-user" : "onecode-user";
|
|
116
|
+
for (const [source, path] of settingsSources(cwd, home)) {
|
|
119
117
|
const file = readSettingsFile(path);
|
|
120
118
|
const perms = file?.permissions;
|
|
121
119
|
if (!perms) continue;
|
|
122
|
-
const
|
|
120
|
+
const fromProject = source === "project" || source === "project-local";
|
|
121
|
+
const allowTarget = fromProject ? merged.projectAllow : merged.allow;
|
|
123
122
|
if (Array.isArray(perms.allow)) allowTarget.push(...perms.allow.filter((r) => typeof r === "string"));
|
|
124
123
|
if (Array.isArray(perms.deny)) merged.deny.push(...perms.deny.filter((r) => typeof r === "string"));
|
|
125
124
|
if (Array.isArray(perms.ask)) merged.ask.push(...perms.ask.filter((r) => typeof r === "string"));
|
|
126
125
|
if (perms.disableBypassPermissionsMode === "disable") merged.disableBypassPermissionsMode = true;
|
|
127
|
-
if (
|
|
126
|
+
if (perms.blockReadsOutsideWorkingDirectories === true) merged.blockReadsOutsideWorkingDirectories = true;
|
|
127
|
+
if (source.startsWith("onecode-") && source !== userScope) continue;
|
|
128
128
|
const defaultMode = normalizePermissionMode(perms.defaultMode);
|
|
129
129
|
// The modes a repo may not grant itself (MODES_NEVER_FROM_PROJECT) are
|
|
130
130
|
// honoured from user and managed scope only.
|
|
131
|
-
const fromProject = path === paths.project || path === paths.local;
|
|
132
131
|
if (defaultMode && !(fromProject && MODES_NEVER_FROM_PROJECT.has(defaultMode))) {
|
|
133
132
|
merged.defaultMode = defaultMode;
|
|
134
133
|
}
|
|
@@ -162,16 +161,152 @@ export function resolveStartupMode(
|
|
|
162
161
|
return { bypassRefused };
|
|
163
162
|
}
|
|
164
163
|
|
|
164
|
+
export type RuleBehavior = "allow" | "ask" | "deny";
|
|
165
|
+
|
|
166
|
+
/** Where a permission rule was read from, for the `/permissions` panel. */
|
|
167
|
+
export type RuleSource = SettingsSource;
|
|
168
|
+
|
|
169
|
+
export interface SourcedRule {
|
|
170
|
+
behavior: RuleBehavior;
|
|
171
|
+
raw: string;
|
|
172
|
+
source: RuleSource;
|
|
173
|
+
/** The settings file the rule is in. */
|
|
174
|
+
path: string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface SourcedDirectory {
|
|
178
|
+
/** As written in the settings file. */
|
|
179
|
+
raw: string;
|
|
180
|
+
/** Absolute: `~` expanded, a relative entry resolved against the working directory. */
|
|
181
|
+
path: string;
|
|
182
|
+
source: RuleSource;
|
|
183
|
+
/** The settings file it is in. */
|
|
184
|
+
settingsPath: string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Claude Code's `permissions.additionalDirectories`, from every source, with
|
|
189
|
+
* the file each came from. The caller decides which sources are trusted: a
|
|
190
|
+
* repository's own files are applied only after the user trusts them.
|
|
191
|
+
*/
|
|
192
|
+
export function listWorkspaceDirectories(cwd: string, home: string): SourcedDirectory[] {
|
|
193
|
+
const dirs: SourcedDirectory[] = [];
|
|
194
|
+
for (const [source, settingsPath] of settingsSources(cwd, home)) {
|
|
195
|
+
const list = readSettingsFile(settingsPath)?.permissions?.additionalDirectories;
|
|
196
|
+
if (!Array.isArray(list)) continue;
|
|
197
|
+
for (const raw of list) {
|
|
198
|
+
if (typeof raw !== "string" || !raw.trim()) continue;
|
|
199
|
+
dirs.push({ raw, path: resolve(cwd, expandTilde(raw.trim(), home)), source, settingsPath });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return dirs;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Add a directory to a One Code settings file's `permissions.additionalDirectories`. */
|
|
206
|
+
export function persistWorkspaceDirectory(dir: string, filePath: string): void {
|
|
207
|
+
addToPermissionsList("additionalDirectories", dir, filePath);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Remove a directory, as written, from a One Code settings file. False when it is not there. */
|
|
211
|
+
export function removeWorkspaceDirectory(raw: string, filePath: string): boolean {
|
|
212
|
+
return removeFromPermissionsList("additionalDirectories", raw, filePath);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Every permission rule with the file it came from, in load order (the order
|
|
217
|
+
* `loadPermissionSettings` merges them). The panel lists them and can delete a
|
|
218
|
+
* rule from One Code's own files only: One Code never edits Claude Code's
|
|
219
|
+
* files, the repository's or managed policy.
|
|
220
|
+
*/
|
|
221
|
+
export function listPermissionRules(cwd: string, home: string): SourcedRule[] {
|
|
222
|
+
const rules: SourcedRule[] = [];
|
|
223
|
+
for (const [source, path] of settingsSources(cwd, home)) {
|
|
224
|
+
const perms = readSettingsFile(path)?.permissions;
|
|
225
|
+
if (!perms) continue;
|
|
226
|
+
for (const behavior of ["allow", "ask", "deny"] as const) {
|
|
227
|
+
const list = perms[behavior];
|
|
228
|
+
if (!Array.isArray(list)) continue;
|
|
229
|
+
for (const raw of list) if (typeof raw === "string") rules.push({ behavior, raw, source, path });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return rules;
|
|
233
|
+
}
|
|
234
|
+
|
|
165
235
|
/**
|
|
166
|
-
* Append
|
|
236
|
+
* Append a rule to a One Code settings file, creating it if needed.
|
|
167
237
|
* Strict read + atomic write, like the other `~/.onecode` writers: a malformed
|
|
168
|
-
* file is not silently clobbered (it may also hold
|
|
169
|
-
* and a half-written file is never visible to a concurrent reader.
|
|
238
|
+
* file is not silently clobbered (it may also hold a subagent model setting),
|
|
239
|
+
* and a half-written file is never visible to a concurrent reader. Returns
|
|
240
|
+
* false, writing nothing, when the file already holds the rule.
|
|
170
241
|
*/
|
|
242
|
+
export function persistPermissionRule(behavior: RuleBehavior, rule: string, filePath: string): boolean {
|
|
243
|
+
return addToPermissionsList(behavior, rule, filePath);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** `persistPermissionRule` for an allow rule (`/allow`). */
|
|
171
247
|
export function persistAllowRule(rule: string, filePath: string): void {
|
|
248
|
+
persistPermissionRule("allow", rule, filePath);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Remove every copy of a rule from a One Code settings file. Returns false,
|
|
253
|
+
* writing nothing, when the file does not hold it. An emptied list is kept as
|
|
254
|
+
* `[]`, and the file's other keys are preserved.
|
|
255
|
+
*/
|
|
256
|
+
export function removePermissionRule(behavior: RuleBehavior, rule: string, filePath: string): boolean {
|
|
257
|
+
return removeFromPermissionsList(behavior, rule, filePath);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* The "Block" answer to the first outside-read prompt: Claude Code writes
|
|
262
|
+
* `permissions.blockReadsOutsideWorkingDirectories: true` to its user
|
|
263
|
+
* settings; One Code writes it to its own (`filePath`, the One Code global
|
|
264
|
+
* file), since it never writes `~/.claude`.
|
|
265
|
+
*/
|
|
266
|
+
export function persistBlockOutsideReads(filePath: string): void {
|
|
267
|
+
const file = readSettingsForWrite(filePath) as ClaudeSettingsFile;
|
|
268
|
+
(file.permissions ??= {}).blockReadsOutsideWorkingDirectories = true;
|
|
269
|
+
writeSettings(filePath, file as Record<string, unknown>);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Whether the first outside-read prompt was answered on this machine: One
|
|
274
|
+
* Code's own flag in its global settings, or Claude Code's
|
|
275
|
+
* `hasSeenAutoModeOutsideReadPrompt` in `~/.claude.json` (read only), so a
|
|
276
|
+
* user who answered it in Claude Code is not asked again.
|
|
277
|
+
*/
|
|
278
|
+
/** Whether the first outside-read prompt was answered; `claudeJson` is undefined in independent mode. */
|
|
279
|
+
export function outsideReadPromptSeen(oneCodeSettings: string, claudeJson: string | undefined): boolean {
|
|
280
|
+
const seen = (path: string) => (readClaudeSettingsFile(path) as { hasSeenAutoModeOutsideReadPrompt?: unknown } | undefined)?.hasSeenAutoModeOutsideReadPrompt === true;
|
|
281
|
+
return seen(oneCodeSettings) || (claudeJson !== undefined && seen(claudeJson));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** Record that the first outside-read prompt was answered (Claude Code's key, in One Code's file). */
|
|
285
|
+
export function markOutsideReadPromptSeen(oneCodeSettings: string): void {
|
|
286
|
+
const file = readSettingsForWrite(oneCodeSettings);
|
|
287
|
+
if (file.hasSeenAutoModeOutsideReadPrompt === true) return;
|
|
288
|
+
file.hasSeenAutoModeOutsideReadPrompt = true;
|
|
289
|
+
writeSettings(oneCodeSettings, file);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** A string list under `permissions` that One Code edits in its own files. */
|
|
293
|
+
type PermissionsList = RuleBehavior | "additionalDirectories";
|
|
294
|
+
|
|
295
|
+
/** False, writing nothing, when the list already holds `value`. */
|
|
296
|
+
function addToPermissionsList(field: PermissionsList, value: string, filePath: string): boolean {
|
|
297
|
+
const file = readSettingsForWrite(filePath) as ClaudeSettingsFile;
|
|
298
|
+
const list = ((file.permissions ??= {})[field] ??= []);
|
|
299
|
+
if (list.includes(value)) return false;
|
|
300
|
+
list.push(value);
|
|
301
|
+
writeSettings(filePath, file as Record<string, unknown>);
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function removeFromPermissionsList(field: PermissionsList, value: string, filePath: string): boolean {
|
|
172
306
|
const file = readSettingsForWrite(filePath) as ClaudeSettingsFile;
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
307
|
+
const list = file.permissions?.[field];
|
|
308
|
+
if (!Array.isArray(list) || !list.includes(value)) return false;
|
|
309
|
+
file.permissions![field] = list.filter((entry) => entry !== value);
|
|
176
310
|
writeSettings(filePath, file as Record<string, unknown>);
|
|
311
|
+
return true;
|
|
177
312
|
}
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* same shape as `MCP_TOOLS_CHANNEL` sharing tool definitions).
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
22
23
|
import { type BridgeWatchApi, watchBridge } from "../lib/bridge-watch.ts";
|
|
23
24
|
|
|
24
25
|
export const SUBAGENT_GATE_CHANNEL = "one-code:subagent-permission-gate";
|
|
@@ -37,8 +38,21 @@ export interface ChildToolCall {
|
|
|
37
38
|
signal?: AbortSignal;
|
|
38
39
|
/** The child session's id (what the gate can see); the runner maps it to `agent`. */
|
|
39
40
|
sessionId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* The child's own model (its session state, never the model's to write). The
|
|
43
|
+
* gate judges a child's call by this model's tier, not the parent's.
|
|
44
|
+
*/
|
|
45
|
+
model?: Model<Api>;
|
|
40
46
|
/** The run name of the asking agent, for the prompt title — set by the runner, not the gate. */
|
|
41
47
|
agent?: string;
|
|
48
|
+
/**
|
|
49
|
+
* The main session's tool call that started the asking child's current turn
|
|
50
|
+
* (its Agent call, or a later SendMessage), set by the runner from its own
|
|
51
|
+
* state, never from tool input. The classifier reads the main session as far
|
|
52
|
+
* as that call, not the rest of a batch still in flight
|
|
53
|
+
* (auto-mode/history.ts childHistoryCursor).
|
|
54
|
+
*/
|
|
55
|
+
parentToolCallId?: string;
|
|
42
56
|
}
|
|
43
57
|
|
|
44
58
|
/** A permission decision: `undefined` = allow; otherwise block with a model-facing reason. */
|
|
@@ -47,6 +61,17 @@ export type ChildGateDecision = { block: true; reason: string } | undefined;
|
|
|
47
61
|
/** The parent's decision closure, threaded into a child's permission gate. */
|
|
48
62
|
export type PermissionBridge = (call: ChildToolCall) => Promise<ChildGateDecision>;
|
|
49
63
|
|
|
64
|
+
/** Bind a bridge to one parent session; neither stopped children nor stale approvals may run. */
|
|
65
|
+
export function sessionPermissionBridge(evaluate: PermissionBridge, parentSignal: AbortSignal): PermissionBridge {
|
|
66
|
+
return async (call) => {
|
|
67
|
+
const signal = call.signal ? AbortSignal.any([parentSignal, call.signal]) : parentSignal;
|
|
68
|
+
const stopped: ChildGateDecision = { block: true, reason: "The agent or its parent permission session has stopped; denied to fail safe." };
|
|
69
|
+
if (signal.aborted) return stopped;
|
|
70
|
+
const result = await evaluate({ ...call, signal });
|
|
71
|
+
return signal.aborted ? stopped : result;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
50
75
|
export interface SubagentGatePayload {
|
|
51
76
|
decide: PermissionBridge;
|
|
52
77
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace directories: Claude Code's additional working directories
|
|
3
|
+
* (`permissions.additionalDirectories`, `--add-dir`, `/add-dir`, the
|
|
4
|
+
* /permissions Workspace tab). Pure apart from the filesystem check in
|
|
5
|
+
* `validateWorkspaceDirectory`.
|
|
6
|
+
*
|
|
7
|
+
* What one grants here (working-docs/decisions/modes.md, "Workspace
|
|
8
|
+
* directories"): reads inside it are working-space reads in every mode, and
|
|
9
|
+
* acceptEdits may write inside it. Auto mode's unclassified writes and
|
|
10
|
+
* deletions stay confined to the working directory, a credential path inside
|
|
11
|
+
* one is never a working-space read, and a directory from the repository's
|
|
12
|
+
* own settings applies only after the user trusts the repository.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { statSync } from "node:fs";
|
|
16
|
+
import { delimiter, parse, resolve } from "node:path";
|
|
17
|
+
import { expandTilde, tryRealpath } from "../lib/paths.ts";
|
|
18
|
+
import { isWithin } from "../auto-mode/paths.ts";
|
|
19
|
+
|
|
20
|
+
export type ValidatedDirectory = { path: string } | { error: string };
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Check a directory the user wants to add, as Claude Code's
|
|
24
|
+
* `validateDirectoryForWorkspace` does: it must exist and be a directory, and
|
|
25
|
+
* must not already be covered by the working directory or another workspace
|
|
26
|
+
* directory. One Code also refuses the filesystem root and the home directory
|
|
27
|
+
* itself, which would make almost every read on the machine a working-space
|
|
28
|
+
* read. `existing` holds the directories already in the workspace.
|
|
29
|
+
*/
|
|
30
|
+
export function validateWorkspaceDirectory(input: string, cwd: string, home: string, existing: readonly string[]): ValidatedDirectory {
|
|
31
|
+
const trimmed = input.trim();
|
|
32
|
+
if (!trimmed) return { error: "Enter a directory path." };
|
|
33
|
+
const spelled = resolve(cwd, expandTilde(trimmed, home));
|
|
34
|
+
// Compared where it resolves: the workspace list holds resolved paths, and on
|
|
35
|
+
// macOS /var is /private/var.
|
|
36
|
+
const path = tryRealpath(spelled) ?? spelled;
|
|
37
|
+
let isDirectory = false;
|
|
38
|
+
try {
|
|
39
|
+
isDirectory = statSync(path).isDirectory();
|
|
40
|
+
} catch {
|
|
41
|
+
return { error: `${path} does not exist.` };
|
|
42
|
+
}
|
|
43
|
+
if (!isDirectory) return { error: `${path} is not a directory.` };
|
|
44
|
+
const tooBroad = tooBroadForWorkspace(path, home);
|
|
45
|
+
if (tooBroad) return { error: tooBroad };
|
|
46
|
+
if (isWithin(tryRealpath(cwd) ?? resolve(cwd), path)) return { error: `${path} is already inside the working directory.` };
|
|
47
|
+
const covering = existing.find((dir) => isWithin(dir, path));
|
|
48
|
+
if (covering) return { error: `${path} is already in the workspace (${covering}).` };
|
|
49
|
+
return { path };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Why a directory is too broad to be a workspace directory, or undefined: the
|
|
54
|
+
* filesystem root, the home directory and any directory above it would make
|
|
55
|
+
* almost every read on the machine a working-space read. Every source is checked, settings files
|
|
56
|
+
* included. `path` is judged as given, so resolve it first.
|
|
57
|
+
*/
|
|
58
|
+
export function tooBroadForWorkspace(path: string, home: string): string | undefined {
|
|
59
|
+
if (parse(path).root === path) return "The filesystem root cannot be a workspace directory. Add a narrower directory.";
|
|
60
|
+
// The home directory itself, or a directory above it (`/Users`, `C:\Users`).
|
|
61
|
+
if (isWithin(path, tryRealpath(home) ?? resolve(home))) {
|
|
62
|
+
return "Your home directory, or a directory that contains it, cannot be a workspace directory. Add a narrower directory.";
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* `--add-dir` takes one string (pi flags are single-valued), so several
|
|
69
|
+
* directories are separated like PATH entries: `:` on macOS and Linux, `;` on
|
|
70
|
+
* Windows.
|
|
71
|
+
*/
|
|
72
|
+
export function parseAddDirFlag(value: string | undefined): string[] {
|
|
73
|
+
if (!value) return [];
|
|
74
|
+
return value
|
|
75
|
+
.split(delimiter)
|
|
76
|
+
.map((part) => part.trim())
|
|
77
|
+
.filter(Boolean);
|
|
78
|
+
}
|