@kr78/pi-coding-agent 17.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14861 -0
- package/README.md +35 -0
- package/dist/CHANGELOG-chtdxh1z.md +14861 -0
- package/dist/cli.js +20483 -0
- package/dist/template-c2hyaytt.js +1653 -0
- package/dist/template-f8wx9vfn.css +1355 -0
- package/dist/template-qat058wr.html +55 -0
- package/dist/tool-views.generated-jdfmzwmn.js +35 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +104 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/extensions/README.md +142 -0
- package/examples/extensions/api-demo.ts +78 -0
- package/examples/extensions/chalk-logger.ts +25 -0
- package/examples/extensions/hello.ts +31 -0
- package/examples/extensions/pirate.ts +43 -0
- package/examples/extensions/plan-mode.ts +549 -0
- package/examples/extensions/reload-runtime.ts +38 -0
- package/examples/extensions/thinking-note.ts +13 -0
- package/examples/extensions/tools.ts +145 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +17 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +48 -0
- package/examples/hooks/confirm-destructive.ts +58 -0
- package/examples/hooks/custom-compaction.ts +115 -0
- package/examples/hooks/dirty-repo-guard.ts +51 -0
- package/examples/hooks/file-trigger.ts +40 -0
- package/examples/hooks/git-checkpoint.ts +52 -0
- package/examples/hooks/handoff.ts +149 -0
- package/examples/hooks/permission-gate.ts +33 -0
- package/examples/hooks/protected-paths.ts +29 -0
- package/examples/hooks/qna.ts +118 -0
- package/examples/hooks/status-line.ts +39 -0
- package/examples/sdk/01-minimal.ts +21 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +46 -0
- package/examples/sdk/04-skills.ts +43 -0
- package/examples/sdk/06-extensions.ts +82 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +35 -0
- package/examples/sdk/08-prompt-templates.ts +41 -0
- package/examples/sdk/08-slash-commands.ts +46 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
- package/examples/sdk/11-sessions.ts +47 -0
- package/examples/sdk/12-redis-sessions.ts +54 -0
- package/examples/sdk/13-sql-sessions.ts +61 -0
- package/examples/sdk/README.md +169 -0
- package/package.json +587 -0
- package/scripts/bench-guard.ts +71 -0
- package/scripts/bench-title-models.ts +332 -0
- package/scripts/build-binary.ts +117 -0
- package/scripts/bundle-dist.ts +123 -0
- package/scripts/compile-binary.ts +69 -0
- package/scripts/embed-mupdf-wasm.ts +67 -0
- package/scripts/format-prompts.ts +68 -0
- package/scripts/generate-aria-snapshot.ts +134 -0
- package/scripts/generate-docs-index.ts +58 -0
- package/scripts/generate-share-viewer.ts +34 -0
- package/scripts/legacy-pi-virtual-module.ts +205 -0
- package/scripts/measure-prompt-tokens.ts +63 -0
- package/scripts/omp +51 -0
- package/scripts/omp.ts +19 -0
- package/scripts/security-compare.ts +40 -0
- package/src/advisor/advise-tool.ts +234 -0
- package/src/advisor/config.ts +341 -0
- package/src/advisor/emission-guard.ts +172 -0
- package/src/advisor/index.ts +6 -0
- package/src/advisor/runtime.ts +1412 -0
- package/src/advisor/transcript-recorder.ts +215 -0
- package/src/advisor/watchdog.ts +135 -0
- package/src/async/index.ts +1 -0
- package/src/async/job-manager.ts +847 -0
- package/src/auto-thinking/classifier.ts +220 -0
- package/src/autolearn/controller.ts +152 -0
- package/src/autolearn/managed-skills.ts +255 -0
- package/src/autoresearch/command-resume.md +14 -0
- package/src/autoresearch/dashboard.ts +436 -0
- package/src/autoresearch/git.ts +331 -0
- package/src/autoresearch/helpers.ts +218 -0
- package/src/autoresearch/index.ts +541 -0
- package/src/autoresearch/prompt-setup.md +43 -0
- package/src/autoresearch/prompt.md +103 -0
- package/src/autoresearch/resume-message.md +10 -0
- package/src/autoresearch/state.ts +273 -0
- package/src/autoresearch/storage.ts +700 -0
- package/src/autoresearch/tools/init-experiment.ts +268 -0
- package/src/autoresearch/tools/log-experiment.ts +520 -0
- package/src/autoresearch/tools/run-experiment.ts +407 -0
- package/src/autoresearch/tools/update-notes.ts +109 -0
- package/src/autoresearch/types.ts +168 -0
- package/src/capability/context-file.ts +44 -0
- package/src/capability/extension-module.ts +34 -0
- package/src/capability/extension.ts +47 -0
- package/src/capability/fs.ts +117 -0
- package/src/capability/hook.ts +40 -0
- package/src/capability/index.ts +467 -0
- package/src/capability/instruction.ts +37 -0
- package/src/capability/mcp.ts +115 -0
- package/src/capability/prompt.ts +35 -0
- package/src/capability/rule-buckets.ts +66 -0
- package/src/capability/rule.ts +298 -0
- package/src/capability/settings.ts +34 -0
- package/src/capability/skill.ts +69 -0
- package/src/capability/slash-command.ts +40 -0
- package/src/capability/ssh.ts +41 -0
- package/src/capability/system-prompt.ts +34 -0
- package/src/capability/tool.ts +38 -0
- package/src/capability/types.ts +187 -0
- package/src/cleanse/agent.ts +226 -0
- package/src/cleanse/balance.ts +79 -0
- package/src/cleanse/checkers.ts +996 -0
- package/src/cleanse/index.ts +190 -0
- package/src/cleanse/loop.ts +51 -0
- package/src/cleanse/parsers.ts +726 -0
- package/src/cleanse/progress.ts +50 -0
- package/src/cleanse/prompts/assignment.md +47 -0
- package/src/cleanse/types.ts +72 -0
- package/src/cli/agents-cli.ts +138 -0
- package/src/cli/args.ts +368 -0
- package/src/cli/auth-broker-cli.ts +940 -0
- package/src/cli/auth-gateway-cli.ts +674 -0
- package/src/cli/bench-cli.ts +990 -0
- package/src/cli/browser-relay-cli.ts +119 -0
- package/src/cli/classify-install-target.ts +76 -0
- package/src/cli/claude-trace-cli.ts +795 -0
- package/src/cli/command-help.ts +107 -0
- package/src/cli/commands/init-xdg.ts +27 -0
- package/src/cli/completion-gen.ts +550 -0
- package/src/cli/config-cli.ts +459 -0
- package/src/cli/dry-balance-cli.ts +864 -0
- package/src/cli/extension-flags.ts +48 -0
- package/src/cli/file-processor.ts +132 -0
- package/src/cli/flag-tables.ts +367 -0
- package/src/cli/gallery-cli.ts +272 -0
- package/src/cli/gallery-fixtures/agentic.ts +420 -0
- package/src/cli/gallery-fixtures/codeintel.ts +187 -0
- package/src/cli/gallery-fixtures/edit.ts +254 -0
- package/src/cli/gallery-fixtures/fs.ts +245 -0
- package/src/cli/gallery-fixtures/index.ts +40 -0
- package/src/cli/gallery-fixtures/interaction.ts +46 -0
- package/src/cli/gallery-fixtures/memory.ts +81 -0
- package/src/cli/gallery-fixtures/misc.ts +177 -0
- package/src/cli/gallery-fixtures/search.ts +135 -0
- package/src/cli/gallery-fixtures/shell.ts +241 -0
- package/src/cli/gallery-fixtures/types.ts +57 -0
- package/src/cli/gallery-fixtures/web.ts +158 -0
- package/src/cli/gallery-screenshot.ts +279 -0
- package/src/cli/gc-cli.ts +1566 -0
- package/src/cli/grep-cli.ts +161 -0
- package/src/cli/grievances-cli.ts +256 -0
- package/src/cli/help-extra.ts +89 -0
- package/src/cli/initial-message.ts +58 -0
- package/src/cli/models-cli.ts +385 -0
- package/src/cli/plugin-cli.ts +996 -0
- package/src/cli/profile-alias.ts +369 -0
- package/src/cli/profile-bootstrap.ts +233 -0
- package/src/cli/read-cli.ts +99 -0
- package/src/cli/session-picker.ts +110 -0
- package/src/cli/setup-cli.ts +312 -0
- package/src/cli/setup-model-picker.ts +43 -0
- package/src/cli/shell-cli.ts +176 -0
- package/src/cli/ssh-cli.ts +179 -0
- package/src/cli/startup-cwd.ts +58 -0
- package/src/cli/stats-cli.ts +229 -0
- package/src/cli/thinking-levels.ts +7 -0
- package/src/cli/tiny-models-cli.ts +153 -0
- package/src/cli/ttsr-cli.ts +1013 -0
- package/src/cli/update-cli.ts +1184 -0
- package/src/cli/usage-cli.ts +1084 -0
- package/src/cli/usage-error.ts +7 -0
- package/src/cli/web-search-cli.ts +144 -0
- package/src/cli/worktree-cli.ts +311 -0
- package/src/cli-commands.ts +308 -0
- package/src/cli.ts +428 -0
- package/src/collab/crypto.ts +63 -0
- package/src/collab/display-name.ts +13 -0
- package/src/collab/guest.ts +764 -0
- package/src/collab/host.ts +692 -0
- package/src/collab/protocol.ts +296 -0
- package/src/collab/relay-client.ts +282 -0
- package/src/collab/replication-shrink.ts +111 -0
- package/src/commands/acp.ts +35 -0
- package/src/commands/agents.ts +58 -0
- package/src/commands/auth-broker.ts +100 -0
- package/src/commands/auth-gateway.ts +70 -0
- package/src/commands/bench.ts +64 -0
- package/src/commands/browser-relay.ts +53 -0
- package/src/commands/cleanse.ts +45 -0
- package/src/commands/commit.ts +47 -0
- package/src/commands/complete.ts +67 -0
- package/src/commands/completions.ts +61 -0
- package/src/commands/config.ts +52 -0
- package/src/commands/dry-balance.ts +43 -0
- package/src/commands/gallery.ts +61 -0
- package/src/commands/gc.ts +47 -0
- package/src/commands/grep.ts +49 -0
- package/src/commands/grievances.ts +52 -0
- package/src/commands/install.ts +107 -0
- package/src/commands/join.ts +40 -0
- package/src/commands/launch-help.ts +116 -0
- package/src/commands/launch.ts +34 -0
- package/src/commands/models.ts +61 -0
- package/src/commands/plugin.ts +79 -0
- package/src/commands/read.ts +39 -0
- package/src/commands/say.ts +146 -0
- package/src/commands/setup.ts +68 -0
- package/src/commands/share.ts +71 -0
- package/src/commands/shell.ts +30 -0
- package/src/commands/ssh.ts +61 -0
- package/src/commands/stats.ts +30 -0
- package/src/commands/tiny-models.ts +36 -0
- package/src/commands/token.ts +164 -0
- package/src/commands/ttsr.ts +125 -0
- package/src/commands/update.ts +34 -0
- package/src/commands/usage.ts +55 -0
- package/src/commands/web-search.ts +43 -0
- package/src/commands/worktree.ts +63 -0
- package/src/commit/agentic/agent.ts +322 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +383 -0
- package/src/commit/agentic/lock-files.ts +107 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +25 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +38 -0
- package/src/commit/agentic/state.ts +60 -0
- package/src/commit/agentic/tools/analyze-file.ts +148 -0
- package/src/commit/agentic/tools/git-file-diff.ts +191 -0
- package/src/commit/agentic/tools/git-hunk.ts +52 -0
- package/src/commit/agentic/tools/git-overview.ts +62 -0
- package/src/commit/agentic/tools/index.ts +54 -0
- package/src/commit/agentic/tools/propose-changelog.ts +147 -0
- package/src/commit/agentic/tools/propose-commit.ts +109 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/schemas.ts +11 -0
- package/src/commit/agentic/tools/split-commit.ts +241 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +183 -0
- package/src/commit/analysis/conventional.ts +64 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +107 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +40 -0
- package/src/commit/changelog/generate.ts +101 -0
- package/src/commit/changelog/index.ts +234 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +85 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +69 -0
- package/src/commit/map-reduce/map-phase.ts +193 -0
- package/src/commit/map-reduce/reduce-phase.ts +49 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +95 -0
- package/src/commit/pipeline.ts +244 -0
- package/src/commit/prompts/analysis-system.md +148 -0
- package/src/commit/prompts/analysis-user.md +38 -0
- package/src/commit/prompts/changelog-system.md +50 -0
- package/src/commit/prompts/changelog-user.md +18 -0
- package/src/commit/prompts/file-observer-system.md +24 -0
- package/src/commit/prompts/file-observer-user.md +8 -0
- package/src/commit/prompts/reduce-system.md +50 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +3 -0
- package/src/commit/prompts/summary-system.md +38 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/shared-llm.ts +70 -0
- package/src/commit/types.ts +118 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/commit/utils.ts +58 -0
- package/src/config/api-key-resolver.ts +81 -0
- package/src/config/append-only-context-mode.ts +76 -0
- package/src/config/config-file.ts +347 -0
- package/src/config/inline-tool-descriptors-mode.ts +26 -0
- package/src/config/keybindings.ts +703 -0
- package/src/config/mcp-schema.json +252 -0
- package/src/config/model-discovery.ts +1077 -0
- package/src/config/model-registry.ts +2822 -0
- package/src/config/model-resolver.ts +2115 -0
- package/src/config/model-roles.ts +113 -0
- package/src/config/models-config-schema-bundle.ts +315 -0
- package/src/config/models-config-schema.ts +14 -0
- package/src/config/models-config.ts +130 -0
- package/src/config/prompt-templates.ts +205 -0
- package/src/config/provider-globals.ts +25 -0
- package/src/config/resolve-config-value.ts +95 -0
- package/src/config/service-tier.ts +146 -0
- package/src/config/settings-schema.ts +5887 -0
- package/src/config/settings.ts +2394 -0
- package/src/config.ts +242 -0
- package/src/cursor-bridge-tools.ts +81 -0
- package/src/cursor.ts +960 -0
- package/src/dap/client.ts +1043 -0
- package/src/dap/config.ts +480 -0
- package/src/dap/defaults.json +212 -0
- package/src/dap/index.ts +4 -0
- package/src/dap/session.ts +1841 -0
- package/src/dap/types.ts +611 -0
- package/src/debug/index.ts +584 -0
- package/src/debug/log-formatting.ts +58 -0
- package/src/debug/log-viewer.ts +966 -0
- package/src/debug/profiler.ts +168 -0
- package/src/debug/protocol-probe.ts +267 -0
- package/src/debug/raw-sse-buffer.ts +421 -0
- package/src/debug/raw-sse.ts +312 -0
- package/src/debug/remote-debugger.ts +151 -0
- package/src/debug/report-bundle.ts +411 -0
- package/src/debug/system-info.ts +111 -0
- package/src/debug/terminal-info.ts +124 -0
- package/src/discovery/agent-plugin-format.ts +551 -0
- package/src/discovery/agent-plugins.ts +341 -0
- package/src/discovery/agents-md.ts +67 -0
- package/src/discovery/agents.ts +300 -0
- package/src/discovery/at-imports.ts +273 -0
- package/src/discovery/builtin-defaults.ts +39 -0
- package/src/discovery/builtin-rules/go-add-cleanup.md +33 -0
- package/src/discovery/builtin-rules/go-bench-loop.md +36 -0
- package/src/discovery/builtin-rules/go-exp-promoted.md +40 -0
- package/src/discovery/builtin-rules/go-ioutil.md +37 -0
- package/src/discovery/builtin-rules/go-join-hostport.md +30 -0
- package/src/discovery/builtin-rules/go-new-expr.md +44 -0
- package/src/discovery/builtin-rules/go-rand-v2.md +41 -0
- package/src/discovery/builtin-rules/go-range-int.md +45 -0
- package/src/discovery/builtin-rules/index.ts +74 -0
- package/src/discovery/builtin-rules/rs-box-leak.md +49 -0
- package/src/discovery/builtin-rules/rs-future-prelude.md +24 -0
- package/src/discovery/builtin-rules/rs-lazylock.md +52 -0
- package/src/discovery/builtin-rules/rs-match-ergonomics.md +68 -0
- package/src/discovery/builtin-rules/rs-parking-lot.md +45 -0
- package/src/discovery/builtin-rules/rs-result-type.md +20 -0
- package/src/discovery/builtin-rules/ts-bare-catch.md +39 -0
- package/src/discovery/builtin-rules/ts-import-type.md +43 -0
- package/src/discovery/builtin-rules/ts-no-any.md +66 -0
- package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +45 -0
- package/src/discovery/builtin-rules/ts-no-dynamic-import.md +40 -0
- package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +56 -0
- package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
- package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
- package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
- package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +66 -0
- package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
- package/src/discovery/builtin-rules/ts-set-map.md +28 -0
- package/src/discovery/builtin.ts +945 -0
- package/src/discovery/claude-plugins.ts +640 -0
- package/src/discovery/claude.ts +591 -0
- package/src/discovery/cline.ts +83 -0
- package/src/discovery/codex.ts +553 -0
- package/src/discovery/contained-path.ts +78 -0
- package/src/discovery/cursor.ts +223 -0
- package/src/discovery/gemini.ts +386 -0
- package/src/discovery/github.ts +337 -0
- package/src/discovery/helpers.ts +1183 -0
- package/src/discovery/index.ts +82 -0
- package/src/discovery/mcp-json.ts +182 -0
- package/src/discovery/omp-extension-roots.ts +272 -0
- package/src/discovery/omp-plugins.ts +409 -0
- package/src/discovery/opencode.ts +441 -0
- package/src/discovery/plugin-dir-roots.ts +28 -0
- package/src/discovery/ssh.ts +153 -0
- package/src/discovery/substitute-plugin-root.ts +77 -0
- package/src/discovery/vscode.ts +106 -0
- package/src/discovery/windsurf.ts +149 -0
- package/src/edit/apply-patch/index.ts +87 -0
- package/src/edit/apply-patch/parser.ts +174 -0
- package/src/edit/diff.ts +1008 -0
- package/src/edit/edit-clipboard.ts +23 -0
- package/src/edit/file-snapshot-store.ts +148 -0
- package/src/edit/hashline/block-resolver.ts +33 -0
- package/src/edit/hashline/diff.ts +402 -0
- package/src/edit/hashline/execute.ts +313 -0
- package/src/edit/hashline/filesystem.ts +247 -0
- package/src/edit/hashline/index.ts +5 -0
- package/src/edit/hashline/noop-loop-guard.ts +99 -0
- package/src/edit/hashline/params.ts +12 -0
- package/src/edit/index.ts +699 -0
- package/src/edit/modes/apply-patch.lark +19 -0
- package/src/edit/modes/apply-patch.ts +53 -0
- package/src/edit/modes/patch.ts +1958 -0
- package/src/edit/modes/replace.ts +1191 -0
- package/src/edit/normalize.ts +345 -0
- package/src/edit/notebook.ts +242 -0
- package/src/edit/read-file.ts +25 -0
- package/src/edit/renderer.ts +998 -0
- package/src/edit/snapshot-details.ts +77 -0
- package/src/edit/streaming.ts +710 -0
- package/src/eval/agent-bridge.ts +224 -0
- package/src/eval/backend-helpers.ts +48 -0
- package/src/eval/backend.ts +71 -0
- package/src/eval/bridge-timeout.ts +65 -0
- package/src/eval/budget-bridge.ts +48 -0
- package/src/eval/completion-bridge.ts +212 -0
- package/src/eval/concurrency-bridge.ts +34 -0
- package/src/eval/executor-base.ts +562 -0
- package/src/eval/idle-timeout.ts +91 -0
- package/src/eval/index.ts +6 -0
- package/src/eval/jl/executor.ts +551 -0
- package/src/eval/jl/index.ts +54 -0
- package/src/eval/jl/kernel.ts +236 -0
- package/src/eval/jl/prelude.jl +736 -0
- package/src/eval/jl/prelude.ts +3 -0
- package/src/eval/jl/runner.jl +666 -0
- package/src/eval/jl/runtime.ts +118 -0
- package/src/eval/js/context-manager.ts +872 -0
- package/src/eval/js/executor.ts +178 -0
- package/src/eval/js/index.ts +41 -0
- package/src/eval/js/process-entry.ts +31 -0
- package/src/eval/js/shared/helpers.ts +170 -0
- package/src/eval/js/shared/indirect-eval.ts +30 -0
- package/src/eval/js/shared/local-module-loader.ts +364 -0
- package/src/eval/js/shared/prelude.ts +2 -0
- package/src/eval/js/shared/prelude.txt +294 -0
- package/src/eval/js/shared/rewrite-imports.ts +550 -0
- package/src/eval/js/shared/runtime.ts +590 -0
- package/src/eval/js/shared/types.ts +18 -0
- package/src/eval/js/tool-bridge.ts +163 -0
- package/src/eval/js/worker-core.ts +380 -0
- package/src/eval/js/worker-entry.ts +37 -0
- package/src/eval/js/worker-protocol.ts +47 -0
- package/src/eval/kernel-base.ts +569 -0
- package/src/eval/py/display.ts +71 -0
- package/src/eval/py/executor.ts +643 -0
- package/src/eval/py/index.ts +57 -0
- package/src/eval/py/kernel.ts +235 -0
- package/src/eval/py/prelude.py +673 -0
- package/src/eval/py/prelude.ts +3 -0
- package/src/eval/py/runner.py +1425 -0
- package/src/eval/py/runtime.ts +276 -0
- package/src/eval/py/spawn-options.ts +134 -0
- package/src/eval/py/tool-bridge.ts +201 -0
- package/src/eval/rb/executor.ts +511 -0
- package/src/eval/rb/index.ts +54 -0
- package/src/eval/rb/kernel.ts +231 -0
- package/src/eval/rb/prelude.rb +551 -0
- package/src/eval/rb/prelude.ts +3 -0
- package/src/eval/rb/runner.rb +581 -0
- package/src/eval/rb/runtime.ts +132 -0
- package/src/eval/runtime-env.ts +104 -0
- package/src/eval/session-id.ts +8 -0
- package/src/eval/types.ts +48 -0
- package/src/exa/index.ts +2 -0
- package/src/exa/mcp-client.ts +370 -0
- package/src/exa/types.ts +69 -0
- package/src/exec/bash-executor.ts +627 -0
- package/src/exec/direnv.ts +145 -0
- package/src/exec/exec.ts +53 -0
- package/src/exec/non-interactive-env.ts +118 -0
- package/src/export/custom-share.ts +65 -0
- package/src/export/html/args.ts +20 -0
- package/src/export/html/index.ts +320 -0
- package/src/export/html/share-loader.js +102 -0
- package/src/export/html/template.css +1355 -0
- package/src/export/html/template.html +55 -0
- package/src/export/html/template.js +1653 -0
- package/src/export/html/tool-views.generated.js +35 -0
- package/src/export/html/vendor/highlight.min.js +1213 -0
- package/src/export/html/vendor/marked.min.js +6 -0
- package/src/export/html/web-palette.ts +126 -0
- package/src/export/share.ts +686 -0
- package/src/export/ttsr.ts +590 -0
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
- package/src/extensibility/custom-commands/bundled/review/index.ts +698 -0
- package/src/extensibility/custom-commands/index.ts +2 -0
- package/src/extensibility/custom-commands/loader.ts +242 -0
- package/src/extensibility/custom-commands/types.ts +119 -0
- package/src/extensibility/custom-tools/index.ts +7 -0
- package/src/extensibility/custom-tools/loader.ts +301 -0
- package/src/extensibility/custom-tools/types.ts +287 -0
- package/src/extensibility/custom-tools/wrapper.ts +50 -0
- package/src/extensibility/extensions/compact-handler.ts +40 -0
- package/src/extensibility/extensions/get-commands-handler.ts +78 -0
- package/src/extensibility/extensions/index.ts +16 -0
- package/src/extensibility/extensions/load-errors.ts +13 -0
- package/src/extensibility/extensions/loader.ts +663 -0
- package/src/extensibility/extensions/managed-timers.ts +83 -0
- package/src/extensibility/extensions/model-api.ts +39 -0
- package/src/extensibility/extensions/runner.ts +1396 -0
- package/src/extensibility/extensions/types.ts +1603 -0
- package/src/extensibility/extensions/wrapper.ts +395 -0
- package/src/extensibility/hooks/index.ts +6 -0
- package/src/extensibility/hooks/loader.ts +243 -0
- package/src/extensibility/hooks/runner.ts +425 -0
- package/src/extensibility/hooks/tool-wrapper.ts +124 -0
- package/src/extensibility/hooks/types.ts +612 -0
- package/src/extensibility/legacy-pi-ai-shim.ts +161 -0
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +1460 -0
- package/src/extensibility/legacy-pi-tui-shim.ts +43 -0
- package/src/extensibility/legacy-typebox.ts +101 -0
- package/src/extensibility/plugins/bun-git-cache.ts +91 -0
- package/src/extensibility/plugins/doctor.ts +65 -0
- package/src/extensibility/plugins/git-url.ts +367 -0
- package/src/extensibility/plugins/index.ts +9 -0
- package/src/extensibility/plugins/installer.ts +201 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +2643 -0
- package/src/extensibility/plugins/legacy-pi-virtual-modules.d.ts +4 -0
- package/src/extensibility/plugins/loader.ts +535 -0
- package/src/extensibility/plugins/manager.ts +1142 -0
- package/src/extensibility/plugins/marketplace/cache.ts +136 -0
- package/src/extensibility/plugins/marketplace/fetcher.ts +316 -0
- package/src/extensibility/plugins/marketplace/index.ts +6 -0
- package/src/extensibility/plugins/marketplace/manager.ts +927 -0
- package/src/extensibility/plugins/marketplace/registry.ts +192 -0
- package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
- package/src/extensibility/plugins/marketplace/types.ts +192 -0
- package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
- package/src/extensibility/plugins/parser.ts +107 -0
- package/src/extensibility/plugins/runtime-config.ts +9 -0
- package/src/extensibility/plugins/types.ts +194 -0
- package/src/extensibility/session-handler-types.ts +21 -0
- package/src/extensibility/shared-events.ts +401 -0
- package/src/extensibility/skills.ts +531 -0
- package/src/extensibility/slash-commands.ts +131 -0
- package/src/extensibility/tool-event-input.ts +80 -0
- package/src/extensibility/tool-proxy.ts +28 -0
- package/src/extensibility/utils.ts +192 -0
- package/src/goals/index.ts +3 -0
- package/src/goals/runtime.ts +521 -0
- package/src/goals/state.ts +37 -0
- package/src/goals/tools/goal-tool.ts +251 -0
- package/src/hindsight/backend.ts +354 -0
- package/src/hindsight/bank.ts +156 -0
- package/src/hindsight/client.ts +680 -0
- package/src/hindsight/config.ts +193 -0
- package/src/hindsight/content.ts +266 -0
- package/src/hindsight/index.ts +8 -0
- package/src/hindsight/mental-models.ts +429 -0
- package/src/hindsight/seeds.json +32 -0
- package/src/hindsight/state.ts +530 -0
- package/src/hindsight/transcript.ts +71 -0
- package/src/index.ts +66 -0
- package/src/internal-urls/agent-protocol.ts +180 -0
- package/src/internal-urls/artifact-protocol.ts +151 -0
- package/src/internal-urls/docs-index.ts +102 -0
- package/src/internal-urls/filesystem-resource.ts +34 -0
- package/src/internal-urls/history-protocol.ts +198 -0
- package/src/internal-urls/index.ts +28 -0
- package/src/internal-urls/issue-pr-protocol.ts +594 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/local-protocol.ts +471 -0
- package/src/internal-urls/mcp-protocol.ts +168 -0
- package/src/internal-urls/memory-protocol.ts +380 -0
- package/src/internal-urls/omp-protocol.ts +94 -0
- package/src/internal-urls/parse.ts +103 -0
- package/src/internal-urls/registry-helpers.ts +132 -0
- package/src/internal-urls/router.ts +153 -0
- package/src/internal-urls/rule-protocol.ts +45 -0
- package/src/internal-urls/security-protocol.ts +261 -0
- package/src/internal-urls/skill-protocol.ts +131 -0
- package/src/internal-urls/ssh-protocol.ts +368 -0
- package/src/internal-urls/types.ts +196 -0
- package/src/internal-urls/vault-protocol.ts +940 -0
- package/src/internal-urls/xd-protocol.ts +46 -0
- package/src/irc/bus.ts +380 -0
- package/src/jsonrpc/message-framing.ts +142 -0
- package/src/launch/broker.ts +1368 -0
- package/src/launch/client.ts +521 -0
- package/src/launch/ensure.ts +73 -0
- package/src/launch/paths.ts +14 -0
- package/src/launch/presence.ts +82 -0
- package/src/launch/protocol.ts +448 -0
- package/src/launch/spawn-options.ts +17 -0
- package/src/launch/terminal-output-worker-client.ts +53 -0
- package/src/launch/terminal-output-worker-protocol.ts +11 -0
- package/src/launch/terminal-output-worker.ts +23 -0
- package/src/launch/terminal-output.ts +46 -0
- package/src/lib/xai-http.ts +150 -0
- package/src/live/attestation.ts +91 -0
- package/src/live/controller.ts +517 -0
- package/src/live/prompts/agent-final-message.md +3 -0
- package/src/live/prompts/live-instructions.md +23 -0
- package/src/live/protocol.ts +233 -0
- package/src/live/transport.ts +422 -0
- package/src/live/visualizer.ts +221 -0
- package/src/live/voices.ts +18 -0
- package/src/lsp/client.ts +1465 -0
- package/src/lsp/clients/biome-client.ts +263 -0
- package/src/lsp/clients/index.ts +50 -0
- package/src/lsp/clients/lsp-linter-client.ts +85 -0
- package/src/lsp/clients/swiftlint-client.ts +120 -0
- package/src/lsp/config.ts +549 -0
- package/src/lsp/defaults.json +499 -0
- package/src/lsp/deferred-diagnostics.ts +66 -0
- package/src/lsp/diagnostics-ledger.ts +51 -0
- package/src/lsp/edits.ts +288 -0
- package/src/lsp/format-options.ts +119 -0
- package/src/lsp/index.ts +2821 -0
- package/src/lsp/lspmux.ts +233 -0
- package/src/lsp/mux/daemon.ts +348 -0
- package/src/lsp/mux/protocol.ts +96 -0
- package/src/lsp/mux/server.ts +797 -0
- package/src/lsp/render.ts +668 -0
- package/src/lsp/startup-events.ts +13 -0
- package/src/lsp/types.ts +479 -0
- package/src/lsp/utils.ts +747 -0
- package/src/main.ts +1799 -0
- package/src/markit/NOTICE +32 -0
- package/src/markit/converters/docx.ts +56 -0
- package/src/markit/converters/epub.ts +136 -0
- package/src/markit/converters/pdf/columns.ts +103 -0
- package/src/markit/converters/pdf/extract.ts +598 -0
- package/src/markit/converters/pdf/grid.ts +780 -0
- package/src/markit/converters/pdf/headers.ts +106 -0
- package/src/markit/converters/pdf/index.ts +146 -0
- package/src/markit/converters/pdf/render.ts +501 -0
- package/src/markit/converters/pdf/types.ts +84 -0
- package/src/markit/converters/pptx.ts +325 -0
- package/src/markit/converters/xlsx.ts +173 -0
- package/src/markit/index.ts +2 -0
- package/src/markit/registry.ts +59 -0
- package/src/markit/types.ts +35 -0
- package/src/mcp/client.ts +511 -0
- package/src/mcp/config-writer.ts +377 -0
- package/src/mcp/config.ts +385 -0
- package/src/mcp/index.ts +29 -0
- package/src/mcp/json-rpc.ts +122 -0
- package/src/mcp/loader.ts +125 -0
- package/src/mcp/manager.ts +1524 -0
- package/src/mcp/oauth-credentials.ts +104 -0
- package/src/mcp/oauth-discovery.ts +587 -0
- package/src/mcp/oauth-flow.ts +830 -0
- package/src/mcp/render.ts +214 -0
- package/src/mcp/request-id.ts +24 -0
- package/src/mcp/smithery-auth.ts +108 -0
- package/src/mcp/smithery-connect.ts +154 -0
- package/src/mcp/smithery-registry.ts +500 -0
- package/src/mcp/startup-events.ts +116 -0
- package/src/mcp/timeout.ts +59 -0
- package/src/mcp/tool-bridge.ts +691 -0
- package/src/mcp/tool-cache.ts +117 -0
- package/src/mcp/transports/header-policy.ts +95 -0
- package/src/mcp/transports/http.ts +508 -0
- package/src/mcp/transports/index.ts +7 -0
- package/src/mcp/transports/sse.ts +372 -0
- package/src/mcp/transports/stdio.ts +905 -0
- package/src/mcp/types.ts +467 -0
- package/src/memories/index.ts +1434 -0
- package/src/memories/storage.ts +578 -0
- package/src/memory-backend/index.ts +19 -0
- package/src/memory-backend/local-backend.ts +47 -0
- package/src/memory-backend/messages.ts +19 -0
- package/src/memory-backend/off-backend.ts +25 -0
- package/src/memory-backend/resolve.ts +25 -0
- package/src/memory-backend/runtime.ts +66 -0
- package/src/memory-backend/tool-names.ts +2 -0
- package/src/memory-backend/types.ts +166 -0
- package/src/mnemopi/backend.ts +629 -0
- package/src/mnemopi/config.ts +267 -0
- package/src/mnemopi/embed-client.ts +293 -0
- package/src/mnemopi/embed-protocol.ts +35 -0
- package/src/mnemopi/embed-worker.ts +114 -0
- package/src/mnemopi/index.ts +3 -0
- package/src/mnemopi/state.ts +940 -0
- package/src/modes/acp/acp-agent.ts +2595 -0
- package/src/modes/acp/acp-client-bridge.ts +154 -0
- package/src/modes/acp/acp-event-mapper.ts +1084 -0
- package/src/modes/acp/acp-mode.ts +48 -0
- package/src/modes/acp/index.ts +2 -0
- package/src/modes/acp/terminal-auth.ts +37 -0
- package/src/modes/components/advisor-config.ts +635 -0
- package/src/modes/components/advisor-message.ts +109 -0
- package/src/modes/components/agent-dashboard.ts +1252 -0
- package/src/modes/components/agent-hub-projection.ts +248 -0
- package/src/modes/components/agent-hub-renderer.ts +194 -0
- package/src/modes/components/agent-hub.ts +1126 -0
- package/src/modes/components/agent-transcript-viewer.ts +647 -0
- package/src/modes/components/ask-dialog.ts +1017 -0
- package/src/modes/components/assistant-message.ts +978 -0
- package/src/modes/components/background-tan-message.ts +36 -0
- package/src/modes/components/bash-execution.ts +233 -0
- package/src/modes/components/bordered-loader.ts +41 -0
- package/src/modes/components/btw-panel.ts +161 -0
- package/src/modes/components/cache-invalidation-marker.ts +110 -0
- package/src/modes/components/chat-block.ts +111 -0
- package/src/modes/components/chat-transcript-builder.ts +518 -0
- package/src/modes/components/codex-reset-fireworks.ts +369 -0
- package/src/modes/components/collab-prompt-message.ts +32 -0
- package/src/modes/components/compaction-summary-message.ts +221 -0
- package/src/modes/components/copy-selector.ts +218 -0
- package/src/modes/components/countdown-timer.ts +75 -0
- package/src/modes/components/custom-editor.ts +1036 -0
- package/src/modes/components/custom-message.ts +70 -0
- package/src/modes/components/diff.ts +254 -0
- package/src/modes/components/dynamic-border.ts +37 -0
- package/src/modes/components/error-banner.ts +33 -0
- package/src/modes/components/eval-execution.ts +169 -0
- package/src/modes/components/execution-shared.ts +101 -0
- package/src/modes/components/extensions/extension-dashboard.ts +492 -0
- package/src/modes/components/extensions/extension-list.ts +507 -0
- package/src/modes/components/extensions/index.ts +9 -0
- package/src/modes/components/extensions/inspector-panel.ts +326 -0
- package/src/modes/components/extensions/state-manager.ts +648 -0
- package/src/modes/components/extensions/types.ts +186 -0
- package/src/modes/components/footer.ts +274 -0
- package/src/modes/components/history-search.ts +268 -0
- package/src/modes/components/hook-editor.ts +213 -0
- package/src/modes/components/hook-input.ts +87 -0
- package/src/modes/components/hook-message.ts +67 -0
- package/src/modes/components/hook-selector.ts +691 -0
- package/src/modes/components/index.ts +42 -0
- package/src/modes/components/keybinding-hints.ts +56 -0
- package/src/modes/components/late-diagnostics-message.ts +60 -0
- package/src/modes/components/login-dialog.ts +197 -0
- package/src/modes/components/logout-account-selector.ts +130 -0
- package/src/modes/components/mcp-add-wizard.ts +1413 -0
- package/src/modes/components/message-frame.ts +98 -0
- package/src/modes/components/model-browser.ts +888 -0
- package/src/modes/components/model-hub.ts +2014 -0
- package/src/modes/components/model-picker.ts +237 -0
- package/src/modes/components/move-overlay.ts +293 -0
- package/src/modes/components/oauth-selector.ts +474 -0
- package/src/modes/components/omfg-panel.ts +141 -0
- package/src/modes/components/overlay-box.ts +109 -0
- package/src/modes/components/pause-screen.ts +208 -0
- package/src/modes/components/plan-review-overlay.ts +1226 -0
- package/src/modes/components/plan-toc.ts +138 -0
- package/src/modes/components/plugin-selector.ts +100 -0
- package/src/modes/components/plugin-settings.ts +745 -0
- package/src/modes/components/queue-mode-selector.ts +61 -0
- package/src/modes/components/read-tool-group.ts +856 -0
- package/src/modes/components/reset-usage-selector.ts +161 -0
- package/src/modes/components/segment-track.ts +89 -0
- package/src/modes/components/select-list-mouse-routing.ts +35 -0
- package/src/modes/components/selector-helpers.ts +129 -0
- package/src/modes/components/session-account-selector.ts +62 -0
- package/src/modes/components/session-selector.ts +1035 -0
- package/src/modes/components/settings-defs.ts +267 -0
- package/src/modes/components/settings-selector.ts +1445 -0
- package/src/modes/components/show-images-selector.ts +50 -0
- package/src/modes/components/skill-message.ts +110 -0
- package/src/modes/components/snapcompact-shape-preview-doc.md +14 -0
- package/src/modes/components/snapcompact-shape-preview.ts +192 -0
- package/src/modes/components/status-line/component.ts +1843 -0
- package/src/modes/components/status-line/context-thresholds.ts +86 -0
- package/src/modes/components/status-line/git-utils.ts +42 -0
- package/src/modes/components/status-line/index.ts +5 -0
- package/src/modes/components/status-line/presets.ts +106 -0
- package/src/modes/components/status-line/segments.ts +710 -0
- package/src/modes/components/status-line/separators.ts +55 -0
- package/src/modes/components/status-line/types.ts +159 -0
- package/src/modes/components/stripped-tool-calls-placeholder.ts +35 -0
- package/src/modes/components/theme-selector.ts +68 -0
- package/src/modes/components/thinking-selector.ts +57 -0
- package/src/modes/components/tiny-title-download-progress.ts +90 -0
- package/src/modes/components/tips.txt +26 -0
- package/src/modes/components/todo-reminder.ts +43 -0
- package/src/modes/components/tool-execution.ts +1467 -0
- package/src/modes/components/transcript-container.ts +527 -0
- package/src/modes/components/tree-selector.ts +1006 -0
- package/src/modes/components/ttsr-notification.ts +123 -0
- package/src/modes/components/usage-row.ts +52 -0
- package/src/modes/components/user-message-selector.ts +227 -0
- package/src/modes/components/user-message.ts +167 -0
- package/src/modes/components/visual-truncate.ts +63 -0
- package/src/modes/components/welcome.ts +578 -0
- package/src/modes/controllers/btw-controller.ts +246 -0
- package/src/modes/controllers/command-controller-shared.ts +109 -0
- package/src/modes/controllers/command-controller.ts +2024 -0
- package/src/modes/controllers/event-controller.ts +2173 -0
- package/src/modes/controllers/extension-ui-controller.ts +1243 -0
- package/src/modes/controllers/input-controller.ts +2037 -0
- package/src/modes/controllers/live-command-controller.ts +261 -0
- package/src/modes/controllers/mcp-command-controller.ts +2552 -0
- package/src/modes/controllers/omfg-controller.ts +287 -0
- package/src/modes/controllers/omfg-rule.ts +647 -0
- package/src/modes/controllers/selector-controller.ts +2058 -0
- package/src/modes/controllers/session-focus-controller.ts +117 -0
- package/src/modes/controllers/ssh-command-controller.ts +385 -0
- package/src/modes/controllers/streaming-reveal.ts +399 -0
- package/src/modes/controllers/tan-command-controller.ts +243 -0
- package/src/modes/controllers/todo-command-controller.ts +487 -0
- package/src/modes/controllers/tool-args-reveal.ts +591 -0
- package/src/modes/data/emojis.json +1 -0
- package/src/modes/emoji-autocomplete.ts +285 -0
- package/src/modes/github-ref-autocomplete.ts +75 -0
- package/src/modes/gradient-highlight.ts +99 -0
- package/src/modes/image-references.ts +137 -0
- package/src/modes/index.ts +10 -0
- package/src/modes/interactive-mode.ts +5055 -0
- package/src/modes/internal-url-autocomplete.ts +158 -0
- package/src/modes/loop-limit.ts +192 -0
- package/src/modes/magic-keyword-boundary.ts +23 -0
- package/src/modes/magic-keywords.ts +42 -0
- package/src/modes/markdown-prose.ts +247 -0
- package/src/modes/oauth-manual-input.ts +69 -0
- package/src/modes/orchestrate.ts +43 -0
- package/src/modes/print-mode.ts +282 -0
- package/src/modes/prompt-action-autocomplete.ts +322 -0
- package/src/modes/queue-input.ts +132 -0
- package/src/modes/rpc/host-tools.ts +204 -0
- package/src/modes/rpc/host-uris.ts +241 -0
- package/src/modes/rpc/rpc-client.ts +1213 -0
- package/src/modes/rpc/rpc-frame.ts +316 -0
- package/src/modes/rpc/rpc-input.ts +38 -0
- package/src/modes/rpc/rpc-messages.ts +127 -0
- package/src/modes/rpc/rpc-mode.ts +1519 -0
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +544 -0
- package/src/modes/running-subagent-badge.ts +13 -0
- package/src/modes/runtime-init.ts +144 -0
- package/src/modes/session-observer-registry.ts +223 -0
- package/src/modes/session-teardown.ts +82 -0
- package/src/modes/setup-version.ts +11 -0
- package/src/modes/setup-wizard/index.ts +103 -0
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +103 -0
- package/src/modes/setup-wizard/scenes/model.ts +132 -0
- package/src/modes/setup-wizard/scenes/outro.ts +35 -0
- package/src/modes/setup-wizard/scenes/providers.ts +105 -0
- package/src/modes/setup-wizard/scenes/sign-in.ts +312 -0
- package/src/modes/setup-wizard/scenes/splash.ts +201 -0
- package/src/modes/setup-wizard/scenes/theme.ts +330 -0
- package/src/modes/setup-wizard/scenes/types.ts +65 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +153 -0
- package/src/modes/setup-wizard/startup-splash.ts +107 -0
- package/src/modes/setup-wizard/wizard-overlay.ts +335 -0
- package/src/modes/shared.ts +49 -0
- package/src/modes/skill-command.ts +91 -0
- package/src/modes/theme/dark.json +95 -0
- package/src/modes/theme/defaults/alabaster.json +93 -0
- package/src/modes/theme/defaults/amethyst.json +96 -0
- package/src/modes/theme/defaults/anthracite.json +93 -0
- package/src/modes/theme/defaults/basalt.json +91 -0
- package/src/modes/theme/defaults/birch.json +95 -0
- package/src/modes/theme/defaults/dark-abyss.json +91 -0
- package/src/modes/theme/defaults/dark-arctic.json +104 -0
- package/src/modes/theme/defaults/dark-aurora.json +95 -0
- package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
- package/src/modes/theme/defaults/dark-cavern.json +91 -0
- package/src/modes/theme/defaults/dark-copper.json +95 -0
- package/src/modes/theme/defaults/dark-cosmos.json +90 -0
- package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
- package/src/modes/theme/defaults/dark-dracula.json +98 -0
- package/src/modes/theme/defaults/dark-eclipse.json +91 -0
- package/src/modes/theme/defaults/dark-ember.json +95 -0
- package/src/modes/theme/defaults/dark-equinox.json +90 -0
- package/src/modes/theme/defaults/dark-forest.json +96 -0
- package/src/modes/theme/defaults/dark-github.json +105 -0
- package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
- package/src/modes/theme/defaults/dark-lavender.json +95 -0
- package/src/modes/theme/defaults/dark-lunar.json +89 -0
- package/src/modes/theme/defaults/dark-midnight.json +95 -0
- package/src/modes/theme/defaults/dark-monochrome.json +94 -0
- package/src/modes/theme/defaults/dark-monokai.json +98 -0
- package/src/modes/theme/defaults/dark-nebula.json +90 -0
- package/src/modes/theme/defaults/dark-nord.json +97 -0
- package/src/modes/theme/defaults/dark-ocean.json +101 -0
- package/src/modes/theme/defaults/dark-one.json +100 -0
- package/src/modes/theme/defaults/dark-poimandres.json +143 -0
- package/src/modes/theme/defaults/dark-rainforest.json +91 -0
- package/src/modes/theme/defaults/dark-reef.json +91 -0
- package/src/modes/theme/defaults/dark-retro.json +92 -0
- package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
- package/src/modes/theme/defaults/dark-sakura.json +95 -0
- package/src/modes/theme/defaults/dark-slate.json +95 -0
- package/src/modes/theme/defaults/dark-solarized.json +97 -0
- package/src/modes/theme/defaults/dark-solstice.json +90 -0
- package/src/modes/theme/defaults/dark-starfall.json +91 -0
- package/src/modes/theme/defaults/dark-sunset.json +99 -0
- package/src/modes/theme/defaults/dark-swamp.json +90 -0
- package/src/modes/theme/defaults/dark-synthwave.json +103 -0
- package/src/modes/theme/defaults/dark-taiga.json +91 -0
- package/src/modes/theme/defaults/dark-terminal.json +95 -0
- package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
- package/src/modes/theme/defaults/dark-tundra.json +91 -0
- package/src/modes/theme/defaults/dark-twilight.json +91 -0
- package/src/modes/theme/defaults/dark-volcanic.json +91 -0
- package/src/modes/theme/defaults/graphite.json +92 -0
- package/src/modes/theme/defaults/index.ts +199 -0
- package/src/modes/theme/defaults/light-arctic.json +107 -0
- package/src/modes/theme/defaults/light-aurora-day.json +91 -0
- package/src/modes/theme/defaults/light-canyon.json +91 -0
- package/src/modes/theme/defaults/light-catppuccin.json +106 -0
- package/src/modes/theme/defaults/light-cirrus.json +90 -0
- package/src/modes/theme/defaults/light-coral.json +95 -0
- package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
- package/src/modes/theme/defaults/light-dawn.json +90 -0
- package/src/modes/theme/defaults/light-dunes.json +91 -0
- package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
- package/src/modes/theme/defaults/light-forest.json +100 -0
- package/src/modes/theme/defaults/light-frost.json +95 -0
- package/src/modes/theme/defaults/light-github.json +115 -0
- package/src/modes/theme/defaults/light-glacier.json +91 -0
- package/src/modes/theme/defaults/light-gruvbox.json +108 -0
- package/src/modes/theme/defaults/light-haze.json +90 -0
- package/src/modes/theme/defaults/light-honeycomb.json +95 -0
- package/src/modes/theme/defaults/light-lagoon.json +91 -0
- package/src/modes/theme/defaults/light-lavender.json +95 -0
- package/src/modes/theme/defaults/light-meadow.json +91 -0
- package/src/modes/theme/defaults/light-mint.json +95 -0
- package/src/modes/theme/defaults/light-monochrome.json +101 -0
- package/src/modes/theme/defaults/light-ocean.json +99 -0
- package/src/modes/theme/defaults/light-one.json +99 -0
- package/src/modes/theme/defaults/light-opal.json +91 -0
- package/src/modes/theme/defaults/light-orchard.json +91 -0
- package/src/modes/theme/defaults/light-paper.json +95 -0
- package/src/modes/theme/defaults/light-poimandres.json +143 -0
- package/src/modes/theme/defaults/light-prism.json +90 -0
- package/src/modes/theme/defaults/light-retro.json +98 -0
- package/src/modes/theme/defaults/light-sand.json +95 -0
- package/src/modes/theme/defaults/light-savanna.json +91 -0
- package/src/modes/theme/defaults/light-solarized.json +102 -0
- package/src/modes/theme/defaults/light-soleil.json +90 -0
- package/src/modes/theme/defaults/light-sunset.json +99 -0
- package/src/modes/theme/defaults/light-synthwave.json +98 -0
- package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
- package/src/modes/theme/defaults/light-wetland.json +91 -0
- package/src/modes/theme/defaults/light-zenith.json +89 -0
- package/src/modes/theme/defaults/limestone.json +94 -0
- package/src/modes/theme/defaults/mahogany.json +97 -0
- package/src/modes/theme/defaults/marble.json +93 -0
- package/src/modes/theme/defaults/obsidian.json +91 -0
- package/src/modes/theme/defaults/onyx.json +91 -0
- package/src/modes/theme/defaults/pearl.json +93 -0
- package/src/modes/theme/defaults/porcelain.json +91 -0
- package/src/modes/theme/defaults/quartz.json +96 -0
- package/src/modes/theme/defaults/sandstone.json +95 -0
- package/src/modes/theme/defaults/titanium.json +90 -0
- package/src/modes/theme/light.json +93 -0
- package/src/modes/theme/mermaid-cache.ts +92 -0
- package/src/modes/theme/shimmer.ts +305 -0
- package/src/modes/theme/theme-schema.json +463 -0
- package/src/modes/theme/theme.ts +3171 -0
- package/src/modes/turn-budget.ts +31 -0
- package/src/modes/types.ts +494 -0
- package/src/modes/ultrathink.ts +42 -0
- package/src/modes/utils/context-usage.ts +518 -0
- package/src/modes/utils/copy-targets.ts +378 -0
- package/src/modes/utils/hotkeys-markdown.ts +65 -0
- package/src/modes/utils/interactive-context-helpers.ts +31 -0
- package/src/modes/utils/keybinding-matchers.ts +86 -0
- package/src/modes/utils/tools-markdown.ts +31 -0
- package/src/modes/utils/transcript-render-helpers.ts +253 -0
- package/src/modes/utils/ui-helpers.ts +976 -0
- package/src/modes/warp-events.ts +232 -0
- package/src/modes/workflow.ts +55 -0
- package/src/plan-mode/approved-plan.ts +194 -0
- package/src/plan-mode/model-transition.ts +51 -0
- package/src/plan-mode/plan-files.ts +40 -0
- package/src/plan-mode/plan-handoff.ts +37 -0
- package/src/plan-mode/plan-protection.ts +31 -0
- package/src/plan-mode/state.ts +6 -0
- package/src/priority.json +60 -0
- package/src/prompts/advisor/active-repo-watchdog.md +6 -0
- package/src/prompts/advisor/advise-tool.md +3 -0
- package/src/prompts/advisor/context-files.md +8 -0
- package/src/prompts/advisor/system.md +98 -0
- package/src/prompts/agents/designer.md +74 -0
- package/src/prompts/agents/frontmatter.md +12 -0
- package/src/prompts/agents/init.md +33 -0
- package/src/prompts/agents/librarian.md +119 -0
- package/src/prompts/agents/reviewer.md +139 -0
- package/src/prompts/agents/scout.md +58 -0
- package/src/prompts/agents/security-reviewer.md +75 -0
- package/src/prompts/agents/task.md +17 -0
- package/src/prompts/bench/cache-prefix-chunk.md +1 -0
- package/src/prompts/bench/cache-prefix.md +3 -0
- package/src/prompts/bench/cache-suffix.md +1 -0
- package/src/prompts/bench.md +6 -0
- package/src/prompts/ci-green-request.md +36 -0
- package/src/prompts/dry-balance-bench.md +8 -0
- package/src/prompts/goals/goal-budget-limit.md +16 -0
- package/src/prompts/goals/goal-continuation.md +28 -0
- package/src/prompts/goals/goal-mode-active.md +23 -0
- package/src/prompts/goals/goal-mode-context.md +4 -0
- package/src/prompts/goals/goal-todo-context.md +12 -0
- package/src/prompts/goals/guided-goal-interview.md +43 -0
- package/src/prompts/memories/consolidation.md +30 -0
- package/src/prompts/memories/consolidation_system.md +4 -0
- package/src/prompts/memories/read-path.md +17 -0
- package/src/prompts/memories/stage_one_input.md +6 -0
- package/src/prompts/memories/stage_one_system.md +21 -0
- package/src/prompts/review-custom-request.md +21 -0
- package/src/prompts/review-headless-request.md +16 -0
- package/src/prompts/review-request.md +68 -0
- package/src/prompts/security/scan-coordinator.md +7 -0
- package/src/prompts/security/scan-request.md +21 -0
- package/src/prompts/security/validate-request.md +8 -0
- package/src/prompts/session/launch-completion.md +1 -0
- package/src/prompts/skills/autoload.md +8 -0
- package/src/prompts/skills/user-invocation.md +11 -0
- package/src/prompts/steering/parent-irc.md +5 -0
- package/src/prompts/steering/user-interjection.md +6 -0
- package/src/prompts/system/active-repo-context.md +4 -0
- package/src/prompts/system/agent-creation-architect.md +50 -0
- package/src/prompts/system/agent-creation-user.md +6 -0
- package/src/prompts/system/auto-continue.md +1 -0
- package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
- package/src/prompts/system/auto-thinking-difficulty.md +14 -0
- package/src/prompts/system/autolearn-guidance-learn.md +1 -0
- package/src/prompts/system/autolearn-guidance.md +7 -0
- package/src/prompts/system/autolearn-nudge-autocontinue.md +5 -0
- package/src/prompts/system/background-tan-dispatch.md +8 -0
- package/src/prompts/system/btw-user.md +8 -0
- package/src/prompts/system/commit-message-system.md +14 -0
- package/src/prompts/system/computer-safety.md +14 -0
- package/src/prompts/system/custom-system-prompt.md +64 -0
- package/src/prompts/system/eager-task.md +7 -0
- package/src/prompts/system/eager-todo.md +18 -0
- package/src/prompts/system/empty-stop-retry.md +4 -0
- package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
- package/src/prompts/system/interrupted-thinking.md +7 -0
- package/src/prompts/system/irc-autoreply.md +6 -0
- package/src/prompts/system/irc-incoming.md +9 -0
- package/src/prompts/system/manual-continue.md +7 -0
- package/src/prompts/system/mcp-xdev-guidance.md +11 -0
- package/src/prompts/system/memory-consolidation-system.md +8 -0
- package/src/prompts/system/memory-extraction-system.md +26 -0
- package/src/prompts/system/mid-run-todo-nudge.md +3 -0
- package/src/prompts/system/omfg-user.md +50 -0
- package/src/prompts/system/orchestrate-notice.md +40 -0
- package/src/prompts/system/personalities/default.md +18 -0
- package/src/prompts/system/personalities/friendly.md +17 -0
- package/src/prompts/system/personalities/pragmatic.md +15 -0
- package/src/prompts/system/plan-mode-active.md +125 -0
- package/src/prompts/system/plan-mode-approved.md +22 -0
- package/src/prompts/system/plan-mode-compact-instructions.md +17 -0
- package/src/prompts/system/plan-mode-reference.md +10 -0
- package/src/prompts/system/plan-mode-subagent.md +33 -0
- package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
- package/src/prompts/system/plan-yolo-handoff.md +5 -0
- package/src/prompts/system/prewalk-checklist.md +7 -0
- package/src/prompts/system/prewalk-continue.md +1 -0
- package/src/prompts/system/prewalk-plan.md +13 -0
- package/src/prompts/system/project-prompt.md +61 -0
- package/src/prompts/system/recap-user.md +9 -0
- package/src/prompts/system/resolve-device-reminder.md +3 -0
- package/src/prompts/system/rewind-report.md +6 -0
- package/src/prompts/system/side-channel-no-tools.md +3 -0
- package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-context-stub.md +1 -0
- package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-system-stub.md +1 -0
- package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
- package/src/prompts/system/speech-rewrite.md +15 -0
- package/src/prompts/system/subagent-async-pending.md +6 -0
- package/src/prompts/system/subagent-system-prompt.md +73 -0
- package/src/prompts/system/subagent-user-prompt.md +3 -0
- package/src/prompts/system/subagent-yield-reminder.md +23 -0
- package/src/prompts/system/system-prompt.md +263 -0
- package/src/prompts/system/tan-context-switch.md +17 -0
- package/src/prompts/system/task-label.md +23 -0
- package/src/prompts/system/thinking-loop-redirect.md +10 -0
- package/src/prompts/system/title-marker-instruction.md +1 -0
- package/src/prompts/system/title-system.md +16 -0
- package/src/prompts/system/tool-call-loop-redirect.md +8 -0
- package/src/prompts/system/ttsr-interrupt.md +7 -0
- package/src/prompts/system/ttsr-tool-reminder.md +5 -0
- package/src/prompts/system/ultrathink-notice.md +3 -0
- package/src/prompts/system/unexpected-stop-classifier.md +17 -0
- package/src/prompts/system/unexpected-stop-retry.md +4 -0
- package/src/prompts/system/vibe-mode-active.md +26 -0
- package/src/prompts/system/web-search.md +25 -0
- package/src/prompts/system/workflow-notice.md +112 -0
- package/src/prompts/system/xdev-mount-notice.md +20 -0
- package/src/prompts/tools/apply-patch.md +65 -0
- package/src/prompts/tools/ask.md +22 -0
- package/src/prompts/tools/ast-edit.md +11 -0
- package/src/prompts/tools/ast-grep.md +19 -0
- package/src/prompts/tools/async-result.md +8 -0
- package/src/prompts/tools/bash.md +23 -0
- package/src/prompts/tools/browser.md +29 -0
- package/src/prompts/tools/checkpoint.md +15 -0
- package/src/prompts/tools/computer.md +26 -0
- package/src/prompts/tools/debug.md +3 -0
- package/src/prompts/tools/eval.md +45 -0
- package/src/prompts/tools/github.md +22 -0
- package/src/prompts/tools/glob.md +16 -0
- package/src/prompts/tools/goal.md +11 -0
- package/src/prompts/tools/grep.md +13 -0
- package/src/prompts/tools/hub.md +34 -0
- package/src/prompts/tools/image-attachment-describe-system.md +8 -0
- package/src/prompts/tools/image-attachment-describe.md +10 -0
- package/src/prompts/tools/image-gen.md +7 -0
- package/src/prompts/tools/inspect-image-system.md +20 -0
- package/src/prompts/tools/inspect-image.md +22 -0
- package/src/prompts/tools/learn.md +7 -0
- package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
- package/src/prompts/tools/lsp.md +19 -0
- package/src/prompts/tools/manage-skill.md +9 -0
- package/src/prompts/tools/memory-edit.md +12 -0
- package/src/prompts/tools/patch.md +57 -0
- package/src/prompts/tools/read.md +27 -0
- package/src/prompts/tools/recall.md +7 -0
- package/src/prompts/tools/reflect.md +5 -0
- package/src/prompts/tools/replace.md +30 -0
- package/src/prompts/tools/retain.md +6 -0
- package/src/prompts/tools/rewind.md +14 -0
- package/src/prompts/tools/security-publish.md +1 -0
- package/src/prompts/tools/security-scan.md +1 -0
- package/src/prompts/tools/task-async-contract.md +1 -0
- package/src/prompts/tools/task-summary.md +20 -0
- package/src/prompts/tools/task.md +83 -0
- package/src/prompts/tools/todo.md +42 -0
- package/src/prompts/tools/vibe-kill.md +3 -0
- package/src/prompts/tools/vibe-list.md +3 -0
- package/src/prompts/tools/vibe-send.md +9 -0
- package/src/prompts/tools/vibe-spawn.md +10 -0
- package/src/prompts/tools/vibe-turn-result.md +19 -0
- package/src/prompts/tools/vibe-wait.md +8 -0
- package/src/prompts/tools/web-search.md +8 -0
- package/src/prompts/tools/write.md +14 -0
- package/src/registry/agent-lifecycle.ts +505 -0
- package/src/registry/agent-registry.ts +287 -0
- package/src/registry/persisted-agents.ts +423 -0
- package/src/sdk.ts +3820 -0
- package/src/secrets/index.ts +375 -0
- package/src/secrets/obfuscator.ts +2629 -0
- package/src/secrets/regex.ts +21 -0
- package/src/security/auth.ts +98 -0
- package/src/security/cloud.ts +686 -0
- package/src/security/comparison.ts +255 -0
- package/src/security/contracts/ids.ts +111 -0
- package/src/security/contracts/index.ts +4 -0
- package/src/security/contracts/schemas.ts +219 -0
- package/src/security/contracts/types.ts +254 -0
- package/src/security/contracts/validation.ts +69 -0
- package/src/security/coordinator.ts +708 -0
- package/src/security/importers/codex-security.ts +387 -0
- package/src/security/importers/index.ts +2 -0
- package/src/security/importers/sarif.ts +357 -0
- package/src/security/index.ts +13 -0
- package/src/security/preflight.ts +405 -0
- package/src/security/provenance.ts +106 -0
- package/src/security/publication.ts +326 -0
- package/src/security/remediation.ts +93 -0
- package/src/security/resource-output.ts +50 -0
- package/src/security/sarif.ts +78 -0
- package/src/security/store.ts +430 -0
- package/src/session/acp-permission-gate.ts +165 -0
- package/src/session/agent-session-events.ts +67 -0
- package/src/session/agent-session-types.ts +407 -0
- package/src/session/agent-session.ts +9000 -0
- package/src/session/agent-storage.ts +807 -0
- package/src/session/artifacts.ts +154 -0
- package/src/session/async-job-delivery.ts +82 -0
- package/src/session/auth-broker-config.ts +92 -0
- package/src/session/auth-storage.ts +25 -0
- package/src/session/bash-runner.ts +326 -0
- package/src/session/blob-store.ts +295 -0
- package/src/session/checkpoint-entries.ts +81 -0
- package/src/session/claude-session-store.ts +426 -0
- package/src/session/client-bridge.ts +85 -0
- package/src/session/codex-auto-reset.ts +673 -0
- package/src/session/codex-session-store.ts +673 -0
- package/src/session/compact-modes.ts +105 -0
- package/src/session/credential-pin.ts +93 -0
- package/src/session/eval-runner.ts +219 -0
- package/src/session/exit-diagnostics.ts +310 -0
- package/src/session/foreign-session-import.ts +52 -0
- package/src/session/foreign-session-jsonl.ts +29 -0
- package/src/session/foreign-session-store.ts +26 -0
- package/src/session/history-storage.ts +329 -0
- package/src/session/indexed-session-storage.ts +553 -0
- package/src/session/irc-bridge.ts +203 -0
- package/src/session/launch-completion.ts +37 -0
- package/src/session/messages.ts +1304 -0
- package/src/session/model-controls.ts +757 -0
- package/src/session/prewalk.ts +279 -0
- package/src/session/provider-image-budget.ts +86 -0
- package/src/session/queued-messages.ts +99 -0
- package/src/session/redis-session-storage.ts +257 -0
- package/src/session/retry-fallback-chains.ts +455 -0
- package/src/session/role-models.ts +85 -0
- package/src/session/session-advisors.ts +1896 -0
- package/src/session/session-context.ts +584 -0
- package/src/session/session-dump-format.ts +216 -0
- package/src/session/session-entries.ts +306 -0
- package/src/session/session-handoff.ts +325 -0
- package/src/session/session-history-format.ts +459 -0
- package/src/session/session-listing.ts +715 -0
- package/src/session/session-loader.ts +362 -0
- package/src/session/session-maintenance.ts +3115 -0
- package/src/session/session-manager.ts +2747 -0
- package/src/session/session-memory.ts +222 -0
- package/src/session/session-metadata.ts +53 -0
- package/src/session/session-migrations.ts +78 -0
- package/src/session/session-paths.ts +280 -0
- package/src/session/session-persistence.ts +293 -0
- package/src/session/session-provider-boundary.ts +306 -0
- package/src/session/session-stats.ts +349 -0
- package/src/session/session-storage.ts +774 -0
- package/src/session/session-title-slot.ts +141 -0
- package/src/session/session-tools.ts +1385 -0
- package/src/session/session-workspace.ts +53 -0
- package/src/session/settings-stream-fn.ts +79 -0
- package/src/session/shake-types.ts +43 -0
- package/src/session/snapcompact-inline.ts +545 -0
- package/src/session/snapcompact-savings-journal.ts +113 -0
- package/src/session/sql-session-storage.ts +374 -0
- package/src/session/stream-guards.ts +417 -0
- package/src/session/streaming-output.ts +1459 -0
- package/src/session/todo-tracker.ts +380 -0
- package/src/session/tool-choice-queue.ts +305 -0
- package/src/session/ttsr-coordinator.ts +496 -0
- package/src/session/turn-persistence.ts +142 -0
- package/src/session/turn-recovery.ts +2005 -0
- package/src/session/unexpected-stop-classifier.ts +141 -0
- package/src/session/yield-queue.ts +288 -0
- package/src/slash-commands/acp-builtins.ts +70 -0
- package/src/slash-commands/available-commands.ts +105 -0
- package/src/slash-commands/builtin-registry.ts +3149 -0
- package/src/slash-commands/helpers/active-oauth-account.ts +80 -0
- package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
- package/src/slash-commands/helpers/context-report.ts +66 -0
- package/src/slash-commands/helpers/format.ts +46 -0
- package/src/slash-commands/helpers/logout.ts +108 -0
- package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
- package/src/slash-commands/helpers/mcp.ts +533 -0
- package/src/slash-commands/helpers/parse.ts +85 -0
- package/src/slash-commands/helpers/reset-usage.ts +68 -0
- package/src/slash-commands/helpers/security.ts +451 -0
- package/src/slash-commands/helpers/session-pin.ts +44 -0
- package/src/slash-commands/helpers/ssh.ts +196 -0
- package/src/slash-commands/helpers/stats-dashboard.ts +86 -0
- package/src/slash-commands/helpers/todo.ts +285 -0
- package/src/slash-commands/helpers/usage-report.ts +198 -0
- package/src/slash-commands/marketplace-install-parser.ts +99 -0
- package/src/slash-commands/types.ts +139 -0
- package/src/ssh/config-writer.ts +183 -0
- package/src/ssh/connection-manager.ts +667 -0
- package/src/ssh/file-transfer.ts +214 -0
- package/src/ssh/sshfs-mount.ts +163 -0
- package/src/ssh/utils.ts +51 -0
- package/src/startup-splash.ts +19 -0
- package/src/stt/asr-client.ts +401 -0
- package/src/stt/asr-protocol.ts +65 -0
- package/src/stt/asr-worker.ts +603 -0
- package/src/stt/downloader.ts +142 -0
- package/src/stt/endpointer.ts +259 -0
- package/src/stt/index.ts +6 -0
- package/src/stt/models.ts +150 -0
- package/src/stt/sherpa-runtime.ts +71 -0
- package/src/stt/stt-controller.ts +320 -0
- package/src/stt/submit-trigger.ts +74 -0
- package/src/subprocess/worker-client.ts +463 -0
- package/src/subprocess/worker-runtime.ts +494 -0
- package/src/system-prompt.ts +921 -0
- package/src/task/agents.ts +170 -0
- package/src/task/commands.ts +132 -0
- package/src/task/discovery.ts +145 -0
- package/src/task/executor.ts +3431 -0
- package/src/task/index.ts +1515 -0
- package/src/task/isolation-ownership.ts +106 -0
- package/src/task/isolation-runner.ts +444 -0
- package/src/task/label.ts +40 -0
- package/src/task/name-generator.ts +1577 -0
- package/src/task/omp-command.ts +26 -0
- package/src/task/output-manager.ts +115 -0
- package/src/task/parallel.ts +221 -0
- package/src/task/persisted-revive.ts +173 -0
- package/src/task/prewalk.ts +6 -0
- package/src/task/prompt-policy.ts +8 -0
- package/src/task/provider-concurrency.ts +100 -0
- package/src/task/read-only-policy.ts +27 -0
- package/src/task/render.ts +1830 -0
- package/src/task/renderer.ts +14 -0
- package/src/task/repair-args.ts +118 -0
- package/src/task/spawn-policy.ts +72 -0
- package/src/task/structured-subagent.ts +676 -0
- package/src/task/subprocess-tool-registry.ts +88 -0
- package/src/task/types.ts +555 -0
- package/src/task/worktree.ts +967 -0
- package/src/task/yield-assembly.ts +198 -0
- package/src/telemetry-export.ts +504 -0
- package/src/thinking.ts +377 -0
- package/src/tiny/device.ts +111 -0
- package/src/tiny/dtype.ts +101 -0
- package/src/tiny/message-preproc.ts +155 -0
- package/src/tiny/models.ts +268 -0
- package/src/tiny/text.ts +290 -0
- package/src/tiny/title-client.ts +460 -0
- package/src/tiny/title-protocol.ts +56 -0
- package/src/tiny/worker.ts +354 -0
- package/src/tools/acp-bridge.ts +125 -0
- package/src/tools/approval.ts +245 -0
- package/src/tools/ask.ts +1459 -0
- package/src/tools/ast-edit.ts +718 -0
- package/src/tools/ast-grep.ts +526 -0
- package/src/tools/auto-generated-guard.ts +335 -0
- package/src/tools/bash-interactive.ts +435 -0
- package/src/tools/bash-interceptor.ts +148 -0
- package/src/tools/bash-pty-selection.ts +14 -0
- package/src/tools/bash-skill-urls.ts +350 -0
- package/src/tools/bash.ts +1826 -0
- package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
- package/src/tools/browser/aria/aria-snapshot.ts +131 -0
- package/src/tools/browser/attach.ts +219 -0
- package/src/tools/browser/cmux/cmux-tab.ts +1531 -0
- package/src/tools/browser/cmux/rpc.ts +200 -0
- package/src/tools/browser/cmux/socket-client.ts +445 -0
- package/src/tools/browser/launch.ts +939 -0
- package/src/tools/browser/readable.ts +112 -0
- package/src/tools/browser/registry.ts +447 -0
- package/src/tools/browser/relay/bridge.ts +945 -0
- package/src/tools/browser/relay/daemon.ts +117 -0
- package/src/tools/browser/relay/extension-assets/background.js.txt +242 -0
- package/src/tools/browser/relay/extension-assets/manifest.json.txt +14 -0
- package/src/tools/browser/relay/extension-assets/options.html.txt +53 -0
- package/src/tools/browser/relay/extension-assets/options.js.txt +23 -0
- package/src/tools/browser/relay/kind.ts +41 -0
- package/src/tools/browser/relay/protocol.ts +54 -0
- package/src/tools/browser/relay/server.ts +141 -0
- package/src/tools/browser/render.ts +229 -0
- package/src/tools/browser/run-output.ts +76 -0
- package/src/tools/browser/shared-daemon.ts +139 -0
- package/src/tools/browser/tab-protocol.ts +123 -0
- package/src/tools/browser/tab-supervisor.ts +1077 -0
- package/src/tools/browser/tab-worker-entry.ts +29 -0
- package/src/tools/browser/tab-worker.ts +1982 -0
- package/src/tools/browser.ts +487 -0
- package/src/tools/builtin-names.ts +67 -0
- package/src/tools/checkpoint.ts +137 -0
- package/src/tools/computer/exposure.ts +14 -0
- package/src/tools/computer/protocol.ts +69 -0
- package/src/tools/computer/supervisor.ts +409 -0
- package/src/tools/computer/worker-entry.ts +39 -0
- package/src/tools/computer/worker.ts +745 -0
- package/src/tools/computer-renderer.ts +147 -0
- package/src/tools/computer.ts +222 -0
- package/src/tools/conflict-detect.ts +815 -0
- package/src/tools/context.ts +49 -0
- package/src/tools/debug.ts +1121 -0
- package/src/tools/default-renderer.ts +154 -0
- package/src/tools/essential-tools.ts +46 -0
- package/src/tools/eval-backends.ts +34 -0
- package/src/tools/eval-format/index.ts +24 -0
- package/src/tools/eval-format/javascript.ts +952 -0
- package/src/tools/eval-format/julia.ts +446 -0
- package/src/tools/eval-format/python.ts +544 -0
- package/src/tools/eval-format/ruby.ts +380 -0
- package/src/tools/eval-render.ts +784 -0
- package/src/tools/eval.ts +774 -0
- package/src/tools/fetch.ts +1889 -0
- package/src/tools/file-recorder.ts +35 -0
- package/src/tools/fs-cache-invalidation.ts +28 -0
- package/src/tools/gh-cache-invalidation.ts +175 -0
- package/src/tools/gh-format.ts +12 -0
- package/src/tools/gh-renderer.ts +484 -0
- package/src/tools/gh.ts +3958 -0
- package/src/tools/github-cache.ts +663 -0
- package/src/tools/glob.ts +691 -0
- package/src/tools/grep.ts +1920 -0
- package/src/tools/grouped-file-output.ts +210 -0
- package/src/tools/hub/index.ts +579 -0
- package/src/tools/hub/jobs.ts +714 -0
- package/src/tools/hub/launch.ts +690 -0
- package/src/tools/hub/messaging.ts +735 -0
- package/src/tools/hub/types.ts +117 -0
- package/src/tools/image-gen.ts +1689 -0
- package/src/tools/image-providers.ts +50 -0
- package/src/tools/index.ts +736 -0
- package/src/tools/inspect-image-renderer.ts +133 -0
- package/src/tools/inspect-image.ts +316 -0
- package/src/tools/json-tree.ts +260 -0
- package/src/tools/jtd-to-json-schema.ts +219 -0
- package/src/tools/jtd-to-typescript.ts +136 -0
- package/src/tools/jtd-utils.ts +102 -0
- package/src/tools/learn.ts +141 -0
- package/src/tools/list-limit.ts +40 -0
- package/src/tools/manage-skill.ts +102 -0
- package/src/tools/match-line-format.ts +20 -0
- package/src/tools/memory-edit.ts +61 -0
- package/src/tools/memory-recall.ts +102 -0
- package/src/tools/memory-reflect.ts +88 -0
- package/src/tools/memory-render.ts +211 -0
- package/src/tools/memory-retain.ts +89 -0
- package/src/tools/output-meta.ts +860 -0
- package/src/tools/output-schema-validator.ts +307 -0
- package/src/tools/path-utils.ts +1489 -0
- package/src/tools/plan-mode-guard.ts +155 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +44 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +80 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +57 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +380 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +174 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +233 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +260 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +99 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +63 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +51 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +212 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +59 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +42 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +235 -0
- package/src/tools/read.ts +3762 -0
- package/src/tools/render-utils.ts +926 -0
- package/src/tools/renderers.ts +133 -0
- package/src/tools/report-tool-issue.ts +568 -0
- package/src/tools/resolve.ts +423 -0
- package/src/tools/review.ts +103 -0
- package/src/tools/run-scope.ts +417 -0
- package/src/tools/security-scan.ts +287 -0
- package/src/tools/shell-tokenize.ts +213 -0
- package/src/tools/sqlite-reader.ts +884 -0
- package/src/tools/terminal-output.ts +141 -0
- package/src/tools/todo.ts +1226 -0
- package/src/tools/tool-errors.ts +62 -0
- package/src/tools/tool-result.ts +102 -0
- package/src/tools/tool-timeouts.ts +38 -0
- package/src/tools/tts.ts +266 -0
- package/src/tools/vibe.ts +608 -0
- package/src/tools/write.ts +1646 -0
- package/src/tools/xdev.ts +560 -0
- package/src/tools/yield.ts +486 -0
- package/src/tts/downloader.ts +64 -0
- package/src/tts/index.ts +10 -0
- package/src/tts/models.ts +137 -0
- package/src/tts/runtime.ts +21 -0
- package/src/tts/speakable.ts +392 -0
- package/src/tts/speech-enhancer.ts +206 -0
- package/src/tts/streaming-player.ts +120 -0
- package/src/tts/tts-client.ts +475 -0
- package/src/tts/tts-protocol.ts +69 -0
- package/src/tts/tts-worker.ts +434 -0
- package/src/tts/vocalizer.ts +419 -0
- package/src/tts/wav.ts +58 -0
- package/src/tui/code-cell.ts +268 -0
- package/src/tui/file-list.ts +55 -0
- package/src/tui/hyperlink.ts +178 -0
- package/src/tui/index.ts +13 -0
- package/src/tui/output-block.ts +268 -0
- package/src/tui/status-line.ts +54 -0
- package/src/tui/tree-list.ts +172 -0
- package/src/tui/types.ts +15 -0
- package/src/tui/utils.ts +103 -0
- package/src/tui/width-aware-text.ts +58 -0
- package/src/utils/active-repo-context.ts +143 -0
- package/src/utils/block-context.ts +312 -0
- package/src/utils/changelog.ts +373 -0
- package/src/utils/clipboard.ts +361 -0
- package/src/utils/command-args.ts +74 -0
- package/src/utils/commit-message-generator.ts +148 -0
- package/src/utils/cpuprofile.ts +235 -0
- package/src/utils/edit-mode.ts +61 -0
- package/src/utils/enhanced-paste.ts +230 -0
- package/src/utils/event-bus.ts +33 -0
- package/src/utils/external-editor.ts +80 -0
- package/src/utils/fetch-timeout.ts +10 -0
- package/src/utils/file-display-mode.ts +44 -0
- package/src/utils/file-mentions.ts +293 -0
- package/src/utils/git.ts +2472 -0
- package/src/utils/image-loading.ts +236 -0
- package/src/utils/image-resize.ts +420 -0
- package/src/utils/image-vision-fallback.ts +196 -0
- package/src/utils/inspect-image-mode.ts +39 -0
- package/src/utils/ipc.ts +38 -0
- package/src/utils/jj.ts +422 -0
- package/src/utils/lang-from-path.ts +251 -0
- package/src/utils/late-cleanup.ts +17 -0
- package/src/utils/local-date.ts +7 -0
- package/src/utils/mac-file-urls.applescript +37 -0
- package/src/utils/markit-cache.ts +166 -0
- package/src/utils/markit.ts +223 -0
- package/src/utils/mupdf-wasm-embed.ts +12 -0
- package/src/utils/open.ts +126 -0
- package/src/utils/profile-tree.ts +111 -0
- package/src/utils/prompt-path.ts +3 -0
- package/src/utils/qrcode.ts +535 -0
- package/src/utils/sample-profile.ts +437 -0
- package/src/utils/session-color.ts +142 -0
- package/src/utils/shell-snapshot-fn-env.sh +63 -0
- package/src/utils/shell-snapshot.ts +326 -0
- package/src/utils/sixel.ts +69 -0
- package/src/utils/thinking-display.ts +163 -0
- package/src/utils/title-generator.ts +597 -0
- package/src/utils/token-rate.ts +72 -0
- package/src/utils/tool-choice.ts +50 -0
- package/src/utils/tools-manager.ts +411 -0
- package/src/utils/turndown.ts +82 -0
- package/src/utils/zip.ts +1106 -0
- package/src/vibe/runtime.ts +1684 -0
- package/src/vibe/state.ts +4 -0
- package/src/web/kagi.ts +305 -0
- package/src/web/parallel.ts +354 -0
- package/src/web/scrapers/artifacthub.ts +207 -0
- package/src/web/scrapers/arxiv.ts +83 -0
- package/src/web/scrapers/aur.ts +162 -0
- package/src/web/scrapers/biorxiv.ts +133 -0
- package/src/web/scrapers/bluesky.ts +262 -0
- package/src/web/scrapers/brew.ts +172 -0
- package/src/web/scrapers/cheatsh.ts +68 -0
- package/src/web/scrapers/chocolatey.ts +196 -0
- package/src/web/scrapers/choosealicense.ts +95 -0
- package/src/web/scrapers/cisa-kev.ts +87 -0
- package/src/web/scrapers/clojars.ts +154 -0
- package/src/web/scrapers/coingecko.ts +177 -0
- package/src/web/scrapers/crates-io.ts +97 -0
- package/src/web/scrapers/crossref.ts +136 -0
- package/src/web/scrapers/devto.ts +147 -0
- package/src/web/scrapers/discogs.ts +306 -0
- package/src/web/scrapers/discourse.ts +197 -0
- package/src/web/scrapers/dockerhub.ts +138 -0
- package/src/web/scrapers/docs-rs.ts +663 -0
- package/src/web/scrapers/fdroid.ts +134 -0
- package/src/web/scrapers/firefox-addons.ts +191 -0
- package/src/web/scrapers/flathub.ts +223 -0
- package/src/web/scrapers/github-gist.ts +58 -0
- package/src/web/scrapers/github.ts +800 -0
- package/src/web/scrapers/gitlab.ts +401 -0
- package/src/web/scrapers/go-pkg.ts +266 -0
- package/src/web/scrapers/hackage.ts +129 -0
- package/src/web/scrapers/hackernews.ts +189 -0
- package/src/web/scrapers/hex.ts +105 -0
- package/src/web/scrapers/huggingface.ts +321 -0
- package/src/web/scrapers/iacr.ts +89 -0
- package/src/web/scrapers/index.ts +252 -0
- package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
- package/src/web/scrapers/lemmy.ts +203 -0
- package/src/web/scrapers/lobsters.ts +175 -0
- package/src/web/scrapers/mastodon.ts +292 -0
- package/src/web/scrapers/maven.ts +138 -0
- package/src/web/scrapers/mdn.ts +173 -0
- package/src/web/scrapers/metacpan.ts +222 -0
- package/src/web/scrapers/musicbrainz.ts +250 -0
- package/src/web/scrapers/npm.ts +98 -0
- package/src/web/scrapers/nuget.ts +183 -0
- package/src/web/scrapers/nvd.ts +222 -0
- package/src/web/scrapers/ollama.ts +239 -0
- package/src/web/scrapers/open-vsx.ts +106 -0
- package/src/web/scrapers/opencorporates.ts +292 -0
- package/src/web/scrapers/openlibrary.ts +336 -0
- package/src/web/scrapers/orcid.ts +286 -0
- package/src/web/scrapers/osv.ts +176 -0
- package/src/web/scrapers/packagist.ts +160 -0
- package/src/web/scrapers/pub-dev.ts +143 -0
- package/src/web/scrapers/pubmed.ts +211 -0
- package/src/web/scrapers/pypi.ts +112 -0
- package/src/web/scrapers/rawg.ts +110 -0
- package/src/web/scrapers/readthedocs.ts +121 -0
- package/src/web/scrapers/reddit.ts +95 -0
- package/src/web/scrapers/repology.ts +251 -0
- package/src/web/scrapers/rfc.ts +201 -0
- package/src/web/scrapers/rubygems.ts +103 -0
- package/src/web/scrapers/searchcode.ts +189 -0
- package/src/web/scrapers/sec-edgar.ts +261 -0
- package/src/web/scrapers/semantic-scholar.ts +171 -0
- package/src/web/scrapers/snapcraft.ts +187 -0
- package/src/web/scrapers/sourcegraph.ts +336 -0
- package/src/web/scrapers/spdx.ts +108 -0
- package/src/web/scrapers/spotify.ts +198 -0
- package/src/web/scrapers/stackoverflow.ts +120 -0
- package/src/web/scrapers/terraform.ts +277 -0
- package/src/web/scrapers/tldr.ts +47 -0
- package/src/web/scrapers/twitter.ts +94 -0
- package/src/web/scrapers/types.ts +354 -0
- package/src/web/scrapers/utils.ts +109 -0
- package/src/web/scrapers/vimeo.ts +133 -0
- package/src/web/scrapers/vscode-marketplace.ts +187 -0
- package/src/web/scrapers/w3c.ts +156 -0
- package/src/web/scrapers/wikidata.ts +344 -0
- package/src/web/scrapers/wikipedia.ts +84 -0
- package/src/web/scrapers/youtube.ts +325 -0
- package/src/web/search/index.ts +393 -0
- package/src/web/search/provider.ts +272 -0
- package/src/web/search/providers/anthropic.ts +406 -0
- package/src/web/search/providers/base.ts +112 -0
- package/src/web/search/providers/brave.ts +181 -0
- package/src/web/search/providers/browser-headers.ts +82 -0
- package/src/web/search/providers/browser-page.ts +125 -0
- package/src/web/search/providers/codex.ts +788 -0
- package/src/web/search/providers/duckduckgo.ts +382 -0
- package/src/web/search/providers/ecosia.ts +183 -0
- package/src/web/search/providers/exa.ts +513 -0
- package/src/web/search/providers/firecrawl.ts +213 -0
- package/src/web/search/providers/gemini.ts +634 -0
- package/src/web/search/providers/google.ts +195 -0
- package/src/web/search/providers/jina.ts +144 -0
- package/src/web/search/providers/kagi.ts +98 -0
- package/src/web/search/providers/kimi.ts +221 -0
- package/src/web/search/providers/mojeek.ts +220 -0
- package/src/web/search/providers/parallel.ts +186 -0
- package/src/web/search/providers/perplexity-auth.ts +142 -0
- package/src/web/search/providers/perplexity.ts +997 -0
- package/src/web/search/providers/public.ts +199 -0
- package/src/web/search/providers/searxng.ts +467 -0
- package/src/web/search/providers/startpage.ts +225 -0
- package/src/web/search/providers/synthetic.ts +126 -0
- package/src/web/search/providers/tavily.ts +244 -0
- package/src/web/search/providers/tinyfish.ts +166 -0
- package/src/web/search/providers/utils.ts +130 -0
- package/src/web/search/providers/xai.ts +372 -0
- package/src/web/search/providers/zai.ts +452 -0
- package/src/web/search/query.ts +850 -0
- package/src/web/search/render.ts +262 -0
- package/src/web/search/types.ts +518 -0
- package/src/web/search/utils.ts +17 -0
- package/src/workspace-tree.ts +326 -0
|
@@ -0,0 +1,1035 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Component,
|
|
3
|
+
Container,
|
|
4
|
+
FuzzyText,
|
|
5
|
+
Input,
|
|
6
|
+
matchesKey,
|
|
7
|
+
padding,
|
|
8
|
+
replaceTabs,
|
|
9
|
+
routeSgrMouseInput,
|
|
10
|
+
ScrollView,
|
|
11
|
+
Spacer,
|
|
12
|
+
Text,
|
|
13
|
+
truncateToWidth,
|
|
14
|
+
visibleWidth,
|
|
15
|
+
} from "@oh-my-pi/pi-tui";
|
|
16
|
+
import { formatBytes } from "@oh-my-pi/pi-utils";
|
|
17
|
+
import { theme } from "../../modes/theme/theme";
|
|
18
|
+
import { matchesAppInterrupt, matchesSelectDown, matchesSelectUp } from "../../modes/utils/keybinding-matchers";
|
|
19
|
+
import type { SessionInfo, SessionStatus } from "../../session/session-listing";
|
|
20
|
+
import { shortenPath } from "../../tools/render-utils";
|
|
21
|
+
import { DynamicBorder } from "./dynamic-border";
|
|
22
|
+
import { HookSelectorComponent } from "./hook-selector";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Themed glyph + colored label for a session's lifecycle status, or `undefined`
|
|
26
|
+
* when there is nothing useful to show (`unknown`/unset) so the metadata line
|
|
27
|
+
* stays uncluttered. The glyph resolves through the active symbol preset
|
|
28
|
+
* (nerdfont / unicode / ascii) via `theme.status.*`.
|
|
29
|
+
*/
|
|
30
|
+
function formatSessionStatus(status: SessionStatus | undefined): string | undefined {
|
|
31
|
+
switch (status) {
|
|
32
|
+
case "complete":
|
|
33
|
+
return theme.fg("success", `${theme.status.success} done`);
|
|
34
|
+
case "interrupted":
|
|
35
|
+
return theme.fg("warning", `${theme.status.warning} interrupted`);
|
|
36
|
+
case "aborted":
|
|
37
|
+
return theme.fg("muted", `${theme.status.aborted} aborted`);
|
|
38
|
+
case "error":
|
|
39
|
+
return theme.fg("error", `${theme.status.error} error`);
|
|
40
|
+
case "pending":
|
|
41
|
+
return theme.fg("accent", `${theme.status.pending} pending`);
|
|
42
|
+
default:
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Returns the IDs of sessions whose recorded prompts match a query, best first. */
|
|
48
|
+
export type SessionHistoryMatcher = (query: string) => string[];
|
|
49
|
+
|
|
50
|
+
function sessionSearchText(session: SessionInfo): string {
|
|
51
|
+
const parts = [
|
|
52
|
+
session.id,
|
|
53
|
+
session.title ?? "",
|
|
54
|
+
session.cwd ?? "",
|
|
55
|
+
session.firstMessage ?? "",
|
|
56
|
+
session.allMessagesText,
|
|
57
|
+
session.path,
|
|
58
|
+
];
|
|
59
|
+
return parts.filter(Boolean).join(" ");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Lowercased per-session search haystack, built once and cached on the
|
|
64
|
+
* {@link SessionInfo} itself (so it dies with the listing that produced it).
|
|
65
|
+
* Rebuilding it per keystroke — a ~4KB string join plus `toLowerCase` per
|
|
66
|
+
* session — was one of the costs that made resume search visibly lag.
|
|
67
|
+
*
|
|
68
|
+
* Only the string is cached. A prebuilt fuzzy index (~60KB per 4KB session)
|
|
69
|
+
* would cost hundreds of MB on multi-thousand-session listings, so fuzzy
|
|
70
|
+
* indexes are built transiently per scan visit instead (see
|
|
71
|
+
* {@link scoreFuzzySession} callers).
|
|
72
|
+
*/
|
|
73
|
+
const kSearchTextLower = Symbol("session.searchTextLower");
|
|
74
|
+
|
|
75
|
+
interface SearchableSessionInfo extends SessionInfo {
|
|
76
|
+
[kSearchTextLower]?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function sessionTextLower(session: SessionInfo): string {
|
|
80
|
+
const tagged = session as SearchableSessionInfo;
|
|
81
|
+
let textLower = tagged[kSearchTextLower];
|
|
82
|
+
if (textLower === undefined) {
|
|
83
|
+
textLower = sessionSearchText(session).toLowerCase();
|
|
84
|
+
tagged[kSearchTextLower] = textLower;
|
|
85
|
+
}
|
|
86
|
+
return textLower;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function tokenizeSessionQuery(query: string): string[] {
|
|
90
|
+
const trimmed = query.trim().toLowerCase();
|
|
91
|
+
return trimmed ? trimmed.split(/\s+/) : [];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function compareSessionRecency(a: SessionInfo, b: SessionInfo): number {
|
|
95
|
+
return b.modified.getTime() - a.modified.getTime();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const MIN_PURE_FUZZY_TOKEN_SCORE = -20;
|
|
99
|
+
|
|
100
|
+
/** One ranked search hit; `index` is the session's position in the unfiltered list (recency order). */
|
|
101
|
+
interface RankedSessionMatch {
|
|
102
|
+
session: SessionInfo;
|
|
103
|
+
score: number;
|
|
104
|
+
index: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* True when every query token appears verbatim in the haystack. Literal
|
|
109
|
+
* matches rank purely by recency, so they skip fuzzy scoring entirely — a pure
|
|
110
|
+
* fast path, not a semantic change: a contiguous substring of the lowercased
|
|
111
|
+
* text always lies within one normalized word per query sub-token, so every
|
|
112
|
+
* literal token also fuzzy-matches.
|
|
113
|
+
*/
|
|
114
|
+
function isLiteralMatch(textLower: string, tokens: string[]): boolean {
|
|
115
|
+
for (const token of tokens) {
|
|
116
|
+
if (!textLower.includes(token)) return false;
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Fuzzy-score one non-literal session against every query token. Returns
|
|
123
|
+
* undefined when a token fails to match or the weakest token is pure-fuzzy
|
|
124
|
+
* noise. The caller builds `fuzzy` once per session visit so multi-token
|
|
125
|
+
* queries share a single index.
|
|
126
|
+
*/
|
|
127
|
+
function scoreFuzzySession(
|
|
128
|
+
session: SessionInfo,
|
|
129
|
+
index: number,
|
|
130
|
+
tokens: string[],
|
|
131
|
+
fuzzy: FuzzyText,
|
|
132
|
+
): RankedSessionMatch | undefined {
|
|
133
|
+
let score = 0;
|
|
134
|
+
let worstTokenScore = Number.NEGATIVE_INFINITY;
|
|
135
|
+
for (const token of tokens) {
|
|
136
|
+
const match = fuzzy.match(token);
|
|
137
|
+
if (!match.matches) return undefined;
|
|
138
|
+
score += match.score;
|
|
139
|
+
worstTokenScore = Math.max(worstTokenScore, match.score);
|
|
140
|
+
}
|
|
141
|
+
if (worstTokenScore >= MIN_PURE_FUZZY_TOKEN_SCORE) return undefined;
|
|
142
|
+
return { session, score, index };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function compareLiteralRank(a: RankedSessionMatch, b: RankedSessionMatch): number {
|
|
146
|
+
return compareSessionRecency(a.session, b.session) || a.index - b.index;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function compareFuzzyRank(a: RankedSessionMatch, b: RankedSessionMatch): number {
|
|
150
|
+
return a.score - b.score || compareSessionRecency(a.session, b.session) || a.index - b.index;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Filter and rank session picker search results.
|
|
155
|
+
*
|
|
156
|
+
* Resume search narrows a recency-sorted list: once every query token appears
|
|
157
|
+
* as a literal substring, newer sessions should beat a slightly better fuzzy
|
|
158
|
+
* position match. Pure fuzzy/acronym matches still sort by fuzzy score after
|
|
159
|
+
* literal matches, but weak pure fuzzy tokens are dropped as noise.
|
|
160
|
+
*
|
|
161
|
+
* This is the synchronous reference implementation; {@link SessionList} runs
|
|
162
|
+
* the same primitives incrementally so huge listings never block a keystroke.
|
|
163
|
+
*/
|
|
164
|
+
export function rankSessionSearchMatches(allSessions: SessionInfo[], query: string): SessionInfo[] {
|
|
165
|
+
const tokens = tokenizeSessionQuery(query);
|
|
166
|
+
if (tokens.length === 0) return allSessions;
|
|
167
|
+
|
|
168
|
+
const literal: RankedSessionMatch[] = [];
|
|
169
|
+
const fuzzyMatches: RankedSessionMatch[] = [];
|
|
170
|
+
for (let index = 0; index < allSessions.length; index++) {
|
|
171
|
+
const session = allSessions[index]!;
|
|
172
|
+
const textLower = sessionTextLower(session);
|
|
173
|
+
if (isLiteralMatch(textLower, tokens)) {
|
|
174
|
+
literal.push({ session, score: 0, index });
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const match = scoreFuzzySession(session, index, tokens, new FuzzyText(textLower));
|
|
178
|
+
if (match) fuzzyMatches.push(match);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
literal.sort(compareLiteralRank);
|
|
182
|
+
fuzzyMatches.sort(compareFuzzyRank);
|
|
183
|
+
const out: SessionInfo[] = [];
|
|
184
|
+
for (const match of literal) out.push(match.session);
|
|
185
|
+
for (const match of fuzzyMatches) out.push(match.session);
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Combine metadata matches with prompt-history matches for ranking, using both
|
|
191
|
+
* signals rather than replacing one with the other.
|
|
192
|
+
*
|
|
193
|
+
* - `fuzzy` is the ordered metadata/session-text result.
|
|
194
|
+
* - `historyIds` are session IDs whose recorded prompts matched the query,
|
|
195
|
+
* ordered by prompt-history rank (typically newest matching prompt first); duplicates are tolerated.
|
|
196
|
+
*
|
|
197
|
+
* Ranking: prompt-history matches lead in history order, then remaining
|
|
198
|
+
* metadata matches keep their existing order. A metadata match is never dropped,
|
|
199
|
+
* and history matches not present in `allSessions` (e.g. deleted or out-of-scope
|
|
200
|
+
* sessions) are ignored since they cannot be resumed from here.
|
|
201
|
+
*/
|
|
202
|
+
export function mergeSessionRanking(
|
|
203
|
+
allSessions: SessionInfo[],
|
|
204
|
+
fuzzy: SessionInfo[],
|
|
205
|
+
historyIds: string[],
|
|
206
|
+
): SessionInfo[] {
|
|
207
|
+
if (historyIds.length === 0) return fuzzy;
|
|
208
|
+
|
|
209
|
+
const sessionsById = new Map<string, SessionInfo>();
|
|
210
|
+
for (const session of allSessions) {
|
|
211
|
+
if (!sessionsById.has(session.id)) sessionsById.set(session.id, session);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const historyMatches: SessionInfo[] = [];
|
|
215
|
+
const historyPaths = new Set<string>();
|
|
216
|
+
for (const id of historyIds) {
|
|
217
|
+
const session = sessionsById.get(id);
|
|
218
|
+
if (!session || historyPaths.has(session.path)) continue;
|
|
219
|
+
historyMatches.push(session);
|
|
220
|
+
historyPaths.add(session.path);
|
|
221
|
+
}
|
|
222
|
+
if (historyMatches.length === 0) return fuzzy;
|
|
223
|
+
|
|
224
|
+
const metadataOnly = fuzzy.filter(session => !historyPaths.has(session.path));
|
|
225
|
+
return [...historyMatches, ...metadataOnly];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Delay before the prompt-history DB is consulted for the current query.
|
|
230
|
+
* History matching hits SQLite synchronously (an FTS lookup plus a LIKE scan
|
|
231
|
+
* over every stored prompt — tens to hundreds of ms on a year-old database),
|
|
232
|
+
* so it must never run per keystroke: fuzzy results render immediately and
|
|
233
|
+
* the history merge lands once typing pauses.
|
|
234
|
+
*/
|
|
235
|
+
const HISTORY_MERGE_DEBOUNCE_MS = 150;
|
|
236
|
+
/**
|
|
237
|
+
* Minimum query length for history augmentation. A single character matches
|
|
238
|
+
* essentially every stored prompt — the most expensive FTS prefix to expand —
|
|
239
|
+
* and only reorders the recency-ranked list by noise.
|
|
240
|
+
*/
|
|
241
|
+
const HISTORY_MERGE_MIN_QUERY = 2;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Sessions fuzzy-scored synchronously inside the keystroke itself. Small
|
|
245
|
+
* listings finish within it, keeping the complete-in-one-frame behavior;
|
|
246
|
+
* anything left spills into async chunks. A fuzzy visit costs ~100µs (index
|
|
247
|
+
* build over the ≤4KB per-session corpus dominates), so 100 visits ≈ 10ms —
|
|
248
|
+
* about one frame. Counts rather than a deadline keep chunk boundaries
|
|
249
|
+
* deterministic (and testable under fake timers).
|
|
250
|
+
*/
|
|
251
|
+
const FUZZY_SCAN_INLINE_COUNT = 100;
|
|
252
|
+
/**
|
|
253
|
+
* Sessions fuzzy-scored per async chunk (~15ms). Each chunk yields back to
|
|
254
|
+
* the event loop so the next keystroke is never blocked behind a long scan; a
|
|
255
|
+
* new query bumps the scan generation and orphans pending chunks.
|
|
256
|
+
*/
|
|
257
|
+
const FUZZY_SCAN_CHUNK_COUNT = 150;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Custom session list component with multi-line items and search
|
|
261
|
+
*/
|
|
262
|
+
class SessionList implements Component {
|
|
263
|
+
#filteredSessions: SessionInfo[] = [];
|
|
264
|
+
#selectedIndex: number = 0;
|
|
265
|
+
// Maps a 0-based line within this list's own render to a filtered-session
|
|
266
|
+
// index, or undefined for chrome rows (search line, blanks, scrollbar gap).
|
|
267
|
+
// Rebuilt every render so the picker's mouse hit-testing tracks the live
|
|
268
|
+
// scroll window. Only consulted while the picker holds the alternate screen
|
|
269
|
+
// (where the overlay enables mouse tracking and paints from screen row 0).
|
|
270
|
+
#hitRows: (number | undefined)[] = [];
|
|
271
|
+
readonly #searchInput: Input;
|
|
272
|
+
onSelect?: (session: SessionInfo) => void;
|
|
273
|
+
onCancel?: () => void;
|
|
274
|
+
onExit: () => void = () => {};
|
|
275
|
+
onToggleScope?: () => void;
|
|
276
|
+
// Snapshot of the live terminal-row getter; the visible window is derived
|
|
277
|
+
// from it per render so the picker fits the viewport (and adapts to resize).
|
|
278
|
+
readonly #getTerminalRows: () => number;
|
|
279
|
+
|
|
280
|
+
onDeleteRequest?: (session: SessionInfo) => void;
|
|
281
|
+
|
|
282
|
+
#allSessions: SessionInfo[];
|
|
283
|
+
#showCwd: boolean;
|
|
284
|
+
readonly #historyMatcher?: SessionHistoryMatcher;
|
|
285
|
+
#historyMergeTimer: NodeJS.Timeout | undefined;
|
|
286
|
+
/** Re-render hook for async list updates (fuzzy scan chunks, history merge). */
|
|
287
|
+
onRequestRender?: () => void;
|
|
288
|
+
|
|
289
|
+
// ── Incremental search state ──────────────────────────────────────────
|
|
290
|
+
// #filteredSessions is always composed from these three inputs (see
|
|
291
|
+
// #composeFiltered), so late-arriving fuzzy chunks and the debounced
|
|
292
|
+
// history merge can land in any order without clobbering each other.
|
|
293
|
+
/** Recency-ranked sessions whose text contains every query token verbatim. */
|
|
294
|
+
#literalRanked: RankedSessionMatch[] = [];
|
|
295
|
+
/** Score-ranked fuzzy-only matches, appended by scan chunks. */
|
|
296
|
+
#fuzzyRanked: RankedSessionMatch[] = [];
|
|
297
|
+
/** Prompt-history session IDs for the current query, once the merge landed. */
|
|
298
|
+
#historyIds: string[] = [];
|
|
299
|
+
/** Invalidates in-flight scan chunks when the query or dataset changes. */
|
|
300
|
+
#scanGeneration = 0;
|
|
301
|
+
#scanTimer: NodeJS.Timeout | undefined;
|
|
302
|
+
/**
|
|
303
|
+
* True once the user moved the selection for the current query; blocks the
|
|
304
|
+
* history merge from reordering the list under their cursor. (Fuzzy chunks
|
|
305
|
+
* only append below the literal group, which never shifts existing rows.)
|
|
306
|
+
*/
|
|
307
|
+
#selectionMoved = false;
|
|
308
|
+
|
|
309
|
+
constructor(
|
|
310
|
+
sessions: SessionInfo[],
|
|
311
|
+
showCwd = false,
|
|
312
|
+
historyMatcher?: SessionHistoryMatcher,
|
|
313
|
+
getTerminalRows: () => number = () => 24,
|
|
314
|
+
) {
|
|
315
|
+
this.#getTerminalRows = getTerminalRows;
|
|
316
|
+
this.#allSessions = sessions;
|
|
317
|
+
this.#showCwd = showCwd;
|
|
318
|
+
this.#historyMatcher = historyMatcher;
|
|
319
|
+
this.#filteredSessions = sessions;
|
|
320
|
+
this.#searchInput = new Input();
|
|
321
|
+
|
|
322
|
+
// Handle Enter in search input - select current item
|
|
323
|
+
this.#searchInput.onSubmit = () => {
|
|
324
|
+
const selected = this.#filteredSessions[this.#selectedIndex];
|
|
325
|
+
if (selected) {
|
|
326
|
+
this.onSelect?.(selected);
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Number of sessions to show at once, sized so the whole picker fits the
|
|
333
|
+
* current viewport instead of pushing its header/search off the top.
|
|
334
|
+
*
|
|
335
|
+
* Budget = rows − chrome − reserve, divided by the worst-case per-session
|
|
336
|
+
* height. Chrome (12) is the surrounding spacers/borders/header (7) plus the
|
|
337
|
+
* list's search line, blank, scroll indicator, blank, and hint (5). A titled
|
|
338
|
+
* session is the tallest item at 4 lines (title + preview + metadata +
|
|
339
|
+
* blank); budgeting for that guarantees no overflow even when every visible
|
|
340
|
+
* entry has a title. The reserve covers below-editor hook widgets / cursor.
|
|
341
|
+
*/
|
|
342
|
+
#visibleCount(): number {
|
|
343
|
+
const CHROME = 12;
|
|
344
|
+
const PER_SESSION = 4;
|
|
345
|
+
const RESERVE = 1;
|
|
346
|
+
const budget = this.#getTerminalRows() - CHROME - RESERVE;
|
|
347
|
+
return Math.max(2, Math.floor(budget / PER_SESSION));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Replace the visible dataset, e.g. when toggling folder/all-projects scope. */
|
|
351
|
+
setSessions(sessions: SessionInfo[], showCwd: boolean): void {
|
|
352
|
+
this.#allSessions = sessions;
|
|
353
|
+
this.#showCwd = showCwd;
|
|
354
|
+
this.#selectedIndex = 0;
|
|
355
|
+
this.#filterSessions(this.#searchInput.getValue());
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
#filterSessions(query: string): void {
|
|
359
|
+
this.#scanGeneration++;
|
|
360
|
+
if (this.#scanTimer !== undefined) {
|
|
361
|
+
clearTimeout(this.#scanTimer);
|
|
362
|
+
this.#scanTimer = undefined;
|
|
363
|
+
}
|
|
364
|
+
this.#selectionMoved = false;
|
|
365
|
+
this.#historyIds = [];
|
|
366
|
+
this.#literalRanked = [];
|
|
367
|
+
this.#fuzzyRanked = [];
|
|
368
|
+
|
|
369
|
+
const tokens = tokenizeSessionQuery(query);
|
|
370
|
+
if (tokens.length === 0) {
|
|
371
|
+
this.#filteredSessions = this.#allSessions;
|
|
372
|
+
this.#selectedIndex = Math.min(this.#selectedIndex, Math.max(0, this.#filteredSessions.length - 1));
|
|
373
|
+
this.#scheduleHistoryMerge(query);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Literal pass: one substring scan per token per session, synchronous so
|
|
378
|
+
// every keystroke gets immediate recency-ranked feedback regardless of
|
|
379
|
+
// listing size.
|
|
380
|
+
const literal: RankedSessionMatch[] = [];
|
|
381
|
+
const rest: number[] = [];
|
|
382
|
+
const all = this.#allSessions;
|
|
383
|
+
for (let index = 0; index < all.length; index++) {
|
|
384
|
+
if (isLiteralMatch(sessionTextLower(all[index]!), tokens)) {
|
|
385
|
+
literal.push({ session: all[index]!, score: 0, index });
|
|
386
|
+
} else {
|
|
387
|
+
rest.push(index);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
literal.sort(compareLiteralRank);
|
|
391
|
+
this.#literalRanked = literal;
|
|
392
|
+
|
|
393
|
+
// Fuzzy pass: building a fuzzy index per session is too expensive to run
|
|
394
|
+
// across a huge listing inside one keystroke, so scan a bounded slice now
|
|
395
|
+
// and spill the remainder into async chunks.
|
|
396
|
+
this.#scanFuzzySlice(this.#scanGeneration, tokens, rest, 0, FUZZY_SCAN_INLINE_COUNT);
|
|
397
|
+
this.#composeFiltered();
|
|
398
|
+
this.#scheduleHistoryMerge(query);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Score up to `budget` sessions from `rest[start..]` (indexes into the
|
|
403
|
+
* unfiltered list), then schedule the remainder on a macrotask so pending
|
|
404
|
+
* input events run first. Chunks that added matches recompose the visible
|
|
405
|
+
* list and request a render; a stale generation aborts silently.
|
|
406
|
+
*/
|
|
407
|
+
#scanFuzzySlice(generation: number, tokens: string[], rest: number[], start: number, budget: number): void {
|
|
408
|
+
const all = this.#allSessions;
|
|
409
|
+
const end = Math.min(rest.length, start + budget);
|
|
410
|
+
for (let i = start; i < end; i++) {
|
|
411
|
+
const index = rest[i]!;
|
|
412
|
+
const session = all[index]!;
|
|
413
|
+
const match = scoreFuzzySession(session, index, tokens, new FuzzyText(sessionTextLower(session)));
|
|
414
|
+
if (match) this.#fuzzyRanked.push(match);
|
|
415
|
+
}
|
|
416
|
+
if (end >= rest.length) return;
|
|
417
|
+
this.#scanTimer = setTimeout(() => {
|
|
418
|
+
this.#scanTimer = undefined;
|
|
419
|
+
if (generation !== this.#scanGeneration) return;
|
|
420
|
+
const before = this.#fuzzyRanked.length;
|
|
421
|
+
this.#scanFuzzySlice(generation, tokens, rest, end, FUZZY_SCAN_CHUNK_COUNT);
|
|
422
|
+
if (this.#fuzzyRanked.length > before) {
|
|
423
|
+
this.#composeFiltered();
|
|
424
|
+
this.onRequestRender?.();
|
|
425
|
+
}
|
|
426
|
+
}, 0);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Rebuild {@link #filteredSessions} from the current literal, fuzzy, and
|
|
431
|
+
* history inputs: literal matches first (recency), fuzzy-only matches below
|
|
432
|
+
* (score), prompt-history matches promoted to the top when present.
|
|
433
|
+
*/
|
|
434
|
+
#composeFiltered(): void {
|
|
435
|
+
this.#fuzzyRanked.sort(compareFuzzyRank);
|
|
436
|
+
const base: SessionInfo[] = [];
|
|
437
|
+
for (const match of this.#literalRanked) base.push(match.session);
|
|
438
|
+
for (const match of this.#fuzzyRanked) base.push(match.session);
|
|
439
|
+
this.#filteredSessions =
|
|
440
|
+
this.#historyIds.length > 0 ? mergeSessionRanking(this.#allSessions, base, this.#historyIds) : base;
|
|
441
|
+
this.#selectedIndex = Math.min(this.#selectedIndex, Math.max(0, this.#filteredSessions.length - 1));
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Augment ranked results with prompt-history matches without replacing them.
|
|
446
|
+
* The session-list corpus only sees the first 4KB of each session, so a prompt
|
|
447
|
+
* typed deep into a long session is invisible to text search; `historyMatcher`
|
|
448
|
+
* recovers those via `history.db`. The lookup hits SQLite synchronously, so it
|
|
449
|
+
* is debounced off the keystroke path ({@link HISTORY_MERGE_DEBOUNCE_MS}) and
|
|
450
|
+
* composed in when it lands, discarded if the query changed meanwhile.
|
|
451
|
+
*/
|
|
452
|
+
#scheduleHistoryMerge(query: string): void {
|
|
453
|
+
if (this.#historyMergeTimer !== undefined) {
|
|
454
|
+
clearTimeout(this.#historyMergeTimer);
|
|
455
|
+
this.#historyMergeTimer = undefined;
|
|
456
|
+
}
|
|
457
|
+
const matcher = this.#historyMatcher;
|
|
458
|
+
const trimmed = query.trim();
|
|
459
|
+
if (!matcher || trimmed.length < HISTORY_MERGE_MIN_QUERY) return;
|
|
460
|
+
this.#historyMergeTimer = setTimeout(() => {
|
|
461
|
+
this.#historyMergeTimer = undefined;
|
|
462
|
+
if (this.#searchInput.getValue() !== query) return;
|
|
463
|
+
if (this.#selectionMoved) return;
|
|
464
|
+
const historyIds = matcher(trimmed);
|
|
465
|
+
if (historyIds.length === 0) return;
|
|
466
|
+
this.#historyIds = historyIds;
|
|
467
|
+
this.#composeFiltered();
|
|
468
|
+
this.onRequestRender?.();
|
|
469
|
+
}, HISTORY_MERGE_DEBOUNCE_MS);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/** Cancel pending async search work; idempotent, called on every picker exit path. */
|
|
473
|
+
dispose(): void {
|
|
474
|
+
this.#scanGeneration++;
|
|
475
|
+
if (this.#scanTimer !== undefined) {
|
|
476
|
+
clearTimeout(this.#scanTimer);
|
|
477
|
+
this.#scanTimer = undefined;
|
|
478
|
+
}
|
|
479
|
+
if (this.#historyMergeTimer !== undefined) {
|
|
480
|
+
clearTimeout(this.#historyMergeTimer);
|
|
481
|
+
this.#historyMergeTimer = undefined;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
removeSession(sessionPath: string): void {
|
|
486
|
+
const index = this.#allSessions.findIndex(s => s.path === sessionPath);
|
|
487
|
+
if (index === -1) return;
|
|
488
|
+
this.#allSessions.splice(index, 1);
|
|
489
|
+
// Re-filter to update filteredSessions
|
|
490
|
+
this.#filterSessions(this.#searchInput.getValue());
|
|
491
|
+
// Adjust selectedIndex if we deleted the last item or beyond
|
|
492
|
+
if (this.#selectedIndex >= this.#filteredSessions.length) {
|
|
493
|
+
this.#selectedIndex = Math.max(0, this.#filteredSessions.length - 1);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/** Resolve a list-local rendered-line index to a filtered-session index. */
|
|
498
|
+
hitTestSession(line: number): number | undefined {
|
|
499
|
+
return this.#hitRows[line];
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/** Wheel notch: move the selection one step (clamped, no wrap). */
|
|
503
|
+
handleWheel(delta: -1 | 1): void {
|
|
504
|
+
if (this.#filteredSessions.length === 0) return;
|
|
505
|
+
this.#selectionMoved = true;
|
|
506
|
+
this.#selectedIndex = Math.max(0, Math.min(this.#filteredSessions.length - 1, this.#selectedIndex + delta));
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/** Mouse click: select the session under the pointer and resume it. */
|
|
510
|
+
selectAndConfirm(index: number): void {
|
|
511
|
+
const session = this.#filteredSessions[index];
|
|
512
|
+
if (!session) return;
|
|
513
|
+
this.#selectedIndex = index;
|
|
514
|
+
this.onSelect?.(session);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
invalidate(): void {
|
|
518
|
+
// No cached state to invalidate currently
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
render(width: number): readonly string[] {
|
|
522
|
+
const lines: string[] = [];
|
|
523
|
+
this.#hitRows = [];
|
|
524
|
+
|
|
525
|
+
// Render search input
|
|
526
|
+
lines.push(...this.#searchInput.render(width));
|
|
527
|
+
lines.push(""); // Blank line after search
|
|
528
|
+
|
|
529
|
+
if (this.#filteredSessions.length === 0) {
|
|
530
|
+
if (this.#showCwd) {
|
|
531
|
+
// "All" scope - no sessions anywhere that match filter
|
|
532
|
+
lines.push(truncateToWidth(theme.fg("muted", " No sessions found"), width));
|
|
533
|
+
} else {
|
|
534
|
+
// "Current folder" scope - hint to try "all"
|
|
535
|
+
lines.push(
|
|
536
|
+
truncateToWidth(theme.fg("muted", " No sessions in current folder. Press Tab to view all."), width),
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
return lines;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Format dates
|
|
543
|
+
const formatDate = (date: Date): string => {
|
|
544
|
+
const now = new Date();
|
|
545
|
+
const diffMs = now.getTime() - date.getTime();
|
|
546
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
547
|
+
const diffHours = Math.floor(diffMs / 3600000);
|
|
548
|
+
const diffDays = Math.floor(diffMs / 86400000);
|
|
549
|
+
|
|
550
|
+
if (diffMins < 1) return "just now";
|
|
551
|
+
if (diffMins < 60) return `${diffMins} minute${diffMins !== 1 ? "s" : ""} ago`;
|
|
552
|
+
if (diffHours < 24) return `${diffHours} hour${diffHours !== 1 ? "s" : ""} ago`;
|
|
553
|
+
if (diffDays === 1) return "1 day ago";
|
|
554
|
+
if (diffDays < 7) return `${diffDays} days ago`;
|
|
555
|
+
|
|
556
|
+
return date.toLocaleDateString();
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
// Calculate visible range with scrolling. The window is sized to the
|
|
560
|
+
// current viewport so the picker never overflows past the top.
|
|
561
|
+
const maxVisible = this.#visibleCount();
|
|
562
|
+
const startIndex = Math.max(
|
|
563
|
+
0,
|
|
564
|
+
Math.min(this.#selectedIndex - Math.floor(maxVisible / 2), this.#filteredSessions.length - maxVisible),
|
|
565
|
+
);
|
|
566
|
+
const endIndex = Math.min(startIndex + maxVisible, this.#filteredSessions.length);
|
|
567
|
+
|
|
568
|
+
// Render visible sessions (3 lines, or 4 when a title adds a preview line).
|
|
569
|
+
// Each session block is built into sessionLines, then wrapped by ScrollView
|
|
570
|
+
// so the right-edge scrollbar is proportional at the physical-line level.
|
|
571
|
+
const sessionLines: string[] = [];
|
|
572
|
+
const sessionRowIndex: number[] = [];
|
|
573
|
+
const overflow = this.#filteredSessions.length > maxVisible;
|
|
574
|
+
const rowWidth = Math.max(0, width - (overflow ? 1 : 0));
|
|
575
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
576
|
+
const blockStart = sessionLines.length;
|
|
577
|
+
const session = this.#filteredSessions[i];
|
|
578
|
+
const isSelected = i === this.#selectedIndex;
|
|
579
|
+
|
|
580
|
+
// Normalize first message to single line
|
|
581
|
+
const normalizedMessage = session.firstMessage.replace(/\n/g, " ").trim();
|
|
582
|
+
|
|
583
|
+
// First line: cursor + title (or first message if no title)
|
|
584
|
+
const cursorSymbol = `${theme.nav.cursor} `;
|
|
585
|
+
const cursorWidth = visibleWidth(cursorSymbol);
|
|
586
|
+
const cursor = isSelected ? theme.fg("accent", cursorSymbol) : padding(cursorWidth);
|
|
587
|
+
const maxWidth = rowWidth - cursorWidth; // Account for cursor width
|
|
588
|
+
|
|
589
|
+
if (session.title) {
|
|
590
|
+
// Has title: show title on first line, dimmed first message on second line
|
|
591
|
+
const truncatedTitle = truncateToWidth(session.title, maxWidth);
|
|
592
|
+
const titleLine = cursor + (isSelected ? theme.bold(truncatedTitle) : truncatedTitle);
|
|
593
|
+
sessionLines.push(titleLine);
|
|
594
|
+
|
|
595
|
+
// Second line: dimmed first message preview
|
|
596
|
+
const truncatedPreview = truncateToWidth(normalizedMessage, maxWidth);
|
|
597
|
+
sessionLines.push(` ${theme.fg("dim", truncatedPreview)}`);
|
|
598
|
+
} else {
|
|
599
|
+
// No title: show first message as main line
|
|
600
|
+
const truncatedMsg = truncateToWidth(normalizedMessage, maxWidth);
|
|
601
|
+
const messageLine = cursor + (isSelected ? theme.bold(truncatedMsg) : truncatedMsg);
|
|
602
|
+
sessionLines.push(messageLine);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Metadata line: date + file size + lifecycle status (+ project dir in
|
|
606
|
+
// all-projects scope). The status segment carries its own color, so each
|
|
607
|
+
// segment is dimmed individually rather than wrapping the whole line.
|
|
608
|
+
const dim = (s: string) => theme.fg("dim", s);
|
|
609
|
+
const dot = dim(theme.sep.dot);
|
|
610
|
+
const modified = formatDate(session.modified);
|
|
611
|
+
let metadata = ` ${dim(modified)} ${dot} ${dim(formatBytes(session.size))}`;
|
|
612
|
+
const status = formatSessionStatus(session.status);
|
|
613
|
+
if (status) {
|
|
614
|
+
metadata += ` ${dot} ${status}`;
|
|
615
|
+
}
|
|
616
|
+
if (session.parentSessionPath) {
|
|
617
|
+
metadata += ` ${dot} ${dim(`${theme.icon.branch} fork`)}`;
|
|
618
|
+
}
|
|
619
|
+
if (this.#showCwd && session.cwd) {
|
|
620
|
+
metadata += ` ${dot} ${dim(shortenPath(session.cwd))}`;
|
|
621
|
+
}
|
|
622
|
+
const metadataLine = truncateToWidth(metadata, rowWidth);
|
|
623
|
+
|
|
624
|
+
sessionLines.push(metadataLine);
|
|
625
|
+
sessionLines.push(""); // Blank line between sessions
|
|
626
|
+
for (let k = blockStart; k < sessionLines.length; k++) sessionRowIndex[k] = i;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Wrap the rendered window in a ScrollView for a proportional right-edge bar.
|
|
630
|
+
const visibleCount = endIndex - startIndex;
|
|
631
|
+
const linesPerItem = visibleCount > 0 ? sessionLines.length / visibleCount : 1;
|
|
632
|
+
const sv = new ScrollView(sessionLines, {
|
|
633
|
+
height: sessionLines.length,
|
|
634
|
+
scrollbar: "auto",
|
|
635
|
+
totalRows: Math.round(this.#filteredSessions.length * linesPerItem),
|
|
636
|
+
theme: { track: t => theme.fg("muted", t), thumb: t => theme.fg("accent", t) },
|
|
637
|
+
});
|
|
638
|
+
sv.setScrollOffset(Math.round(startIndex * linesPerItem));
|
|
639
|
+
const sessionRegionStart = lines.length;
|
|
640
|
+
const svLines = sv.render(width);
|
|
641
|
+
for (let k = 0; k < svLines.length; k++) this.#hitRows[sessionRegionStart + k] = sessionRowIndex[k];
|
|
642
|
+
lines.push(...svLines);
|
|
643
|
+
|
|
644
|
+
return lines;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
handleInput(keyData: string): void {
|
|
648
|
+
// Delete key — or Backspace on an empty search query — request delete
|
|
649
|
+
// confirmation from the parent. macOS laptops have no dedicated Forward
|
|
650
|
+
// Delete key: Fn+Backspace is the only way to send \e[3~, and many macOS
|
|
651
|
+
// terminals (Terminal.app, some iTerm2 profiles) deliver \x7f for that
|
|
652
|
+
// combo instead. Regular Backspace on an empty query means "delete
|
|
653
|
+
// session"; with a typed query it stays bound to the search Input so users
|
|
654
|
+
// can still edit their filter text.
|
|
655
|
+
if (
|
|
656
|
+
matchesKey(keyData, "delete") ||
|
|
657
|
+
(matchesKey(keyData, "backspace") && this.#searchInput.getValue().length === 0)
|
|
658
|
+
) {
|
|
659
|
+
const selected = this.#filteredSessions[this.#selectedIndex];
|
|
660
|
+
if (selected && this.onDeleteRequest) {
|
|
661
|
+
this.onDeleteRequest(selected);
|
|
662
|
+
}
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
// Up arrow
|
|
666
|
+
if (matchesSelectUp(keyData)) {
|
|
667
|
+
this.#selectionMoved = true;
|
|
668
|
+
this.#selectedIndex = Math.max(0, this.#selectedIndex - 1);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
// Down arrow
|
|
672
|
+
if (matchesSelectDown(keyData)) {
|
|
673
|
+
this.#selectionMoved = true;
|
|
674
|
+
this.#selectedIndex = Math.min(this.#filteredSessions.length - 1, this.#selectedIndex + 1);
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
// Page up - jump up by maxVisible items
|
|
678
|
+
if (matchesKey(keyData, "pageUp")) {
|
|
679
|
+
this.#selectionMoved = true;
|
|
680
|
+
this.#selectedIndex = Math.max(0, this.#selectedIndex - this.#visibleCount());
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
// Page down - jump down by maxVisible items
|
|
684
|
+
if (matchesKey(keyData, "pageDown")) {
|
|
685
|
+
this.#selectionMoved = true;
|
|
686
|
+
this.#selectedIndex = Math.min(this.#filteredSessions.length - 1, this.#selectedIndex + this.#visibleCount());
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
// Enter
|
|
690
|
+
if (matchesKey(keyData, "enter") || matchesKey(keyData, "return") || keyData === "\n") {
|
|
691
|
+
const selected = this.#filteredSessions[this.#selectedIndex];
|
|
692
|
+
if (selected && this.onSelect) {
|
|
693
|
+
this.onSelect(selected);
|
|
694
|
+
}
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
// Escape - cancel
|
|
698
|
+
if (matchesAppInterrupt(keyData)) {
|
|
699
|
+
if (this.onCancel) {
|
|
700
|
+
this.onCancel();
|
|
701
|
+
}
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
// Ctrl+C - exit
|
|
705
|
+
if (matchesKey(keyData, "ctrl+c")) {
|
|
706
|
+
this.onExit();
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
// Tab - toggle folder / all-projects scope
|
|
710
|
+
if (matchesKey(keyData, "tab")) {
|
|
711
|
+
this.onToggleScope?.();
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
// Pass everything else to search input
|
|
715
|
+
this.#searchInput.handleInput(keyData);
|
|
716
|
+
this.#filterSessions(this.#searchInput.getValue());
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
export interface SessionSelectorOptions {
|
|
721
|
+
onDelete?: (session: SessionInfo) => Promise<boolean>;
|
|
722
|
+
historyMatcher?: SessionHistoryMatcher;
|
|
723
|
+
/** Loads sessions across all projects for the all-projects scope toggle (Tab). */
|
|
724
|
+
loadAllSessions?: () => Promise<SessionInfo[]>;
|
|
725
|
+
/** Preloaded all-projects list; cached so the first Tab toggle is instant. */
|
|
726
|
+
allSessions?: SessionInfo[];
|
|
727
|
+
/** Picker heading; defaults to "Resume Session". */
|
|
728
|
+
title?: string;
|
|
729
|
+
/** Fixed scope label, or false to omit the scope suffix. */
|
|
730
|
+
scopeLabel?: string | false;
|
|
731
|
+
/** Show each session's working directory in the list. */
|
|
732
|
+
showCwd?: boolean;
|
|
733
|
+
/**
|
|
734
|
+
* Reads the live terminal height so the visible window fits the viewport.
|
|
735
|
+
* Omitted only in tests; defaults to a conservative 24 rows.
|
|
736
|
+
*/
|
|
737
|
+
getTerminalRows?: () => number;
|
|
738
|
+
/**
|
|
739
|
+
* Fill the whole viewport and pin the footer (hint + bottom border) to the
|
|
740
|
+
* last rows, so the footer stops drifting as the list window changes height.
|
|
741
|
+
* Set by the standalone `--resume` picker (fullscreen alternate screen); the
|
|
742
|
+
* in-editor selector leaves it off and renders compactly.
|
|
743
|
+
*/
|
|
744
|
+
fillHeight?: boolean;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Component that renders a session selector with optional confirmation dialog
|
|
749
|
+
*/
|
|
750
|
+
export class SessionSelectorComponent extends Container {
|
|
751
|
+
#sessionList: SessionList;
|
|
752
|
+
#confirmationDialog: HookSelectorComponent | null = null;
|
|
753
|
+
// Hosts whichever of `#sessionList` / `#confirmationDialog` is live this
|
|
754
|
+
// frame. The delete dialog REPLACES the list in this slot rather than being
|
|
755
|
+
// appended below the picker chrome, so the picker is always
|
|
756
|
+
// `chrome + max(list, dialog) + chrome` and never overflows the viewport
|
|
757
|
+
// (issue #3283: an overflowing dialog frame committed the header into
|
|
758
|
+
// scrollback, stranding it above the viewport once the dialog closed).
|
|
759
|
+
#contentSlot: Container;
|
|
760
|
+
#messageContainer: Container;
|
|
761
|
+
#headerText: Text;
|
|
762
|
+
#onDelete?: (session: SessionInfo) => Promise<boolean>;
|
|
763
|
+
#onRequestRender?: () => void;
|
|
764
|
+
readonly #loadAllSessions?: () => Promise<SessionInfo[]>;
|
|
765
|
+
#folderSessions: SessionInfo[];
|
|
766
|
+
#globalSessions: SessionInfo[] | null = null;
|
|
767
|
+
#scope: "folder" | "all" = "folder";
|
|
768
|
+
#toggling = false;
|
|
769
|
+
#inputLocked = false;
|
|
770
|
+
// 0-based line where the session list begins within this component's own
|
|
771
|
+
// render, captured each frame. The fullscreen picker overlay paints from
|
|
772
|
+
// screen row 0, so a mouse row maps to `row - #listLineOffset` inside the
|
|
773
|
+
// list. Only meaningful while the picker holds the alternate screen.
|
|
774
|
+
#listLineOffset = 0;
|
|
775
|
+
// 0-based line where the pinned footer begins; clicks at or below it never
|
|
776
|
+
// hit-test the list, so a footer click on a cramped (trimmed) frame can't
|
|
777
|
+
// resume a session scrolled off-screen.
|
|
778
|
+
#footerStart = 0;
|
|
779
|
+
readonly #getTerminalRows: () => number;
|
|
780
|
+
readonly #fillHeight: boolean;
|
|
781
|
+
readonly #bottomBorder = new DynamicBorder();
|
|
782
|
+
readonly #title: string;
|
|
783
|
+
readonly #scopeLabel: string | false | undefined;
|
|
784
|
+
|
|
785
|
+
constructor(
|
|
786
|
+
sessions: SessionInfo[],
|
|
787
|
+
onSelect: (session: SessionInfo) => void,
|
|
788
|
+
onCancel: () => void,
|
|
789
|
+
onExit: () => void,
|
|
790
|
+
options: SessionSelectorOptions = {},
|
|
791
|
+
) {
|
|
792
|
+
super();
|
|
793
|
+
|
|
794
|
+
this.#messageContainer = new Container();
|
|
795
|
+
this.#onDelete = options.onDelete;
|
|
796
|
+
this.#loadAllSessions = options.loadAllSessions;
|
|
797
|
+
this.#folderSessions = sessions;
|
|
798
|
+
this.#globalSessions = options.allSessions ?? null;
|
|
799
|
+
this.#getTerminalRows = options.getTerminalRows ?? (() => 24);
|
|
800
|
+
this.#fillHeight = options.fillHeight ?? false;
|
|
801
|
+
this.#title = options.title ?? "Resume Session";
|
|
802
|
+
this.#scopeLabel = options.scopeLabel;
|
|
803
|
+
// Add header
|
|
804
|
+
this.addChild(new Spacer(1));
|
|
805
|
+
this.#headerText = new Text(this.#headerLabel(), 1, 0);
|
|
806
|
+
this.addChild(this.#headerText);
|
|
807
|
+
this.addChild(new Spacer(1));
|
|
808
|
+
this.addChild(new DynamicBorder());
|
|
809
|
+
this.addChild(new Spacer(1));
|
|
810
|
+
this.addChild(this.#messageContainer);
|
|
811
|
+
// Create session list in folder scope; the empty-state hint invites the
|
|
812
|
+
// user to Tab into all-projects rather than silently surfacing other
|
|
813
|
+
// projects' history (issue #3099).
|
|
814
|
+
this.#sessionList = new SessionList(
|
|
815
|
+
sessions,
|
|
816
|
+
options.showCwd ?? false,
|
|
817
|
+
options.historyMatcher,
|
|
818
|
+
options.getTerminalRows,
|
|
819
|
+
);
|
|
820
|
+
// Every exit path cancels the list's pending history merge, so a stale
|
|
821
|
+
// debounce timer can never run its SQLite lookup after the picker closed.
|
|
822
|
+
this.#sessionList.onSelect = session => {
|
|
823
|
+
this.#sessionList.dispose();
|
|
824
|
+
onSelect(session);
|
|
825
|
+
};
|
|
826
|
+
this.#sessionList.onCancel = () => {
|
|
827
|
+
this.#sessionList.dispose();
|
|
828
|
+
onCancel();
|
|
829
|
+
};
|
|
830
|
+
this.#sessionList.onExit = () => {
|
|
831
|
+
this.#sessionList.dispose();
|
|
832
|
+
onExit();
|
|
833
|
+
};
|
|
834
|
+
this.#sessionList.onRequestRender = () => this.#onRequestRender?.();
|
|
835
|
+
this.#sessionList.onDeleteRequest = (session: SessionInfo) => {
|
|
836
|
+
this.#showDeleteConfirmation(session);
|
|
837
|
+
};
|
|
838
|
+
if (this.#loadAllSessions || this.#globalSessions) {
|
|
839
|
+
this.#sessionList.onToggleScope = () => {
|
|
840
|
+
void this.#toggleScope();
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
this.#contentSlot = new Container();
|
|
844
|
+
this.#contentSlot.addChild(this.#sessionList);
|
|
845
|
+
this.addChild(this.#contentSlot);
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
#headerLabel(): string {
|
|
849
|
+
if (this.#scopeLabel === false) return theme.bold(this.#title);
|
|
850
|
+
const scopeLabel = this.#scopeLabel ?? (this.#scope === "all" ? "all projects" : "current folder");
|
|
851
|
+
return `${theme.bold(this.#title)} ${theme.fg("muted", `(${scopeLabel})`)}`;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Toggle between current-folder and all-projects scope. The global list is
|
|
856
|
+
* loaded lazily on first switch and cached, so the common folder-scope path
|
|
857
|
+
* never pays for the cross-project scan.
|
|
858
|
+
*/
|
|
859
|
+
async #toggleScope(): Promise<void> {
|
|
860
|
+
if (this.#toggling || this.#confirmationDialog) return;
|
|
861
|
+
if (this.#scope === "folder") {
|
|
862
|
+
let global = this.#globalSessions;
|
|
863
|
+
if (!global) {
|
|
864
|
+
if (!this.#loadAllSessions) return;
|
|
865
|
+
this.#toggling = true;
|
|
866
|
+
this.#messageContainer.clear();
|
|
867
|
+
this.#messageContainer.addChild(new Text(theme.fg("muted", " Loading all projects…"), 1, 0));
|
|
868
|
+
this.#onRequestRender?.();
|
|
869
|
+
try {
|
|
870
|
+
global = await this.#loadAllSessions();
|
|
871
|
+
} catch (err) {
|
|
872
|
+
this.#showError(err instanceof Error ? err.message : String(err));
|
|
873
|
+
this.#toggling = false;
|
|
874
|
+
this.#onRequestRender?.();
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
this.#globalSessions = global;
|
|
878
|
+
this.#messageContainer.clear();
|
|
879
|
+
this.#toggling = false;
|
|
880
|
+
}
|
|
881
|
+
this.#scope = "all";
|
|
882
|
+
this.#sessionList.setSessions(global, true);
|
|
883
|
+
} else {
|
|
884
|
+
this.#scope = "folder";
|
|
885
|
+
this.#sessionList.setSessions(this.#folderSessions, false);
|
|
886
|
+
}
|
|
887
|
+
this.#headerText.setText(this.#headerLabel());
|
|
888
|
+
this.#onRequestRender?.();
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
setOnRequestRender(callback: () => void): void {
|
|
892
|
+
this.#onRequestRender = callback;
|
|
893
|
+
}
|
|
894
|
+
/** Ignore input after selection while the host resumes the session. */
|
|
895
|
+
lockInput(): void {
|
|
896
|
+
this.#inputLocked = true;
|
|
897
|
+
}
|
|
898
|
+
/** Re-enable input after a failed resume so the user can pick again. */
|
|
899
|
+
unlockInput(): void {
|
|
900
|
+
this.#inputLocked = false;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Dispose the session list explicitly: while the delete-confirmation dialog
|
|
905
|
+
* is mounted the list is detached from the child tree, so Container's
|
|
906
|
+
* child-walking dispose would miss its pending history-merge timer.
|
|
907
|
+
*/
|
|
908
|
+
override dispose(): void {
|
|
909
|
+
this.#sessionList.dispose();
|
|
910
|
+
super.dispose();
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
#clearError(): void {
|
|
914
|
+
this.#messageContainer.clear();
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
#showError(message: string): void {
|
|
918
|
+
this.#messageContainer.clear();
|
|
919
|
+
this.#messageContainer.addChild(new Text(theme.fg("error", `Error: ${replaceTabs(message)}`), 1, 0));
|
|
920
|
+
this.#messageContainer.addChild(new Spacer(1));
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
#showDeleteConfirmation(session: SessionInfo): void {
|
|
924
|
+
const displayName = session.title || session.firstMessage.slice(0, 40) || session.id;
|
|
925
|
+
const closeDialog = () => {
|
|
926
|
+
this.#confirmationDialog = null;
|
|
927
|
+
// Restore the SessionList into the content slot so the picker is back
|
|
928
|
+
// to its normal layout on the very next render — the same frame the
|
|
929
|
+
// dialog disappears.
|
|
930
|
+
this.#contentSlot.clear();
|
|
931
|
+
this.#contentSlot.addChild(this.#sessionList);
|
|
932
|
+
this.#onRequestRender?.();
|
|
933
|
+
};
|
|
934
|
+
this.#confirmationDialog = new HookSelectorComponent(
|
|
935
|
+
`Delete session?\n${displayName}`,
|
|
936
|
+
["Yes", "No"],
|
|
937
|
+
async (option: string) => {
|
|
938
|
+
if (option === "Yes" && this.#onDelete) {
|
|
939
|
+
this.#clearError();
|
|
940
|
+
try {
|
|
941
|
+
const deleted = await this.#onDelete(session);
|
|
942
|
+
if (deleted) {
|
|
943
|
+
this.#sessionList.removeSession(session.path);
|
|
944
|
+
}
|
|
945
|
+
} catch (err) {
|
|
946
|
+
this.#showError(err instanceof Error ? err.message : String(err));
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
closeDialog();
|
|
950
|
+
},
|
|
951
|
+
closeDialog,
|
|
952
|
+
);
|
|
953
|
+
// Swap the SessionList out of the content slot and mount the dialog in its
|
|
954
|
+
// place: the dialog competes only with the SessionList's rendered budget,
|
|
955
|
+
// never the SessionList AND the picker chrome, so the picker frame stays
|
|
956
|
+
// inside the terminal viewport and the TUI never commits the header into
|
|
957
|
+
// scrollback (issue #3283).
|
|
958
|
+
this.#contentSlot.clear();
|
|
959
|
+
this.#contentSlot.addChild(this.#confirmationDialog);
|
|
960
|
+
this.#onRequestRender?.();
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* Concatenate the children's renders (like {@link Container}) while recording
|
|
965
|
+
* the line where the session list begins, so the fullscreen picker can hit-
|
|
966
|
+
* test mouse rows against the live list window. SessionList rebuilds its lines
|
|
967
|
+
* every frame, so Container's reference-memoization never applied here.
|
|
968
|
+
*
|
|
969
|
+
* In fill-height mode the body is padded (or, on a cramped terminal, trimmed)
|
|
970
|
+
* to leave exactly enough room for the footer at the screen bottom, so the
|
|
971
|
+
* footer is always visible and never drifts as the list window resizes. The
|
|
972
|
+
* in-editor selector just appends the footer directly.
|
|
973
|
+
*/
|
|
974
|
+
override render(width: number): readonly string[] {
|
|
975
|
+
const lines: string[] = [];
|
|
976
|
+
for (const child of this.children) {
|
|
977
|
+
const childLines = child.render(width);
|
|
978
|
+
if (child === this.#contentSlot) this.#listLineOffset = lines.length;
|
|
979
|
+
for (const line of childLines) lines.push(line);
|
|
980
|
+
}
|
|
981
|
+
const footer = this.#footerLines(width);
|
|
982
|
+
if (this.#fillHeight) {
|
|
983
|
+
const target = Math.max(0, this.#getTerminalRows() - footer.length);
|
|
984
|
+
if (lines.length > target) lines.length = target;
|
|
985
|
+
else for (let i = lines.length; i < target; i++) lines.push("");
|
|
986
|
+
}
|
|
987
|
+
this.#footerStart = lines.length;
|
|
988
|
+
for (const line of footer) lines.push(line);
|
|
989
|
+
return lines;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/** Blank · keybinding hint · bottom border. Rendered by {@link render}. */
|
|
993
|
+
#footerLines(width: number): string[] {
|
|
994
|
+
const scopeHint = this.#scope === "all" ? "current folder" : "all projects";
|
|
995
|
+
const hint = theme.fg("muted", ` [Del/⌫ delete · Enter select · Tab ${scopeHint} · Esc cancel]`);
|
|
996
|
+
return ["", hint, "", ...this.#bottomBorder.render(width)];
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
handleInput(keyData: string): void {
|
|
1000
|
+
if (this.#inputLocked) return;
|
|
1001
|
+
if (keyData.startsWith("\x1b[<")) {
|
|
1002
|
+
this.#handleMouse(keyData);
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
if (this.#confirmationDialog) {
|
|
1006
|
+
this.#confirmationDialog.handleInput(keyData);
|
|
1007
|
+
} else {
|
|
1008
|
+
this.#sessionList.handleInput(keyData);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* SGR mouse reports, delivered only while the picker holds the alternate
|
|
1014
|
+
* screen (the fullscreen overlay enables tracking and paints from screen row
|
|
1015
|
+
* 0). Wheel scrolls the list; a left click resumes the session under the
|
|
1016
|
+
* pointer. Mouse is inert while the delete-confirmation dialog is open.
|
|
1017
|
+
*/
|
|
1018
|
+
#handleMouse(data: string): void {
|
|
1019
|
+
if (this.#confirmationDialog) return;
|
|
1020
|
+
routeSgrMouseInput(data, event => {
|
|
1021
|
+
if (event.wheel !== null) {
|
|
1022
|
+
this.#sessionList.handleWheel(event.wheel);
|
|
1023
|
+
return true;
|
|
1024
|
+
}
|
|
1025
|
+
if (!event.leftClick || event.row >= this.#footerStart) return true;
|
|
1026
|
+
const index = this.#sessionList.hitTestSession(event.row - this.#listLineOffset);
|
|
1027
|
+
if (index !== undefined) this.#sessionList.selectAndConfirm(index);
|
|
1028
|
+
return true;
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
getSessionList(): SessionList {
|
|
1033
|
+
return this.#sessionList;
|
|
1034
|
+
}
|
|
1035
|
+
}
|