one-code-extension 0.4.1 → 0.6.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 +16 -5
- 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 +40 -28
- package/docs/guide/doctor.md +20 -13
- package/docs/guide/hooks.md +18 -3
- package/docs/guide/installation.md +26 -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 +58 -31
- 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 +124 -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 +642 -0
- package/extensions/background/index.ts +614 -248
- package/extensions/background/loop-fire.ts +173 -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 +56 -0
- package/extensions/background/wakeup.ts +178 -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 +66 -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 +250 -78
- package/extensions/btw/panel.ts +228 -100
- package/extensions/btw/prompt.ts +41 -4
- package/extensions/cache-marks/index.ts +42 -0
- package/extensions/claude-compat/index.ts +7 -11
- package/extensions/claude-context/index.ts +436 -63
- package/extensions/compaction/cut.ts +157 -0
- package/extensions/compaction/index.ts +219 -75
- package/extensions/compaction/kept-thinking.ts +62 -0
- package/extensions/compaction/prompt.ts +15 -12
- package/extensions/context-budget/budget.ts +16 -2
- package/extensions/context-budget/index.ts +35 -15
- package/extensions/context-management/index.ts +36 -28
- 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 +141 -25
- 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 +420 -42
- package/extensions/file-tracker/replay.ts +137 -24
- package/extensions/file-tracker/restore.ts +66 -0
- package/extensions/file-tracker/results.ts +66 -0
- package/extensions/file-tracker/shell-reads.ts +211 -0
- package/extensions/file-tracker/tracker.ts +45 -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 +209 -58
- package/extensions/hooks/matcher.ts +3 -0
- package/extensions/hooks/prompt-context.ts +59 -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 +26 -12
- 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/ledger/index.ts +46 -0
- package/extensions/ledger/wire.ts +154 -0
- package/extensions/lib/agent-cron.ts +146 -0
- package/extensions/lib/agent-loader.ts +18 -3
- package/extensions/lib/agent-view.ts +85 -0
- package/extensions/lib/anthropic-auth.ts +98 -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 +52 -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 +97 -0
- package/extensions/lib/covered-messages.ts +23 -0
- package/extensions/lib/deferred.ts +359 -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/ledger/fold-memo.ts +49 -0
- package/extensions/lib/ledger/fold.ts +265 -0
- package/extensions/lib/ledger/layout.ts +72 -0
- package/extensions/lib/ledger/plan.ts +102 -0
- package/extensions/lib/ledger/records.ts +276 -0
- package/extensions/lib/ledger/state.ts +47 -0
- package/extensions/lib/ledger/validate.ts +141 -0
- package/extensions/lib/ledger/wire.ts +632 -0
- package/extensions/lib/local-command.ts +71 -19
- 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 +178 -0
- package/extensions/lib/model-catalog/models-dev.json +18533 -0
- package/extensions/lib/model-catalog/openrouter.json +5050 -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 +357 -73
- 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 +38 -2
- package/extensions/lib/plan-mode-channels.ts +42 -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/previous-mark.ts +101 -0
- package/extensions/lib/process-state.ts +48 -0
- package/extensions/lib/process-tree.ts +132 -8
- package/extensions/lib/prompt-options.ts +82 -0
- package/extensions/lib/queued-delivery.ts +44 -0
- package/extensions/lib/reminders.ts +370 -358
- package/extensions/lib/replaced-builtins.mjs +199 -0
- package/extensions/lib/replay-call.ts +70 -0
- package/extensions/lib/request-replay.ts +547 -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 +24 -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 +112 -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 +129 -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 +159 -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 +76 -12
- 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 +90 -43
- 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 +220 -121
- 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 +164 -73
- 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/model-default/index.ts +86 -19
- 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 +1426 -398
- package/extensions/permissions/matcher.ts +425 -74
- package/extensions/permissions/modes.ts +11 -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 +276 -92
- package/extensions/plan-mode/reminder.ts +89 -21
- package/extensions/plan-mode/run-state.ts +26 -0
- 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 +64 -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 +14 -7
- package/extensions/recap/index.ts +73 -71
- 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/announce.ts +30 -0
- package/extensions/skill/code-review.ts +97 -0
- package/extensions/skill/index.ts +469 -132
- package/extensions/skill/invoke.ts +118 -75
- 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 +146 -31
- package/extensions/subagents/default-model.ts +2 -3
- package/extensions/subagents/delegation-steer.ts +4 -4
- package/extensions/subagents/fork-cache.ts +82 -0
- package/extensions/subagents/guide-agent.ts +189 -0
- package/extensions/subagents/hand-back-review.ts +3 -0
- package/extensions/subagents/index.ts +1594 -852
- package/extensions/subagents/live-runs.ts +26 -6
- package/extensions/subagents/model-select.ts +38 -25
- package/extensions/subagents/outcome.ts +5 -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/parent-mode.ts +50 -0
- package/extensions/subagents/pending-claim.ts +18 -1
- package/extensions/subagents/runner.ts +135 -80
- package/extensions/subagents/runs.ts +44 -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 +165 -47
- package/extensions/system-prompt/template.ts +34 -51
- 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 +204 -70
- 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/index.ts +366 -144
- 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 +108 -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 +157 -162
- package/extensions/workflow/records.ts +1 -0
- package/extensions/workflow/run-manager.ts +33 -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 +162 -44
- package/extensions/worktree/powershell-guards.ts +167 -0
- package/extensions/worktree/rewrite.ts +14 -16
- package/package.json +21 -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/tool-search/announce.ts +0 -42
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thinking removed from the turns a compaction keeps. Pure: no pi imports.
|
|
3
|
+
*
|
|
4
|
+
* On Fable 5.1, Opus 5.5 and Sonnet 5.5 a signed thinking block is bound to
|
|
5
|
+
* the conversation before it, and a compaction rewrites that conversation:
|
|
6
|
+
* the kept reply's thinking fails the check on every later request (a 400 on
|
|
7
|
+
* accounts created from 2026-08-31; dropped silently under pi-ai 0.99.2's
|
|
8
|
+
* `drop_block`; findings §46). Blocks may be removed from the start, so the
|
|
9
|
+
* kept turns go out without theirs, from the first request after the
|
|
10
|
+
* compaction on, the same bytes every time. Thinking produced after the
|
|
11
|
+
* compaction binds to that stripped history and stays.
|
|
12
|
+
*
|
|
13
|
+
* The kept turns are the assistant messages older than the latest compaction
|
|
14
|
+
* entry on the session branch (`lib/compaction-boundary.ts`): every message
|
|
15
|
+
* produced since is newer. Text and tool calls stay.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** APIs whose replayed thinking carries a signature the provider checks (pi-ai's converters). */
|
|
19
|
+
const SIGNED_THINKING_APIS = new Set(["anthropic-messages", "bedrock-converse-stream"]);
|
|
20
|
+
|
|
21
|
+
type ContextMessage = { role: string; timestamp?: number; content?: unknown };
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The messages with every thinking block (redacted ones included) removed from
|
|
25
|
+
* assistant messages older than `compactionTime`, or undefined when nothing
|
|
26
|
+
* changes: another API, no compaction, or no kept thinking. An assistant
|
|
27
|
+
* message left empty is skipped by pi-ai's converter, as any empty one is.
|
|
28
|
+
*/
|
|
29
|
+
export function withoutKeptThinking<M extends ContextMessage>(
|
|
30
|
+
messages: readonly M[],
|
|
31
|
+
api: string | undefined,
|
|
32
|
+
compactionTime: number | undefined,
|
|
33
|
+
): M[] | undefined {
|
|
34
|
+
if (!signsThinking(api) || compactionTime === undefined || Number.isNaN(compactionTime)) return undefined;
|
|
35
|
+
return stripThinking(messages, (message) => typeof message.timestamp === "number" && message.timestamp < compactionTime);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The messages with every assistant message's thinking removed, for a request
|
|
40
|
+
* whose system prompt and tools are not the session's (the standalone
|
|
41
|
+
* compaction request): none of its signed blocks would pass the check. The
|
|
42
|
+
* messages unchanged on other APIs.
|
|
43
|
+
*/
|
|
44
|
+
export function withoutThinking<M extends ContextMessage>(messages: M[], api: string | undefined): M[] {
|
|
45
|
+
return (signsThinking(api) && stripThinking(messages, () => true)) || messages;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Whether requests on `api` carry signed thinking the provider checks. */
|
|
49
|
+
export const signsThinking = (api: string | undefined): boolean => api !== undefined && SIGNED_THINKING_APIS.has(api);
|
|
50
|
+
|
|
51
|
+
/** The messages with thinking removed from the assistant messages `applies` picks, or undefined when none had any. Copies only on a change. */
|
|
52
|
+
function stripThinking<M extends ContextMessage>(messages: readonly M[], applies: (message: M) => boolean): M[] | undefined {
|
|
53
|
+
let result: M[] | undefined;
|
|
54
|
+
messages.forEach((message, i) => {
|
|
55
|
+
if (message.role !== "assistant" || !Array.isArray(message.content) || !message.content.some(isThinking) || !applies(message)) return;
|
|
56
|
+
result ??= messages.slice();
|
|
57
|
+
result[i] = { ...message, content: message.content.filter((block) => !isThinking(block)) };
|
|
58
|
+
});
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const isThinking = (block: unknown): boolean => (block as { type?: unknown } | null)?.type === "thinking";
|
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
* COMPACTION_INSTRUCTION matches Claude Code's: appended as a user text block
|
|
5
5
|
* after the full conversation, the model answers with an <analysis> block
|
|
6
6
|
* followed by a <summary> block, and only the <summary> content becomes the
|
|
7
|
-
* surviving context. Auto-compaction uses the same prompt.
|
|
7
|
+
* surviving context. Auto-compaction uses the same prompt. Two lines end in a
|
|
8
|
+
* space, as Claude Code's do; they are written `\x20` so editors keep them.
|
|
8
9
|
*
|
|
9
10
|
* Claude Code runs the call on the *session's own model* with max_tokens
|
|
10
|
-
*
|
|
11
|
-
* provider prompt cache pays for most of the compaction
|
|
12
|
-
* does the same
|
|
11
|
+
* 128000 (findings §47), keeping the system prompt, tools, and message
|
|
12
|
+
* prefix intact — so the provider prompt cache pays for most of the compaction
|
|
13
|
+
* call. The extension does the same; the cap is lowered to the model's output
|
|
14
|
+
* limit and to the room the context window leaves.
|
|
13
15
|
*/
|
|
14
16
|
|
|
15
|
-
export const COMPACTION_MAX_TOKENS =
|
|
17
|
+
export const COMPACTION_MAX_TOKENS = 128_000;
|
|
16
18
|
|
|
17
19
|
export const COMPACTION_INSTRUCTION = `CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.
|
|
18
20
|
|
|
@@ -87,7 +89,7 @@ Here's an example of how your output should be structured:
|
|
|
87
89
|
5. Problem Solving:
|
|
88
90
|
[Description of solved problems and ongoing troubleshooting]
|
|
89
91
|
|
|
90
|
-
6. All user messages
|
|
92
|
+
6. All user messages:\x20
|
|
91
93
|
- [Detailed non tool use user message]
|
|
92
94
|
- [...]
|
|
93
95
|
|
|
@@ -105,7 +107,7 @@ Here's an example of how your output should be structured:
|
|
|
105
107
|
</summary>
|
|
106
108
|
</example>
|
|
107
109
|
|
|
108
|
-
Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response
|
|
110
|
+
Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response.\x20
|
|
109
111
|
|
|
110
112
|
There may be additional summarization instructions provided in the included context. If so, remember to follow these instructions when creating the above summary. Examples of instructions include:
|
|
111
113
|
<example>
|
|
@@ -138,7 +140,7 @@ export function buildCompactionInstruction(options: {
|
|
|
138
140
|
* says so, so the summary covers the part that is actually discarded
|
|
139
141
|
* instead of re-telling what the model will still see in full.
|
|
140
142
|
*/
|
|
141
|
-
keptTail?: { count: number;
|
|
143
|
+
keptTail?: { count: number; landmark?: string };
|
|
142
144
|
}): string {
|
|
143
145
|
const notice =
|
|
144
146
|
options.reason === "manual"
|
|
@@ -155,11 +157,12 @@ export function buildCompactionInstruction(options: {
|
|
|
155
157
|
|
|
156
158
|
/**
|
|
157
159
|
* The scope note for pi's kept tail: the summary replaces only what precedes
|
|
158
|
-
* it.
|
|
159
|
-
* can find in the transcript, since a bare count is
|
|
160
|
+
* it. Naming the first kept message (how it opens, or the tool it calls) gives
|
|
161
|
+
* the model a landmark it can find in the transcript, since a bare count is
|
|
162
|
+
* easy to miscount.
|
|
160
163
|
*/
|
|
161
|
-
export function keptTailNote(tail: { count: number;
|
|
162
|
-
const landmark = tail.
|
|
164
|
+
export function keptTailNote(tail: { count: number; landmark?: string }): string {
|
|
165
|
+
const landmark = tail.landmark?.trim() ? `, beginning with ${tail.landmark.trim()}` : "";
|
|
163
166
|
return ` Only the earlier part of the conversation is being summarized: the final ${tail.count} ${
|
|
164
167
|
tail.count === 1 ? "message" : "messages"
|
|
165
168
|
}${landmark}, stay in context verbatim after the summary. Do not summarize them; cover everything before them, and use them only to judge which earlier details still matter.`;
|
|
@@ -32,17 +32,31 @@ function finite(n: number | null | undefined): number | undefined {
|
|
|
32
32
|
* from; `left` takes the size now and returns what remains of the budget. The
|
|
33
33
|
* value never rises within a turn (as CC's does not), the first known size
|
|
34
34
|
* becomes the baseline when the turn started without an estimate, and an
|
|
35
|
-
* unknown size repeats the last value.
|
|
35
|
+
* unknown size repeats the last value. A compaction inside the turn shrinks
|
|
36
|
+
* the context below the baseline, so `rebase` measures growth from the
|
|
37
|
+
* smaller context on top of what the turn had already spent; without it the
|
|
38
|
+
* countdown stood still until the context regrew past the turn's start.
|
|
36
39
|
*/
|
|
37
40
|
export class TurnBudget {
|
|
38
41
|
private start: number | undefined;
|
|
42
|
+
/** Spent since `start`. */
|
|
39
43
|
private spent = 0;
|
|
44
|
+
/** Spent before the last rebase. */
|
|
45
|
+
private banked = 0;
|
|
40
46
|
|
|
41
47
|
constructor(readonly budget: number) {}
|
|
42
48
|
|
|
43
49
|
startTurn(contextTokens: number | null | undefined): void {
|
|
44
50
|
this.start = finite(contextTokens);
|
|
45
51
|
this.spent = 0;
|
|
52
|
+
this.banked = 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Measure from `contextTokens` (or the next known size) on, keeping what the turn spent so far. */
|
|
56
|
+
rebase(contextTokens: number | null | undefined): void {
|
|
57
|
+
this.banked += this.spent;
|
|
58
|
+
this.spent = 0;
|
|
59
|
+
this.start = finite(contextTokens);
|
|
46
60
|
}
|
|
47
61
|
|
|
48
62
|
left(contextTokens: number | null | undefined): number {
|
|
@@ -51,7 +65,7 @@ export class TurnBudget {
|
|
|
51
65
|
if (this.start === undefined) this.start = now;
|
|
52
66
|
this.spent = Math.max(this.spent, now - this.start);
|
|
53
67
|
}
|
|
54
|
-
return Math.max(0, this.budget - this.spent);
|
|
68
|
+
return Math.max(0, this.budget - this.banked - this.spent);
|
|
55
69
|
}
|
|
56
70
|
}
|
|
57
71
|
|
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* context-budget extension — Claude Code's `<total_tokens>N tokens left</total_tokens>`
|
|
3
|
-
* line, in the
|
|
3
|
+
* line, in the places CC puts it (budget.ts says what the number is). It
|
|
4
|
+
* stores the line in One Code's own way; system-reminder's payload hook turns
|
|
5
|
+
* the stored line into Claude Code's per-model shapes on the wire
|
|
6
|
+
* (lib/turn-budget-layout.ts):
|
|
4
7
|
*
|
|
5
|
-
* - the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
+
* - the first prompt: the constant budget in the first-message context stack
|
|
9
|
+
* (CONTEXT_ORDER.totalTokens), so it joins the mid-conversation system
|
|
10
|
+
* message where there is one;
|
|
11
|
+
* - every later user message: the constant budget as a raw marker, a `sticky-append`
|
|
12
|
+
* reminder keyed once per session (`since: 0`: every user message a request
|
|
13
|
+
* sends carries it, the first prompt excepted);
|
|
8
14
|
* - every tool result: the countdown, a RAW `last-append` one-shot queued at
|
|
9
|
-
* `tool_result` time and
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* It emits only at runtime, never at load, so the "listeners load first" rule
|
|
15
|
-
* for the bus is not at stake;
|
|
15
|
+
* `tool_result` time and bound to its call's id, so it rides that result on
|
|
16
|
+
* the next request (pi runs a parallel batch's `tool_result` hooks
|
|
17
|
+
* concurrently; unbound, every countdown would land on the batch's last
|
|
18
|
+
* result). The request that carries it records it (extensions/ledger), so no
|
|
19
|
+
* later request re-renders it;
|
|
16
20
|
* - the system prompt, before the gitStatus block — appended by the
|
|
17
21
|
* system-prompt extension from the same pure module.
|
|
18
22
|
*
|
|
19
23
|
* A turn starts at the first `agent_start` after a settle (whoever opened it: a
|
|
20
24
|
* prompt or a harness notification) and its baseline is pi's context estimate
|
|
21
|
-
* at that moment. CC_TOTAL_TOKENS=0 turns
|
|
25
|
+
* at that moment; a compaction rebases it (budget.ts). CC_TOTAL_TOKENS=0 turns
|
|
26
|
+
* all three off.
|
|
22
27
|
*/
|
|
23
28
|
|
|
24
29
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
25
|
-
import { REMINDER_CHANNEL, type ReminderPayload } from "../lib/reminders.ts";
|
|
30
|
+
import { CONTEXT_ORDER, REMINDER_CHANNEL, type ReminderPayload } from "../lib/reminders.ts";
|
|
26
31
|
import { totalTokensBlock, TurnBudget, turnTokenBudget } from "./budget.ts";
|
|
27
32
|
|
|
28
33
|
const USER_MESSAGE_KEY = "total-tokens";
|
|
34
|
+
const FIRST_PROMPT_KEY = "total-tokens-first";
|
|
29
35
|
|
|
30
36
|
export default function contextBudgetExtension(pi: ExtensionAPI) {
|
|
31
37
|
const enabled = () => process.env.CC_TOTAL_TOKENS !== "0";
|
|
@@ -38,11 +44,18 @@ export default function contextBudgetExtension(pi: ExtensionAPI) {
|
|
|
38
44
|
if (!enabled()) return;
|
|
39
45
|
pi.events.emit(REMINDER_CHANNEL, {
|
|
40
46
|
text: totalTokensBlock(budget.budget),
|
|
41
|
-
|
|
47
|
+
key: FIRST_PROMPT_KEY,
|
|
48
|
+
placement: "first-prepend",
|
|
49
|
+
order: CONTEXT_ORDER.totalTokens,
|
|
50
|
+
} satisfies ReminderPayload);
|
|
51
|
+
pi.events.emit(REMINDER_CHANNEL, {
|
|
52
|
+
text: totalTokensBlock(budget.budget),
|
|
42
53
|
key: USER_MESSAGE_KEY,
|
|
43
54
|
placement: "sticky-append",
|
|
44
55
|
raw: true,
|
|
45
56
|
since: 0,
|
|
57
|
+
// The first prompt carries the line in the context stack instead.
|
|
58
|
+
skipStackCarrier: true,
|
|
46
59
|
} satisfies ReminderPayload);
|
|
47
60
|
});
|
|
48
61
|
|
|
@@ -54,13 +67,20 @@ export default function contextBudgetExtension(pi: ExtensionAPI) {
|
|
|
54
67
|
pi.on("agent_settled", () => {
|
|
55
68
|
busy = false;
|
|
56
69
|
});
|
|
70
|
+
// A compaction (an auto one mid-turn, an overflow retry) drops the context
|
|
71
|
+
// below the turn's baseline; pi knows its new size only after the next reply,
|
|
72
|
+
// so the first size it reports becomes the baseline.
|
|
73
|
+
pi.on("session_compact", (_event, ctx) => {
|
|
74
|
+
budget.rebase(ctx.getContextUsage()?.tokens);
|
|
75
|
+
});
|
|
57
76
|
|
|
58
|
-
pi.on("tool_result", (
|
|
77
|
+
pi.on("tool_result", (event, ctx) => {
|
|
59
78
|
if (!enabled()) return;
|
|
60
79
|
pi.events.emit(REMINDER_CHANNEL, {
|
|
61
80
|
text: totalTokensBlock(budget.left(ctx.getContextUsage()?.tokens)),
|
|
62
81
|
placement: "last-append",
|
|
63
82
|
raw: true,
|
|
83
|
+
toolCallId: event.toolCallId,
|
|
64
84
|
} satisfies ReminderPayload);
|
|
65
85
|
});
|
|
66
86
|
}
|
|
@@ -38,9 +38,8 @@
|
|
|
38
38
|
* for an anthropic-messages endpoint you have confirmed accepts it.
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import { type ExtensionAPI, getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
41
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
42
|
+
import { isAnthropicOAuth } from "../lib/anthropic-auth.ts";
|
|
44
43
|
import { looksLikeAnthropicRequest } from "../lib/anthropic-payload.ts";
|
|
45
44
|
import { CACHE_RETENTION_ENV, mainSessionCacheRetention } from "../lib/cache-retention.ts";
|
|
46
45
|
|
|
@@ -59,11 +58,20 @@ const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
|
59
58
|
// "fallbacks: Extra inputs are not permitted" (verified live, api.anthropic.com
|
|
60
59
|
// 2026-09-01). Mirrors pi's shouldUseServerSideFallbackBeta.
|
|
61
60
|
const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
|
|
61
|
+
// The same trap for models whose compat carries `supportsMidConvoEffort` (Opus 5,
|
|
62
|
+
// Opus 5.5, Fable 5.1): pi inserts `role: "system"` messages holding an
|
|
63
|
+
// `output_config`, and without these two betas the API 400s with
|
|
64
|
+
// "messages.1.output_config: Extra inputs are not permitted" (verified live,
|
|
65
|
+
// 2026-09-23). `test/unit/context-management.test.ts` fails when the installed
|
|
66
|
+
// pi-ai declares a beta this list does not account for.
|
|
67
|
+
const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
|
|
68
|
+
const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
|
|
62
69
|
|
|
63
70
|
export interface AnthropicModelCompat {
|
|
64
71
|
forceAdaptiveThinking?: boolean;
|
|
65
72
|
supportsEagerToolInputStreaming?: boolean;
|
|
66
73
|
allowedFallbackModels?: unknown[];
|
|
74
|
+
supportsMidConvoEffort?: boolean;
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
/** pi's beta list for this model/auth, with the context-management beta appended. */
|
|
@@ -75,6 +83,7 @@ export function anthropicBetas(oauth: boolean, compat: AnthropicModelCompat | un
|
|
|
75
83
|
if (compat?.forceAdaptiveThinking !== true) betas.push(INTERLEAVED_THINKING_BETA);
|
|
76
84
|
// pi puts a `fallbacks` body field on these models; the beta must ride along.
|
|
77
85
|
if ((compat?.allowedFallbackModels?.length ?? 0) > 0) betas.push(SERVER_SIDE_FALLBACK_BETA);
|
|
86
|
+
if (compat?.supportsMidConvoEffort === true) betas.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
|
|
78
87
|
betas.push(CONTEXT_MANAGEMENT_BETA);
|
|
79
88
|
return betas.join(",");
|
|
80
89
|
}
|
|
@@ -83,9 +92,16 @@ export function anthropicBetas(oauth: boolean, compat: AnthropicModelCompat | un
|
|
|
83
92
|
// tool-search); re-exported so existing importers keep working.
|
|
84
93
|
export { looksLikeAnthropicRequest } from "../lib/anthropic-payload.ts";
|
|
85
94
|
|
|
86
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* The edit is rejected unless thinking is on: enabled or adaptive in the
|
|
97
|
+
* request, or left to an adaptive model's default. A request that turns
|
|
98
|
+
* thinking off (`{ type: "disabled" }`, "off" effort on Opus 5 and Haiku 5.5)
|
|
99
|
+
* takes no edit, adaptive model or not (round-2 review H3).
|
|
100
|
+
*/
|
|
87
101
|
export function clearThinkingApplies(payload: Record<string, unknown>, forceAdaptiveThinking: boolean): boolean {
|
|
88
|
-
|
|
102
|
+
const type = (payload.thinking as { type?: unknown } | undefined)?.type;
|
|
103
|
+
if (type === undefined) return payload.thinking === undefined && forceAdaptiveThinking;
|
|
104
|
+
return type === "enabled" || type === "adaptive";
|
|
89
105
|
}
|
|
90
106
|
|
|
91
107
|
export function withClearThinking(payload: Record<string, unknown>): Record<string, unknown> {
|
|
@@ -99,29 +115,6 @@ export function withClearThinking(payload: Record<string, unknown>): Record<stri
|
|
|
99
115
|
};
|
|
100
116
|
}
|
|
101
117
|
|
|
102
|
-
/** mtime cache: this runs on every provider request, the hottest path there is. */
|
|
103
|
-
let authCache: { mtimeMs: number; oauth: boolean } | undefined;
|
|
104
|
-
|
|
105
|
-
/** OAuth logins need pi's identity betas kept in the header we overwrite. */
|
|
106
|
-
export function isAnthropicOAuth(): boolean {
|
|
107
|
-
// getAgentDir() honours PI_CODING_AGENT_DIR, so an isolated one-code app
|
|
108
|
-
// reads its own auth.json rather than ~/.pi's.
|
|
109
|
-
const path = join(getAgentDir(), "auth.json");
|
|
110
|
-
try {
|
|
111
|
-
const mtimeMs = statSync(path).mtimeMs;
|
|
112
|
-
const cached = authCache;
|
|
113
|
-
if (cached && cached.mtimeMs === mtimeMs) return cached.oauth;
|
|
114
|
-
const auth = JSON.parse(readFileSync(path, "utf8"));
|
|
115
|
-
const entry = auth?.anthropic;
|
|
116
|
-
const oauth = entry?.type === "oauth" || typeof entry?.refresh === "string";
|
|
117
|
-
authCache = { mtimeMs, oauth };
|
|
118
|
-
return oauth;
|
|
119
|
-
} catch {
|
|
120
|
-
authCache = undefined;
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
118
|
interface AnthropicishModel {
|
|
126
119
|
api?: string;
|
|
127
120
|
provider?: string;
|
|
@@ -141,6 +134,21 @@ export function clearThinkingEnabled(flag: string | undefined, model: Anthropici
|
|
|
141
134
|
return model.provider === "anthropic" && (model.baseUrl ?? "").includes("api.anthropic.com");
|
|
142
135
|
}
|
|
143
136
|
|
|
137
|
+
/**
|
|
138
|
+
* The headers a side call on the session model needs so its request matches the
|
|
139
|
+
* session's: the auth headers plus, where clear_thinking is on, the beta header
|
|
140
|
+
* the session's requests carry (completeSimple bypasses our header hook).
|
|
141
|
+
*/
|
|
142
|
+
export function sessionRequestHeaders<H extends Record<string, string | null>>(
|
|
143
|
+
model: { api?: string; provider?: string; baseUrl?: string; compat?: unknown } | undefined,
|
|
144
|
+
headers: H | undefined,
|
|
145
|
+
): H | Record<string, string | null> | undefined {
|
|
146
|
+
// compat is a provider union; clearThinkingEnabled only passes Anthropic models.
|
|
147
|
+
const anthropic = model as AnthropicishModel | undefined;
|
|
148
|
+
if (!clearThinkingEnabled(process.env.CC_CLEAR_THINKING, anthropic)) return headers;
|
|
149
|
+
return { ...headers, "anthropic-beta": anthropicBetas(isAnthropicOAuth(), anthropic?.compat) };
|
|
150
|
+
}
|
|
151
|
+
|
|
144
152
|
export default function contextManagementExtension(pi: ExtensionAPI) {
|
|
145
153
|
const flag = () => process.env.CC_CLEAR_THINKING;
|
|
146
154
|
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
* MCP servers reachable, what external programs are missing — then the issues.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { dirname, join } from "node:path";
|
|
11
|
-
import { fileURLToPath } from "node:url";
|
|
12
10
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
13
11
|
import { extensionVersion } from "../lib/package-version.ts";
|
|
14
12
|
import { piVersionWarning, TESTED_PI_MAX_EXCLUSIVE, TESTED_PI_MIN } from "../lib/pi-version.ts";
|
|
@@ -20,6 +18,10 @@ import { collectCompat, importedConfigSection, mcpSection } from "./compat.ts";
|
|
|
20
18
|
import { checkDependencies, dependenciesSection, type ShellsInput } from "./dependencies.ts";
|
|
21
19
|
import { readSettingsEnv } from "../lib/claude-settings.ts";
|
|
22
20
|
import { resolveBashSpawn, resolvePowerShellSpawn } from "../lib/shell-spawn.ts";
|
|
21
|
+
import { upgradeCommandFor } from "../lib/update-check.mjs";
|
|
22
|
+
import { replacedBuiltinsFix } from "../lib/replaced-builtins.mjs";
|
|
23
|
+
import { keepWindowFix } from "../lib/compaction-keep.mjs";
|
|
24
|
+
import { configCommand } from "./builtins.ts";
|
|
23
25
|
import { shellToolPolicy } from "../powershell/policy.ts";
|
|
24
26
|
import { collectModelFacts, modelsSection } from "./models.ts";
|
|
25
27
|
import { computePresets, presetsSection } from "./presets.ts";
|
|
@@ -35,8 +37,8 @@ import {
|
|
|
35
37
|
type SessionView,
|
|
36
38
|
shortenHome,
|
|
37
39
|
} from "./report.ts";
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
import { MODE_LABELS } from "../lib/config-mode.ts";
|
|
41
|
+
import { BUNDLED_AGENTS_DIR } from "../subagents/agents.ts";
|
|
40
42
|
|
|
41
43
|
/** The environment variables a first-time user is most likely to already have; hinted when nothing is configured. */
|
|
42
44
|
export const COMMON_KEY_ENV_VARS = ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "GEMINI_API_KEY", "OPENROUTER_API_KEY", "OPENCODE_API_KEY"];
|
|
@@ -60,14 +62,21 @@ export function installationSection(env: DoctorEnvironment, findings: Finding[])
|
|
|
60
62
|
lines.push({ text: `Node ${env.nodeVersion} · ${env.platform}-${env.arch}`, level: "dim" });
|
|
61
63
|
lines.push({ text: `pi agent dir: ${shortenHome(env.agentDir, env.home)} (auth, models, sessions, pi settings)`, level: "dim" });
|
|
62
64
|
lines.push({ text: `One Code state: ${shortenHome(env.stateDir, env.home)} (own settings, plans)`, level: "dim" });
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
lines.push({ text: `Config sources: ${MODE_LABELS[env.configMode]} (switch in /memory)`, level: "dim" });
|
|
66
|
+
if (env.configMode === "independent") {
|
|
67
|
+
lines.push({ text: "Claude Code config: not read (~/.claude, .claude/, CLAUDE.md, ~/.claude.json, managed settings)", level: "dim" });
|
|
68
|
+
} else {
|
|
69
|
+
const claudeDir = env.env.CLAUDE_CONFIG_DIR ? `${env.env.CLAUDE_CONFIG_DIR} (CLAUDE_CONFIG_DIR)` : shortenHome(`${env.home}/.claude`, env.home);
|
|
70
|
+
lines.push({ text: `Claude Code config read from: ${claudeDir} (never written)`, level: "dim" });
|
|
71
|
+
}
|
|
65
72
|
|
|
66
73
|
const versionWarning = piVersionWarning(env.piVersion);
|
|
67
74
|
if (versionWarning) {
|
|
68
75
|
lines.push({ text: `pi ${env.piVersion} is outside the tested range ${TESTED_PI_MIN} – <${TESTED_PI_MAX_EXCLUSIVE}`, level: "warn" });
|
|
69
76
|
findings.push({ level: "warn", text: versionWarning, fix: env.install === "app" ? "Upgrade One Code (it pins a tested pi)." : "Update one-code-extension, or pin pi inside the tested range." });
|
|
70
77
|
}
|
|
78
|
+
replacedBuiltinsLines(env, lines, findings);
|
|
79
|
+
compactionKeepLines(env, lines, findings);
|
|
71
80
|
|
|
72
81
|
if (env.latest) {
|
|
73
82
|
switch (env.latest.status) {
|
|
@@ -76,7 +85,7 @@ export function installationSection(env: DoctorEnvironment, findings: Finding[])
|
|
|
76
85
|
break;
|
|
77
86
|
case "behind":
|
|
78
87
|
lines.push({
|
|
79
|
-
text: `Updates: ${env.latest.version} is available (you have ${env.oneCodeVersion}) — ${env.install
|
|
88
|
+
text: `Updates: ${env.latest.version} is available (you have ${env.oneCodeVersion}) — ${upgradeCommandFor(env.install, env.env)}`,
|
|
80
89
|
level: "warn",
|
|
81
90
|
});
|
|
82
91
|
break;
|
|
@@ -90,6 +99,40 @@ export function installationSection(env: DoctorEnvironment, findings: Finding[])
|
|
|
90
99
|
return { title: "Installation", lines };
|
|
91
100
|
}
|
|
92
101
|
|
|
102
|
+
/** pi 0.99's built-in tool search and MCP, which ours replace: off, or still loaded with the fix. */
|
|
103
|
+
function replacedBuiltinsLines(env: DoctorEnvironment, lines: ReportLine[], findings: Finding[]): void {
|
|
104
|
+
const view = env.replacedBuiltins;
|
|
105
|
+
if (!view) return;
|
|
106
|
+
if (view.left.length === 0) {
|
|
107
|
+
lines.push({ text: "pi's built-in tool-search and mcp: off (One Code provides its own)", level: "dim" });
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const names = view.left.map((builtin) => builtin.name).join(" and ");
|
|
111
|
+
lines.push({ text: `pi's built-in ${names}: still on, so pi warns at every start`, level: "warn" });
|
|
112
|
+
findings.push({
|
|
113
|
+
level: "warn",
|
|
114
|
+
text: `pi skips its built-in ${names} because One Code provides its own, and warns about it at every start, advising you to remove One Code. Keep One Code; turning the built-in off silences the warning.`,
|
|
115
|
+
fix: replacedBuiltinsFix(view.left, view.paths, configCommand(env.install)),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** pi's compaction keep window: 0, or above 0 with the fix (lib/compaction-keep.mjs). */
|
|
120
|
+
function compactionKeepLines(env: DoctorEnvironment, lines: ReportLine[], findings: Finding[]): void {
|
|
121
|
+
const view = env.compactionKeep;
|
|
122
|
+
if (!view) return;
|
|
123
|
+
if (view.value === 0) {
|
|
124
|
+
lines.push({ text: "pi's compaction keep window: 0 (One Code keeps the last reply, as Claude Code does)", level: "dim" });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const where = view.source === "default" ? "pi's default" : `set in the ${view.source} settings${view.model ? ` for ${view.model}` : ""}`;
|
|
128
|
+
lines.push({ text: `pi's compaction keep window: ${view.value} tokens (${where}), so /compact refuses shorter sessions`, level: "warn" });
|
|
129
|
+
findings.push({
|
|
130
|
+
level: "warn",
|
|
131
|
+
text: `One Code keeps only the last reply after a compaction, so pi's keep window of ${view.value} tokens only stops /compact on a session shorter than that.`,
|
|
132
|
+
fix: keepWindowFix(shortenHome(view.source === "project" ? view.paths.project : view.paths.user, env.home), view.model),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
93
136
|
export interface ProviderSummary {
|
|
94
137
|
provider: string;
|
|
95
138
|
name: string;
|
|
@@ -178,7 +221,15 @@ export function buildDoctorReport({ env, registry, session }: BuildInput): Docto
|
|
|
178
221
|
const presets = computePresets(registry.available, session.model);
|
|
179
222
|
sections.push(presetsSection(presets, session.model));
|
|
180
223
|
|
|
181
|
-
const compat = collectCompat({
|
|
224
|
+
const compat = collectCompat({
|
|
225
|
+
cwd: env.cwd,
|
|
226
|
+
home: env.home,
|
|
227
|
+
agentDir: env.agentDir,
|
|
228
|
+
env: env.env,
|
|
229
|
+
bundledAgentsDir: BUNDLED_AGENTS_DIR,
|
|
230
|
+
piConfigDirName: env.piConfigDirName,
|
|
231
|
+
registeredMcpServers: env.registeredMcpServers,
|
|
232
|
+
});
|
|
182
233
|
findings.push(...compat.findings);
|
|
183
234
|
sections.push(importedConfigSection(compat, env.home));
|
|
184
235
|
sections.push(mcpSection(compat, session, env.home));
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which of pi's built-in extensions that One Code replaces the running pi
|
|
3
|
+
* still loads, read from pi's own settings (lib/replaced-builtins.mjs has the
|
|
4
|
+
* rule). Shared by the startup notice (branding) and `/doctor`, in the
|
|
5
|
+
* session and from `onecode doctor`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createRequire } from "node:module";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { CONFIG_DIR_NAME, getPackageDir, type SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
11
|
+
import { piHasBuiltinExtensions } from "../lib/pi-version.ts";
|
|
12
|
+
import { type CompactionKeepView, compactionKeepView } from "../lib/compaction-keep.mjs";
|
|
13
|
+
import { BUILTIN_EXTENSIONS_PI, type BuiltinLeftOn, builtinsLeftOn, type GlobMatcher, globMatches } from "../lib/replaced-builtins.mjs";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* pi's own minimatch, the matcher its `!` override entries go through, loaded
|
|
17
|
+
* from pi's install so every glob form (extglobs included) reads as pi reads
|
|
18
|
+
* it. Falls back to the module's port when that copy cannot be loaded (a
|
|
19
|
+
* compiled pi binary, an unusual layout).
|
|
20
|
+
*/
|
|
21
|
+
function piGlobMatcher(): GlobMatcher {
|
|
22
|
+
try {
|
|
23
|
+
const { minimatch } = createRequire(join(getPackageDir(), "package.json"))("minimatch") as { minimatch?: unknown };
|
|
24
|
+
if (typeof minimatch === "function") return (pattern, path) => (minimatch as (path: string, pattern: string) => boolean)(path, pattern);
|
|
25
|
+
} catch {
|
|
26
|
+
// pi's copy is not reachable: use the port.
|
|
27
|
+
}
|
|
28
|
+
return globMatches;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ReplacedBuiltinsView {
|
|
32
|
+
/** The replaced built-ins pi still loads; empty when the settings turn them all off. */
|
|
33
|
+
left: BuiltinLeftOn[];
|
|
34
|
+
/** The settings files a fix edits. */
|
|
35
|
+
paths: { user: string; project: string };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The view for a pi with the built-ins, or undefined on an older pi (nothing
|
|
40
|
+
* to report) or when the settings cannot be read (pi reports that itself).
|
|
41
|
+
*/
|
|
42
|
+
export function replacedBuiltinsView(
|
|
43
|
+
piVersion: string | undefined,
|
|
44
|
+
settings: () => Pick<SettingsManager, "getGlobalSettings" | "getProjectSettings">,
|
|
45
|
+
paths: { agentDir: string; cwd: string },
|
|
46
|
+
): ReplacedBuiltinsView | undefined {
|
|
47
|
+
if (!piHasBuiltinExtensions(piVersion, BUILTIN_EXTENSIONS_PI)) return undefined;
|
|
48
|
+
try {
|
|
49
|
+
const manager = settings();
|
|
50
|
+
return {
|
|
51
|
+
left: builtinsLeftOn(manager.getGlobalSettings().extensions, manager.getProjectSettings().extensions, piGlobMatcher()),
|
|
52
|
+
paths: { user: join(paths.agentDir, "settings.json"), project: join(paths.cwd, CONFIG_DIR_NAME, "settings.json") },
|
|
53
|
+
};
|
|
54
|
+
} catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** pi's compaction keep window and the settings files that set it, or undefined when they cannot be read. */
|
|
60
|
+
export function keepView(
|
|
61
|
+
settings: () => Pick<SettingsManager, "getGlobalSettings" | "getProjectSettings">,
|
|
62
|
+
paths: { agentDir: string; cwd: string },
|
|
63
|
+
modelKey?: string,
|
|
64
|
+
): (CompactionKeepView & { paths: { user: string; project: string } }) | undefined {
|
|
65
|
+
try {
|
|
66
|
+
const manager = settings();
|
|
67
|
+
return {
|
|
68
|
+
...compactionKeepView(manager.getGlobalSettings(), manager.getProjectSettings(), modelKey),
|
|
69
|
+
paths: { user: join(paths.agentDir, "settings.json"), project: join(paths.cwd, CONFIG_DIR_NAME, "settings.json") },
|
|
70
|
+
};
|
|
71
|
+
} catch {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Whether this is the bundled app (its launcher sets `CC_VERSION`) or One Code on the user's own pi. */
|
|
77
|
+
export function installKind(env: NodeJS.ProcessEnv = process.env): "app" | "pi-package" {
|
|
78
|
+
return env.CC_VERSION ? "app" : "pi-package";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** How the user opens pi's config UI: `onecode config` under the bundled app. */
|
|
82
|
+
export function configCommand(install: "app" | "pi-package"): string {
|
|
83
|
+
return install === "app" ? "onecode config" : "pi config";
|
|
84
|
+
}
|
package/extensions/doctor/cli.ts
CHANGED
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { join } from "node:path";
|
|
14
|
-
import { ModelRegistry, ModelRuntime, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
14
|
+
import { CONFIG_DIR_NAME, ModelRegistry, ModelRuntime, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
15
|
+
import { keepView, replacedBuiltinsView } from "./builtins.ts";
|
|
15
16
|
import { oneCodeStateDir } from "../lib/paths.ts";
|
|
16
17
|
import { loadPermissionSettings } from "../permissions/settings.ts";
|
|
17
18
|
import { buildDoctorReport } from "./build.ts";
|
|
18
19
|
import { type DoctorReport, renderDoctorText, type SessionView } from "./report.ts";
|
|
19
20
|
import { lookupLatestVersion } from "./update-lookup.ts";
|
|
21
|
+
import { configMode } from "../lib/config-mode.ts";
|
|
20
22
|
|
|
21
23
|
export interface DoctorCliOptions {
|
|
22
24
|
agentDir: string;
|
|
@@ -68,6 +70,7 @@ export async function collectDoctorCliReport(options: DoctorCliOptions): Promise
|
|
|
68
70
|
home,
|
|
69
71
|
agentDir,
|
|
70
72
|
stateDir: oneCodeStateDir(env, home),
|
|
73
|
+
configMode: configMode(),
|
|
71
74
|
env,
|
|
72
75
|
platform: process.platform,
|
|
73
76
|
arch: process.arch,
|
|
@@ -75,6 +78,9 @@ export async function collectDoctorCliReport(options: DoctorCliOptions): Promise
|
|
|
75
78
|
oneCodeVersion: options.version,
|
|
76
79
|
install: options.install,
|
|
77
80
|
piVersion: options.piVersion,
|
|
81
|
+
replacedBuiltins: replacedBuiltinsView(options.piVersion, () => settings, { agentDir, cwd }),
|
|
82
|
+
compactionKeep: keepView(() => settings, { agentDir, cwd }),
|
|
83
|
+
piConfigDirName: CONFIG_DIR_NAME,
|
|
78
84
|
latest,
|
|
79
85
|
},
|
|
80
86
|
registry: {
|