@kr78/pi-coding-agent 17.2.10
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/CHANGELOG.md +14861 -0
- package/README.md +35 -0
- package/dist/CHANGELOG-chtdxh1z.md +14861 -0
- package/dist/cli.js +20483 -0
- package/dist/template-c2hyaytt.js +1653 -0
- package/dist/template-f8wx9vfn.css +1355 -0
- package/dist/template-qat058wr.html +55 -0
- package/dist/tool-views.generated-jdfmzwmn.js +35 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +104 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/extensions/README.md +142 -0
- package/examples/extensions/api-demo.ts +78 -0
- package/examples/extensions/chalk-logger.ts +25 -0
- package/examples/extensions/hello.ts +31 -0
- package/examples/extensions/pirate.ts +43 -0
- package/examples/extensions/plan-mode.ts +549 -0
- package/examples/extensions/reload-runtime.ts +38 -0
- package/examples/extensions/thinking-note.ts +13 -0
- package/examples/extensions/tools.ts +145 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +17 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +48 -0
- package/examples/hooks/confirm-destructive.ts +58 -0
- package/examples/hooks/custom-compaction.ts +115 -0
- package/examples/hooks/dirty-repo-guard.ts +51 -0
- package/examples/hooks/file-trigger.ts +40 -0
- package/examples/hooks/git-checkpoint.ts +52 -0
- package/examples/hooks/handoff.ts +149 -0
- package/examples/hooks/permission-gate.ts +33 -0
- package/examples/hooks/protected-paths.ts +29 -0
- package/examples/hooks/qna.ts +118 -0
- package/examples/hooks/status-line.ts +39 -0
- package/examples/sdk/01-minimal.ts +21 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +46 -0
- package/examples/sdk/04-skills.ts +43 -0
- package/examples/sdk/06-extensions.ts +82 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +35 -0
- package/examples/sdk/08-prompt-templates.ts +41 -0
- package/examples/sdk/08-slash-commands.ts +46 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
- package/examples/sdk/11-sessions.ts +47 -0
- package/examples/sdk/12-redis-sessions.ts +54 -0
- package/examples/sdk/13-sql-sessions.ts +61 -0
- package/examples/sdk/README.md +169 -0
- package/package.json +587 -0
- package/scripts/bench-guard.ts +71 -0
- package/scripts/bench-title-models.ts +332 -0
- package/scripts/build-binary.ts +117 -0
- package/scripts/bundle-dist.ts +123 -0
- package/scripts/compile-binary.ts +69 -0
- package/scripts/embed-mupdf-wasm.ts +67 -0
- package/scripts/format-prompts.ts +68 -0
- package/scripts/generate-aria-snapshot.ts +134 -0
- package/scripts/generate-docs-index.ts +58 -0
- package/scripts/generate-share-viewer.ts +34 -0
- package/scripts/legacy-pi-virtual-module.ts +205 -0
- package/scripts/measure-prompt-tokens.ts +63 -0
- package/scripts/omp +51 -0
- package/scripts/omp.ts +19 -0
- package/scripts/security-compare.ts +40 -0
- package/src/advisor/advise-tool.ts +234 -0
- package/src/advisor/config.ts +341 -0
- package/src/advisor/emission-guard.ts +172 -0
- package/src/advisor/index.ts +6 -0
- package/src/advisor/runtime.ts +1412 -0
- package/src/advisor/transcript-recorder.ts +215 -0
- package/src/advisor/watchdog.ts +135 -0
- package/src/async/index.ts +1 -0
- package/src/async/job-manager.ts +847 -0
- package/src/auto-thinking/classifier.ts +220 -0
- package/src/autolearn/controller.ts +152 -0
- package/src/autolearn/managed-skills.ts +255 -0
- package/src/autoresearch/command-resume.md +14 -0
- package/src/autoresearch/dashboard.ts +436 -0
- package/src/autoresearch/git.ts +331 -0
- package/src/autoresearch/helpers.ts +218 -0
- package/src/autoresearch/index.ts +541 -0
- package/src/autoresearch/prompt-setup.md +43 -0
- package/src/autoresearch/prompt.md +103 -0
- package/src/autoresearch/resume-message.md +10 -0
- package/src/autoresearch/state.ts +273 -0
- package/src/autoresearch/storage.ts +700 -0
- package/src/autoresearch/tools/init-experiment.ts +268 -0
- package/src/autoresearch/tools/log-experiment.ts +520 -0
- package/src/autoresearch/tools/run-experiment.ts +407 -0
- package/src/autoresearch/tools/update-notes.ts +109 -0
- package/src/autoresearch/types.ts +168 -0
- package/src/capability/context-file.ts +44 -0
- package/src/capability/extension-module.ts +34 -0
- package/src/capability/extension.ts +47 -0
- package/src/capability/fs.ts +117 -0
- package/src/capability/hook.ts +40 -0
- package/src/capability/index.ts +467 -0
- package/src/capability/instruction.ts +37 -0
- package/src/capability/mcp.ts +115 -0
- package/src/capability/prompt.ts +35 -0
- package/src/capability/rule-buckets.ts +66 -0
- package/src/capability/rule.ts +298 -0
- package/src/capability/settings.ts +34 -0
- package/src/capability/skill.ts +69 -0
- package/src/capability/slash-command.ts +40 -0
- package/src/capability/ssh.ts +41 -0
- package/src/capability/system-prompt.ts +34 -0
- package/src/capability/tool.ts +38 -0
- package/src/capability/types.ts +187 -0
- package/src/cleanse/agent.ts +226 -0
- package/src/cleanse/balance.ts +79 -0
- package/src/cleanse/checkers.ts +996 -0
- package/src/cleanse/index.ts +190 -0
- package/src/cleanse/loop.ts +51 -0
- package/src/cleanse/parsers.ts +726 -0
- package/src/cleanse/progress.ts +50 -0
- package/src/cleanse/prompts/assignment.md +47 -0
- package/src/cleanse/types.ts +72 -0
- package/src/cli/agents-cli.ts +138 -0
- package/src/cli/args.ts +368 -0
- package/src/cli/auth-broker-cli.ts +940 -0
- package/src/cli/auth-gateway-cli.ts +674 -0
- package/src/cli/bench-cli.ts +990 -0
- package/src/cli/browser-relay-cli.ts +119 -0
- package/src/cli/classify-install-target.ts +76 -0
- package/src/cli/claude-trace-cli.ts +795 -0
- package/src/cli/command-help.ts +107 -0
- package/src/cli/commands/init-xdg.ts +27 -0
- package/src/cli/completion-gen.ts +550 -0
- package/src/cli/config-cli.ts +459 -0
- package/src/cli/dry-balance-cli.ts +864 -0
- package/src/cli/extension-flags.ts +48 -0
- package/src/cli/file-processor.ts +132 -0
- package/src/cli/flag-tables.ts +367 -0
- package/src/cli/gallery-cli.ts +272 -0
- package/src/cli/gallery-fixtures/agentic.ts +420 -0
- package/src/cli/gallery-fixtures/codeintel.ts +187 -0
- package/src/cli/gallery-fixtures/edit.ts +254 -0
- package/src/cli/gallery-fixtures/fs.ts +245 -0
- package/src/cli/gallery-fixtures/index.ts +40 -0
- package/src/cli/gallery-fixtures/interaction.ts +46 -0
- package/src/cli/gallery-fixtures/memory.ts +81 -0
- package/src/cli/gallery-fixtures/misc.ts +177 -0
- package/src/cli/gallery-fixtures/search.ts +135 -0
- package/src/cli/gallery-fixtures/shell.ts +241 -0
- package/src/cli/gallery-fixtures/types.ts +57 -0
- package/src/cli/gallery-fixtures/web.ts +158 -0
- package/src/cli/gallery-screenshot.ts +279 -0
- package/src/cli/gc-cli.ts +1566 -0
- package/src/cli/grep-cli.ts +161 -0
- package/src/cli/grievances-cli.ts +256 -0
- package/src/cli/help-extra.ts +89 -0
- package/src/cli/initial-message.ts +58 -0
- package/src/cli/models-cli.ts +385 -0
- package/src/cli/plugin-cli.ts +996 -0
- package/src/cli/profile-alias.ts +369 -0
- package/src/cli/profile-bootstrap.ts +233 -0
- package/src/cli/read-cli.ts +99 -0
- package/src/cli/session-picker.ts +110 -0
- package/src/cli/setup-cli.ts +312 -0
- package/src/cli/setup-model-picker.ts +43 -0
- package/src/cli/shell-cli.ts +176 -0
- package/src/cli/ssh-cli.ts +179 -0
- package/src/cli/startup-cwd.ts +58 -0
- package/src/cli/stats-cli.ts +229 -0
- package/src/cli/thinking-levels.ts +7 -0
- package/src/cli/tiny-models-cli.ts +153 -0
- package/src/cli/ttsr-cli.ts +1013 -0
- package/src/cli/update-cli.ts +1184 -0
- package/src/cli/usage-cli.ts +1084 -0
- package/src/cli/usage-error.ts +7 -0
- package/src/cli/web-search-cli.ts +144 -0
- package/src/cli/worktree-cli.ts +311 -0
- package/src/cli-commands.ts +308 -0
- package/src/cli.ts +428 -0
- package/src/collab/crypto.ts +63 -0
- package/src/collab/display-name.ts +13 -0
- package/src/collab/guest.ts +764 -0
- package/src/collab/host.ts +692 -0
- package/src/collab/protocol.ts +296 -0
- package/src/collab/relay-client.ts +282 -0
- package/src/collab/replication-shrink.ts +111 -0
- package/src/commands/acp.ts +35 -0
- package/src/commands/agents.ts +58 -0
- package/src/commands/auth-broker.ts +100 -0
- package/src/commands/auth-gateway.ts +70 -0
- package/src/commands/bench.ts +64 -0
- package/src/commands/browser-relay.ts +53 -0
- package/src/commands/cleanse.ts +45 -0
- package/src/commands/commit.ts +47 -0
- package/src/commands/complete.ts +67 -0
- package/src/commands/completions.ts +61 -0
- package/src/commands/config.ts +52 -0
- package/src/commands/dry-balance.ts +43 -0
- package/src/commands/gallery.ts +61 -0
- package/src/commands/gc.ts +47 -0
- package/src/commands/grep.ts +49 -0
- package/src/commands/grievances.ts +52 -0
- package/src/commands/install.ts +107 -0
- package/src/commands/join.ts +40 -0
- package/src/commands/launch-help.ts +116 -0
- package/src/commands/launch.ts +34 -0
- package/src/commands/models.ts +61 -0
- package/src/commands/plugin.ts +79 -0
- package/src/commands/read.ts +39 -0
- package/src/commands/say.ts +146 -0
- package/src/commands/setup.ts +68 -0
- package/src/commands/share.ts +71 -0
- package/src/commands/shell.ts +30 -0
- package/src/commands/ssh.ts +61 -0
- package/src/commands/stats.ts +30 -0
- package/src/commands/tiny-models.ts +36 -0
- package/src/commands/token.ts +164 -0
- package/src/commands/ttsr.ts +125 -0
- package/src/commands/update.ts +34 -0
- package/src/commands/usage.ts +55 -0
- package/src/commands/web-search.ts +43 -0
- package/src/commands/worktree.ts +63 -0
- package/src/commit/agentic/agent.ts +322 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +383 -0
- package/src/commit/agentic/lock-files.ts +107 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +25 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +38 -0
- package/src/commit/agentic/state.ts +60 -0
- package/src/commit/agentic/tools/analyze-file.ts +148 -0
- package/src/commit/agentic/tools/git-file-diff.ts +191 -0
- package/src/commit/agentic/tools/git-hunk.ts +52 -0
- package/src/commit/agentic/tools/git-overview.ts +62 -0
- package/src/commit/agentic/tools/index.ts +54 -0
- package/src/commit/agentic/tools/propose-changelog.ts +147 -0
- package/src/commit/agentic/tools/propose-commit.ts +109 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/schemas.ts +11 -0
- package/src/commit/agentic/tools/split-commit.ts +241 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +183 -0
- package/src/commit/analysis/conventional.ts +64 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +107 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +40 -0
- package/src/commit/changelog/generate.ts +101 -0
- package/src/commit/changelog/index.ts +234 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +85 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +69 -0
- package/src/commit/map-reduce/map-phase.ts +193 -0
- package/src/commit/map-reduce/reduce-phase.ts +49 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +95 -0
- package/src/commit/pipeline.ts +244 -0
- package/src/commit/prompts/analysis-system.md +148 -0
- package/src/commit/prompts/analysis-user.md +38 -0
- package/src/commit/prompts/changelog-system.md +50 -0
- package/src/commit/prompts/changelog-user.md +18 -0
- package/src/commit/prompts/file-observer-system.md +24 -0
- package/src/commit/prompts/file-observer-user.md +8 -0
- package/src/commit/prompts/reduce-system.md +50 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +3 -0
- package/src/commit/prompts/summary-system.md +38 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/shared-llm.ts +70 -0
- package/src/commit/types.ts +118 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/commit/utils.ts +58 -0
- package/src/config/api-key-resolver.ts +81 -0
- package/src/config/append-only-context-mode.ts +76 -0
- package/src/config/config-file.ts +347 -0
- package/src/config/inline-tool-descriptors-mode.ts +26 -0
- package/src/config/keybindings.ts +703 -0
- package/src/config/mcp-schema.json +252 -0
- package/src/config/model-discovery.ts +1077 -0
- package/src/config/model-registry.ts +2822 -0
- package/src/config/model-resolver.ts +2115 -0
- package/src/config/model-roles.ts +113 -0
- package/src/config/models-config-schema-bundle.ts +315 -0
- package/src/config/models-config-schema.ts +14 -0
- package/src/config/models-config.ts +130 -0
- package/src/config/prompt-templates.ts +205 -0
- package/src/config/provider-globals.ts +25 -0
- package/src/config/resolve-config-value.ts +95 -0
- package/src/config/service-tier.ts +146 -0
- package/src/config/settings-schema.ts +5887 -0
- package/src/config/settings.ts +2394 -0
- package/src/config.ts +242 -0
- package/src/cursor-bridge-tools.ts +81 -0
- package/src/cursor.ts +960 -0
- package/src/dap/client.ts +1043 -0
- package/src/dap/config.ts +480 -0
- package/src/dap/defaults.json +212 -0
- package/src/dap/index.ts +4 -0
- package/src/dap/session.ts +1841 -0
- package/src/dap/types.ts +611 -0
- package/src/debug/index.ts +584 -0
- package/src/debug/log-formatting.ts +58 -0
- package/src/debug/log-viewer.ts +966 -0
- package/src/debug/profiler.ts +168 -0
- package/src/debug/protocol-probe.ts +267 -0
- package/src/debug/raw-sse-buffer.ts +421 -0
- package/src/debug/raw-sse.ts +312 -0
- package/src/debug/remote-debugger.ts +151 -0
- package/src/debug/report-bundle.ts +411 -0
- package/src/debug/system-info.ts +111 -0
- package/src/debug/terminal-info.ts +124 -0
- package/src/discovery/agent-plugin-format.ts +551 -0
- package/src/discovery/agent-plugins.ts +341 -0
- package/src/discovery/agents-md.ts +67 -0
- package/src/discovery/agents.ts +300 -0
- package/src/discovery/at-imports.ts +273 -0
- package/src/discovery/builtin-defaults.ts +39 -0
- package/src/discovery/builtin-rules/go-add-cleanup.md +33 -0
- package/src/discovery/builtin-rules/go-bench-loop.md +36 -0
- package/src/discovery/builtin-rules/go-exp-promoted.md +40 -0
- package/src/discovery/builtin-rules/go-ioutil.md +37 -0
- package/src/discovery/builtin-rules/go-join-hostport.md +30 -0
- package/src/discovery/builtin-rules/go-new-expr.md +44 -0
- package/src/discovery/builtin-rules/go-rand-v2.md +41 -0
- package/src/discovery/builtin-rules/go-range-int.md +45 -0
- package/src/discovery/builtin-rules/index.ts +74 -0
- package/src/discovery/builtin-rules/rs-box-leak.md +49 -0
- package/src/discovery/builtin-rules/rs-future-prelude.md +24 -0
- package/src/discovery/builtin-rules/rs-lazylock.md +52 -0
- package/src/discovery/builtin-rules/rs-match-ergonomics.md +68 -0
- package/src/discovery/builtin-rules/rs-parking-lot.md +45 -0
- package/src/discovery/builtin-rules/rs-result-type.md +20 -0
- package/src/discovery/builtin-rules/ts-bare-catch.md +39 -0
- package/src/discovery/builtin-rules/ts-import-type.md +43 -0
- package/src/discovery/builtin-rules/ts-no-any.md +66 -0
- package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +45 -0
- package/src/discovery/builtin-rules/ts-no-dynamic-import.md +40 -0
- package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +56 -0
- package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
- package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
- package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
- package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +66 -0
- package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
- package/src/discovery/builtin-rules/ts-set-map.md +28 -0
- package/src/discovery/builtin.ts +945 -0
- package/src/discovery/claude-plugins.ts +640 -0
- package/src/discovery/claude.ts +591 -0
- package/src/discovery/cline.ts +83 -0
- package/src/discovery/codex.ts +553 -0
- package/src/discovery/contained-path.ts +78 -0
- package/src/discovery/cursor.ts +223 -0
- package/src/discovery/gemini.ts +386 -0
- package/src/discovery/github.ts +337 -0
- package/src/discovery/helpers.ts +1183 -0
- package/src/discovery/index.ts +82 -0
- package/src/discovery/mcp-json.ts +182 -0
- package/src/discovery/omp-extension-roots.ts +272 -0
- package/src/discovery/omp-plugins.ts +409 -0
- package/src/discovery/opencode.ts +441 -0
- package/src/discovery/plugin-dir-roots.ts +28 -0
- package/src/discovery/ssh.ts +153 -0
- package/src/discovery/substitute-plugin-root.ts +77 -0
- package/src/discovery/vscode.ts +106 -0
- package/src/discovery/windsurf.ts +149 -0
- package/src/edit/apply-patch/index.ts +87 -0
- package/src/edit/apply-patch/parser.ts +174 -0
- package/src/edit/diff.ts +1008 -0
- package/src/edit/edit-clipboard.ts +23 -0
- package/src/edit/file-snapshot-store.ts +148 -0
- package/src/edit/hashline/block-resolver.ts +33 -0
- package/src/edit/hashline/diff.ts +402 -0
- package/src/edit/hashline/execute.ts +313 -0
- package/src/edit/hashline/filesystem.ts +247 -0
- package/src/edit/hashline/index.ts +5 -0
- package/src/edit/hashline/noop-loop-guard.ts +99 -0
- package/src/edit/hashline/params.ts +12 -0
- package/src/edit/index.ts +699 -0
- package/src/edit/modes/apply-patch.lark +19 -0
- package/src/edit/modes/apply-patch.ts +53 -0
- package/src/edit/modes/patch.ts +1958 -0
- package/src/edit/modes/replace.ts +1191 -0
- package/src/edit/normalize.ts +345 -0
- package/src/edit/notebook.ts +242 -0
- package/src/edit/read-file.ts +25 -0
- package/src/edit/renderer.ts +998 -0
- package/src/edit/snapshot-details.ts +77 -0
- package/src/edit/streaming.ts +710 -0
- package/src/eval/agent-bridge.ts +224 -0
- package/src/eval/backend-helpers.ts +48 -0
- package/src/eval/backend.ts +71 -0
- package/src/eval/bridge-timeout.ts +65 -0
- package/src/eval/budget-bridge.ts +48 -0
- package/src/eval/completion-bridge.ts +212 -0
- package/src/eval/concurrency-bridge.ts +34 -0
- package/src/eval/executor-base.ts +562 -0
- package/src/eval/idle-timeout.ts +91 -0
- package/src/eval/index.ts +6 -0
- package/src/eval/jl/executor.ts +551 -0
- package/src/eval/jl/index.ts +54 -0
- package/src/eval/jl/kernel.ts +236 -0
- package/src/eval/jl/prelude.jl +736 -0
- package/src/eval/jl/prelude.ts +3 -0
- package/src/eval/jl/runner.jl +666 -0
- package/src/eval/jl/runtime.ts +118 -0
- package/src/eval/js/context-manager.ts +872 -0
- package/src/eval/js/executor.ts +178 -0
- package/src/eval/js/index.ts +41 -0
- package/src/eval/js/process-entry.ts +31 -0
- package/src/eval/js/shared/helpers.ts +170 -0
- package/src/eval/js/shared/indirect-eval.ts +30 -0
- package/src/eval/js/shared/local-module-loader.ts +364 -0
- package/src/eval/js/shared/prelude.ts +2 -0
- package/src/eval/js/shared/prelude.txt +294 -0
- package/src/eval/js/shared/rewrite-imports.ts +550 -0
- package/src/eval/js/shared/runtime.ts +590 -0
- package/src/eval/js/shared/types.ts +18 -0
- package/src/eval/js/tool-bridge.ts +163 -0
- package/src/eval/js/worker-core.ts +380 -0
- package/src/eval/js/worker-entry.ts +37 -0
- package/src/eval/js/worker-protocol.ts +47 -0
- package/src/eval/kernel-base.ts +569 -0
- package/src/eval/py/display.ts +71 -0
- package/src/eval/py/executor.ts +643 -0
- package/src/eval/py/index.ts +57 -0
- package/src/eval/py/kernel.ts +235 -0
- package/src/eval/py/prelude.py +673 -0
- package/src/eval/py/prelude.ts +3 -0
- package/src/eval/py/runner.py +1425 -0
- package/src/eval/py/runtime.ts +276 -0
- package/src/eval/py/spawn-options.ts +134 -0
- package/src/eval/py/tool-bridge.ts +201 -0
- package/src/eval/rb/executor.ts +511 -0
- package/src/eval/rb/index.ts +54 -0
- package/src/eval/rb/kernel.ts +231 -0
- package/src/eval/rb/prelude.rb +551 -0
- package/src/eval/rb/prelude.ts +3 -0
- package/src/eval/rb/runner.rb +581 -0
- package/src/eval/rb/runtime.ts +132 -0
- package/src/eval/runtime-env.ts +104 -0
- package/src/eval/session-id.ts +8 -0
- package/src/eval/types.ts +48 -0
- package/src/exa/index.ts +2 -0
- package/src/exa/mcp-client.ts +370 -0
- package/src/exa/types.ts +69 -0
- package/src/exec/bash-executor.ts +627 -0
- package/src/exec/direnv.ts +145 -0
- package/src/exec/exec.ts +53 -0
- package/src/exec/non-interactive-env.ts +118 -0
- package/src/export/custom-share.ts +65 -0
- package/src/export/html/args.ts +20 -0
- package/src/export/html/index.ts +320 -0
- package/src/export/html/share-loader.js +102 -0
- package/src/export/html/template.css +1355 -0
- package/src/export/html/template.html +55 -0
- package/src/export/html/template.js +1653 -0
- package/src/export/html/tool-views.generated.js +35 -0
- package/src/export/html/vendor/highlight.min.js +1213 -0
- package/src/export/html/vendor/marked.min.js +6 -0
- package/src/export/html/web-palette.ts +126 -0
- package/src/export/share.ts +686 -0
- package/src/export/ttsr.ts +590 -0
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
- package/src/extensibility/custom-commands/bundled/review/index.ts +698 -0
- package/src/extensibility/custom-commands/index.ts +2 -0
- package/src/extensibility/custom-commands/loader.ts +242 -0
- package/src/extensibility/custom-commands/types.ts +119 -0
- package/src/extensibility/custom-tools/index.ts +7 -0
- package/src/extensibility/custom-tools/loader.ts +301 -0
- package/src/extensibility/custom-tools/types.ts +287 -0
- package/src/extensibility/custom-tools/wrapper.ts +50 -0
- package/src/extensibility/extensions/compact-handler.ts +40 -0
- package/src/extensibility/extensions/get-commands-handler.ts +78 -0
- package/src/extensibility/extensions/index.ts +16 -0
- package/src/extensibility/extensions/load-errors.ts +13 -0
- package/src/extensibility/extensions/loader.ts +663 -0
- package/src/extensibility/extensions/managed-timers.ts +83 -0
- package/src/extensibility/extensions/model-api.ts +39 -0
- package/src/extensibility/extensions/runner.ts +1396 -0
- package/src/extensibility/extensions/types.ts +1603 -0
- package/src/extensibility/extensions/wrapper.ts +395 -0
- package/src/extensibility/hooks/index.ts +6 -0
- package/src/extensibility/hooks/loader.ts +243 -0
- package/src/extensibility/hooks/runner.ts +425 -0
- package/src/extensibility/hooks/tool-wrapper.ts +124 -0
- package/src/extensibility/hooks/types.ts +612 -0
- package/src/extensibility/legacy-pi-ai-shim.ts +161 -0
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +1460 -0
- package/src/extensibility/legacy-pi-tui-shim.ts +43 -0
- package/src/extensibility/legacy-typebox.ts +101 -0
- package/src/extensibility/plugins/bun-git-cache.ts +91 -0
- package/src/extensibility/plugins/doctor.ts +65 -0
- package/src/extensibility/plugins/git-url.ts +367 -0
- package/src/extensibility/plugins/index.ts +9 -0
- package/src/extensibility/plugins/installer.ts +201 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +2643 -0
- package/src/extensibility/plugins/legacy-pi-virtual-modules.d.ts +4 -0
- package/src/extensibility/plugins/loader.ts +535 -0
- package/src/extensibility/plugins/manager.ts +1142 -0
- package/src/extensibility/plugins/marketplace/cache.ts +136 -0
- package/src/extensibility/plugins/marketplace/fetcher.ts +316 -0
- package/src/extensibility/plugins/marketplace/index.ts +6 -0
- package/src/extensibility/plugins/marketplace/manager.ts +927 -0
- package/src/extensibility/plugins/marketplace/registry.ts +192 -0
- package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
- package/src/extensibility/plugins/marketplace/types.ts +192 -0
- package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
- package/src/extensibility/plugins/parser.ts +107 -0
- package/src/extensibility/plugins/runtime-config.ts +9 -0
- package/src/extensibility/plugins/types.ts +194 -0
- package/src/extensibility/session-handler-types.ts +21 -0
- package/src/extensibility/shared-events.ts +401 -0
- package/src/extensibility/skills.ts +531 -0
- package/src/extensibility/slash-commands.ts +131 -0
- package/src/extensibility/tool-event-input.ts +80 -0
- package/src/extensibility/tool-proxy.ts +28 -0
- package/src/extensibility/utils.ts +192 -0
- package/src/goals/index.ts +3 -0
- package/src/goals/runtime.ts +521 -0
- package/src/goals/state.ts +37 -0
- package/src/goals/tools/goal-tool.ts +251 -0
- package/src/hindsight/backend.ts +354 -0
- package/src/hindsight/bank.ts +156 -0
- package/src/hindsight/client.ts +680 -0
- package/src/hindsight/config.ts +193 -0
- package/src/hindsight/content.ts +266 -0
- package/src/hindsight/index.ts +8 -0
- package/src/hindsight/mental-models.ts +429 -0
- package/src/hindsight/seeds.json +32 -0
- package/src/hindsight/state.ts +530 -0
- package/src/hindsight/transcript.ts +71 -0
- package/src/index.ts +66 -0
- package/src/internal-urls/agent-protocol.ts +180 -0
- package/src/internal-urls/artifact-protocol.ts +151 -0
- package/src/internal-urls/docs-index.ts +102 -0
- package/src/internal-urls/filesystem-resource.ts +34 -0
- package/src/internal-urls/history-protocol.ts +198 -0
- package/src/internal-urls/index.ts +28 -0
- package/src/internal-urls/issue-pr-protocol.ts +594 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/local-protocol.ts +471 -0
- package/src/internal-urls/mcp-protocol.ts +168 -0
- package/src/internal-urls/memory-protocol.ts +380 -0
- package/src/internal-urls/omp-protocol.ts +94 -0
- package/src/internal-urls/parse.ts +103 -0
- package/src/internal-urls/registry-helpers.ts +132 -0
- package/src/internal-urls/router.ts +153 -0
- package/src/internal-urls/rule-protocol.ts +45 -0
- package/src/internal-urls/security-protocol.ts +261 -0
- package/src/internal-urls/skill-protocol.ts +131 -0
- package/src/internal-urls/ssh-protocol.ts +368 -0
- package/src/internal-urls/types.ts +196 -0
- package/src/internal-urls/vault-protocol.ts +940 -0
- package/src/internal-urls/xd-protocol.ts +46 -0
- package/src/irc/bus.ts +380 -0
- package/src/jsonrpc/message-framing.ts +142 -0
- package/src/launch/broker.ts +1368 -0
- package/src/launch/client.ts +521 -0
- package/src/launch/ensure.ts +73 -0
- package/src/launch/paths.ts +14 -0
- package/src/launch/presence.ts +82 -0
- package/src/launch/protocol.ts +448 -0
- package/src/launch/spawn-options.ts +17 -0
- package/src/launch/terminal-output-worker-client.ts +53 -0
- package/src/launch/terminal-output-worker-protocol.ts +11 -0
- package/src/launch/terminal-output-worker.ts +23 -0
- package/src/launch/terminal-output.ts +46 -0
- package/src/lib/xai-http.ts +150 -0
- package/src/live/attestation.ts +91 -0
- package/src/live/controller.ts +517 -0
- package/src/live/prompts/agent-final-message.md +3 -0
- package/src/live/prompts/live-instructions.md +23 -0
- package/src/live/protocol.ts +233 -0
- package/src/live/transport.ts +422 -0
- package/src/live/visualizer.ts +221 -0
- package/src/live/voices.ts +18 -0
- package/src/lsp/client.ts +1465 -0
- package/src/lsp/clients/biome-client.ts +263 -0
- package/src/lsp/clients/index.ts +50 -0
- package/src/lsp/clients/lsp-linter-client.ts +85 -0
- package/src/lsp/clients/swiftlint-client.ts +120 -0
- package/src/lsp/config.ts +549 -0
- package/src/lsp/defaults.json +499 -0
- package/src/lsp/deferred-diagnostics.ts +66 -0
- package/src/lsp/diagnostics-ledger.ts +51 -0
- package/src/lsp/edits.ts +288 -0
- package/src/lsp/format-options.ts +119 -0
- package/src/lsp/index.ts +2821 -0
- package/src/lsp/lspmux.ts +233 -0
- package/src/lsp/mux/daemon.ts +348 -0
- package/src/lsp/mux/protocol.ts +96 -0
- package/src/lsp/mux/server.ts +797 -0
- package/src/lsp/render.ts +668 -0
- package/src/lsp/startup-events.ts +13 -0
- package/src/lsp/types.ts +479 -0
- package/src/lsp/utils.ts +747 -0
- package/src/main.ts +1799 -0
- package/src/markit/NOTICE +32 -0
- package/src/markit/converters/docx.ts +56 -0
- package/src/markit/converters/epub.ts +136 -0
- package/src/markit/converters/pdf/columns.ts +103 -0
- package/src/markit/converters/pdf/extract.ts +598 -0
- package/src/markit/converters/pdf/grid.ts +780 -0
- package/src/markit/converters/pdf/headers.ts +106 -0
- package/src/markit/converters/pdf/index.ts +146 -0
- package/src/markit/converters/pdf/render.ts +501 -0
- package/src/markit/converters/pdf/types.ts +84 -0
- package/src/markit/converters/pptx.ts +325 -0
- package/src/markit/converters/xlsx.ts +173 -0
- package/src/markit/index.ts +2 -0
- package/src/markit/registry.ts +59 -0
- package/src/markit/types.ts +35 -0
- package/src/mcp/client.ts +511 -0
- package/src/mcp/config-writer.ts +377 -0
- package/src/mcp/config.ts +385 -0
- package/src/mcp/index.ts +29 -0
- package/src/mcp/json-rpc.ts +122 -0
- package/src/mcp/loader.ts +125 -0
- package/src/mcp/manager.ts +1524 -0
- package/src/mcp/oauth-credentials.ts +104 -0
- package/src/mcp/oauth-discovery.ts +587 -0
- package/src/mcp/oauth-flow.ts +830 -0
- package/src/mcp/render.ts +214 -0
- package/src/mcp/request-id.ts +24 -0
- package/src/mcp/smithery-auth.ts +108 -0
- package/src/mcp/smithery-connect.ts +154 -0
- package/src/mcp/smithery-registry.ts +500 -0
- package/src/mcp/startup-events.ts +116 -0
- package/src/mcp/timeout.ts +59 -0
- package/src/mcp/tool-bridge.ts +691 -0
- package/src/mcp/tool-cache.ts +117 -0
- package/src/mcp/transports/header-policy.ts +95 -0
- package/src/mcp/transports/http.ts +508 -0
- package/src/mcp/transports/index.ts +7 -0
- package/src/mcp/transports/sse.ts +372 -0
- package/src/mcp/transports/stdio.ts +905 -0
- package/src/mcp/types.ts +467 -0
- package/src/memories/index.ts +1434 -0
- package/src/memories/storage.ts +578 -0
- package/src/memory-backend/index.ts +19 -0
- package/src/memory-backend/local-backend.ts +47 -0
- package/src/memory-backend/messages.ts +19 -0
- package/src/memory-backend/off-backend.ts +25 -0
- package/src/memory-backend/resolve.ts +25 -0
- package/src/memory-backend/runtime.ts +66 -0
- package/src/memory-backend/tool-names.ts +2 -0
- package/src/memory-backend/types.ts +166 -0
- package/src/mnemopi/backend.ts +629 -0
- package/src/mnemopi/config.ts +267 -0
- package/src/mnemopi/embed-client.ts +293 -0
- package/src/mnemopi/embed-protocol.ts +35 -0
- package/src/mnemopi/embed-worker.ts +114 -0
- package/src/mnemopi/index.ts +3 -0
- package/src/mnemopi/state.ts +940 -0
- package/src/modes/acp/acp-agent.ts +2595 -0
- package/src/modes/acp/acp-client-bridge.ts +154 -0
- package/src/modes/acp/acp-event-mapper.ts +1084 -0
- package/src/modes/acp/acp-mode.ts +48 -0
- package/src/modes/acp/index.ts +2 -0
- package/src/modes/acp/terminal-auth.ts +37 -0
- package/src/modes/components/advisor-config.ts +635 -0
- package/src/modes/components/advisor-message.ts +109 -0
- package/src/modes/components/agent-dashboard.ts +1252 -0
- package/src/modes/components/agent-hub-projection.ts +248 -0
- package/src/modes/components/agent-hub-renderer.ts +194 -0
- package/src/modes/components/agent-hub.ts +1126 -0
- package/src/modes/components/agent-transcript-viewer.ts +647 -0
- package/src/modes/components/ask-dialog.ts +1017 -0
- package/src/modes/components/assistant-message.ts +978 -0
- package/src/modes/components/background-tan-message.ts +36 -0
- package/src/modes/components/bash-execution.ts +233 -0
- package/src/modes/components/bordered-loader.ts +41 -0
- package/src/modes/components/btw-panel.ts +161 -0
- package/src/modes/components/cache-invalidation-marker.ts +110 -0
- package/src/modes/components/chat-block.ts +111 -0
- package/src/modes/components/chat-transcript-builder.ts +518 -0
- package/src/modes/components/codex-reset-fireworks.ts +369 -0
- package/src/modes/components/collab-prompt-message.ts +32 -0
- package/src/modes/components/compaction-summary-message.ts +221 -0
- package/src/modes/components/copy-selector.ts +218 -0
- package/src/modes/components/countdown-timer.ts +75 -0
- package/src/modes/components/custom-editor.ts +1036 -0
- package/src/modes/components/custom-message.ts +70 -0
- package/src/modes/components/diff.ts +254 -0
- package/src/modes/components/dynamic-border.ts +37 -0
- package/src/modes/components/error-banner.ts +33 -0
- package/src/modes/components/eval-execution.ts +169 -0
- package/src/modes/components/execution-shared.ts +101 -0
- package/src/modes/components/extensions/extension-dashboard.ts +492 -0
- package/src/modes/components/extensions/extension-list.ts +507 -0
- package/src/modes/components/extensions/index.ts +9 -0
- package/src/modes/components/extensions/inspector-panel.ts +326 -0
- package/src/modes/components/extensions/state-manager.ts +648 -0
- package/src/modes/components/extensions/types.ts +186 -0
- package/src/modes/components/footer.ts +274 -0
- package/src/modes/components/history-search.ts +268 -0
- package/src/modes/components/hook-editor.ts +213 -0
- package/src/modes/components/hook-input.ts +87 -0
- package/src/modes/components/hook-message.ts +67 -0
- package/src/modes/components/hook-selector.ts +691 -0
- package/src/modes/components/index.ts +42 -0
- package/src/modes/components/keybinding-hints.ts +56 -0
- package/src/modes/components/late-diagnostics-message.ts +60 -0
- package/src/modes/components/login-dialog.ts +197 -0
- package/src/modes/components/logout-account-selector.ts +130 -0
- package/src/modes/components/mcp-add-wizard.ts +1413 -0
- package/src/modes/components/message-frame.ts +98 -0
- package/src/modes/components/model-browser.ts +888 -0
- package/src/modes/components/model-hub.ts +2014 -0
- package/src/modes/components/model-picker.ts +237 -0
- package/src/modes/components/move-overlay.ts +293 -0
- package/src/modes/components/oauth-selector.ts +474 -0
- package/src/modes/components/omfg-panel.ts +141 -0
- package/src/modes/components/overlay-box.ts +109 -0
- package/src/modes/components/pause-screen.ts +208 -0
- package/src/modes/components/plan-review-overlay.ts +1226 -0
- package/src/modes/components/plan-toc.ts +138 -0
- package/src/modes/components/plugin-selector.ts +100 -0
- package/src/modes/components/plugin-settings.ts +745 -0
- package/src/modes/components/queue-mode-selector.ts +61 -0
- package/src/modes/components/read-tool-group.ts +856 -0
- package/src/modes/components/reset-usage-selector.ts +161 -0
- package/src/modes/components/segment-track.ts +89 -0
- package/src/modes/components/select-list-mouse-routing.ts +35 -0
- package/src/modes/components/selector-helpers.ts +129 -0
- package/src/modes/components/session-account-selector.ts +62 -0
- package/src/modes/components/session-selector.ts +1035 -0
- package/src/modes/components/settings-defs.ts +267 -0
- package/src/modes/components/settings-selector.ts +1445 -0
- package/src/modes/components/show-images-selector.ts +50 -0
- package/src/modes/components/skill-message.ts +110 -0
- package/src/modes/components/snapcompact-shape-preview-doc.md +14 -0
- package/src/modes/components/snapcompact-shape-preview.ts +192 -0
- package/src/modes/components/status-line/component.ts +1843 -0
- package/src/modes/components/status-line/context-thresholds.ts +86 -0
- package/src/modes/components/status-line/git-utils.ts +42 -0
- package/src/modes/components/status-line/index.ts +5 -0
- package/src/modes/components/status-line/presets.ts +106 -0
- package/src/modes/components/status-line/segments.ts +710 -0
- package/src/modes/components/status-line/separators.ts +55 -0
- package/src/modes/components/status-line/types.ts +159 -0
- package/src/modes/components/stripped-tool-calls-placeholder.ts +35 -0
- package/src/modes/components/theme-selector.ts +68 -0
- package/src/modes/components/thinking-selector.ts +57 -0
- package/src/modes/components/tiny-title-download-progress.ts +90 -0
- package/src/modes/components/tips.txt +26 -0
- package/src/modes/components/todo-reminder.ts +43 -0
- package/src/modes/components/tool-execution.ts +1467 -0
- package/src/modes/components/transcript-container.ts +527 -0
- package/src/modes/components/tree-selector.ts +1006 -0
- package/src/modes/components/ttsr-notification.ts +123 -0
- package/src/modes/components/usage-row.ts +52 -0
- package/src/modes/components/user-message-selector.ts +227 -0
- package/src/modes/components/user-message.ts +167 -0
- package/src/modes/components/visual-truncate.ts +63 -0
- package/src/modes/components/welcome.ts +578 -0
- package/src/modes/controllers/btw-controller.ts +246 -0
- package/src/modes/controllers/command-controller-shared.ts +109 -0
- package/src/modes/controllers/command-controller.ts +2024 -0
- package/src/modes/controllers/event-controller.ts +2173 -0
- package/src/modes/controllers/extension-ui-controller.ts +1243 -0
- package/src/modes/controllers/input-controller.ts +2037 -0
- package/src/modes/controllers/live-command-controller.ts +261 -0
- package/src/modes/controllers/mcp-command-controller.ts +2552 -0
- package/src/modes/controllers/omfg-controller.ts +287 -0
- package/src/modes/controllers/omfg-rule.ts +647 -0
- package/src/modes/controllers/selector-controller.ts +2058 -0
- package/src/modes/controllers/session-focus-controller.ts +117 -0
- package/src/modes/controllers/ssh-command-controller.ts +385 -0
- package/src/modes/controllers/streaming-reveal.ts +399 -0
- package/src/modes/controllers/tan-command-controller.ts +243 -0
- package/src/modes/controllers/todo-command-controller.ts +487 -0
- package/src/modes/controllers/tool-args-reveal.ts +591 -0
- package/src/modes/data/emojis.json +1 -0
- package/src/modes/emoji-autocomplete.ts +285 -0
- package/src/modes/github-ref-autocomplete.ts +75 -0
- package/src/modes/gradient-highlight.ts +99 -0
- package/src/modes/image-references.ts +137 -0
- package/src/modes/index.ts +10 -0
- package/src/modes/interactive-mode.ts +5055 -0
- package/src/modes/internal-url-autocomplete.ts +158 -0
- package/src/modes/loop-limit.ts +192 -0
- package/src/modes/magic-keyword-boundary.ts +23 -0
- package/src/modes/magic-keywords.ts +42 -0
- package/src/modes/markdown-prose.ts +247 -0
- package/src/modes/oauth-manual-input.ts +69 -0
- package/src/modes/orchestrate.ts +43 -0
- package/src/modes/print-mode.ts +282 -0
- package/src/modes/prompt-action-autocomplete.ts +322 -0
- package/src/modes/queue-input.ts +132 -0
- package/src/modes/rpc/host-tools.ts +204 -0
- package/src/modes/rpc/host-uris.ts +241 -0
- package/src/modes/rpc/rpc-client.ts +1213 -0
- package/src/modes/rpc/rpc-frame.ts +316 -0
- package/src/modes/rpc/rpc-input.ts +38 -0
- package/src/modes/rpc/rpc-messages.ts +127 -0
- package/src/modes/rpc/rpc-mode.ts +1519 -0
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +544 -0
- package/src/modes/running-subagent-badge.ts +13 -0
- package/src/modes/runtime-init.ts +144 -0
- package/src/modes/session-observer-registry.ts +223 -0
- package/src/modes/session-teardown.ts +82 -0
- package/src/modes/setup-version.ts +11 -0
- package/src/modes/setup-wizard/index.ts +103 -0
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +103 -0
- package/src/modes/setup-wizard/scenes/model.ts +132 -0
- package/src/modes/setup-wizard/scenes/outro.ts +35 -0
- package/src/modes/setup-wizard/scenes/providers.ts +105 -0
- package/src/modes/setup-wizard/scenes/sign-in.ts +312 -0
- package/src/modes/setup-wizard/scenes/splash.ts +201 -0
- package/src/modes/setup-wizard/scenes/theme.ts +330 -0
- package/src/modes/setup-wizard/scenes/types.ts +65 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +153 -0
- package/src/modes/setup-wizard/startup-splash.ts +107 -0
- package/src/modes/setup-wizard/wizard-overlay.ts +335 -0
- package/src/modes/shared.ts +49 -0
- package/src/modes/skill-command.ts +91 -0
- package/src/modes/theme/dark.json +95 -0
- package/src/modes/theme/defaults/alabaster.json +93 -0
- package/src/modes/theme/defaults/amethyst.json +96 -0
- package/src/modes/theme/defaults/anthracite.json +93 -0
- package/src/modes/theme/defaults/basalt.json +91 -0
- package/src/modes/theme/defaults/birch.json +95 -0
- package/src/modes/theme/defaults/dark-abyss.json +91 -0
- package/src/modes/theme/defaults/dark-arctic.json +104 -0
- package/src/modes/theme/defaults/dark-aurora.json +95 -0
- package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
- package/src/modes/theme/defaults/dark-cavern.json +91 -0
- package/src/modes/theme/defaults/dark-copper.json +95 -0
- package/src/modes/theme/defaults/dark-cosmos.json +90 -0
- package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
- package/src/modes/theme/defaults/dark-dracula.json +98 -0
- package/src/modes/theme/defaults/dark-eclipse.json +91 -0
- package/src/modes/theme/defaults/dark-ember.json +95 -0
- package/src/modes/theme/defaults/dark-equinox.json +90 -0
- package/src/modes/theme/defaults/dark-forest.json +96 -0
- package/src/modes/theme/defaults/dark-github.json +105 -0
- package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
- package/src/modes/theme/defaults/dark-lavender.json +95 -0
- package/src/modes/theme/defaults/dark-lunar.json +89 -0
- package/src/modes/theme/defaults/dark-midnight.json +95 -0
- package/src/modes/theme/defaults/dark-monochrome.json +94 -0
- package/src/modes/theme/defaults/dark-monokai.json +98 -0
- package/src/modes/theme/defaults/dark-nebula.json +90 -0
- package/src/modes/theme/defaults/dark-nord.json +97 -0
- package/src/modes/theme/defaults/dark-ocean.json +101 -0
- package/src/modes/theme/defaults/dark-one.json +100 -0
- package/src/modes/theme/defaults/dark-poimandres.json +143 -0
- package/src/modes/theme/defaults/dark-rainforest.json +91 -0
- package/src/modes/theme/defaults/dark-reef.json +91 -0
- package/src/modes/theme/defaults/dark-retro.json +92 -0
- package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
- package/src/modes/theme/defaults/dark-sakura.json +95 -0
- package/src/modes/theme/defaults/dark-slate.json +95 -0
- package/src/modes/theme/defaults/dark-solarized.json +97 -0
- package/src/modes/theme/defaults/dark-solstice.json +90 -0
- package/src/modes/theme/defaults/dark-starfall.json +91 -0
- package/src/modes/theme/defaults/dark-sunset.json +99 -0
- package/src/modes/theme/defaults/dark-swamp.json +90 -0
- package/src/modes/theme/defaults/dark-synthwave.json +103 -0
- package/src/modes/theme/defaults/dark-taiga.json +91 -0
- package/src/modes/theme/defaults/dark-terminal.json +95 -0
- package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
- package/src/modes/theme/defaults/dark-tundra.json +91 -0
- package/src/modes/theme/defaults/dark-twilight.json +91 -0
- package/src/modes/theme/defaults/dark-volcanic.json +91 -0
- package/src/modes/theme/defaults/graphite.json +92 -0
- package/src/modes/theme/defaults/index.ts +199 -0
- package/src/modes/theme/defaults/light-arctic.json +107 -0
- package/src/modes/theme/defaults/light-aurora-day.json +91 -0
- package/src/modes/theme/defaults/light-canyon.json +91 -0
- package/src/modes/theme/defaults/light-catppuccin.json +106 -0
- package/src/modes/theme/defaults/light-cirrus.json +90 -0
- package/src/modes/theme/defaults/light-coral.json +95 -0
- package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
- package/src/modes/theme/defaults/light-dawn.json +90 -0
- package/src/modes/theme/defaults/light-dunes.json +91 -0
- package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
- package/src/modes/theme/defaults/light-forest.json +100 -0
- package/src/modes/theme/defaults/light-frost.json +95 -0
- package/src/modes/theme/defaults/light-github.json +115 -0
- package/src/modes/theme/defaults/light-glacier.json +91 -0
- package/src/modes/theme/defaults/light-gruvbox.json +108 -0
- package/src/modes/theme/defaults/light-haze.json +90 -0
- package/src/modes/theme/defaults/light-honeycomb.json +95 -0
- package/src/modes/theme/defaults/light-lagoon.json +91 -0
- package/src/modes/theme/defaults/light-lavender.json +95 -0
- package/src/modes/theme/defaults/light-meadow.json +91 -0
- package/src/modes/theme/defaults/light-mint.json +95 -0
- package/src/modes/theme/defaults/light-monochrome.json +101 -0
- package/src/modes/theme/defaults/light-ocean.json +99 -0
- package/src/modes/theme/defaults/light-one.json +99 -0
- package/src/modes/theme/defaults/light-opal.json +91 -0
- package/src/modes/theme/defaults/light-orchard.json +91 -0
- package/src/modes/theme/defaults/light-paper.json +95 -0
- package/src/modes/theme/defaults/light-poimandres.json +143 -0
- package/src/modes/theme/defaults/light-prism.json +90 -0
- package/src/modes/theme/defaults/light-retro.json +98 -0
- package/src/modes/theme/defaults/light-sand.json +95 -0
- package/src/modes/theme/defaults/light-savanna.json +91 -0
- package/src/modes/theme/defaults/light-solarized.json +102 -0
- package/src/modes/theme/defaults/light-soleil.json +90 -0
- package/src/modes/theme/defaults/light-sunset.json +99 -0
- package/src/modes/theme/defaults/light-synthwave.json +98 -0
- package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
- package/src/modes/theme/defaults/light-wetland.json +91 -0
- package/src/modes/theme/defaults/light-zenith.json +89 -0
- package/src/modes/theme/defaults/limestone.json +94 -0
- package/src/modes/theme/defaults/mahogany.json +97 -0
- package/src/modes/theme/defaults/marble.json +93 -0
- package/src/modes/theme/defaults/obsidian.json +91 -0
- package/src/modes/theme/defaults/onyx.json +91 -0
- package/src/modes/theme/defaults/pearl.json +93 -0
- package/src/modes/theme/defaults/porcelain.json +91 -0
- package/src/modes/theme/defaults/quartz.json +96 -0
- package/src/modes/theme/defaults/sandstone.json +95 -0
- package/src/modes/theme/defaults/titanium.json +90 -0
- package/src/modes/theme/light.json +93 -0
- package/src/modes/theme/mermaid-cache.ts +92 -0
- package/src/modes/theme/shimmer.ts +305 -0
- package/src/modes/theme/theme-schema.json +463 -0
- package/src/modes/theme/theme.ts +3171 -0
- package/src/modes/turn-budget.ts +31 -0
- package/src/modes/types.ts +494 -0
- package/src/modes/ultrathink.ts +42 -0
- package/src/modes/utils/context-usage.ts +518 -0
- package/src/modes/utils/copy-targets.ts +378 -0
- package/src/modes/utils/hotkeys-markdown.ts +65 -0
- package/src/modes/utils/interactive-context-helpers.ts +31 -0
- package/src/modes/utils/keybinding-matchers.ts +86 -0
- package/src/modes/utils/tools-markdown.ts +31 -0
- package/src/modes/utils/transcript-render-helpers.ts +253 -0
- package/src/modes/utils/ui-helpers.ts +976 -0
- package/src/modes/warp-events.ts +232 -0
- package/src/modes/workflow.ts +55 -0
- package/src/plan-mode/approved-plan.ts +194 -0
- package/src/plan-mode/model-transition.ts +51 -0
- package/src/plan-mode/plan-files.ts +40 -0
- package/src/plan-mode/plan-handoff.ts +37 -0
- package/src/plan-mode/plan-protection.ts +31 -0
- package/src/plan-mode/state.ts +6 -0
- package/src/priority.json +60 -0
- package/src/prompts/advisor/active-repo-watchdog.md +6 -0
- package/src/prompts/advisor/advise-tool.md +3 -0
- package/src/prompts/advisor/context-files.md +8 -0
- package/src/prompts/advisor/system.md +98 -0
- package/src/prompts/agents/designer.md +74 -0
- package/src/prompts/agents/frontmatter.md +12 -0
- package/src/prompts/agents/init.md +33 -0
- package/src/prompts/agents/librarian.md +119 -0
- package/src/prompts/agents/reviewer.md +139 -0
- package/src/prompts/agents/scout.md +58 -0
- package/src/prompts/agents/security-reviewer.md +75 -0
- package/src/prompts/agents/task.md +17 -0
- package/src/prompts/bench/cache-prefix-chunk.md +1 -0
- package/src/prompts/bench/cache-prefix.md +3 -0
- package/src/prompts/bench/cache-suffix.md +1 -0
- package/src/prompts/bench.md +6 -0
- package/src/prompts/ci-green-request.md +36 -0
- package/src/prompts/dry-balance-bench.md +8 -0
- package/src/prompts/goals/goal-budget-limit.md +16 -0
- package/src/prompts/goals/goal-continuation.md +28 -0
- package/src/prompts/goals/goal-mode-active.md +23 -0
- package/src/prompts/goals/goal-mode-context.md +4 -0
- package/src/prompts/goals/goal-todo-context.md +12 -0
- package/src/prompts/goals/guided-goal-interview.md +43 -0
- package/src/prompts/memories/consolidation.md +30 -0
- package/src/prompts/memories/consolidation_system.md +4 -0
- package/src/prompts/memories/read-path.md +17 -0
- package/src/prompts/memories/stage_one_input.md +6 -0
- package/src/prompts/memories/stage_one_system.md +21 -0
- package/src/prompts/review-custom-request.md +21 -0
- package/src/prompts/review-headless-request.md +16 -0
- package/src/prompts/review-request.md +68 -0
- package/src/prompts/security/scan-coordinator.md +7 -0
- package/src/prompts/security/scan-request.md +21 -0
- package/src/prompts/security/validate-request.md +8 -0
- package/src/prompts/session/launch-completion.md +1 -0
- package/src/prompts/skills/autoload.md +8 -0
- package/src/prompts/skills/user-invocation.md +11 -0
- package/src/prompts/steering/parent-irc.md +5 -0
- package/src/prompts/steering/user-interjection.md +6 -0
- package/src/prompts/system/active-repo-context.md +4 -0
- package/src/prompts/system/agent-creation-architect.md +50 -0
- package/src/prompts/system/agent-creation-user.md +6 -0
- package/src/prompts/system/auto-continue.md +1 -0
- package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
- package/src/prompts/system/auto-thinking-difficulty.md +14 -0
- package/src/prompts/system/autolearn-guidance-learn.md +1 -0
- package/src/prompts/system/autolearn-guidance.md +7 -0
- package/src/prompts/system/autolearn-nudge-autocontinue.md +5 -0
- package/src/prompts/system/background-tan-dispatch.md +8 -0
- package/src/prompts/system/btw-user.md +8 -0
- package/src/prompts/system/commit-message-system.md +14 -0
- package/src/prompts/system/computer-safety.md +14 -0
- package/src/prompts/system/custom-system-prompt.md +64 -0
- package/src/prompts/system/eager-task.md +7 -0
- package/src/prompts/system/eager-todo.md +18 -0
- package/src/prompts/system/empty-stop-retry.md +4 -0
- package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
- package/src/prompts/system/interrupted-thinking.md +7 -0
- package/src/prompts/system/irc-autoreply.md +6 -0
- package/src/prompts/system/irc-incoming.md +9 -0
- package/src/prompts/system/manual-continue.md +7 -0
- package/src/prompts/system/mcp-xdev-guidance.md +11 -0
- package/src/prompts/system/memory-consolidation-system.md +8 -0
- package/src/prompts/system/memory-extraction-system.md +26 -0
- package/src/prompts/system/mid-run-todo-nudge.md +3 -0
- package/src/prompts/system/omfg-user.md +50 -0
- package/src/prompts/system/orchestrate-notice.md +40 -0
- package/src/prompts/system/personalities/default.md +18 -0
- package/src/prompts/system/personalities/friendly.md +17 -0
- package/src/prompts/system/personalities/pragmatic.md +15 -0
- package/src/prompts/system/plan-mode-active.md +125 -0
- package/src/prompts/system/plan-mode-approved.md +22 -0
- package/src/prompts/system/plan-mode-compact-instructions.md +17 -0
- package/src/prompts/system/plan-mode-reference.md +10 -0
- package/src/prompts/system/plan-mode-subagent.md +33 -0
- package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
- package/src/prompts/system/plan-yolo-handoff.md +5 -0
- package/src/prompts/system/prewalk-checklist.md +7 -0
- package/src/prompts/system/prewalk-continue.md +1 -0
- package/src/prompts/system/prewalk-plan.md +13 -0
- package/src/prompts/system/project-prompt.md +61 -0
- package/src/prompts/system/recap-user.md +9 -0
- package/src/prompts/system/resolve-device-reminder.md +3 -0
- package/src/prompts/system/rewind-report.md +6 -0
- package/src/prompts/system/side-channel-no-tools.md +3 -0
- package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-context-stub.md +1 -0
- package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-system-stub.md +1 -0
- package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
- package/src/prompts/system/speech-rewrite.md +15 -0
- package/src/prompts/system/subagent-async-pending.md +6 -0
- package/src/prompts/system/subagent-system-prompt.md +73 -0
- package/src/prompts/system/subagent-user-prompt.md +3 -0
- package/src/prompts/system/subagent-yield-reminder.md +23 -0
- package/src/prompts/system/system-prompt.md +263 -0
- package/src/prompts/system/tan-context-switch.md +17 -0
- package/src/prompts/system/task-label.md +23 -0
- package/src/prompts/system/thinking-loop-redirect.md +10 -0
- package/src/prompts/system/title-marker-instruction.md +1 -0
- package/src/prompts/system/title-system.md +16 -0
- package/src/prompts/system/tool-call-loop-redirect.md +8 -0
- package/src/prompts/system/ttsr-interrupt.md +7 -0
- package/src/prompts/system/ttsr-tool-reminder.md +5 -0
- package/src/prompts/system/ultrathink-notice.md +3 -0
- package/src/prompts/system/unexpected-stop-classifier.md +17 -0
- package/src/prompts/system/unexpected-stop-retry.md +4 -0
- package/src/prompts/system/vibe-mode-active.md +26 -0
- package/src/prompts/system/web-search.md +25 -0
- package/src/prompts/system/workflow-notice.md +112 -0
- package/src/prompts/system/xdev-mount-notice.md +20 -0
- package/src/prompts/tools/apply-patch.md +65 -0
- package/src/prompts/tools/ask.md +22 -0
- package/src/prompts/tools/ast-edit.md +11 -0
- package/src/prompts/tools/ast-grep.md +19 -0
- package/src/prompts/tools/async-result.md +8 -0
- package/src/prompts/tools/bash.md +23 -0
- package/src/prompts/tools/browser.md +29 -0
- package/src/prompts/tools/checkpoint.md +15 -0
- package/src/prompts/tools/computer.md +26 -0
- package/src/prompts/tools/debug.md +3 -0
- package/src/prompts/tools/eval.md +45 -0
- package/src/prompts/tools/github.md +22 -0
- package/src/prompts/tools/glob.md +16 -0
- package/src/prompts/tools/goal.md +11 -0
- package/src/prompts/tools/grep.md +13 -0
- package/src/prompts/tools/hub.md +34 -0
- package/src/prompts/tools/image-attachment-describe-system.md +8 -0
- package/src/prompts/tools/image-attachment-describe.md +10 -0
- package/src/prompts/tools/image-gen.md +7 -0
- package/src/prompts/tools/inspect-image-system.md +20 -0
- package/src/prompts/tools/inspect-image.md +22 -0
- package/src/prompts/tools/learn.md +7 -0
- package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
- package/src/prompts/tools/lsp.md +19 -0
- package/src/prompts/tools/manage-skill.md +9 -0
- package/src/prompts/tools/memory-edit.md +12 -0
- package/src/prompts/tools/patch.md +57 -0
- package/src/prompts/tools/read.md +27 -0
- package/src/prompts/tools/recall.md +7 -0
- package/src/prompts/tools/reflect.md +5 -0
- package/src/prompts/tools/replace.md +30 -0
- package/src/prompts/tools/retain.md +6 -0
- package/src/prompts/tools/rewind.md +14 -0
- package/src/prompts/tools/security-publish.md +1 -0
- package/src/prompts/tools/security-scan.md +1 -0
- package/src/prompts/tools/task-async-contract.md +1 -0
- package/src/prompts/tools/task-summary.md +20 -0
- package/src/prompts/tools/task.md +83 -0
- package/src/prompts/tools/todo.md +42 -0
- package/src/prompts/tools/vibe-kill.md +3 -0
- package/src/prompts/tools/vibe-list.md +3 -0
- package/src/prompts/tools/vibe-send.md +9 -0
- package/src/prompts/tools/vibe-spawn.md +10 -0
- package/src/prompts/tools/vibe-turn-result.md +19 -0
- package/src/prompts/tools/vibe-wait.md +8 -0
- package/src/prompts/tools/web-search.md +8 -0
- package/src/prompts/tools/write.md +14 -0
- package/src/registry/agent-lifecycle.ts +505 -0
- package/src/registry/agent-registry.ts +287 -0
- package/src/registry/persisted-agents.ts +423 -0
- package/src/sdk.ts +3820 -0
- package/src/secrets/index.ts +375 -0
- package/src/secrets/obfuscator.ts +2629 -0
- package/src/secrets/regex.ts +21 -0
- package/src/security/auth.ts +98 -0
- package/src/security/cloud.ts +686 -0
- package/src/security/comparison.ts +255 -0
- package/src/security/contracts/ids.ts +111 -0
- package/src/security/contracts/index.ts +4 -0
- package/src/security/contracts/schemas.ts +219 -0
- package/src/security/contracts/types.ts +254 -0
- package/src/security/contracts/validation.ts +69 -0
- package/src/security/coordinator.ts +708 -0
- package/src/security/importers/codex-security.ts +387 -0
- package/src/security/importers/index.ts +2 -0
- package/src/security/importers/sarif.ts +357 -0
- package/src/security/index.ts +13 -0
- package/src/security/preflight.ts +405 -0
- package/src/security/provenance.ts +106 -0
- package/src/security/publication.ts +326 -0
- package/src/security/remediation.ts +93 -0
- package/src/security/resource-output.ts +50 -0
- package/src/security/sarif.ts +78 -0
- package/src/security/store.ts +430 -0
- package/src/session/acp-permission-gate.ts +165 -0
- package/src/session/agent-session-events.ts +67 -0
- package/src/session/agent-session-types.ts +407 -0
- package/src/session/agent-session.ts +9000 -0
- package/src/session/agent-storage.ts +807 -0
- package/src/session/artifacts.ts +154 -0
- package/src/session/async-job-delivery.ts +82 -0
- package/src/session/auth-broker-config.ts +92 -0
- package/src/session/auth-storage.ts +25 -0
- package/src/session/bash-runner.ts +326 -0
- package/src/session/blob-store.ts +295 -0
- package/src/session/checkpoint-entries.ts +81 -0
- package/src/session/claude-session-store.ts +426 -0
- package/src/session/client-bridge.ts +85 -0
- package/src/session/codex-auto-reset.ts +673 -0
- package/src/session/codex-session-store.ts +673 -0
- package/src/session/compact-modes.ts +105 -0
- package/src/session/credential-pin.ts +93 -0
- package/src/session/eval-runner.ts +219 -0
- package/src/session/exit-diagnostics.ts +310 -0
- package/src/session/foreign-session-import.ts +52 -0
- package/src/session/foreign-session-jsonl.ts +29 -0
- package/src/session/foreign-session-store.ts +26 -0
- package/src/session/history-storage.ts +329 -0
- package/src/session/indexed-session-storage.ts +553 -0
- package/src/session/irc-bridge.ts +203 -0
- package/src/session/launch-completion.ts +37 -0
- package/src/session/messages.ts +1304 -0
- package/src/session/model-controls.ts +757 -0
- package/src/session/prewalk.ts +279 -0
- package/src/session/provider-image-budget.ts +86 -0
- package/src/session/queued-messages.ts +99 -0
- package/src/session/redis-session-storage.ts +257 -0
- package/src/session/retry-fallback-chains.ts +455 -0
- package/src/session/role-models.ts +85 -0
- package/src/session/session-advisors.ts +1896 -0
- package/src/session/session-context.ts +584 -0
- package/src/session/session-dump-format.ts +216 -0
- package/src/session/session-entries.ts +306 -0
- package/src/session/session-handoff.ts +325 -0
- package/src/session/session-history-format.ts +459 -0
- package/src/session/session-listing.ts +715 -0
- package/src/session/session-loader.ts +362 -0
- package/src/session/session-maintenance.ts +3115 -0
- package/src/session/session-manager.ts +2747 -0
- package/src/session/session-memory.ts +222 -0
- package/src/session/session-metadata.ts +53 -0
- package/src/session/session-migrations.ts +78 -0
- package/src/session/session-paths.ts +280 -0
- package/src/session/session-persistence.ts +293 -0
- package/src/session/session-provider-boundary.ts +306 -0
- package/src/session/session-stats.ts +349 -0
- package/src/session/session-storage.ts +774 -0
- package/src/session/session-title-slot.ts +141 -0
- package/src/session/session-tools.ts +1385 -0
- package/src/session/session-workspace.ts +53 -0
- package/src/session/settings-stream-fn.ts +79 -0
- package/src/session/shake-types.ts +43 -0
- package/src/session/snapcompact-inline.ts +545 -0
- package/src/session/snapcompact-savings-journal.ts +113 -0
- package/src/session/sql-session-storage.ts +374 -0
- package/src/session/stream-guards.ts +417 -0
- package/src/session/streaming-output.ts +1459 -0
- package/src/session/todo-tracker.ts +380 -0
- package/src/session/tool-choice-queue.ts +305 -0
- package/src/session/ttsr-coordinator.ts +496 -0
- package/src/session/turn-persistence.ts +142 -0
- package/src/session/turn-recovery.ts +2005 -0
- package/src/session/unexpected-stop-classifier.ts +141 -0
- package/src/session/yield-queue.ts +288 -0
- package/src/slash-commands/acp-builtins.ts +70 -0
- package/src/slash-commands/available-commands.ts +105 -0
- package/src/slash-commands/builtin-registry.ts +3149 -0
- package/src/slash-commands/helpers/active-oauth-account.ts +80 -0
- package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
- package/src/slash-commands/helpers/context-report.ts +66 -0
- package/src/slash-commands/helpers/format.ts +46 -0
- package/src/slash-commands/helpers/logout.ts +108 -0
- package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
- package/src/slash-commands/helpers/mcp.ts +533 -0
- package/src/slash-commands/helpers/parse.ts +85 -0
- package/src/slash-commands/helpers/reset-usage.ts +68 -0
- package/src/slash-commands/helpers/security.ts +451 -0
- package/src/slash-commands/helpers/session-pin.ts +44 -0
- package/src/slash-commands/helpers/ssh.ts +196 -0
- package/src/slash-commands/helpers/stats-dashboard.ts +86 -0
- package/src/slash-commands/helpers/todo.ts +285 -0
- package/src/slash-commands/helpers/usage-report.ts +198 -0
- package/src/slash-commands/marketplace-install-parser.ts +99 -0
- package/src/slash-commands/types.ts +139 -0
- package/src/ssh/config-writer.ts +183 -0
- package/src/ssh/connection-manager.ts +667 -0
- package/src/ssh/file-transfer.ts +214 -0
- package/src/ssh/sshfs-mount.ts +163 -0
- package/src/ssh/utils.ts +51 -0
- package/src/startup-splash.ts +19 -0
- package/src/stt/asr-client.ts +401 -0
- package/src/stt/asr-protocol.ts +65 -0
- package/src/stt/asr-worker.ts +603 -0
- package/src/stt/downloader.ts +142 -0
- package/src/stt/endpointer.ts +259 -0
- package/src/stt/index.ts +6 -0
- package/src/stt/models.ts +150 -0
- package/src/stt/sherpa-runtime.ts +71 -0
- package/src/stt/stt-controller.ts +320 -0
- package/src/stt/submit-trigger.ts +74 -0
- package/src/subprocess/worker-client.ts +463 -0
- package/src/subprocess/worker-runtime.ts +494 -0
- package/src/system-prompt.ts +921 -0
- package/src/task/agents.ts +170 -0
- package/src/task/commands.ts +132 -0
- package/src/task/discovery.ts +145 -0
- package/src/task/executor.ts +3431 -0
- package/src/task/index.ts +1515 -0
- package/src/task/isolation-ownership.ts +106 -0
- package/src/task/isolation-runner.ts +444 -0
- package/src/task/label.ts +40 -0
- package/src/task/name-generator.ts +1577 -0
- package/src/task/omp-command.ts +26 -0
- package/src/task/output-manager.ts +115 -0
- package/src/task/parallel.ts +221 -0
- package/src/task/persisted-revive.ts +173 -0
- package/src/task/prewalk.ts +6 -0
- package/src/task/prompt-policy.ts +8 -0
- package/src/task/provider-concurrency.ts +100 -0
- package/src/task/read-only-policy.ts +27 -0
- package/src/task/render.ts +1830 -0
- package/src/task/renderer.ts +14 -0
- package/src/task/repair-args.ts +118 -0
- package/src/task/spawn-policy.ts +72 -0
- package/src/task/structured-subagent.ts +676 -0
- package/src/task/subprocess-tool-registry.ts +88 -0
- package/src/task/types.ts +555 -0
- package/src/task/worktree.ts +967 -0
- package/src/task/yield-assembly.ts +198 -0
- package/src/telemetry-export.ts +504 -0
- package/src/thinking.ts +377 -0
- package/src/tiny/device.ts +111 -0
- package/src/tiny/dtype.ts +101 -0
- package/src/tiny/message-preproc.ts +155 -0
- package/src/tiny/models.ts +268 -0
- package/src/tiny/text.ts +290 -0
- package/src/tiny/title-client.ts +460 -0
- package/src/tiny/title-protocol.ts +56 -0
- package/src/tiny/worker.ts +354 -0
- package/src/tools/acp-bridge.ts +125 -0
- package/src/tools/approval.ts +245 -0
- package/src/tools/ask.ts +1459 -0
- package/src/tools/ast-edit.ts +718 -0
- package/src/tools/ast-grep.ts +526 -0
- package/src/tools/auto-generated-guard.ts +335 -0
- package/src/tools/bash-interactive.ts +435 -0
- package/src/tools/bash-interceptor.ts +148 -0
- package/src/tools/bash-pty-selection.ts +14 -0
- package/src/tools/bash-skill-urls.ts +350 -0
- package/src/tools/bash.ts +1826 -0
- package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
- package/src/tools/browser/aria/aria-snapshot.ts +131 -0
- package/src/tools/browser/attach.ts +219 -0
- package/src/tools/browser/cmux/cmux-tab.ts +1531 -0
- package/src/tools/browser/cmux/rpc.ts +200 -0
- package/src/tools/browser/cmux/socket-client.ts +445 -0
- package/src/tools/browser/launch.ts +939 -0
- package/src/tools/browser/readable.ts +112 -0
- package/src/tools/browser/registry.ts +447 -0
- package/src/tools/browser/relay/bridge.ts +945 -0
- package/src/tools/browser/relay/daemon.ts +117 -0
- package/src/tools/browser/relay/extension-assets/background.js.txt +242 -0
- package/src/tools/browser/relay/extension-assets/manifest.json.txt +14 -0
- package/src/tools/browser/relay/extension-assets/options.html.txt +53 -0
- package/src/tools/browser/relay/extension-assets/options.js.txt +23 -0
- package/src/tools/browser/relay/kind.ts +41 -0
- package/src/tools/browser/relay/protocol.ts +54 -0
- package/src/tools/browser/relay/server.ts +141 -0
- package/src/tools/browser/render.ts +229 -0
- package/src/tools/browser/run-output.ts +76 -0
- package/src/tools/browser/shared-daemon.ts +139 -0
- package/src/tools/browser/tab-protocol.ts +123 -0
- package/src/tools/browser/tab-supervisor.ts +1077 -0
- package/src/tools/browser/tab-worker-entry.ts +29 -0
- package/src/tools/browser/tab-worker.ts +1982 -0
- package/src/tools/browser.ts +487 -0
- package/src/tools/builtin-names.ts +67 -0
- package/src/tools/checkpoint.ts +137 -0
- package/src/tools/computer/exposure.ts +14 -0
- package/src/tools/computer/protocol.ts +69 -0
- package/src/tools/computer/supervisor.ts +409 -0
- package/src/tools/computer/worker-entry.ts +39 -0
- package/src/tools/computer/worker.ts +745 -0
- package/src/tools/computer-renderer.ts +147 -0
- package/src/tools/computer.ts +222 -0
- package/src/tools/conflict-detect.ts +815 -0
- package/src/tools/context.ts +49 -0
- package/src/tools/debug.ts +1121 -0
- package/src/tools/default-renderer.ts +154 -0
- package/src/tools/essential-tools.ts +46 -0
- package/src/tools/eval-backends.ts +34 -0
- package/src/tools/eval-format/index.ts +24 -0
- package/src/tools/eval-format/javascript.ts +952 -0
- package/src/tools/eval-format/julia.ts +446 -0
- package/src/tools/eval-format/python.ts +544 -0
- package/src/tools/eval-format/ruby.ts +380 -0
- package/src/tools/eval-render.ts +784 -0
- package/src/tools/eval.ts +774 -0
- package/src/tools/fetch.ts +1889 -0
- package/src/tools/file-recorder.ts +35 -0
- package/src/tools/fs-cache-invalidation.ts +28 -0
- package/src/tools/gh-cache-invalidation.ts +175 -0
- package/src/tools/gh-format.ts +12 -0
- package/src/tools/gh-renderer.ts +484 -0
- package/src/tools/gh.ts +3958 -0
- package/src/tools/github-cache.ts +663 -0
- package/src/tools/glob.ts +691 -0
- package/src/tools/grep.ts +1920 -0
- package/src/tools/grouped-file-output.ts +210 -0
- package/src/tools/hub/index.ts +579 -0
- package/src/tools/hub/jobs.ts +714 -0
- package/src/tools/hub/launch.ts +690 -0
- package/src/tools/hub/messaging.ts +735 -0
- package/src/tools/hub/types.ts +117 -0
- package/src/tools/image-gen.ts +1689 -0
- package/src/tools/image-providers.ts +50 -0
- package/src/tools/index.ts +736 -0
- package/src/tools/inspect-image-renderer.ts +133 -0
- package/src/tools/inspect-image.ts +316 -0
- package/src/tools/json-tree.ts +260 -0
- package/src/tools/jtd-to-json-schema.ts +219 -0
- package/src/tools/jtd-to-typescript.ts +136 -0
- package/src/tools/jtd-utils.ts +102 -0
- package/src/tools/learn.ts +141 -0
- package/src/tools/list-limit.ts +40 -0
- package/src/tools/manage-skill.ts +102 -0
- package/src/tools/match-line-format.ts +20 -0
- package/src/tools/memory-edit.ts +61 -0
- package/src/tools/memory-recall.ts +102 -0
- package/src/tools/memory-reflect.ts +88 -0
- package/src/tools/memory-render.ts +211 -0
- package/src/tools/memory-retain.ts +89 -0
- package/src/tools/output-meta.ts +860 -0
- package/src/tools/output-schema-validator.ts +307 -0
- package/src/tools/path-utils.ts +1489 -0
- package/src/tools/plan-mode-guard.ts +155 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +44 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +80 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +57 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +380 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +174 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +233 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +260 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +99 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +63 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +51 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +212 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +59 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +42 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +235 -0
- package/src/tools/read.ts +3762 -0
- package/src/tools/render-utils.ts +926 -0
- package/src/tools/renderers.ts +133 -0
- package/src/tools/report-tool-issue.ts +568 -0
- package/src/tools/resolve.ts +423 -0
- package/src/tools/review.ts +103 -0
- package/src/tools/run-scope.ts +417 -0
- package/src/tools/security-scan.ts +287 -0
- package/src/tools/shell-tokenize.ts +213 -0
- package/src/tools/sqlite-reader.ts +884 -0
- package/src/tools/terminal-output.ts +141 -0
- package/src/tools/todo.ts +1226 -0
- package/src/tools/tool-errors.ts +62 -0
- package/src/tools/tool-result.ts +102 -0
- package/src/tools/tool-timeouts.ts +38 -0
- package/src/tools/tts.ts +266 -0
- package/src/tools/vibe.ts +608 -0
- package/src/tools/write.ts +1646 -0
- package/src/tools/xdev.ts +560 -0
- package/src/tools/yield.ts +486 -0
- package/src/tts/downloader.ts +64 -0
- package/src/tts/index.ts +10 -0
- package/src/tts/models.ts +137 -0
- package/src/tts/runtime.ts +21 -0
- package/src/tts/speakable.ts +392 -0
- package/src/tts/speech-enhancer.ts +206 -0
- package/src/tts/streaming-player.ts +120 -0
- package/src/tts/tts-client.ts +475 -0
- package/src/tts/tts-protocol.ts +69 -0
- package/src/tts/tts-worker.ts +434 -0
- package/src/tts/vocalizer.ts +419 -0
- package/src/tts/wav.ts +58 -0
- package/src/tui/code-cell.ts +268 -0
- package/src/tui/file-list.ts +55 -0
- package/src/tui/hyperlink.ts +178 -0
- package/src/tui/index.ts +13 -0
- package/src/tui/output-block.ts +268 -0
- package/src/tui/status-line.ts +54 -0
- package/src/tui/tree-list.ts +172 -0
- package/src/tui/types.ts +15 -0
- package/src/tui/utils.ts +103 -0
- package/src/tui/width-aware-text.ts +58 -0
- package/src/utils/active-repo-context.ts +143 -0
- package/src/utils/block-context.ts +312 -0
- package/src/utils/changelog.ts +373 -0
- package/src/utils/clipboard.ts +361 -0
- package/src/utils/command-args.ts +74 -0
- package/src/utils/commit-message-generator.ts +148 -0
- package/src/utils/cpuprofile.ts +235 -0
- package/src/utils/edit-mode.ts +61 -0
- package/src/utils/enhanced-paste.ts +230 -0
- package/src/utils/event-bus.ts +33 -0
- package/src/utils/external-editor.ts +80 -0
- package/src/utils/fetch-timeout.ts +10 -0
- package/src/utils/file-display-mode.ts +44 -0
- package/src/utils/file-mentions.ts +293 -0
- package/src/utils/git.ts +2472 -0
- package/src/utils/image-loading.ts +236 -0
- package/src/utils/image-resize.ts +420 -0
- package/src/utils/image-vision-fallback.ts +196 -0
- package/src/utils/inspect-image-mode.ts +39 -0
- package/src/utils/ipc.ts +38 -0
- package/src/utils/jj.ts +422 -0
- package/src/utils/lang-from-path.ts +251 -0
- package/src/utils/late-cleanup.ts +17 -0
- package/src/utils/local-date.ts +7 -0
- package/src/utils/mac-file-urls.applescript +37 -0
- package/src/utils/markit-cache.ts +166 -0
- package/src/utils/markit.ts +223 -0
- package/src/utils/mupdf-wasm-embed.ts +12 -0
- package/src/utils/open.ts +126 -0
- package/src/utils/profile-tree.ts +111 -0
- package/src/utils/prompt-path.ts +3 -0
- package/src/utils/qrcode.ts +535 -0
- package/src/utils/sample-profile.ts +437 -0
- package/src/utils/session-color.ts +142 -0
- package/src/utils/shell-snapshot-fn-env.sh +63 -0
- package/src/utils/shell-snapshot.ts +326 -0
- package/src/utils/sixel.ts +69 -0
- package/src/utils/thinking-display.ts +163 -0
- package/src/utils/title-generator.ts +597 -0
- package/src/utils/token-rate.ts +72 -0
- package/src/utils/tool-choice.ts +50 -0
- package/src/utils/tools-manager.ts +411 -0
- package/src/utils/turndown.ts +82 -0
- package/src/utils/zip.ts +1106 -0
- package/src/vibe/runtime.ts +1684 -0
- package/src/vibe/state.ts +4 -0
- package/src/web/kagi.ts +305 -0
- package/src/web/parallel.ts +354 -0
- package/src/web/scrapers/artifacthub.ts +207 -0
- package/src/web/scrapers/arxiv.ts +83 -0
- package/src/web/scrapers/aur.ts +162 -0
- package/src/web/scrapers/biorxiv.ts +133 -0
- package/src/web/scrapers/bluesky.ts +262 -0
- package/src/web/scrapers/brew.ts +172 -0
- package/src/web/scrapers/cheatsh.ts +68 -0
- package/src/web/scrapers/chocolatey.ts +196 -0
- package/src/web/scrapers/choosealicense.ts +95 -0
- package/src/web/scrapers/cisa-kev.ts +87 -0
- package/src/web/scrapers/clojars.ts +154 -0
- package/src/web/scrapers/coingecko.ts +177 -0
- package/src/web/scrapers/crates-io.ts +97 -0
- package/src/web/scrapers/crossref.ts +136 -0
- package/src/web/scrapers/devto.ts +147 -0
- package/src/web/scrapers/discogs.ts +306 -0
- package/src/web/scrapers/discourse.ts +197 -0
- package/src/web/scrapers/dockerhub.ts +138 -0
- package/src/web/scrapers/docs-rs.ts +663 -0
- package/src/web/scrapers/fdroid.ts +134 -0
- package/src/web/scrapers/firefox-addons.ts +191 -0
- package/src/web/scrapers/flathub.ts +223 -0
- package/src/web/scrapers/github-gist.ts +58 -0
- package/src/web/scrapers/github.ts +800 -0
- package/src/web/scrapers/gitlab.ts +401 -0
- package/src/web/scrapers/go-pkg.ts +266 -0
- package/src/web/scrapers/hackage.ts +129 -0
- package/src/web/scrapers/hackernews.ts +189 -0
- package/src/web/scrapers/hex.ts +105 -0
- package/src/web/scrapers/huggingface.ts +321 -0
- package/src/web/scrapers/iacr.ts +89 -0
- package/src/web/scrapers/index.ts +252 -0
- package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
- package/src/web/scrapers/lemmy.ts +203 -0
- package/src/web/scrapers/lobsters.ts +175 -0
- package/src/web/scrapers/mastodon.ts +292 -0
- package/src/web/scrapers/maven.ts +138 -0
- package/src/web/scrapers/mdn.ts +173 -0
- package/src/web/scrapers/metacpan.ts +222 -0
- package/src/web/scrapers/musicbrainz.ts +250 -0
- package/src/web/scrapers/npm.ts +98 -0
- package/src/web/scrapers/nuget.ts +183 -0
- package/src/web/scrapers/nvd.ts +222 -0
- package/src/web/scrapers/ollama.ts +239 -0
- package/src/web/scrapers/open-vsx.ts +106 -0
- package/src/web/scrapers/opencorporates.ts +292 -0
- package/src/web/scrapers/openlibrary.ts +336 -0
- package/src/web/scrapers/orcid.ts +286 -0
- package/src/web/scrapers/osv.ts +176 -0
- package/src/web/scrapers/packagist.ts +160 -0
- package/src/web/scrapers/pub-dev.ts +143 -0
- package/src/web/scrapers/pubmed.ts +211 -0
- package/src/web/scrapers/pypi.ts +112 -0
- package/src/web/scrapers/rawg.ts +110 -0
- package/src/web/scrapers/readthedocs.ts +121 -0
- package/src/web/scrapers/reddit.ts +95 -0
- package/src/web/scrapers/repology.ts +251 -0
- package/src/web/scrapers/rfc.ts +201 -0
- package/src/web/scrapers/rubygems.ts +103 -0
- package/src/web/scrapers/searchcode.ts +189 -0
- package/src/web/scrapers/sec-edgar.ts +261 -0
- package/src/web/scrapers/semantic-scholar.ts +171 -0
- package/src/web/scrapers/snapcraft.ts +187 -0
- package/src/web/scrapers/sourcegraph.ts +336 -0
- package/src/web/scrapers/spdx.ts +108 -0
- package/src/web/scrapers/spotify.ts +198 -0
- package/src/web/scrapers/stackoverflow.ts +120 -0
- package/src/web/scrapers/terraform.ts +277 -0
- package/src/web/scrapers/tldr.ts +47 -0
- package/src/web/scrapers/twitter.ts +94 -0
- package/src/web/scrapers/types.ts +354 -0
- package/src/web/scrapers/utils.ts +109 -0
- package/src/web/scrapers/vimeo.ts +133 -0
- package/src/web/scrapers/vscode-marketplace.ts +187 -0
- package/src/web/scrapers/w3c.ts +156 -0
- package/src/web/scrapers/wikidata.ts +344 -0
- package/src/web/scrapers/wikipedia.ts +84 -0
- package/src/web/scrapers/youtube.ts +325 -0
- package/src/web/search/index.ts +393 -0
- package/src/web/search/provider.ts +272 -0
- package/src/web/search/providers/anthropic.ts +406 -0
- package/src/web/search/providers/base.ts +112 -0
- package/src/web/search/providers/brave.ts +181 -0
- package/src/web/search/providers/browser-headers.ts +82 -0
- package/src/web/search/providers/browser-page.ts +125 -0
- package/src/web/search/providers/codex.ts +788 -0
- package/src/web/search/providers/duckduckgo.ts +382 -0
- package/src/web/search/providers/ecosia.ts +183 -0
- package/src/web/search/providers/exa.ts +513 -0
- package/src/web/search/providers/firecrawl.ts +213 -0
- package/src/web/search/providers/gemini.ts +634 -0
- package/src/web/search/providers/google.ts +195 -0
- package/src/web/search/providers/jina.ts +144 -0
- package/src/web/search/providers/kagi.ts +98 -0
- package/src/web/search/providers/kimi.ts +221 -0
- package/src/web/search/providers/mojeek.ts +220 -0
- package/src/web/search/providers/parallel.ts +186 -0
- package/src/web/search/providers/perplexity-auth.ts +142 -0
- package/src/web/search/providers/perplexity.ts +997 -0
- package/src/web/search/providers/public.ts +199 -0
- package/src/web/search/providers/searxng.ts +467 -0
- package/src/web/search/providers/startpage.ts +225 -0
- package/src/web/search/providers/synthetic.ts +126 -0
- package/src/web/search/providers/tavily.ts +244 -0
- package/src/web/search/providers/tinyfish.ts +166 -0
- package/src/web/search/providers/utils.ts +130 -0
- package/src/web/search/providers/xai.ts +372 -0
- package/src/web/search/providers/zai.ts +452 -0
- package/src/web/search/query.ts +850 -0
- package/src/web/search/render.ts +262 -0
- package/src/web/search/types.ts +518 -0
- package/src/web/search/utils.ts +17 -0
- package/src/workspace-tree.ts +326 -0
|
@@ -0,0 +1,1467 @@
|
|
|
1
|
+
import type { Clipboard, SnapshotStore } from "@oh-my-pi/hashline";
|
|
2
|
+
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
3
|
+
import {
|
|
4
|
+
Box,
|
|
5
|
+
type Component,
|
|
6
|
+
Container,
|
|
7
|
+
getImageDimensions,
|
|
8
|
+
Image,
|
|
9
|
+
ImageProtocol,
|
|
10
|
+
imageFallback,
|
|
11
|
+
type NativeScrollbackLiveRegion,
|
|
12
|
+
Spacer,
|
|
13
|
+
TERMINAL,
|
|
14
|
+
Text,
|
|
15
|
+
type TUI,
|
|
16
|
+
} from "@oh-my-pi/pi-tui";
|
|
17
|
+
import { getProjectDir, logger, sanitizeText } from "@oh-my-pi/pi-utils";
|
|
18
|
+
import { EDIT_MODE_STRATEGIES, type EditMode, type PerFileDiffPreview } from "../../edit";
|
|
19
|
+
import type { Theme } from "../../modes/theme/theme";
|
|
20
|
+
import { getThemeEpoch, theme } from "../../modes/theme/theme";
|
|
21
|
+
import { BASH_DEFAULT_PREVIEW_LINES } from "../../tools/bash";
|
|
22
|
+
import { formatDefaultToolExecution } from "../../tools/default-renderer";
|
|
23
|
+
import { EVAL_DEFAULT_PREVIEW_LINES } from "../../tools/eval";
|
|
24
|
+
import { isWaitingPollDetails } from "../../tools/hub";
|
|
25
|
+
import { formatStatusIcon, replaceTabs, resolveImageOptions } from "../../tools/render-utils";
|
|
26
|
+
import { type FirstResultViewportRepaint, toolRenderers } from "../../tools/renderers";
|
|
27
|
+
import { TODO_STRIKE_TOTAL_FRAMES, type TodoToolDetails } from "../../tools/todo";
|
|
28
|
+
import type { XdevState } from "../../tools/xdev";
|
|
29
|
+
import { isFramedBlockComponent, markFramedBlockComponent, renderStatusLine, WidthAwareText } from "../../tui";
|
|
30
|
+
import { convertImageToPng } from "../../utils/image-loading";
|
|
31
|
+
import { sanitizeWithOptionalSixelPassthrough } from "../../utils/sixel";
|
|
32
|
+
import { renderDiff } from "./diff";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Drop trailing removal/hunk-header lines that appear in a streaming diff
|
|
36
|
+
* before the matching `+added` lines have arrived. Without this, a partial
|
|
37
|
+
* apply_patch / hashline preview shows `-old` first and then visibly grows
|
|
38
|
+
* the `+new` block beneath it — the "removals first, additions catching up"
|
|
39
|
+
* jitter. Once the next streaming tick brings the additions in, the trailing
|
|
40
|
+
* block reappears alongside them.
|
|
41
|
+
*/
|
|
42
|
+
function stripTrailingUnbalancedRemoval(diff: string | undefined): string | undefined {
|
|
43
|
+
if (!diff) return diff;
|
|
44
|
+
const lines = diff.split("\n");
|
|
45
|
+
let lastAddIdx = -1;
|
|
46
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
47
|
+
if (lines[i].startsWith("+")) {
|
|
48
|
+
lastAddIdx = i;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
let hasTrailingUnbalanced = false;
|
|
53
|
+
for (let i = lastAddIdx + 1; i < lines.length; i++) {
|
|
54
|
+
const line = lines[i];
|
|
55
|
+
if (line.startsWith("-") || line.startsWith("@@")) {
|
|
56
|
+
hasTrailingUnbalanced = true;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!hasTrailingUnbalanced) return diff;
|
|
61
|
+
if (lastAddIdx === -1) return "";
|
|
62
|
+
return lines.slice(0, lastAddIdx + 1).join("\n");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type DisplaceableToolName = "hub" | "todo";
|
|
66
|
+
|
|
67
|
+
function isTodoToolDetails(details: unknown): details is TodoToolDetails {
|
|
68
|
+
return (
|
|
69
|
+
typeof details === "object" &&
|
|
70
|
+
details !== null &&
|
|
71
|
+
"phases" in details &&
|
|
72
|
+
Array.isArray((details as { phases?: unknown }).phases)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function displaceableToolName(
|
|
77
|
+
toolName: string,
|
|
78
|
+
result: { details?: unknown; isError?: boolean },
|
|
79
|
+
isPartial: boolean,
|
|
80
|
+
): DisplaceableToolName | undefined {
|
|
81
|
+
if (result.isError === true) return undefined;
|
|
82
|
+
if (toolName === "hub" && isWaitingPollDetails(result.details)) return "hub";
|
|
83
|
+
if (toolName === "todo" && !isPartial && isTodoToolDetails(result.details)) return "todo";
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function stabilizeStreamingPreviews(previews: PerFileDiffPreview[]): PerFileDiffPreview[] {
|
|
88
|
+
let changed = false;
|
|
89
|
+
const next = previews.map(preview => {
|
|
90
|
+
if (!preview.diff) return preview;
|
|
91
|
+
const trimmed = stripTrailingUnbalancedRemoval(preview.diff);
|
|
92
|
+
if (trimmed === preview.diff) return preview;
|
|
93
|
+
changed = true;
|
|
94
|
+
return { ...preview, diff: trimmed ?? "" };
|
|
95
|
+
});
|
|
96
|
+
return changed ? next : previews;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function isEditLikeToolName(toolName: string): boolean {
|
|
100
|
+
return toolName === "edit" || toolName === "apply_patch";
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function resolveEditModeForTool(toolName: string, tool: AgentTool | undefined): EditMode | undefined {
|
|
104
|
+
if (toolName === "apply_patch") return "apply_patch";
|
|
105
|
+
if (toolName !== "edit") return undefined;
|
|
106
|
+
return (tool as { mode?: EditMode } | undefined)?.mode;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function rawTextInputFromPartialJson(partialJson: unknown): string | undefined {
|
|
110
|
+
if (typeof partialJson !== "string") return undefined;
|
|
111
|
+
if (partialJson.length === 0) return undefined;
|
|
112
|
+
const trimmed = partialJson.trimStart();
|
|
113
|
+
if (trimmed.length === 0) return undefined;
|
|
114
|
+
const first = trimmed[0];
|
|
115
|
+
// Function-tool arguments stream as JSON. Custom/free-form tools stream raw
|
|
116
|
+
// text in the same transport field; only the raw form is a valid fallback for
|
|
117
|
+
// the conventional `input` parameter.
|
|
118
|
+
if (first === "{" || first === '"') return undefined;
|
|
119
|
+
return partialJson;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Read the streamed raw-JSON buffer a tool block stashes on its args, narrowed
|
|
123
|
+
* rather than cast: a missing or non-string `__partialJson` yields `undefined`. */
|
|
124
|
+
function partialJsonOf(args: unknown): string | undefined {
|
|
125
|
+
if (args == null || typeof args !== "object" || !("__partialJson" in args)) return undefined;
|
|
126
|
+
const value = args.__partialJson;
|
|
127
|
+
return typeof value === "string" ? value : undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getArgsWithStreamedTextInput(args: unknown): unknown {
|
|
131
|
+
if (args == null || typeof args !== "object") return args;
|
|
132
|
+
const record = args as Record<string, unknown>;
|
|
133
|
+
if (typeof record.input === "string") return args;
|
|
134
|
+
const input = rawTextInputFromPartialJson(record.__partialJson);
|
|
135
|
+
return input === undefined ? args : { ...record, input };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
type ToolRendererStage = "call" | "result";
|
|
139
|
+
|
|
140
|
+
class SafeToolRendererComponent implements Component {
|
|
141
|
+
#toolName: string;
|
|
142
|
+
#stage: ToolRendererStage;
|
|
143
|
+
#component: Component;
|
|
144
|
+
#fallback: () => Component | undefined;
|
|
145
|
+
#warned = false;
|
|
146
|
+
readonly wantsKeyRelease: boolean | undefined;
|
|
147
|
+
|
|
148
|
+
constructor(
|
|
149
|
+
toolName: string,
|
|
150
|
+
stage: ToolRendererStage,
|
|
151
|
+
component: Component,
|
|
152
|
+
fallback: () => Component | undefined,
|
|
153
|
+
) {
|
|
154
|
+
this.#toolName = toolName;
|
|
155
|
+
this.#stage = stage;
|
|
156
|
+
this.#component = component;
|
|
157
|
+
this.#fallback = fallback;
|
|
158
|
+
this.wantsKeyRelease = component.wantsKeyRelease;
|
|
159
|
+
if (isFramedBlockComponent(component)) {
|
|
160
|
+
markFramedBlockComponent(this);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
render(width: number): readonly string[] {
|
|
165
|
+
try {
|
|
166
|
+
return this.#component.render(width);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
if (!this.#warned) {
|
|
169
|
+
this.#warned = true;
|
|
170
|
+
logger.warn("Tool renderer failed", { tool: this.#toolName, stage: this.#stage, error: String(err) });
|
|
171
|
+
}
|
|
172
|
+
return this.#fallback()?.render(width) ?? [];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
handleInput(data: string): void {
|
|
177
|
+
const handleInput = this.#component.handleInput;
|
|
178
|
+
if (handleInput === undefined) return;
|
|
179
|
+
handleInput.call(this.#component, data);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
invalidate(): void {
|
|
183
|
+
const invalidate = this.#component.invalidate;
|
|
184
|
+
if (invalidate === undefined) return;
|
|
185
|
+
invalidate.call(this.#component);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
setIgnoreTight(ignore: boolean): void {
|
|
189
|
+
const setIgnoreTight = this.#component.setIgnoreTight;
|
|
190
|
+
if (setIgnoreTight === undefined) return;
|
|
191
|
+
setIgnoreTight.call(this.#component, ignore);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
dispose(): void {
|
|
195
|
+
const dispose = this.#component.dispose;
|
|
196
|
+
if (dispose === undefined) return;
|
|
197
|
+
dispose.call(this.#component);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Transcript-side probe telling a block whether it is still inside the live
|
|
202
|
+
* (repaintable) region. Implemented by `TranscriptContainer`; injected rather
|
|
203
|
+
* than imported so the component stays decoupled from the transcript.
|
|
204
|
+
*/
|
|
205
|
+
export interface TranscriptLiveRegionProbe {
|
|
206
|
+
isBlockInLiveRegion(component: Component): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Whether none of the block's rows have entered native scrollback (see
|
|
209
|
+
* `TranscriptContainer.isBlockUncommitted`). Optional: standalone hosts
|
|
210
|
+
* without commit tracking omit it, and blocks treat their rows as
|
|
211
|
+
* uncommitted.
|
|
212
|
+
*/
|
|
213
|
+
isBlockUncommitted?(component: Component): boolean;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Minimal TUI surface ToolExecutionComponent uses to schedule repaints and share image budget. */
|
|
217
|
+
export interface ToolExecutionUi {
|
|
218
|
+
requestRender(): void;
|
|
219
|
+
requestComponentRender(component: Component): void;
|
|
220
|
+
resetDisplay(): void;
|
|
221
|
+
imageBudget?: TUI["imageBudget"];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface ToolExecutionOptions {
|
|
225
|
+
snapshots?: SnapshotStore;
|
|
226
|
+
/** Session-persistent edit clipboard register, forked per preview frame. */
|
|
227
|
+
clipboard?: Clipboard;
|
|
228
|
+
showImages?: boolean; // default: true (only used if terminal supports images)
|
|
229
|
+
editFuzzyThreshold?: number;
|
|
230
|
+
editAllowFuzzy?: boolean;
|
|
231
|
+
/** Live-region probe used to settle detached task progress once the block
|
|
232
|
+
* leaves the repaintable transcript region. */
|
|
233
|
+
liveRegion?: TranscriptLiveRegionProbe;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface ToolExecutionHandle extends Component {
|
|
237
|
+
updateArgs(args: any, toolCallId?: string): void;
|
|
238
|
+
updateResult(
|
|
239
|
+
result: {
|
|
240
|
+
content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;
|
|
241
|
+
details?: any;
|
|
242
|
+
isError?: boolean;
|
|
243
|
+
},
|
|
244
|
+
isPartial?: boolean,
|
|
245
|
+
toolCallId?: string,
|
|
246
|
+
): void;
|
|
247
|
+
setArgsComplete(toolCallId?: string): void;
|
|
248
|
+
setExpanded(expanded: boolean): void;
|
|
249
|
+
setToolActivityVisible(visible: boolean): void;
|
|
250
|
+
/** Freeze the block as final history: stop spinners and let it commit to scrollback. */
|
|
251
|
+
seal(): void;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Redraw live tool blocks at the spinner's glyph-advance rate. Rendering more
|
|
255
|
+
* often produced identical frames — the previous 30fps cadence emitted ~2.4
|
|
256
|
+
* paints per glyph step, and although the terminal I/O layer dedupes those, the
|
|
257
|
+
* compose pipeline still ran end-to-end per frame (issue #4353). Matching the
|
|
258
|
+
* render tick to the glyph tick halves the paints during tool execution with no
|
|
259
|
+
* visible change. */
|
|
260
|
+
export const SPINNER_RENDER_INTERVAL_MS = 80;
|
|
261
|
+
/** Advance the spinner glyph at its classic ~12.5fps step (mirrors `Loader`). */
|
|
262
|
+
export const SPINNER_GLYPH_ADVANCE_MS = 80;
|
|
263
|
+
|
|
264
|
+
/** Phase-locked spinner glyph index shared by every live tool block so parallel
|
|
265
|
+
* spinners advance in lockstep instead of each tracking its own start time. */
|
|
266
|
+
export function sharedSpinnerFrame(frameCount: number, now: number = performance.now()): number {
|
|
267
|
+
return frameCount > 0 ? Math.floor(now / SPINNER_GLYPH_ADVANCE_MS) % frameCount : 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Stable per-instance counter so each tool execution's inline images get a
|
|
271
|
+
// graphics id that survives child re-creation (the image budget keys off it).
|
|
272
|
+
let toolExecutionInstanceSeq = 0;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Component that renders a tool call with its result (updateable)
|
|
276
|
+
*/
|
|
277
|
+
export class ToolExecutionComponent extends Container implements NativeScrollbackLiveRegion {
|
|
278
|
+
#contentBox: Box; // Used for custom tools and bash visual truncation
|
|
279
|
+
#contentText: WidthAwareText; // Generic fallback (no custom/built-in renderer)
|
|
280
|
+
// Which container the constructor mounted: bespoke/built-in renderers use
|
|
281
|
+
// #contentBox, everything else the generic #contentText fallback.
|
|
282
|
+
#usesContentBox = false;
|
|
283
|
+
#multiFileBoxes: (Box | Spacer)[] = []; // Extra boxes for multi-file edit results
|
|
284
|
+
#imageComponents: Image[] = [];
|
|
285
|
+
#imageSpacers: Spacer[] = [];
|
|
286
|
+
readonly #instanceId = ++toolExecutionInstanceSeq;
|
|
287
|
+
#toolName: string;
|
|
288
|
+
#toolLabel: string;
|
|
289
|
+
#args: any;
|
|
290
|
+
#expanded = false;
|
|
291
|
+
#toolActivityVisible = true;
|
|
292
|
+
#showImages: boolean;
|
|
293
|
+
#editFuzzyThreshold: number | undefined;
|
|
294
|
+
#editAllowFuzzy: boolean | undefined;
|
|
295
|
+
#snapshots?: SnapshotStore;
|
|
296
|
+
#clipboard?: Clipboard;
|
|
297
|
+
#isPartial = true;
|
|
298
|
+
#resultVersion = 0;
|
|
299
|
+
#lastDisplayKey: string | undefined;
|
|
300
|
+
// Bumped whenever a render input that #rebuildDisplay consumes but the memo
|
|
301
|
+
// key cannot cheaply hash changes: streamed call args, the async edit-diff
|
|
302
|
+
// preview, and Kitty PNG conversions. Folded into the dirty key so those
|
|
303
|
+
// updates are not swallowed by the memo (see #updateDisplay).
|
|
304
|
+
#displayInputVersion = 0;
|
|
305
|
+
// Set once #rebuildDisplay has populated the display. Replaces a
|
|
306
|
+
// #contentBox.children.length probe so the memo fast-path also covers the
|
|
307
|
+
// #contentText fallback path (which leaves #contentBox empty).
|
|
308
|
+
#displayBuilt = false;
|
|
309
|
+
// Number of Image children the last rebuild emitted. Only when this is > 0 does
|
|
310
|
+
// the memo key fold in viewport-dependent image sizing (resolveImageOptions),
|
|
311
|
+
// so a terminal resize re-shapes image-bearing results to rescale them without
|
|
312
|
+
// forcing the common image-free result to re-shape on every resize tick.
|
|
313
|
+
#renderedImageCount = 0;
|
|
314
|
+
#tool?: AgentTool;
|
|
315
|
+
#ui: ToolExecutionUi;
|
|
316
|
+
#cwd: string;
|
|
317
|
+
#result?: {
|
|
318
|
+
content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;
|
|
319
|
+
isError?: boolean;
|
|
320
|
+
details?: any;
|
|
321
|
+
};
|
|
322
|
+
// Edit preview state
|
|
323
|
+
#editMode?: EditMode;
|
|
324
|
+
#editDiffPreview?: PerFileDiffPreview[];
|
|
325
|
+
#editDiffAbort?: AbortController;
|
|
326
|
+
#editDiffLastArgsKey?: string;
|
|
327
|
+
// Latest in-flight streaming diff recompute, captured so it can be awaited.
|
|
328
|
+
#editDiffInFlight?: Promise<void>;
|
|
329
|
+
/** Set when newer args arrived while a preview compute was in flight; the
|
|
330
|
+
* drain loop re-runs once the current compute settles, so a slow diff
|
|
331
|
+
* coalesces streamed ticks instead of being aborted by each one. */
|
|
332
|
+
#editDiffDirty = false;
|
|
333
|
+
// Cached converted images for Kitty protocol (which requires PNG), keyed by index
|
|
334
|
+
#convertedImages: Map<number, { data: string; mimeType: string }> = new Map();
|
|
335
|
+
// Spinner animation for partial task results
|
|
336
|
+
#spinnerFrame?: number;
|
|
337
|
+
#spinnerInterval?: NodeJS.Timeout;
|
|
338
|
+
// Todo write completion strikethrough reveal animation
|
|
339
|
+
#todoStrikeInterval?: NodeJS.Timeout;
|
|
340
|
+
// Track if args are still being streamed (for edit/write spinner)
|
|
341
|
+
#argsComplete = false;
|
|
342
|
+
// Sealed once the tool reaches a terminal state (result delivered, or the
|
|
343
|
+
// turn abandoned it without one). Drives `isTranscriptBlockFinalized`: until
|
|
344
|
+
// sealed the block stays in the transcript's repaintable live region so a
|
|
345
|
+
// late result still repaints instead of stranding the streaming preview.
|
|
346
|
+
#sealed = false;
|
|
347
|
+
// Tool result snapshots that may be superseded by a later same-tool call
|
|
348
|
+
// while still in the transcript live region. `hub` uses this for repeated
|
|
349
|
+
// all-running polls; `todo` uses it for per-turn state snapshots so only the
|
|
350
|
+
// latest list remains visible.
|
|
351
|
+
#displaceableByToolName: DisplaceableToolName | undefined;
|
|
352
|
+
// Probe into the owning transcript (absent outside the interactive
|
|
353
|
+
// transcript, e.g. in tests): whether this block is still repaintable.
|
|
354
|
+
#liveRegion?: TranscriptLiveRegionProbe;
|
|
355
|
+
// One-way latch for a detached (`async.state === "running"`) task block
|
|
356
|
+
// whose rows became native-scrollback history — it left the transcript
|
|
357
|
+
// live region, or its head rows were committed while it was still the
|
|
358
|
+
// live tail. Further partial snapshots are dropped so committed rows are
|
|
359
|
+
// never mutated (see #maybeFreezeBackgroundTask).
|
|
360
|
+
#backgroundTaskFrozen = false;
|
|
361
|
+
// Whether the freeze may restyle the progress rows static gray. Set only
|
|
362
|
+
// when the latch fired while no row was committed: a recolor of rows
|
|
363
|
+
// already on the tape would itself diverge immutable history and force an
|
|
364
|
+
// erase-replay (or, with scrollback rebuild off, a duplicate slab).
|
|
365
|
+
#backgroundTaskFrozenStyled = false;
|
|
366
|
+
// Wall clock captured at each repaintable rebuild of a task card and
|
|
367
|
+
// reused verbatim once the card freezes or any of its rows commit, so
|
|
368
|
+
// time-derived rows (current-tool elapsed, retry countdown) cannot drift
|
|
369
|
+
// a committed byte on later rebuilds (theme epoch, image toggles).
|
|
370
|
+
#taskRenderNowMs = Date.now();
|
|
371
|
+
// Set on each `render()` when the last painted pending shape must be
|
|
372
|
+
// replayed wholesale when the first result arrives. Reset gates key off
|
|
373
|
+
// these so a topology-changing update that lands before the shape reaches
|
|
374
|
+
// the terminal never triggers a full-viewport replay (which on direct
|
|
375
|
+
// terminals wipes native scrollback and flashes the user's history —
|
|
376
|
+
// reviewer note on PR #4315).
|
|
377
|
+
#firstResultViewportRepaintShapePainted = false;
|
|
378
|
+
#partialResultShapePainted = false;
|
|
379
|
+
#renderState: {
|
|
380
|
+
spinnerFrame?: number;
|
|
381
|
+
expanded: boolean;
|
|
382
|
+
isPartial: boolean;
|
|
383
|
+
renderContext?: Record<string, unknown>;
|
|
384
|
+
} = {
|
|
385
|
+
expanded: false,
|
|
386
|
+
isPartial: true,
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
constructor(
|
|
390
|
+
toolName: string,
|
|
391
|
+
args: any,
|
|
392
|
+
options: ToolExecutionOptions = {},
|
|
393
|
+
tool: AgentTool | undefined,
|
|
394
|
+
ui: ToolExecutionUi,
|
|
395
|
+
cwd: string = getProjectDir(),
|
|
396
|
+
_toolCallId?: string,
|
|
397
|
+
) {
|
|
398
|
+
super();
|
|
399
|
+
this.#toolName = toolName;
|
|
400
|
+
this.#toolLabel = tool?.label ?? toolName;
|
|
401
|
+
this.#showImages = options.showImages ?? true;
|
|
402
|
+
this.#editFuzzyThreshold = options.editFuzzyThreshold;
|
|
403
|
+
this.#editAllowFuzzy = options.editAllowFuzzy;
|
|
404
|
+
this.#snapshots = options.snapshots;
|
|
405
|
+
this.#clipboard = options.clipboard;
|
|
406
|
+
this.#liveRegion = options.liveRegion;
|
|
407
|
+
this.#tool = tool;
|
|
408
|
+
this.#ui = ui;
|
|
409
|
+
this.#cwd = cwd;
|
|
410
|
+
this.#args = args;
|
|
411
|
+
this.#editMode = resolveEditModeForTool(toolName, tool);
|
|
412
|
+
|
|
413
|
+
// Always create both - contentBox for custom tools/bash/tools with renderers, contentText for other built-ins.
|
|
414
|
+
// paddingY is 1 so background-tinted blocks (custom/extension tools and the
|
|
415
|
+
// generic fallback) get top/bottom breathing room. TranscriptContainer
|
|
416
|
+
// strips PLAIN-blank edges, so framed/minimal blocks (no bg set) drop these
|
|
417
|
+
// lines and keep their tight spacing — only tinted lines survive.
|
|
418
|
+
this.#contentBox = new Box(0, 1);
|
|
419
|
+
this.#contentText = new WidthAwareText(contentWidth => this.#renderDefaultCard(contentWidth), 1, 1);
|
|
420
|
+
|
|
421
|
+
// Use Box for custom tools or built-in tools that have renderers
|
|
422
|
+
const hasRenderer = toolName in toolRenderers;
|
|
423
|
+
const hasCustomRenderer = !!(tool?.renderCall || tool?.renderResult);
|
|
424
|
+
this.#usesContentBox = hasCustomRenderer || hasRenderer;
|
|
425
|
+
if (this.#usesContentBox) {
|
|
426
|
+
this.addChild(this.#contentBox);
|
|
427
|
+
} else {
|
|
428
|
+
this.addChild(this.#contentText);
|
|
429
|
+
}
|
|
430
|
+
// Tool blocks are visually distinct cards (background-tinted or framed),
|
|
431
|
+
// so keep their horizontal padding even when the user enables tight layout.
|
|
432
|
+
this.setIgnoreTight(true);
|
|
433
|
+
|
|
434
|
+
this.#updateSpinnerAnimation();
|
|
435
|
+
this.#updateDisplay();
|
|
436
|
+
this.#schedulePreviewDiff();
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
updateArgs(args: any, _toolCallId?: string): void {
|
|
440
|
+
// Reference-equality short-circuit before any further work. Callers
|
|
441
|
+
// always allocate a new arg object on each streamed delta (see
|
|
442
|
+
// event-controller.ts and ui-helpers.ts), so a same-reference assignment
|
|
443
|
+
// signals "nothing meaningful changed" and the renderer can skip.
|
|
444
|
+
if (args === this.#args) return;
|
|
445
|
+
this.#args = args;
|
|
446
|
+
this.#displayInputVersion++;
|
|
447
|
+
this.#updateSpinnerAnimation();
|
|
448
|
+
this.#schedulePreviewDiff();
|
|
449
|
+
this.#updateDisplay();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Signal that args are complete (tool is about to execute).
|
|
454
|
+
* This triggers an immediate final diff computation for edit-like tools.
|
|
455
|
+
*/
|
|
456
|
+
setArgsComplete(_toolCallId?: string): void {
|
|
457
|
+
this.#argsComplete = true;
|
|
458
|
+
this.#updateSpinnerAnimation();
|
|
459
|
+
this.#schedulePreviewDiff();
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Await the streaming diff recompute kicked off by the most recent
|
|
464
|
+
* `updateArgs`/`setArgsComplete`. The recompute reads the file and re-runs the
|
|
465
|
+
* whole-file Myers diff off the render path, signalling completion only via a
|
|
466
|
+
* throttled `requestRender`. Tests await this to sample a *settled* preview
|
|
467
|
+
* deterministically instead of racing the spinner's render ticks.
|
|
468
|
+
*/
|
|
469
|
+
async whenPreviewSettled(): Promise<void> {
|
|
470
|
+
await this.#editDiffInFlight;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Schedule a streaming diff preview recompute, coalescing bursts of
|
|
475
|
+
* `updateArgs` into one compute at a time: run the current compute to
|
|
476
|
+
* completion and re-run only after it settles when newer args arrived, never
|
|
477
|
+
* cancelling an in-flight compute on a fresh tick. The reveal controller pushes
|
|
478
|
+
* args ~30fps and a whole-file hashline/large-file diff can outlast a frame, so
|
|
479
|
+
* cancel-per-tick would starve every compute and no preview would land until
|
|
480
|
+
* args complete. Coalescing lets each diff land, so the preview tracks the
|
|
481
|
+
* stream at the rate the diffs can sustain.
|
|
482
|
+
*/
|
|
483
|
+
#schedulePreviewDiff(): void {
|
|
484
|
+
this.#editDiffDirty = true;
|
|
485
|
+
if (this.#editDiffInFlight) return;
|
|
486
|
+
this.#editDiffInFlight = this.#drainPreviewDiff().finally(() => {
|
|
487
|
+
this.#editDiffInFlight = undefined;
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
async #drainPreviewDiff(): Promise<void> {
|
|
492
|
+
while (this.#editDiffDirty) {
|
|
493
|
+
this.#editDiffDirty = false;
|
|
494
|
+
await this.#computePreviewDiff();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
async #computePreviewDiff(): Promise<void> {
|
|
499
|
+
const editMode = this.#editMode;
|
|
500
|
+
if (!editMode) return;
|
|
501
|
+
const strategy = EDIT_MODE_STRATEGIES[editMode];
|
|
502
|
+
if (!strategy) return;
|
|
503
|
+
|
|
504
|
+
const args = this.#args;
|
|
505
|
+
if (args == null || typeof args !== "object") return;
|
|
506
|
+
|
|
507
|
+
const previewArgs = getArgsWithStreamedTextInput(args);
|
|
508
|
+
const partialJson = partialJsonOf(previewArgs);
|
|
509
|
+
let effectiveArgs: unknown;
|
|
510
|
+
try {
|
|
511
|
+
effectiveArgs = strategy.extractCompleteEdits(previewArgs, partialJson);
|
|
512
|
+
} catch {
|
|
513
|
+
effectiveArgs = previewArgs;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Coalesce duplicate computes for identical args. The key pairs the
|
|
517
|
+
// streaming flag with a content hash: the final (args-complete) pass
|
|
518
|
+
// computes an untrimmed diff and must run even when the payload is
|
|
519
|
+
// byte-identical to the last streamed chunk — only `isStreaming` differs,
|
|
520
|
+
// and it flips the trailing-line trim. Without the flag a single-line edit
|
|
521
|
+
// whose trailing payload line never gets a newline stays stuck on the
|
|
522
|
+
// trimmed "no changes" streaming preview and renders no diff. Hashing keeps
|
|
523
|
+
// the retained key tiny instead of holding the whole serialized blob.
|
|
524
|
+
const streamingState = this.#argsComplete ? "final" : "stream";
|
|
525
|
+
let argsKey: string;
|
|
526
|
+
try {
|
|
527
|
+
argsKey = `${streamingState}:${Bun.hash(JSON.stringify(effectiveArgs))}`;
|
|
528
|
+
} catch {
|
|
529
|
+
// effectiveArgs isn't JSON-serializable (exotic value in tool args).
|
|
530
|
+
// The raw streamed JSON is a plain string, so hash that instead of a
|
|
531
|
+
// timestamp — a deterministic key keeps the dedup cache working
|
|
532
|
+
// instead of recomputing (and re-reading the file) on every render.
|
|
533
|
+
argsKey = `${streamingState}:partial:${Bun.hash(partialJson ?? "")}`;
|
|
534
|
+
}
|
|
535
|
+
if (argsKey === this.#editDiffLastArgsKey) return;
|
|
536
|
+
this.#editDiffLastArgsKey = argsKey;
|
|
537
|
+
|
|
538
|
+
// Single-flight (the drain loop never overlaps computes), so this controller
|
|
539
|
+
// only ever cancels the live compute on teardown via `stopAnimation`.
|
|
540
|
+
const controller = new AbortController();
|
|
541
|
+
this.#editDiffAbort = controller;
|
|
542
|
+
|
|
543
|
+
try {
|
|
544
|
+
const isStreaming = !this.#argsComplete;
|
|
545
|
+
if (editMode === "hashline" && !this.#snapshots) return;
|
|
546
|
+
const previews = await strategy.computeDiffPreview(effectiveArgs, {
|
|
547
|
+
cwd: this.#cwd,
|
|
548
|
+
signal: controller.signal,
|
|
549
|
+
snapshots: this.#snapshots!,
|
|
550
|
+
clipboard: this.#clipboard,
|
|
551
|
+
fuzzyThreshold: this.#editFuzzyThreshold,
|
|
552
|
+
allowFuzzy: this.#editAllowFuzzy,
|
|
553
|
+
isStreaming,
|
|
554
|
+
});
|
|
555
|
+
if (controller.signal.aborted) return;
|
|
556
|
+
if (previews) {
|
|
557
|
+
this.#editDiffPreview = isStreaming ? stabilizeStreamingPreviews(previews) : previews;
|
|
558
|
+
this.#displayInputVersion++;
|
|
559
|
+
this.#updateDisplay();
|
|
560
|
+
this.#ui.requestRender();
|
|
561
|
+
}
|
|
562
|
+
} catch (err) {
|
|
563
|
+
if (controller.signal.aborted) return;
|
|
564
|
+
logger.warn("Edit preview diff failed", { tool: this.#toolName, error: String(err) });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
updateResult(
|
|
569
|
+
result: {
|
|
570
|
+
content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;
|
|
571
|
+
details?: any;
|
|
572
|
+
isError?: boolean;
|
|
573
|
+
},
|
|
574
|
+
isPartial = false,
|
|
575
|
+
_toolCallId?: string,
|
|
576
|
+
): void {
|
|
577
|
+
// A detached task spawn keeps streaming progress snapshots after the
|
|
578
|
+
// block froze (left the transcript live region, or its rows entered
|
|
579
|
+
// native scrollback). Drop them: repainting would rewrite rows the
|
|
580
|
+
// engine may already have committed. The terminal snapshot (async
|
|
581
|
+
// completed/failed → isPartial=false) still settles a card that is
|
|
582
|
+
// wholly uncommitted (still on screen); once any row is on the tape
|
|
583
|
+
// the card is immutable history — replacing it would re-commit the
|
|
584
|
+
// whole slab below the stale copy — so the settlement is dropped and
|
|
585
|
+
// the job's result surfaces through its own delivery message.
|
|
586
|
+
if (this.#toolName === "task" && this.#maybeFreezeBackgroundTask()) {
|
|
587
|
+
if (isPartial) return;
|
|
588
|
+
if (!(this.#liveRegion?.isBlockUncommitted?.(this) ?? true)) return;
|
|
589
|
+
}
|
|
590
|
+
const hadNoResult = this.#result === undefined;
|
|
591
|
+
const wasPartialResult = this.#result !== undefined && this.#isPartial;
|
|
592
|
+
const firstResultRepaintShapePainted = this.#firstResultViewportRepaintShapePainted;
|
|
593
|
+
const partialResultPainted = this.#partialResultShapePainted;
|
|
594
|
+
this.#firstResultViewportRepaintShapePainted = false;
|
|
595
|
+
this.#partialResultShapePainted = false;
|
|
596
|
+
this.#result = result;
|
|
597
|
+
this.#resultVersion++;
|
|
598
|
+
this.#isPartial = isPartial;
|
|
599
|
+
this.#displaceableByToolName = displaceableToolName(this.#toolName, result, isPartial);
|
|
600
|
+
// When tool is complete, ensure args are marked complete so spinner stops
|
|
601
|
+
if (!isPartial) {
|
|
602
|
+
this.#argsComplete = true;
|
|
603
|
+
}
|
|
604
|
+
this.#updateSpinnerAnimation();
|
|
605
|
+
this.#updateTodoStrikeAnimation();
|
|
606
|
+
this.#updateDisplay();
|
|
607
|
+
this.#resetDisplayForResultTopologyChange(
|
|
608
|
+
hadNoResult && firstResultRepaintShapePainted,
|
|
609
|
+
wasPartialResult && partialResultPainted,
|
|
610
|
+
isPartial,
|
|
611
|
+
);
|
|
612
|
+
// Convert non-PNG images to PNG for Kitty protocol (async)
|
|
613
|
+
this.#maybeConvertImagesForKitty();
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Get all image blocks from result content and details.images.
|
|
618
|
+
* Some tools (like generate_image) store images in details to avoid bloating model context.
|
|
619
|
+
*/
|
|
620
|
+
#getAllImageBlocks(): Array<{ data?: string; mimeType?: string }> {
|
|
621
|
+
if (!this.#result) return [];
|
|
622
|
+
const contentImages = this.#result.content?.filter((c: any) => c.type === "image") || [];
|
|
623
|
+
const detailImages = this.#result.details?.images || [];
|
|
624
|
+
return [...contentImages, ...detailImages];
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Convert non-PNG images to PNG for Kitty graphics protocol.
|
|
629
|
+
* Kitty requires PNG format (f=100), so JPEG/GIF/WebP won't display.
|
|
630
|
+
*/
|
|
631
|
+
#maybeConvertImagesForKitty(): void {
|
|
632
|
+
// Only needed for Kitty protocol
|
|
633
|
+
if (TERMINAL.imageProtocol !== ImageProtocol.Kitty) return;
|
|
634
|
+
if (!this.#result) return;
|
|
635
|
+
|
|
636
|
+
const imageBlocks = this.#getAllImageBlocks();
|
|
637
|
+
|
|
638
|
+
for (let i = 0; i < imageBlocks.length; i++) {
|
|
639
|
+
const img = imageBlocks[i];
|
|
640
|
+
if (!img.data || !img.mimeType) continue;
|
|
641
|
+
// Skip if already PNG or already converted
|
|
642
|
+
if (img.mimeType === "image/png") continue;
|
|
643
|
+
if (this.#convertedImages.has(i)) continue;
|
|
644
|
+
|
|
645
|
+
// Convert async - catch errors from processing
|
|
646
|
+
const index = i;
|
|
647
|
+
convertImageToPng({ type: "image", data: img.data, mimeType: img.mimeType })
|
|
648
|
+
.then(converted => {
|
|
649
|
+
this.#convertedImages.set(index, converted);
|
|
650
|
+
this.#displayInputVersion++;
|
|
651
|
+
this.#updateDisplay();
|
|
652
|
+
this.#ui.requestRender();
|
|
653
|
+
})
|
|
654
|
+
.catch(() => {
|
|
655
|
+
// Ignore conversion failures - display will use original image format
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Start or stop spinner animation for live states that visibly tick.
|
|
662
|
+
*/
|
|
663
|
+
#updateSpinnerAnimation(): void {
|
|
664
|
+
// Live partial tool blocks stay repaintable until a terminal result seals
|
|
665
|
+
// them. Todo snapshots and detached background tool progress are deliberate
|
|
666
|
+
// static exceptions because their rows can be superseded or committed to
|
|
667
|
+
// scrollback while later updates continue elsewhere.
|
|
668
|
+
const isStreamingArgs = !this.#argsComplete && (isEditLikeToolName(this.#toolName) || this.#toolName === "write");
|
|
669
|
+
const isBackgroundAsyncRunning =
|
|
670
|
+
(this.#result?.details as { async?: { state?: string } } | undefined)?.async?.state === "running";
|
|
671
|
+
const renderer = toolRenderers[this.#toolName] as
|
|
672
|
+
| {
|
|
673
|
+
animatedPendingPreview?: boolean | ((args: unknown) => boolean);
|
|
674
|
+
animatedPartialResult?: boolean | ((args: unknown) => boolean);
|
|
675
|
+
}
|
|
676
|
+
| undefined;
|
|
677
|
+
const pendingAnimation = renderer?.animatedPendingPreview;
|
|
678
|
+
const partialAnimation = renderer?.animatedPartialResult;
|
|
679
|
+
const pendingCallConsumesSpinner =
|
|
680
|
+
this.#result === undefined &&
|
|
681
|
+
(renderer === undefined
|
|
682
|
+
? // Only the generic #formatToolExecution fallback consumes the frame;
|
|
683
|
+
// a custom renderCall/renderResult pair routes through the custom
|
|
684
|
+
// branch whose pending label is a static tool-name Text.
|
|
685
|
+
!this.#tool?.renderCall && !this.#tool?.renderResult
|
|
686
|
+
: typeof pendingAnimation === "function"
|
|
687
|
+
? pendingAnimation(this.#args)
|
|
688
|
+
: pendingAnimation === true);
|
|
689
|
+
const partialResultConsumesSpinner =
|
|
690
|
+
this.#result !== undefined &&
|
|
691
|
+
(renderer === undefined
|
|
692
|
+
? !this.#tool?.renderCall && !this.#tool?.renderResult
|
|
693
|
+
: typeof partialAnimation === "function"
|
|
694
|
+
? partialAnimation(this.#args)
|
|
695
|
+
: partialAnimation === true);
|
|
696
|
+
const isLivePartialTool =
|
|
697
|
+
this.#isPartial &&
|
|
698
|
+
this.#toolName !== "todo" &&
|
|
699
|
+
!isBackgroundAsyncRunning &&
|
|
700
|
+
(pendingCallConsumesSpinner || partialResultConsumesSpinner);
|
|
701
|
+
const needsSpinner = isStreamingArgs || isLivePartialTool || this.#displaceableByToolName === "hub";
|
|
702
|
+
if (needsSpinner && !this.#spinnerInterval) {
|
|
703
|
+
const frameCount = theme.spinnerFrames.length;
|
|
704
|
+
const frame = sharedSpinnerFrame(frameCount);
|
|
705
|
+
this.#spinnerFrame = frame;
|
|
706
|
+
this.#renderState.spinnerFrame = frame;
|
|
707
|
+
this.#spinnerInterval = setInterval(() => {
|
|
708
|
+
// If a detached task interval from an older render path is still live,
|
|
709
|
+
// stop it the instant the block leaves the repaintable region.
|
|
710
|
+
if (this.#maybeFreezeBackgroundTask()) return;
|
|
711
|
+
const now = performance.now();
|
|
712
|
+
const frameCount = theme.spinnerFrames.length;
|
|
713
|
+
this.#spinnerFrame = sharedSpinnerFrame(frameCount, now);
|
|
714
|
+
this.#renderState.spinnerFrame = this.#spinnerFrame;
|
|
715
|
+
// Component-scoped: a spinner tick only changes this tool block, so
|
|
716
|
+
// the TUI reuses every other root subtree instead of walking the
|
|
717
|
+
// whole tree (issue #4377).
|
|
718
|
+
this.#ui.requestComponentRender(this);
|
|
719
|
+
}, SPINNER_RENDER_INTERVAL_MS);
|
|
720
|
+
} else if (!needsSpinner && this.#spinnerInterval) {
|
|
721
|
+
clearInterval(this.#spinnerInterval);
|
|
722
|
+
this.#spinnerInterval = undefined;
|
|
723
|
+
// Clear the last drawn frame so a non-live renderCall (e.g. a write whose
|
|
724
|
+
// args just completed) stops showing a frozen spinner glyph. Skip when a
|
|
725
|
+
// todo strike owns the frame — it sets its own value right after this.
|
|
726
|
+
if (!this.#todoStrikeInterval) {
|
|
727
|
+
this.#spinnerFrame = undefined;
|
|
728
|
+
this.#renderState.spinnerFrame = undefined;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Freeze a detached (`async.state === "running"`) task block once its rows
|
|
735
|
+
* become native-scrollback history: the block left the transcript's live
|
|
736
|
+
* region (a later block streams below it), or — while it is still the
|
|
737
|
+
* live tail — its head rows were committed because the frame outgrew the
|
|
738
|
+
* viewport. Committed rows are immutable, so from that point every further
|
|
739
|
+
* partial snapshot is dropped. Rows restyle static gray only when nothing
|
|
740
|
+
* is committed yet; otherwise the bytes stay exactly as painted. One-way —
|
|
741
|
+
* blocks never re-enter the live region. Returns whether the block is
|
|
742
|
+
* frozen.
|
|
743
|
+
*/
|
|
744
|
+
#maybeFreezeBackgroundTask(): boolean {
|
|
745
|
+
if (this.#backgroundTaskFrozen) return true;
|
|
746
|
+
if (this.#toolName !== "task" || this.#liveRegion === undefined) return false;
|
|
747
|
+
const asyncState = (this.#result?.details as { async?: { state?: string } } | undefined)?.async?.state;
|
|
748
|
+
if (asyncState !== "running") return false;
|
|
749
|
+
const uncommitted = this.#liveRegion.isBlockUncommitted?.(this) ?? true;
|
|
750
|
+
if (uncommitted && this.#liveRegion.isBlockInLiveRegion(this)) return false;
|
|
751
|
+
this.#backgroundTaskFrozen = true;
|
|
752
|
+
this.#updateSpinnerAnimation();
|
|
753
|
+
if (uncommitted) {
|
|
754
|
+
this.#backgroundTaskFrozenStyled = true;
|
|
755
|
+
this.#updateDisplay();
|
|
756
|
+
this.#ui.requestRender();
|
|
757
|
+
}
|
|
758
|
+
return true;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
#updateTodoStrikeAnimation(): void {
|
|
762
|
+
if (this.#toolName !== "todo" || this.#isPartial || this.#result?.isError) {
|
|
763
|
+
this.#stopTodoStrikeAnimation();
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
const completedTasks = (this.#result?.details as { completedTasks?: unknown[] } | undefined)?.completedTasks;
|
|
767
|
+
if (!completedTasks || completedTasks.length === 0) {
|
|
768
|
+
this.#stopTodoStrikeAnimation();
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
if (this.#todoStrikeInterval) return;
|
|
772
|
+
|
|
773
|
+
this.#spinnerFrame = 0;
|
|
774
|
+
this.#renderState.spinnerFrame = 0;
|
|
775
|
+
this.#todoStrikeInterval = setInterval(() => {
|
|
776
|
+
const nextFrame = (this.#spinnerFrame ?? 0) + 1;
|
|
777
|
+
if (nextFrame > TODO_STRIKE_TOTAL_FRAMES) {
|
|
778
|
+
this.#stopTodoStrikeAnimation();
|
|
779
|
+
} else {
|
|
780
|
+
this.#spinnerFrame = nextFrame;
|
|
781
|
+
this.#renderState.spinnerFrame = nextFrame;
|
|
782
|
+
}
|
|
783
|
+
// Component-scoped: strike animation only mutates this tool block's
|
|
784
|
+
// glyph, so the TUI reuses every other root subtree (issue #4377).
|
|
785
|
+
this.#ui.requestComponentRender(this);
|
|
786
|
+
}, 65);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
#stopTodoStrikeAnimation(): void {
|
|
790
|
+
if (this.#todoStrikeInterval) {
|
|
791
|
+
clearInterval(this.#todoStrikeInterval);
|
|
792
|
+
this.#todoStrikeInterval = undefined;
|
|
793
|
+
}
|
|
794
|
+
if (!this.#spinnerInterval) {
|
|
795
|
+
this.#spinnerFrame = undefined;
|
|
796
|
+
this.#renderState.spinnerFrame = undefined;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Standalone harnesses may mount a tool component directly under `TUI`
|
|
802
|
+
* instead of inside `TranscriptContainer`. In that shape the component must
|
|
803
|
+
* report its own live-region seam while unfinalized, or the core renderer
|
|
804
|
+
* treats it like shell output and commits still-mutating preview rows to
|
|
805
|
+
* immutable native scrollback before the result replaces them.
|
|
806
|
+
*/
|
|
807
|
+
getNativeScrollbackLiveRegionStart(): number | undefined {
|
|
808
|
+
return this.isTranscriptBlockFinalized() ? undefined : 0;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Keeps in-flight TV-wall frames out of immutable native scrollback: the
|
|
813
|
+
* `vibe_wait` wall, displaceable snapshots (`hub` waiting polls, `todo`
|
|
814
|
+
* lists), and live `task` calls. Their frames replace each other rather
|
|
815
|
+
* than append — task progress rows rewrite in place on every snapshot —
|
|
816
|
+
* so an unpinned commit records a per-tick frozen snapshot (and for
|
|
817
|
+
* displaceable blocks force-seals them, stacking the next poll below).
|
|
818
|
+
* The finalized frame commits exactly once when the pin lifts.
|
|
819
|
+
*/
|
|
820
|
+
isNativeScrollbackLiveRegionPinned(): boolean {
|
|
821
|
+
if (this.isTranscriptBlockFinalized()) return false;
|
|
822
|
+
return this.#toolName === "vibe_wait" || this.#toolName === "task" || this.#displaceableByToolName !== undefined;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Whether this block has reached a terminal state for transcript freezing.
|
|
827
|
+
* Reports `false` while it can still visually change so the
|
|
828
|
+
* {@link TranscriptContainer} keeps it inside the repaintable live region:
|
|
829
|
+
* a foreground tool awaiting its result, or one streaming partial output.
|
|
830
|
+
* A final (non-partial) result, a background-async tool the agent has moved
|
|
831
|
+
* past, or an explicit {@link seal} flips it to `true`.
|
|
832
|
+
*/
|
|
833
|
+
isTranscriptBlockFinalized(): boolean {
|
|
834
|
+
if (this.#sealed) return true;
|
|
835
|
+
if (this.#result === undefined) return false;
|
|
836
|
+
// A displaceable snapshot stays live: its rows are kept out of native
|
|
837
|
+
// scrollback so a follow-up tool call can remove the block.
|
|
838
|
+
if (this.#displaceableByToolName) return false;
|
|
839
|
+
if (!this.#isPartial) return true;
|
|
840
|
+
// Partial result: a background async tool is accepted to freeze (the agent
|
|
841
|
+
// continues while it runs and would otherwise pin an unbounded live region);
|
|
842
|
+
// a foreground tool streaming partial output stays live until it finishes.
|
|
843
|
+
return (this.#result.details as { async?: { state?: string } } | undefined)?.async?.state === "running";
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Mark the tool terminal even though no result arrived (the turn aborted or
|
|
848
|
+
* abandoned it) and stop animating, so it can freeze and stops pinning the
|
|
849
|
+
* transcript live region.
|
|
850
|
+
*/
|
|
851
|
+
seal(): void {
|
|
852
|
+
if (this.#sealed) return;
|
|
853
|
+
this.#sealed = true;
|
|
854
|
+
this.#displaceableByToolName = undefined;
|
|
855
|
+
// A sealed detached task is abandoned history: settle its progress rows
|
|
856
|
+
// on static gray — but only while none of them are committed; a recolor
|
|
857
|
+
// on the tape would diverge immutable history.
|
|
858
|
+
this.#backgroundTaskFrozen = true;
|
|
859
|
+
if (this.#liveRegion?.isBlockUncommitted?.(this) ?? true) {
|
|
860
|
+
this.#backgroundTaskFrozenStyled = true;
|
|
861
|
+
}
|
|
862
|
+
this.stopAnimation();
|
|
863
|
+
this.#updateDisplay();
|
|
864
|
+
this.#ui.requestRender();
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Whether this block is a supersedable result snapshot that has not been
|
|
869
|
+
* sealed. Such a block never finalized, so none of its rows entered native
|
|
870
|
+
* scrollback and the whole block can be removed when a follow-up matching
|
|
871
|
+
* tool call supersedes it.
|
|
872
|
+
*/
|
|
873
|
+
isDisplaceableBlock(): boolean {
|
|
874
|
+
return this.#displaceableByToolName !== undefined && !this.#sealed;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
canBeDisplacedBy(nextToolName: string | undefined): boolean {
|
|
878
|
+
return (
|
|
879
|
+
this.#displaceableByToolName !== undefined && this.#displaceableByToolName === nextToolName && !this.#sealed
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* Stop spinner animation and cleanup resources.
|
|
885
|
+
*/
|
|
886
|
+
stopAnimation(): void {
|
|
887
|
+
if (this.#spinnerInterval) {
|
|
888
|
+
clearInterval(this.#spinnerInterval);
|
|
889
|
+
this.#spinnerInterval = undefined;
|
|
890
|
+
this.#spinnerFrame = undefined;
|
|
891
|
+
this.#renderState.spinnerFrame = undefined;
|
|
892
|
+
}
|
|
893
|
+
this.#stopTodoStrikeAnimation();
|
|
894
|
+
this.#editDiffAbort?.abort();
|
|
895
|
+
this.#editDiffAbort = undefined;
|
|
896
|
+
// Drop any queued rerun so the drain loop exits instead of recomputing a
|
|
897
|
+
// preview for a torn-down block after its in-flight compute is aborted.
|
|
898
|
+
this.#editDiffDirty = false;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
setExpanded(expanded: boolean): void {
|
|
902
|
+
this.#expanded = expanded;
|
|
903
|
+
this.#updateDisplay();
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
setToolActivityVisible(visible: boolean): void {
|
|
907
|
+
this.#toolActivityVisible = visible;
|
|
908
|
+
super.invalidate();
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
setShowImages(show: boolean): void {
|
|
912
|
+
this.#showImages = show;
|
|
913
|
+
this.#updateDisplay();
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
override invalidate(): void {
|
|
917
|
+
super.invalidate();
|
|
918
|
+
this.#updateDisplay();
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
#updateDisplay(): void {
|
|
922
|
+
// `TERMINAL.imageProtocol` is resolved by an async capability probe during
|
|
923
|
+
// TUI startup, so a result rendered before it lands must re-shape once it
|
|
924
|
+
// does (it gates Image children vs text fallback in #rebuildDisplay); keyed
|
|
925
|
+
// here for the same reason markdown.ts keys its render cache on it.
|
|
926
|
+
const key = `${this.#resultVersion}|${this.#expanded}|${this.#isPartial}|${this.#spinnerFrame ?? "-"}|${this.#showImages}|${getThemeEpoch()}|${this.#displayInputVersion}|${this.#backgroundTaskFrozenStyled}|${TERMINAL.imageProtocol ?? "-"}|${this.#imageSizeKey()}`;
|
|
927
|
+
if (key === this.#lastDisplayKey && this.#displayBuilt) return;
|
|
928
|
+
this.#lastDisplayKey = key;
|
|
929
|
+
|
|
930
|
+
this.#rebuildDisplay();
|
|
931
|
+
this.#displayBuilt = true;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
#rendererFlag(name: "forceResultViewportRepaintOnSettle"): boolean {
|
|
935
|
+
const toolValue = (this.#tool as Record<string, unknown> | undefined)?.[name];
|
|
936
|
+
const rendererValue = toolRenderers[this.#toolName]?.[name];
|
|
937
|
+
return toolValue === true || (toolValue === undefined && rendererValue === true);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* True while the last painted pending-call shape opted into a full viewport
|
|
942
|
+
* repaint at the first result (`forceFirstResultViewportRepaint`) — e.g. a
|
|
943
|
+
* collapsed write tail window, which the first result render re-anchors
|
|
944
|
+
* instead of preserving. Kept as a per-paint fact so a topology-changing update that
|
|
945
|
+
* lands before the pending rows reach the terminal skips the reset.
|
|
946
|
+
*/
|
|
947
|
+
#needsFirstResultViewportRepaintAtRender(): boolean {
|
|
948
|
+
if (this.#result !== undefined) return false;
|
|
949
|
+
const toolValue = (this.#tool as { forceFirstResultViewportRepaint?: FirstResultViewportRepaint } | undefined)
|
|
950
|
+
?.forceFirstResultViewportRepaint;
|
|
951
|
+
const value =
|
|
952
|
+
toolValue !== undefined ? toolValue : toolRenderers[this.#toolName]?.forceFirstResultViewportRepaint;
|
|
953
|
+
if (typeof value === "function") return value(this.#args, this.#renderState);
|
|
954
|
+
return value === true;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
#resetDisplayForResultTopologyChange(
|
|
958
|
+
firstResultAfterRepaintShapePaint: boolean,
|
|
959
|
+
partialResultPaintedBeforeSettle: boolean,
|
|
960
|
+
isPartial: boolean,
|
|
961
|
+
): void {
|
|
962
|
+
const provisionalResultSettled =
|
|
963
|
+
partialResultPaintedBeforeSettle && !isPartial && this.#rendererFlag("forceResultViewportRepaintOnSettle");
|
|
964
|
+
if (firstResultAfterRepaintShapePaint || provisionalResultSettled) {
|
|
965
|
+
this.#ui.resetDisplay();
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
override render(width: number): readonly string[] {
|
|
970
|
+
if (!this.#toolActivityVisible) return [];
|
|
971
|
+
const lines = super.render(width);
|
|
972
|
+
// Update the paint-tracking flags after `super.render(width)` — the
|
|
973
|
+
// override runs on every compose the parent Container performs, so a
|
|
974
|
+
// frame that never gets composed leaves the flags false and prevents a
|
|
975
|
+
// spurious `resetDisplay()`.
|
|
976
|
+
this.#firstResultViewportRepaintShapePainted = this.#needsFirstResultViewportRepaintAtRender();
|
|
977
|
+
this.#partialResultShapePainted = this.#result !== undefined && this.#isPartial;
|
|
978
|
+
return lines;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// Viewport-/settings-dependent image sizing folded into the memo key only when
|
|
982
|
+
// the last rebuild actually emitted images, so a terminal resize re-shapes an
|
|
983
|
+
// image-bearing result (to rescale it) without re-shaping every image-free
|
|
984
|
+
// result on each resize tick.
|
|
985
|
+
#imageSizeKey(): string {
|
|
986
|
+
if (this.#renderedImageCount === 0) return "-";
|
|
987
|
+
const o = resolveImageOptions();
|
|
988
|
+
return `${o.maxWidthCells}:${o.maxHeightCells ?? "-"}`;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
#rebuildDisplay(): void {
|
|
992
|
+
// Sync shared mutable render state for component closures
|
|
993
|
+
this.#renderState.expanded = this.#expanded;
|
|
994
|
+
this.#renderState.isPartial = this.#isPartial;
|
|
995
|
+
this.#renderState.spinnerFrame = this.#spinnerFrame;
|
|
996
|
+
|
|
997
|
+
// Non-self-framing tools (custom/extension renderers and the generic
|
|
998
|
+
// fallback) get a padded, state-tinted block — built-ins that draw their
|
|
999
|
+
// own frame opt out below via the framed-component mark. A benign skip
|
|
1000
|
+
// (steering/peer interrupt aborted a still-pending call) never ran, so it
|
|
1001
|
+
// gets the neutral pending tint rather than the error tint (#7199).
|
|
1002
|
+
const benignSkip = this.#isBenignSkip();
|
|
1003
|
+
const stateBgKey =
|
|
1004
|
+
this.#isPartial || benignSkip ? "toolPendingBg" : this.#result?.isError ? "toolErrorBg" : "toolSuccessBg";
|
|
1005
|
+
const stateBgFn = (t: string) => theme.bg(stateBgKey, t);
|
|
1006
|
+
|
|
1007
|
+
// A benign skip is a synthetic placeholder for a call that never executed,
|
|
1008
|
+
// so bypass any bespoke error frame and draw the neutral generic card —
|
|
1009
|
+
// the per-tool ✘/red-border would misread normal mid-turn steering as a
|
|
1010
|
+
// failure (#7199).
|
|
1011
|
+
if (benignSkip) {
|
|
1012
|
+
this.#renderBenignSkipCard(stateBgFn);
|
|
1013
|
+
} else if (this.#tool && (this.#tool.renderCall || this.#tool.renderResult)) {
|
|
1014
|
+
const tool = this.#tool;
|
|
1015
|
+
const mergeCallAndResult = Boolean((tool as { mergeCallAndResult?: boolean }).mergeCallAndResult);
|
|
1016
|
+
// Custom tools use Box for flexible component rendering
|
|
1017
|
+
this.#contentBox.setBgFn(undefined);
|
|
1018
|
+
this.#contentBox.clear();
|
|
1019
|
+
// Mirror the built-in renderer branch so custom renderers (notably the
|
|
1020
|
+
// task tool, whose live instance routes through here) receive the same
|
|
1021
|
+
// render context — e.g. the `hasResult` flag that suppresses the task
|
|
1022
|
+
// call preview once result lines exist.
|
|
1023
|
+
this.#renderState.renderContext = this.#buildRenderContext();
|
|
1024
|
+
|
|
1025
|
+
// Render call component. The fallback label only stands in for a
|
|
1026
|
+
// missing `renderCall`; when the call is intentionally suppressed
|
|
1027
|
+
// (mergeCallAndResult once a result exists) we render nothing here so
|
|
1028
|
+
// the result component isn't preceded by a redundant tool-name line.
|
|
1029
|
+
const shouldRenderCall = !this.#result || !mergeCallAndResult;
|
|
1030
|
+
if (shouldRenderCall) {
|
|
1031
|
+
if (tool.renderCall) {
|
|
1032
|
+
try {
|
|
1033
|
+
const callArgs = this.#getCallArgsForRender();
|
|
1034
|
+
const callComponent = tool.renderCall(callArgs, this.#renderState, theme) as Component | undefined;
|
|
1035
|
+
if (callComponent) {
|
|
1036
|
+
this.#contentBox.addChild(
|
|
1037
|
+
new SafeToolRendererComponent(
|
|
1038
|
+
this.#toolName,
|
|
1039
|
+
"call",
|
|
1040
|
+
callComponent,
|
|
1041
|
+
() => new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0),
|
|
1042
|
+
),
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
} catch (err) {
|
|
1046
|
+
logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
|
|
1047
|
+
// Fall back to default on error
|
|
1048
|
+
this.#contentBox.addChild(new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0));
|
|
1049
|
+
}
|
|
1050
|
+
} else {
|
|
1051
|
+
// No custom renderCall, show tool name
|
|
1052
|
+
this.#contentBox.addChild(new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0));
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// Render result component if we have a result
|
|
1057
|
+
if (this.#result && tool.renderResult) {
|
|
1058
|
+
try {
|
|
1059
|
+
const renderResult = tool.renderResult as (
|
|
1060
|
+
result: { content: Array<{ type: string; text?: string }>; details?: unknown; isError?: boolean },
|
|
1061
|
+
options: { expanded: boolean; isPartial: boolean; spinnerFrame?: number },
|
|
1062
|
+
theme: Theme,
|
|
1063
|
+
args?: unknown,
|
|
1064
|
+
) => Component;
|
|
1065
|
+
const resultComponent = renderResult(
|
|
1066
|
+
{
|
|
1067
|
+
content: this.#result.content as any,
|
|
1068
|
+
details: this.#result.details,
|
|
1069
|
+
isError: this.#result.isError,
|
|
1070
|
+
},
|
|
1071
|
+
this.#renderState,
|
|
1072
|
+
theme,
|
|
1073
|
+
this.#args,
|
|
1074
|
+
);
|
|
1075
|
+
if (resultComponent) {
|
|
1076
|
+
this.#contentBox.addChild(
|
|
1077
|
+
new SafeToolRendererComponent(this.#toolName, "result", resultComponent, () => {
|
|
1078
|
+
const output = this.#getTextOutput();
|
|
1079
|
+
if (!output) return undefined;
|
|
1080
|
+
return new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0);
|
|
1081
|
+
}),
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
} catch (err) {
|
|
1085
|
+
logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
|
|
1086
|
+
// Fall back to showing raw output on error
|
|
1087
|
+
const output = this.#getTextOutput();
|
|
1088
|
+
if (output) {
|
|
1089
|
+
this.#contentBox.addChild(new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0));
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
} else if (this.#result) {
|
|
1093
|
+
// Has result but no custom renderResult
|
|
1094
|
+
const output = this.#getTextOutput();
|
|
1095
|
+
if (output) {
|
|
1096
|
+
this.#contentBox.addChild(new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0));
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
// Custom tools that draw their own frame (task) render flush; plain
|
|
1100
|
+
// extension renderers get the padded, state-tinted block back.
|
|
1101
|
+
const customFramed = this.#contentBox.children.some(isFramedBlockComponent);
|
|
1102
|
+
this.#contentBox.setPaddingX(customFramed ? 0 : 1);
|
|
1103
|
+
this.#contentBox.setBgFn(customFramed ? undefined : stateBgFn);
|
|
1104
|
+
} else if (this.#toolName in toolRenderers) {
|
|
1105
|
+
// Built-in tools with renderers
|
|
1106
|
+
const renderer = toolRenderers[this.#toolName];
|
|
1107
|
+
|
|
1108
|
+
// Clean up previous multi-file boxes
|
|
1109
|
+
for (const box of this.#multiFileBoxes) {
|
|
1110
|
+
this.removeChild(box);
|
|
1111
|
+
}
|
|
1112
|
+
this.#multiFileBoxes = [];
|
|
1113
|
+
|
|
1114
|
+
// Check for multi-file edit results
|
|
1115
|
+
const perFileResults = this.#result?.details?.perFileResults as
|
|
1116
|
+
| Array<{ path: string; isError?: boolean }>
|
|
1117
|
+
| undefined;
|
|
1118
|
+
if (perFileResults && perFileResults.length > 1) {
|
|
1119
|
+
// Multi-file: render each file as its own Box (identical to separate tool calls)
|
|
1120
|
+
this.#contentBox.setBgFn(undefined);
|
|
1121
|
+
this.#contentBox.clear();
|
|
1122
|
+
|
|
1123
|
+
const renderContext = this.#buildRenderContext();
|
|
1124
|
+
this.#renderState.renderContext = renderContext;
|
|
1125
|
+
|
|
1126
|
+
for (let i = 0; i < perFileResults.length; i++) {
|
|
1127
|
+
const fileResult = perFileResults[i];
|
|
1128
|
+
if (i > 0) {
|
|
1129
|
+
const spacer = new Spacer(1);
|
|
1130
|
+
this.#multiFileBoxes.push(spacer);
|
|
1131
|
+
this.addChild(spacer);
|
|
1132
|
+
}
|
|
1133
|
+
const fileBox = new Box(0, 0);
|
|
1134
|
+
try {
|
|
1135
|
+
const resultComponent = renderer.renderResult(
|
|
1136
|
+
{ content: [], details: fileResult, isError: fileResult.isError },
|
|
1137
|
+
this.#renderState,
|
|
1138
|
+
theme,
|
|
1139
|
+
);
|
|
1140
|
+
if (resultComponent) {
|
|
1141
|
+
fileBox.addChild(
|
|
1142
|
+
new SafeToolRendererComponent(this.#toolName, "result", resultComponent, () => undefined),
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1145
|
+
} catch (err) {
|
|
1146
|
+
logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
|
|
1147
|
+
}
|
|
1148
|
+
this.#multiFileBoxes.push(fileBox);
|
|
1149
|
+
this.addChild(fileBox);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
// Show pending indicator for remaining files
|
|
1153
|
+
const totalFiles = this.#args?.edits
|
|
1154
|
+
? new Set((this.#args.edits as any[]).map((e: any) => e?.path).filter(Boolean)).size
|
|
1155
|
+
: 0;
|
|
1156
|
+
const remaining = Math.max(0, totalFiles - perFileResults.length);
|
|
1157
|
+
if (remaining > 0 && this.#isPartial) {
|
|
1158
|
+
const pendingSpacer = new Spacer(1);
|
|
1159
|
+
this.#multiFileBoxes.push(pendingSpacer);
|
|
1160
|
+
this.addChild(pendingSpacer);
|
|
1161
|
+
const pendingBox = new Box(0, 0);
|
|
1162
|
+
const spinner =
|
|
1163
|
+
this.#spinnerFrame !== undefined ? formatStatusIcon("running", theme, this.#spinnerFrame) : "";
|
|
1164
|
+
const pendingText = renderStatusLine(
|
|
1165
|
+
{
|
|
1166
|
+
iconOverride: spinner,
|
|
1167
|
+
title: "Edit",
|
|
1168
|
+
description: theme.fg("dim", `${remaining} more file${remaining > 1 ? "s" : ""} pending…`),
|
|
1169
|
+
},
|
|
1170
|
+
theme,
|
|
1171
|
+
);
|
|
1172
|
+
pendingBox.addChild(new Text(pendingText, 0, 0));
|
|
1173
|
+
this.#multiFileBoxes.push(pendingBox);
|
|
1174
|
+
this.addChild(pendingBox);
|
|
1175
|
+
}
|
|
1176
|
+
} else {
|
|
1177
|
+
// Single-file or no result: standard rendering
|
|
1178
|
+
// Inline renderers skip background styling
|
|
1179
|
+
this.#contentBox.setBgFn(undefined);
|
|
1180
|
+
this.#contentBox.clear();
|
|
1181
|
+
|
|
1182
|
+
const renderContext = this.#buildRenderContext();
|
|
1183
|
+
this.#renderState.renderContext = renderContext;
|
|
1184
|
+
|
|
1185
|
+
const shouldRenderCall = !this.#result || !renderer.mergeCallAndResult;
|
|
1186
|
+
if (shouldRenderCall) {
|
|
1187
|
+
// Render call component
|
|
1188
|
+
try {
|
|
1189
|
+
const callArgs = this.#getCallArgsForRender();
|
|
1190
|
+
const callComponent = renderer.renderCall(callArgs, this.#renderState, theme);
|
|
1191
|
+
if (callComponent) {
|
|
1192
|
+
this.#contentBox.addChild(
|
|
1193
|
+
new SafeToolRendererComponent(
|
|
1194
|
+
this.#toolName,
|
|
1195
|
+
"call",
|
|
1196
|
+
callComponent,
|
|
1197
|
+
() => new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0),
|
|
1198
|
+
),
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
} catch (err) {
|
|
1202
|
+
logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
|
|
1203
|
+
// Fall back to default on error
|
|
1204
|
+
this.#contentBox.addChild(new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0));
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// Render result component if we have a result
|
|
1209
|
+
if (this.#result) {
|
|
1210
|
+
try {
|
|
1211
|
+
const resultComponent = renderer.renderResult(
|
|
1212
|
+
{
|
|
1213
|
+
content: this.#result.content as any,
|
|
1214
|
+
details: this.#result.details,
|
|
1215
|
+
isError: this.#result.isError,
|
|
1216
|
+
},
|
|
1217
|
+
this.#renderState,
|
|
1218
|
+
theme,
|
|
1219
|
+
this.#getCallArgsForRender(),
|
|
1220
|
+
);
|
|
1221
|
+
if (resultComponent) {
|
|
1222
|
+
this.#contentBox.addChild(
|
|
1223
|
+
new SafeToolRendererComponent(this.#toolName, "result", resultComponent, () => {
|
|
1224
|
+
const output = this.#getTextOutput();
|
|
1225
|
+
if (!output) return undefined;
|
|
1226
|
+
return new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0);
|
|
1227
|
+
}),
|
|
1228
|
+
);
|
|
1229
|
+
}
|
|
1230
|
+
} catch (err) {
|
|
1231
|
+
logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
|
|
1232
|
+
// Fall back to showing raw output on error
|
|
1233
|
+
const output = this.#getTextOutput();
|
|
1234
|
+
if (output) {
|
|
1235
|
+
this.#contentBox.addChild(new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0));
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
} else {
|
|
1241
|
+
// Generic fallback (no custom/built-in renderer). WidthAwareText
|
|
1242
|
+
// reformats at render time so output fills the actual terminal width
|
|
1243
|
+
// instead of a fixed column cap.
|
|
1244
|
+
this.#contentText.setCustomBgFn(stateBgFn);
|
|
1245
|
+
this.#contentText.invalidate();
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
// Handle images (same for both custom and built-in)
|
|
1249
|
+
for (const img of this.#imageComponents) {
|
|
1250
|
+
this.removeChild(img);
|
|
1251
|
+
}
|
|
1252
|
+
this.#imageComponents = [];
|
|
1253
|
+
for (const spacer of this.#imageSpacers) {
|
|
1254
|
+
this.removeChild(spacer);
|
|
1255
|
+
}
|
|
1256
|
+
this.#imageSpacers = [];
|
|
1257
|
+
|
|
1258
|
+
if (this.#result) {
|
|
1259
|
+
const imageBlocks = this.#getAllImageBlocks();
|
|
1260
|
+
|
|
1261
|
+
for (let i = 0; i < imageBlocks.length; i++) {
|
|
1262
|
+
const img = imageBlocks[i];
|
|
1263
|
+
if (TERMINAL.imageProtocol && this.#showImages && img.data && img.mimeType) {
|
|
1264
|
+
// Use converted PNG for Kitty protocol if available
|
|
1265
|
+
const converted = this.#convertedImages.get(i);
|
|
1266
|
+
const imageData = converted?.data ?? img.data;
|
|
1267
|
+
const imageMimeType = converted?.mimeType ?? img.mimeType;
|
|
1268
|
+
|
|
1269
|
+
// For Kitty, skip non-PNG images that haven't been converted yet
|
|
1270
|
+
if (TERMINAL.imageProtocol === ImageProtocol.Kitty && imageMimeType !== "image/png") {
|
|
1271
|
+
continue;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
const spacer = new Spacer(1);
|
|
1275
|
+
this.addChild(spacer);
|
|
1276
|
+
this.#imageSpacers.push(spacer);
|
|
1277
|
+
const imageComponent = new Image(
|
|
1278
|
+
imageData,
|
|
1279
|
+
imageMimeType,
|
|
1280
|
+
{ fallbackColor: (s: string) => theme.fg("toolOutput", s) },
|
|
1281
|
+
{ ...resolveImageOptions(), budget: this.#ui.imageBudget, imageKey: `te${this.#instanceId}:${i}` },
|
|
1282
|
+
);
|
|
1283
|
+
this.#imageComponents.push(imageComponent);
|
|
1284
|
+
this.addChild(imageComponent);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
this.#renderedImageCount = this.#imageComponents.length;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
#getCallArgsForRender(): any {
|
|
1292
|
+
const renderArgs = getArgsWithStreamedTextInput(this.#args);
|
|
1293
|
+
if (!isEditLikeToolName(this.#toolName)) {
|
|
1294
|
+
return renderArgs;
|
|
1295
|
+
}
|
|
1296
|
+
const previews = this.#editDiffPreview;
|
|
1297
|
+
if (!previews || previews.length === 0) {
|
|
1298
|
+
return renderArgs;
|
|
1299
|
+
}
|
|
1300
|
+
// Single-file previews feed the existing `previewDiff` channel consumed
|
|
1301
|
+
// by `formatStreamingDiff` in the renderer.
|
|
1302
|
+
const first = previews[0];
|
|
1303
|
+
if (!first?.diff) {
|
|
1304
|
+
return renderArgs;
|
|
1305
|
+
}
|
|
1306
|
+
return { ...(renderArgs as Record<string, unknown>), previewDiff: first.diff };
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
/**
|
|
1310
|
+
* Build render context for tools that need extra state (bash, python, edit)
|
|
1311
|
+
*/
|
|
1312
|
+
#buildRenderContext(): Record<string, unknown> {
|
|
1313
|
+
const context: Record<string, unknown> = {};
|
|
1314
|
+
const normalizeTimeoutSeconds = (value: unknown, maxSeconds: number): number | undefined => {
|
|
1315
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
|
|
1316
|
+
return Math.max(1, Math.min(maxSeconds, value));
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
if (this.#toolName === "bash") {
|
|
1320
|
+
// Bash needs render context even before a result exists. The renderer uses the pending-call args
|
|
1321
|
+
// plus this context to keep the inline command preview visible while tool-call JSON is still streaming.
|
|
1322
|
+
if (this.#result) {
|
|
1323
|
+
// Pass raw output and expanded state - renderer handles width-aware truncation
|
|
1324
|
+
const output = this.#getTextOutput().trimEnd();
|
|
1325
|
+
context.output = output;
|
|
1326
|
+
}
|
|
1327
|
+
context.expanded = this.#expanded;
|
|
1328
|
+
context.previewLines = BASH_DEFAULT_PREVIEW_LINES;
|
|
1329
|
+
context.timeout = normalizeTimeoutSeconds(this.#args?.timeout, 3600);
|
|
1330
|
+
} else if (this.#toolName === "eval" && this.#result) {
|
|
1331
|
+
const output = this.#getTextOutput().trimEnd();
|
|
1332
|
+
context.output = output;
|
|
1333
|
+
context.expanded = this.#expanded;
|
|
1334
|
+
context.previewLines = EVAL_DEFAULT_PREVIEW_LINES;
|
|
1335
|
+
} else if (this.#toolName === "task") {
|
|
1336
|
+
// Once a result snapshot exists the task renderer's `renderResult`
|
|
1337
|
+
// draws every dispatched agent as a progress/result line, so tell
|
|
1338
|
+
// `renderCall` to drop its duplicate streaming preview list.
|
|
1339
|
+
context.hasResult = Boolean(this.#result);
|
|
1340
|
+
// Settled as history (out of the live region, before any row entered
|
|
1341
|
+
// the tape): progress rows render static gray (see task/render.ts).
|
|
1342
|
+
context.frozen = this.#backgroundTaskFrozenStyled;
|
|
1343
|
+
// Freeze the render clock alongside the latch — and independently the
|
|
1344
|
+
// moment any row commits, closing the window between a commit paint
|
|
1345
|
+
// and the next snapshot where a settings-triggered rebuild could
|
|
1346
|
+
// re-derive elapsed/countdown bytes under committed rows.
|
|
1347
|
+
if (!this.#backgroundTaskFrozen && (this.#liveRegion?.isBlockUncommitted?.(this) ?? true)) {
|
|
1348
|
+
this.#taskRenderNowMs = Date.now();
|
|
1349
|
+
}
|
|
1350
|
+
context.nowMs = this.#taskRenderNowMs;
|
|
1351
|
+
} else if (isEditLikeToolName(this.#toolName)) {
|
|
1352
|
+
context.editMode = this.#editMode;
|
|
1353
|
+
const previews = this.#editDiffPreview;
|
|
1354
|
+
if (previews && previews.length > 0) {
|
|
1355
|
+
const first = previews[0];
|
|
1356
|
+
if (first?.diff || first?.error) {
|
|
1357
|
+
context.editDiffPreview = first.error
|
|
1358
|
+
? { error: first.error }
|
|
1359
|
+
: { diff: first.diff ?? "", firstChangedLine: first.firstChangedLine };
|
|
1360
|
+
}
|
|
1361
|
+
if (previews.length > 1) {
|
|
1362
|
+
context.perFileDiffPreview = previews;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
if (!previews?.some(preview => preview.diff)) {
|
|
1366
|
+
const editMode = this.#editMode;
|
|
1367
|
+
const strategy = editMode ? EDIT_MODE_STRATEGIES[editMode] : undefined;
|
|
1368
|
+
const fallback = strategy?.renderStreamingFallback(getArgsWithStreamedTextInput(this.#args), theme);
|
|
1369
|
+
if (fallback) context.editStreamingFallback = fallback;
|
|
1370
|
+
}
|
|
1371
|
+
context.renderDiff = renderDiff;
|
|
1372
|
+
} else if (this.#toolName === "write") {
|
|
1373
|
+
// Device-dispatch previews resolve renderers from the canonical tool map.
|
|
1374
|
+
const writeTool = this.#tool as { session?: { xdev?: XdevState } } | undefined;
|
|
1375
|
+
const xdev = writeTool?.session?.xdev;
|
|
1376
|
+
if (xdev) {
|
|
1377
|
+
context.resolveXdevMounted = (name: string) =>
|
|
1378
|
+
xdev.mountedNames.has(name) ? xdev.tools.get(name) : undefined;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
return context;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
#getTextOutput(): string {
|
|
1386
|
+
if (!this.#result) return "";
|
|
1387
|
+
|
|
1388
|
+
const textBlocks = this.#result.content?.filter((c: any) => c.type === "text") || [];
|
|
1389
|
+
const imageBlocks = this.#getAllImageBlocks();
|
|
1390
|
+
|
|
1391
|
+
let output = textBlocks
|
|
1392
|
+
.map((c: any) => {
|
|
1393
|
+
return sanitizeWithOptionalSixelPassthrough(c.text || "", sanitizeText);
|
|
1394
|
+
})
|
|
1395
|
+
.join("\n");
|
|
1396
|
+
|
|
1397
|
+
if (imageBlocks.length > 0 && (!TERMINAL.imageProtocol || !this.#showImages)) {
|
|
1398
|
+
const imageIndicators = imageBlocks
|
|
1399
|
+
.map((img: any) => {
|
|
1400
|
+
const dims = img.data ? (getImageDimensions(img.data, img.mimeType) ?? undefined) : undefined;
|
|
1401
|
+
return imageFallback(img.mimeType, dims);
|
|
1402
|
+
})
|
|
1403
|
+
.join("\n");
|
|
1404
|
+
output = output ? `${output}\n${imageIndicators}` : imageIndicators;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
return output;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
/**
|
|
1411
|
+
* Format the generic call/result card at `contentWidth`. Shared by the
|
|
1412
|
+
* #contentText fallback and the benign-skip path so both render identically.
|
|
1413
|
+
*/
|
|
1414
|
+
#renderDefaultCard(contentWidth: number): string {
|
|
1415
|
+
return formatDefaultToolExecution(
|
|
1416
|
+
{
|
|
1417
|
+
label: this.#toolLabel,
|
|
1418
|
+
args: this.#args,
|
|
1419
|
+
result: this.#result
|
|
1420
|
+
? { output: this.#getTextOutput(), isError: this.#result.isError, skipped: this.#isBenignSkip() }
|
|
1421
|
+
: undefined,
|
|
1422
|
+
options: this.#renderState,
|
|
1423
|
+
},
|
|
1424
|
+
contentWidth,
|
|
1425
|
+
theme,
|
|
1426
|
+
);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
/**
|
|
1430
|
+
* True for a steering/peer-interrupt placeholder. A synthetic placeholder
|
|
1431
|
+
* identifies a call that never entered `tool.execute`; an interrupted
|
|
1432
|
+
* placeholder identifies one that started but threw before returning usable
|
|
1433
|
+
* output. Both are normal steering control flow and render neutrally (#7199).
|
|
1434
|
+
*/
|
|
1435
|
+
#isBenignSkip(): boolean {
|
|
1436
|
+
if (this.#isPartial || !this.#result) return false;
|
|
1437
|
+
const details = this.#result.details as
|
|
1438
|
+
| { __synthetic?: boolean; __interrupted?: boolean; source?: string; execution?: string }
|
|
1439
|
+
| undefined;
|
|
1440
|
+
if (details?.source !== "interrupt_skipped") return false;
|
|
1441
|
+
return details.__synthetic === true || (details.__interrupted === true && details.execution === "started");
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
/**
|
|
1445
|
+
* Render a benign skip as the neutral generic card, replacing any bespoke
|
|
1446
|
+
* renderer's error frame. Generic-fallback tools already route through
|
|
1447
|
+
* {@link #renderDefaultCard} (which emits the info card for a skip); they
|
|
1448
|
+
* only need the neutral tint. Bespoke-renderer tools get their content box
|
|
1449
|
+
* swapped for the same neutral card.
|
|
1450
|
+
*/
|
|
1451
|
+
#renderBenignSkipCard(stateBgFn: (text: string) => string): void {
|
|
1452
|
+
if (!this.#usesContentBox) {
|
|
1453
|
+
this.#contentText.setCustomBgFn(stateBgFn);
|
|
1454
|
+
this.#contentText.invalidate();
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
for (const box of this.#multiFileBoxes) {
|
|
1458
|
+
this.removeChild(box);
|
|
1459
|
+
}
|
|
1460
|
+
this.#multiFileBoxes = [];
|
|
1461
|
+
this.#contentBox.setBgFn(undefined);
|
|
1462
|
+
this.#contentBox.clear();
|
|
1463
|
+
this.#contentBox.setPaddingX(1);
|
|
1464
|
+
this.#contentBox.setBgFn(stateBgFn);
|
|
1465
|
+
this.#contentBox.addChild(new WidthAwareText(contentWidth => this.#renderDefaultCard(contentWidth), 0, 0));
|
|
1466
|
+
}
|
|
1467
|
+
}
|