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
package/extensions/mcp/trust.ts
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* server found in .mcp.json" and remembers the answer in
|
|
6
6
|
* `enabledMcpjsonServers` / `disabledMcpjsonServers` /
|
|
7
7
|
* `enableAllProjectMcpServers`. One Code honours those three keys READ-ONLY
|
|
8
|
-
* (
|
|
9
|
-
*
|
|
8
|
+
* (the approving two from the user's settings only, the disable list from
|
|
9
|
+
* `.claude/settings.local.json` too — never the checked-in project
|
|
10
|
+
* `settings.json`, which would let a repo approve itself) and keeps its
|
|
10
11
|
* own answers under `~/.onecode`, keyed to a hash of each server's config so a
|
|
11
12
|
* changed command re-prompts (CC keys by name alone). Servers from
|
|
12
13
|
* `~/.claude.json` and plugins never prompt: the user wrote the first, and
|
|
@@ -14,8 +15,9 @@
|
|
|
14
15
|
* ARE prompted (that file can be checked in — `git clone && onecode` would
|
|
15
16
|
* otherwise spawn its servers with no consent, review H1); CC never reads
|
|
16
17
|
* `mcpServers` from that file at all. Its `enableAll*`/`enabledMcpjsonServers`
|
|
17
|
-
* policy keys are honoured
|
|
18
|
-
*
|
|
18
|
+
* policy keys are never honoured, for the same reason: git provenance cannot
|
|
19
|
+
* tell a user's file from one shipped with a copied checkout
|
|
20
|
+
* (`readClaudeMcpjsonPolicy`).
|
|
19
21
|
*
|
|
20
22
|
* A "No" is persisted as a project-scope disable (`lib/mcp-overrides.ts`), so
|
|
21
23
|
* the server shows as disabled in `/mcp` and Enable there brings it back —
|
|
@@ -23,17 +25,15 @@
|
|
|
23
25
|
* only. Same shape as `hooks/trust.ts`.
|
|
24
26
|
*/
|
|
25
27
|
|
|
26
|
-
import { execFile } from "node:child_process";
|
|
27
28
|
import { createHash } from "node:crypto";
|
|
28
|
-
import { promisify } from "node:util";
|
|
29
29
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
30
30
|
import { basename, dirname, join } from "node:path";
|
|
31
|
-
import { readSettingsFile,
|
|
31
|
+
import { readSettingsFile, type SettingsSource, settingsSources } from "../lib/claude-settings.ts";
|
|
32
|
+
import { claudeSourcesOn } from "../lib/config-mode.ts";
|
|
32
33
|
import { boundConsentItems } from "../lib/consent-preview.ts";
|
|
33
|
-
import {
|
|
34
|
+
import { consentStorePath } from "../lib/consent-stores.ts";
|
|
34
35
|
import type { McpServer } from "./config.ts";
|
|
35
|
-
|
|
36
|
-
const execFileAsync = promisify(execFile);
|
|
36
|
+
import { escapeControlText } from "../lib/terminal-text.ts";
|
|
37
37
|
|
|
38
38
|
interface ProjectApprovals {
|
|
39
39
|
/** "Use this and all future MCP servers in this project" was chosen. */
|
|
@@ -47,19 +47,42 @@ interface ApprovalStore {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export function approvalStorePath(): string {
|
|
50
|
-
return
|
|
50
|
+
return consentStorePath("mcp");
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
* A server whose config a repository can ship (a project `.mcp.json
|
|
55
|
-
* checked-in `.claude/settings.local.json
|
|
56
|
-
* plugin's `.mcp.json` (also named `.mcp.json`) is
|
|
57
|
-
* plugin was the consent.
|
|
54
|
+
* A server whose config a repository can ship (a project `.mcp.json`, a
|
|
55
|
+
* checked-in `.claude/settings.local.json`, or pi's project `.pi/mcp.json`) —
|
|
56
|
+
* so it is consent-gated. A plugin's `.mcp.json` (also named `.mcp.json`) is
|
|
57
|
+
* excluded: installing the plugin was the consent. pi's user file
|
|
58
|
+
* (`<agentDir>/mcp.json`) is the user's own, like `~/.claude.json`.
|
|
58
59
|
*/
|
|
59
60
|
export function isProjectScopedServer(server: McpServer, pluginConfigPaths: ReadonlySet<string>): boolean {
|
|
60
61
|
if (pluginConfigPaths.has(server.source)) return false;
|
|
61
62
|
const base = basename(server.source);
|
|
62
|
-
return base === ".mcp.json" || base === "settings.local.json";
|
|
63
|
+
return base === ".mcp.json" || base === "settings.local.json" || server.piOrigin === "project";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** A server from a project `.mcp.json`: the only kind Claude Code's own answers approve. */
|
|
67
|
+
function definedInMcpjson(server: McpServer): boolean {
|
|
68
|
+
return basename(server.source) === ".mcp.json";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The project file a consent-gated server comes from, as the dialog names it. */
|
|
72
|
+
function configLabel(server: McpServer): string {
|
|
73
|
+
if (definedInLocalSettings(server)) return ".claude/settings.local.json";
|
|
74
|
+
// pi's project file is `<dir>/<pi's config dir>/mcp.json`, `.pi/mcp.json` unless pi is rebranded.
|
|
75
|
+
return server.piOrigin === "project" ? `${basename(dirname(server.source))}/mcp.json` : ".mcp.json";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** "a and b" for the distinct config files of `servers`. */
|
|
79
|
+
function configLabels(servers: McpServer[]): string {
|
|
80
|
+
return [...new Set(servers.map(configLabel))].join(" and ");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** A server defined in `.claude/settings.local.json` rather than a `.mcp.json`. */
|
|
84
|
+
function definedInLocalSettings(server: McpServer): boolean {
|
|
85
|
+
return basename(server.source) === "settings.local.json";
|
|
63
86
|
}
|
|
64
87
|
|
|
65
88
|
/** The directory the `.mcp.json` lives in — approvals are per config file, not per cwd. */
|
|
@@ -79,12 +102,15 @@ function canonicalize(value: unknown): unknown {
|
|
|
79
102
|
return value;
|
|
80
103
|
}
|
|
81
104
|
|
|
82
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Everything that decides what the server runs or talks to; `source`/`missingEnv` are not part of it.
|
|
107
|
+
* A stdio `cwd` (pi's files only) joins the material only when set, so existing approvals keep their hash.
|
|
108
|
+
*/
|
|
83
109
|
export function hashServerConfig(server: McpServer): string {
|
|
84
110
|
const material =
|
|
85
111
|
server.kind === "stdio"
|
|
86
|
-
? { kind: "stdio", command: server.command, args: server.args, env: server.env ?? {} }
|
|
87
|
-
: { kind: "http", url: server.url, headers: server.headers ?? {} };
|
|
112
|
+
? { kind: "stdio", command: server.command, args: server.args, env: server.env ?? {}, ...(server.cwd ? { cwd: server.cwd } : {}) }
|
|
113
|
+
: { kind: "http", url: server.url, headers: server.headers ?? {}, ...(server.transport ? { transport: server.transport } : {}) };
|
|
88
114
|
return createHash("sha256").update(JSON.stringify(canonicalize(material))).digest("hex");
|
|
89
115
|
}
|
|
90
116
|
|
|
@@ -100,45 +126,36 @@ function stringArray(value: unknown): string[] {
|
|
|
100
126
|
}
|
|
101
127
|
|
|
102
128
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
129
|
+
* Claude Code's answers that One Code honours. The approving keys
|
|
130
|
+
* (`enableAllProjectMcpServers`, `enabledMcpjsonServers`) count only from the
|
|
131
|
+
* user's `~/.claude/settings.json`. Until 2026-09-27 they also counted from a
|
|
132
|
+
* `.claude/settings.local.json` that git reported untracked, but a directory
|
|
133
|
+
* that carries its own `.git` (a tarball of a working copy, a copied or
|
|
134
|
+
* synced checkout) makes a shipped file untracked too, so its servers
|
|
135
|
+
* connected with no prompt, headless included. No check of the local file
|
|
136
|
+
* can tell who wrote it, so it no longer approves anything: its servers go
|
|
137
|
+
* through One Code's own dialog and hash-keyed store. Its
|
|
138
|
+
* `disabledMcpjsonServers` only tightens, so it is still honoured. Async for
|
|
139
|
+
* its callers; nothing here shells out any more.
|
|
111
140
|
*/
|
|
112
|
-
async function localPolicyFileIsTrusted(cwd: string, path: string): Promise<boolean> {
|
|
113
|
-
try {
|
|
114
|
-
await execFileAsync("git", ["ls-files", "--error-unmatch", "--", path], { cwd, timeout: 5_000 });
|
|
115
|
-
return false; // exit 0 → tracked → do not trust its policy keys
|
|
116
|
-
} catch (error) {
|
|
117
|
-
// execFile rejects with `code` = the numeric exit code on a non-zero exit
|
|
118
|
-
// (1 = untracked in a repo, 128 = not a repo — both mean "not tracked, safe
|
|
119
|
-
// to trust"); a spawn failure gives a string code (e.g. "ENOENT") and a
|
|
120
|
-
// timeout gives a non-numeric code — those are "could not decide" → closed.
|
|
121
|
-
return typeof (error as { code?: unknown }).code === "number";
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
141
|
export async function readClaudeMcpjsonPolicy(cwd: string, home: string): Promise<ClaudeMcpjsonPolicy> {
|
|
126
|
-
|
|
142
|
+
// Independent mode (lib/config-mode.ts) reads the same keys from One Code's
|
|
143
|
+
// user file, and only the tightening one from its per-repo file.
|
|
144
|
+
const claude = claudeSourcesOn();
|
|
145
|
+
const userScope: SettingsSource = claude ? "claude-user" : "onecode-user";
|
|
146
|
+
const localScope: SettingsSource = claude ? "project-local" : "onecode-project";
|
|
127
147
|
const policy: ClaudeMcpjsonPolicy = { enableAll: false, enabled: new Set(), disabled: new Set() };
|
|
128
|
-
// Deliberately not
|
|
148
|
+
// Deliberately not the project file: a checked-in settings.json granting
|
|
129
149
|
// enableAllProjectMcpServers would be the repo approving its own servers.
|
|
130
|
-
// The local file is
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// servers (review H1).
|
|
134
|
-
const sources = [paths.user];
|
|
135
|
-
if (await localPolicyFileIsTrusted(cwd, paths.local)) sources.push(paths.local);
|
|
136
|
-
for (const path of sources) {
|
|
150
|
+
// The local file is in the checkout too, whatever git says about it.
|
|
151
|
+
for (const [source, path] of settingsSources(cwd, home)) {
|
|
152
|
+
if (source !== userScope && source !== localScope) continue;
|
|
137
153
|
const file = readSettingsFile(path);
|
|
138
154
|
if (!file) continue;
|
|
155
|
+
for (const name of stringArray(file.disabledMcpjsonServers)) policy.disabled.add(name);
|
|
156
|
+
if (source === localScope) continue;
|
|
139
157
|
if (typeof file.enableAllProjectMcpServers === "boolean") policy.enableAll = file.enableAllProjectMcpServers;
|
|
140
158
|
for (const name of stringArray(file.enabledMcpjsonServers)) policy.enabled.add(name);
|
|
141
|
-
for (const name of stringArray(file.disabledMcpjsonServers)) policy.disabled.add(name);
|
|
142
159
|
}
|
|
143
160
|
return policy;
|
|
144
161
|
}
|
|
@@ -182,25 +199,81 @@ export function persistEnableAll(projectRoot: string, storePath = approvalStoreP
|
|
|
182
199
|
writeStore(storePath, store);
|
|
183
200
|
}
|
|
184
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Why `/mcp`'s Reconnect must not connect a server, or undefined. A server
|
|
204
|
+
* whose config references an unset variable is never connected (startup
|
|
205
|
+
* skips it and never asks for consent), so Reconnect must not either: it
|
|
206
|
+
* would spawn the command with the variable expanded to nothing, and a
|
|
207
|
+
* project server would run with no consent.
|
|
208
|
+
*/
|
|
209
|
+
export function reconnectRefusal(server: McpServer): string | undefined {
|
|
210
|
+
if (!server.missingEnv?.length) return undefined;
|
|
211
|
+
const names = server.missingEnv.join(", ");
|
|
212
|
+
return `"${server.name}" needs ${names} set in the environment. Set ${server.missingEnv.length === 1 ? "it" : "them"} and restart One Code.`;
|
|
213
|
+
}
|
|
214
|
+
|
|
185
215
|
export const CHOICE_ALL = "Use this and all future MCP servers in this project";
|
|
186
216
|
export const CHOICE_THIS = "Use this MCP server";
|
|
187
217
|
export const CHOICE_THESE = "Use these MCP servers";
|
|
188
218
|
export const CHOICE_NO = "No";
|
|
189
219
|
|
|
190
|
-
/** Claude Code's dialog title for one or several newly found servers. */
|
|
191
|
-
export function promptTitle(names: string[]): string {
|
|
220
|
+
/** Claude Code's dialog title for one or several newly found servers; `file` names where they were found. */
|
|
221
|
+
export function promptTitle(names: string[], file = ".mcp.json"): string {
|
|
192
222
|
return names.length === 1
|
|
193
|
-
? `New MCP server found in
|
|
194
|
-
: `${names.length} new MCP servers found in
|
|
223
|
+
? `New MCP server found in ${file}: ${escapeControlText(names[0])}`
|
|
224
|
+
: `${names.length} new MCP servers found in ${file}`;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Environment variables that change what a stdio server's command runs, or
|
|
229
|
+
* where it loads code from: an interpreter's preload and search paths, the
|
|
230
|
+
* dynamic loader's, `PATH`, and npm's config. Matched case-insensitively
|
|
231
|
+
* (Windows environment names are). The consent dialog shows these values in
|
|
232
|
+
* full, because `npx -y some-mcp` with `NODE_OPTIONS=--require ./x.js` is not
|
|
233
|
+
* the command it looks like.
|
|
234
|
+
*/
|
|
235
|
+
const EXECUTION_ENV = new Set([
|
|
236
|
+
"PATH",
|
|
237
|
+
"NODE_OPTIONS",
|
|
238
|
+
"NODE_PATH",
|
|
239
|
+
"LD_PRELOAD",
|
|
240
|
+
"LD_LIBRARY_PATH",
|
|
241
|
+
"LD_AUDIT",
|
|
242
|
+
"PYTHONPATH",
|
|
243
|
+
"PYTHONSTARTUP",
|
|
244
|
+
"PYTHONHOME",
|
|
245
|
+
"PERL5OPT",
|
|
246
|
+
"PERL5LIB",
|
|
247
|
+
"RUBYOPT",
|
|
248
|
+
"RUBYLIB",
|
|
249
|
+
"BASH_ENV",
|
|
250
|
+
"ENV",
|
|
251
|
+
"JAVA_TOOL_OPTIONS",
|
|
252
|
+
"_JAVA_OPTIONS",
|
|
253
|
+
"JDK_JAVA_OPTIONS",
|
|
254
|
+
"ELECTRON_RUN_AS_NODE",
|
|
255
|
+
"GIT_SSH_COMMAND",
|
|
256
|
+
"GIT_EXEC_PATH",
|
|
257
|
+
"COMSPEC",
|
|
258
|
+
"PATHEXT",
|
|
259
|
+
]);
|
|
260
|
+
const EXECUTION_ENV_PREFIXES = ["DYLD_", "NPM_CONFIG_"];
|
|
261
|
+
|
|
262
|
+
/** Whether an env key changes what a server's command executes (`EXECUTION_ENV`). */
|
|
263
|
+
export function changesExecution(key: string): boolean {
|
|
264
|
+
const upper = key.toUpperCase();
|
|
265
|
+
return EXECUTION_ENV.has(upper) || EXECUTION_ENV_PREFIXES.some((prefix) => upper.startsWith(prefix));
|
|
195
266
|
}
|
|
196
267
|
|
|
197
268
|
/**
|
|
198
269
|
* One line per server naming what would run, for the dialog body. Commands and
|
|
199
|
-
* URLs are shown in full (a truncated one hides where a padded attack lives)
|
|
200
|
-
* env
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
270
|
+
* URLs are shown in full (a truncated one hides where a padded attack lives).
|
|
271
|
+
* Every `env` key a stdio server sets is named; the values of the keys that
|
|
272
|
+
* change what executes (`changesExecution`) are shown in full, quoted, and the
|
|
273
|
+
* rest are not echoed, since they are usually credentials. The variable NAMES
|
|
274
|
+
* a server's command/args/env/headers reference are listed too (from
|
|
275
|
+
* `referencedEnv`, captured before expansion) — approving a URL should not
|
|
276
|
+
* silently ship a credential the header interpolates (review M5).
|
|
204
277
|
*/
|
|
205
278
|
export function describeServers(servers: McpServer[]): string {
|
|
206
279
|
const lines = servers.map((server) => {
|
|
@@ -210,14 +283,17 @@ export function describeServers(servers: McpServer[]): string {
|
|
|
210
283
|
: `${server.name}: ${server.url}`;
|
|
211
284
|
const vars = server.referencedEnv ?? [];
|
|
212
285
|
const headerNames = server.kind === "http" ? Object.keys(server.headers ?? {}) : [];
|
|
286
|
+
const env = server.kind === "stdio" ? Object.entries(server.env ?? {}) : [];
|
|
213
287
|
const notes = [
|
|
288
|
+
server.kind === "stdio" && server.cwd ? `cwd: ${server.cwd}` : "",
|
|
289
|
+
env.length ? `env: ${env.map(([key, value]) => (changesExecution(key) ? `${key}=${JSON.stringify(value)}` : key)).join(", ")}` : "",
|
|
214
290
|
vars.length ? `uses ${vars.map((v) => `$${v}`).join(", ")}` : "",
|
|
215
291
|
headerNames.length ? `headers: ${headerNames.join(", ")}` : "",
|
|
216
292
|
].filter(Boolean);
|
|
217
293
|
return notes.length ? `${what}\n (${notes.join("; ")})` : what;
|
|
218
294
|
});
|
|
219
295
|
// Bound the modal: a very long command/url or many servers cannot flood it.
|
|
220
|
-
return boundConsentItems(lines,
|
|
296
|
+
return boundConsentItems(lines, `review ${configLabels(servers)} before approving`);
|
|
221
297
|
}
|
|
222
298
|
|
|
223
299
|
export interface McpTrustDeps {
|
|
@@ -255,9 +331,8 @@ export async function approveMcpServers(
|
|
|
255
331
|
const approved: McpServer[] = [];
|
|
256
332
|
const withheld: McpTrustOutcome["withheld"] = [];
|
|
257
333
|
const pending: McpServer[] = [];
|
|
258
|
-
// Reading CC's policy
|
|
259
|
-
//
|
|
260
|
-
// user-scope or plugin servers must not pay a git spawn at connect.
|
|
334
|
+
// Reading CC's policy reads two settings files, so only do it when a
|
|
335
|
+
// server actually needs consent.
|
|
261
336
|
const anyProjectScoped = servers.some((s) => isProjectScopedServer(s, pluginConfigPaths));
|
|
262
337
|
const claude: ClaudeMcpjsonPolicy = anyProjectScoped
|
|
263
338
|
? await readClaudeMcpjsonPolicy(cwd, home)
|
|
@@ -272,7 +347,12 @@ export async function approveMcpServers(
|
|
|
272
347
|
withheld.push({ server, reason: "disabled-by-claude-settings" });
|
|
273
348
|
continue;
|
|
274
349
|
}
|
|
275
|
-
|
|
350
|
+
// Claude Code's own answers approve `.mcp.json` servers only. A server
|
|
351
|
+
// DEFINED in settings.local.json must never be approved by that same
|
|
352
|
+
// file's `enableAllProjectMcpServers` (SECURITY-REVIEW-2026-09-23 H4), and
|
|
353
|
+
// one from pi's `.pi/mcp.json` is not a file those answers were about: both
|
|
354
|
+
// go through One Code's hash-keyed consent below, like any other.
|
|
355
|
+
if (definedInMcpjson(server) && (claude.enableAll || claude.enabled.has(server.name))) {
|
|
276
356
|
approved.push(server);
|
|
277
357
|
continue;
|
|
278
358
|
}
|
|
@@ -293,8 +373,12 @@ export async function approveMcpServers(
|
|
|
293
373
|
|
|
294
374
|
if (!deps.hasUI) {
|
|
295
375
|
for (const server of pending) withheld.push({ server, reason: "not-approved" });
|
|
376
|
+
// enabledMcpjsonServers approves `.mcp.json` servers only (above), so the
|
|
377
|
+
// hint names it only when one of those is waiting.
|
|
378
|
+
const fromMcpjson = pending.some(definedInMcpjson);
|
|
379
|
+
const sources = configLabels(pending);
|
|
296
380
|
deps.notify(
|
|
297
|
-
`Skipped ${pending.length} MCP server${pending.length === 1 ? "" : "s"} from
|
|
381
|
+
`Skipped ${pending.length} MCP server${pending.length === 1 ? "" : "s"} from ${sources} (${pending.map((s) => s.name).join(", ")}): not yet approved and no UI to ask. Approve once in an interactive session${fromMcpjson ? ", or set enabledMcpjsonServers in ~/.claude/settings.json" : ""}.`,
|
|
298
382
|
);
|
|
299
383
|
return { approved, withheld };
|
|
300
384
|
}
|
|
@@ -306,7 +390,7 @@ export async function approveMcpServers(
|
|
|
306
390
|
if (!prompt) {
|
|
307
391
|
const useLabel = pending.length === 1 ? CHOICE_THIS : CHOICE_THESE;
|
|
308
392
|
prompt = deps
|
|
309
|
-
.select(`${promptTitle(names)}\n\n${describeServers(pending)}\n\nThese run on your machine.`, [CHOICE_ALL, useLabel, CHOICE_NO])
|
|
393
|
+
.select(`${promptTitle(names, configLabels(pending))}\n\n${describeServers(pending)}\n\nThese run on your machine.`, [CHOICE_ALL, useLabel, CHOICE_NO])
|
|
310
394
|
.finally(() => pendingPrompts.delete(key));
|
|
311
395
|
pendingPrompts.set(key, prompt);
|
|
312
396
|
}
|
|
@@ -328,7 +412,7 @@ export async function approveMcpServers(
|
|
|
328
412
|
}
|
|
329
413
|
}
|
|
330
414
|
if (choice !== CHOICE_ALL && choice !== CHOICE_THIS && choice !== CHOICE_THESE) {
|
|
331
|
-
deps.notify(`MCP server${pending.length === 1 ? "" : "s"} from
|
|
415
|
+
deps.notify(`MCP server${pending.length === 1 ? "" : "s"} from ${configLabels(pending)} not connected (${names.join(", ")}); enable in /mcp.`);
|
|
332
416
|
}
|
|
333
417
|
return { approved, withheld };
|
|
334
418
|
}
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
ONECODE_DESCRIPTOR,
|
|
25
25
|
ONECODE_GLOBAL_DESCRIPTOR,
|
|
26
26
|
PROJECT_DESCRIPTOR,
|
|
27
|
+
instructionRule,
|
|
27
28
|
} from "../lib/claude-context.ts";
|
|
28
29
|
import { forwardSlashes, isRelativeInside, tildify } from "../lib/paths.ts";
|
|
29
30
|
import { tryReadFile } from "../lib/plugins.ts";
|
|
@@ -69,12 +70,16 @@ export function buildMemoryEntries(opts: {
|
|
|
69
70
|
home: string;
|
|
70
71
|
homeClaudeDir: string;
|
|
71
72
|
homeOneCodeDir: string;
|
|
72
|
-
|
|
73
|
+
/** The auto-memory folder; undefined while auto-memory is off (no folder row, as in Claude Code). */
|
|
74
|
+
memoryDir: string | undefined;
|
|
73
75
|
}): MemoryEntry[] {
|
|
74
76
|
const { cwd, home, homeClaudeDir, homeOneCodeDir, memoryDir } = opts;
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
// The same rule the # claudeMd block uses, so the list matches what it sends.
|
|
78
|
+
const rule = instructionRule(home);
|
|
79
|
+
// Independent mode (lib/config-mode.ts) reads no CLAUDE.md: its always-offered
|
|
80
|
+
// files are the global ONECODE.md and the project's AGENTS.md instead.
|
|
81
|
+
const independent = rule === "agents-md";
|
|
82
|
+
const discovered = discoverContextFilePaths({ cwd, homeClaudeDir, homeOneCodeDir, rule });
|
|
78
83
|
const referenced = referencedImports(discovered, home);
|
|
79
84
|
// (descriptor, dir) → the discovered path, so per-dir lookups reuse the real
|
|
80
85
|
// on-disk casing discovery already resolved (no second stat/readdir here).
|
|
@@ -91,15 +96,15 @@ export function buildMemoryEntries(opts: {
|
|
|
91
96
|
const disp = (path: string) => displayPath(path, cwd, home);
|
|
92
97
|
|
|
93
98
|
// Global user instructions — always offered, matching CC (created on save).
|
|
94
|
-
const
|
|
99
|
+
const globalOneCode = found.get(`${ONECODE_GLOBAL_DESCRIPTOR}\0${homeOneCodeDir}`);
|
|
100
|
+
const globalUser = independent ? (globalOneCode ?? join(homeOneCodeDir, "ONECODE.md")) : join(homeClaudeDir, "CLAUDE.md");
|
|
95
101
|
add({
|
|
96
102
|
title: "User instructions",
|
|
97
|
-
description: `Saved in ${disp(
|
|
98
|
-
path:
|
|
103
|
+
description: `Saved in ${disp(globalUser)}`,
|
|
104
|
+
path: globalUser,
|
|
99
105
|
kind: "file",
|
|
100
|
-
exists: found.has(`${GLOBAL_DESCRIPTOR}\0${homeClaudeDir}`),
|
|
106
|
+
exists: independent ? globalOneCode !== undefined : found.has(`${GLOBAL_DESCRIPTOR}\0${homeClaudeDir}`),
|
|
101
107
|
});
|
|
102
|
-
const globalOneCode = found.get(`${ONECODE_GLOBAL_DESCRIPTOR}\0${homeOneCodeDir}`);
|
|
103
108
|
if (globalOneCode) {
|
|
104
109
|
add({
|
|
105
110
|
title: "One Code user instructions",
|
|
@@ -114,13 +119,14 @@ export function buildMemoryEntries(opts: {
|
|
|
114
119
|
const isCwd = d === cwd;
|
|
115
120
|
const claude = join(d, "CLAUDE.md");
|
|
116
121
|
if (isCwd) {
|
|
117
|
-
// Project instructions — always offered (created on save).
|
|
122
|
+
// Project instructions — always offered (created on save): AGENTS.md in independent mode.
|
|
123
|
+
const [name, descriptor] = independent ? ["AGENTS.md", AGENTS_DESCRIPTOR] : ["CLAUDE.md", PROJECT_DESCRIPTOR];
|
|
118
124
|
add({
|
|
119
125
|
title: "Project instructions",
|
|
120
|
-
description: `Checked in at ${disp(
|
|
121
|
-
path:
|
|
126
|
+
description: `Checked in at ${disp(join(d, name))}`,
|
|
127
|
+
path: join(d, name),
|
|
122
128
|
kind: "file",
|
|
123
|
-
exists: found.has(`${
|
|
129
|
+
exists: found.has(`${descriptor}\0${d}`),
|
|
124
130
|
});
|
|
125
131
|
} else if (found.has(`${PROJECT_DESCRIPTOR}\0${d}`)) {
|
|
126
132
|
add({ title: disp(claude), path: claude, kind: "file", exists: true });
|
|
@@ -143,6 +149,9 @@ export function buildMemoryEntries(opts: {
|
|
|
143
149
|
exists: true,
|
|
144
150
|
});
|
|
145
151
|
}
|
|
152
|
+
// `.claude/AGENTS.md`, which the AGENTS.md fallback loads too.
|
|
153
|
+
const dotClaudeAgents = found.get(`${AGENTS_DESCRIPTOR}\0${join(d, ".claude")}`);
|
|
154
|
+
if (dotClaudeAgents) add({ title: disp(dotClaudeAgents), path: dotClaudeAgents, kind: "file", exists: true });
|
|
146
155
|
|
|
147
156
|
const oneCode = found.get(`${ONECODE_DESCRIPTOR}\0${d}`);
|
|
148
157
|
if (oneCode) {
|
|
@@ -156,7 +165,7 @@ export function buildMemoryEntries(opts: {
|
|
|
156
165
|
}
|
|
157
166
|
}
|
|
158
167
|
|
|
159
|
-
add({ title: "Open auto-memory folder", path: memoryDir, kind: "folder", exists: true });
|
|
168
|
+
if (memoryDir) add({ title: "Open auto-memory folder", path: memoryDir, kind: "folder", exists: true });
|
|
160
169
|
return entries;
|
|
161
170
|
}
|
|
162
171
|
|