@greppleai/grip 0.0.0-stage → 0.0.1
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 +22 -0
- package/README.md +725 -2
- package/dist/bun/cli.d.ts +3 -0
- package/dist/bun/cli.d.ts.map +1 -0
- package/dist/bun/cli.js +11 -0
- package/dist/bun/cli.js.map +1 -0
- package/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/bun/register-bedrock.d.ts.map +1 -0
- package/dist/bun/register-bedrock.js +4 -0
- package/dist/bun/register-bedrock.js.map +1 -0
- package/dist/bun/restore-sandbox-env.d.ts +13 -0
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
- package/dist/bun/restore-sandbox-env.js +32 -0
- package/dist/bun/restore-sandbox-env.js.map +1 -0
- package/dist/cli/args.d.ts +70 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +441 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config-selector.d.ts +14 -0
- package/dist/cli/config-selector.d.ts.map +1 -0
- package/dist/cli/config-selector.js +31 -0
- package/dist/cli/config-selector.js.map +1 -0
- package/dist/cli/file-processor.d.ts +15 -0
- package/dist/cli/file-processor.d.ts.map +1 -0
- package/dist/cli/file-processor.js +60 -0
- package/dist/cli/file-processor.js.map +1 -0
- package/dist/cli/initial-message.d.ts +18 -0
- package/dist/cli/initial-message.d.ts.map +1 -0
- package/dist/cli/initial-message.js +22 -0
- package/dist/cli/initial-message.js.map +1 -0
- package/dist/cli/list-models.d.ts +9 -0
- package/dist/cli/list-models.d.ts.map +1 -0
- package/dist/cli/list-models.js +98 -0
- package/dist/cli/list-models.js.map +1 -0
- package/dist/cli/session-picker.d.ts +9 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +35 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +82 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +406 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-session.d.ts +970 -0
- package/dist/core/agent-session.d.ts.map +1 -0
- package/dist/core/agent-session.js +5176 -0
- package/dist/core/agent-session.js.map +1 -0
- package/dist/core/auth-guidance.d.ts +5 -0
- package/dist/core/auth-guidance.d.ts.map +1 -0
- package/dist/core/auth-guidance.js +21 -0
- package/dist/core/auth-guidance.js.map +1 -0
- package/dist/core/auth-storage.d.ts +150 -0
- package/dist/core/auth-storage.d.ts.map +1 -0
- package/dist/core/auth-storage.js +557 -0
- package/dist/core/auth-storage.js.map +1 -0
- package/dist/core/bash-executor.d.ts +26 -0
- package/dist/core/bash-executor.d.ts.map +1 -0
- package/dist/core/bash-executor.js +99 -0
- package/dist/core/bash-executor.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +83 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/core/compaction/branch-summarization.js +220 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +65 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -0
- package/dist/core/compaction/compaction.js +550 -0
- package/dist/core/compaction/compaction.js.map +1 -0
- package/dist/core/compaction/compression-detection-ledger.d.ts +34 -0
- package/dist/core/compaction/compression-detection-ledger.d.ts.map +1 -0
- package/dist/core/compaction/compression-detection-ledger.js +52 -0
- package/dist/core/compaction/compression-detection-ledger.js.map +1 -0
- package/dist/core/compaction/compression-detector.d.ts +71 -0
- package/dist/core/compaction/compression-detector.d.ts.map +1 -0
- package/dist/core/compaction/compression-detector.js +407 -0
- package/dist/core/compaction/compression-detector.js.map +1 -0
- package/dist/core/compaction/compression-economics.d.ts +55 -0
- package/dist/core/compaction/compression-economics.d.ts.map +1 -0
- package/dist/core/compaction/compression-economics.js +151 -0
- package/dist/core/compaction/compression-economics.js.map +1 -0
- package/dist/core/compaction/utils.d.ts +28 -0
- package/dist/core/compaction/utils.d.ts.map +1 -0
- package/dist/core/compaction/utils.js +165 -0
- package/dist/core/compaction/utils.js.map +1 -0
- package/dist/core/defaults.d.ts +3 -0
- package/dist/core/defaults.d.ts.map +1 -0
- package/dist/core/defaults.js +2 -0
- package/dist/core/defaults.js.map +1 -0
- package/dist/core/diagnostics.d.ts +18 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/event-bus.d.ts +9 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/exec.d.ts +29 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +75 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +245 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +21 -0
- package/dist/core/export-html/index.d.ts.map +1 -0
- package/dist/core/export-html/index.js +230 -0
- package/dist/core/export-html/index.js.map +1 -0
- package/dist/core/export-html/template.css +1066 -0
- package/dist/core/export-html/template.html +55 -0
- package/dist/core/export-html/template.js +1864 -0
- package/dist/core/export-html/tool-renderer.d.ts +32 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +108 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +78 -0
- package/dist/core/extensions/loader.d.ts +24 -0
- package/dist/core/extensions/loader.d.ts.map +1 -0
- package/dist/core/extensions/loader.js +613 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +160 -0
- package/dist/core/extensions/runner.d.ts.map +1 -0
- package/dist/core/extensions/runner.js +962 -0
- package/dist/core/extensions/runner.js.map +1 -0
- package/dist/core/extensions/types.d.ts +1311 -0
- package/dist/core/extensions/types.d.ts.map +1 -0
- package/dist/core/extensions/types.js +51 -0
- package/dist/core/extensions/types.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts +20 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -0
- package/dist/core/extensions/wrapper.js +22 -0
- package/dist/core/extensions/wrapper.js.map +1 -0
- package/dist/core/footer-data-provider.d.ts +52 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -0
- package/dist/core/footer-data-provider.js +318 -0
- package/dist/core/footer-data-provider.js.map +1 -0
- package/dist/core/grip-agent.d.ts +240 -0
- package/dist/core/grip-agent.d.ts.map +1 -0
- package/dist/core/grip-agent.js +1243 -0
- package/dist/core/grip-agent.js.map +1 -0
- package/dist/core/grip-manifest.d.ts +9 -0
- package/dist/core/grip-manifest.d.ts.map +1 -0
- package/dist/core/grip-manifest.js +25 -0
- package/dist/core/grip-manifest.js.map +1 -0
- package/dist/core/hooks/aggregate.d.ts +5 -0
- package/dist/core/hooks/aggregate.d.ts.map +1 -0
- package/dist/core/hooks/aggregate.js +226 -0
- package/dist/core/hooks/aggregate.js.map +1 -0
- package/dist/core/hooks/config.d.ts +14 -0
- package/dist/core/hooks/config.d.ts.map +1 -0
- package/dist/core/hooks/config.js +372 -0
- package/dist/core/hooks/config.js.map +1 -0
- package/dist/core/hooks/executor.d.ts +12 -0
- package/dist/core/hooks/executor.d.ts.map +1 -0
- package/dist/core/hooks/executor.js +708 -0
- package/dist/core/hooks/executor.js.map +1 -0
- package/dist/core/hooks/index.d.ts +9 -0
- package/dist/core/hooks/index.d.ts.map +1 -0
- package/dist/core/hooks/index.js +14 -0
- package/dist/core/hooks/index.js.map +1 -0
- package/dist/core/hooks/matcher.d.ts +10 -0
- package/dist/core/hooks/matcher.d.ts.map +1 -0
- package/dist/core/hooks/matcher.js +70 -0
- package/dist/core/hooks/matcher.js.map +1 -0
- package/dist/core/hooks/trust-store.d.ts +38 -0
- package/dist/core/hooks/trust-store.d.ts.map +1 -0
- package/dist/core/hooks/trust-store.js +167 -0
- package/dist/core/hooks/trust-store.js.map +1 -0
- package/dist/core/hooks/types.d.ts +234 -0
- package/dist/core/hooks/types.d.ts.map +1 -0
- package/dist/core/hooks/types.js +52 -0
- package/dist/core/hooks/types.js.map +1 -0
- package/dist/core/http-dispatcher.d.ts +21 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -0
- package/dist/core/http-dispatcher.js +82 -0
- package/dist/core/http-dispatcher.js.map +1 -0
- package/dist/core/instruction-resource-loader.d.ts +81 -0
- package/dist/core/instruction-resource-loader.d.ts.map +1 -0
- package/dist/core/instruction-resource-loader.js +574 -0
- package/dist/core/instruction-resource-loader.js.map +1 -0
- package/dist/core/keybindings.d.ts +399 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +299 -0
- package/dist/core/keybindings.js.map +1 -0
- package/dist/core/lsp/abort.d.ts +3 -0
- package/dist/core/lsp/abort.d.ts.map +1 -0
- package/dist/core/lsp/abort.js +28 -0
- package/dist/core/lsp/abort.js.map +1 -0
- package/dist/core/lsp/client.d.ts +108 -0
- package/dist/core/lsp/client.d.ts.map +1 -0
- package/dist/core/lsp/client.js +586 -0
- package/dist/core/lsp/client.js.map +1 -0
- package/dist/core/lsp/config-loader.d.ts +44 -0
- package/dist/core/lsp/config-loader.d.ts.map +1 -0
- package/dist/core/lsp/config-loader.js +223 -0
- package/dist/core/lsp/config-loader.js.map +1 -0
- package/dist/core/lsp/config.d.ts +134 -0
- package/dist/core/lsp/config.d.ts.map +1 -0
- package/dist/core/lsp/config.js +682 -0
- package/dist/core/lsp/config.js.map +1 -0
- package/dist/core/lsp/diagnostics.d.ts +18 -0
- package/dist/core/lsp/diagnostics.d.ts.map +1 -0
- package/dist/core/lsp/diagnostics.js +311 -0
- package/dist/core/lsp/diagnostics.js.map +1 -0
- package/dist/core/lsp/file-sync.d.ts +58 -0
- package/dist/core/lsp/file-sync.d.ts.map +1 -0
- package/dist/core/lsp/file-sync.js +432 -0
- package/dist/core/lsp/file-sync.js.map +1 -0
- package/dist/core/lsp/integration.d.ts +62 -0
- package/dist/core/lsp/integration.d.ts.map +1 -0
- package/dist/core/lsp/integration.js +145 -0
- package/dist/core/lsp/integration.js.map +1 -0
- package/dist/core/lsp/language-map.d.ts +54 -0
- package/dist/core/lsp/language-map.d.ts.map +1 -0
- package/dist/core/lsp/language-map.js +300 -0
- package/dist/core/lsp/language-map.js.map +1 -0
- package/dist/core/lsp/manager.d.ts +120 -0
- package/dist/core/lsp/manager.d.ts.map +1 -0
- package/dist/core/lsp/manager.js +636 -0
- package/dist/core/lsp/manager.js.map +1 -0
- package/dist/core/lsp/navigation.d.ts +32 -0
- package/dist/core/lsp/navigation.d.ts.map +1 -0
- package/dist/core/lsp/navigation.js +327 -0
- package/dist/core/lsp/navigation.js.map +1 -0
- package/dist/core/lsp/portable-path.d.ts +18 -0
- package/dist/core/lsp/portable-path.d.ts.map +1 -0
- package/dist/core/lsp/portable-path.js +83 -0
- package/dist/core/lsp/portable-path.js.map +1 -0
- package/dist/core/lsp/refactor.d.ts +32 -0
- package/dist/core/lsp/refactor.d.ts.map +1 -0
- package/dist/core/lsp/refactor.js +519 -0
- package/dist/core/lsp/refactor.js.map +1 -0
- package/dist/core/lsp/transport.d.ts +39 -0
- package/dist/core/lsp/transport.d.ts.map +1 -0
- package/dist/core/lsp/transport.js +261 -0
- package/dist/core/lsp/transport.js.map +1 -0
- package/dist/core/messages.d.ts +34 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +140 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/model-registry.d.ts +148 -0
- package/dist/core/model-registry.d.ts.map +1 -0
- package/dist/core/model-registry.js +812 -0
- package/dist/core/model-registry.js.map +1 -0
- package/dist/core/model-resolver.d.ts +115 -0
- package/dist/core/model-resolver.d.ts.map +1 -0
- package/dist/core/model-resolver.js +498 -0
- package/dist/core/model-resolver.js.map +1 -0
- package/dist/core/output-guard.d.ts +7 -0
- package/dist/core/output-guard.d.ts.map +1 -0
- package/dist/core/output-guard.js +89 -0
- package/dist/core/output-guard.js.map +1 -0
- package/dist/core/package-manager.d.ts +209 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +2341 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/prompt-templates.d.ts +57 -0
- package/dist/core/prompt-templates.d.ts.map +1 -0
- package/dist/core/prompt-templates.js +353 -0
- package/dist/core/prompt-templates.js.map +1 -0
- package/dist/core/provider-display-names.d.ts +2 -0
- package/dist/core/provider-display-names.d.ts.map +1 -0
- package/dist/core/provider-display-names.js +33 -0
- package/dist/core/provider-display-names.js.map +1 -0
- package/dist/core/remote-workspace-protocol/contract.d.ts +456 -0
- package/dist/core/remote-workspace-protocol/contract.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/contract.js +809 -0
- package/dist/core/remote-workspace-protocol/contract.js.map +1 -0
- package/dist/core/remote-workspace-protocol/session.d.ts +247 -0
- package/dist/core/remote-workspace-protocol/session.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/session.js +1839 -0
- package/dist/core/remote-workspace-protocol/session.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +32 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -0
- package/dist/core/resolve-config-value.js +257 -0
- package/dist/core/resolve-config-value.js.map +1 -0
- package/dist/core/resource-loader.d.ts +200 -0
- package/dist/core/resource-loader.d.ts.map +1 -0
- package/dist/core/resource-loader.js +1209 -0
- package/dist/core/resource-loader.js.map +1 -0
- package/dist/core/rules.d.ts +40 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +57 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/sandbox/command.d.ts +27 -0
- package/dist/core/sandbox/command.d.ts.map +1 -0
- package/dist/core/sandbox/command.js +124 -0
- package/dist/core/sandbox/command.js.map +1 -0
- package/dist/core/sandbox/docker.d.ts +169 -0
- package/dist/core/sandbox/docker.d.ts.map +1 -0
- package/dist/core/sandbox/docker.js +633 -0
- package/dist/core/sandbox/docker.js.map +1 -0
- package/dist/core/sandbox/lima.d.ts +38 -0
- package/dist/core/sandbox/lima.d.ts.map +1 -0
- package/dist/core/sandbox/lima.js +324 -0
- package/dist/core/sandbox/lima.js.map +1 -0
- package/dist/core/session/constants.d.ts +2 -0
- package/dist/core/session/constants.d.ts.map +1 -0
- package/dist/core/session/constants.js +2 -0
- package/dist/core/session/constants.js.map +1 -0
- package/dist/core/session/context-metadata.d.ts +5 -0
- package/dist/core/session/context-metadata.d.ts.map +1 -0
- package/dist/core/session/context-metadata.js +55 -0
- package/dist/core/session/context-metadata.js.map +1 -0
- package/dist/core/session/context.d.ts +14 -0
- package/dist/core/session/context.d.ts.map +1 -0
- package/dist/core/session/context.js +117 -0
- package/dist/core/session/context.js.map +1 -0
- package/dist/core/session/ids.d.ts +9 -0
- package/dist/core/session/ids.d.ts.map +1 -0
- package/dist/core/session/ids.js +21 -0
- package/dist/core/session/ids.js.map +1 -0
- package/dist/core/session/in-memory-session-manager.d.ts +17 -0
- package/dist/core/session/in-memory-session-manager.d.ts.map +1 -0
- package/dist/core/session/in-memory-session-manager.js +40 -0
- package/dist/core/session/in-memory-session-manager.js.map +1 -0
- package/dist/core/session/in-memory-session.d.ts +7 -0
- package/dist/core/session/in-memory-session.d.ts.map +1 -0
- package/dist/core/session/in-memory-session.js +11 -0
- package/dist/core/session/in-memory-session.js.map +1 -0
- package/dist/core/session/jsonl-errors.d.ts +36 -0
- package/dist/core/session/jsonl-errors.d.ts.map +1 -0
- package/dist/core/session/jsonl-errors.js +49 -0
- package/dist/core/session/jsonl-errors.js.map +1 -0
- package/dist/core/session/jsonl-helpers.d.ts +20 -0
- package/dist/core/session/jsonl-helpers.d.ts.map +1 -0
- package/dist/core/session/jsonl-helpers.js +21 -0
- package/dist/core/session/jsonl-helpers.js.map +1 -0
- package/dist/core/session/local-session-manager.d.ts +30 -0
- package/dist/core/session/local-session-manager.d.ts.map +1 -0
- package/dist/core/session/local-session-manager.js +205 -0
- package/dist/core/session/local-session-manager.js.map +1 -0
- package/dist/core/session/local-session.d.ts +9 -0
- package/dist/core/session/local-session.d.ts.map +1 -0
- package/dist/core/session/local-session.js +15 -0
- package/dist/core/session/local-session.js.map +1 -0
- package/dist/core/session/migrations.d.ts +11 -0
- package/dist/core/session/migrations.d.ts.map +1 -0
- package/dist/core/session/migrations.js +78 -0
- package/dist/core/session/migrations.js.map +1 -0
- package/dist/core/session/remote-session-client.d.ts +83 -0
- package/dist/core/session/remote-session-client.d.ts.map +1 -0
- package/dist/core/session/remote-session-client.js +224 -0
- package/dist/core/session/remote-session-client.js.map +1 -0
- package/dist/core/session/remote-session-manager.d.ts +32 -0
- package/dist/core/session/remote-session-manager.d.ts.map +1 -0
- package/dist/core/session/remote-session-manager.js +124 -0
- package/dist/core/session/remote-session-manager.js.map +1 -0
- package/dist/core/session/remote-session.d.ts +20 -0
- package/dist/core/session/remote-session.d.ts.map +1 -0
- package/dist/core/session/remote-session.js +33 -0
- package/dist/core/session/remote-session.js.map +1 -0
- package/dist/core/session/session-manager.d.ts +18 -0
- package/dist/core/session/session-manager.d.ts.map +1 -0
- package/dist/core/session/session-manager.js +2 -0
- package/dist/core/session/session-manager.js.map +1 -0
- package/dist/core/session/session.d.ts +140 -0
- package/dist/core/session/session.d.ts.map +1 -0
- package/dist/core/session/session.js +461 -0
- package/dist/core/session/session.js.map +1 -0
- package/dist/core/session/stores/in-memory-session-store.d.ts +39 -0
- package/dist/core/session/stores/in-memory-session-store.d.ts.map +1 -0
- package/dist/core/session/stores/in-memory-session-store.js +168 -0
- package/dist/core/session/stores/in-memory-session-store.js.map +1 -0
- package/dist/core/session/stores/jsonl-session-store.d.ts +97 -0
- package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -0
- package/dist/core/session/stores/jsonl-session-store.js +1140 -0
- package/dist/core/session/stores/jsonl-session-store.js.map +1 -0
- package/dist/core/session/stores/remote-session-store.d.ts +44 -0
- package/dist/core/session/stores/remote-session-store.d.ts.map +1 -0
- package/dist/core/session/stores/remote-session-store.js +159 -0
- package/dist/core/session/stores/remote-session-store.js.map +1 -0
- package/dist/core/session/stores/session-store.d.ts +42 -0
- package/dist/core/session/stores/session-store.d.ts.map +1 -0
- package/dist/core/session/stores/session-store.js +2 -0
- package/dist/core/session/stores/session-store.js.map +1 -0
- package/dist/core/session/types.d.ts +141 -0
- package/dist/core/session/types.d.ts.map +1 -0
- package/dist/core/session/types.js +2 -0
- package/dist/core/session/types.js.map +1 -0
- package/dist/core/session/usage-ledger.d.ts +18 -0
- package/dist/core/session/usage-ledger.d.ts.map +1 -0
- package/dist/core/session/usage-ledger.js +68 -0
- package/dist/core/session/usage-ledger.js.map +1 -0
- package/dist/core/session-cwd.d.ts +19 -0
- package/dist/core/session-cwd.d.ts.map +1 -0
- package/dist/core/session-cwd.js +38 -0
- package/dist/core/session-cwd.js.map +1 -0
- package/dist/core/settings-manager.d.ts +318 -0
- package/dist/core/settings-manager.d.ts.map +1 -0
- package/dist/core/settings-manager.js +991 -0
- package/dist/core/settings-manager.js.map +1 -0
- package/dist/core/skills.d.ts +40 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +57 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/slash-commands.d.ts +15 -0
- package/dist/core/slash-commands.d.ts.map +1 -0
- package/dist/core/slash-commands.js +36 -0
- package/dist/core/slash-commands.js.map +1 -0
- package/dist/core/source-info.d.ts +26 -0
- package/dist/core/source-info.d.ts.map +1 -0
- package/dist/core/source-info.js +27 -0
- package/dist/core/source-info.js.map +1 -0
- package/dist/core/system-prompt.d.ts +32 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +131 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/telemetry.d.ts +3 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +9 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/timings.d.ts +10 -0
- package/dist/core/timings.d.ts.map +1 -0
- package/dist/core/timings.js +41 -0
- package/dist/core/timings.js.map +1 -0
- package/dist/core/tools/bash.d.ts +51 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +310 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/compress-context.d.ts +27 -0
- package/dist/core/tools/compress-context.d.ts.map +1 -0
- package/dist/core/tools/compress-context.js +142 -0
- package/dist/core/tools/compress-context.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +82 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +327 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +50 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +324 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +60 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/find.d.ts +22 -0
- package/dist/core/tools/find.d.ts.map +1 -0
- package/dist/core/tools/find.js +268 -0
- package/dist/core/tools/find.js.map +1 -0
- package/dist/core/tools/grep.d.ts +27 -0
- package/dist/core/tools/grep.d.ts.map +1 -0
- package/dist/core/tools/grep.js +332 -0
- package/dist/core/tools/grep.js.map +1 -0
- package/dist/core/tools/hash-store.d.ts +12 -0
- package/dist/core/tools/hash-store.d.ts.map +1 -0
- package/dist/core/tools/hash-store.js +48 -0
- package/dist/core/tools/hash-store.js.map +1 -0
- package/dist/core/tools/hashline/apply.d.ts +40 -0
- package/dist/core/tools/hashline/apply.d.ts.map +1 -0
- package/dist/core/tools/hashline/apply.js +261 -0
- package/dist/core/tools/hashline/apply.js.map +1 -0
- package/dist/core/tools/hashline/hash.d.ts +56 -0
- package/dist/core/tools/hashline/hash.d.ts.map +1 -0
- package/dist/core/tools/hashline/hash.js +196 -0
- package/dist/core/tools/hashline/hash.js.map +1 -0
- package/dist/core/tools/hashline/parse.d.ts +8 -0
- package/dist/core/tools/hashline/parse.d.ts.map +1 -0
- package/dist/core/tools/hashline/parse.js +41 -0
- package/dist/core/tools/hashline/parse.js.map +1 -0
- package/dist/core/tools/hashline/resolve.d.ts +51 -0
- package/dist/core/tools/hashline/resolve.d.ts.map +1 -0
- package/dist/core/tools/hashline/resolve.js +187 -0
- package/dist/core/tools/hashline/resolve.js.map +1 -0
- package/dist/core/tools/hashline-utils.d.ts +6 -0
- package/dist/core/tools/hashline-utils.d.ts.map +1 -0
- package/dist/core/tools/hashline-utils.js +23 -0
- package/dist/core/tools/hashline-utils.js.map +1 -0
- package/dist/core/tools/index.d.ts +36 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +141 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/ls.d.ts +21 -0
- package/dist/core/tools/ls.d.ts.map +1 -0
- package/dist/core/tools/ls.js +156 -0
- package/dist/core/tools/ls.js.map +1 -0
- package/dist/core/tools/operations.d.ts +201 -0
- package/dist/core/tools/operations.d.ts.map +1 -0
- package/dist/core/tools/operations.js +697 -0
- package/dist/core/tools/operations.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts +54 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -0
- package/dist/core/tools/output-accumulator.js +184 -0
- package/dist/core/tools/output-accumulator.js.map +1 -0
- package/dist/core/tools/path-utils.d.ts +9 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -0
- package/dist/core/tools/path-utils.js +99 -0
- package/dist/core/tools/path-utils.js.map +1 -0
- package/dist/core/tools/read.d.ts +32 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +318 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/render-utils.d.ts +33 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -0
- package/dist/core/tools/render-utils.js +61 -0
- package/dist/core/tools/render-utils.js.map +1 -0
- package/dist/core/tools/replace-diff.d.ts +16 -0
- package/dist/core/tools/replace-diff.d.ts.map +1 -0
- package/dist/core/tools/replace-diff.js +117 -0
- package/dist/core/tools/replace-diff.js.map +1 -0
- package/dist/core/tools/replace-normalize.d.ts +2 -0
- package/dist/core/tools/replace-normalize.d.ts.map +1 -0
- package/dist/core/tools/replace-normalize.js +73 -0
- package/dist/core/tools/replace-normalize.js.map +1 -0
- package/dist/core/tools/replace-render.d.ts +51 -0
- package/dist/core/tools/replace-render.d.ts.map +1 -0
- package/dist/core/tools/replace-render.js +162 -0
- package/dist/core/tools/replace-render.js.map +1 -0
- package/dist/core/tools/runtime.d.ts +2 -0
- package/dist/core/tools/runtime.d.ts.map +1 -0
- package/dist/core/tools/runtime.js +6 -0
- package/dist/core/tools/runtime.js.map +1 -0
- package/dist/core/tools/session-history.d.ts +55 -0
- package/dist/core/tools/session-history.d.ts.map +1 -0
- package/dist/core/tools/session-history.js +649 -0
- package/dist/core/tools/session-history.js.map +1 -0
- package/dist/core/tools/subagent-agents.d.ts +29 -0
- package/dist/core/tools/subagent-agents.d.ts.map +1 -0
- package/dist/core/tools/subagent-agents.js +223 -0
- package/dist/core/tools/subagent-agents.js.map +1 -0
- package/dist/core/tools/subagent.d.ts +185 -0
- package/dist/core/tools/subagent.d.ts.map +1 -0
- package/dist/core/tools/subagent.js +1309 -0
- package/dist/core/tools/subagent.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.js +34 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +39 -0
- package/dist/core/tools/truncate.d.ts.map +1 -0
- package/dist/core/tools/truncate.js +215 -0
- package/dist/core/tools/truncate.js.map +1 -0
- package/dist/core/tools/websearch.d.ts +33 -0
- package/dist/core/tools/websearch.d.ts.map +1 -0
- package/dist/core/tools/websearch.js +341 -0
- package/dist/core/tools/websearch.js.map +1 -0
- package/dist/core/tools/workspace-tool-host.d.ts +102 -0
- package/dist/core/tools/workspace-tool-host.d.ts.map +1 -0
- package/dist/core/tools/workspace-tool-host.js +348 -0
- package/dist/core/tools/workspace-tool-host.js.map +1 -0
- package/dist/core/tools/write.d.ts +16 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +204 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/core/workspace-identity.d.ts +7 -0
- package/dist/core/workspace-identity.d.ts.map +1 -0
- package/dist/core/workspace-identity.js +2 -0
- package/dist/core/workspace-identity.js.map +1 -0
- package/dist/daemon/command.d.ts +6 -0
- package/dist/daemon/command.d.ts.map +1 -0
- package/dist/daemon/command.js +58 -0
- package/dist/daemon/command.js.map +1 -0
- package/dist/daemon/config.d.ts +43 -0
- package/dist/daemon/config.d.ts.map +1 -0
- package/dist/daemon/config.js +304 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/help.d.ts +2 -0
- package/dist/daemon/help.d.ts.map +1 -0
- package/dist/daemon/help.js +42 -0
- package/dist/daemon/help.js.map +1 -0
- package/dist/daemon/lsp-config.d.ts +4 -0
- package/dist/daemon/lsp-config.d.ts.map +1 -0
- package/dist/daemon/lsp-config.js +155 -0
- package/dist/daemon/lsp-config.js.map +1 -0
- package/dist/daemon/security.d.ts +19 -0
- package/dist/daemon/security.d.ts.map +1 -0
- package/dist/daemon/security.js +175 -0
- package/dist/daemon/security.js.map +1 -0
- package/dist/daemon/server.d.ts +20 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +400 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/workspace-runtime.d.ts +46 -0
- package/dist/daemon/workspace-runtime.d.ts.map +1 -0
- package/dist/daemon/workspace-runtime.js +673 -0
- package/dist/daemon/workspace-runtime.js.map +1 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +39 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +763 -0
- package/dist/main.js.map +1 -0
- package/dist/migrations.d.ts +35 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +412 -0
- package/dist/migrations.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/assistant-message.js +149 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +36 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/bash-execution.js +173 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +18 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.js +54 -0
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.js +44 -0
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts +74 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/config-selector.js +514 -0
- package/dist/modes/interactive/components/config-selector.js.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.js +33 -0
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +25 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-editor.js +85 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +20 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-message.js +80 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -0
- package/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/modes/interactive/components/diff.d.ts.map +1 -0
- package/dist/modes/interactive/components/diff.js +118 -0
- package/dist/modes/interactive/components/diff.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.js +21 -0
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +22 -0
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-editor.js +128 -0
- package/dist/modes/interactive/components/extension-editor.js.map +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-input.js +61 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-selector.js +83 -0
- package/dist/modes/interactive/components/extension-selector.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +36 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -0
- package/dist/modes/interactive/components/footer.js +227 -0
- package/dist/modes/interactive/components/footer.js.map +1 -0
- package/dist/modes/interactive/components/hook-execution.d.ts +19 -0
- package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/hook-execution.js +184 -0
- package/dist/modes/interactive/components/hook-execution.js.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.js +36 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +55 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
- package/dist/modes/interactive/components/login-dialog.js +176 -0
- package/dist/modes/interactive/components/login-dialog.js.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts +4 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.js +19 -0
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
- package/dist/modes/interactive/components/mermaid.d.ts +14 -0
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
- package/dist/modes/interactive/components/mermaid.js +228 -0
- package/dist/modes/interactive/components/mermaid.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +52 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-selector.js +296 -0
- package/dist/modes/interactive/components/model-selector.js.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.js +165 -0
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +50 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +300 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +22 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.js +144 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +108 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector.js +835 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +81 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-selector.js +455 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.js +39 -0
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/theme-selector.js +50 -0
- package/dist/modes/interactive/components/theme-selector.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.js +51 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +67 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution.js +306 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +127 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/tree-selector.js +1098 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.js +114 -0
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +16 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message.js +49 -0
- package/dist/modes/interactive/components/user-message.js.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.js +33 -0
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +557 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-mode.js +5859 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +86 -0
- package/dist/modes/interactive/theme/light.json +85 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.d.ts +106 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme.js +1030 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -0
- package/dist/modes/json-event.d.ts +28 -0
- package/dist/modes/json-event.d.ts.map +1 -0
- package/dist/modes/json-event.js +12 -0
- package/dist/modes/json-event.js.map +1 -0
- package/dist/modes/print-mode.d.ts +29 -0
- package/dist/modes/print-mode.d.ts.map +1 -0
- package/dist/modes/print-mode.js +142 -0
- package/dist/modes/print-mode.js.map +1 -0
- package/dist/modes/rpc/jsonl.d.ts +17 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -0
- package/dist/modes/rpc/jsonl.js +49 -0
- package/dist/modes/rpc/jsonl.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +321 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-client.js +755 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +20 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-mode.js +963 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +652 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-types.js +8 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -0
- package/dist/package-manager-cli.d.ts +4 -0
- package/dist/package-manager-cli.d.ts.map +1 -0
- package/dist/package-manager-cli.js +488 -0
- package/dist/package-manager-cli.js.map +1 -0
- package/dist/utils/ansi.d.ts +2 -0
- package/dist/utils/ansi.d.ts.map +1 -0
- package/dist/utils/ansi.js +25 -0
- package/dist/utils/ansi.js.map +1 -0
- package/dist/utils/changelog.d.ts +23 -0
- package/dist/utils/changelog.d.ts.map +1 -0
- package/dist/utils/changelog.js +74 -0
- package/dist/utils/changelog.js.map +1 -0
- package/dist/utils/child-process.d.ts +15 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +88 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts +13 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -0
- package/dist/utils/clipboard-image.js +248 -0
- package/dist/utils/clipboard-image.js.map +1 -0
- package/dist/utils/clipboard-native.d.ts +11 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -0
- package/dist/utils/clipboard-native.js +20 -0
- package/dist/utils/clipboard-native.js.map +1 -0
- package/dist/utils/clipboard.d.ts +4 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +171 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/deprecation.d.ts +4 -0
- package/dist/utils/deprecation.d.ts.map +1 -0
- package/dist/utils/deprecation.js +13 -0
- package/dist/utils/deprecation.js.map +1 -0
- package/dist/utils/directory-completions.d.ts +5 -0
- package/dist/utils/directory-completions.d.ts.map +1 -0
- package/dist/utils/directory-completions.js +64 -0
- package/dist/utils/directory-completions.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts +6 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -0
- package/dist/utils/exif-orientation.js +166 -0
- package/dist/utils/exif-orientation.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/fs-watch.d.ts +5 -0
- package/dist/utils/fs-watch.d.ts.map +1 -0
- package/dist/utils/fs-watch.js +25 -0
- package/dist/utils/fs-watch.js.map +1 -0
- package/dist/utils/git.d.ts +27 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +237 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/grip-user-agent.d.ts +2 -0
- package/dist/utils/grip-user-agent.d.ts.map +1 -0
- package/dist/utils/grip-user-agent.js +5 -0
- package/dist/utils/grip-user-agent.js.map +1 -0
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +40 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/image-convert.d.ts +12 -0
- package/dist/utils/image-convert.d.ts.map +1 -0
- package/dist/utils/image-convert.js +43 -0
- package/dist/utils/image-convert.js.map +1 -0
- package/dist/utils/image-process.d.ts +18 -0
- package/dist/utils/image-process.d.ts.map +1 -0
- package/dist/utils/image-process.js +83 -0
- package/dist/utils/image-process.js.map +1 -0
- package/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +133 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +19 -0
- package/dist/utils/image-resize.d.ts.map +1 -0
- package/dist/utils/image-resize.js +81 -0
- package/dist/utils/image-resize.js.map +1 -0
- package/dist/utils/json.d.ts +3 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/mime.d.ts +3 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +110 -0
- package/dist/utils/mime.js.map +1 -0
- package/dist/utils/open-browser.d.ts +9 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +22 -0
- package/dist/utils/open-browser.js.map +1 -0
- package/dist/utils/paths.d.ts +31 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +87 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/photon.d.ts +22 -0
- package/dist/utils/photon.d.ts.map +1 -0
- package/dist/utils/photon.js +125 -0
- package/dist/utils/photon.js.map +1 -0
- package/dist/utils/shell.d.ts +28 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +188 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +17 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -0
- package/dist/utils/syntax-highlight.js +125 -0
- package/dist/utils/syntax-highlight.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +5 -0
- package/dist/utils/tools-manager.d.ts.map +1 -0
- package/dist/utils/tools-manager.js +329 -0
- package/dist/utils/tools-manager.js.map +1 -0
- package/dist/utils/version-check.d.ts +14 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +91 -0
- package/dist/utils/version-check.js.map +1 -0
- package/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/utils/windows-self-update.d.ts.map +1 -0
- package/dist/utils/windows-self-update.js +77 -0
- package/dist/utils/windows-self-update.js.map +1 -0
- package/docs/compaction.md +408 -0
- package/docs/custom-provider.md +714 -0
- package/docs/daemon-architecture.md +399 -0
- package/docs/daemon.md +110 -0
- package/docs/development.md +72 -0
- package/docs/docs.json +164 -0
- package/docs/extensions.md +2745 -0
- package/docs/hooks.md +85 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +81 -0
- package/docs/json.md +89 -0
- package/docs/keybindings.md +230 -0
- package/docs/lsp.md +499 -0
- package/docs/migrating-to-grip.md +18 -0
- package/docs/models.md +496 -0
- package/docs/packages.md +228 -0
- package/docs/prompt-templates.md +88 -0
- package/docs/providers.md +251 -0
- package/docs/quickstart.md +167 -0
- package/docs/rpc.md +1492 -0
- package/docs/rules.md +117 -0
- package/docs/sandbox.md +181 -0
- package/docs/sdk.md +360 -0
- package/docs/session-format.md +414 -0
- package/docs/sessions.md +137 -0
- package/docs/settings.md +371 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +246 -0
- package/docs/terminal-setup.md +112 -0
- package/docs/termux.md +129 -0
- package/docs/themes.md +295 -0
- package/docs/tmux.md +61 -0
- package/docs/tui.md +918 -0
- package/docs/usage.md +304 -0
- package/docs/windows.md +17 -0
- package/examples/README.md +31 -0
- package/examples/daemon-docker/Dockerfile +43 -0
- package/examples/daemon-docker/README.md +45 -0
- package/examples/extensions/README.md +208 -0
- package/examples/extensions/auto-commit-on-exit.ts +46 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/border-status-editor.ts +145 -0
- package/examples/extensions/built-in-tool-renderer.ts +259 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +82 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +131 -0
- package/examples/extensions/custom-footer.ts +79 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +707 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +402 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +104 -0
- package/examples/extensions/dirty-repo-guard.ts +59 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +133 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/examples/extensions/dynamic-resources/RULES.md +8 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +16 -0
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/git-merge-and-resolve.ts +125 -0
- package/examples/extensions/github-issue-autocomplete.ts +191 -0
- package/examples/extensions/handoff.ts +191 -0
- package/examples/extensions/hello.ts +26 -0
- package/examples/extensions/hidden-thinking-label.ts +53 -0
- package/examples/extensions/inline-bash.ts +104 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +194 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +428 -0
- package/examples/extensions/modal-editor.ts +86 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +55 -0
- package/examples/extensions/overlay-qa-tests.ts +1374 -0
- package/examples/extensions/overlay-test.ts +171 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +346 -0
- package/examples/extensions/plan-mode/utils.ts +172 -0
- package/examples/extensions/preset.ts +426 -0
- package/examples/extensions/prompt-customizer.ts +97 -0
- package/examples/extensions/protected-paths.ts +29 -0
- package/examples/extensions/provider-payload.ts +18 -0
- package/examples/extensions/qna.ts +125 -0
- package/examples/extensions/question.ts +294 -0
- package/examples/extensions/questionnaire.ts +459 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +118 -0
- package/examples/extensions/sandbox/index.ts +320 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +381 -0
- package/examples/extensions/space-invaders.ts +597 -0
- package/examples/extensions/status-line.ts +32 -0
- package/examples/extensions/structured-output.ts +65 -0
- package/examples/extensions/subagent/README.md +175 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +1083 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +186 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/tic-tac-toe.ts +1091 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +306 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +141 -0
- package/examples/extensions/trigger-compact.ts +50 -0
- package/examples/extensions/truncated-tool.ts +200 -0
- package/examples/extensions/widget-placement.ts +9 -0
- package/examples/extensions/with-deps/index.ts +32 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/extensions/working-indicator.ts +123 -0
- package/examples/extensions/working-message-test.ts +25 -0
- package/examples/remote-session-server/README.md +71 -0
- package/examples/remote-session-server/server.ts +353 -0
- package/examples/rpc-extension-ui.ts +642 -0
- package/examples/sandbox-docker/Dockerfile +274 -0
- package/examples/sandbox-docker/README.md +88 -0
- package/examples/sdk/01-minimal.ts +27 -0
- package/examples/sdk/02-custom-model.ts +54 -0
- package/examples/sdk/03-custom-prompt.ts +76 -0
- package/examples/sdk/04-skills.ts +60 -0
- package/examples/sdk/05-tools.ts +55 -0
- package/examples/sdk/06-extensions.ts +94 -0
- package/examples/sdk/07-context-files.ts +47 -0
- package/examples/sdk/08-prompt-templates.ts +56 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +50 -0
- package/examples/sdk/10-settings.ts +58 -0
- package/examples/sdk/11-sessions.ts +54 -0
- package/examples/sdk/12-full-control.ts +79 -0
- package/examples/sdk/13-session-runtime.ts +49 -0
- package/examples/sdk/README.md +94 -0
- package/npm-shrinkwrap.json +1878 -0
- package/package.json +102 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAkB,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAY,MAAM,qBAAqB,CAAC;AAQrH,OAAO,EAAE,wBAAwB,EAAiB,MAAM,8BAA8B,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EACN,aAAa,IAAI,qBAAqB,GAEtC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAc1C,MAAM,OAAO,sBAAuB,SAAQ,SAAS;IAC5C,UAAU,CAAM;IAChB,WAAW,CAAO;IAClB,mBAAmB,CAAY;IAC/B,qBAAqB,CAAa;IAClC,uBAAuB,CAAa;IACpC,aAAa,GAAQ,EAAE,CAAC;IACxB,eAAe,GAAY,EAAE,CAAC;IAC9B,YAAY,GAAa,EAAE,CAAC;IAC5B,QAAQ,CAAS;IACjB,UAAU,CAAS;IACnB,IAAI,CAAM;IACV,QAAQ,GAAG,KAAK,CAAC;IACjB,UAAU,CAAU;IACpB,eAAe,CAAS;IACxB,SAAS,GAAG,IAAI,CAAC;IACjB,cAAc,CAA4B;IAC1C,qBAAqB,CAA4B;IACjD,EAAE,CAAM;IACR,GAAG,CAAS;IACZ,gBAAgB,GAAG,KAAK,CAAC;IACzB,YAAY,GAAG,KAAK,CAAC;IACrB,MAAM,CAA8B;IACpC,eAAe,GAAoD,IAAI,GAAG,EAAE,CAAC;IAC7E,aAAa,GAAG,KAAK,CAAC;IAE9B,YACC,QAAgB,EAChB,UAAkB,EAClB,IAAS,EACT,OAAO,GAAyB,EAAE,EAClC,cAAoD,EACpD,EAAO,EACP,GAAW,EACV;QACD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,qBAAqB,GAAG,wBAAwB,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAoB,CAAC,CAAC;QAC1G,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;QAC7C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;QACrD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QAEf,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7B,+FAA+F;QAC/F,qEAAqE;QACrE,yFAAyF;QACzF,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC;QACnF,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC;QACzF,IAAI,CAAC,mBAAmB,GAAG,IAAI,SAAS,EAAE,CAAC;QAE3C,IAAI,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9F,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEO,eAAe,GAA2C;QACjE,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,IAAI,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC;IAAA,CAC/E;IAEO,iBAAiB,GAAkD;QAC1E,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,IAAI,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC;IAAA,CACnF;IAEO,qBAAqB,GAAY;QACxC,OAAO,IAAI,CAAC,qBAAqB,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC;IAAA,CACrF;IAEO,cAAc,GAAoB;QACzC,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,cAAc,EAAE,WAAW,IAAI,SAAS,CAAC;QACtD,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,IAAI,SAAS,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,WAAW,IAAI,IAAI,CAAC,qBAAqB,CAAC,WAAW,IAAI,SAAS,CAAC;IAAA,CAC9F;IAEO,gBAAgB,CAAC,aAAoC,EAAqB;QACjF,OAAO;YACN,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,UAAU,EAAE,GAAG,EAAE,CAAC;gBACjB,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;YAAA,CACxB;YACD,aAAa;YACb,KAAK,EAAE,IAAI,CAAC,aAAa;YACzB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,KAAK;SACtC,CAAC;IAAA,CACF;IAEO,kBAAkB,GAAc;QACvC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAAA,CACxE;IAEO,oBAAoB,GAA0B;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAAA,CACtD;IAED,UAAU,CAAC,IAAS,EAAQ;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,oBAAoB,GAAS;QAC5B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;IAAA,CACxB;IAED,eAAe,GAAS;QACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;IAAA,CACxB;IAED,YAAY,CAAC,MAAkC,EAAE,SAAS,GAAG,KAAK,EAAQ;QACzE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,0BAA0B,EAAE,CAAC;IAAA,CAClC;IAEO,0BAA0B,GAAS;QAC1C,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO;YAAE,OAAO;QACpC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ;gBAAE,SAAS;YACzC,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW;gBAAE,SAAS;YAC3C,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,SAAS;YAE1C,MAAM,KAAK,GAAG,CAAC,CAAC;YAChB,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;gBACxD,IAAI,SAAS,EAAE,CAAC;oBACf,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;oBAC3C,IAAI,CAAC,aAAa,EAAE,CAAC;oBACrB,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;gBACzB,CAAC;YAAA,CACD,CAAC,CAAC;QACJ,CAAC;IAAA,CACD;IAED,WAAW,CAAC,QAAiB,EAAQ;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,aAAa,CAAC,IAAa,EAAQ;QAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,kBAAkB,CAAC,KAAa,EAAQ;QACvC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEQ,UAAU,GAAS;QAC3B,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEQ,MAAM,CAAC,KAAa,EAAY;QACxC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACX,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAAA,CAC3B;IAEO,sBAAsB,GAA4B;QACzD,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO;YAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAAA,CACjD;IAEO,cAAc,CAAC,eAA0B,EAAW;QAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,IAAI,CAAC,YAAY,EAAE,CAAC;YACnB,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;YACpG,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;YACvC,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACR,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;YACvC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,IAAI,CAAC;IAAA,CACZ;IAEO,gBAAgB,CAAC,eAA0B,EAAW;QAC7D,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,CAAC,cAAc,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9C,IAAI,CAAC,SAAS;gBAAE,OAAO,KAAK,CAAC;YAC7B,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,SAAS,GAAG,cAAc,CAC/B,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAc,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EACrE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EACtD,KAAK,EACL,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,uBAAuB,CAAC,CACnD,CAAC;YACF,IAAI,CAAC,uBAAuB,GAAG,SAAS,CAAC;YACzC,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACR,IAAI,CAAC,uBAAuB,GAAG,SAAS,CAAC;YACzC,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9C,IAAI,CAAC,SAAS;gBAAE,OAAO,KAAK,CAAC;YAC7B,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;QACb,CAAC;IAAA,CACD;IAEO,uBAAuB,CAAC,mBAA4C,EAAW;QACtF,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACtG,IAAI,eAAe,YAAY,GAAG;YAAE,eAAe,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACjF,eAAe,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;QAChE,OAAO,cAAc,IAAI,gBAAgB,CAAC;IAAA,CAC1C;IAEO,oBAAoB,CAAC,mBAA4C,EAAW;QACnF,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;QACpD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IAAA,CACZ;IAEO,mBAAmB,GAAS;QACnC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,eAAe;YAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAClE,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,YAAY;YAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACjE,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;IAAA,CACvB;IAEO,kBAAkB,GAAS;QAClC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QACtF,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;QACvC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YACzD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ;gBAAE,SAAS;YACzF,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,SAAS,EAAE,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;YAChD,MAAM,aAAa,GAAG,SAAS,EAAE,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC;YAC5D,IAAI,YAAY,CAAC,MAAM,KAAK,OAAO,IAAI,aAAa,KAAK,WAAW;gBAAE,SAAS;YAC/E,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,cAAc,GAAG,IAAI,KAAK,CAC/B,SAAS,EACT,aAAa,EACb,EAAE,aAAa,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,EACjE,EAAE,aAAa,EAAE,IAAI,CAAC,eAAe,EAAE,CACvC,CAAC;YACF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QAC/B,CAAC;IAAA,CACD;IAEO,aAAa,GAAS;QAC7B,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC1D,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,MAAM,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3D,MAAM,UAAU,GAAG,qBAAqB;YACvC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,mBAAmB,CAAC;YACnD,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;QAElD,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,qBAAqB,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAAA,CACzG;IAEO,aAAa,GAAW;QAC/B,OAAO,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAAA,CAC3D;IAEO,mBAAmB,GAAW;QACrC,IAAI,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,OAAO,EAAE,CAAC;YACb,IAAI,IAAI,OAAO,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACZ,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC;IAAA,CACZ;CACD","sourcesContent":["import { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@greppleai/grip-tui\";\nimport type {\n\tToolCallRenderer,\n\tToolDefinition,\n\tToolRenderContext,\n\tToolRenderShell,\n\tToolResultRenderer,\n} from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { LocalToolOperations } from \"../../../core/tools/operations.ts\";\nimport {\n\tgetTextOutput as getRenderedTextOutput,\n\ttype ToolTextOutputContent,\n} from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\nexport interface ToolExecutionDisplayResult {\n\tcontent: ToolTextOutputContent[];\n\tdetails?: any;\n\tisError: boolean;\n}\n\ntype ToolBackgroundFormatter = (text: string) => string;\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: ToolExecutionDisplayResult;\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = createAllToolDefinitions(new LocalToolOperations(cwd))[toolName as ToolName];\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolCallRenderer<any, any> | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderCall;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderCall;\n\t\t}\n\t\treturn this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolResultRenderer<any, any, any> | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderResult;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderResult;\n\t\t}\n\t\treturn this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.builtInToolDefinition !== undefined || this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): ToolRenderShell {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(this.toolName)), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t}\n\n\tupdateArgs(args: any): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(result: ToolExecutionDisplayResult, isPartial = false): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate getBackgroundFormatter(): ToolBackgroundFormatter {\n\t\tif (this.isPartial) return (text) => theme.bg(\"toolPendingBg\", text);\n\t\tif (this.result?.isError) return (text) => theme.bg(\"toolErrorBg\", text);\n\t\treturn (text) => theme.bg(\"toolSuccessBg\", text);\n\t}\n\n\tprivate renderToolCall(renderContainer: Container): boolean {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tif (!callRenderer) {\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\tthis.callRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t} catch {\n\t\t\tthis.callRendererComponent = undefined;\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate renderToolResult(renderContainer: Container): boolean {\n\t\tif (!this.result) return false;\n\t\tconst resultRenderer = this.getResultRenderer();\n\t\tif (!resultRenderer) {\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = resultRenderer(\n\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\ttheme,\n\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t);\n\t\t\tthis.resultRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tthis.resultRendererComponent = undefined;\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate renderDefinitionContent(backgroundFormatter: ToolBackgroundFormatter): boolean {\n\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\tif (renderContainer instanceof Box) renderContainer.setBgFn(backgroundFormatter);\n\t\trenderContainer.clear();\n\t\tconst callHasContent = this.renderToolCall(renderContainer);\n\t\tconst resultHasContent = this.renderToolResult(renderContainer);\n\t\treturn callHasContent || resultHasContent;\n\t}\n\n\tprivate renderGenericContent(backgroundFormatter: ToolBackgroundFormatter): boolean {\n\t\tthis.contentText.setCustomBgFn(backgroundFormatter);\n\t\tthis.contentText.setText(this.formatToolExecution());\n\t\treturn true;\n\t}\n\n\tprivate clearRenderedImages(): void {\n\t\tfor (const image of this.imageComponents) this.removeChild(image);\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) this.removeChild(spacer);\n\t\tthis.imageSpacers = [];\n\t}\n\n\tprivate renderResultImages(): void {\n\t\tif (!this.result) return;\n\t\tconst imageBlocks = this.result.content.filter((content) => content.type === \"image\");\n\t\tconst capabilities = getCapabilities();\n\t\tfor (let index = 0; index < imageBlocks.length; index++) {\n\t\t\tconst image = imageBlocks[index];\n\t\t\tif (!capabilities.images || !this.showImages || !image.data || !image.mimeType) continue;\n\t\t\tconst converted = this.convertedImages.get(index);\n\t\t\tconst imageData = converted?.data ?? image.data;\n\t\t\tconst imageMimeType = converted?.mimeType ?? image.mimeType;\n\t\t\tif (capabilities.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\t\t\tconst spacer = new Spacer(1);\n\t\t\tthis.addChild(spacer);\n\t\t\tthis.imageSpacers.push(spacer);\n\t\t\tconst imageComponent = new Image(\n\t\t\t\timageData,\n\t\t\t\timageMimeType,\n\t\t\t\t{ fallbackColor: (text: string) => theme.fg(\"toolOutput\", text) },\n\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t);\n\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\tthis.addChild(imageComponent);\n\t\t}\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst backgroundFormatter = this.getBackgroundFormatter();\n\t\tthis.hideComponent = false;\n\t\tconst hasRendererDefinition = this.hasRendererDefinition();\n\t\tconst hasContent = hasRendererDefinition\n\t\t\t? this.renderDefinitionContent(backgroundFormatter)\n\t\t\t: this.renderGenericContent(backgroundFormatter);\n\n\t\tthis.clearRenderedImages();\n\t\tthis.renderResultImages();\n\t\tif (hasRendererDefinition && !hasContent && this.imageComponents.length === 0) this.hideComponent = true;\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\ttext += `\\n${output}`;\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { type Component, Container, type Focusable } from "@greppleai/grip-tui";
|
|
2
|
+
import type { SessionTreeNode } from "../../../core/session/types.ts";
|
|
3
|
+
/** Filter mode for tree display */
|
|
4
|
+
export type FilterMode = "default" | "no-tools" | "user-only" | "labeled-only" | "all";
|
|
5
|
+
declare class TreeList implements Component {
|
|
6
|
+
private flatNodes;
|
|
7
|
+
private filteredNodes;
|
|
8
|
+
private selectedIndex;
|
|
9
|
+
private currentLeafId;
|
|
10
|
+
private maxVisibleLines;
|
|
11
|
+
private filterMode;
|
|
12
|
+
private searchQuery;
|
|
13
|
+
private toolCallMap;
|
|
14
|
+
private multipleRoots;
|
|
15
|
+
private showLabelTimestamps;
|
|
16
|
+
private activePathIds;
|
|
17
|
+
private visibleParentMap;
|
|
18
|
+
private visibleChildrenMap;
|
|
19
|
+
private lastSelectedId;
|
|
20
|
+
private foldedNodes;
|
|
21
|
+
onSelect?: (entryId: string) => void;
|
|
22
|
+
onCancel?: () => void;
|
|
23
|
+
onCopy?: (text: string | undefined) => void;
|
|
24
|
+
onLabelEdit?: (entryId: string, currentLabel: string | undefined) => void;
|
|
25
|
+
constructor(tree: SessionTreeNode[], currentLeafId: string | null, maxVisibleLines: number, initialSelectedId?: string, initialFilterMode?: FilterMode);
|
|
26
|
+
/**
|
|
27
|
+
* Find the index of the nearest visible entry, walking up the parent chain if needed.
|
|
28
|
+
* Returns the index in filteredNodes, or the last index as fallback.
|
|
29
|
+
*/
|
|
30
|
+
private findNearestVisibleIndex;
|
|
31
|
+
/** Build the set of entry IDs on the path from root to current leaf */
|
|
32
|
+
private buildActivePath;
|
|
33
|
+
private findActiveSubtrees;
|
|
34
|
+
private createTreeTraversalStack;
|
|
35
|
+
private recordAssistantToolCalls;
|
|
36
|
+
private prioritizeActiveChildren;
|
|
37
|
+
private getTraversalChildIndent;
|
|
38
|
+
private getTraversalChildGutters;
|
|
39
|
+
private pushTraversalChildren;
|
|
40
|
+
private flattenTree;
|
|
41
|
+
private shouldDisplayAssistantNode;
|
|
42
|
+
private passesNodeFilterMode;
|
|
43
|
+
private matchesNodeSearch;
|
|
44
|
+
private shouldIncludeFilteredNode;
|
|
45
|
+
private applyFilter;
|
|
46
|
+
private findNearestVisibleAncestor;
|
|
47
|
+
private buildVisibleTreeStructure;
|
|
48
|
+
private resolveVisibleChildLayout;
|
|
49
|
+
private layoutVisibleTree;
|
|
50
|
+
/**
|
|
51
|
+
* Recompute indentation/connectors for the filtered view.
|
|
52
|
+
* Filtering can hide intermediate entries, so descendants attach to the nearest visible ancestor.
|
|
53
|
+
*/
|
|
54
|
+
private recalculateVisualStructure;
|
|
55
|
+
/** Get searchable text content from a node */
|
|
56
|
+
private getSearchableText;
|
|
57
|
+
invalidate(): void;
|
|
58
|
+
getSearchQuery(): string;
|
|
59
|
+
getSelectedNode(): SessionTreeNode | undefined;
|
|
60
|
+
copySelected(): void;
|
|
61
|
+
updateNodeLabel(entryId: string, label: string | undefined, labelTimestamp?: string): void;
|
|
62
|
+
private getStatusLabels;
|
|
63
|
+
private getVisibleNodeRange;
|
|
64
|
+
private renderPrefixCharacter;
|
|
65
|
+
private renderNodePrefix;
|
|
66
|
+
private renderNodeLine;
|
|
67
|
+
render(width: number): string[];
|
|
68
|
+
private normalizeDisplayText;
|
|
69
|
+
private getAssistantDisplayText;
|
|
70
|
+
private getMessageDisplayText;
|
|
71
|
+
private getEntryDisplayText;
|
|
72
|
+
private formatLabelTimestamp;
|
|
73
|
+
private extractContent;
|
|
74
|
+
private extractFullContent;
|
|
75
|
+
private getEntryCopyText;
|
|
76
|
+
private hasTextContent;
|
|
77
|
+
private formatToolCall;
|
|
78
|
+
private foldSelectedNodeOrMoveToPreviousBranch;
|
|
79
|
+
private unfoldSelectedNodeOrMoveToNextBranch;
|
|
80
|
+
private handleTreeMovementInput;
|
|
81
|
+
private cancelSearchOrSelection;
|
|
82
|
+
private handleTreeSelectionInput;
|
|
83
|
+
private setFilterMode;
|
|
84
|
+
private toggleFilterMode;
|
|
85
|
+
private cycleFilterMode;
|
|
86
|
+
private handleTreeFilterInput;
|
|
87
|
+
private appendTreeSearchInput;
|
|
88
|
+
private handleTreeEditingInput;
|
|
89
|
+
handleInput(keyData: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Whether a node can be folded. A node is foldable if it has visible children
|
|
92
|
+
* and is either a root (no visible parent) or a segment start (visible parent
|
|
93
|
+
* has multiple visible children).
|
|
94
|
+
*/
|
|
95
|
+
private isFoldable;
|
|
96
|
+
private findNextBranchSegmentStart;
|
|
97
|
+
private findPreviousBranchSegmentStart;
|
|
98
|
+
/**
|
|
99
|
+
* Find the index of the next branch segment start in the given direction.
|
|
100
|
+
* A segment start is the first child of a branch point.
|
|
101
|
+
*
|
|
102
|
+
* "up" walks the visible parent chain; "down" walks visible children
|
|
103
|
+
* (always following the first child).
|
|
104
|
+
*/
|
|
105
|
+
private findBranchSegmentStart;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Component that renders a session tree selector for navigation
|
|
109
|
+
*/
|
|
110
|
+
export declare class TreeSelectorComponent extends Container implements Focusable {
|
|
111
|
+
private treeList;
|
|
112
|
+
private labelInput;
|
|
113
|
+
private labelInputContainer;
|
|
114
|
+
private treeContainer;
|
|
115
|
+
private onLabelChangeCallback?;
|
|
116
|
+
onCopy?: (text: string | undefined) => void;
|
|
117
|
+
private _focused;
|
|
118
|
+
get focused(): boolean;
|
|
119
|
+
set focused(value: boolean);
|
|
120
|
+
constructor(tree: SessionTreeNode[], currentLeafId: string | null, terminalHeight: number, onSelect: (entryId: string) => void, onCancel: () => void, onLabelChange?: (entryId: string, label: string | undefined) => void, initialSelectedId?: string, initialFilterMode?: FilterMode);
|
|
121
|
+
private showLabelInput;
|
|
122
|
+
private hideLabelInput;
|
|
123
|
+
handleInput(keyData: string): void;
|
|
124
|
+
getTreeList(): TreeList;
|
|
125
|
+
}
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=tree-selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tree-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@greppleai/grip-agent-core\";\nimport type { AssistantMessage } from \"@greppleai/grip-ai\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\tInput,\n\tSpacer,\n\tText,\n\tTruncatedText,\n\ttruncateToWidth,\n} from \"@greppleai/grip-tui\";\nimport type { SessionTreeNode } from \"../../../core/session/types.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint, keyText } from \"./keybinding-hints.ts\";\n\n/** Gutter info: position (displayIndent where connector was) and whether to show │ */\ninterface GutterInfo {\n\tposition: number; // displayIndent level where the connector was shown\n\tshow: boolean; // true = show │, false = show spaces\n}\n\n/** Flattened tree node for navigation */\ninterface FlatNode {\n\tnode: SessionTreeNode;\n\t/** Indentation level (each level = 3 chars) */\n\tindent: number;\n\t/** Whether to show connector (├─ or └─) - true if parent has multiple children */\n\tshowConnector: boolean;\n\t/** If showConnector, true = last sibling (└─), false = not last (├─) */\n\tisLast: boolean;\n\t/** Gutter info for each ancestor branch point */\n\tgutters: GutterInfo[];\n\t/** True if this node is a root under a virtual branching root (multiple roots) */\n\tisVirtualRootChild: boolean;\n}\n\ninterface TreeTraversalItem {\n\tnode: SessionTreeNode;\n\tindent: number;\n\tjustBranched: boolean;\n\tshowConnector: boolean;\n\tisLast: boolean;\n\tgutters: GutterInfo[];\n\tisVirtualRootChild: boolean;\n}\n\ninterface VisibleTreeStructure {\n\tparentMap: Map<string, string | null>;\n\tchildrenMap: Map<string | null, string[]>;\n\tnodesById: Map<string, FlatNode>;\n\trootIds: string[];\n}\n\ninterface VisibleChildLayout {\n\tindent: number;\n\tgutters: GutterInfo[];\n\tbranched: boolean;\n}\n// grip-ignore noNearIdenticalDataStructures: Viewport slice indices and terminal selection cell columns evolve independently.\ninterface VisibleNodeRange {\n\tstart: number;\n\tend: number;\n}\n\ntype BranchSegmentTraversalDirection = \"up\" | \"down\";\n\n/** Filter mode for tree display */\nexport type FilterMode = \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\";\n\nconst FILTER_MODES: readonly FilterMode[] = [\"default\", \"no-tools\", \"user-only\", \"labeled-only\", \"all\"];\n\nfunction hasTreeSearchControlCharacters(value: string): boolean {\n\tfor (const character of value) {\n\t\tconst code = character.charCodeAt(0);\n\t\tif (code < 32 || code === 0x7f || (code >= 0x80 && code <= 0x9f)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Tree list component with selection and ASCII art visualization\n */\n/** Tool call info for lookup */\ninterface ToolCallInfo {\n\tname: string;\n\targuments: Record<string, unknown>;\n}\n\ntype TreeFileMutationToolName = \"write\" | \"edit\";\ntype TreeSearchToolName = \"grep\" | \"find\";\n\nfunction shortenTreeToolPath(path: string): string {\n\tconst home = process.env.HOME || process.env.USERPROFILE || \"\";\n\treturn home && path.startsWith(home) ? `~${path.slice(home.length)}` : path;\n}\n\nfunction formatTreeReadToolCall(args: Record<string, unknown>): string {\n\tconst path = shortenTreeToolPath(String(args.path || args.file_path || \"\"));\n\tconst offset = args.offset as number | undefined;\n\tconst limit = args.limit as number | undefined;\n\tlet display = path;\n\tif (offset !== undefined || limit !== undefined) {\n\t\tconst start = offset ?? 1;\n\t\tconst end = limit !== undefined ? start + limit - 1 : \"\";\n\t\tdisplay += `:${start}${end ? `-${end}` : \"\"}`;\n\t}\n\treturn `[read: ${display}]`;\n}\n\nfunction formatTreeFileMutationToolCall(name: TreeFileMutationToolName, args: Record<string, unknown>): string {\n\treturn `[${name}: ${shortenTreeToolPath(String(args.path || args.file_path || \"\"))}]`;\n}\n\nfunction formatTreeBashToolCall(args: Record<string, unknown>): string {\n\tconst rawCommand = String(args.command || \"\");\n\tconst command = rawCommand\n\t\t.replace(/[\\n\\t]/g, \" \")\n\t\t.trim()\n\t\t.slice(0, 50);\n\treturn `[bash: ${command}${rawCommand.length > 50 ? \"...\" : \"\"}]`;\n}\n\nfunction formatTreeSearchToolCall(name: TreeSearchToolName, args: Record<string, unknown>): string {\n\tconst pattern = String(args.pattern || \"\");\n\tconst path = shortenTreeToolPath(String(args.path || \".\"));\n\treturn name === \"grep\" ? `[grep: /${pattern}/ in ${path}]` : `[find: ${pattern} in ${path}]`;\n}\n\nfunction formatCustomTreeToolCall(name: string, args: Record<string, unknown>): string {\n\tconst argsString = JSON.stringify(args).slice(0, 40);\n\treturn `[${name}: ${argsString}${JSON.stringify(args).length > 40 ? \"...\" : \"\"}]`;\n}\n\nclass TreeList implements Component {\n\tprivate flatNodes: FlatNode[] = [];\n\tprivate filteredNodes: FlatNode[] = [];\n\tprivate selectedIndex = 0;\n\tprivate currentLeafId: string | null;\n\tprivate maxVisibleLines: number;\n\tprivate filterMode: FilterMode = \"default\";\n\tprivate searchQuery = \"\";\n\tprivate toolCallMap: Map<string, ToolCallInfo> = new Map();\n\tprivate multipleRoots = false;\n\tprivate showLabelTimestamps = false;\n\tprivate activePathIds: Set<string> = new Set();\n\tprivate visibleParentMap: Map<string, string | null> = new Map();\n\tprivate visibleChildrenMap: Map<string | null, string[]> = new Map();\n\tprivate lastSelectedId: string | null = null;\n\tprivate foldedNodes: Set<string> = new Set();\n\n\tpublic onSelect?: (entryId: string) => void;\n\tpublic onCancel?: () => void;\n\tpublic onCopy?: (text: string | undefined) => void;\n\tpublic onLabelEdit?: (entryId: string, currentLabel: string | undefined) => void;\n\n\tconstructor(\n\t\ttree: SessionTreeNode[],\n\t\tcurrentLeafId: string | null,\n\t\tmaxVisibleLines: number,\n\t\tinitialSelectedId?: string,\n\t\tinitialFilterMode?: FilterMode,\n\t) {\n\t\tthis.currentLeafId = currentLeafId;\n\t\tthis.maxVisibleLines = maxVisibleLines;\n\t\tthis.filterMode = initialFilterMode ?? \"default\";\n\t\tthis.multipleRoots = tree.length > 1;\n\t\tthis.flatNodes = this.flattenTree(tree);\n\t\tthis.buildActivePath();\n\t\tthis.applyFilter();\n\n\t\t// Start with initialSelectedId if provided, otherwise current leaf\n\t\tconst targetId = initialSelectedId ?? currentLeafId;\n\t\tthis.selectedIndex = this.findNearestVisibleIndex(targetId);\n\t\tthis.lastSelectedId = this.filteredNodes[this.selectedIndex]?.node.entry.id ?? null;\n\t}\n\n\t/**\n\t * Find the index of the nearest visible entry, walking up the parent chain if needed.\n\t * Returns the index in filteredNodes, or the last index as fallback.\n\t */\n\tprivate findNearestVisibleIndex(entryId: string | null): number {\n\t\tif (this.filteredNodes.length === 0) return 0;\n\n\t\t// Build a map for parent lookup\n\t\tconst entryMap = new Map<string, FlatNode>();\n\t\tfor (const flatNode of this.flatNodes) {\n\t\t\tentryMap.set(flatNode.node.entry.id, flatNode);\n\t\t}\n\n\t\t// Build a map of visible entry IDs to their indices in filteredNodes\n\t\tconst visibleIdToIndex = new Map<string, number>(this.filteredNodes.map((node, i) => [node.node.entry.id, i]));\n\n\t\t// Walk from entryId up to root, looking for a visible entry\n\t\tlet currentId = entryId;\n\t\twhile (currentId !== null) {\n\t\t\tconst index = visibleIdToIndex.get(currentId);\n\t\t\tif (index !== undefined) return index;\n\t\t\tconst node = entryMap.get(currentId);\n\t\t\tif (!node) break;\n\t\t\tcurrentId = node.node.entry.parentId ?? null;\n\t\t}\n\n\t\t// Fallback: last visible entry\n\t\treturn this.filteredNodes.length - 1;\n\t}\n\n\t/** Build the set of entry IDs on the path from root to current leaf */\n\tprivate buildActivePath(): void {\n\t\tthis.activePathIds.clear();\n\t\tif (!this.currentLeafId) return;\n\n\t\t// Build a map of id -> entry for parent lookup\n\t\tconst entryMap = new Map<string, FlatNode>();\n\t\tfor (const flatNode of this.flatNodes) {\n\t\t\tentryMap.set(flatNode.node.entry.id, flatNode);\n\t\t}\n\n\t\t// Walk from leaf to root\n\t\tlet currentId: string | null = this.currentLeafId;\n\t\twhile (currentId) {\n\t\t\tthis.activePathIds.add(currentId);\n\t\t\tconst node = entryMap.get(currentId);\n\t\t\tif (!node) break;\n\t\t\tcurrentId = node.node.entry.parentId ?? null;\n\t\t}\n\t}\n\n\tprivate findActiveSubtrees(roots: SessionTreeNode[]): Map<SessionTreeNode, boolean> {\n\t\tconst allNodes: SessionTreeNode[] = [];\n\t\tconst preOrderStack = [...roots];\n\t\twhile (preOrderStack.length > 0) {\n\t\t\tconst node = preOrderStack.pop()!;\n\t\t\tallNodes.push(node);\n\t\t\tfor (let i = node.children.length - 1; i >= 0; i--) preOrderStack.push(node.children[i]);\n\t\t}\n\n\t\tconst containsActive = new Map<SessionTreeNode, boolean>();\n\t\tfor (let i = allNodes.length - 1; i >= 0; i--) {\n\t\t\tconst node = allNodes[i];\n\t\t\tlet hasActiveEntry = this.currentLeafId !== null && node.entry.id === this.currentLeafId;\n\t\t\tfor (const child of node.children) {\n\t\t\t\tif (containsActive.get(child)) hasActiveEntry = true;\n\t\t\t}\n\t\t\tcontainsActive.set(node, hasActiveEntry);\n\t\t}\n\t\treturn containsActive;\n\t}\n\n\tprivate createTreeTraversalStack(\n\t\troots: SessionTreeNode[],\n\t\tcontainsActive: Map<SessionTreeNode, boolean>,\n\t): TreeTraversalItem[] {\n\t\tconst orderedRoots = [...roots].sort((a, b) => Number(containsActive.get(b)) - Number(containsActive.get(a)));\n\t\tconst stack: TreeTraversalItem[] = [];\n\t\tfor (let i = orderedRoots.length - 1; i >= 0; i--) {\n\t\t\tstack.push({\n\t\t\t\tnode: orderedRoots[i],\n\t\t\t\tindent: this.multipleRoots ? 1 : 0,\n\t\t\t\tjustBranched: this.multipleRoots,\n\t\t\t\tshowConnector: this.multipleRoots,\n\t\t\t\tisLast: i === orderedRoots.length - 1,\n\t\t\t\tgutters: [],\n\t\t\t\tisVirtualRootChild: this.multipleRoots,\n\t\t\t});\n\t\t}\n\t\treturn stack;\n\t}\n\n\tprivate recordAssistantToolCalls(node: SessionTreeNode): void {\n\t\tconst entry = node.entry;\n\t\tif (entry.type !== \"message\" || entry.message.role !== \"assistant\") return;\n\t\tconst content = (entry.message as { content?: unknown }).content;\n\t\tif (!Array.isArray(content)) return;\n\t\tfor (const block of content) {\n\t\t\tif (typeof block !== \"object\" || block === null || !(\"type\" in block) || block.type !== \"toolCall\") continue;\n\t\t\tconst toolCall = block as { id: string; name: string; arguments: Record<string, unknown> };\n\t\t\tthis.toolCallMap.set(toolCall.id, { name: toolCall.name, arguments: toolCall.arguments });\n\t\t}\n\t}\n\n\tprivate prioritizeActiveChildren(\n\t\tchildren: SessionTreeNode[],\n\t\tcontainsActive: Map<SessionTreeNode, boolean>,\n\t): SessionTreeNode[] {\n\t\tconst prioritized: SessionTreeNode[] = [];\n\t\tconst rest: SessionTreeNode[] = [];\n\t\tfor (const child of children) {\n\t\t\tif (containsActive.get(child)) prioritized.push(child);\n\t\t\telse rest.push(child);\n\t\t}\n\t\treturn [...prioritized, ...rest];\n\t}\n\n\tprivate getTraversalChildIndent(item: TreeTraversalItem, multipleChildren: boolean): number {\n\t\tif (multipleChildren || (item.justBranched && item.indent > 0)) return item.indent + 1;\n\t\treturn item.indent;\n\t}\n\n\tprivate getTraversalChildGutters(item: TreeTraversalItem): GutterInfo[] {\n\t\tif (!item.showConnector || item.isVirtualRootChild) return item.gutters;\n\t\tconst currentDisplayIndent = this.multipleRoots ? Math.max(0, item.indent - 1) : item.indent;\n\t\treturn [...item.gutters, { position: Math.max(0, currentDisplayIndent - 1), show: !item.isLast }];\n\t}\n\n\tprivate pushTraversalChildren(\n\t\tstack: TreeTraversalItem[],\n\t\titem: TreeTraversalItem,\n\t\tcontainsActive: Map<SessionTreeNode, boolean>,\n\t): void {\n\t\tconst orderedChildren = this.prioritizeActiveChildren(item.node.children, containsActive);\n\t\tconst multipleChildren = orderedChildren.length > 1;\n\t\tconst childIndent = this.getTraversalChildIndent(item, multipleChildren);\n\t\tconst childGutters = this.getTraversalChildGutters(item);\n\t\tfor (let i = orderedChildren.length - 1; i >= 0; i--) {\n\t\t\tstack.push({\n\t\t\t\tnode: orderedChildren[i],\n\t\t\t\tindent: childIndent,\n\t\t\t\tjustBranched: multipleChildren,\n\t\t\t\tshowConnector: multipleChildren,\n\t\t\t\tisLast: i === orderedChildren.length - 1,\n\t\t\t\tgutters: childGutters,\n\t\t\t\tisVirtualRootChild: false,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate flattenTree(roots: SessionTreeNode[]): FlatNode[] {\n\t\tthis.toolCallMap.clear();\n\t\tconst result: FlatNode[] = [];\n\t\tconst containsActive = this.findActiveSubtrees(roots);\n\t\tconst stack = this.createTreeTraversalStack(roots, containsActive);\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst item = stack.pop()!;\n\t\t\tthis.recordAssistantToolCalls(item.node);\n\t\t\tresult.push({\n\t\t\t\tnode: item.node,\n\t\t\t\tindent: item.indent,\n\t\t\t\tshowConnector: item.showConnector,\n\t\t\t\tisLast: item.isLast,\n\t\t\t\tgutters: item.gutters,\n\t\t\t\tisVirtualRootChild: item.isVirtualRootChild,\n\t\t\t});\n\t\t\tthis.pushTraversalChildren(stack, item, containsActive);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate shouldDisplayAssistantNode(flatNode: FlatNode): boolean {\n\t\tconst entry = flatNode.node.entry;\n\t\tif (entry.type !== \"message\" || entry.message.role !== \"assistant\" || entry.id === this.currentLeafId) {\n\t\t\treturn true;\n\t\t}\n\t\tconst message = entry.message as { stopReason?: string; content?: unknown };\n\t\tconst hasText = this.hasTextContent(message.content);\n\t\tconst isErrorOrAborted =\n\t\t\tmessage.stopReason !== undefined && message.stopReason !== \"stop\" && message.stopReason !== \"toolUse\";\n\t\treturn hasText || isErrorOrAborted;\n\t}\n\n\tprivate passesNodeFilterMode(flatNode: FlatNode): boolean {\n\t\tconst entry = flatNode.node.entry;\n\t\tconst isSettingsEntry =\n\t\t\tentry.type === \"label\" ||\n\t\t\tentry.type === \"custom\" ||\n\t\t\tentry.type === \"model_change\" ||\n\t\t\tentry.type === \"thinking_level_change\" ||\n\t\t\tentry.type === \"session_info\";\n\t\tswitch (this.filterMode) {\n\t\t\tcase \"user-only\":\n\t\t\t\treturn entry.type === \"message\" && entry.message.role === \"user\";\n\t\t\tcase \"no-tools\":\n\t\t\t\treturn !isSettingsEntry && !(entry.type === \"message\" && entry.message.role === \"toolResult\");\n\t\t\tcase \"labeled-only\":\n\t\t\t\treturn flatNode.node.label !== undefined;\n\t\t\tcase \"all\":\n\t\t\t\treturn true;\n\t\t\tdefault:\n\t\t\t\treturn !isSettingsEntry;\n\t\t}\n\t}\n\n\tprivate matchesNodeSearch(flatNode: FlatNode, searchTokens: string[]): boolean {\n\t\tif (searchTokens.length === 0) return true;\n\t\tconst nodeText: string = this.getSearchableText(flatNode.node).toLowerCase();\n\t\treturn searchTokens.every((token) => nodeText.includes(token));\n\t}\n\n\tprivate shouldIncludeFilteredNode(flatNode: FlatNode, searchTokens: string[]): boolean {\n\t\tif (!this.shouldDisplayAssistantNode(flatNode)) return false;\n\t\tif (!this.passesNodeFilterMode(flatNode)) return false;\n\t\treturn this.matchesNodeSearch(flatNode, searchTokens);\n\t}\n\tprivate applyFilter(): void {\n\t\t// Update lastSelectedId only when we have a valid selection (non-empty list)\n\t\t// This preserves the selection when switching through empty filter results\n\t\tif (this.filteredNodes.length > 0) {\n\t\t\tthis.lastSelectedId = this.filteredNodes[this.selectedIndex]?.node.entry.id ?? this.lastSelectedId;\n\t\t}\n\n\t\tconst searchTokens = this.searchQuery.toLowerCase().split(/\\s+/).filter(Boolean);\n\n\t\tthis.filteredNodes = this.flatNodes.filter((flatNode) => this.shouldIncludeFilteredNode(flatNode, searchTokens));\n\n\t\t// Filter out descendants of folded nodes.\n\t\tif (this.foldedNodes.size > 0) {\n\t\t\tconst skipSet = new Set<string>();\n\t\t\tfor (const flatNode of this.flatNodes) {\n\t\t\t\tconst { id, parentId } = flatNode.node.entry;\n\t\t\t\tif (parentId != null && (this.foldedNodes.has(parentId) || skipSet.has(parentId))) {\n\t\t\t\t\tskipSet.add(id);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.filteredNodes = this.filteredNodes.filter((flatNode) => !skipSet.has(flatNode.node.entry.id));\n\t\t}\n\n\t\t// Recalculate visual structure (indent, connectors, gutters) based on visible tree\n\t\tthis.recalculateVisualStructure();\n\n\t\t// Try to preserve cursor on the same node, or find nearest visible ancestor\n\t\tif (this.lastSelectedId) {\n\t\t\tthis.selectedIndex = this.findNearestVisibleIndex(this.lastSelectedId);\n\t\t} else if (this.selectedIndex >= this.filteredNodes.length) {\n\t\t\t// Clamp index if out of bounds\n\t\t\tthis.selectedIndex = Math.max(0, this.filteredNodes.length - 1);\n\t\t}\n\n\t\t// Update lastSelectedId to the actual selection (may have changed due to parent walk)\n\t\tif (this.filteredNodes.length > 0) {\n\t\t\tthis.lastSelectedId = this.filteredNodes[this.selectedIndex]?.node.entry.id ?? this.lastSelectedId;\n\t\t}\n\t}\n\n\tprivate findNearestVisibleAncestor(\n\t\tnodeId: string,\n\t\tvisibleIds: ReadonlySet<string>,\n\t\tnodesById: ReadonlyMap<string, FlatNode>,\n\t): string | null {\n\t\tlet currentId = nodesById.get(nodeId)?.node.entry.parentId ?? null;\n\t\twhile (currentId !== null) {\n\t\t\tif (visibleIds.has(currentId)) return currentId;\n\t\t\tcurrentId = nodesById.get(currentId)?.node.entry.parentId ?? null;\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate buildVisibleTreeStructure(): VisibleTreeStructure {\n\t\tconst visibleIds = new Set(this.filteredNodes.map((flatNode) => flatNode.node.entry.id));\n\t\tconst allNodesById = new Map<string, FlatNode>();\n\t\tfor (const flatNode of this.flatNodes) allNodesById.set(flatNode.node.entry.id, flatNode);\n\t\tconst parentMap = new Map<string, string | null>();\n\t\tconst childrenMap = new Map<string | null, string[]>([[null, []]]);\n\t\tconst nodesById = new Map<string, FlatNode>();\n\t\tfor (const flatNode of this.filteredNodes) {\n\t\t\tconst nodeId = flatNode.node.entry.id;\n\t\t\tconst ancestorId = this.findNearestVisibleAncestor(nodeId, visibleIds, allNodesById);\n\t\t\tparentMap.set(nodeId, ancestorId);\n\t\t\tnodesById.set(nodeId, flatNode);\n\t\t\tlet children = childrenMap.get(ancestorId);\n\t\t\tif (!children) {\n\t\t\t\tchildren = [];\n\t\t\t\tchildrenMap.set(ancestorId, children);\n\t\t\t}\n\t\t\tchildren.push(nodeId);\n\t\t}\n\t\treturn { parentMap, childrenMap, nodesById, rootIds: childrenMap.get(null) ?? [] };\n\t}\n\n\tprivate resolveVisibleChildLayout(item: TreeTraversalItem, multipleChildren: boolean): VisibleChildLayout {\n\t\tlet indent = item.indent;\n\t\tif (multipleChildren || (item.justBranched && item.indent > 0)) indent++;\n\t\tconst connectorDisplayed = item.showConnector && !item.isVirtualRootChild;\n\t\tconst currentDisplayIndent = this.multipleRoots ? Math.max(0, item.indent - 1) : item.indent;\n\t\tconst connectorPosition = Math.max(0, currentDisplayIndent - 1);\n\t\tconst gutters = connectorDisplayed\n\t\t\t? [...item.gutters, { position: connectorPosition, show: !item.isLast }]\n\t\t\t: item.gutters;\n\t\treturn { indent, gutters, branched: multipleChildren };\n\t}\n\n\tprivate layoutVisibleTree(structure: VisibleTreeStructure): void {\n\t\tconst stack: TreeTraversalItem[] = [];\n\t\tfor (let index = structure.rootIds.length - 1; index >= 0; index--) {\n\t\t\tconst flatNode = structure.nodesById.get(structure.rootIds[index]);\n\t\t\tif (!flatNode) continue;\n\t\t\tstack.push({\n\t\t\t\tnode: flatNode.node,\n\t\t\t\tindent: this.multipleRoots ? 1 : 0,\n\t\t\t\tjustBranched: this.multipleRoots,\n\t\t\t\tshowConnector: this.multipleRoots,\n\t\t\t\tisLast: index === structure.rootIds.length - 1,\n\t\t\t\tgutters: [],\n\t\t\t\tisVirtualRootChild: this.multipleRoots,\n\t\t\t});\n\t\t}\n\t\twhile (stack.length > 0) {\n\t\t\tconst item = stack.pop()!;\n\t\t\tconst nodeId = item.node.entry.id;\n\t\t\tconst flatNode = structure.nodesById.get(nodeId);\n\t\t\tif (!flatNode) continue;\n\t\t\tflatNode.indent = item.indent;\n\t\t\tflatNode.showConnector = item.showConnector;\n\t\t\tflatNode.isLast = item.isLast;\n\t\t\tflatNode.gutters = item.gutters;\n\t\t\tflatNode.isVirtualRootChild = item.isVirtualRootChild;\n\t\t\tconst children = structure.childrenMap.get(nodeId) ?? [];\n\t\t\tconst childLayout = this.resolveVisibleChildLayout(item, children.length > 1);\n\t\t\tfor (let index = children.length - 1; index >= 0; index--) {\n\t\t\t\tconst child = structure.nodesById.get(children[index]);\n\t\t\t\tif (!child) continue;\n\t\t\t\tstack.push({\n\t\t\t\t\tnode: child.node,\n\t\t\t\t\tindent: childLayout.indent,\n\t\t\t\t\tjustBranched: childLayout.branched,\n\t\t\t\t\tshowConnector: childLayout.branched,\n\t\t\t\t\tisLast: index === children.length - 1,\n\t\t\t\t\tgutters: childLayout.gutters,\n\t\t\t\t\tisVirtualRootChild: false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Recompute indentation/connectors for the filtered view.\n\t * Filtering can hide intermediate entries, so descendants attach to the nearest visible ancestor.\n\t */\n\tprivate recalculateVisualStructure(): void {\n\t\tif (this.filteredNodes.length === 0) return;\n\t\tconst structure = this.buildVisibleTreeStructure();\n\t\tthis.multipleRoots = structure.rootIds.length > 1;\n\t\tthis.layoutVisibleTree(structure);\n\t\tthis.visibleParentMap = structure.parentMap;\n\t\tthis.visibleChildrenMap = structure.childrenMap;\n\t}\n\n\t/** Get searchable text content from a node */\n\tprivate getSearchableText(node: SessionTreeNode): string {\n\t\tconst entry = node.entry;\n\t\tconst parts: string[] = [];\n\n\t\tif (node.label) {\n\t\t\tparts.push(node.label);\n\t\t}\n\n\t\tswitch (entry.type) {\n\t\t\tcase \"message\": {\n\t\t\t\tconst msg = entry.message;\n\t\t\t\tparts.push(msg.role);\n\t\t\t\tif (\"content\" in msg && msg.content) {\n\t\t\t\t\tparts.push(this.extractContent(msg.content));\n\t\t\t\t}\n\t\t\t\tif (msg.role === \"bashExecution\") {\n\t\t\t\t\tconst bashMsg = msg as { command?: string };\n\t\t\t\t\tif (bashMsg.command) parts.push(bashMsg.command);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"custom_message\": {\n\t\t\t\tparts.push(entry.customType);\n\t\t\t\tif (typeof entry.content === \"string\") {\n\t\t\t\t\tparts.push(entry.content);\n\t\t\t\t} else {\n\t\t\t\t\tparts.push(this.extractContent(entry.content));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"compaction\":\n\t\t\t\tparts.push(\"compaction\");\n\t\t\t\tbreak;\n\t\t\tcase \"branch_summary\":\n\t\t\t\tparts.push(\"branch summary\", entry.summary);\n\t\t\t\tbreak;\n\t\t\tcase \"session_info\":\n\t\t\t\tparts.push(\"title\");\n\t\t\t\tif (entry.name) parts.push(entry.name);\n\t\t\t\tbreak;\n\t\t\tcase \"model_change\":\n\t\t\t\tparts.push(\"model\", entry.modelId);\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_level_change\":\n\t\t\t\tparts.push(\"thinking\", entry.thinkingLevel);\n\t\t\t\tbreak;\n\t\t\tcase \"custom\":\n\t\t\t\tparts.push(\"custom\", entry.customType);\n\t\t\t\tbreak;\n\t\t\tcase \"label\":\n\t\t\t\tparts.push(\"label\", entry.label ?? \"\");\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn parts.join(\" \");\n\t}\n\n\tinvalidate(): void {}\n\n\tgetSearchQuery(): string {\n\t\treturn this.searchQuery;\n\t}\n\n\tgetSelectedNode(): SessionTreeNode | undefined {\n\t\treturn this.filteredNodes[this.selectedIndex]?.node;\n\t}\n\n\tcopySelected(): void {\n\t\tconst node = this.getSelectedNode();\n\t\tthis.onCopy?.(node ? this.getEntryCopyText(node) : undefined);\n\t}\n\n\tupdateNodeLabel(entryId: string, label: string | undefined, labelTimestamp?: string): void {\n\t\tfor (const flatNode of this.flatNodes) {\n\t\t\tif (flatNode.node.entry.id === entryId) {\n\t\t\t\tflatNode.node.label = label;\n\t\t\t\tflatNode.node.labelTimestamp = label ? (labelTimestamp ?? new Date().toISOString()) : undefined;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getStatusLabels(): string {\n\t\tlet labels = \"\";\n\t\tswitch (this.filterMode) {\n\t\t\tcase \"no-tools\":\n\t\t\t\tlabels += \" [no-tools]\";\n\t\t\t\tbreak;\n\t\t\tcase \"user-only\":\n\t\t\t\tlabels += \" [user]\";\n\t\t\t\tbreak;\n\t\t\tcase \"labeled-only\":\n\t\t\t\tlabels += \" [labeled]\";\n\t\t\t\tbreak;\n\t\t\tcase \"all\":\n\t\t\t\tlabels += \" [all]\";\n\t\t\t\tbreak;\n\t\t}\n\t\tif (this.showLabelTimestamps) {\n\t\t\tlabels += \" [+label time]\";\n\t\t}\n\t\treturn labels;\n\t}\n\n\tprivate getVisibleNodeRange(): VisibleNodeRange {\n\t\tconst start = Math.max(\n\t\t\t0,\n\t\t\tMath.min(\n\t\t\t\tthis.selectedIndex - Math.floor(this.maxVisibleLines / 2),\n\t\t\t\tthis.filteredNodes.length - this.maxVisibleLines,\n\t\t\t),\n\t\t);\n\t\treturn { start, end: Math.min(start + this.maxVisibleLines, this.filteredNodes.length) };\n\t}\n\n\tprivate renderPrefixCharacter(\n\t\tflatNode: FlatNode,\n\t\tentryId: string,\n\t\tlevel: number,\n\t\tposition: number,\n\t\tconnectorPosition: number,\n\t\tisFolded: boolean,\n\t): string {\n\t\tconst gutter = flatNode.gutters.find((candidate) => candidate.position === level);\n\t\tif (gutter) return position === 0 && gutter.show ? \"│\" : \" \";\n\t\tif (level !== connectorPosition) return \" \";\n\t\tif (position === 0) return flatNode.isLast ? \"└\" : \"├\";\n\t\tif (position !== 1) return \" \";\n\t\tif (isFolded) return \"⊞\";\n\t\treturn this.isFoldable(entryId) ? \"⊟\" : \"─\";\n\t}\n\n\tprivate renderNodePrefix(flatNode: FlatNode): string {\n\t\tconst displayIndent = this.multipleRoots ? Math.max(0, flatNode.indent - 1) : flatNode.indent;\n\t\tconst showsConnector = flatNode.showConnector && !flatNode.isVirtualRootChild;\n\t\tconst connectorPosition = showsConnector ? displayIndent - 1 : -1;\n\t\tconst isFolded = this.foldedNodes.has(flatNode.node.entry.id);\n\t\tconst characters: string[] = [];\n\t\tfor (let index = 0; index < displayIndent * 3; index++) {\n\t\t\tcharacters.push(\n\t\t\t\tthis.renderPrefixCharacter(\n\t\t\t\t\tflatNode,\n\t\t\t\t\tflatNode.node.entry.id,\n\t\t\t\t\tMath.floor(index / 3),\n\t\t\t\t\tindex % 3,\n\t\t\t\t\tconnectorPosition,\n\t\t\t\t\tisFolded,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst foldMarker = isFolded && !showsConnector ? theme.fg(\"accent\", \"⊞ \") : \"\";\n\t\treturn theme.fg(\"dim\", characters.join(\"\")) + foldMarker;\n\t}\n\n\tprivate renderNodeLine(flatNode: FlatNode, index: number, width: number): string {\n\t\tconst entry = flatNode.node.entry;\n\t\tconst isSelected = index === this.selectedIndex;\n\t\tconst cursor = isSelected ? theme.fg(\"accent\", \"› \") : \" \";\n\t\tconst pathMarker = this.activePathIds.has(entry.id) ? theme.fg(\"accent\", \"• \") : \"\";\n\t\tconst label = flatNode.node.label ? theme.fg(\"warning\", `[${flatNode.node.label}] `) : \"\";\n\t\tconst labelTimestamp =\n\t\t\tthis.showLabelTimestamps && flatNode.node.label && flatNode.node.labelTimestamp\n\t\t\t\t? theme.fg(\"muted\", `${this.formatLabelTimestamp(flatNode.node.labelTimestamp)} `)\n\t\t\t\t: \"\";\n\t\tconst content = this.getEntryDisplayText(flatNode.node, isSelected);\n\t\tconst line = cursor + this.renderNodePrefix(flatNode) + pathMarker + label + labelTimestamp + content;\n\t\treturn truncateToWidth(isSelected ? theme.bg(\"selectedBg\", line) : line, width);\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.filteredNodes.length === 0) {\n\t\t\treturn [\n\t\t\t\ttruncateToWidth(theme.fg(\"muted\", \" No entries found\"), width),\n\t\t\t\ttruncateToWidth(theme.fg(\"muted\", ` (0/0)${this.getStatusLabels()}`), width),\n\t\t\t];\n\t\t}\n\t\tconst lines: string[] = [];\n\t\tconst range = this.getVisibleNodeRange();\n\t\tfor (let index = range.start; index < range.end; index++) {\n\t\t\tlines.push(this.renderNodeLine(this.filteredNodes[index], index, width));\n\t\t}\n\t\tlines.push(\n\t\t\ttruncateToWidth(\n\t\t\t\ttheme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.filteredNodes.length})${this.getStatusLabels()}`),\n\t\t\t\twidth,\n\t\t\t),\n\t\t);\n\t\treturn lines;\n\t}\n\tprivate normalizeDisplayText(value: string): string {\n\t\treturn value.replace(/[\\n\\t]/g, \" \").trim();\n\t}\n\n\tprivate getAssistantDisplayText(message: AssistantMessage): string {\n\t\tconst textContent = this.normalizeDisplayText(this.extractContent(message.content));\n\t\tif (textContent) return theme.fg(\"success\", \"assistant: \") + textContent;\n\t\tif (message.stopReason === \"aborted\") {\n\t\t\treturn theme.fg(\"success\", \"assistant: \") + theme.fg(\"muted\", \"(aborted)\");\n\t\t}\n\t\tif (message.errorMessage) {\n\t\t\tconst errorMessage = this.normalizeDisplayText(message.errorMessage).slice(0, 80);\n\t\t\treturn theme.fg(\"success\", \"assistant: \") + theme.fg(\"error\", errorMessage);\n\t\t}\n\t\treturn theme.fg(\"success\", \"assistant: \") + theme.fg(\"muted\", \"(no content)\");\n\t}\n\n\tprivate getMessageDisplayText(message: AgentMessage): string {\n\t\tswitch (message.role) {\n\t\t\tcase \"user\":\n\t\t\t\treturn theme.fg(\"accent\", \"user: \") + this.normalizeDisplayText(this.extractContent(message.content));\n\t\t\tcase \"assistant\":\n\t\t\t\treturn this.getAssistantDisplayText(message);\n\t\t\tcase \"toolResult\": {\n\t\t\t\tconst toolCall = this.toolCallMap.get(message.toolCallId);\n\t\t\t\treturn toolCall\n\t\t\t\t\t? theme.fg(\"muted\", this.formatToolCall(toolCall.name, toolCall.arguments))\n\t\t\t\t\t: theme.fg(\"muted\", `[${message.toolName ?? \"tool\"}]`);\n\t\t\t}\n\t\t\tcase \"bashExecution\":\n\t\t\t\treturn theme.fg(\"dim\", `[bash]: ${this.normalizeDisplayText(message.command ?? \"\")}`);\n\t\t\tdefault:\n\t\t\t\treturn theme.fg(\"dim\", `[${message.role}]`);\n\t\t}\n\t}\n\n\tprivate getEntryDisplayText(node: SessionTreeNode, isSelected: boolean): string {\n\t\tconst entry = node.entry;\n\t\tlet result: string;\n\n\t\tswitch (entry.type) {\n\t\t\tcase \"message\":\n\t\t\t\tresult = this.getMessageDisplayText(entry.message);\n\t\t\t\tbreak;\n\t\t\tcase \"custom_message\":\n\t\t\t\tresult =\n\t\t\t\t\ttheme.fg(\"customMessageLabel\", `[${entry.customType}]: `) +\n\t\t\t\t\tthis.normalizeDisplayText(this.extractFullContent(entry.content));\n\t\t\t\tbreak;\n\t\t\tcase \"compaction\": {\n\t\t\t\tconst tokens = Math.round(entry.tokensBefore / 1000);\n\t\t\t\tresult = theme.fg(\"borderAccent\", `[compaction: ${tokens}k tokens]`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"branch_summary\":\n\t\t\t\tresult = theme.fg(\"warning\", `[branch summary]: `) + this.normalizeDisplayText(entry.summary);\n\t\t\t\tbreak;\n\t\t\tcase \"model_change\":\n\t\t\t\tresult = theme.fg(\"dim\", `[model: ${entry.modelId}]`);\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_level_change\":\n\t\t\t\tresult = theme.fg(\"dim\", `[thinking: ${entry.thinkingLevel}]`);\n\t\t\t\tbreak;\n\t\t\tcase \"custom\":\n\t\t\t\tresult = theme.fg(\"dim\", `[custom: ${entry.customType}]`);\n\t\t\t\tbreak;\n\t\t\tcase \"label\":\n\t\t\t\tresult = theme.fg(\"dim\", `[label: ${entry.label ?? \"(cleared)\"}]`);\n\t\t\t\tbreak;\n\t\t\tcase \"session_info\":\n\t\t\t\tresult = entry.name\n\t\t\t\t\t? [theme.fg(\"dim\", \"[title: \"), theme.fg(\"dim\", entry.name), theme.fg(\"dim\", \"]\")].join(\"\")\n\t\t\t\t\t: [theme.fg(\"dim\", \"[title: \"), theme.italic(theme.fg(\"dim\", \"empty\")), theme.fg(\"dim\", \"]\")].join(\"\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tresult = \"\";\n\t\t}\n\n\t\treturn isSelected ? theme.bold(result) : result;\n\t}\n\n\tprivate formatLabelTimestamp(timestamp: string): string {\n\t\tconst date = new Date(timestamp);\n\t\tconst now = new Date();\n\t\tconst hours = date.getHours().toString().padStart(2, \"0\");\n\t\tconst minutes = date.getMinutes().toString().padStart(2, \"0\");\n\t\tconst time = `${hours}:${minutes}`;\n\n\t\tif (\n\t\t\tdate.getFullYear() === now.getFullYear() &&\n\t\t\tdate.getMonth() === now.getMonth() &&\n\t\t\tdate.getDate() === now.getDate()\n\t\t) {\n\t\t\treturn time;\n\t\t}\n\n\t\tconst month = date.getMonth() + 1;\n\t\tconst day = date.getDate();\n\t\tif (date.getFullYear() === now.getFullYear()) {\n\t\t\treturn `${month}/${day} ${time}`;\n\t\t}\n\n\t\tconst year = date.getFullYear().toString().slice(-2);\n\t\treturn `${year}/${month}/${day} ${time}`;\n\t}\n\n\tprivate extractContent(content: unknown): string {\n\t\treturn this.extractFullContent(content).slice(0, 200);\n\t}\n\n\tprivate extractFullContent(content: unknown): string {\n\t\tif (typeof content === \"string\") return content;\n\t\tif (!Array.isArray(content)) return \"\";\n\n\t\tlet result = \"\";\n\t\tfor (const block of content) {\n\t\t\tif (typeof block === \"object\" && block !== null && \"type\" in block && block.type === \"text\") {\n\t\t\t\tresult += (block as { text: string }).text;\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate getEntryCopyText(node: SessionTreeNode): string | undefined {\n\t\tconst entry = node.entry;\n\t\tlet text: string | undefined;\n\n\t\tswitch (entry.type) {\n\t\t\tcase \"message\":\n\t\t\t\tif (entry.message.role === \"bashExecution\") {\n\t\t\t\t\ttext = entry.message.command;\n\t\t\t\t} else if (\"content\" in entry.message) {\n\t\t\t\t\ttext = this.extractFullContent(entry.message.content);\n\t\t\t\t\tif (!text && entry.message.role === \"assistant\") {\n\t\t\t\t\t\ttext = entry.message.errorMessage;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"custom_message\":\n\t\t\t\ttext = this.extractFullContent(entry.content);\n\t\t\t\tbreak;\n\t\t\tcase \"compaction\":\n\t\t\t\ttext = entry.summary;\n\t\t\t\tbreak;\n\t\t\tcase \"branch_summary\":\n\t\t\t\ttext = entry.summary;\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn text?.trim() ? text : undefined;\n\t}\n\n\tprivate hasTextContent(content: unknown): boolean {\n\t\tif (typeof content === \"string\") return content.trim().length > 0;\n\t\tif (Array.isArray(content)) {\n\t\t\tfor (const c of content) {\n\t\t\t\tif (typeof c === \"object\" && c !== null && \"type\" in c && c.type === \"text\") {\n\t\t\t\t\tconst text = (c as { text?: string }).text;\n\t\t\t\t\tif (text && text.trim().length > 0) return true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate formatToolCall(name: string, args: Record<string, unknown>): string {\n\t\tswitch (name) {\n\t\t\tcase \"read\":\n\t\t\t\treturn formatTreeReadToolCall(args);\n\t\t\tcase \"write\":\n\t\t\tcase \"edit\":\n\t\t\t\treturn formatTreeFileMutationToolCall(name, args);\n\t\t\tcase \"bash\":\n\t\t\t\treturn formatTreeBashToolCall(args);\n\t\t\tcase \"grep\":\n\t\t\tcase \"find\":\n\t\t\t\treturn formatTreeSearchToolCall(name, args);\n\t\t\tcase \"ls\":\n\t\t\t\treturn `[ls: ${shortenTreeToolPath(String(args.path || \".\"))}]`;\n\t\t\tdefault:\n\t\t\t\treturn formatCustomTreeToolCall(name, args);\n\t\t}\n\t}\n\n\tprivate foldSelectedNodeOrMoveToPreviousBranch(): void {\n\t\tconst currentId = this.filteredNodes[this.selectedIndex]?.node.entry.id;\n\t\tif (currentId && this.isFoldable(currentId) && !this.foldedNodes.has(currentId)) {\n\t\t\tthis.foldedNodes.add(currentId);\n\t\t\tthis.applyFilter();\n\t\t\treturn;\n\t\t}\n\t\tthis.selectedIndex = this.findBranchSegmentStart(\"up\");\n\t}\n\n\tprivate unfoldSelectedNodeOrMoveToNextBranch(): void {\n\t\tconst currentId = this.filteredNodes[this.selectedIndex]?.node.entry.id;\n\t\tif (currentId && this.foldedNodes.has(currentId)) {\n\t\t\tthis.foldedNodes.delete(currentId);\n\t\t\tthis.applyFilter();\n\t\t\treturn;\n\t\t}\n\t\tthis.selectedIndex = this.findBranchSegmentStart(\"down\");\n\t}\n\n\tprivate handleTreeMovementInput(keyData: string): boolean {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = this.selectedIndex === 0 ? this.filteredNodes.length - 1 : this.selectedIndex - 1;\n\t\t\treturn true;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = this.selectedIndex === this.filteredNodes.length - 1 ? 0 : this.selectedIndex + 1;\n\t\t\treturn true;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.tree.foldOrUp\")) {\n\t\t\tthis.foldSelectedNodeOrMoveToPreviousBranch();\n\t\t\treturn true;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.tree.unfoldOrDown\")) {\n\t\t\tthis.unfoldSelectedNodeOrMoveToNextBranch();\n\t\t\treturn true;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.editor.cursorLeft\") || kb.matches(keyData, \"tui.select.pageUp\")) {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - this.maxVisibleLines);\n\t\t\treturn true;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.editor.cursorRight\") || kb.matches(keyData, \"tui.select.pageDown\")) {\n\t\t\tthis.selectedIndex = Math.min(this.filteredNodes.length - 1, this.selectedIndex + this.maxVisibleLines);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate cancelSearchOrSelection(): void {\n\t\tif (!this.searchQuery) {\n\t\t\tthis.onCancel?.();\n\t\t\treturn;\n\t\t}\n\t\tthis.searchQuery = \"\";\n\t\tthis.foldedNodes.clear();\n\t\tthis.applyFilter();\n\t}\n\n\tprivate handleTreeSelectionInput(keyData: string): boolean {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst selected = this.filteredNodes[this.selectedIndex];\n\t\t\tif (selected) this.onSelect?.(selected.node.entry.id);\n\t\t\treturn true;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.message.copy\")) {\n\t\t\tthis.copySelected();\n\t\t\treturn true;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.cancelSearchOrSelection();\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate setFilterMode(mode: FilterMode): void {\n\t\tthis.filterMode = mode;\n\t\tthis.foldedNodes.clear();\n\t\tthis.applyFilter();\n\t}\n\n\tprivate toggleFilterMode(mode: FilterMode): void {\n\t\tthis.setFilterMode(this.filterMode === mode ? \"default\" : mode);\n\t}\n\n\tprivate cycleFilterMode(step: number): void {\n\t\tconst currentIndex = FILTER_MODES.indexOf(this.filterMode);\n\t\tthis.setFilterMode(FILTER_MODES[(currentIndex + step + FILTER_MODES.length) % FILTER_MODES.length]);\n\t}\n\n\tprivate handleTreeFilterInput(keyData: string): boolean {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"app.tree.filter.default\")) this.setFilterMode(\"default\");\n\t\telse if (kb.matches(keyData, \"app.tree.filter.noTools\")) this.toggleFilterMode(\"no-tools\");\n\t\telse if (kb.matches(keyData, \"app.tree.filter.userOnly\")) this.toggleFilterMode(\"user-only\");\n\t\telse if (kb.matches(keyData, \"app.tree.filter.labeledOnly\")) this.toggleFilterMode(\"labeled-only\");\n\t\telse if (kb.matches(keyData, \"app.tree.filter.all\")) this.toggleFilterMode(\"all\");\n\t\telse if (kb.matches(keyData, \"app.tree.filter.cycleBackward\")) this.cycleFilterMode(-1);\n\t\telse if (kb.matches(keyData, \"app.tree.filter.cycleForward\")) this.cycleFilterMode(1);\n\t\telse return false;\n\t\treturn true;\n\t}\n\n\tprivate appendTreeSearchInput(keyData: string): void {\n\t\tif (keyData.length === 0 || hasTreeSearchControlCharacters(keyData)) return;\n\t\tthis.searchQuery += keyData;\n\t\tthis.foldedNodes.clear();\n\t\tthis.applyFilter();\n\t}\n\n\tprivate handleTreeEditingInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.editor.deleteCharBackward\")) {\n\t\t\tif (this.searchQuery.length > 0) {\n\t\t\t\tthis.searchQuery = this.searchQuery.slice(0, -1);\n\t\t\t\tthis.foldedNodes.clear();\n\t\t\t\tthis.applyFilter();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.tree.editLabel\")) {\n\t\t\tconst selected = this.filteredNodes[this.selectedIndex];\n\t\t\tif (selected) this.onLabelEdit?.(selected.node.entry.id, selected.node.label);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.tree.toggleLabelTimestamp\")) {\n\t\t\tthis.showLabelTimestamps = !this.showLabelTimestamps;\n\t\t\treturn;\n\t\t}\n\t\tthis.appendTreeSearchInput(keyData);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tif (this.handleTreeMovementInput(keyData)) return;\n\t\tif (this.handleTreeSelectionInput(keyData)) return;\n\t\tif (this.handleTreeFilterInput(keyData)) return;\n\t\tthis.handleTreeEditingInput(keyData);\n\t}\n\n\t/**\n\t * Whether a node can be folded. A node is foldable if it has visible children\n\t * and is either a root (no visible parent) or a segment start (visible parent\n\t * has multiple visible children).\n\t */\n\tprivate isFoldable(entryId: string): boolean {\n\t\tconst children = this.visibleChildrenMap.get(entryId);\n\t\tif (!children || children.length === 0) return false;\n\t\tconst parentId = this.visibleParentMap.get(entryId);\n\t\tif (parentId === null || parentId === undefined) return true;\n\t\tconst siblings = this.visibleChildrenMap.get(parentId);\n\t\treturn siblings !== undefined && siblings.length > 1;\n\t}\n\n\tprivate findNextBranchSegmentStart(selectedId: string, indexByEntryId: ReadonlyMap<string, number>): number {\n\t\tlet currentId = selectedId;\n\t\twhile (true) {\n\t\t\tconst children = this.visibleChildrenMap.get(currentId) ?? [];\n\t\t\tif (children.length === 0) return indexByEntryId.get(currentId)!;\n\t\t\tif (children.length > 1) return indexByEntryId.get(children[0])!;\n\t\t\tcurrentId = children[0];\n\t\t}\n\t}\n\n\tprivate findPreviousBranchSegmentStart(selectedId: string, indexByEntryId: ReadonlyMap<string, number>): number {\n\t\tlet currentId = selectedId;\n\t\twhile (true) {\n\t\t\tconst parentId = this.visibleParentMap.get(currentId) ?? null;\n\t\t\tif (parentId === null) return indexByEntryId.get(currentId)!;\n\t\t\tconst siblings = this.visibleChildrenMap.get(parentId) ?? [];\n\t\t\tif (siblings.length > 1) {\n\t\t\t\tconst segmentStart = indexByEntryId.get(currentId)!;\n\t\t\t\tif (segmentStart < this.selectedIndex) return segmentStart;\n\t\t\t}\n\t\t\tcurrentId = parentId;\n\t\t}\n\t}\n\n\t/**\n\t * Find the index of the next branch segment start in the given direction.\n\t * A segment start is the first child of a branch point.\n\t *\n\t * \"up\" walks the visible parent chain; \"down\" walks visible children\n\t * (always following the first child).\n\t */\n\tprivate findBranchSegmentStart(direction: BranchSegmentTraversalDirection): number {\n\t\tconst selectedId = this.filteredNodes[this.selectedIndex]?.node.entry.id;\n\t\tif (!selectedId) return this.selectedIndex;\n\n\t\tconst indexByEntryId = new Map(this.filteredNodes.map((node, index) => [node.node.entry.id, index]));\n\t\treturn direction === \"down\"\n\t\t\t? this.findNextBranchSegmentStart(selectedId, indexByEntryId)\n\t\t\t: this.findPreviousBranchSegmentStart(selectedId, indexByEntryId);\n\t}\n}\n\n/** Component that displays the current search query */\nclass SearchLine implements Component {\n\tprivate treeList: TreeList;\n\n\tconstructor(treeList: TreeList) {\n\t\tthis.treeList = treeList;\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst query = this.treeList.getSearchQuery();\n\t\tif (query) {\n\t\t\treturn [truncateToWidth(` ${theme.fg(\"muted\", \"Type to search:\")} ${theme.fg(\"accent\", query)}`, width)];\n\t\t}\n\t\treturn [truncateToWidth(` ${theme.fg(\"muted\", \"Type to search:\")}`, width)];\n\t}\n\n\thandleInput(_keyData: string): void {}\n}\n\n/** Label input component shown when editing a label */\nclass LabelInput implements Component, Focusable {\n\tprivate input: Input;\n\tprivate entryId: string;\n\tpublic onSubmit?: (entryId: string, label: string | undefined) => void;\n\tpublic onCancel?: () => void;\n\n\t// Focusable implementation - propagate to input for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.input.focused = value;\n\t}\n\n\tconstructor(entryId: string, currentLabel: string | undefined) {\n\t\tthis.entryId = entryId;\n\t\tthis.input = new Input();\n\t\tif (currentLabel) {\n\t\t\tthis.input.setValue(currentLabel);\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tconst indent = \" \";\n\t\tconst availableWidth = width - indent.length;\n\t\tlines.push(truncateToWidth(`${indent}${theme.fg(\"muted\", \"Label (empty to remove):\")}`, width));\n\t\tlines.push(...this.input.render(availableWidth).map((line) => truncateToWidth(`${indent}${line}`, width)));\n\t\tlines.push(\n\t\t\ttruncateToWidth(\n\t\t\t\t`${indent}${keyHint(\"tui.select.confirm\", \"save\")} ${keyHint(\"tui.select.cancel\", \"cancel\")}`,\n\t\t\t\twidth,\n\t\t\t),\n\t\t);\n\t\treturn lines;\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst value = this.input.getValue().trim();\n\t\t\tthis.onSubmit?.(this.entryId, value || undefined);\n\t\t} else if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel?.();\n\t\t} else {\n\t\t\tthis.input.handleInput(keyData);\n\t\t}\n\t}\n}\n\n/**\n * Component that renders a session tree selector for navigation\n */\nexport class TreeSelectorComponent extends Container implements Focusable {\n\tprivate treeList: TreeList;\n\tprivate labelInput: LabelInput | null = null;\n\tprivate labelInputContainer: Container;\n\tprivate treeContainer: Container;\n\tprivate onLabelChangeCallback?: (entryId: string, label: string | undefined) => void;\n\tpublic onCopy?: (text: string | undefined) => void;\n\n\t// Focusable implementation - propagate to labelInput when active for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\t// Propagate to labelInput when it's active\n\t\tif (this.labelInput) {\n\t\t\tthis.labelInput.focused = value;\n\t\t}\n\t}\n\n\tconstructor(\n\t\ttree: SessionTreeNode[],\n\t\tcurrentLeafId: string | null,\n\t\tterminalHeight: number,\n\t\tonSelect: (entryId: string) => void,\n\t\tonCancel: () => void,\n\t\tonLabelChange?: (entryId: string, label: string | undefined) => void,\n\t\tinitialSelectedId?: string,\n\t\tinitialFilterMode?: FilterMode,\n\t) {\n\t\tsuper();\n\n\t\tthis.onLabelChangeCallback = onLabelChange;\n\t\tconst maxVisibleLines = Math.max(5, Math.floor(terminalHeight / 2));\n\n\t\tthis.treeList = new TreeList(tree, currentLeafId, maxVisibleLines, initialSelectedId, initialFilterMode);\n\t\tthis.treeList.onSelect = onSelect;\n\t\tthis.treeList.onCancel = onCancel;\n\t\tthis.treeList.onCopy = (text) => this.onCopy?.(text);\n\t\tthis.treeList.onLabelEdit = (entryId, currentLabel) => this.showLabelInput(entryId, currentLabel);\n\n\t\tthis.treeContainer = new Container();\n\t\tthis.treeContainer.addChild(this.treeList);\n\n\t\tthis.labelInputContainer = new Container();\n\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Text(theme.bold(\" Session Tree\"), 1, 0));\n\t\tconst filterKeys = [\n\t\t\tkeyText(\"app.tree.filter.default\"),\n\t\t\tkeyText(\"app.tree.filter.noTools\"),\n\t\t\tkeyText(\"app.tree.filter.userOnly\"),\n\t\t\tkeyText(\"app.tree.filter.labeledOnly\"),\n\t\t\tkeyText(\"app.tree.filter.all\"),\n\t\t].join(\"/\");\n\t\tconst cycleKeys = `${keyText(\"app.tree.filter.cycleForward\")}/${keyText(\"app.tree.filter.cycleBackward\")}`;\n\t\tconst branchKeys = `${keyText(\"app.tree.foldOrUp\")}/${keyText(\"app.tree.unfoldOrDown\")}`;\n\t\tthis.addChild(\n\t\t\tnew TruncatedText(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\t` ↑/↓: move. ←/→: page. ${branchKeys}: fold/branch. ${keyText(\"app.message.copy\")}: copy. ${keyText(\"app.tree.editLabel\")}: label. ${filterKeys}: filters (${cycleKeys} cycle). ${keyText(\"app.tree.toggleLabelTimestamp\")}: label time`,\n\t\t\t\t),\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new SearchLine(this.treeList));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(this.treeContainer);\n\t\tthis.addChild(this.labelInputContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tif (tree.length === 0) {\n\t\t\tsetTimeout(() => onCancel(), 100);\n\t\t}\n\t}\n\n\tprivate showLabelInput(entryId: string, currentLabel: string | undefined): void {\n\t\tthis.labelInput = new LabelInput(entryId, currentLabel);\n\t\tthis.labelInput.onSubmit = (id, label) => {\n\t\t\tthis.treeList.updateNodeLabel(id, label);\n\t\t\tthis.onLabelChangeCallback?.(id, label);\n\t\t\tthis.hideLabelInput();\n\t\t};\n\t\tthis.labelInput.onCancel = () => this.hideLabelInput();\n\n\t\t// Propagate current focused state to the new labelInput\n\t\tthis.labelInput.focused = this._focused;\n\n\t\tthis.treeContainer.clear();\n\t\tthis.labelInputContainer.clear();\n\t\tthis.labelInputContainer.addChild(this.labelInput);\n\t}\n\n\tprivate hideLabelInput(): void {\n\t\tthis.labelInput = null;\n\t\tthis.labelInputContainer.clear();\n\t\tthis.treeContainer.clear();\n\t\tthis.treeContainer.addChild(this.treeList);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tif (this.labelInput) {\n\t\t\tthis.labelInput.handleInput(keyData);\n\t\t} else {\n\t\t\tthis.treeList.handleInput(keyData);\n\t\t}\n\t}\n\n\tgetTreeList(): TreeList {\n\t\treturn this.treeList;\n\t}\n}\n"]}
|