one-code-extension 0.4.1 → 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 +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 +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 +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 +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 +18 -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/panel.ts
CHANGED
|
@@ -1,86 +1,110 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pure state, key decoding, and rendering for the `/btw`
|
|
3
|
-
* Code's
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Pure state, key decoding, and rendering for the `/btw` panel, laid out as
|
|
3
|
+
* Claude Code's: the session's earlier side questions (the last five, with a
|
|
4
|
+
* count of older ones), the current question marked `/btw`, the answer
|
|
5
|
+
* indented under them, and a hint line naming only the keys that apply.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Shift+←/→, `[`/`]` and Tab/Shift+Tab browse the earlier answers, ↑/↓ scroll
|
|
8
|
+
* (PgUp/PgDn and Home/End too), `c` copies the answer on screen, `f` forks the
|
|
9
|
+
* current answer into a background subagent, `x` clears the history, and Esc,
|
|
10
|
+
* Enter, Space or `q` close.
|
|
11
|
+
*
|
|
12
|
+
* Kept free of pi imports so the browse and scroll maths and the layout are
|
|
13
|
+
* unit-tested; the extension owns the overlay, the model call, the clipboard
|
|
14
|
+
* write and the fork request.
|
|
11
15
|
*/
|
|
12
16
|
|
|
13
|
-
import {
|
|
17
|
+
import type { BtwExchange } from "./prompt.ts";
|
|
18
|
+
import { keyId, keyText } from "../lib/key-input.ts";
|
|
19
|
+
import { panelTopRule, safeThemeBold, safeThemePaint, truncateLine, wrapPlainText } from "../lib/tui-render.ts";
|
|
14
20
|
|
|
15
21
|
export const BTW_MAX_HEIGHT = 24;
|
|
16
22
|
|
|
17
|
-
/**
|
|
18
|
-
export const
|
|
23
|
+
/** Earlier questions listed (and browsable) above the current one. */
|
|
24
|
+
export const SHOWN_HISTORY = 5;
|
|
19
25
|
|
|
20
|
-
/**
|
|
21
|
-
|
|
26
|
+
/** Lines one ↑/↓ press scrolls. */
|
|
27
|
+
const SCROLL_STEP = 3;
|
|
22
28
|
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
* appearance (loading, error, answer) is rendered — and tested — here rather
|
|
26
|
-
* than assembled by the extension wiring.
|
|
27
|
-
*/
|
|
28
|
-
export type BtwBody = { kind: "loading" } | { kind: "error"; message: string } | { kind: "answer"; text: string };
|
|
29
|
+
/** Columns the answer is indented by, under the question list. */
|
|
30
|
+
const ANSWER_INDENT = 4;
|
|
29
31
|
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
case "error":
|
|
36
|
-
return `Side question failed: ${body.message}`;
|
|
37
|
-
case "answer":
|
|
38
|
-
return body.text || "(no answer)";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
32
|
+
/** Columns the question list is indented by. */
|
|
33
|
+
const LIST_INDENT = 2;
|
|
34
|
+
|
|
35
|
+
/** The current question's body: its answer, a failure, or still waiting. */
|
|
36
|
+
export type BtwBody = { kind: "loading" } | { kind: "error"; message: string } | { kind: "answer"; text: string };
|
|
41
37
|
|
|
42
38
|
export interface BtwPanelState {
|
|
43
|
-
/** First
|
|
39
|
+
/** First answer line shown (0 = top). */
|
|
44
40
|
offset: number;
|
|
45
41
|
/** Largest valid offset for the current viewport; render keeps it current. */
|
|
46
42
|
maxOffset: number;
|
|
47
|
-
/** Visible
|
|
43
|
+
/** Visible answer lines in the current viewport; render keeps it current. */
|
|
48
44
|
viewport: number;
|
|
49
|
-
/** Set for one frame after a copy so the
|
|
45
|
+
/** Set for one frame after a copy so the hint can confirm it. */
|
|
50
46
|
copied: boolean;
|
|
47
|
+
/** Why the last copy failed (no clipboard route), shown in the hint until the next key. */
|
|
48
|
+
copyError?: string;
|
|
49
|
+
/** The earlier exchange on screen (an index into the history), or null for the current question. */
|
|
50
|
+
selected: number | null;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export function initialBtwState(): BtwPanelState {
|
|
54
|
-
return { offset: 0, maxOffset: 0, viewport: 1, copied: false };
|
|
54
|
+
return { offset: 0, maxOffset: 0, viewport: 1, copied: false, selected: null };
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
export type BtwKey =
|
|
57
|
+
export type BtwKey =
|
|
58
|
+
| { kind: "up" | "down" | "pageUp" | "pageDown" | "top" | "bottom" | "copy" | "fork" | "clear" | "close" }
|
|
59
|
+
| { kind: "browse"; direction: "older" | "newer"; wrap: boolean };
|
|
58
60
|
|
|
59
61
|
export function decodeBtwKey(data: string): BtwKey | undefined {
|
|
60
|
-
switch (data) {
|
|
61
|
-
case "
|
|
62
|
-
case "
|
|
63
|
-
case "\x10": // ctrl+p
|
|
62
|
+
switch (keyId(data)) {
|
|
63
|
+
case "up":
|
|
64
|
+
case "ctrl+p":
|
|
64
65
|
return { kind: "up" };
|
|
65
|
-
case "
|
|
66
|
-
case "
|
|
67
|
-
case "\x0e": // ctrl+n
|
|
66
|
+
case "down":
|
|
67
|
+
case "ctrl+n":
|
|
68
68
|
return { kind: "down" };
|
|
69
|
-
case "
|
|
69
|
+
case "pageUp":
|
|
70
70
|
return { kind: "pageUp" };
|
|
71
|
-
case "
|
|
71
|
+
case "pageDown":
|
|
72
72
|
return { kind: "pageDown" };
|
|
73
|
-
case "
|
|
74
|
-
case "\x1bOH":
|
|
73
|
+
case "home":
|
|
75
74
|
return { kind: "top" };
|
|
76
|
-
case "
|
|
77
|
-
case "\x1bOF":
|
|
75
|
+
case "end":
|
|
78
76
|
return { kind: "bottom" };
|
|
77
|
+
case "shift+left":
|
|
78
|
+
return { kind: "browse", direction: "older", wrap: false };
|
|
79
|
+
case "shift+right":
|
|
80
|
+
return { kind: "browse", direction: "newer", wrap: false };
|
|
81
|
+
case "tab":
|
|
82
|
+
return { kind: "browse", direction: "older", wrap: true };
|
|
83
|
+
case "shift+tab":
|
|
84
|
+
return { kind: "browse", direction: "newer", wrap: true };
|
|
85
|
+
case "escape":
|
|
86
|
+
case "ctrl+c":
|
|
87
|
+
case "ctrl+d":
|
|
88
|
+
case "enter":
|
|
89
|
+
case "space":
|
|
90
|
+
return { kind: "close" };
|
|
91
|
+
default:
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
switch (keyText(data)) {
|
|
95
|
+
case "[":
|
|
96
|
+
return { kind: "browse", direction: "older", wrap: false };
|
|
97
|
+
case "]":
|
|
98
|
+
return { kind: "browse", direction: "newer", wrap: false };
|
|
79
99
|
case "c":
|
|
80
100
|
case "C":
|
|
81
101
|
return { kind: "copy" };
|
|
82
|
-
case "
|
|
83
|
-
case "
|
|
102
|
+
case "f":
|
|
103
|
+
case "F":
|
|
104
|
+
return { kind: "fork" };
|
|
105
|
+
case "x":
|
|
106
|
+
case "X":
|
|
107
|
+
return { kind: "clear" };
|
|
84
108
|
case "q":
|
|
85
109
|
return { kind: "close" };
|
|
86
110
|
default:
|
|
@@ -88,7 +112,7 @@ export function decodeBtwKey(data: string): BtwKey | undefined {
|
|
|
88
112
|
}
|
|
89
113
|
}
|
|
90
114
|
|
|
91
|
-
export type BtwEffect = { kind: "copy" } | { kind: "close" };
|
|
115
|
+
export type BtwEffect = { kind: "copy" } | { kind: "fork" } | { kind: "clear" } | { kind: "close" };
|
|
92
116
|
|
|
93
117
|
/** Page size for PgUp/PgDn: nearly a full viewport, one line of overlap for orientation. */
|
|
94
118
|
function pageStep(viewport: number): number {
|
|
@@ -96,26 +120,68 @@ function pageStep(viewport: number): number {
|
|
|
96
120
|
}
|
|
97
121
|
|
|
98
122
|
/**
|
|
99
|
-
*
|
|
100
|
-
* (
|
|
101
|
-
* `
|
|
102
|
-
* render from the real viewport.
|
|
123
|
+
* Move the selection one step through the current question and the last
|
|
124
|
+
* SHOWN_HISTORY earlier ones (Claude Code's order: older goes up the list).
|
|
125
|
+
* Without `wrap` it stops at either end; with it, it cycles.
|
|
103
126
|
*/
|
|
104
|
-
|
|
127
|
+
function browse(state: BtwPanelState, historyLength: number, direction: "older" | "newer", wrap: boolean): void {
|
|
128
|
+
const reachable = Math.min(historyLength, SHOWN_HISTORY);
|
|
129
|
+
const distance = state.selected === null ? 0 : historyLength - state.selected;
|
|
130
|
+
const step = direction === "older" ? 1 : -1;
|
|
131
|
+
const next = wrap ? (distance + step + reachable + 1) % (reachable + 1) : Math.min(Math.max(distance + step, 0), reachable);
|
|
132
|
+
if (next === distance) return;
|
|
133
|
+
state.selected = next === 0 ? null : historyLength - next;
|
|
134
|
+
state.offset = 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Copy an answer and report the outcome in the hint line. pi's
|
|
139
|
+
* `copyToClipboard` rejects when no clipboard route works (Wayland without
|
|
140
|
+
* `wl-copy`, X11 without `xclip`); unhandled, that rejection ends the process,
|
|
141
|
+
* so the reason is shown in place of the confirmation instead.
|
|
142
|
+
*/
|
|
143
|
+
export function copyAnswer(copy: (text: string) => Promise<void>, text: string, state: BtwPanelState, repaint: () => void): Promise<void> {
|
|
144
|
+
let pending: Promise<void>;
|
|
145
|
+
try {
|
|
146
|
+
pending = Promise.resolve(copy(text));
|
|
147
|
+
} catch (error) {
|
|
148
|
+
pending = Promise.reject(error);
|
|
149
|
+
}
|
|
150
|
+
return pending.then(
|
|
151
|
+
() => {
|
|
152
|
+
state.copied = true;
|
|
153
|
+
state.copyError = undefined;
|
|
154
|
+
repaint();
|
|
155
|
+
},
|
|
156
|
+
(error: unknown) => {
|
|
157
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
158
|
+
state.copied = false;
|
|
159
|
+
state.copyError = `Copy failed: ${reason.split("\n")[0]}`;
|
|
160
|
+
repaint();
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Apply a key. Returns an effect for the extension to run (copy, fork, clear,
|
|
167
|
+
* close) or undefined for a scroll or browse (repaint only). Offsets clamp to
|
|
168
|
+
* `state.maxOffset` and page by `state.viewport`, both set by the last render.
|
|
169
|
+
*/
|
|
170
|
+
export function applyBtwKey(state: BtwPanelState, key: BtwKey, historyLength: number): BtwEffect | undefined {
|
|
105
171
|
state.copied = false;
|
|
106
|
-
|
|
172
|
+
state.copyError = undefined;
|
|
107
173
|
switch (key.kind) {
|
|
108
174
|
case "up":
|
|
109
|
-
state.offset = Math.max(0, state.offset -
|
|
175
|
+
state.offset = Math.max(0, state.offset - SCROLL_STEP);
|
|
110
176
|
return undefined;
|
|
111
177
|
case "down":
|
|
112
|
-
state.offset = Math.min(state.maxOffset, state.offset +
|
|
178
|
+
state.offset = Math.min(state.maxOffset, state.offset + SCROLL_STEP);
|
|
113
179
|
return undefined;
|
|
114
180
|
case "pageUp":
|
|
115
|
-
state.offset = Math.max(0, state.offset -
|
|
181
|
+
state.offset = Math.max(0, state.offset - pageStep(state.viewport));
|
|
116
182
|
return undefined;
|
|
117
183
|
case "pageDown":
|
|
118
|
-
state.offset = Math.min(state.maxOffset, state.offset +
|
|
184
|
+
state.offset = Math.min(state.maxOffset, state.offset + pageStep(state.viewport));
|
|
119
185
|
return undefined;
|
|
120
186
|
case "top":
|
|
121
187
|
state.offset = 0;
|
|
@@ -123,57 +189,119 @@ export function applyBtwKey(state: BtwPanelState, key: BtwKey): BtwEffect | unde
|
|
|
123
189
|
case "bottom":
|
|
124
190
|
state.offset = state.maxOffset;
|
|
125
191
|
return undefined;
|
|
192
|
+
case "browse":
|
|
193
|
+
browse(state, historyLength, key.direction, key.wrap);
|
|
194
|
+
return undefined;
|
|
126
195
|
case "copy":
|
|
127
|
-
|
|
196
|
+
case "fork":
|
|
197
|
+
case "clear":
|
|
128
198
|
case "close":
|
|
129
|
-
return { kind:
|
|
199
|
+
return { kind: key.kind };
|
|
130
200
|
}
|
|
131
201
|
}
|
|
132
202
|
|
|
133
203
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* `state.offset`/`state.maxOffset` so key handling scrolls against the real
|
|
138
|
-
* body length. Every line is width-truncated (pi-tui crashes on an overwide
|
|
139
|
-
* line).
|
|
204
|
+
* Renders an answer to lines at a width: plain wrapping by default, Markdown in
|
|
205
|
+
* the extension. `ref` is stable for one answer (its exchange, or the panel
|
|
206
|
+
* state for the current one), so a renderer can cache by it.
|
|
140
207
|
*/
|
|
141
|
-
export
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
208
|
+
export type AnswerRenderer = (text: string, width: number, ref: object) => string[];
|
|
209
|
+
|
|
210
|
+
export interface BtwPanelInput {
|
|
211
|
+
state: BtwPanelState;
|
|
212
|
+
/** The session's earlier exchanges, oldest first. */
|
|
213
|
+
history: readonly BtwExchange[];
|
|
214
|
+
question: string;
|
|
215
|
+
body: BtwBody;
|
|
216
|
+
width: number;
|
|
217
|
+
height: number;
|
|
218
|
+
/** The current answer can be forked (the extension knows whether a fork can start). */
|
|
219
|
+
canFork?: boolean;
|
|
220
|
+
/** A fork request is in flight. */
|
|
221
|
+
forking?: boolean;
|
|
222
|
+
renderAnswer?: AnswerRenderer;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** One question on one line, whitespace collapsed, cut to fit (Claude Code's list row). */
|
|
226
|
+
function questionLine(question: string, width: number): string {
|
|
227
|
+
return truncateLine(question.replace(/\s+/g, " ").trim(), Math.max(20, width - 7));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Render the panel to at most `height` lines. The answer scrolls within what
|
|
232
|
+
* the question list and hint leave; `state.offset`, `maxOffset` and `viewport`
|
|
233
|
+
* are written back so key handling scrolls against the real answer length.
|
|
234
|
+
* Every line is width-truncated (pi-tui crashes on an overwide line).
|
|
235
|
+
*/
|
|
236
|
+
export function renderBtwPanel(input: BtwPanelInput, theme?: unknown): string[] {
|
|
237
|
+
const { state, history, question, body, width, height } = input;
|
|
146
238
|
const paint = safeThemePaint(theme);
|
|
239
|
+
const bold = safeThemeBold(theme);
|
|
147
240
|
const inner = Math.max(1, width);
|
|
241
|
+
const pad = " ".repeat(LIST_INDENT);
|
|
242
|
+
if (state.selected !== null && (state.selected < 0 || state.selected >= history.length)) state.selected = null;
|
|
243
|
+
const selected = state.selected === null ? undefined : history[state.selected];
|
|
148
244
|
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
245
|
+
// On a short dock, list fewer earlier questions rather than overflow it: the
|
|
246
|
+
// rule, blanks, current question, one answer row and the hint always fit.
|
|
247
|
+
// A browsed question the trimmed list leaves out takes the list's first row
|
|
248
|
+
// (the count's, if that is the only one), so its answer never shows alone.
|
|
249
|
+
const listRows = Math.max(0, height - 7);
|
|
250
|
+
let shownCount = Math.min(SHOWN_HISTORY, history.length);
|
|
251
|
+
while (shownCount > 0 && shownCount + (history.length > shownCount ? 1 : 0) > listRows) shownCount--;
|
|
252
|
+
let start = history.length - shownCount;
|
|
253
|
+
if (state.selected !== null && state.selected < start) {
|
|
254
|
+
if (shownCount === 0 && listRows > 0) shownCount = 1;
|
|
255
|
+
start = Math.min(state.selected, history.length - shownCount);
|
|
256
|
+
}
|
|
257
|
+
const shown = history.slice(start, start + shownCount);
|
|
258
|
+
const hidden = history.length - shown.length;
|
|
259
|
+
const list: string[] = [];
|
|
260
|
+
if (hidden > 0 && shownCount < listRows) list.push(paint("muted", `${pad}(+${hidden} earlier /btw)`));
|
|
261
|
+
shown.forEach((exchange, i) => {
|
|
262
|
+
const text = `${pad}/btw ${questionLine(exchange.question, inner)}`;
|
|
263
|
+
list.push(state.selected === start + i ? bold(text) : paint("muted", text));
|
|
264
|
+
});
|
|
265
|
+
const marker = selected ? paint("muted", "/btw ") : bold(paint("warning", "/btw "));
|
|
266
|
+
list.push(`${pad}${marker}${paint("muted", questionLine(question, inner))}`);
|
|
267
|
+
|
|
268
|
+
const answerWidth = Math.max(1, inner - ANSWER_INDENT);
|
|
269
|
+
const renderAnswer = input.renderAnswer ?? wrapPlainText;
|
|
270
|
+
const answerLines = selected
|
|
271
|
+
? renderAnswer(selected.answer, answerWidth, selected)
|
|
272
|
+
: body.kind === "answer"
|
|
273
|
+
? renderAnswer(body.text || "(no answer)", answerWidth, state)
|
|
274
|
+
: body.kind === "error"
|
|
275
|
+
? wrapPlainText(body.message, answerWidth).map((line) => paint("error", line))
|
|
276
|
+
: [paint("muted", "Answering…")];
|
|
277
|
+
|
|
278
|
+
const header = [panelTopRule(paint, inner), "", ...list, ""];
|
|
279
|
+
const footerRows = 2; // blank + hint
|
|
280
|
+
const capacity = Math.max(1, height - header.length - footerRows);
|
|
166
281
|
state.viewport = capacity;
|
|
167
|
-
state.maxOffset = Math.max(0,
|
|
282
|
+
state.maxOffset = Math.max(0, answerLines.length - capacity);
|
|
168
283
|
state.offset = Math.min(Math.max(0, state.offset), state.maxOffset);
|
|
284
|
+
const indent = " ".repeat(ANSWER_INDENT);
|
|
285
|
+
const visible = answerLines.slice(state.offset, state.offset + capacity).map((line) => `${indent}${line}`);
|
|
169
286
|
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
287
|
+
const currentAnswer = body.kind === "answer" && body.text !== "";
|
|
288
|
+
const hasAnswer = Boolean(selected) || currentAnswer;
|
|
289
|
+
let hint: string;
|
|
290
|
+
if (input.forking) {
|
|
291
|
+
hint = paint("muted", "Forking…");
|
|
292
|
+
} else {
|
|
293
|
+
const parts: string[] = [];
|
|
294
|
+
if (history.length > 0) parts.push(paint("muted", "⇧←/→ to browse"));
|
|
295
|
+
else if (body.kind !== "loading") parts.push(paint("muted", "↑/↓ to scroll"));
|
|
296
|
+
if (hasAnswer) {
|
|
297
|
+
if (state.copyError) parts.push(paint("error", state.copyError));
|
|
298
|
+
else parts.push(state.copied ? paint("success", "Copied to clipboard") : paint("muted", "c to copy"));
|
|
299
|
+
}
|
|
300
|
+
if (input.canFork && !selected && currentAnswer) parts.push(paint("muted", "f to fork"));
|
|
301
|
+
if (history.length > 0) parts.push(paint("muted", "x to clear history"));
|
|
302
|
+
parts.push(paint("muted", "Esc to close"));
|
|
303
|
+
hint = parts.join(paint("muted", " · "));
|
|
304
|
+
}
|
|
177
305
|
|
|
178
|
-
return [...header, ...visible,
|
|
306
|
+
return [...header, ...visible, "", `${pad}${hint}`].map((line) => truncateLine(line, inner));
|
|
179
307
|
}
|
package/extensions/btw/prompt.ts
CHANGED
|
@@ -6,16 +6,19 @@
|
|
|
6
6
|
* answering model as a separate, tool-less instance, prepended to the user's
|
|
7
7
|
* question as the final user message.
|
|
8
8
|
*
|
|
9
|
-
* Kept free of pi imports so the message assembly
|
|
9
|
+
* Kept free of pi imports (pi-ai types only) so the message assembly is
|
|
10
10
|
* unit-tested; the extension owns the model call, the spinner, and the panel.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import type { Api, AssistantMessage, Message, Model, UserMessage } from "@earendil-works/pi-ai";
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* CC's verbatim side-question reminder (captures/btw.json message 20). It frames
|
|
15
17
|
* the answering instance as a separate, lightweight, tool-less agent so the
|
|
16
|
-
* model answers in one shot from context instead of trying to act.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
18
|
+
* model answers in one shot from context instead of trying to act. Like Claude
|
|
19
|
+
* Code, the replayed request still declares the session's real tools (they are
|
|
20
|
+
* part of the cached prefix); a tool call in the answer is never executed, only
|
|
21
|
+
* its text is shown, and the exchange never reaches the main conversation.
|
|
19
22
|
*/
|
|
20
23
|
export const SIDE_QUESTION_REMINDER = `<system-reminder>This is a side question from the user. You must answer this question directly in a single response.
|
|
21
24
|
|
|
@@ -43,3 +46,37 @@ Simply answer the question with the information you have.</system-reminder>`;
|
|
|
43
46
|
export function sideQuestionMessage(question: string): string {
|
|
44
47
|
return `${SIDE_QUESTION_REMINDER}\n\n${question.trim()}`;
|
|
45
48
|
}
|
|
49
|
+
|
|
50
|
+
/** One answered side question, kept for the rest of the session. */
|
|
51
|
+
export interface BtwExchange {
|
|
52
|
+
question: string;
|
|
53
|
+
answer: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The model an injected assistant message is attributed to. */
|
|
57
|
+
type ModelRef = Pick<Model<Api>, "api" | "provider" | "id">;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* One exchange as the user/assistant pair a later request carries: the bare
|
|
61
|
+
* question (no reminder) and the answer, as Claude Code threads its side
|
|
62
|
+
* session's history into the next side question. A fork gets the same pairs.
|
|
63
|
+
*/
|
|
64
|
+
export function exchangeMessages(exchange: BtwExchange, model: ModelRef, timestamp = Date.now()): Message[] {
|
|
65
|
+
const user: UserMessage = { role: "user", content: [{ type: "text", text: exchange.question }], timestamp };
|
|
66
|
+
const assistant: AssistantMessage = {
|
|
67
|
+
role: "assistant",
|
|
68
|
+
content: [{ type: "text", text: exchange.answer }],
|
|
69
|
+
api: model.api,
|
|
70
|
+
provider: model.provider,
|
|
71
|
+
model: model.id,
|
|
72
|
+
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
|
|
73
|
+
stopReason: "stop",
|
|
74
|
+
timestamp,
|
|
75
|
+
};
|
|
76
|
+
return [user, assistant];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Every earlier exchange, oldest first, as the messages sent before a new side question. */
|
|
80
|
+
export function historyMessages(exchanges: readonly BtwExchange[], model: ModelRef, timestamp = Date.now()): Message[] {
|
|
81
|
+
return exchanges.flatMap((exchange) => exchangeMessages(exchange, model, timestamp));
|
|
82
|
+
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* It also points discovery at the catalog of skills bundled with this package
|
|
12
12
|
* (`<package>/skills`) — Claude Code's self-contained built-in skills, which
|
|
13
13
|
* ship inside its binary rather than on disk, so nothing else would surface
|
|
14
|
-
* them. See docs/decisions/skills-plugins.md and docs/findings (the extraction
|
|
14
|
+
* them. See working-docs/decisions/skills-plugins.md and working-docs/findings (the extraction
|
|
15
15
|
* process is recorded in .claude/skills/extract-cc-skills/).
|
|
16
16
|
*
|
|
17
17
|
* CLAUDE.md needs no handling — pi discovers it natively alongside AGENTS.md.
|
|
@@ -19,12 +19,10 @@
|
|
|
19
19
|
|
|
20
20
|
import { existsSync } from "node:fs";
|
|
21
21
|
import os from "node:os";
|
|
22
|
-
import { join } from "node:path";
|
|
23
22
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
24
|
-
import { claudeConfigDir } from "../lib/paths.ts";
|
|
25
|
-
import { claudeUserDir } from "../lib/paths.ts";
|
|
23
|
+
import { claudeConfigDir, claudeUserDir } from "../lib/paths.ts";
|
|
26
24
|
|
|
27
|
-
import { BUNDLED_SKILLS_DIR } from "../lib/skill-scan.ts";
|
|
25
|
+
import { BUNDLED_SKILLS_DIR, commandDirs, skillSourceDirs } from "../lib/skill-scan.ts";
|
|
28
26
|
|
|
29
27
|
/**
|
|
30
28
|
* `claudeDir` is Claude Code's config dir (honours CLAUDE_CONFIG_DIR), defaulting
|
|
@@ -38,19 +36,17 @@ export function claudeResourcePaths(
|
|
|
38
36
|
claudeDir: string = claudeUserDir(home),
|
|
39
37
|
bundledSkillsDir?: string,
|
|
40
38
|
): { skillPaths: string[]; promptPaths: string[] } {
|
|
39
|
+
// The folders follow the config mode (lib/skill-scan.ts, lib/config-mode.ts).
|
|
41
40
|
const candidates = {
|
|
42
41
|
skillPaths: [
|
|
43
|
-
|
|
44
|
-
join(home, ".agents", "skills"),
|
|
45
|
-
join(cwd, ".claude", "skills"),
|
|
46
|
-
join(cwd, ".agents", "skills"),
|
|
42
|
+
...skillSourceDirs(cwd, home, claudeDir).map(({ dir }) => dir),
|
|
47
43
|
// The bundled catalog is listed LAST so it loses a name collision:
|
|
48
44
|
// pi keeps the first-loaded skill for a given name, so a user or
|
|
49
45
|
// project skill of the same name wins and the bundled one is the
|
|
50
|
-
// fallback (see docs/decisions/skills-plugins.md).
|
|
46
|
+
// fallback (see working-docs/decisions/skills-plugins.md).
|
|
51
47
|
...(bundledSkillsDir ? [bundledSkillsDir] : []),
|
|
52
48
|
],
|
|
53
|
-
promptPaths:
|
|
49
|
+
promptPaths: commandDirs(cwd, home, claudeDir),
|
|
54
50
|
};
|
|
55
51
|
return {
|
|
56
52
|
skillPaths: candidates.skillPaths.filter((p) => existsSync(p)),
|