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
|
@@ -13,31 +13,53 @@
|
|
|
13
13
|
* turn puts the block on the queue before the turn's next request — until
|
|
14
14
|
* 2026-09-05 the mid-turn requests ran with no plan reminder while every edit
|
|
15
15
|
* was denied "see the plan-mode reminder" (STEERING-REVIEW-2026-09-05 M3) —
|
|
16
|
-
* and on
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* allocation.
|
|
16
|
+
* and on session_start, after restoring a previous path and its baseline.
|
|
17
|
+
* A session that STARTS in plan mode must install the block before the first
|
|
18
|
+
* prompt is stamped: before_agent_start is already too late to anchor it to
|
|
19
|
+
* that prompt. before_agent_start also re-announces the existing state.
|
|
21
20
|
*/
|
|
22
21
|
|
|
23
22
|
import { existsSync, readFileSync } from "node:fs";
|
|
24
23
|
import { join } from "node:path";
|
|
25
|
-
import type
|
|
24
|
+
import { defineTool, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
25
|
+
import { registerFormTool } from "../lib/tool-variants.ts";
|
|
26
26
|
import { Type } from "typebox";
|
|
27
27
|
import { DEFER_CHANNEL } from "../lib/deferred.ts";
|
|
28
28
|
import { oneCodeStateDir } from "../lib/paths.ts";
|
|
29
29
|
import { REMINDER_CHANNEL } from "../lib/reminders.ts";
|
|
30
|
+
import { CONTEXT_BASELINE_CHANNEL, restoredContext } from "../lib/context-stack.ts";
|
|
31
|
+
import { canShowCustomUi } from "../lib/headless-output.ts";
|
|
30
32
|
import { ccToolRenderers, safeThemePaint } from "../lib/tui-render.ts";
|
|
33
|
+
import { userDenialText } from "../lib/user-denial.ts";
|
|
31
34
|
import type { PermissionMode } from "../permissions/matcher.ts";
|
|
32
35
|
import { PERMISSION_STATUS_CHANNEL, type PermissionStatus } from "../permissions/modes.ts";
|
|
33
36
|
import { buildPlanModeReminder } from "./reminder.ts";
|
|
34
37
|
import { randomSlug } from "./slug.ts";
|
|
35
|
-
import {
|
|
38
|
+
import {
|
|
39
|
+
approvedPlanText,
|
|
40
|
+
ENTER_PLAN_MODE_DESCRIPTION,
|
|
41
|
+
enteredPlanModeText,
|
|
42
|
+
enterPlanModeDescription,
|
|
43
|
+
EXIT_PLAN_MODE_DESCRIPTION,
|
|
44
|
+
exitedPlanModeText,
|
|
45
|
+
} from "./texts.ts";
|
|
46
|
+
import { createMarkdownProse } from "../subagents/prose.ts";
|
|
47
|
+
import type { ProseRenderer } from "../subagents/panel-render.ts";
|
|
48
|
+
import {
|
|
49
|
+
clampOffset,
|
|
50
|
+
decodeViewerKey,
|
|
51
|
+
initialPlanChoice,
|
|
52
|
+
KEEP_PLANNING_QUESTION,
|
|
53
|
+
type PlanChoice,
|
|
54
|
+
planLines,
|
|
55
|
+
renderPlanViewer,
|
|
56
|
+
runPlanApproval,
|
|
57
|
+
selectPlanChoice,
|
|
58
|
+
} from "./viewer.ts";
|
|
36
59
|
|
|
37
|
-
import { MODE_CHANNEL, PLAN_FILE_CHANNEL } from "../lib/plan-mode-channels.ts";
|
|
60
|
+
import { MODE_CHANNEL, PLAN_FILE_CHANNEL, PLAN_FILE_ENTRY, planFileOnBranch } from "../lib/plan-mode-channels.ts";
|
|
61
|
+
import { panelUi } from "../lib/panel-focus.ts";
|
|
38
62
|
export { MODE_CHANNEL, PLAN_FILE_CHANNEL };
|
|
39
|
-
/** Session entry type persisting the allocated path across resume/branch. */
|
|
40
|
-
const PLAN_FILE_ENTRY = "one-code:plan-mode-file";
|
|
41
63
|
|
|
42
64
|
const PLANS_DIR = () => join(oneCodeStateDir(), "plans");
|
|
43
65
|
|
|
@@ -64,16 +86,19 @@ export default function planModeExtension(pi: ExtensionAPI) {
|
|
|
64
86
|
*/
|
|
65
87
|
let modeBeforePlan: PermissionMode | undefined;
|
|
66
88
|
let planFilePath: string | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Whether the plan file existed when plan mode came on, which picks Claude
|
|
91
|
+
* Code's "Plan File Info" line. Fixed for the mode's whole run, so the sticky
|
|
92
|
+
* block stays byte-identical turn after turn (plan-mode/reminder.ts);
|
|
93
|
+
* cleared when the mode ends.
|
|
94
|
+
*/
|
|
95
|
+
let planExistedAtEntry: boolean | undefined;
|
|
67
96
|
|
|
68
97
|
/** Restore the branch's plan file, else allocate a fresh slug. */
|
|
69
98
|
const ensurePlanFile = (ctx: ExtensionContext): string => {
|
|
70
99
|
if (planFilePath) return planFilePath;
|
|
71
100
|
|
|
72
|
-
|
|
73
|
-
if (entry.type !== "custom" || entry.customType !== PLAN_FILE_ENTRY) continue;
|
|
74
|
-
const path = (entry.data as { path?: unknown } | undefined)?.path;
|
|
75
|
-
if (typeof path === "string") planFilePath = path;
|
|
76
|
-
}
|
|
101
|
+
planFilePath = planFileOnBranch(ctx.sessionManager.getBranch());
|
|
77
102
|
if (planFilePath) return planFilePath;
|
|
78
103
|
|
|
79
104
|
let path = join(PLANS_DIR(), `${randomSlug()}.md`);
|
|
@@ -86,17 +111,38 @@ export default function planModeExtension(pi: ExtensionAPI) {
|
|
|
86
111
|
};
|
|
87
112
|
|
|
88
113
|
/** Re-announce path + reminder; every-turn re-emits replace by key. */
|
|
89
|
-
const refresh = (ctx: ExtensionContext) => {
|
|
114
|
+
const refresh = (ctx: ExtensionContext, toolCallId?: string) => {
|
|
90
115
|
const path = ensurePlanFile(ctx);
|
|
116
|
+
planExistedAtEntry ??= existsSync(path);
|
|
117
|
+
pi.events.emit(CONTEXT_BASELINE_CHANNEL, { key: "plan-mode", value: { path, existed: planExistedAtEntry } });
|
|
91
118
|
pi.events.emit(PLAN_FILE_CHANNEL, { path });
|
|
92
119
|
pi.events.emit(REMINDER_CHANNEL, {
|
|
93
|
-
text: buildPlanModeReminder(path),
|
|
120
|
+
text: buildPlanModeReminder(path, planExistedAtEntry),
|
|
94
121
|
scope: "every-turn",
|
|
95
122
|
key: "permission-mode",
|
|
96
123
|
placement: "sticky-append",
|
|
124
|
+
toolCallId,
|
|
97
125
|
});
|
|
98
126
|
};
|
|
99
127
|
|
|
128
|
+
/**
|
|
129
|
+
* pi-tui's Markdown renderer for the approval dialog, loaded on first use.
|
|
130
|
+
* A failed load is not cached (the theme may not be ready yet); the dialog
|
|
131
|
+
* then wraps the plan as plain text.
|
|
132
|
+
*/
|
|
133
|
+
let markdownLoad: Promise<ProseRenderer | undefined> | undefined;
|
|
134
|
+
const planMarkdown = (): Promise<ProseRenderer | undefined> =>
|
|
135
|
+
(markdownLoad ??= createMarkdownProse().catch(() => {
|
|
136
|
+
markdownLoad = undefined;
|
|
137
|
+
return undefined;
|
|
138
|
+
}));
|
|
139
|
+
|
|
140
|
+
/** Plan approvals the user dismissed without words: the turn stops once pi records their result. */
|
|
141
|
+
const abortAfterResult = new Set<string>();
|
|
142
|
+
pi.on("tool_execution_end", (event, ctx) => {
|
|
143
|
+
if (abortAfterResult.delete(event.toolCallId)) ctx.abort();
|
|
144
|
+
});
|
|
145
|
+
|
|
100
146
|
/** The last context seen, for a refresh triggered off the bus (no ctx of its own). */
|
|
101
147
|
let lastCtx: ExtensionContext | undefined;
|
|
102
148
|
|
|
@@ -106,17 +152,27 @@ export default function planModeExtension(pi: ExtensionAPI) {
|
|
|
106
152
|
const previous = currentMode;
|
|
107
153
|
currentMode = status.mode;
|
|
108
154
|
if (currentMode === "plan" && previous !== "plan") modeBeforePlan = previous as PermissionMode | undefined;
|
|
109
|
-
|
|
155
|
+
if (currentMode !== "plan") planExistedAtEntry = undefined;
|
|
156
|
+
// Entering plan mode mid-turn: permissions' setMode has just closed the
|
|
110
157
|
// shared "permission-mode" key (before broadcasting this status, so this
|
|
111
158
|
// re-add is not undone) and will announce the change on the next tool
|
|
112
159
|
// result; the standing block has to be back on the queue for that same
|
|
113
160
|
// request. The path is announced over PLAN_FILE_CHANNEL inside refresh,
|
|
114
161
|
// synchronously, so setMode's announcement can name it.
|
|
115
|
-
if (currentMode === "plan" && previous !== "plan" && lastCtx) refresh(lastCtx);
|
|
162
|
+
if (currentMode === "plan" && previous !== "plan" && lastCtx) refresh(lastCtx, status.toolCallId);
|
|
116
163
|
});
|
|
117
164
|
|
|
118
165
|
pi.on("session_start", (_event, ctx) => {
|
|
119
166
|
lastCtx = ctx;
|
|
167
|
+
const restored = restoredContext(pi.events);
|
|
168
|
+
const baseline = restored?.baselines["plan-mode"] as { path?: unknown; existed?: unknown } | undefined;
|
|
169
|
+
const path = planFileOnBranch(ctx.sessionManager.getBranch());
|
|
170
|
+
if (currentMode === "plan" && restored?.baselines["permission-mode"] === "plan" &&
|
|
171
|
+
path && baseline?.path === path && typeof baseline.existed === "boolean") {
|
|
172
|
+
planFilePath = path;
|
|
173
|
+
planExistedAtEntry = baseline.existed;
|
|
174
|
+
}
|
|
175
|
+
if (currentMode === "plan") refresh(ctx);
|
|
120
176
|
});
|
|
121
177
|
|
|
122
178
|
pi.on("before_agent_start", (_event, ctx) => {
|
|
@@ -124,42 +180,45 @@ export default function planModeExtension(pi: ExtensionAPI) {
|
|
|
124
180
|
if (currentMode === "plan") refresh(ctx);
|
|
125
181
|
});
|
|
126
182
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
183
|
+
/**
|
|
184
|
+
* enter_plan_mode's description follows the model's tier: Claude Code's,
|
|
185
|
+
* which prefers plan mode, on frontier and workhorse, and One Code's, which
|
|
186
|
+
* says most tasks do not need it, on cheap and tiny (`texts.ts`, through the
|
|
187
|
+
* shared lib/tool-variants.ts). A re-registration keeps the tool's active
|
|
188
|
+
* state, so the deferred tool stays deferred, and it sets no prompt snippet,
|
|
189
|
+
* so the system prompt never moves with it.
|
|
190
|
+
*/
|
|
191
|
+
registerFormTool(
|
|
192
|
+
pi,
|
|
193
|
+
defineTool({
|
|
194
|
+
name: "enter_plan_mode",
|
|
195
|
+
label: "Enter plan mode",
|
|
196
|
+
...ccToolRenderers("Enter plan mode"),
|
|
197
|
+
description: ENTER_PLAN_MODE_DESCRIPTION,
|
|
198
|
+
parameters: Type.Object({}),
|
|
199
|
+
async execute(toolCallId, _params, _signal, _onUpdate, ctx) {
|
|
200
|
+
pi.events.emit(MODE_CHANNEL, { mode: "plan", toolCallId });
|
|
201
|
+
// setMode broadcasts synchronously over the status channel, so the
|
|
202
|
+
// listener above has already installed the block and announced the
|
|
203
|
+
// path (or the mode was plan already and both stand); name the file in
|
|
204
|
+
// the tool result too so the model can start writing this same turn.
|
|
205
|
+
const path = ensurePlanFile(ctx);
|
|
206
|
+
return {
|
|
207
|
+
content: [{ type: "text", text: enteredPlanModeText(path) }],
|
|
208
|
+
details: { planFilePath: path },
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
}),
|
|
212
|
+
enterPlanModeDescription,
|
|
213
|
+
);
|
|
153
214
|
|
|
154
215
|
pi.registerTool({
|
|
155
216
|
name: "exit_plan_mode",
|
|
156
217
|
label: "Exit plan mode",
|
|
157
218
|
...ccToolRenderers("Exit plan mode"),
|
|
158
|
-
description:
|
|
159
|
-
"Signal that planning is complete and ask the user to approve the plan.\n" +
|
|
160
|
-
"Takes no parameters: the plan is read from the plan file named in the plan-mode reminder, which you must have written before calling this. The user reviews that file's contents.",
|
|
219
|
+
description: EXIT_PLAN_MODE_DESCRIPTION,
|
|
161
220
|
parameters: Type.Object({}),
|
|
162
|
-
async execute(
|
|
221
|
+
async execute(toolCallId, _params, signal, _onUpdate, ctx) {
|
|
163
222
|
// Guard the out-of-sequence call: without this, a cold exit_plan_mode
|
|
164
223
|
// (never entered plan mode) allocates a fresh empty plan file and blames
|
|
165
224
|
// "the plan file is empty" — a plausible but wrong cause a weak model
|
|
@@ -226,11 +285,30 @@ export default function planModeExtension(pi: ExtensionAPI) {
|
|
|
226
285
|
];
|
|
227
286
|
const choices = options.map((o) => o.label);
|
|
228
287
|
|
|
229
|
-
|
|
288
|
+
// The plan renders as Markdown, like assistant text in the transcript.
|
|
289
|
+
const prose = canShowCustomUi(ctx) ? await planMarkdown() : undefined;
|
|
290
|
+
const planRef = {};
|
|
291
|
+
const markdown = prose ? (text: string, width: number) => prose(planRef, text, width) : undefined;
|
|
292
|
+
|
|
293
|
+
// The scroll position and the highlighted choice outlive one showing: a
|
|
294
|
+
// blank keep-planning answer reopens the dialog where the user left it.
|
|
295
|
+
const maxVisible = 12;
|
|
296
|
+
let offset = 0;
|
|
297
|
+
let selected: PlanChoice = initialPlanChoice(options);
|
|
298
|
+
const showDialog = (): Promise<PlanChoice | null> => !canShowCustomUi(ctx) ? selectPlanChoice(ctx.ui, plan, path, choices, signal) : panelUi(pi.events, ctx.ui).custom<PlanChoice | null>((tui, theme, _keybindings, close) => {
|
|
299
|
+
// An aborted turn closes the dialog as a cancel; a choice or a cancel
|
|
300
|
+
// drops the abort listener. Either way the dialog settles once.
|
|
301
|
+
let settled = false;
|
|
302
|
+
const onAbort = () => done(null);
|
|
303
|
+
const done = (choice: PlanChoice | null) => {
|
|
304
|
+
if (settled) return;
|
|
305
|
+
settled = true;
|
|
306
|
+
signal?.removeEventListener("abort", onAbort);
|
|
307
|
+
close(choice);
|
|
308
|
+
};
|
|
309
|
+
if (signal?.aborted) queueMicrotask(onAbort);
|
|
310
|
+
else signal?.addEventListener("abort", onAbort, { once: true });
|
|
230
311
|
const paint = safeThemePaint(theme);
|
|
231
|
-
const maxVisible = 12;
|
|
232
|
-
let offset = 0;
|
|
233
|
-
let selected: PlanChoice = initialPlanChoice(options);
|
|
234
312
|
let lineCount = 0;
|
|
235
313
|
// The dialog stays open while exit_plan_mode runs, so pi's working
|
|
236
314
|
// spinner drives ~8 frames a second — and re-wrapping the whole plan
|
|
@@ -243,7 +321,7 @@ export default function planModeExtension(pi: ExtensionAPI) {
|
|
|
243
321
|
let wrapped: { width: number; lines: string[] } | undefined;
|
|
244
322
|
let frame: { key: string; lines: string[] } | undefined;
|
|
245
323
|
const wrapAt = (wrapWidth: number): string[] => {
|
|
246
|
-
if (wrapped?.width !== wrapWidth) wrapped = { width: wrapWidth, lines:
|
|
324
|
+
if (wrapped?.width !== wrapWidth) wrapped = { width: wrapWidth, lines: planLines(plan, wrapWidth, markdown) };
|
|
247
325
|
return wrapped.lines;
|
|
248
326
|
};
|
|
249
327
|
return {
|
|
@@ -274,29 +352,38 @@ export default function planModeExtension(pi: ExtensionAPI) {
|
|
|
274
352
|
},
|
|
275
353
|
};
|
|
276
354
|
});
|
|
355
|
+
const decision = await runPlanApproval(
|
|
356
|
+
options,
|
|
357
|
+
showDialog,
|
|
358
|
+
() => ctx.ui.input(KEEP_PLANNING_QUESTION, undefined, { signal }),
|
|
359
|
+
signal,
|
|
360
|
+
);
|
|
277
361
|
|
|
278
|
-
const picked =
|
|
362
|
+
const picked = decision.kind === "approve" ? options[decision.index] : undefined;
|
|
279
363
|
if (picked?.mode) {
|
|
280
|
-
pi.events.emit(MODE_CHANNEL, { mode: picked.mode });
|
|
364
|
+
pi.events.emit(MODE_CHANNEL, { mode: picked.mode, toolCallId });
|
|
365
|
+
// Claude Code's exit reminder, queued from execute so it is written
|
|
366
|
+
// into this result after the mode notice.
|
|
367
|
+
pi.events.emit(REMINDER_CHANNEL, { text: exitedPlanModeText(path), toolCallId });
|
|
281
368
|
return {
|
|
282
|
-
content: [
|
|
283
|
-
{
|
|
284
|
-
type: "text",
|
|
285
|
-
text: `Plan approved by the user. You may now implement it. The approved plan stays at ${path} for reference.`,
|
|
286
|
-
},
|
|
287
|
-
],
|
|
369
|
+
content: [{ type: "text", text: approvedPlanText(path, plan) }],
|
|
288
370
|
details: { plan, approved: true },
|
|
289
371
|
};
|
|
290
372
|
}
|
|
291
373
|
|
|
374
|
+
// Rejected: Claude Code's rejection text. With the user's words the model
|
|
375
|
+
// acts on them and keeps planning; without (Esc) the turn stops, as a
|
|
376
|
+
// reasonless permission rejection does (permissions/index.ts): `terminate`
|
|
377
|
+
// ends pi's loop after the batch, and the abort waits for the recorded
|
|
378
|
+
// result so the run ends as the user's interrupt.
|
|
379
|
+
const feedback = decision.kind === "reject" ? decision.feedback : undefined;
|
|
380
|
+
const stop = !feedback;
|
|
381
|
+
if (stop) abortAfterResult.add(toolCallId);
|
|
292
382
|
return {
|
|
293
|
-
content: [
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
},
|
|
298
|
-
],
|
|
299
|
-
details: { plan, approved: false },
|
|
383
|
+
content: [{ type: "text", text: userDenialText(feedback) }],
|
|
384
|
+
details: { plan, approved: false, ...(feedback ? { feedback } : {}) },
|
|
385
|
+
isError: true,
|
|
386
|
+
...(stop ? { terminate: true } : {}),
|
|
300
387
|
};
|
|
301
388
|
},
|
|
302
389
|
});
|
|
@@ -1,30 +1,98 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plan-mode reminder text (pure)
|
|
3
|
-
*
|
|
4
|
-
* carried by every user message since plan mode came
|
|
5
|
-
* that anchor only while the re-emitted text is
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* Plan-mode reminder text (pure): Claude Code's plan-mode instructions, the
|
|
3
|
+
* five-phase workflow, with One Code's tool and agent names. The block is a
|
|
4
|
+
* sticky-append reminder carried by every user message since plan mode came
|
|
5
|
+
* on, and the queue keeps that anchor only while the re-emitted text is
|
|
6
|
+
* unchanged, so the text must not flip while the mode lasts: a text that
|
|
7
|
+
* flipped when the file appeared re-anchored the block and re-cached every
|
|
8
|
+
* message between entering plan mode and the first write
|
|
9
|
+
* (CACHE-REVIEW-2026-09-04 M2). Claude Code's own "Plan File Info" line
|
|
10
|
+
* depends on whether the plan file exists; the caller decides that once, when
|
|
11
|
+
* plan mode comes on (`planExists`), and keeps it until the mode ends.
|
|
8
12
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* parameter. Claude Code's own text does vary with the file's existence; ours
|
|
13
|
-
* folds both states into one sentence so the cached prefix survives.
|
|
13
|
+
* Claude Code puts this text in a system message on the models that take one
|
|
14
|
+
* and in a reminder elsewhere; One Code delivers it through the reminder
|
|
15
|
+
* queue's plan-mode placement either way.
|
|
14
16
|
*/
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
/** Claude Code's "Plan File Info" line, for a plan file that exists or not yet. */
|
|
19
|
+
export function planFileInfo(filePath: string, planExists: boolean): string {
|
|
20
|
+
return planExists
|
|
21
|
+
? `A plan file already exists at ${filePath}. You can read it and make incremental edits using the edit tool.`
|
|
22
|
+
: `No plan file exists yet. You should create your plan at ${filePath} using the write tool.`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function buildPlanModeReminder(filePath: string, planExists = false): string {
|
|
26
|
+
const fileInfo = planFileInfo(filePath, planExists);
|
|
18
27
|
return [
|
|
19
|
-
|
|
28
|
+
"Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supercedes any other instructions you have received.",
|
|
29
|
+
"",
|
|
30
|
+
"## Plan File Info:",
|
|
31
|
+
fileInfo,
|
|
32
|
+
"You should build your plan incrementally by writing to or editing this file. NOTE that this is the only file you are allowed to edit - other than this you are only allowed to take READ-ONLY actions.",
|
|
33
|
+
"",
|
|
34
|
+
"## Plan Workflow",
|
|
35
|
+
"",
|
|
36
|
+
"### Phase 1: Initial Understanding",
|
|
37
|
+
"Goal: Gain a comprehensive understanding of the user's request by reading through code and asking them questions. Critical: In this phase you should only use the explore subagent type.",
|
|
38
|
+
"",
|
|
39
|
+
"1. Focus on understanding the user's request and the code associated with their request. Actively search for existing functions, utilities, and patterns that can be reused — avoid proposing new code when suitable implementations already exist.",
|
|
40
|
+
"",
|
|
41
|
+
"2. **Launch up to 3 explore agents IN PARALLEL** (single message, multiple tool calls) to efficiently explore the codebase.",
|
|
42
|
+
" - Use 1 agent when the task is isolated to known files, the user provided specific file paths, or you're making a small targeted change.",
|
|
43
|
+
" - Use multiple agents when: the scope is uncertain, multiple areas of the codebase are involved, or you need to understand existing patterns before planning.",
|
|
44
|
+
" - Quality over quantity - 3 agents maximum, but you should try to use the minimum number of agents necessary (usually just 1)",
|
|
45
|
+
" - If using multiple agents: Provide each agent with a specific search focus or area to explore. Example: One agent searches for existing implementations, another explores related components, a third investigating testing patterns",
|
|
46
|
+
"",
|
|
47
|
+
"### Phase 2: Design",
|
|
48
|
+
"Goal: Design an implementation approach.",
|
|
49
|
+
"",
|
|
50
|
+
"Launch plan agent(s) to design the implementation based on the user's intent and your exploration results from Phase 1.",
|
|
51
|
+
"",
|
|
52
|
+
"You can launch up to 3 agent(s) in parallel.",
|
|
53
|
+
"",
|
|
54
|
+
"**Guidelines:**",
|
|
55
|
+
"- **Default**: Launch at least 1 plan agent for most tasks - it helps validate your understanding and consider alternatives",
|
|
56
|
+
"- **Skip agents**: Only for truly trivial tasks (typo fixes, single-line changes, simple renames)",
|
|
57
|
+
"- **Multiple agents**: Use up to 3 agents for complex tasks that benefit from different perspectives",
|
|
58
|
+
"",
|
|
59
|
+
"Examples of when to use multiple agents:",
|
|
60
|
+
"- The task touches multiple parts of the codebase",
|
|
61
|
+
"- It's a large refactor or architectural change",
|
|
62
|
+
"- There are many edge cases to consider",
|
|
63
|
+
"- You'd benefit from exploring different approaches",
|
|
64
|
+
"",
|
|
65
|
+
"Example perspectives by task type:",
|
|
66
|
+
"- New feature: simplicity vs performance vs maintainability",
|
|
67
|
+
"- Bug fix: root cause vs workaround vs prevention",
|
|
68
|
+
"- Refactoring: minimal change vs clean architecture",
|
|
69
|
+
"",
|
|
70
|
+
"In the agent prompt:",
|
|
71
|
+
"- Provide comprehensive background context from Phase 1 exploration including filenames and code path traces",
|
|
72
|
+
"- Describe requirements and constraints",
|
|
73
|
+
"- Request a detailed implementation plan",
|
|
74
|
+
"",
|
|
75
|
+
"### Phase 3: Review",
|
|
76
|
+
"Goal: Review the plan(s) from Phase 2 and ensure alignment with the user's intentions.",
|
|
77
|
+
"1. Read the critical files you identified during exploration to deepen your understanding",
|
|
78
|
+
"2. Ensure that the plans align with the user's original request",
|
|
79
|
+
"3. Use ask_user_question to clarify any remaining questions with the user",
|
|
80
|
+
"",
|
|
81
|
+
"### Phase 4: Final Plan",
|
|
82
|
+
"Goal: Write your final plan to the plan file (the only file you can edit).",
|
|
83
|
+
"- Begin with a **Context** section: explain why this change is being made — the problem or need it addresses, what prompted it, and the intended outcome",
|
|
84
|
+
"- Include only your recommended approach, not all alternatives",
|
|
85
|
+
"- Ensure that the plan file is concise enough to scan quickly, but detailed enough to execute effectively",
|
|
86
|
+
"- Name the critical files to be modified. For changes that repeat a pattern across many files, describe the pattern once and list a few representative paths — do not enumerate every file or line number",
|
|
87
|
+
"- Reference existing functions and utilities you found that should be reused, with their file paths",
|
|
88
|
+
"- Include a verification section describing how to test the changes end-to-end (run the code, use MCP tools, run tests)",
|
|
89
|
+
"",
|
|
90
|
+
"### Phase 5: Call exit_plan_mode",
|
|
91
|
+
"At the very end of your turn, once you have asked the user questions and are happy with your final plan file - you should always call exit_plan_mode to indicate to the user that you are done planning.",
|
|
92
|
+
"This is critical - your turn should only end with either using the ask_user_question tool OR calling exit_plan_mode. Do not stop unless it's for these 2 reasons",
|
|
20
93
|
"",
|
|
21
|
-
"
|
|
22
|
-
'1. Explore: delegate broad reconnaissance to the `Agent` tool with `subagent_type: "explore"` (up to 3 in parallel) rather than reading everything yourself.',
|
|
23
|
-
'2. Design: delegate the implementation strategy to the `Agent` tool with `subagent_type: "plan"` once exploration has mapped the ground.',
|
|
24
|
-
"3. Review the critical files yourself, and call `ask_user_question` for any decision you cannot make on the user's behalf.",
|
|
25
|
-
`4. Write the final plan to ${filePath}: a Context section explaining why, your recommended approach (not several options), the critical files named, existing utilities to reuse, and a verification section.`,
|
|
26
|
-
"5. Call `exit_plan_mode` to ask the user to approve the plan. It reads the plan file directly — you do not pass the plan as a parameter. If `exit_plan_mode` is not in your active tools, load it first with tool_search (`select:exit_plan_mode`).",
|
|
94
|
+
"**Important:** Use ask_user_question ONLY to clarify requirements or choose between approaches. Use exit_plan_mode to request plan approval. Do NOT ask about plan approval in any other way - no text questions, no ask_user_question. Phrases like \"Is this plan okay?\", \"Should I proceed?\", \"How does this plan look?\", \"Any changes before we start?\", or similar MUST use exit_plan_mode.",
|
|
27
95
|
"",
|
|
28
|
-
"
|
|
96
|
+
"NOTE: At any point in time through this workflow you should feel free to ask the user questions or clarifications using the ask_user_question tool. Don't make large assumptions about user intent. The goal is to present a well researched plan to the user, and tie any loose ends before implementation begins.",
|
|
29
97
|
].join("\n");
|
|
30
98
|
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plan-mode tools' model-facing texts (pure): Claude Code's EnterPlanMode
|
|
3
|
+
* and ExitPlanMode descriptions and results, with One Code's snake_case tool
|
|
4
|
+
* names. The plan stays file-based (decisions/modes.md, "Plan mode is
|
|
5
|
+
* file-based"); only the wording follows Claude Code.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { DescriptionForm } from "../lib/tool-variants.ts";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Claude Code's EnterPlanMode description, which prefers plan mode for any
|
|
12
|
+
* non-trivial implementation task. Frontier and workhorse models get it.
|
|
13
|
+
*/
|
|
14
|
+
export const ENTER_PLAN_MODE_DESCRIPTION = [
|
|
15
|
+
"Use this tool proactively when you're about to start a non-trivial implementation task. Getting user sign-off on your approach before writing code prevents wasted effort and ensures alignment. This tool transitions you into plan mode where you can explore the codebase and design an implementation approach for user approval.",
|
|
16
|
+
"",
|
|
17
|
+
"## When to Use This Tool",
|
|
18
|
+
"",
|
|
19
|
+
"**Prefer using enter_plan_mode** for implementation tasks unless they're simple. Use it when ANY of these conditions apply:",
|
|
20
|
+
"",
|
|
21
|
+
"1. **New Feature Implementation**: Adding meaningful new functionality",
|
|
22
|
+
" - Example: \"Add a logout button\" - where should it go? What should happen on click?",
|
|
23
|
+
" - Example: \"Add form validation\" - what rules? What error messages?",
|
|
24
|
+
"",
|
|
25
|
+
"2. **Multiple Valid Approaches**: The task can be solved in several different ways",
|
|
26
|
+
" - Example: \"Add caching to the API\" - could use Redis, in-memory, file-based, etc.",
|
|
27
|
+
" - Example: \"Improve performance\" - many optimization strategies possible",
|
|
28
|
+
"",
|
|
29
|
+
"3. **Code Modifications**: Changes that affect existing behavior or structure",
|
|
30
|
+
" - Example: \"Update the login flow\" - what exactly should change?",
|
|
31
|
+
" - Example: \"Refactor this component\" - what's the target architecture?",
|
|
32
|
+
"",
|
|
33
|
+
"4. **Architectural Decisions**: The task requires choosing between patterns or technologies",
|
|
34
|
+
" - Example: \"Add real-time updates\" - WebSockets vs SSE vs polling",
|
|
35
|
+
" - Example: \"Implement state management\" - Redux vs Context vs custom solution",
|
|
36
|
+
"",
|
|
37
|
+
"5. **Multi-File Changes**: The task will likely touch more than 2-3 files",
|
|
38
|
+
" - Example: \"Refactor the authentication system\"",
|
|
39
|
+
" - Example: \"Add a new API endpoint with tests\"",
|
|
40
|
+
"",
|
|
41
|
+
"6. **Unclear Requirements**: You need to explore before understanding the full scope",
|
|
42
|
+
" - Example: \"Make the app faster\" - need to profile and identify bottlenecks",
|
|
43
|
+
" - Example: \"Fix the bug in checkout\" - need to investigate root cause",
|
|
44
|
+
"",
|
|
45
|
+
"7. **User Preferences Matter**: The implementation could reasonably go multiple ways",
|
|
46
|
+
" - If you would use ask_user_question to clarify the approach, use enter_plan_mode instead",
|
|
47
|
+
" - Plan mode lets you explore first, then present options with context",
|
|
48
|
+
"",
|
|
49
|
+
"## When NOT to Use This Tool",
|
|
50
|
+
"",
|
|
51
|
+
"Only skip enter_plan_mode for simple tasks:",
|
|
52
|
+
"- Single-line or few-line fixes (typos, obvious bugs, small tweaks)",
|
|
53
|
+
"- Adding a single function with clear requirements",
|
|
54
|
+
"- Tasks where the user has given very specific, detailed instructions",
|
|
55
|
+
"- Pure research/exploration tasks (use the Agent tool instead)",
|
|
56
|
+
"",
|
|
57
|
+
"## What Happens in Plan Mode",
|
|
58
|
+
"",
|
|
59
|
+
"In plan mode, you'll:",
|
|
60
|
+
"1. Thoroughly explore the codebase using `find`, `grep`, and read",
|
|
61
|
+
"2. Understand existing patterns and architecture",
|
|
62
|
+
"3. Design an implementation approach",
|
|
63
|
+
"4. Present your plan to the user for approval",
|
|
64
|
+
"5. Use ask_user_question if you need to clarify approaches",
|
|
65
|
+
"6. Exit plan mode with exit_plan_mode when ready to implement",
|
|
66
|
+
"",
|
|
67
|
+
"## Examples",
|
|
68
|
+
"",
|
|
69
|
+
"### GOOD - Use enter_plan_mode:",
|
|
70
|
+
"User: \"Add user authentication to the app\"",
|
|
71
|
+
"- Requires architectural decisions (session vs JWT, where to store tokens, middleware structure)",
|
|
72
|
+
"",
|
|
73
|
+
"User: \"Optimize the database queries\"",
|
|
74
|
+
"- Multiple approaches possible, need to profile first, significant impact",
|
|
75
|
+
"",
|
|
76
|
+
"User: \"Implement dark mode\"",
|
|
77
|
+
"- Architectural decision on theme system, affects many components",
|
|
78
|
+
"",
|
|
79
|
+
"User: \"Add a delete button to the user profile\"",
|
|
80
|
+
"- Seems simple but involves: where to place it, confirmation dialog, API call, error handling, state updates",
|
|
81
|
+
"",
|
|
82
|
+
"User: \"Update the error handling in the API\"",
|
|
83
|
+
"- Affects multiple files, user should approve the approach",
|
|
84
|
+
"",
|
|
85
|
+
"### BAD - Don't use enter_plan_mode:",
|
|
86
|
+
"User: \"Fix the typo in the README\"",
|
|
87
|
+
"- Straightforward, no planning needed",
|
|
88
|
+
"",
|
|
89
|
+
"User: \"Add a console.log to debug this function\"",
|
|
90
|
+
"- Simple, obvious implementation",
|
|
91
|
+
"",
|
|
92
|
+
"User: \"What files handle routing?\"",
|
|
93
|
+
"- Research task, not implementation planning",
|
|
94
|
+
"",
|
|
95
|
+
"## Important Notes",
|
|
96
|
+
"",
|
|
97
|
+
"- This tool REQUIRES user approval - they must consent to entering plan mode",
|
|
98
|
+
"- If unsure whether to use it, err on the side of planning - it's better to get alignment upfront than to redo work",
|
|
99
|
+
"- Users appreciate being consulted before significant changes are made to their codebase",
|
|
100
|
+
"",
|
|
101
|
+
].join("\n");
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* One Code's own description for the cheap and tiny tiers. Weak models read a
|
|
105
|
+
* "prefer plan mode" description as standing policy and planned trivial tasks
|
|
106
|
+
* (decisions/tools.md, "Weak-model steering"), so this one says most tasks do
|
|
107
|
+
* not need it.
|
|
108
|
+
*/
|
|
109
|
+
export const ENTER_PLAN_MODE_DESCRIPTION_WEAK =
|
|
110
|
+
"Enter plan mode: read-only investigation to design an approach before changing anything. Most tasks do not need it.\n" +
|
|
111
|
+
"For a small or clearly-scoped change, act directly instead. Enter plan mode only for multi-file work whose design is genuinely unclear, or when the user asks for a plan. In plan mode only read-only tools are available, plus one writable file: the plan file whose path you are told, where you build the plan incrementally.";
|
|
112
|
+
|
|
113
|
+
/** The enter_plan_mode description for a description form: Claude Code's short form, ours as the long one. */
|
|
114
|
+
export function enterPlanModeDescription(form: DescriptionForm): string {
|
|
115
|
+
return form === "long" ? ENTER_PLAN_MODE_DESCRIPTION_WEAK : ENTER_PLAN_MODE_DESCRIPTION;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Claude Code's ExitPlanMode description. */
|
|
119
|
+
export const EXIT_PLAN_MODE_DESCRIPTION = [
|
|
120
|
+
"Use this tool when you are in plan mode and have finished writing your plan to the plan file and are ready for user approval.",
|
|
121
|
+
"",
|
|
122
|
+
"## How This Tool Works",
|
|
123
|
+
"- You should have already written your plan to the plan file specified in the plan mode system message",
|
|
124
|
+
"- This tool does NOT take the plan content as a parameter - it will read the plan from the file you wrote",
|
|
125
|
+
"- This tool simply signals that you're done planning and ready for the user to review and approve",
|
|
126
|
+
"- The user will see the contents of your plan file when they review it",
|
|
127
|
+
"",
|
|
128
|
+
"## When to Use This Tool",
|
|
129
|
+
"IMPORTANT: Only use this tool when the task requires planning the implementation steps of a task that requires writing code. For research tasks where you're gathering information, searching files, reading files or in general trying to understand the codebase - do NOT use this tool.",
|
|
130
|
+
"",
|
|
131
|
+
"## Before Using This Tool",
|
|
132
|
+
"Ensure your plan is complete and unambiguous:",
|
|
133
|
+
"- If you have unresolved questions about requirements or approach, use ask_user_question first (in earlier phases)",
|
|
134
|
+
"- Once your plan is finalized, use THIS tool to request approval",
|
|
135
|
+
"",
|
|
136
|
+
"**Important:** Do NOT use ask_user_question to ask \"Is this plan okay?\" or \"Should I proceed?\" - that's exactly what THIS tool does. exit_plan_mode inherently requests user approval of your plan.",
|
|
137
|
+
"",
|
|
138
|
+
"## Examples",
|
|
139
|
+
"",
|
|
140
|
+
"1. Initial task: \"Search for and understand the implementation of vim mode in the codebase\" - Do not use the exit plan mode tool because you are not planning the implementation steps of a task.",
|
|
141
|
+
"2. Initial task: \"Help me implement yank mode for vim\" - Use the exit plan mode tool after you have finished planning the implementation steps of the task.",
|
|
142
|
+
"3. Initial task: \"Add a new feature to handle user authentication\" - If unsure about auth method (OAuth, JWT, etc.), use ask_user_question first, then use exit plan mode tool after clarifying the approach.",
|
|
143
|
+
"",
|
|
144
|
+
].join("\n");
|
|
145
|
+
|
|
146
|
+
/** Claude Code's EnterPlanMode result. */
|
|
147
|
+
const ENTERED_PLAN_MODE = [
|
|
148
|
+
"Entered plan mode. You should now focus on exploring the codebase and designing an implementation approach.",
|
|
149
|
+
"",
|
|
150
|
+
"In plan mode, you should:",
|
|
151
|
+
"1. Thoroughly explore the codebase to understand existing patterns",
|
|
152
|
+
"2. Identify similar features and architectural approaches",
|
|
153
|
+
"3. Consider multiple approaches and their trade-offs",
|
|
154
|
+
"4. Use ask_user_question if you need to clarify the approach",
|
|
155
|
+
"5. Design a concrete implementation strategy",
|
|
156
|
+
"6. When ready, use exit_plan_mode to present your plan for approval",
|
|
157
|
+
"",
|
|
158
|
+
"Remember: DO NOT write or edit any files yet. This is a read-only exploration and planning phase.",
|
|
159
|
+
].join("\n");
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* enter_plan_mode's result: Claude Code's text, then the plan file's path so
|
|
163
|
+
* the model can start writing the plan in the same turn.
|
|
164
|
+
*/
|
|
165
|
+
export function enteredPlanModeText(planFilePath: string): string {
|
|
166
|
+
return `${ENTERED_PLAN_MODE}\n\nYour plan file is ${planFilePath}, the one file you may write: build your plan there.`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** exit_plan_mode's result when the user approves: Claude Code's text, with the plan file's contents. */
|
|
170
|
+
export function approvedPlanText(planFilePath: string, plan: string): string {
|
|
171
|
+
return `User has approved your plan. You can now start coding. Start with updating your todo list if applicable\n\nYour plan has been saved to: ${planFilePath}\nYou can refer back to it if needed during implementation.\n\n## Approved Plan:\n${plan}`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Claude Code's reminder after the approval: plan mode is over and the plan file stays readable. */
|
|
175
|
+
export function exitedPlanModeText(planFilePath: string): string {
|
|
176
|
+
return `## Exited Plan Mode\n\nYou have exited plan mode. You can now make edits, run tools, and take actions. The plan file is located at ${planFilePath} if you need to reference it.`;
|
|
177
|
+
}
|