one-code-extension 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -219
- package/agents/general-purpose.md +2 -2
- package/docs/guide/README.md +2 -1
- package/docs/guide/bring-your-claude-code-setup.md +60 -9
- package/docs/guide/configuration.md +48 -14
- package/docs/guide/differences-from-claude-code.md +32 -23
- package/docs/guide/doctor.md +20 -13
- package/docs/guide/hooks.md +18 -3
- package/docs/guide/installation.md +27 -4
- package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
- package/docs/guide/providers-and-models.md +137 -54
- package/docs/guide/reference.md +27 -15
- package/docs/guide/sessions-and-context.md +69 -16
- package/docs/guide/skills-plugins-and-mcp.md +57 -20
- package/docs/guide/subagents-and-workflows.md +95 -29
- package/docs/guide/tasks-and-background-work.md +101 -26
- package/docs/guide/terminal-interface.md +24 -12
- package/docs/guide/tools.md +46 -5
- package/docs/guide/troubleshooting.md +13 -9
- package/docs/guide/windows.md +66 -34
- package/extensions/artifacts/gallery.ts +227 -0
- package/extensions/artifacts/index.ts +288 -0
- package/extensions/artifacts/store.ts +570 -0
- package/extensions/artifacts/viewer.ts +199 -0
- package/extensions/ask-user/description.ts +67 -0
- package/extensions/ask-user/dialogs.ts +80 -0
- package/extensions/ask-user/index.ts +37 -33
- package/extensions/ask-user/questions.ts +32 -7
- package/extensions/ask-user/widget.ts +45 -25
- package/extensions/auto-mode/actions.ts +6 -0
- package/extensions/auto-mode/cache.ts +88 -0
- package/extensions/auto-mode/classifier-prompt.ts +5 -4
- package/extensions/auto-mode/classifier.ts +290 -65
- package/extensions/auto-mode/config.ts +72 -20
- package/extensions/auto-mode/decision-log.ts +2 -0
- package/extensions/auto-mode/defaults.ts +1 -1
- package/extensions/auto-mode/denials.ts +123 -0
- package/extensions/auto-mode/git-checkout-programs.ts +187 -0
- package/extensions/auto-mode/git-status-meta.ts +159 -0
- package/extensions/auto-mode/history.ts +189 -0
- package/extensions/auto-mode/instructions.ts +58 -52
- package/extensions/auto-mode/model-select.ts +159 -134
- package/extensions/auto-mode/paths.ts +57 -5
- package/extensions/auto-mode/pause.ts +57 -2
- package/extensions/auto-mode/prompt.ts +37 -21
- package/extensions/auto-mode/read-only-options.ts +724 -0
- package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
- package/extensions/auto-mode/rules.ts +18 -1
- package/extensions/auto-mode/safety-floor.ts +361 -18
- package/extensions/auto-mode/setup-run.ts +20 -14
- package/extensions/auto-mode/shell-analysis.ts +764 -490
- package/extensions/auto-mode/shell-parse.ts +885 -0
- package/extensions/auto-mode/system-note.ts +33 -0
- package/extensions/auto-mode/transcript.ts +80 -51
- package/extensions/background/cron.ts +515 -0
- package/extensions/background/index.ts +514 -236
- package/extensions/background/loop-fire.ts +136 -0
- package/extensions/background/loop-preamble.ts +59 -0
- package/extensions/background/loop-skill.ts +163 -0
- package/extensions/background/monitor-batch.ts +53 -0
- package/extensions/background/noop-fold.ts +128 -0
- package/extensions/background/switch-guard.ts +52 -0
- package/extensions/background/wakeup.ts +159 -55
- package/extensions/bash/background.ts +53 -17
- package/extensions/bash/child.ts +7 -0
- package/extensions/bash/description.ts +188 -0
- package/extensions/bash/guards.ts +15 -67
- package/extensions/bash/index.ts +88 -35
- package/extensions/branding/compaction-keep.ts +63 -0
- package/extensions/branding/declined.ts +22 -0
- package/extensions/branding/index.ts +133 -9
- package/extensions/branding/prompt-editor.ts +53 -6
- package/extensions/branding/queued-edit.ts +31 -0
- package/extensions/branding/replaced-builtins.ts +68 -0
- package/extensions/branding/startup.ts +33 -71
- package/extensions/btw/index.ts +229 -71
- package/extensions/btw/panel.ts +228 -100
- package/extensions/btw/prompt.ts +41 -4
- package/extensions/claude-compat/index.ts +7 -11
- package/extensions/claude-context/index.ts +446 -58
- package/extensions/compaction/cut.ts +157 -0
- package/extensions/compaction/index.ts +216 -75
- package/extensions/compaction/kept-thinking.ts +62 -0
- package/extensions/compaction/prompt.ts +15 -12
- package/extensions/context-budget/index.ts +24 -5
- package/extensions/context-management/index.ts +25 -0
- package/extensions/doctor/build.ts +59 -8
- package/extensions/doctor/builtins.ts +84 -0
- package/extensions/doctor/cli.ts +7 -1
- package/extensions/doctor/compat.ts +88 -23
- package/extensions/doctor/dependencies.ts +41 -5
- package/extensions/doctor/fix-prompt.ts +9 -2
- package/extensions/doctor/index.ts +102 -58
- package/extensions/doctor/models.ts +102 -63
- package/extensions/doctor/presets.ts +42 -27
- package/extensions/doctor/report.ts +19 -2
- package/extensions/doctor/viewer.ts +49 -27
- package/extensions/effort/index.ts +72 -19
- package/extensions/effort/settings.ts +21 -0
- package/extensions/effort/slider.ts +24 -20
- package/extensions/exit/index.ts +32 -1
- package/extensions/file-tracker/index.ts +337 -26
- package/extensions/file-tracker/replay.ts +96 -10
- package/extensions/file-tracker/restore.ts +63 -0
- package/extensions/file-tracker/results.ts +66 -0
- package/extensions/file-tracker/shell-reads.ts +211 -0
- package/extensions/file-tracker/tracker.ts +32 -15
- package/extensions/footer/footer-line.ts +45 -24
- package/extensions/footer/index.ts +47 -2
- package/extensions/footer/pr.ts +34 -5
- package/extensions/hooks/compaction.ts +7 -0
- package/extensions/hooks/executor.ts +32 -30
- package/extensions/hooks/index.ts +198 -31
- package/extensions/hooks/matcher.ts +3 -0
- package/extensions/hooks/protocol.ts +41 -3
- package/extensions/hooks/settings.ts +50 -19
- package/extensions/hooks/subagent-bridge.ts +2 -0
- package/extensions/hooks/trust.ts +13 -5
- package/extensions/idle-compact/index.ts +119 -0
- package/extensions/idle-compact/policy.ts +143 -0
- package/extensions/init/index.ts +11 -10
- package/extensions/init/prompt.ts +25 -32
- package/extensions/interrupted/index.ts +13 -1
- package/extensions/kept-thinking/index.ts +27 -0
- package/extensions/lib/agent-cron.ts +130 -0
- package/extensions/lib/agent-loader.ts +15 -1
- package/extensions/lib/agent-view.ts +85 -0
- package/extensions/lib/anthropic-payload.ts +82 -1
- package/extensions/lib/anthropic-server-call.ts +230 -0
- package/extensions/lib/anthropic-server-tools.ts +485 -0
- package/extensions/lib/app-launch.mjs +94 -0
- package/extensions/lib/argument-hints.ts +190 -0
- package/extensions/lib/atomic-write.ts +6 -2
- package/extensions/lib/auto-memory.ts +75 -0
- package/extensions/lib/bash-parser.ts +84 -0
- package/extensions/lib/btw-fork.ts +93 -0
- package/extensions/lib/child-extensions.ts +42 -0
- package/extensions/lib/child-writes.ts +45 -0
- package/extensions/lib/claude-context.ts +515 -100
- package/extensions/lib/claude-external-includes.ts +68 -0
- package/extensions/lib/claude-id.ts +22 -0
- package/extensions/lib/claude-rules.ts +323 -0
- package/extensions/lib/claude-settings.ts +76 -4
- package/extensions/lib/compaction-boundary.ts +36 -0
- package/extensions/lib/compaction-keep.mjs +83 -0
- package/extensions/lib/config-mode.ts +112 -0
- package/extensions/lib/consent-dialogs.ts +63 -0
- package/extensions/lib/consent-preview.ts +5 -1
- package/extensions/lib/consent-stores.ts +48 -0
- package/extensions/lib/context-facts.ts +78 -0
- package/extensions/lib/context-stack.ts +81 -0
- package/extensions/lib/deferred.ts +219 -25
- package/extensions/lib/dock-rows.ts +60 -0
- package/extensions/lib/empty-tool-result.ts +27 -0
- package/extensions/lib/environment-block.ts +76 -0
- package/extensions/lib/fetch-timeout.ts +24 -6
- package/extensions/{system-prompt → lib}/git-status.ts +51 -13
- package/extensions/lib/git.ts +75 -13
- package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
- package/extensions/lib/grammars/README.md +2 -0
- package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
- package/extensions/lib/guide-docs.ts +45 -0
- package/extensions/lib/headless-output.ts +46 -0
- package/extensions/lib/hook-gate.ts +7 -7
- package/extensions/lib/interrupt.ts +20 -4
- package/extensions/lib/key-input.ts +455 -0
- package/extensions/lib/keys.ts +14 -1
- package/extensions/lib/local-command.ts +47 -13
- package/extensions/lib/mcp-overrides.ts +1 -1
- package/extensions/lib/mcp-share.ts +46 -0
- package/extensions/lib/memory-content.ts +146 -0
- package/extensions/lib/memory-index.ts +18 -0
- package/extensions/lib/memory.ts +134 -123
- package/extensions/lib/model-catalog/huggingface.json +174 -0
- package/extensions/lib/model-catalog/models-dev.json +18297 -0
- package/extensions/lib/model-catalog/openrouter.json +5252 -0
- package/extensions/lib/model-catalog-data.ts +513 -0
- package/extensions/lib/model-catalog.ts +462 -0
- package/extensions/lib/model-choice-warnings.ts +137 -0
- package/extensions/lib/model-pairings.ts +152 -0
- package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
- package/extensions/lib/model-policy.ts +112 -15
- package/extensions/lib/model-tier.ts +283 -355
- package/extensions/lib/model-unusable.ts +1 -1
- package/extensions/lib/newer-model.ts +100 -0
- package/extensions/lib/notices.ts +87 -0
- package/extensions/lib/notifications.ts +308 -64
- package/extensions/lib/one-code-settings.ts +74 -8
- package/extensions/lib/open-browser.ts +63 -0
- package/extensions/lib/openrouter-generation.ts +94 -0
- package/extensions/lib/operation-deadline.ts +30 -0
- package/extensions/lib/original-command.ts +4 -4
- package/extensions/lib/package-version.ts +1 -1
- package/extensions/lib/panel-focus.ts +134 -0
- package/extensions/lib/paths.ts +17 -2
- package/extensions/lib/permission-gate.ts +72 -6
- package/extensions/lib/persisted-output.ts +60 -8
- package/extensions/lib/pi-ai-estimate.ts +19 -3
- package/extensions/lib/pi-version.ts +21 -2
- package/extensions/lib/plan-mode-channels.ts +20 -5
- package/extensions/lib/plugins.ts +26 -17
- package/extensions/lib/powershell-parse-script.ts +208 -0
- package/extensions/lib/powershell-parser.ts +344 -0
- package/extensions/lib/process-tree.ts +131 -8
- package/extensions/lib/prompt-options.ts +82 -0
- package/extensions/lib/queued-delivery.ts +44 -0
- package/extensions/lib/reminders.ts +364 -58
- package/extensions/lib/replaced-builtins.mjs +199 -0
- package/extensions/lib/replay-call.ts +70 -0
- package/extensions/lib/request-replay.ts +439 -0
- package/extensions/lib/scratchpad.ts +81 -14
- package/extensions/lib/send-now-channel.ts +7 -0
- package/extensions/lib/session-model-tier.ts +51 -0
- package/extensions/lib/session-work.ts +64 -0
- package/extensions/lib/settings-channels.ts +4 -4
- package/extensions/lib/shell-exit-semantics.ts +170 -0
- package/extensions/lib/shell-quote.ts +11 -0
- package/extensions/lib/shell-result.ts +70 -0
- package/extensions/lib/shell-spawn.ts +70 -6
- package/extensions/lib/shell-tool.ts +75 -25
- package/extensions/lib/side-call-cache.ts +124 -0
- package/extensions/lib/side-call-run.ts +96 -0
- package/extensions/lib/side-call-usage.ts +38 -0
- package/extensions/lib/side-call.ts +13 -1
- package/extensions/lib/single-flight.ts +18 -0
- package/extensions/lib/skill-body.ts +42 -0
- package/extensions/lib/skill-scan.ts +63 -24
- package/extensions/lib/spill-file.ts +140 -0
- package/extensions/lib/subagent-handback.ts +113 -0
- package/extensions/lib/system-role.ts +156 -0
- package/extensions/lib/terminal-text.ts +114 -0
- package/extensions/lib/text-width.ts +47 -16
- package/extensions/lib/timer-ops.ts +20 -0
- package/extensions/lib/tool-additions.ts +149 -0
- package/extensions/lib/tool-call-corruption.ts +134 -0
- package/extensions/lib/tool-path.ts +66 -0
- package/extensions/lib/tool-variants.ts +69 -0
- package/extensions/lib/tui-render.ts +255 -27
- package/extensions/lib/turn-budget-layout.ts +143 -0
- package/extensions/lib/update-check.mjs +15 -2
- package/extensions/lib/usage-bus.ts +1 -1
- package/extensions/lib/user-denial.ts +38 -0
- package/extensions/lib/workspace-channel.ts +16 -0
- package/extensions/lib/worktree-channel.ts +31 -3
- package/extensions/lib/worktree-isolation.ts +40 -10
- package/extensions/lsp/client.ts +8 -9
- package/extensions/lsp/index.ts +70 -4
- package/extensions/lsp/keep-alive.ts +1 -1
- package/extensions/lsp/trust.ts +119 -0
- package/extensions/lsp/watcher.ts +1 -1
- package/extensions/mcp/announce.ts +87 -5
- package/extensions/mcp/client.ts +161 -48
- package/extensions/mcp/config.ts +132 -8
- package/extensions/mcp/discovery.ts +19 -0
- package/extensions/mcp/index.ts +209 -71
- package/extensions/mcp/oauth/browser.ts +38 -17
- package/extensions/mcp/oauth/flow.ts +25 -17
- package/extensions/mcp/oauth/provider.ts +14 -8
- package/extensions/mcp/oauth/store.ts +34 -16
- package/extensions/mcp/panel/keys.ts +12 -11
- package/extensions/mcp/panel/render.ts +9 -6
- package/extensions/mcp/schema.ts +104 -5
- package/extensions/mcp/trust.ts +151 -67
- package/extensions/memory/entries.ts +23 -14
- package/extensions/memory/index.ts +134 -28
- package/extensions/memory/open-external.ts +33 -18
- package/extensions/memory/panel.ts +135 -26
- package/extensions/newer-model/index.ts +31 -0
- package/extensions/notebook/description.ts +18 -0
- package/extensions/notebook/index.ts +6 -5
- package/extensions/notebook/notebook.ts +1 -1
- package/extensions/permissions/index.ts +1300 -381
- package/extensions/permissions/matcher.ts +425 -74
- package/extensions/permissions/modes.ts +6 -4
- package/extensions/permissions/panel/host.ts +130 -0
- package/extensions/permissions/panel/keys.ts +48 -0
- package/extensions/permissions/panel/render.ts +450 -0
- package/extensions/permissions/panel/state.ts +550 -0
- package/extensions/permissions/powershell-cmdlets.ts +198 -0
- package/extensions/permissions/powershell-paths.ts +197 -0
- package/extensions/permissions/powershell-rules.ts +207 -280
- package/extensions/permissions/powershell-tree.ts +557 -0
- package/extensions/permissions/project-trust.ts +27 -11
- package/extensions/permissions/protected-paths.ts +14 -2
- package/extensions/permissions/session-grant.ts +6 -0
- package/extensions/permissions/settings.ts +166 -31
- package/extensions/permissions/subagent-gate.ts +25 -0
- package/extensions/permissions/workspace.ts +78 -0
- package/extensions/plan-mode/index.ts +156 -69
- package/extensions/plan-mode/reminder.ts +89 -21
- package/extensions/plan-mode/texts.ts +177 -0
- package/extensions/plan-mode/viewer.ts +92 -27
- package/extensions/plugins/counts.ts +3 -3
- package/extensions/plugins/index.ts +61 -46
- package/extensions/plugins/install/install.ts +16 -0
- package/extensions/plugins/marketplace/sync.ts +9 -3
- package/extensions/plugins/marketplace/types.ts +3 -1
- package/extensions/plugins/panel/keys.ts +21 -24
- package/extensions/plugins/panel/render.ts +12 -6
- package/extensions/plugins/shell-expand.ts +107 -0
- package/extensions/plugins/template.ts +32 -15
- package/extensions/powershell/child.ts +7 -0
- package/extensions/powershell/description.ts +38 -6
- package/extensions/powershell/guards.ts +1 -1
- package/extensions/powershell/index.ts +12 -7
- package/extensions/recap/index.ts +65 -60
- package/extensions/recap/prompt.ts +2 -2
- package/extensions/recap/scheduler.ts +3 -5
- package/extensions/search-tools/grep-merge.ts +39 -0
- package/extensions/search-tools/index.ts +0 -0
- package/extensions/send-now/chord.ts +62 -0
- package/extensions/send-now/index.ts +133 -0
- package/extensions/session-title/index.ts +3 -0
- package/extensions/session-title/title.ts +4 -1
- package/extensions/skill/code-review.ts +97 -0
- package/extensions/skill/index.ts +421 -101
- package/extensions/skill/invoke.ts +128 -18
- package/extensions/skill/listing.ts +133 -9
- package/extensions/skill/panel/keys.ts +15 -16
- package/extensions/skill/panel/render.ts +5 -2
- package/extensions/skill/panel/state.ts +12 -1
- package/extensions/subagents/agent-args.ts +39 -0
- package/extensions/subagents/agent-description.ts +132 -0
- package/extensions/subagents/agents.ts +116 -23
- package/extensions/subagents/announce.ts +69 -0
- package/extensions/subagents/default-model.ts +2 -3
- package/extensions/subagents/delegation-steer.ts +4 -4
- package/extensions/subagents/fork-cache.ts +76 -0
- package/extensions/subagents/guide-agent.ts +189 -0
- package/extensions/subagents/hand-back-review.ts +3 -0
- package/extensions/subagents/index.ts +1493 -824
- package/extensions/subagents/live-runs.ts +26 -6
- package/extensions/subagents/model-select.ts +38 -25
- package/extensions/subagents/outcome.ts +2 -2
- package/extensions/subagents/panel-keys.ts +73 -31
- package/extensions/subagents/panel-render.ts +120 -96
- package/extensions/subagents/panel-widget.ts +60 -89
- package/extensions/subagents/runner.ts +108 -80
- package/extensions/subagents/runs.ts +39 -5
- package/extensions/subagents/send-to-main-tool.ts +1 -1
- package/extensions/subagents/session-turns.ts +32 -8
- package/extensions/subagents/shell-panel.ts +36 -178
- package/extensions/subagents/tasks-dialog.ts +170 -0
- package/extensions/subagents/viewport-mirror.ts +95 -0
- package/extensions/subagents/worktree.ts +57 -13
- package/extensions/system-prompt/environment.ts +19 -19
- package/extensions/system-prompt/idle-turn.ts +65 -0
- package/extensions/system-prompt/index.ts +131 -47
- package/extensions/system-prompt/template.ts +24 -50
- package/extensions/system-prompt/tiers/common.ts +23 -64
- package/extensions/system-prompt/tiers/frontier.ts +32 -11
- package/extensions/system-prompt/tiers/low.ts +67 -45
- package/extensions/system-prompt/tiers/mid.ts +96 -38
- package/extensions/system-reminder/index.ts +175 -13
- package/extensions/tasks/descriptions.ts +190 -0
- package/extensions/tasks/index.ts +120 -41
- package/extensions/tasks/store.ts +83 -16
- package/extensions/tool-call-corruption/child.ts +7 -0
- package/extensions/tool-call-corruption/index.ts +237 -0
- package/extensions/tool-search/announce.ts +16 -0
- package/extensions/tool-search/index.ts +189 -41
- package/extensions/tool-style/index.ts +68 -10
- package/extensions/tool-style/write-description.ts +40 -0
- package/extensions/tool-style/write-render.ts +237 -0
- package/extensions/turn-duration/index.ts +7 -3
- package/extensions/turn-duration/line.ts +47 -4
- package/extensions/web/backends.ts +6 -9
- package/extensions/web/description.ts +50 -0
- package/extensions/web/index.ts +118 -53
- package/extensions/web/native-call.ts +15 -0
- package/extensions/web/native-results.ts +41 -0
- package/extensions/web-fetch/description.ts +42 -0
- package/extensions/web-fetch/extract.ts +53 -6
- package/extensions/web-fetch/index.ts +125 -76
- package/extensions/web-fetch/page-content.ts +19 -0
- package/extensions/web-fetch/response.ts +49 -0
- package/extensions/web-fetch/summarize.ts +9 -10
- package/extensions/workflow/agent-session.ts +105 -18
- package/extensions/workflow/args.ts +24 -0
- package/extensions/workflow/description.ts +67 -0
- package/extensions/workflow/globals.ts +17 -3
- package/extensions/workflow/index.ts +145 -162
- package/extensions/workflow/records.ts +1 -0
- package/extensions/workflow/run-manager.ts +29 -6
- package/extensions/workflow/saved-workflows.ts +3 -2
- package/extensions/workflow/types.ts +22 -1
- package/extensions/workflow/viewer.ts +54 -24
- package/extensions/workflow/widget.ts +20 -0
- package/extensions/worktree/descriptions.ts +91 -0
- package/extensions/worktree/guards.ts +316 -54
- package/extensions/worktree/index.ts +121 -39
- package/extensions/worktree/powershell-guards.ts +167 -0
- package/extensions/worktree/rewrite.ts +14 -16
- package/package.json +19 -7
- package/skills/artifact-design/SKILL.md +85 -0
- package/skills/code-review/SKILL.md +20 -20
- package/skills/code-review/cells/arguments-and-flags.md +19 -0
- package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
- package/skills/code-review/cells/high-8-inline.md +122 -0
- package/skills/code-review/cells/low-1-pass-max4.md +27 -0
- package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
- package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
- package/skills/code-review/cells/medium-3x5-verify.md +132 -0
- package/skills/code-review/cells/minimal-prompt.md +32 -0
- package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
- package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
- package/skills/fewer-permission-prompts/SKILL.md +1 -1
- package/skills/loop/SKILL.md +11 -0
- package/skills/security-review/SKILL.md +2 -5
- package/skills/simplify/SKILL.md +7 -5
- package/skills/workflow-authoring/SKILL.md +143 -0
- package/themes/onecode-light.json +1 -1
- package/themes/onecode.json +1 -1
- package/types/app.d.ts +58 -0
- package/types/community-packages.d.ts +26 -1
- package/extensions/auto-mode/recoverability.ts +0 -229
- package/extensions/lib/capability-index.ts +0 -466
- package/extensions/lib/model-facts.generated.json +0 -2675
- package/extensions/lib/model-facts.ts +0 -162
package/extensions/btw/index.ts
CHANGED
|
@@ -8,100 +8,181 @@
|
|
|
8
8
|
* focused overlay panel, not in the transcript — so the exchange never enters
|
|
9
9
|
* the main agent's context and cannot steer its work.
|
|
10
10
|
*
|
|
11
|
-
* The call
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
11
|
+
* The call is Claude Code's: the session's last provider request replayed
|
|
12
|
+
* unchanged (system, every tool, every message), the reply that answered it,
|
|
13
|
+
* the session's earlier side exchanges, then the reminder and question, so it
|
|
14
|
+
* reads the cache the session wrote (lib/request-replay.ts; the compaction
|
|
15
|
+
* extension publishes the capture). Without a capture for the session model,
|
|
16
|
+
* or on a provider API the replay does not cover, it falls back to a
|
|
17
|
+
* standalone call: the messages the session last sent (captured from the
|
|
18
|
+
* `context` event), the earlier side exchanges, an empty system prompt,
|
|
19
|
+
* name-only tool stubs so a history carrying tool_use blocks stays valid on
|
|
20
|
+
* strict providers, and withReasoningFallback for models that cannot disable
|
|
21
|
+
* thinking. Both run on the SESSION model: a side question deserves the same
|
|
22
|
+
* quality as the main conversation.
|
|
18
23
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* from an injected side exchange); and the call runs with an empty system prompt
|
|
24
|
-
* (the `context` event carries no system prompt to reuse), relying on the shared
|
|
25
|
-
* history plus the reminder.
|
|
24
|
+
* Like Claude Code, the session keeps a side history: each answered question
|
|
25
|
+
* is threaded into the next one and listed in the panel, where it can be
|
|
26
|
+
* browsed and cleared. `f` forks the current answer into a background fork
|
|
27
|
+
* subagent through the subagents extension (lib/btw-fork.ts).
|
|
26
28
|
*/
|
|
27
29
|
|
|
28
30
|
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
29
31
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
import {
|
|
33
|
+
convertToLlm,
|
|
34
|
+
copyToClipboard,
|
|
35
|
+
type ExtensionAPI,
|
|
36
|
+
type ExtensionCommandContext,
|
|
37
|
+
getAgentDir,
|
|
38
|
+
SettingsManager,
|
|
39
|
+
UserMessageComponent,
|
|
40
|
+
} from "@earendil-works/pi-coding-agent";
|
|
41
|
+
import { ARGUMENT_HINT_CHANNEL, type ArgumentHint } from "../lib/argument-hints.ts";
|
|
42
|
+
import { btwForkedLine, type BtwForkResult, requestBtwFork } from "../lib/btw-fork.ts";
|
|
43
|
+
import { canShowCustomUi, notifyOrPrint, printAnswer } from "../lib/headless-output.ts";
|
|
44
|
+
import { announcePromptOptions } from "../lib/prompt-options.ts";
|
|
45
|
+
import { followLastExchange, replaySideCall } from "../lib/replay-call.ts";
|
|
46
|
+
import { answerText, stripImageBlocks, toolStubs, trimToTurnBoundary, withoutSystemMessages } from "../lib/side-call.ts";
|
|
47
|
+
import { boundedDockHeight, linesComponent, safeThemePaint, truncateLine } from "../lib/tui-render.ts";
|
|
48
|
+
import { CONVERSATION_CACHE_PLACEMENT } from "../lib/side-call-cache.ts";
|
|
49
|
+
import { releaseSideCalls, runSideCall } from "../lib/side-call-run.ts";
|
|
35
50
|
import { recordUsage } from "../lib/usage-bus.ts";
|
|
36
|
-
import
|
|
37
|
-
import {
|
|
51
|
+
import type { ProseRenderer } from "../subagents/panel-render.ts";
|
|
52
|
+
import { createMarkdownProse } from "../subagents/prose.ts";
|
|
53
|
+
import { applyBtwKey, type BtwBody, BTW_MAX_HEIGHT, copyAnswer, decodeBtwKey, initialBtwState, renderBtwPanel } from "./panel.ts";
|
|
54
|
+
import { type BtwExchange, exchangeMessages, historyMessages, sideQuestionMessage } from "./prompt.ts";
|
|
55
|
+
import { panelUi } from "../lib/panel-focus.ts";
|
|
38
56
|
|
|
39
57
|
const BTW_MAX_TOKENS = 8192;
|
|
40
58
|
const BTW_TIMEOUT_MS = 120_000;
|
|
41
59
|
/** Description on the name-only tool stubs sent with the side question. */
|
|
42
60
|
const STUB_REASON = "Unavailable during this side question; answer in text.";
|
|
61
|
+
/**
|
|
62
|
+
* The transcript record of a started fork, Claude Code's `/btw <question>` row
|
|
63
|
+
* with `⎿ ⑂ forked <name> (<id>)` under it. A display-only session entry: it
|
|
64
|
+
* never reaches the model, which learns of the fork from a one-shot reminder.
|
|
65
|
+
*/
|
|
66
|
+
const FORK_ENTRY_TYPE = "one-code:btw-fork";
|
|
67
|
+
|
|
68
|
+
interface BtwForkEntry {
|
|
69
|
+
question: string;
|
|
70
|
+
name: string;
|
|
71
|
+
taskId: string;
|
|
72
|
+
}
|
|
43
73
|
|
|
44
74
|
export default function btwExtension(pi: ExtensionAPI) {
|
|
75
|
+
// The fork entry's `/btw` row is drawn as pi draws a user prompt, with the
|
|
76
|
+
// padding pi read from settings at startup.
|
|
77
|
+
let outputPad = 1;
|
|
78
|
+
try {
|
|
79
|
+
outputPad = SettingsManager.create(process.cwd(), getAgentDir()).getOutputPad();
|
|
80
|
+
} catch {
|
|
81
|
+
// Unreadable settings: pi's default padding.
|
|
82
|
+
}
|
|
83
|
+
pi.registerEntryRenderer<BtwForkEntry>(FORK_ENTRY_TYPE, (entry, _options, theme) => {
|
|
84
|
+
const data = entry.data;
|
|
85
|
+
if (!data) return undefined;
|
|
86
|
+
const row = new UserMessageComponent(`/btw ${data.question}`, undefined, outputPad);
|
|
87
|
+
const paint = safeThemePaint(theme);
|
|
88
|
+
return linesComponent((width) => [...row.render(width), truncateLine(` ⎿ ${paint("dim", btwForkedLine(data.name, data.taskId))}`, width)]);
|
|
89
|
+
});
|
|
90
|
+
|
|
45
91
|
// The exact request messages the session last sent (after every extension's
|
|
46
92
|
// mutations), captured like recap and the compaction extension do.
|
|
47
93
|
let capturedMessages: AgentMessage[] | undefined;
|
|
48
94
|
pi.on("context", (event) => {
|
|
49
95
|
capturedMessages = event.messages;
|
|
50
96
|
});
|
|
97
|
+
// The same request as it went on the wire, and the reply that answered it.
|
|
98
|
+
const exchange = followLastExchange(pi);
|
|
99
|
+
|
|
100
|
+
// The session's answered side questions, oldest first: sent before each new
|
|
101
|
+
// question and listed in the panel. `x` in the panel clears them.
|
|
102
|
+
let history: BtwExchange[] = [];
|
|
51
103
|
|
|
52
104
|
// The controller for an open panel's in-flight call. Aborted when the session
|
|
53
105
|
// is replaced or torn down, so a late resolve cannot repaint a disposed `tui`
|
|
54
106
|
// or record usage on a stale `pi` (the crash the subagents panel once hit —
|
|
55
|
-
// docs/decisions/tools.md lifecycle review).
|
|
107
|
+
// working-docs/decisions/tools.md lifecycle review).
|
|
56
108
|
let inFlight: AbortController | undefined;
|
|
109
|
+
// Bumped when the session is replaced or torn down, so a fork request that
|
|
110
|
+
// settles afterwards touches neither the closed panel nor a stale ctx.
|
|
111
|
+
let sessionEpoch = 0;
|
|
57
112
|
|
|
58
|
-
// A new session (including after /clear) shares no context with the old one
|
|
59
|
-
// and any in-flight side question is abandoned.
|
|
113
|
+
// A new session (including after /clear) shares no context with the old one:
|
|
114
|
+
// its side history starts empty and any in-flight side question is abandoned.
|
|
60
115
|
pi.on("session_start", () => {
|
|
116
|
+
sessionEpoch++;
|
|
117
|
+
// Claude Code's `[question]` placeholder after a bare `/btw` in the prompt.
|
|
118
|
+
pi.events.emit(ARGUMENT_HINT_CHANNEL, { command: "btw", hint: "[question]" } satisfies ArgumentHint);
|
|
61
119
|
capturedMessages = undefined;
|
|
120
|
+
history = [];
|
|
62
121
|
inFlight?.abort();
|
|
63
122
|
inFlight = undefined;
|
|
64
123
|
});
|
|
65
|
-
pi.on("session_shutdown", () => {
|
|
124
|
+
pi.on("session_shutdown", (_event, ctx) => {
|
|
125
|
+
sessionEpoch++;
|
|
66
126
|
inFlight?.abort();
|
|
67
127
|
inFlight = undefined;
|
|
128
|
+
releaseSideCalls(ctx.sessionManager.getSessionId());
|
|
68
129
|
});
|
|
69
130
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
131
|
+
// The answer renders as Markdown, like the transcript; plain wrapped text
|
|
132
|
+
// until the renderer loads, or if it cannot.
|
|
133
|
+
let prose: ProseRenderer | undefined;
|
|
134
|
+
let proseLoad: Promise<void> | undefined;
|
|
135
|
+
const loadProse = (): Promise<void> =>
|
|
136
|
+
(proseLoad ??= createMarkdownProse().then(
|
|
137
|
+
(renderer) => {
|
|
138
|
+
prose = renderer;
|
|
139
|
+
},
|
|
140
|
+
() => {},
|
|
141
|
+
));
|
|
142
|
+
|
|
143
|
+
/** Run the side question against the session model, after the earlier exchanges; returns the answer text. */
|
|
144
|
+
async function ask(ctx: ExtensionCommandContext, question: string, earlier: readonly BtwExchange[], signal: AbortSignal): Promise<string> {
|
|
145
|
+
const model = ctx.model as Model<Api> | undefined;
|
|
73
146
|
if (!model) throw new Error("No model is configured for this session.");
|
|
147
|
+
const before = historyMessages(earlier, model);
|
|
148
|
+
const replayed = await replaySideCall(ctx, model, exchange, sideQuestionMessage(question), {
|
|
149
|
+
signal,
|
|
150
|
+
timeoutMs: BTW_TIMEOUT_MS,
|
|
151
|
+
onUsage: (usage) => recordUsage(pi, "btw", usage),
|
|
152
|
+
history: before,
|
|
153
|
+
});
|
|
154
|
+
if (replayed !== undefined) return replayed;
|
|
155
|
+
|
|
156
|
+
// No replay for this model, or it failed: the standalone call.
|
|
74
157
|
const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
|
|
75
158
|
if (!auth.ok) throw new Error("No API key is available for the current model.");
|
|
76
|
-
const baseUrl = (auth as { baseUrl?: string }).baseUrl;
|
|
77
|
-
|
|
78
159
|
const tools = toolStubs(pi.getActiveTools(), STUB_REASON);
|
|
79
|
-
const context = trimToTurnBoundary(capturedMessages ?? []);
|
|
160
|
+
const context = trimToTurnBoundary(withoutSystemMessages(capturedMessages ?? []));
|
|
80
161
|
// btw runs on a cheap, possibly text-only reader and answers a text question,
|
|
81
162
|
// so images the conversation carried are stripped before the call
|
|
82
|
-
// (docs/decisions/model-policy.md).
|
|
83
|
-
const messages = [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
);
|
|
163
|
+
// (working-docs/decisions/model-policy.md).
|
|
164
|
+
const messages = [
|
|
165
|
+
...stripImageBlocks(convertToLlm(context)),
|
|
166
|
+
...before,
|
|
167
|
+
{ role: "user" as const, content: sideQuestionMessage(question), timestamp: Date.now() },
|
|
168
|
+
];
|
|
169
|
+
const result = await runSideCall({
|
|
170
|
+
kind: "btw",
|
|
171
|
+
model,
|
|
172
|
+
auth,
|
|
173
|
+
sessionId: ctx.sessionManager.getSessionId(),
|
|
174
|
+
context: { systemPrompt: "", messages, tools },
|
|
175
|
+
signal,
|
|
176
|
+
timeoutMs: BTW_TIMEOUT_MS,
|
|
177
|
+
maxTokens: BTW_MAX_TOKENS,
|
|
178
|
+
cache: CONVERSATION_CACHE_PLACEMENT,
|
|
179
|
+
onUsage: (usage) => recordUsage(pi, "btw", usage),
|
|
180
|
+
});
|
|
181
|
+
// completeSimple reports a failure (a network error, a timeout) in the
|
|
182
|
+
// reply instead of throwing; its empty text is not an answer.
|
|
183
|
+
if (signal.aborted) return "";
|
|
184
|
+
if (result.stopReason === "aborted") throw new Error(`No answer within ${BTW_TIMEOUT_MS / 1000} seconds.`);
|
|
185
|
+
if (result.stopReason === "error") throw new Error(result.errorMessage || "The model returned an error.");
|
|
105
186
|
return answerText(result.content);
|
|
106
187
|
}
|
|
107
188
|
|
|
@@ -113,15 +194,27 @@ export default function btwExtension(pi: ExtensionAPI) {
|
|
|
113
194
|
ctx.ui.notify("Ask a side question: /btw <question>", "info");
|
|
114
195
|
return;
|
|
115
196
|
}
|
|
197
|
+
// The panel can fork a background agent whose completion opens the
|
|
198
|
+
// session's first turn; this context carries the options that turn
|
|
199
|
+
// is built from (lib/prompt-options.ts).
|
|
200
|
+
announcePromptOptions(pi.events, ctx);
|
|
116
201
|
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
if (!ctx
|
|
202
|
+
// RPC has dialogs but no custom panel. Deliver its answer as a notice,
|
|
203
|
+
// never a main-conversation message; one-shot runs print it instead.
|
|
204
|
+
if (!canShowCustomUi(ctx)) {
|
|
205
|
+
inFlight?.abort();
|
|
206
|
+
const controller = new AbortController();
|
|
207
|
+
inFlight = controller;
|
|
120
208
|
try {
|
|
121
|
-
const answer = await ask(ctx, question,
|
|
122
|
-
|
|
209
|
+
const answer = await ask(ctx, question, history, controller.signal);
|
|
210
|
+
if (controller.signal.aborted) return;
|
|
211
|
+
if (answer) history.push({ question, answer });
|
|
212
|
+
if (ctx.mode === "rpc") ctx.ui.notify(answer || "(no answer)", "info");
|
|
213
|
+
else printAnswer(ctx, answer || "(no answer)");
|
|
123
214
|
} catch (error) {
|
|
124
|
-
|
|
215
|
+
if (!controller.signal.aborted) notifyOrPrint(ctx, `Side question failed: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
216
|
+
} finally {
|
|
217
|
+
if (inFlight === controller) inFlight = undefined;
|
|
125
218
|
}
|
|
126
219
|
return;
|
|
127
220
|
}
|
|
@@ -132,11 +225,22 @@ export default function btwExtension(pi: ExtensionAPI) {
|
|
|
132
225
|
inFlight?.abort();
|
|
133
226
|
const controller = new AbortController();
|
|
134
227
|
inFlight = controller;
|
|
135
|
-
|
|
228
|
+
// The earlier exchanges this panel lists and browses; the current one
|
|
229
|
+
// joins `history` when it lands, so the next /btw lists it.
|
|
230
|
+
let earlier = [...history];
|
|
231
|
+
const view: { answer?: string; error?: string; forking?: boolean } = {};
|
|
136
232
|
const bodyState = (): BtwBody =>
|
|
137
233
|
view.error !== undefined ? { kind: "error", message: view.error } : view.answer !== undefined ? { kind: "answer", text: view.answer } : { kind: "loading" };
|
|
234
|
+
// Reported after the panel closes: a started fork joins the transcript as
|
|
235
|
+
// Claude Code's `⑂ forked` entry; a failure is an error notice.
|
|
236
|
+
let forkResult: BtwForkResult | undefined;
|
|
237
|
+
const reportFork = (result: BtwForkResult) => {
|
|
238
|
+
if ("error" in result) ctx.ui.notify(result.error, "error");
|
|
239
|
+
else pi.appendEntry<BtwForkEntry>(FORK_ENTRY_TYPE, { question, name: result.name, taskId: result.taskId });
|
|
240
|
+
};
|
|
241
|
+
let panelOpen = true;
|
|
138
242
|
|
|
139
|
-
await ctx.ui.custom<null>((tui, theme, _keybindings, done) => {
|
|
243
|
+
await panelUi(pi.events, ctx.ui).custom<null>((tui, theme, _keybindings, done) => {
|
|
140
244
|
const state = initialBtwState();
|
|
141
245
|
let cache: { width: number; lines: string[] } | undefined;
|
|
142
246
|
const repaint = () => {
|
|
@@ -147,13 +251,15 @@ export default function btwExtension(pi: ExtensionAPI) {
|
|
|
147
251
|
tui.requestRender();
|
|
148
252
|
} catch {}
|
|
149
253
|
};
|
|
254
|
+
if (!prose) void loadProse().then(() => prose && repaint());
|
|
150
255
|
|
|
151
256
|
// Kick off the model call once, at mount, so `repaint` is bound.
|
|
152
257
|
void (async () => {
|
|
153
258
|
try {
|
|
154
|
-
const answer = await ask(ctx, question, controller.signal);
|
|
259
|
+
const answer = await ask(ctx, question, earlier, controller.signal);
|
|
155
260
|
if (controller.signal.aborted) return;
|
|
156
261
|
view.answer = answer;
|
|
262
|
+
if (answer) history.push({ question, answer });
|
|
157
263
|
} catch (error) {
|
|
158
264
|
if (controller.signal.aborted) return;
|
|
159
265
|
view.error = error instanceof Error ? error.message : String(error);
|
|
@@ -161,6 +267,30 @@ export default function btwExtension(pi: ExtensionAPI) {
|
|
|
161
267
|
repaint();
|
|
162
268
|
})();
|
|
163
269
|
|
|
270
|
+
const fork = (answer: string) => {
|
|
271
|
+
const model = ctx.model as Model<Api> | undefined;
|
|
272
|
+
if (!model) return;
|
|
273
|
+
view.forking = true;
|
|
274
|
+
repaint();
|
|
275
|
+
const epoch = sessionEpoch;
|
|
276
|
+
// The fork sees what the answer was written from: the earlier exchanges
|
|
277
|
+
// still listed (none once cleared), then this one.
|
|
278
|
+
const messages = [...historyMessages(earlier, model), ...exchangeMessages({ question, answer }, model)];
|
|
279
|
+
void requestBtwFork(pi.events, { ctx, question, messages }).then((result) => {
|
|
280
|
+
if (epoch !== sessionEpoch) return;
|
|
281
|
+
if (panelOpen) {
|
|
282
|
+
view.forking = false;
|
|
283
|
+
forkResult = result;
|
|
284
|
+
done(null);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
// The user closed the panel while the fork was starting.
|
|
288
|
+
try {
|
|
289
|
+
reportFork(result);
|
|
290
|
+
} catch {}
|
|
291
|
+
});
|
|
292
|
+
};
|
|
293
|
+
|
|
164
294
|
return {
|
|
165
295
|
render: (width: number) => {
|
|
166
296
|
if (cache?.width === width) return cache.lines;
|
|
@@ -169,26 +299,52 @@ export default function btwExtension(pi: ExtensionAPI) {
|
|
|
169
299
|
// Belt-and-suspenders truncate on top of renderBtwPanel's own,
|
|
170
300
|
// matching every sibling dock panel: pi-tui crashes the app on
|
|
171
301
|
// a line wider than the terminal.
|
|
172
|
-
const lines = renderBtwPanel(
|
|
302
|
+
const lines = renderBtwPanel(
|
|
303
|
+
{
|
|
304
|
+
state,
|
|
305
|
+
history: earlier,
|
|
306
|
+
question,
|
|
307
|
+
body: bodyState(),
|
|
308
|
+
width,
|
|
309
|
+
height,
|
|
310
|
+
canFork: true,
|
|
311
|
+
forking: view.forking,
|
|
312
|
+
renderAnswer: prose ? (text, width, ref) => prose!(ref, text, width) : undefined,
|
|
313
|
+
},
|
|
314
|
+
theme,
|
|
315
|
+
).map((line) => truncateLine(line, width));
|
|
173
316
|
cache = { width, lines };
|
|
174
317
|
return lines;
|
|
175
318
|
},
|
|
176
319
|
handleInput: (data: string) => {
|
|
177
320
|
const key = decodeBtwKey(data);
|
|
178
321
|
if (!key) return;
|
|
179
|
-
|
|
322
|
+
// While a fork starts only closing works; its notice follows.
|
|
323
|
+
if (view.forking) {
|
|
324
|
+
if (key.kind === "close") done(null);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const effect = applyBtwKey(state, key, earlier.length);
|
|
328
|
+
const shown = state.selected === null ? view.answer : earlier[state.selected]?.answer;
|
|
180
329
|
switch (effect?.kind) {
|
|
181
330
|
case "close":
|
|
182
331
|
done(null);
|
|
183
332
|
return;
|
|
184
333
|
case "copy":
|
|
185
334
|
// Only offer copy once there is a non-empty answer.
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
335
|
+
if (shown) void copyAnswer(copyToClipboard, shown, state, repaint);
|
|
336
|
+
return;
|
|
337
|
+
case "fork":
|
|
338
|
+
// The current answer only, not one browsed from the history.
|
|
339
|
+
if (state.selected === null && view.answer) fork(view.answer);
|
|
340
|
+
return;
|
|
341
|
+
case "clear":
|
|
342
|
+
if (earlier.length === 0) return;
|
|
343
|
+
history = history.filter((entry) => !earlier.includes(entry));
|
|
344
|
+
earlier = [];
|
|
345
|
+
state.selected = null;
|
|
346
|
+
state.offset = 0;
|
|
347
|
+
repaint();
|
|
192
348
|
return;
|
|
193
349
|
default:
|
|
194
350
|
repaint();
|
|
@@ -200,8 +356,10 @@ export default function btwExtension(pi: ExtensionAPI) {
|
|
|
200
356
|
};
|
|
201
357
|
});
|
|
202
358
|
|
|
359
|
+
panelOpen = false;
|
|
203
360
|
controller.abort();
|
|
204
361
|
if (inFlight === controller) inFlight = undefined;
|
|
362
|
+
if (forkResult) reportFork(forkResult);
|
|
205
363
|
},
|
|
206
364
|
});
|
|
207
365
|
}
|