one-code-extension 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -219
- package/agents/general-purpose.md +2 -2
- package/docs/guide/README.md +2 -1
- package/docs/guide/bring-your-claude-code-setup.md +60 -9
- package/docs/guide/configuration.md +48 -14
- package/docs/guide/differences-from-claude-code.md +32 -23
- package/docs/guide/doctor.md +20 -13
- package/docs/guide/hooks.md +18 -3
- package/docs/guide/installation.md +27 -4
- package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
- package/docs/guide/providers-and-models.md +137 -54
- package/docs/guide/reference.md +27 -15
- package/docs/guide/sessions-and-context.md +69 -16
- package/docs/guide/skills-plugins-and-mcp.md +57 -20
- package/docs/guide/subagents-and-workflows.md +95 -29
- package/docs/guide/tasks-and-background-work.md +101 -26
- package/docs/guide/terminal-interface.md +24 -12
- package/docs/guide/tools.md +46 -5
- package/docs/guide/troubleshooting.md +13 -9
- package/docs/guide/windows.md +66 -34
- package/extensions/artifacts/gallery.ts +227 -0
- package/extensions/artifacts/index.ts +288 -0
- package/extensions/artifacts/store.ts +570 -0
- package/extensions/artifacts/viewer.ts +199 -0
- package/extensions/ask-user/description.ts +67 -0
- package/extensions/ask-user/dialogs.ts +80 -0
- package/extensions/ask-user/index.ts +37 -33
- package/extensions/ask-user/questions.ts +32 -7
- package/extensions/ask-user/widget.ts +45 -25
- package/extensions/auto-mode/actions.ts +6 -0
- package/extensions/auto-mode/cache.ts +88 -0
- package/extensions/auto-mode/classifier-prompt.ts +5 -4
- package/extensions/auto-mode/classifier.ts +290 -65
- package/extensions/auto-mode/config.ts +72 -20
- package/extensions/auto-mode/decision-log.ts +2 -0
- package/extensions/auto-mode/defaults.ts +1 -1
- package/extensions/auto-mode/denials.ts +123 -0
- package/extensions/auto-mode/git-checkout-programs.ts +187 -0
- package/extensions/auto-mode/git-status-meta.ts +159 -0
- package/extensions/auto-mode/history.ts +189 -0
- package/extensions/auto-mode/instructions.ts +58 -52
- package/extensions/auto-mode/model-select.ts +159 -134
- package/extensions/auto-mode/paths.ts +57 -5
- package/extensions/auto-mode/pause.ts +57 -2
- package/extensions/auto-mode/prompt.ts +37 -21
- package/extensions/auto-mode/read-only-options.ts +724 -0
- package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
- package/extensions/auto-mode/rules.ts +18 -1
- package/extensions/auto-mode/safety-floor.ts +361 -18
- package/extensions/auto-mode/setup-run.ts +20 -14
- package/extensions/auto-mode/shell-analysis.ts +764 -490
- package/extensions/auto-mode/shell-parse.ts +885 -0
- package/extensions/auto-mode/system-note.ts +33 -0
- package/extensions/auto-mode/transcript.ts +80 -51
- package/extensions/background/cron.ts +515 -0
- package/extensions/background/index.ts +514 -236
- package/extensions/background/loop-fire.ts +136 -0
- package/extensions/background/loop-preamble.ts +59 -0
- package/extensions/background/loop-skill.ts +163 -0
- package/extensions/background/monitor-batch.ts +53 -0
- package/extensions/background/noop-fold.ts +128 -0
- package/extensions/background/switch-guard.ts +52 -0
- package/extensions/background/wakeup.ts +159 -55
- package/extensions/bash/background.ts +53 -17
- package/extensions/bash/child.ts +7 -0
- package/extensions/bash/description.ts +188 -0
- package/extensions/bash/guards.ts +15 -67
- package/extensions/bash/index.ts +88 -35
- package/extensions/branding/compaction-keep.ts +63 -0
- package/extensions/branding/declined.ts +22 -0
- package/extensions/branding/index.ts +133 -9
- package/extensions/branding/prompt-editor.ts +53 -6
- package/extensions/branding/queued-edit.ts +31 -0
- package/extensions/branding/replaced-builtins.ts +68 -0
- package/extensions/branding/startup.ts +33 -71
- package/extensions/btw/index.ts +229 -71
- package/extensions/btw/panel.ts +228 -100
- package/extensions/btw/prompt.ts +41 -4
- package/extensions/claude-compat/index.ts +7 -11
- package/extensions/claude-context/index.ts +446 -58
- package/extensions/compaction/cut.ts +157 -0
- package/extensions/compaction/index.ts +216 -75
- package/extensions/compaction/kept-thinking.ts +62 -0
- package/extensions/compaction/prompt.ts +15 -12
- package/extensions/context-budget/index.ts +24 -5
- package/extensions/context-management/index.ts +25 -0
- package/extensions/doctor/build.ts +59 -8
- package/extensions/doctor/builtins.ts +84 -0
- package/extensions/doctor/cli.ts +7 -1
- package/extensions/doctor/compat.ts +88 -23
- package/extensions/doctor/dependencies.ts +41 -5
- package/extensions/doctor/fix-prompt.ts +9 -2
- package/extensions/doctor/index.ts +102 -58
- package/extensions/doctor/models.ts +102 -63
- package/extensions/doctor/presets.ts +42 -27
- package/extensions/doctor/report.ts +19 -2
- package/extensions/doctor/viewer.ts +49 -27
- package/extensions/effort/index.ts +72 -19
- package/extensions/effort/settings.ts +21 -0
- package/extensions/effort/slider.ts +24 -20
- package/extensions/exit/index.ts +32 -1
- package/extensions/file-tracker/index.ts +337 -26
- package/extensions/file-tracker/replay.ts +96 -10
- package/extensions/file-tracker/restore.ts +63 -0
- package/extensions/file-tracker/results.ts +66 -0
- package/extensions/file-tracker/shell-reads.ts +211 -0
- package/extensions/file-tracker/tracker.ts +32 -15
- package/extensions/footer/footer-line.ts +45 -24
- package/extensions/footer/index.ts +47 -2
- package/extensions/footer/pr.ts +34 -5
- package/extensions/hooks/compaction.ts +7 -0
- package/extensions/hooks/executor.ts +32 -30
- package/extensions/hooks/index.ts +198 -31
- package/extensions/hooks/matcher.ts +3 -0
- package/extensions/hooks/protocol.ts +41 -3
- package/extensions/hooks/settings.ts +50 -19
- package/extensions/hooks/subagent-bridge.ts +2 -0
- package/extensions/hooks/trust.ts +13 -5
- package/extensions/idle-compact/index.ts +119 -0
- package/extensions/idle-compact/policy.ts +143 -0
- package/extensions/init/index.ts +11 -10
- package/extensions/init/prompt.ts +25 -32
- package/extensions/interrupted/index.ts +13 -1
- package/extensions/kept-thinking/index.ts +27 -0
- package/extensions/lib/agent-cron.ts +130 -0
- package/extensions/lib/agent-loader.ts +15 -1
- package/extensions/lib/agent-view.ts +85 -0
- package/extensions/lib/anthropic-payload.ts +82 -1
- package/extensions/lib/anthropic-server-call.ts +230 -0
- package/extensions/lib/anthropic-server-tools.ts +485 -0
- package/extensions/lib/app-launch.mjs +94 -0
- package/extensions/lib/argument-hints.ts +190 -0
- package/extensions/lib/atomic-write.ts +6 -2
- package/extensions/lib/auto-memory.ts +75 -0
- package/extensions/lib/bash-parser.ts +84 -0
- package/extensions/lib/btw-fork.ts +93 -0
- package/extensions/lib/child-extensions.ts +42 -0
- package/extensions/lib/child-writes.ts +45 -0
- package/extensions/lib/claude-context.ts +515 -100
- package/extensions/lib/claude-external-includes.ts +68 -0
- package/extensions/lib/claude-id.ts +22 -0
- package/extensions/lib/claude-rules.ts +323 -0
- package/extensions/lib/claude-settings.ts +76 -4
- package/extensions/lib/compaction-boundary.ts +36 -0
- package/extensions/lib/compaction-keep.mjs +83 -0
- package/extensions/lib/config-mode.ts +112 -0
- package/extensions/lib/consent-dialogs.ts +63 -0
- package/extensions/lib/consent-preview.ts +5 -1
- package/extensions/lib/consent-stores.ts +48 -0
- package/extensions/lib/context-facts.ts +78 -0
- package/extensions/lib/context-stack.ts +81 -0
- package/extensions/lib/deferred.ts +219 -25
- package/extensions/lib/dock-rows.ts +60 -0
- package/extensions/lib/empty-tool-result.ts +27 -0
- package/extensions/lib/environment-block.ts +76 -0
- package/extensions/lib/fetch-timeout.ts +24 -6
- package/extensions/{system-prompt → lib}/git-status.ts +51 -13
- package/extensions/lib/git.ts +75 -13
- package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
- package/extensions/lib/grammars/README.md +2 -0
- package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
- package/extensions/lib/guide-docs.ts +45 -0
- package/extensions/lib/headless-output.ts +46 -0
- package/extensions/lib/hook-gate.ts +7 -7
- package/extensions/lib/interrupt.ts +20 -4
- package/extensions/lib/key-input.ts +455 -0
- package/extensions/lib/keys.ts +14 -1
- package/extensions/lib/local-command.ts +47 -13
- package/extensions/lib/mcp-overrides.ts +1 -1
- package/extensions/lib/mcp-share.ts +46 -0
- package/extensions/lib/memory-content.ts +146 -0
- package/extensions/lib/memory-index.ts +18 -0
- package/extensions/lib/memory.ts +134 -123
- package/extensions/lib/model-catalog/huggingface.json +174 -0
- package/extensions/lib/model-catalog/models-dev.json +18297 -0
- package/extensions/lib/model-catalog/openrouter.json +5252 -0
- package/extensions/lib/model-catalog-data.ts +513 -0
- package/extensions/lib/model-catalog.ts +462 -0
- package/extensions/lib/model-choice-warnings.ts +137 -0
- package/extensions/lib/model-pairings.ts +152 -0
- package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
- package/extensions/lib/model-policy.ts +112 -15
- package/extensions/lib/model-tier.ts +283 -355
- package/extensions/lib/model-unusable.ts +1 -1
- package/extensions/lib/newer-model.ts +100 -0
- package/extensions/lib/notices.ts +87 -0
- package/extensions/lib/notifications.ts +308 -64
- package/extensions/lib/one-code-settings.ts +74 -8
- package/extensions/lib/open-browser.ts +63 -0
- package/extensions/lib/openrouter-generation.ts +94 -0
- package/extensions/lib/operation-deadline.ts +30 -0
- package/extensions/lib/original-command.ts +4 -4
- package/extensions/lib/package-version.ts +1 -1
- package/extensions/lib/panel-focus.ts +134 -0
- package/extensions/lib/paths.ts +17 -2
- package/extensions/lib/permission-gate.ts +72 -6
- package/extensions/lib/persisted-output.ts +60 -8
- package/extensions/lib/pi-ai-estimate.ts +19 -3
- package/extensions/lib/pi-version.ts +21 -2
- package/extensions/lib/plan-mode-channels.ts +20 -5
- package/extensions/lib/plugins.ts +26 -17
- package/extensions/lib/powershell-parse-script.ts +208 -0
- package/extensions/lib/powershell-parser.ts +344 -0
- package/extensions/lib/process-tree.ts +131 -8
- package/extensions/lib/prompt-options.ts +82 -0
- package/extensions/lib/queued-delivery.ts +44 -0
- package/extensions/lib/reminders.ts +364 -58
- package/extensions/lib/replaced-builtins.mjs +199 -0
- package/extensions/lib/replay-call.ts +70 -0
- package/extensions/lib/request-replay.ts +439 -0
- package/extensions/lib/scratchpad.ts +81 -14
- package/extensions/lib/send-now-channel.ts +7 -0
- package/extensions/lib/session-model-tier.ts +51 -0
- package/extensions/lib/session-work.ts +64 -0
- package/extensions/lib/settings-channels.ts +4 -4
- package/extensions/lib/shell-exit-semantics.ts +170 -0
- package/extensions/lib/shell-quote.ts +11 -0
- package/extensions/lib/shell-result.ts +70 -0
- package/extensions/lib/shell-spawn.ts +70 -6
- package/extensions/lib/shell-tool.ts +75 -25
- package/extensions/lib/side-call-cache.ts +124 -0
- package/extensions/lib/side-call-run.ts +96 -0
- package/extensions/lib/side-call-usage.ts +38 -0
- package/extensions/lib/side-call.ts +13 -1
- package/extensions/lib/single-flight.ts +18 -0
- package/extensions/lib/skill-body.ts +42 -0
- package/extensions/lib/skill-scan.ts +63 -24
- package/extensions/lib/spill-file.ts +140 -0
- package/extensions/lib/subagent-handback.ts +113 -0
- package/extensions/lib/system-role.ts +156 -0
- package/extensions/lib/terminal-text.ts +114 -0
- package/extensions/lib/text-width.ts +47 -16
- package/extensions/lib/timer-ops.ts +20 -0
- package/extensions/lib/tool-additions.ts +149 -0
- package/extensions/lib/tool-call-corruption.ts +134 -0
- package/extensions/lib/tool-path.ts +66 -0
- package/extensions/lib/tool-variants.ts +69 -0
- package/extensions/lib/tui-render.ts +255 -27
- package/extensions/lib/turn-budget-layout.ts +143 -0
- package/extensions/lib/update-check.mjs +15 -2
- package/extensions/lib/usage-bus.ts +1 -1
- package/extensions/lib/user-denial.ts +38 -0
- package/extensions/lib/workspace-channel.ts +16 -0
- package/extensions/lib/worktree-channel.ts +31 -3
- package/extensions/lib/worktree-isolation.ts +40 -10
- package/extensions/lsp/client.ts +8 -9
- package/extensions/lsp/index.ts +70 -4
- package/extensions/lsp/keep-alive.ts +1 -1
- package/extensions/lsp/trust.ts +119 -0
- package/extensions/lsp/watcher.ts +1 -1
- package/extensions/mcp/announce.ts +87 -5
- package/extensions/mcp/client.ts +161 -48
- package/extensions/mcp/config.ts +132 -8
- package/extensions/mcp/discovery.ts +19 -0
- package/extensions/mcp/index.ts +209 -71
- package/extensions/mcp/oauth/browser.ts +38 -17
- package/extensions/mcp/oauth/flow.ts +25 -17
- package/extensions/mcp/oauth/provider.ts +14 -8
- package/extensions/mcp/oauth/store.ts +34 -16
- package/extensions/mcp/panel/keys.ts +12 -11
- package/extensions/mcp/panel/render.ts +9 -6
- package/extensions/mcp/schema.ts +104 -5
- package/extensions/mcp/trust.ts +151 -67
- package/extensions/memory/entries.ts +23 -14
- package/extensions/memory/index.ts +134 -28
- package/extensions/memory/open-external.ts +33 -18
- package/extensions/memory/panel.ts +135 -26
- package/extensions/newer-model/index.ts +31 -0
- package/extensions/notebook/description.ts +18 -0
- package/extensions/notebook/index.ts +6 -5
- package/extensions/notebook/notebook.ts +1 -1
- package/extensions/permissions/index.ts +1300 -381
- package/extensions/permissions/matcher.ts +425 -74
- package/extensions/permissions/modes.ts +6 -4
- package/extensions/permissions/panel/host.ts +130 -0
- package/extensions/permissions/panel/keys.ts +48 -0
- package/extensions/permissions/panel/render.ts +450 -0
- package/extensions/permissions/panel/state.ts +550 -0
- package/extensions/permissions/powershell-cmdlets.ts +198 -0
- package/extensions/permissions/powershell-paths.ts +197 -0
- package/extensions/permissions/powershell-rules.ts +207 -280
- package/extensions/permissions/powershell-tree.ts +557 -0
- package/extensions/permissions/project-trust.ts +27 -11
- package/extensions/permissions/protected-paths.ts +14 -2
- package/extensions/permissions/session-grant.ts +6 -0
- package/extensions/permissions/settings.ts +166 -31
- package/extensions/permissions/subagent-gate.ts +25 -0
- package/extensions/permissions/workspace.ts +78 -0
- package/extensions/plan-mode/index.ts +156 -69
- package/extensions/plan-mode/reminder.ts +89 -21
- package/extensions/plan-mode/texts.ts +177 -0
- package/extensions/plan-mode/viewer.ts +92 -27
- package/extensions/plugins/counts.ts +3 -3
- package/extensions/plugins/index.ts +61 -46
- package/extensions/plugins/install/install.ts +16 -0
- package/extensions/plugins/marketplace/sync.ts +9 -3
- package/extensions/plugins/marketplace/types.ts +3 -1
- package/extensions/plugins/panel/keys.ts +21 -24
- package/extensions/plugins/panel/render.ts +12 -6
- package/extensions/plugins/shell-expand.ts +107 -0
- package/extensions/plugins/template.ts +32 -15
- package/extensions/powershell/child.ts +7 -0
- package/extensions/powershell/description.ts +38 -6
- package/extensions/powershell/guards.ts +1 -1
- package/extensions/powershell/index.ts +12 -7
- package/extensions/recap/index.ts +65 -60
- package/extensions/recap/prompt.ts +2 -2
- package/extensions/recap/scheduler.ts +3 -5
- package/extensions/search-tools/grep-merge.ts +39 -0
- package/extensions/search-tools/index.ts +0 -0
- package/extensions/send-now/chord.ts +62 -0
- package/extensions/send-now/index.ts +133 -0
- package/extensions/session-title/index.ts +3 -0
- package/extensions/session-title/title.ts +4 -1
- package/extensions/skill/code-review.ts +97 -0
- package/extensions/skill/index.ts +421 -101
- package/extensions/skill/invoke.ts +128 -18
- package/extensions/skill/listing.ts +133 -9
- package/extensions/skill/panel/keys.ts +15 -16
- package/extensions/skill/panel/render.ts +5 -2
- package/extensions/skill/panel/state.ts +12 -1
- package/extensions/subagents/agent-args.ts +39 -0
- package/extensions/subagents/agent-description.ts +132 -0
- package/extensions/subagents/agents.ts +116 -23
- package/extensions/subagents/announce.ts +69 -0
- package/extensions/subagents/default-model.ts +2 -3
- package/extensions/subagents/delegation-steer.ts +4 -4
- package/extensions/subagents/fork-cache.ts +76 -0
- package/extensions/subagents/guide-agent.ts +189 -0
- package/extensions/subagents/hand-back-review.ts +3 -0
- package/extensions/subagents/index.ts +1493 -824
- package/extensions/subagents/live-runs.ts +26 -6
- package/extensions/subagents/model-select.ts +38 -25
- package/extensions/subagents/outcome.ts +2 -2
- package/extensions/subagents/panel-keys.ts +73 -31
- package/extensions/subagents/panel-render.ts +120 -96
- package/extensions/subagents/panel-widget.ts +60 -89
- package/extensions/subagents/runner.ts +108 -80
- package/extensions/subagents/runs.ts +39 -5
- package/extensions/subagents/send-to-main-tool.ts +1 -1
- package/extensions/subagents/session-turns.ts +32 -8
- package/extensions/subagents/shell-panel.ts +36 -178
- package/extensions/subagents/tasks-dialog.ts +170 -0
- package/extensions/subagents/viewport-mirror.ts +95 -0
- package/extensions/subagents/worktree.ts +57 -13
- package/extensions/system-prompt/environment.ts +19 -19
- package/extensions/system-prompt/idle-turn.ts +65 -0
- package/extensions/system-prompt/index.ts +131 -47
- package/extensions/system-prompt/template.ts +24 -50
- package/extensions/system-prompt/tiers/common.ts +23 -64
- package/extensions/system-prompt/tiers/frontier.ts +32 -11
- package/extensions/system-prompt/tiers/low.ts +67 -45
- package/extensions/system-prompt/tiers/mid.ts +96 -38
- package/extensions/system-reminder/index.ts +175 -13
- package/extensions/tasks/descriptions.ts +190 -0
- package/extensions/tasks/index.ts +120 -41
- package/extensions/tasks/store.ts +83 -16
- package/extensions/tool-call-corruption/child.ts +7 -0
- package/extensions/tool-call-corruption/index.ts +237 -0
- package/extensions/tool-search/announce.ts +16 -0
- package/extensions/tool-search/index.ts +189 -41
- package/extensions/tool-style/index.ts +68 -10
- package/extensions/tool-style/write-description.ts +40 -0
- package/extensions/tool-style/write-render.ts +237 -0
- package/extensions/turn-duration/index.ts +7 -3
- package/extensions/turn-duration/line.ts +47 -4
- package/extensions/web/backends.ts +6 -9
- package/extensions/web/description.ts +50 -0
- package/extensions/web/index.ts +118 -53
- package/extensions/web/native-call.ts +15 -0
- package/extensions/web/native-results.ts +41 -0
- package/extensions/web-fetch/description.ts +42 -0
- package/extensions/web-fetch/extract.ts +53 -6
- package/extensions/web-fetch/index.ts +125 -76
- package/extensions/web-fetch/page-content.ts +19 -0
- package/extensions/web-fetch/response.ts +49 -0
- package/extensions/web-fetch/summarize.ts +9 -10
- package/extensions/workflow/agent-session.ts +105 -18
- package/extensions/workflow/args.ts +24 -0
- package/extensions/workflow/description.ts +67 -0
- package/extensions/workflow/globals.ts +17 -3
- package/extensions/workflow/index.ts +145 -162
- package/extensions/workflow/records.ts +1 -0
- package/extensions/workflow/run-manager.ts +29 -6
- package/extensions/workflow/saved-workflows.ts +3 -2
- package/extensions/workflow/types.ts +22 -1
- package/extensions/workflow/viewer.ts +54 -24
- package/extensions/workflow/widget.ts +20 -0
- package/extensions/worktree/descriptions.ts +91 -0
- package/extensions/worktree/guards.ts +316 -54
- package/extensions/worktree/index.ts +121 -39
- package/extensions/worktree/powershell-guards.ts +167 -0
- package/extensions/worktree/rewrite.ts +14 -16
- package/package.json +19 -7
- package/skills/artifact-design/SKILL.md +85 -0
- package/skills/code-review/SKILL.md +20 -20
- package/skills/code-review/cells/arguments-and-flags.md +19 -0
- package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
- package/skills/code-review/cells/high-8-inline.md +122 -0
- package/skills/code-review/cells/low-1-pass-max4.md +27 -0
- package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
- package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
- package/skills/code-review/cells/medium-3x5-verify.md +132 -0
- package/skills/code-review/cells/minimal-prompt.md +32 -0
- package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
- package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
- package/skills/fewer-permission-prompts/SKILL.md +1 -1
- package/skills/loop/SKILL.md +11 -0
- package/skills/security-review/SKILL.md +2 -5
- package/skills/simplify/SKILL.md +7 -5
- package/skills/workflow-authoring/SKILL.md +143 -0
- package/themes/onecode-light.json +1 -1
- package/themes/onecode.json +1 -1
- package/types/app.d.ts +58 -0
- package/types/community-packages.d.ts +26 -1
- package/extensions/auto-mode/recoverability.ts +0 -229
- package/extensions/lib/capability-index.ts +0 -466
- package/extensions/lib/model-facts.generated.json +0 -2675
- package/extensions/lib/model-facts.ts +0 -162
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A streamed tool call's damage. `corrupt` is certain (not one JSON value, a
|
|
3
|
+
* shell command ending inside an open double quote): the call is blocked and
|
|
4
|
+
* the turn stopped. `suspect` has the shape of a cut but also of a valid
|
|
5
|
+
* command (an option followed by one trailing blank): the call goes back to the
|
|
6
|
+
* model once, and a repeat in the same run counts as corrupt.
|
|
7
|
+
*/
|
|
8
|
+
export interface ToolCallDamage {
|
|
9
|
+
kind: "corrupt" | "suspect";
|
|
10
|
+
reason: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// The last word is an option followed by one blank, or a long option with an
|
|
14
|
+
// empty `=` value: `grep -rn "x"` and `--include="*.py"` cut at the escaped
|
|
15
|
+
// quote (findings §61, Morph). A bare `FOO=` is a valid assignment.
|
|
16
|
+
const CUT_AFTER_OPTION = /(?:^|\s)(-{1,2}[A-Za-z][\w-]*)[ \t]$|(?:^|\s)(--[A-Za-z][\w-]*=)$/;
|
|
17
|
+
// Heredocs and here-strings (bash `<<`, `<<<`; PowerShell `@"…"@`, `@'…'@`)
|
|
18
|
+
// carry quotes the scan below cannot pair, so it does not judge them.
|
|
19
|
+
const HERE_DOCUMENT = /<<|@["']/;
|
|
20
|
+
|
|
21
|
+
/** Inspect one tool call's raw streamed arguments before pi's tolerant parsing hides damage. */
|
|
22
|
+
export function toolCallCorruptionReason(toolName: string, rawArguments: string): ToolCallDamage | undefined {
|
|
23
|
+
// A tool with no parameters may stream no argument text at all; pi reads it as {}.
|
|
24
|
+
if (rawArguments.trim() === "") return;
|
|
25
|
+
let args: unknown;
|
|
26
|
+
try {
|
|
27
|
+
args = JSON.parse(rawArguments);
|
|
28
|
+
} catch {
|
|
29
|
+
return { kind: "corrupt", reason: "The raw tool-call arguments are not exactly one JSON value." };
|
|
30
|
+
}
|
|
31
|
+
if (toolName !== "bash" && toolName !== "powershell" && toolName !== "monitor") return;
|
|
32
|
+
if (!args || typeof args !== "object" || !("command" in args) || typeof args.command !== "string") return;
|
|
33
|
+
const cut = CUT_AFTER_OPTION.exec(args.command);
|
|
34
|
+
if (cut) {
|
|
35
|
+
return {
|
|
36
|
+
kind: "suspect",
|
|
37
|
+
reason: `The shell command ends with "${cut[1] ?? cut[2]}" and nothing after it, the shape of arguments cut off before a quoted string.`,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const command = args.command.trimEnd();
|
|
41
|
+
if (!command.endsWith('"') || HERE_DOCUMENT.test(command)) return;
|
|
42
|
+
|
|
43
|
+
let singleQuoted = false;
|
|
44
|
+
let doubleQuoted = false;
|
|
45
|
+
const escape = toolName === "powershell" ? "`" : "\\";
|
|
46
|
+
for (let i = 0; i < command.length; i++) {
|
|
47
|
+
const char = command[i];
|
|
48
|
+
if (singleQuoted) {
|
|
49
|
+
if (char === "'") singleQuoted = false;
|
|
50
|
+
} else if (char === escape) {
|
|
51
|
+
i++;
|
|
52
|
+
} else if (char === "'" && !doubleQuoted) {
|
|
53
|
+
singleQuoted = true;
|
|
54
|
+
} else if (char === '"') {
|
|
55
|
+
doubleQuoted = !doubleQuoted;
|
|
56
|
+
} else if (char === "#" && !doubleQuoted && (i === 0 || /[\s;&|(]/.test(command[i - 1]))) {
|
|
57
|
+
// A comment runs to the end of its line.
|
|
58
|
+
const newline = command.indexOf("\n", i);
|
|
59
|
+
if (newline === -1) break;
|
|
60
|
+
i = newline;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (doubleQuoted) return { kind: "corrupt", reason: "The shell command ends with an unbalanced double quote, indicating truncated tool-call arguments." };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// GLM's native tool-call tags, which a broken upstream parser leaks into the JSON arguments.
|
|
67
|
+
const TOOL_CALL_MARKUP = /<\/arg_value>\s{0,8}<arg_key>|<\/arg_key>\s{0,8}<arg_value>|<\/tool_call>\s{0,8}<tool_call>/g;
|
|
68
|
+
const LONGEST_MARKUP = 40;
|
|
69
|
+
|
|
70
|
+
/** The number of markup matches that marks a streaming call as leaked. */
|
|
71
|
+
export const TOOL_CALL_MARKUP_LIMIT = 2;
|
|
72
|
+
/**
|
|
73
|
+
* The same inside file content (write, edit, notebook_edit), which can quote
|
|
74
|
+
* the markup legitimately (this repo's tests do); a leak there repeats without
|
|
75
|
+
* end and passes it within a few thousand characters.
|
|
76
|
+
*/
|
|
77
|
+
export const CONTENT_MARKUP_LIMIT = 50;
|
|
78
|
+
|
|
79
|
+
// A string value under one of these keys is file content.
|
|
80
|
+
const CONTENT_KEY = /"(?:content|oldText|newText|new_source)"\s*:\s*$/;
|
|
81
|
+
|
|
82
|
+
/** Whether `index` sits in a string value under a content key: the nearest unescaped quote before it opens that value. */
|
|
83
|
+
function inContentValue(text: string, index: number): boolean {
|
|
84
|
+
// lastIndexOf clamps a negative start to 0, so stop before it can repeat a quote at 0.
|
|
85
|
+
for (let quote = index; quote > 0; ) {
|
|
86
|
+
quote = text.lastIndexOf('"', quote - 1);
|
|
87
|
+
if (quote < 0) break;
|
|
88
|
+
let slashes = 0;
|
|
89
|
+
while (text[quote - 1 - slashes] === "\\") slashes++;
|
|
90
|
+
if (slashes % 2 === 0) return CONTENT_KEY.test(text.slice(Math.max(0, quote - 32), quote));
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Count native tool-call markup in `text` from `from` on, for a call whose
|
|
97
|
+
* arguments are still streaming, apart (`contentCount`) inside file content;
|
|
98
|
+
* `next` is where the following scan resumes, so each delta is scanned once.
|
|
99
|
+
*/
|
|
100
|
+
export function scanToolCallMarkup(text: string, from: number): { count: number; contentCount: number; next: number } {
|
|
101
|
+
TOOL_CALL_MARKUP.lastIndex = from;
|
|
102
|
+
let count = 0;
|
|
103
|
+
let contentCount = 0;
|
|
104
|
+
let next = from;
|
|
105
|
+
for (let match = TOOL_CALL_MARKUP.exec(text); match; match = TOOL_CALL_MARKUP.exec(text)) {
|
|
106
|
+
if (inContentValue(text, match.index)) contentCount++;
|
|
107
|
+
else count++;
|
|
108
|
+
next = TOOL_CALL_MARKUP.lastIndex;
|
|
109
|
+
}
|
|
110
|
+
return { count, contentCount, next: Math.max(next, text.length - LONGEST_MARKUP) };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Blank space a tool call may stream after its last argument character before
|
|
115
|
+
* the stream counts as runaway. Only a run holding a raw tab or newline
|
|
116
|
+
* counts: inside a JSON string those are escaped, so such a run is padding
|
|
117
|
+
* between tokens, never argument content (a string may hold any run of spaces).
|
|
118
|
+
*/
|
|
119
|
+
export const RUNAWAY_PADDING_LIMIT = 10_000;
|
|
120
|
+
|
|
121
|
+
export interface TrailingPadding {
|
|
122
|
+
run: number;
|
|
123
|
+
structural: boolean;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** The trailing blank run after one more streamed delta. */
|
|
127
|
+
export function trailingPadding(previous: TrailingPadding | undefined, delta: string): TrailingPadding {
|
|
128
|
+
const last = delta.search(/\S\s*$/);
|
|
129
|
+
if (last < 0) {
|
|
130
|
+
return { run: (previous?.run ?? 0) + delta.length, structural: (previous?.structural ?? false) || /[\t\n\r]/.test(delta) };
|
|
131
|
+
}
|
|
132
|
+
const tail = delta.slice(last + 1);
|
|
133
|
+
return { run: tail.length, structural: /[\t\n\r]/.test(tail) };
|
|
134
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a file tool's `path` argument exactly as pi's own `read`, `edit` and
|
|
3
|
+
* `write` do (`resolveToCwd` in pi-coding-agent's `core/tools/path-utils.js`,
|
|
4
|
+
* over `utils/paths.js normalizePath`), vendored because the package does not
|
|
5
|
+
* export it. Anything that reasons about the file a pi tool will touch (the
|
|
6
|
+
* file tracker's read-before-write and stale-edit guards, our notebook tool,
|
|
7
|
+
* the worktree rewrite of relative paths) must land on the same file, or a spelling pi accepts (`~/x`, `@x`,
|
|
8
|
+
* `file:///…`, a non-breaking space, Git Bash's `/c/…` on Windows) slips past
|
|
9
|
+
* the guard (TOOLS-REVIEW-2026-09-26 M1). Pure: no pi imports.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors pi 0.87.1 to 0.99.2: Unicode spaces fold to a plain space, one
|
|
12
|
+
* leading `@` is dropped, on Windows a Git Bash/MSYS/Cygwin/WSL drive path
|
|
13
|
+
* becomes `C:\…`, `~` and `~/` expand to the home directory (and `~\` on
|
|
14
|
+
* Windows), a `file://` URL becomes its path, and a relative result resolves
|
|
15
|
+
* against `cwd`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { homedir } from "node:os";
|
|
19
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
|
+
|
|
22
|
+
const UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
23
|
+
|
|
24
|
+
/** pi's `normalizeWindowsShellPath`: `/c/x`, `/mnt/c/x`, `/cygdrive/c/x` to `C:\x`. */
|
|
25
|
+
function windowsShellPath(path: string): string {
|
|
26
|
+
if (!path.startsWith("/") || path.startsWith("//") || path.includes("\\")) return path;
|
|
27
|
+
const match = path.match(/^\/(?:mnt\/|cygdrive\/)?([a-z])(?:\/(.*))?$/i);
|
|
28
|
+
if (!match) return path;
|
|
29
|
+
return `${match[1].toUpperCase()}:\\${match[2]?.replaceAll("/", "\\") ?? ""}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ToolPathOptions {
|
|
33
|
+
home?: string;
|
|
34
|
+
platform?: NodeJS.Platform;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* `raw` as pi's file tools read it before resolving it against a cwd: the
|
|
39
|
+
* steps above except the last. Callers that must tell a relative path from an
|
|
40
|
+
* absolute one the way pi will (the worktree rewrite) judge this, not `raw`.
|
|
41
|
+
*/
|
|
42
|
+
export function normalizeToolPath(raw: string, options: ToolPathOptions = {}): string {
|
|
43
|
+
const platform = options.platform ?? process.platform;
|
|
44
|
+
const home = options.home ?? homedir();
|
|
45
|
+
let path = raw.replace(UNICODE_SPACES, " ");
|
|
46
|
+
if (path.startsWith("@")) path = path.slice(1);
|
|
47
|
+
if (platform === "win32") path = windowsShellPath(path);
|
|
48
|
+
if (path === "~") return home;
|
|
49
|
+
if (path.startsWith("~/") || (platform === "win32" && path.startsWith("~\\"))) return join(home, path.slice(2));
|
|
50
|
+
if (/^file:\/\//.test(path)) {
|
|
51
|
+
// A URL this platform cannot map (`file:///x` on Windows has no drive)
|
|
52
|
+
// stays as written: pi's tool then fails on it, and a guard must not throw.
|
|
53
|
+
try {
|
|
54
|
+
return fileURLToPath(path);
|
|
55
|
+
} catch {
|
|
56
|
+
return path;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return path;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The absolute path a pi file tool resolves `raw` to from `cwd`. */
|
|
63
|
+
export function resolveToolPath(raw: string, cwd: string, options: ToolPathOptions = {}): string {
|
|
64
|
+
const path = normalizeToolPath(raw, options);
|
|
65
|
+
return isAbsolute(path) ? resolve(path) : resolve(cwd, path);
|
|
66
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool descriptions that follow the session, as Claude Code's do.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code sends its strongest models short tool descriptions and its
|
|
5
|
+
* weakest the long ones it wrote for Haiku 4.5; its Bash text also changes
|
|
6
|
+
* with the permission mode. One Code keys the same split on the model's tier
|
|
7
|
+
* (`working-docs/decisions/system-prompt.md`, "Four registers"): frontier and
|
|
8
|
+
* workhorse get the short forms, cheap and tiny the long ones, on every
|
|
9
|
+
* provider.
|
|
10
|
+
*
|
|
11
|
+
* pi copies a tool's description when the tool is registered, so a tool whose
|
|
12
|
+
* text depends on the session is registered again when that text changes
|
|
13
|
+
* (`registerVariantTool`). This can also move a tool in pi's active tool
|
|
14
|
+
* order, so only a model-tier change may re-register after the first request.
|
|
15
|
+
* The tier changes with the model, which starts a new provider cache anyway.
|
|
16
|
+
* Permission-mode variants freeze at the first request (bash/index.ts); live
|
|
17
|
+
* changes ride reminders and the permission gate, never the cached tool list.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { ExtensionAPI, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
21
|
+
import type { PromptTier } from "./model-tier.ts";
|
|
22
|
+
import { sessionModelTier } from "./session-model-tier.ts";
|
|
23
|
+
|
|
24
|
+
/** Which of Claude Code's description forms a tool carries. */
|
|
25
|
+
export type DescriptionForm = "short" | "long";
|
|
26
|
+
|
|
27
|
+
/** Claude Code's short forms on frontier and workhorse; its long forms on cheap and tiny. */
|
|
28
|
+
export function descriptionForm(tier: PromptTier): DescriptionForm {
|
|
29
|
+
return tier === "cheap" || tier === "tiny" ? "long" : "short";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Every tool definition shape registerTool accepts; the concrete generics differ per tool.
|
|
33
|
+
type AnyToolDefinition = ToolDefinition<any, any, any>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Register `define(initial)` now, and return a setter that registers the tool
|
|
37
|
+
* again with `define(next)` when `next` differs from the variant in force.
|
|
38
|
+
* Repeated calls with the same variant do nothing, so callers can apply the
|
|
39
|
+
* session's facts on every event that might change them.
|
|
40
|
+
*/
|
|
41
|
+
export function registerVariantTool<V>(pi: ExtensionAPI, initial: V, define: (variant: V) => AnyToolDefinition): (variant: V) => void {
|
|
42
|
+
let current = initial;
|
|
43
|
+
pi.registerTool(define(initial));
|
|
44
|
+
return (next: V) => {
|
|
45
|
+
if (next === current) return;
|
|
46
|
+
current = next;
|
|
47
|
+
pi.registerTool(define(next));
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Register `tool` with the description `describe` gives the session model's
|
|
53
|
+
* form, following it through the session: the one call each tool with a
|
|
54
|
+
* short and a long form makes.
|
|
55
|
+
*/
|
|
56
|
+
export function registerFormTool(pi: ExtensionAPI, tool: AnyToolDefinition, describe: (form: DescriptionForm) => string): void {
|
|
57
|
+
followDescriptionForm(pi, registerVariantTool<DescriptionForm>(pi, "short", (form) => ({ ...tool, description: describe(form) })));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Apply the frozen session tier's form (and the tier it came from) only at session and model boundaries. */
|
|
61
|
+
export function followDescriptionForm(pi: ExtensionAPI, apply: (form: DescriptionForm, tier: PromptTier) => void): void {
|
|
62
|
+
const requestTier = sessionModelTier(pi);
|
|
63
|
+
const follow = () => {
|
|
64
|
+
const tier = requestTier();
|
|
65
|
+
apply(descriptionForm(tier), tier);
|
|
66
|
+
};
|
|
67
|
+
pi.on("session_start", follow);
|
|
68
|
+
pi.on("model_select", follow);
|
|
69
|
+
}
|