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
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* User-invoked skill commands (pure). pi registers each skill as a `/skill:<name>`
|
|
3
3
|
* slash command and, on invocation, expands it into a `<skill>` block that it
|
|
4
|
-
* submits as a *user message
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* submits as a *user message*. One Code intercepts that command (and its own
|
|
5
|
+
* bare `/<name>` and typed `/<plugin>:<skill>` forms) and delivers the skill
|
|
6
|
+
* the way Claude Code does: a hidden message holding the command breadcrumb
|
|
7
|
+
* and the skill's text, so nothing renders and no `skill` call is needed.
|
|
8
|
+
* A model's `skill` call gets Claude Code's "Launching skill" result with the
|
|
9
|
+
* same text beside it (see index.ts).
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* pi's own `<skill>` block still reaches a session through pi's native
|
|
12
|
+
* expansion on older pi (steer/followUp skip the `input` hook there), which
|
|
13
|
+
* is why the off-skill redaction below still matches it.
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
|
-
import { dirname } from "node:path";
|
|
15
|
-
|
|
16
16
|
const SKILL_PREFIX = "/skill:";
|
|
17
17
|
|
|
18
18
|
/** Parse a `/skill:<name> [args]` command; undefined if it is not one. */
|
|
@@ -45,84 +45,115 @@ export function resolveSkill<T extends { name: string }>(all: T[], wanted: strin
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
49
|
-
* the
|
|
50
|
-
*
|
|
48
|
+
* Claude Code's breadcrumb for a typed slash command, the first text block of
|
|
49
|
+
* the message a typed skill becomes. Its arguments ride `<command-args>` only
|
|
50
|
+
* when there are some.
|
|
51
51
|
*/
|
|
52
|
-
export function
|
|
53
|
-
|
|
54
|
-
References are relative to ${dirname(skill.filePath)}.
|
|
55
|
-
|
|
56
|
-
${body}
|
|
57
|
-
</skill>`;
|
|
58
|
-
return args ? `${block}\n\n${args}` : block;
|
|
52
|
+
export function commandBreadcrumb(name: string, args: string): string {
|
|
53
|
+
return `<command-message>${name}</command-message>\n<command-name>/${name}</command-name>${args ? `\n<command-args>${args}</command-args>` : ""}\n`;
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
const SKILL_BLOCK_RE = /<skill name="([^"]+)"[^>]*>[\s\S]*?<\/skill>/g;
|
|
64
|
-
|
|
65
|
-
export const offSkillNotice = (name: string): string =>
|
|
66
|
-
`[Skill "${name}" is turned off — its instructions were removed. The user can re-enable it from /skills or /plugins.]`;
|
|
56
|
+
// commandBreadcrumb's shape at the start of a message; the arguments may span lines.
|
|
57
|
+
const BREADCRUMB = /^<command-message>[^<\n]*<\/command-message>\n<command-name>(\/[^<\n]*)<\/command-name>(?:\n<command-args>([\s\S]*?)<\/command-args>)?\n/;
|
|
67
58
|
|
|
68
59
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* This is the fail-closed backstop behind the `input`-hook interception:
|
|
74
|
-
* pi's `steer()`/`followUp()` expand `/skill:<name>` natively WITHOUT firing
|
|
75
|
-
* the `input` event (queued interactive messages after the first, RPC
|
|
76
|
-
* steer/followUp), so an off skill's instructions can land in the session
|
|
77
|
-
* history. Redacting on the `context` hook strips them from every outgoing
|
|
78
|
-
* request — the session file keeps the original bytes, and the rewrite is
|
|
79
|
-
* deterministic for a fixed override state, so the request prefix stays
|
|
80
|
-
* byte-stable across turns (prompt-cache friendly).
|
|
60
|
+
* What a user message that opens with commandBreadcrumb shows in the
|
|
61
|
+
* transcript: the command as typed, `/name args`. Claude Code shows a prompt
|
|
62
|
+
* command (a skill, `/init`, `/doctor`) by its command line and keeps the
|
|
63
|
+
* expanded text out of the transcript. `undefined` for any other message.
|
|
81
64
|
*/
|
|
82
|
-
export function
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (!isOff(name)) return block;
|
|
87
|
-
changed = true;
|
|
88
|
-
return offSkillNotice(name);
|
|
89
|
-
});
|
|
90
|
-
return changed ? redacted : undefined;
|
|
65
|
+
export function commandDisplayLine(text: string): string | undefined {
|
|
66
|
+
const match = BREADCRUMB.exec(text);
|
|
67
|
+
if (!match) return undefined;
|
|
68
|
+
return match[2] ? `${match[1]} ${match[2]}` : match[1];
|
|
91
69
|
}
|
|
92
70
|
|
|
93
71
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
72
|
+
* Claude Code's argument substitution in a skill's text: `$ARGUMENTS`,
|
|
73
|
+
* `$ARGUMENTS[n]` and `$n` (both counted from 0) take the arguments, and a
|
|
74
|
+
* backslash keeps a `$` literal. When nothing was substituted, the arguments
|
|
75
|
+
* follow the text on an `ARGUMENTS:` line.
|
|
98
76
|
*/
|
|
99
|
-
export function
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const out =
|
|
105
|
-
if (
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
changed = true;
|
|
110
|
-
return { ...message, content: redacted };
|
|
77
|
+
export function substituteSkillArguments(text: string, args: string): string {
|
|
78
|
+
if (!args.trim()) return text;
|
|
79
|
+
const parts = args.trim().split(/\s+/);
|
|
80
|
+
let used = false;
|
|
81
|
+
// One pass, so an argument holding `$0` is never substituted again.
|
|
82
|
+
const out = text.replace(/\\\$(?=\d|ARGUMENTS)|\$ARGUMENTS\[(\d+)\]|\$ARGUMENTS|\$(\d+)(?!\w)/g, (match, listed?: string, positional?: string) => {
|
|
83
|
+
if (match.startsWith("\\")) return "$";
|
|
84
|
+
if (match === "$ARGUMENTS") {
|
|
85
|
+
used = true;
|
|
86
|
+
return args;
|
|
111
87
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const redacted = redactOffSkillText(block.text, isOff);
|
|
117
|
-
if (redacted === undefined) return block;
|
|
118
|
-
blockChanged = true;
|
|
119
|
-
return { ...block, text: redacted };
|
|
120
|
-
});
|
|
121
|
-
if (!blockChanged) return message;
|
|
122
|
-
changed = true;
|
|
123
|
-
return { ...message, content: blocks };
|
|
88
|
+
const part = parts[Number(listed ?? positional)];
|
|
89
|
+
if (part === undefined) return match;
|
|
90
|
+
used = true;
|
|
91
|
+
return part;
|
|
124
92
|
});
|
|
125
|
-
return
|
|
93
|
+
return used ? out : `${out}\n\nARGUMENTS: ${args}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The text a skill hands the model, as Claude Code builds it: the skill's
|
|
98
|
+
* folder first (`Base directory for this skill: …`, so relative `references/`
|
|
99
|
+
* and `scripts/` resolve), then the body with its arguments. A skill that
|
|
100
|
+
* ships inside One Code, like Claude Code's own, names no folder.
|
|
101
|
+
*/
|
|
102
|
+
export function skillPromptText(body: string, args: string, baseDir: string | undefined): string {
|
|
103
|
+
const text = substituteSkillArguments(body, args);
|
|
104
|
+
return baseDir ? `Base directory for this skill: ${baseDir}\n\n${text}` : text;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The message a typed skill command becomes, as Claude Code sends it: the
|
|
109
|
+
* breadcrumb, then the skill's text, each ending in a newline. Arguments a
|
|
110
|
+
* generated body already carries are not passed again.
|
|
111
|
+
*/
|
|
112
|
+
export function typedSkillContent(name: string, typedArgs: string, promptText: string): [string, string] {
|
|
113
|
+
return [commandBreadcrumb(name, typedArgs), promptText.endsWith("\n") ? promptText : `${promptText}\n`];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* A prompt command (`/init`, `/doctor`, a plugin command) as one user message,
|
|
118
|
+
* in a typed skill's exact bytes: Claude Code sends every prompt command led by
|
|
119
|
+
* its breadcrumb, and the transcript shows it as its command line
|
|
120
|
+
* (commandDisplayLine).
|
|
121
|
+
*/
|
|
122
|
+
export function promptCommandText(name: string, args: string, prompt: string): string {
|
|
123
|
+
return typedSkillContent(name, args, prompt).join("\n");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Claude Code's result for a model's skill call; the skill's text follows it as a second block. */
|
|
127
|
+
export const launchingSkill = (name: string): string => `Launching skill: ${name}`;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The lines that open and close a skill tool result when the model called a
|
|
131
|
+
* skill that takes arguments without passing any. A skill's text is its
|
|
132
|
+
* instructions, not a manual: a weak model "checking the interface" of
|
|
133
|
+
* `/loop` got the no-argument body, which starts an autonomous loop. A mild
|
|
134
|
+
* opening line lost to that body's "The user invoked /loop with no prompt"
|
|
135
|
+
* on DeepSeek V4.1 Flash; telling it to stop and check, plus a closing
|
|
136
|
+
* reminder, turned it around. Only the model's tool calls get this; a user's
|
|
137
|
+
* bare `/<name>` is deliberate.
|
|
138
|
+
*/
|
|
139
|
+
export function missingArgumentsNote(argumentHint: string): { before: string; after: string } {
|
|
140
|
+
return {
|
|
141
|
+
before: `Stop and check before following this. This skill takes arguments (${argumentHint}) and this call passed none, so what follows is its no-argument mode, written as if the user asked for the skill with nothing after it. If the user's request names any of those arguments, do not follow the instructions below: call the skill again with them in \`args\`.`,
|
|
142
|
+
after: "Reminder: those were the no-argument instructions. If the user's request included arguments, call the skill again with them in `args` instead of following them.",
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The hidden message a `/skill:` command is delivered as. `details.input` is
|
|
148
|
+
* the text the user typed, so an extension that saw that text at `input` (the
|
|
149
|
+
* hooks extension's UserPromptSubmit context) can find the message that
|
|
150
|
+
* replaced it.
|
|
151
|
+
*/
|
|
152
|
+
export const SKILL_INVOCATION_TYPE = "one-code:skill-invocation";
|
|
153
|
+
export interface SkillInvocationDetails {
|
|
154
|
+
skill: string;
|
|
155
|
+
args: string;
|
|
156
|
+
input?: string;
|
|
126
157
|
}
|
|
127
158
|
|
|
128
159
|
// ---------------------------------------------------------------------------
|
|
@@ -184,3 +215,15 @@ export function skillCommandCandidates<T extends { name: string; source: string
|
|
|
184
215
|
}
|
|
185
216
|
return out;
|
|
186
217
|
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The `/` suggestions without pi's `/skill:<name>` entry for a skill that also
|
|
221
|
+
* has its bare `/<name>` command, so each skill is listed once, as in Claude
|
|
222
|
+
* Code. Kept when the user is typing `/skill:` themselves, and for a skill
|
|
223
|
+
* whose bare name was skipped (a collision), where `/skill:` is its only form.
|
|
224
|
+
* Typed `/skill:<name>` still runs either way: this only trims the list.
|
|
225
|
+
*/
|
|
226
|
+
export function withoutDuplicateSkillCommands<T extends { value: string }>(items: T[], prefix: string, bareSkills: ReadonlySet<string>): T[] {
|
|
227
|
+
if (!prefix.startsWith("/") || prefix.startsWith("/skill:")) return items;
|
|
228
|
+
return items.filter((item) => !(item.value.startsWith("skill:") && bareSkills.has(item.value.slice("skill:".length))));
|
|
229
|
+
}
|
|
@@ -2,20 +2,144 @@
|
|
|
2
2
|
* The model-facing skills listing (pure). The state decides visibility: "on"
|
|
3
3
|
* carries name + description, "name-only" just the name (saving context
|
|
4
4
|
* tokens), "user-only"/"off" are hidden so the model won't auto-trigger them.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* A skill whose frontmatter sets `disable-model-invocation: true` is hidden
|
|
6
|
+
* whatever its state: only the user may start it, as in Claude Code.
|
|
7
|
+
*
|
|
8
|
+
* Each line is built the way Claude Code builds it: the description, then
|
|
9
|
+
* " - " and the `when_to_use` frontmatter when there is one, clipped at 1,536
|
|
10
|
+
* characters (1,535 and an ellipsis). The description keeps its newlines: a
|
|
11
|
+
* skill written with a YAML block description puts its "Use when…" trigger on
|
|
12
|
+
* the later lines, and a first-line-only listing dropped exactly the sentence
|
|
13
|
+
* that tells the model when to reach for the skill.
|
|
14
|
+
*
|
|
15
|
+
* The whole listing has a budget, 1% of the context window in characters
|
|
16
|
+
* (`SLASH_COMMAND_TOOL_CHAR_BUDGET` replaces it). Over budget, a bundled skill
|
|
17
|
+
* and a name-only one keep their lines; the others keep theirs by usage rank
|
|
18
|
+
* while the budget lasts and are listed by name after that.
|
|
9
19
|
*/
|
|
10
20
|
|
|
11
21
|
import { type SkillState, skillListingVisibility } from "../lib/skill-overrides.ts";
|
|
22
|
+
import type { UsageEntry } from "../lib/usage-tracker.ts";
|
|
12
23
|
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
/** Claude Code's per-entry cap (its `skillListingMaxDescChars` default). */
|
|
25
|
+
export const SKILL_DESCRIPTION_CAP = 1536;
|
|
26
|
+
/** The listing's share of the context window, at 4 characters per token, 200K tokens when the window is unknown. */
|
|
27
|
+
const BUDGET_FRACTION = 0.01;
|
|
28
|
+
const CHARS_PER_TOKEN = 4;
|
|
29
|
+
const DEFAULT_CONTEXT_WINDOW = 200_000;
|
|
30
|
+
|
|
31
|
+
export interface ListedSkill {
|
|
32
|
+
name: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
/** The `when_to_use` frontmatter, appended after " - ". */
|
|
35
|
+
whenToUse?: string;
|
|
36
|
+
state: SkillState;
|
|
37
|
+
disableModelInvocation?: boolean;
|
|
38
|
+
/** Ships inside One Code: keeps its line over budget, as Claude Code's bundled skills do. */
|
|
39
|
+
bundled?: boolean;
|
|
40
|
+
/** The usage score that ranks the line over budget (`usageScore`). */
|
|
41
|
+
usage?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The text after `- <name>: `, clipped as Claude Code clips it. */
|
|
45
|
+
export function listingDescription(skill: Pick<ListedSkill, "description" | "whenToUse">): string {
|
|
46
|
+
const description = skill.description?.trim() ?? "";
|
|
47
|
+
const whenToUse = skill.whenToUse?.trim();
|
|
48
|
+
const text = whenToUse ? `${description} - ${whenToUse}` : description;
|
|
49
|
+
return text.length > SKILL_DESCRIPTION_CAP ? `${text.slice(0, SKILL_DESCRIPTION_CAP - 1)}…` : text;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The listing's character budget for a context window (tokens). */
|
|
53
|
+
export function skillListingBudget(contextWindow: number | undefined, env: NodeJS.ProcessEnv = process.env): number {
|
|
54
|
+
const fromEnv = Number.parseInt(env.SLASH_COMMAND_TOOL_CHAR_BUDGET ?? "", 10);
|
|
55
|
+
if (fromEnv > 0) return fromEnv;
|
|
56
|
+
const window = contextWindow && contextWindow > 0 ? contextWindow : DEFAULT_CONTEXT_WINDOW;
|
|
57
|
+
return Math.max(1, Math.floor(window * CHARS_PER_TOKEN * BUDGET_FRACTION));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Claude Code's ranking score: uses, halved every week since the last one, never below a tenth. */
|
|
61
|
+
export function usageScore(entry: UsageEntry | undefined, now: Date = new Date()): number {
|
|
62
|
+
if (!entry) return 0;
|
|
63
|
+
const last = Date.parse(entry.lastUsedAt);
|
|
64
|
+
if (Number.isNaN(last)) return 0;
|
|
65
|
+
const days = (now.getTime() - last) / 86_400_000;
|
|
66
|
+
return entry.count * Math.max(0.5 ** (days / 7), 0.1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function skillListingText(skills: ReadonlyArray<ListedSkill>, budget = Number.POSITIVE_INFINITY): string {
|
|
70
|
+
const listed = skills.flatMap((skill) => {
|
|
71
|
+
if (skill.disableModelInvocation) return [];
|
|
15
72
|
const visibility = skillListingVisibility(skill.state);
|
|
16
73
|
if (visibility === "hidden") return [];
|
|
17
|
-
|
|
18
|
-
|
|
74
|
+
const short = `- ${skill.name}`;
|
|
75
|
+
if (visibility === "name") return [{ skill, short, full: short }];
|
|
76
|
+
const text = listingDescription(skill);
|
|
77
|
+
return [{ skill, short, full: text ? `${short}: ${text}` : short }];
|
|
19
78
|
});
|
|
20
|
-
|
|
79
|
+
if (listed.length === 0) return "(no skills available)";
|
|
80
|
+
const separators = listed.length - 1;
|
|
81
|
+
const whole = listed.reduce((sum, line) => sum + line.full.length, 0) + separators;
|
|
82
|
+
if (whole <= budget) return listed.map((line) => line.full).join("\n");
|
|
83
|
+
|
|
84
|
+
// A name-only line's full form is its short form, so it needs no place in `kept`.
|
|
85
|
+
const kept = new Set(listed.filter((line) => line.skill.bundled));
|
|
86
|
+
const ranked = listed.filter((line) => !kept.has(line));
|
|
87
|
+
let left = budget - (listed.reduce((sum, line) => sum + (kept.has(line) ? line.full.length : line.short.length), 0) + separators);
|
|
88
|
+
// A stable sort: equal scores keep the listing's order.
|
|
89
|
+
for (const line of [...ranked].sort((a, b) => (b.skill.usage ?? 0) - (a.skill.usage ?? 0))) {
|
|
90
|
+
const extra = line.full.length - line.short.length;
|
|
91
|
+
if (extra > left) continue;
|
|
92
|
+
kept.add(line);
|
|
93
|
+
left -= extra;
|
|
94
|
+
}
|
|
95
|
+
return listed.map((line) => (kept.has(line) ? line.full : line.short)).join("\n");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The skills listing for a session without the skill tool: each skill's file,
|
|
100
|
+
* to read with `reader`. The same states as the tool's listing: user-only and
|
|
101
|
+
* off skills stay hidden, a name-only skill shows no description. Undefined
|
|
102
|
+
* when nothing is listable.
|
|
103
|
+
*/
|
|
104
|
+
export function readableSkillListing(
|
|
105
|
+
skills: ReadonlyArray<ListedSkill & { path?: string; kind?: string }>,
|
|
106
|
+
reader: string,
|
|
107
|
+
): string | undefined {
|
|
108
|
+
const lines = skills
|
|
109
|
+
.filter((skill) => !skill.kind && !skill.disableModelInvocation && skill.path && skillListingVisibility(skill.state) !== "hidden")
|
|
110
|
+
.map((skill) => {
|
|
111
|
+
const text = skillListingVisibility(skill.state) === "full" ? listingDescription(skill) : "";
|
|
112
|
+
return `- ${skill.name}${text ? `: ${text}` : ""} (${skill.path})`;
|
|
113
|
+
});
|
|
114
|
+
if (lines.length === 0) return undefined;
|
|
115
|
+
return `The following skills provide specialized instructions for specific tasks. Read a skill's file with ${reader} when the task matches its description:\n\n${lines.join("\n")}`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Claude Code's reading of a boolean frontmatter flag such as
|
|
120
|
+
* `disable-model-invocation`: `true` or the string `"true"`, nothing else.
|
|
121
|
+
*/
|
|
122
|
+
export function frontmatterFlag(value: unknown): boolean {
|
|
123
|
+
return value === true || value === "true";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* pi's own skills section in a rendered system prompt (`formatSkillsForPrompt`):
|
|
128
|
+
* pi 1.0 renders it as a `<skills>` section, older pi (the 0.84 floor)
|
|
129
|
+
* appends it after a blank line. Both start with this sentence.
|
|
130
|
+
*/
|
|
131
|
+
const PI_SKILLS_LEAD = "The following skills provide specialized instructions for specific tasks.";
|
|
132
|
+
const PI_SKILLS_SECTION = /\n*<skills>\nThe following skills provide specialized instructions for specific tasks\.[\s\S]*?<\/available_skills>\n<\/skills>/;
|
|
133
|
+
const PI_SKILLS_APPENDED = /\n\nThe following skills provide specialized instructions for specific tasks\.[\s\S]*?<\/available_skills>/;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* `prompt` without pi's own skills section ("Use the read tool to load a
|
|
137
|
+
* skill's file …" and its `<available_skills>` list), unchanged when it has
|
|
138
|
+
* none. A session with the skill tool lists skills for that tool instead, and
|
|
139
|
+
* a child agent's prompt (pi adds the section to an agent's own prompt)
|
|
140
|
+
* otherwise told it both "read the file" and "call the skill tool first".
|
|
141
|
+
*/
|
|
142
|
+
export function withoutPiSkillsBlock(prompt: string): string {
|
|
143
|
+
if (!prompt.includes(PI_SKILLS_LEAD)) return prompt;
|
|
144
|
+
return prompt.replace(PI_SKILLS_SECTION, "").replace(PI_SKILLS_APPENDED, "");
|
|
21
145
|
}
|
|
@@ -1,41 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Key decoding for the /skills panel (pure), named through
|
|
3
|
+
* `lib/key-input.ts` so every terminal encoding of a key decodes alike.
|
|
3
4
|
*
|
|
4
|
-
* Same
|
|
5
|
+
* Same key map as the /plugins panel; kept local so the skill
|
|
5
6
|
* extension carries no dependency on another extension's internals. Printable
|
|
6
7
|
* input is a `text` intent the state layer routes (into the search box, or as a
|
|
7
8
|
* single-letter action when search is inactive). Skill names never contain
|
|
8
9
|
* spaces, so Space is always the cycle action, never typed.
|
|
9
10
|
*/
|
|
10
11
|
|
|
12
|
+
import { keyId, keyText } from "../../lib/key-input.ts";
|
|
13
|
+
|
|
11
14
|
export type SkillsKey =
|
|
12
15
|
| { kind: "up" | "down" | "enter" | "space" | "back" | "backspace" | "close" }
|
|
13
16
|
| { kind: "text"; text: string };
|
|
14
17
|
|
|
15
18
|
export function decodeSkillsKey(data: string): SkillsKey | undefined {
|
|
16
|
-
switch (data) {
|
|
17
|
-
case "
|
|
18
|
-
case "\x1bOA":
|
|
19
|
+
switch (keyId(data)) {
|
|
20
|
+
case "up":
|
|
19
21
|
return { kind: "up" };
|
|
20
|
-
case "
|
|
21
|
-
case "\x1bOB":
|
|
22
|
+
case "down":
|
|
22
23
|
return { kind: "down" };
|
|
23
|
-
case "
|
|
24
|
-
case "\n":
|
|
24
|
+
case "enter":
|
|
25
25
|
return { kind: "enter" };
|
|
26
|
-
case "
|
|
26
|
+
case "space":
|
|
27
27
|
return { kind: "space" };
|
|
28
|
-
case "
|
|
28
|
+
case "escape":
|
|
29
29
|
return { kind: "back" };
|
|
30
|
-
case "
|
|
31
|
-
case "
|
|
30
|
+
case "backspace":
|
|
31
|
+
case "ctrl+backspace":
|
|
32
32
|
return { kind: "backspace" };
|
|
33
|
-
case "
|
|
33
|
+
case "ctrl+c":
|
|
34
34
|
return { kind: "close" };
|
|
35
35
|
default:
|
|
36
36
|
break;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
const text = [...data].filter((ch) => ch >= " " && ch !== "\x7f").join("");
|
|
38
|
+
const text = keyText(data);
|
|
40
39
|
return text ? { kind: "text", text } : undefined;
|
|
41
40
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* under-measure and risk pi's overwide-line crash.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { cutPlainText, padPlainText, panelTopRule, searchBoxLines, visibleWidth } from "../../lib/tui-render.ts";
|
|
12
|
+
import { cutPlainText, padPlainText, panelTopRule, searchBoxLines, visibleWidth, wrapHints } from "../../lib/tui-render.ts";
|
|
13
13
|
import type { SkillState } from "../../lib/skill-overrides.ts";
|
|
14
14
|
import { clampSkillsCursor, type SkillsPanelState, type SkillsRow, visibleRows } from "./state.ts";
|
|
15
15
|
|
|
@@ -64,7 +64,10 @@ export function renderSkillsPanel(input: SkillsRenderInput, paint: SkillsPaint):
|
|
|
64
64
|
const out: string[] = [panelTopRule(paint.fg, width)];
|
|
65
65
|
out.push(` ${paint.bold("Skills")}`);
|
|
66
66
|
const sortNote = state.sort === "state" ? "sorted by state" : "sorted by name";
|
|
67
|
-
|
|
67
|
+
// Wraps at the separators on a narrow terminal, so no key is cut off; the
|
|
68
|
+
// list budget below is taken after it.
|
|
69
|
+
const hints = `${rows.length} skill${rows.length === 1 ? "" : "s"} · ${sortNote} · enter/space to cycle · / to search · t to sort · Esc to close`;
|
|
70
|
+
for (const line of wrapHints(hints, Math.max(1, width - 2))) out.push(paint.fg("dim", ` ${line}`));
|
|
68
71
|
out.push("");
|
|
69
72
|
out.push(...searchBoxLines(state.search, "Search skills…", paint.fg, width));
|
|
70
73
|
out.push("");
|
|
@@ -14,7 +14,8 @@ export interface SkillsRow {
|
|
|
14
14
|
/** Override-store key, `<scope>:<name>`. */
|
|
15
15
|
key: string;
|
|
16
16
|
name: string;
|
|
17
|
-
|
|
17
|
+
/** Shown in the row: where the skill comes from; "bundled" is One Code's own catalog. */
|
|
18
|
+
scope: SkillScope | "bundled";
|
|
18
19
|
tokens: number;
|
|
19
20
|
/** Current state; for locked (plugin) rows this is the effective on/off. */
|
|
20
21
|
state: SkillState;
|
|
@@ -63,6 +64,16 @@ export function clampSkillsCursor(state: SkillsPanelState, visible: SkillsRow[])
|
|
|
63
64
|
state.cursor = Math.max(0, Math.min(state.cursor, visible.length - 1));
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Keep the cursor on the skill `key` after the list reordered (a sort toggle,
|
|
69
|
+
* or a state change under the state sort), so the next key acts on the skill
|
|
70
|
+
* the user was looking at, not the one that slid into its row.
|
|
71
|
+
*/
|
|
72
|
+
export function followRow(state: SkillsPanelState, visible: SkillsRow[], key: string): void {
|
|
73
|
+
const index = visible.findIndex((row) => row.key === key);
|
|
74
|
+
if (index >= 0) state.cursor = index;
|
|
75
|
+
}
|
|
76
|
+
|
|
66
77
|
/**
|
|
67
78
|
* Fold a key into the state, returning an effect the wiring must act on. The
|
|
68
79
|
* caller passes the already-filtered/sorted rows so "the selected row" matches
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { DEFAULT_AGENT } from "./runs.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The Agent tool's argument preparation (pure), run by pi before schema
|
|
5
|
+
* validation. `task` is required in the schema: a weak model read an optional
|
|
6
|
+
* task as optional and sent run options with no task, again and again
|
|
7
|
+
* (DeepSeek V3.2, live, 2026-10-05). Two callers still validate:
|
|
8
|
+
*
|
|
9
|
+
* - a Claude Code-trained model writes the task as `prompt`, which is moved
|
|
10
|
+
* into `task` (TOOL-FIDELITY-REVIEW-2026-09-07 H1);
|
|
11
|
+
* - `action: "list"` only browses the catalog and needs no task.
|
|
12
|
+
*
|
|
13
|
+
* A run that names no agent gets general-purpose here, as in Claude Code, so
|
|
14
|
+
* the permission gate, hooks and the stored call see the agent that runs: an
|
|
15
|
+
* `Agent(general-purpose)` deny rule must stop a call that omits the type.
|
|
16
|
+
*
|
|
17
|
+
* Anything that is not a plain object is passed through for the validator to
|
|
18
|
+
* reject as it does today.
|
|
19
|
+
*/
|
|
20
|
+
export function prepareAgentArguments(args: unknown): unknown {
|
|
21
|
+
if (!args || typeof args !== "object" || Array.isArray(args)) return args;
|
|
22
|
+
const input = args as Record<string, unknown>;
|
|
23
|
+
const prepared = withTask(input);
|
|
24
|
+
if (!isRun(input) || (typeof input.subagent_type === "string" && input.subagent_type)) return prepared;
|
|
25
|
+
return { ...prepared, subagent_type: DEFAULT_AGENT };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function withTask(input: Record<string, unknown>): Record<string, unknown> {
|
|
29
|
+
if (typeof input.task === "string" && input.task.length > 0) return input;
|
|
30
|
+
if (typeof input.prompt === "string" && input.prompt.length > 0) return { ...input, task: input.prompt };
|
|
31
|
+
if (input.action === "list" && input.task === undefined) return { ...input, task: "" };
|
|
32
|
+
return input;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A call carrying run options (a task, a name, a model/thinking/isolation override, or action:"run"); one with none lists the catalog. */
|
|
36
|
+
function isRun(input: Record<string, unknown>): boolean {
|
|
37
|
+
if (input.action === "list") return false;
|
|
38
|
+
return input.action === "run" || [input.task, input.prompt, input.name, input.model, input.isolation, input.thinking].some((value) => value != null);
|
|
39
|
+
}
|