@wahack/pi-coding-agent 15.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10031 -0
- package/README.md +36 -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 +79 -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 +172 -0
- package/package.json +554 -0
- package/scripts/build-binary.ts +100 -0
- package/scripts/bundle-dist.ts +90 -0
- package/scripts/format-prompts.ts +68 -0
- package/scripts/generate-docs-index.ts +40 -0
- package/scripts/generate-template.ts +33 -0
- package/scripts/omp +42 -0
- package/scripts/omp.ts +19 -0
- package/src/async/index.ts +1 -0
- package/src/async/job-manager.ts +625 -0
- package/src/auto-thinking/classifier.ts +185 -0
- package/src/autoresearch/command-resume.md +14 -0
- package/src/autoresearch/dashboard.ts +436 -0
- package/src/autoresearch/git.ts +319 -0
- package/src/autoresearch/helpers.ts +218 -0
- package/src/autoresearch/index.ts +536 -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 +699 -0
- package/src/autoresearch/tools/init-experiment.ts +272 -0
- package/src/autoresearch/tools/log-experiment.ts +524 -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/bun-imports.d.ts +28 -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 +436 -0
- package/src/capability/instruction.ts +37 -0
- package/src/capability/mcp.ts +74 -0
- package/src/capability/prompt.ts +35 -0
- package/src/capability/rule-buckets.ts +66 -0
- package/src/capability/rule.ts +261 -0
- package/src/capability/settings.ts +34 -0
- package/src/capability/skill.ts +63 -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 +168 -0
- package/src/cli/agents-cli.ts +138 -0
- package/src/cli/args.ts +340 -0
- package/src/cli/auth-broker-cli.ts +895 -0
- package/src/cli/auth-gateway-cli.ts +611 -0
- package/src/cli/classify-install-target.ts +76 -0
- package/src/cli/claude-trace-cli.ts +795 -0
- package/src/cli/commands/init-xdg.ts +27 -0
- package/src/cli/completion-gen.ts +550 -0
- package/src/cli/config-cli.ts +418 -0
- package/src/cli/dry-balance-cli.ts +856 -0
- package/src/cli/extension-flags.ts +48 -0
- package/src/cli/file-processor.ts +133 -0
- package/src/cli/gallery-cli.ts +230 -0
- package/src/cli/gallery-fixtures/agentic.ts +407 -0
- package/src/cli/gallery-fixtures/codeintel.ts +187 -0
- package/src/cli/gallery-fixtures/edit.ts +194 -0
- package/src/cli/gallery-fixtures/fs.ts +220 -0
- package/src/cli/gallery-fixtures/index.ts +40 -0
- package/src/cli/gallery-fixtures/interaction.ts +49 -0
- package/src/cli/gallery-fixtures/memory.ts +81 -0
- package/src/cli/gallery-fixtures/misc.ts +250 -0
- package/src/cli/gallery-fixtures/search.ts +213 -0
- package/src/cli/gallery-fixtures/shell.ts +167 -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/grep-cli.ts +160 -0
- package/src/cli/grievances-cli.ts +256 -0
- package/src/cli/initial-message.ts +58 -0
- package/src/cli/list-models.ts +194 -0
- package/src/cli/plugin-cli.ts +996 -0
- package/src/cli/read-cli.ts +57 -0
- package/src/cli/session-picker.ts +79 -0
- package/src/cli/setup-cli.ts +231 -0
- package/src/cli/shell-cli.ts +176 -0
- package/src/cli/ssh-cli.ts +179 -0
- package/src/cli/startup-cwd.ts +68 -0
- package/src/cli/stats-cli.ts +238 -0
- package/src/cli/tiny-models-cli.ts +127 -0
- package/src/cli/update-cli.ts +611 -0
- package/src/cli/usage-cli.ts +603 -0
- package/src/cli/web-search-cli.ts +132 -0
- package/src/cli/worktree-cli.ts +291 -0
- package/src/cli-commands.ts +79 -0
- package/src/cli.ts +200 -0
- package/src/commands/acp.ts +24 -0
- package/src/commands/agents.ts +57 -0
- package/src/commands/auth-broker.ts +99 -0
- package/src/commands/auth-gateway.ts +69 -0
- package/src/commands/commit.ts +46 -0
- package/src/commands/complete.ts +66 -0
- package/src/commands/completions.ts +60 -0
- package/src/commands/config.ts +51 -0
- package/src/commands/dry-balance.ts +43 -0
- package/src/commands/gallery.ts +52 -0
- package/src/commands/grep.ts +48 -0
- package/src/commands/grievances.ts +51 -0
- package/src/commands/install.ts +107 -0
- package/src/commands/launch.ts +169 -0
- package/src/commands/plugin.ts +78 -0
- package/src/commands/read.ts +38 -0
- package/src/commands/setup.ts +67 -0
- package/src/commands/shell.ts +29 -0
- package/src/commands/ssh.ts +60 -0
- package/src/commands/stats.ts +29 -0
- package/src/commands/tiny-models.ts +36 -0
- package/src/commands/update.ts +21 -0
- package/src/commands/usage.ts +35 -0
- package/src/commands/web-search.ts +42 -0
- package/src/commands/worktree.ts +56 -0
- package/src/commit/agentic/agent.ts +317 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +355 -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 +146 -0
- package/src/commit/agentic/tools/git-file-diff.ts +191 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +81 -0
- package/src/commit/agentic/tools/index.ts +54 -0
- package/src/commit/agentic/tools/propose-changelog.ts +144 -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 +23 -0
- package/src/commit/agentic/tools/split-commit.ts +245 -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 +105 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +40 -0
- package/src/commit/changelog/generate.ts +97 -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 +92 -0
- package/src/commit/pipeline.ts +243 -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 +77 -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 +60 -0
- package/src/config/append-only-context-mode.ts +31 -0
- package/src/config/config-file.ts +317 -0
- package/src/config/file-lock.ts +164 -0
- package/src/config/keybindings.ts +628 -0
- package/src/config/mcp-schema.json +230 -0
- package/src/config/model-discovery.ts +554 -0
- package/src/config/model-registry.ts +2090 -0
- package/src/config/model-resolver.ts +1502 -0
- package/src/config/model-roles.ts +74 -0
- package/src/config/models-config-schema.ts +226 -0
- package/src/config/models-config.ts +129 -0
- package/src/config/prompt-templates.ts +185 -0
- package/src/config/resolve-config-value.ts +94 -0
- package/src/config/settings-schema.ts +3530 -0
- package/src/config/settings.ts +1178 -0
- package/src/config.ts +242 -0
- package/src/cursor.ts +340 -0
- package/src/dap/client.ts +760 -0
- package/src/dap/config.ts +189 -0
- package/src/dap/defaults.json +212 -0
- package/src/dap/index.ts +4 -0
- package/src/dap/session.ts +1441 -0
- package/src/dap/types.ts +610 -0
- package/src/debug/index.ts +515 -0
- package/src/debug/log-formatting.ts +58 -0
- package/src/debug/log-viewer.ts +908 -0
- package/src/debug/profiler.ts +162 -0
- package/src/debug/protocol-probe.ts +267 -0
- package/src/debug/raw-sse-buffer.ts +273 -0
- package/src/debug/raw-sse.ts +292 -0
- package/src/debug/report-bundle.ts +374 -0
- package/src/debug/system-info.ts +111 -0
- package/src/debug/terminal-info.ts +124 -0
- package/src/discovery/agents-md.ts +67 -0
- package/src/discovery/agents.ts +230 -0
- package/src/discovery/at-imports.ts +273 -0
- package/src/discovery/builtin-defaults.ts +39 -0
- package/src/discovery/builtin-rules/index.ts +54 -0
- package/src/discovery/builtin-rules/rs-box-leak.md +48 -0
- package/src/discovery/builtin-rules/rs-future-prelude.md +23 -0
- package/src/discovery/builtin-rules/rs-lazylock.md +51 -0
- package/src/discovery/builtin-rules/rs-match-ergonomics.md +67 -0
- package/src/discovery/builtin-rules/rs-parking-lot.md +44 -0
- package/src/discovery/builtin-rules/rs-result-type.md +19 -0
- package/src/discovery/builtin-rules/ts-bare-catch.md +38 -0
- package/src/discovery/builtin-rules/ts-import-type.md +42 -0
- package/src/discovery/builtin-rules/ts-no-any.md +56 -0
- package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +44 -0
- package/src/discovery/builtin-rules/ts-no-dynamic-import.md +39 -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 +65 -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 +906 -0
- package/src/discovery/claude-plugins.ts +386 -0
- package/src/discovery/claude.ts +584 -0
- package/src/discovery/cline.ts +83 -0
- package/src/discovery/codex.ts +522 -0
- package/src/discovery/cursor.ts +220 -0
- package/src/discovery/gemini.ts +383 -0
- package/src/discovery/github.ts +154 -0
- package/src/discovery/helpers.ts +1016 -0
- package/src/discovery/index.ts +81 -0
- package/src/discovery/mcp-json.ts +171 -0
- package/src/discovery/omp-extension-roots.ts +190 -0
- package/src/discovery/omp-plugins.ts +383 -0
- package/src/discovery/opencode.ts +398 -0
- package/src/discovery/plugin-dir-roots.ts +28 -0
- package/src/discovery/ssh.ts +153 -0
- package/src/discovery/substitute-plugin-root.ts +29 -0
- package/src/discovery/vscode.ts +105 -0
- package/src/discovery/windsurf.ts +147 -0
- package/src/edit/apply-patch/index.ts +87 -0
- package/src/edit/apply-patch/parser.ts +174 -0
- package/src/edit/diff.ts +999 -0
- package/src/edit/file-snapshot-store.ts +91 -0
- package/src/edit/hashline/block-resolver.ts +33 -0
- package/src/edit/hashline/diff.ts +290 -0
- package/src/edit/hashline/execute.ts +242 -0
- package/src/edit/hashline/filesystem.ts +130 -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 +18 -0
- package/src/edit/index.ts +571 -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 +1891 -0
- package/src/edit/modes/replace.ts +1137 -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 +769 -0
- package/src/edit/streaming.ts +517 -0
- package/src/eval/__tests__/agent-bridge.test.ts +708 -0
- package/src/eval/__tests__/bridge-timeout.test.ts +64 -0
- package/src/eval/__tests__/budget-bridge.test.ts +69 -0
- package/src/eval/__tests__/completion-bridge.test.ts +412 -0
- package/src/eval/__tests__/helpers-local-roots.test.ts +58 -0
- package/src/eval/__tests__/idle-timeout.test.ts +80 -0
- package/src/eval/__tests__/js-context-manager.test.ts +241 -0
- package/src/eval/__tests__/kernel-spawn.test.ts +103 -0
- package/src/eval/agent-bridge.ts +319 -0
- package/src/eval/backend.ts +71 -0
- package/src/eval/bridge-timeout.ts +44 -0
- package/src/eval/budget-bridge.ts +48 -0
- package/src/eval/completion-bridge.ts +207 -0
- package/src/eval/concurrency-bridge.ts +34 -0
- package/src/eval/idle-timeout.ts +91 -0
- package/src/eval/index.ts +4 -0
- package/src/eval/js/context-manager.ts +502 -0
- package/src/eval/js/executor.ts +173 -0
- package/src/eval/js/index.ts +51 -0
- package/src/eval/js/shared/helpers.ts +283 -0
- package/src/eval/js/shared/indirect-eval.ts +30 -0
- package/src/eval/js/shared/local-module-loader.ts +342 -0
- package/src/eval/js/shared/prelude.ts +2 -0
- package/src/eval/js/shared/prelude.txt +246 -0
- package/src/eval/js/shared/rewrite-imports.ts +532 -0
- package/src/eval/js/shared/runtime.ts +352 -0
- package/src/eval/js/shared/types.ts +18 -0
- package/src/eval/js/tool-bridge.ts +162 -0
- package/src/eval/js/worker-core.ts +132 -0
- package/src/eval/js/worker-entry.ts +30 -0
- package/src/eval/js/worker-protocol.ts +47 -0
- package/src/eval/py/__tests__/prelude.test.ts +19 -0
- package/src/eval/py/display.ts +71 -0
- package/src/eval/py/executor.ts +742 -0
- package/src/eval/py/index.ts +68 -0
- package/src/eval/py/kernel.ts +748 -0
- package/src/eval/py/prelude.py +658 -0
- package/src/eval/py/prelude.ts +3 -0
- package/src/eval/py/runner.py +1133 -0
- package/src/eval/py/runtime.ts +276 -0
- package/src/eval/py/spawn-options.ts +126 -0
- package/src/eval/py/tool-bridge.ts +182 -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 +419 -0
- package/src/exec/exec.ts +53 -0
- package/src/exec/non-interactive-env.ts +48 -0
- package/src/export/custom-share.ts +65 -0
- package/src/export/html/index.ts +164 -0
- package/src/export/html/template.css +1051 -0
- package/src/export/html/template.generated.ts +2 -0
- package/src/export/html/template.html +46 -0
- package/src/export/html/template.js +2271 -0
- package/src/export/html/template.macro.ts +25 -0
- package/src/export/html/vendor/highlight.min.js +1213 -0
- package/src/export/html/vendor/marked.min.js +6 -0
- package/src/export/ttsr.ts +583 -0
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
- package/src/extensibility/custom-commands/bundled/review/index.ts +489 -0
- package/src/extensibility/custom-commands/index.ts +2 -0
- package/src/extensibility/custom-commands/loader.ts +238 -0
- package/src/extensibility/custom-commands/types.ts +113 -0
- package/src/extensibility/custom-tools/index.ts +7 -0
- package/src/extensibility/custom-tools/loader.ts +269 -0
- package/src/extensibility/custom-tools/types.ts +270 -0
- package/src/extensibility/custom-tools/wrapper.ts +47 -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/loader.ts +572 -0
- package/src/extensibility/extensions/runner.ts +922 -0
- package/src/extensibility/extensions/types.ts +1322 -0
- package/src/extensibility/extensions/wrapper.ts +223 -0
- package/src/extensibility/hooks/index.ts +5 -0
- package/src/extensibility/hooks/loader.ts +257 -0
- package/src/extensibility/hooks/runner.ts +425 -0
- package/src/extensibility/hooks/tool-wrapper.ts +107 -0
- package/src/extensibility/hooks/types.ts +606 -0
- package/src/extensibility/legacy-pi-ai-shim.ts +24 -0
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +15 -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 +192 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +682 -0
- package/src/extensibility/plugins/loader.ts +313 -0
- package/src/extensibility/plugins/manager.ts +827 -0
- package/src/extensibility/plugins/marketplace/cache.ts +136 -0
- package/src/extensibility/plugins/marketplace/fetcher.ts +317 -0
- package/src/extensibility/plugins/marketplace/index.ts +6 -0
- package/src/extensibility/plugins/marketplace/manager.ts +770 -0
- package/src/extensibility/plugins/marketplace/registry.ts +196 -0
- package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
- package/src/extensibility/plugins/marketplace/types.ts +191 -0
- package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
- package/src/extensibility/plugins/parser.ts +105 -0
- package/src/extensibility/plugins/types.ts +194 -0
- package/src/extensibility/shared-events.ts +343 -0
- package/src/extensibility/skills.ts +312 -0
- package/src/extensibility/slash-commands.ts +227 -0
- package/src/extensibility/tool-proxy.ts +25 -0
- package/src/extensibility/typebox.ts +418 -0
- package/src/extensibility/utils.ts +44 -0
- package/src/goals/index.ts +3 -0
- package/src/goals/runtime.ts +528 -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 +598 -0
- package/src/hindsight/config.ts +175 -0
- package/src/hindsight/content.ts +210 -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 +488 -0
- package/src/hindsight/transcript.ts +71 -0
- package/src/index.ts +59 -0
- package/src/internal-urls/agent-protocol.ts +146 -0
- package/src/internal-urls/artifact-protocol.ts +107 -0
- package/src/internal-urls/docs-index.generated.ts +106 -0
- package/src/internal-urls/history-protocol.ts +113 -0
- package/src/internal-urls/index.ts +25 -0
- package/src/internal-urls/issue-pr-protocol.ts +584 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/local-protocol.ts +287 -0
- package/src/internal-urls/mcp-protocol.ts +151 -0
- package/src/internal-urls/memory-protocol.ts +169 -0
- package/src/internal-urls/omp-protocol.ts +93 -0
- package/src/internal-urls/parse.ts +72 -0
- package/src/internal-urls/registry-helpers.ts +25 -0
- package/src/internal-urls/router.ts +105 -0
- package/src/internal-urls/rule-protocol.ts +45 -0
- package/src/internal-urls/skill-protocol.ts +96 -0
- package/src/internal-urls/types.ts +152 -0
- package/src/internal-urls/vault-protocol.ts +936 -0
- package/src/irc/bus.ts +292 -0
- package/src/lib/xai-http.ts +124 -0
- package/src/lsp/client.ts +1193 -0
- package/src/lsp/clients/biome-client.ts +264 -0
- package/src/lsp/clients/index.ts +50 -0
- package/src/lsp/clients/lsp-linter-client.ts +93 -0
- package/src/lsp/clients/swiftlint-client.ts +120 -0
- package/src/lsp/config.ts +502 -0
- package/src/lsp/defaults.json +493 -0
- package/src/lsp/diagnostics-ledger.ts +51 -0
- package/src/lsp/edits.ts +267 -0
- package/src/lsp/index.ts +2477 -0
- package/src/lsp/lspmux.ts +233 -0
- package/src/lsp/render.ts +694 -0
- package/src/lsp/startup-events.ts +13 -0
- package/src/lsp/types.ts +455 -0
- package/src/lsp/utils.ts +718 -0
- package/src/main.ts +1325 -0
- package/src/mcp/client.ts +484 -0
- package/src/mcp/config-writer.ts +225 -0
- package/src/mcp/config.ts +365 -0
- package/src/mcp/index.ts +29 -0
- package/src/mcp/json-rpc.ts +122 -0
- package/src/mcp/loader.ts +124 -0
- package/src/mcp/manager.ts +1275 -0
- package/src/mcp/oauth-discovery.ts +442 -0
- package/src/mcp/oauth-flow.ts +442 -0
- package/src/mcp/render.ts +132 -0
- package/src/mcp/smithery-auth.ts +104 -0
- package/src/mcp/smithery-connect.ts +145 -0
- package/src/mcp/smithery-registry.ts +477 -0
- package/src/mcp/timeout.ts +59 -0
- package/src/mcp/tool-bridge.ts +426 -0
- package/src/mcp/tool-cache.ts +117 -0
- package/src/mcp/transports/http.ts +519 -0
- package/src/mcp/transports/index.ts +6 -0
- package/src/mcp/transports/stdio.ts +528 -0
- package/src/mcp/types.ts +423 -0
- package/src/memories/index.ts +1150 -0
- package/src/memories/storage.ts +577 -0
- package/src/memory-backend/index.ts +18 -0
- package/src/memory-backend/local-backend.ts +39 -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/types.ts +166 -0
- package/src/mnemopi/backend.ts +547 -0
- package/src/mnemopi/config.ts +160 -0
- package/src/mnemopi/index.ts +3 -0
- package/src/mnemopi/state.ts +584 -0
- package/src/modes/acp/acp-agent.ts +2407 -0
- package/src/modes/acp/acp-client-bridge.ts +154 -0
- package/src/modes/acp/acp-event-mapper.ts +929 -0
- package/src/modes/acp/acp-mode.ts +23 -0
- package/src/modes/acp/index.ts +2 -0
- package/src/modes/acp/terminal-auth.ts +37 -0
- package/src/modes/components/agent-dashboard.ts +1206 -0
- package/src/modes/components/agent-hub.ts +1071 -0
- package/src/modes/components/assistant-message.ts +307 -0
- package/src/modes/components/bash-execution.ts +220 -0
- package/src/modes/components/bordered-loader.ts +41 -0
- package/src/modes/components/branch-summary-message.ts +45 -0
- package/src/modes/components/btw-panel.ts +104 -0
- package/src/modes/components/chat-block.ts +111 -0
- package/src/modes/components/compaction-summary-message.ts +87 -0
- package/src/modes/components/copy-selector.ts +206 -0
- package/src/modes/components/countdown-timer.ts +75 -0
- package/src/modes/components/custom-editor.ts +398 -0
- package/src/modes/components/custom-message.ts +63 -0
- package/src/modes/components/diff.ts +277 -0
- package/src/modes/components/dynamic-border.ts +34 -0
- package/src/modes/components/error-banner.ts +33 -0
- package/src/modes/components/eval-execution.ts +158 -0
- package/src/modes/components/execution-shared.ts +101 -0
- package/src/modes/components/extensions/extension-dashboard.ts +399 -0
- package/src/modes/components/extensions/extension-list.ts +502 -0
- package/src/modes/components/extensions/index.ts +9 -0
- package/src/modes/components/extensions/inspector-panel.ts +317 -0
- package/src/modes/components/extensions/state-manager.ts +627 -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 +280 -0
- package/src/modes/components/hook-editor.ts +167 -0
- package/src/modes/components/hook-input.ts +87 -0
- package/src/modes/components/hook-message.ts +66 -0
- package/src/modes/components/hook-selector.ts +660 -0
- package/src/modes/components/index.ts +38 -0
- package/src/modes/components/keybinding-hints.ts +65 -0
- package/src/modes/components/late-diagnostics-message.ts +60 -0
- package/src/modes/components/login-dialog.ts +164 -0
- package/src/modes/components/mcp-add-wizard.ts +1340 -0
- package/src/modes/components/message-frame.ts +88 -0
- package/src/modes/components/model-selector.ts +1271 -0
- package/src/modes/components/oauth-selector.ts +368 -0
- package/src/modes/components/omfg-panel.ts +141 -0
- package/src/modes/components/overlay-box.ts +108 -0
- package/src/modes/components/plan-review-overlay.ts +820 -0
- package/src/modes/components/plan-toc.ts +138 -0
- package/src/modes/components/plugin-selector.ts +95 -0
- package/src/modes/components/plugin-settings.ts +722 -0
- package/src/modes/components/queue-mode-selector.ts +56 -0
- package/src/modes/components/read-tool-group.ts +670 -0
- package/src/modes/components/segment-track.ts +52 -0
- package/src/modes/components/session-selector.ts +625 -0
- package/src/modes/components/settings-defs.ts +189 -0
- package/src/modes/components/settings-selector.ts +651 -0
- package/src/modes/components/show-images-selector.ts +45 -0
- package/src/modes/components/skill-message.ts +89 -0
- package/src/modes/components/status-line/component.ts +869 -0
- package/src/modes/components/status-line/context-thresholds.ts +79 -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 +584 -0
- package/src/modes/components/status-line/separators.ts +55 -0
- package/src/modes/components/status-line/token-rate.ts +66 -0
- package/src/modes/components/status-line/types.ts +108 -0
- package/src/modes/components/theme-selector.ts +63 -0
- package/src/modes/components/thinking-selector.ts +52 -0
- package/src/modes/components/tiny-title-download-progress.ts +90 -0
- package/src/modes/components/tips.txt +19 -0
- package/src/modes/components/todo-reminder.ts +38 -0
- package/src/modes/components/tool-execution.ts +1024 -0
- package/src/modes/components/transcript-container.ts +608 -0
- package/src/modes/components/tree-selector.ts +978 -0
- package/src/modes/components/ttsr-notification.ts +122 -0
- package/src/modes/components/user-message-selector.ts +227 -0
- package/src/modes/components/user-message.ts +66 -0
- package/src/modes/components/visual-truncate.ts +63 -0
- package/src/modes/components/welcome.ts +493 -0
- package/src/modes/controllers/btw-controller.ts +105 -0
- package/src/modes/controllers/command-controller-shared.ts +109 -0
- package/src/modes/controllers/command-controller.ts +1566 -0
- package/src/modes/controllers/event-controller.ts +1054 -0
- package/src/modes/controllers/extension-ui-controller.ts +886 -0
- package/src/modes/controllers/input-controller.ts +1073 -0
- package/src/modes/controllers/mcp-command-controller.ts +2017 -0
- package/src/modes/controllers/omfg-controller.ts +283 -0
- package/src/modes/controllers/omfg-rule.ts +647 -0
- package/src/modes/controllers/selector-controller.ts +1108 -0
- package/src/modes/controllers/ssh-command-controller.ts +384 -0
- package/src/modes/controllers/streaming-reveal.ts +279 -0
- package/src/modes/controllers/tan-command-controller.ts +173 -0
- package/src/modes/controllers/todo-command-controller.ts +485 -0
- package/src/modes/data/emojis.json +1 -0
- package/src/modes/emoji-autocomplete.ts +285 -0
- package/src/modes/gradient-highlight.ts +87 -0
- package/src/modes/image-references.ts +117 -0
- package/src/modes/index.ts +17 -0
- package/src/modes/interactive-mode.ts +3370 -0
- package/src/modes/internal-url-autocomplete.ts +143 -0
- package/src/modes/loop-limit.ts +140 -0
- package/src/modes/magic-keywords.ts +20 -0
- package/src/modes/markdown-prose.ts +247 -0
- package/src/modes/oauth-manual-input.ts +69 -0
- package/src/modes/orchestrate.ts +42 -0
- package/src/modes/print-mode.ts +126 -0
- package/src/modes/prompt-action-autocomplete.ts +260 -0
- package/src/modes/rpc/host-tools.ts +186 -0
- package/src/modes/rpc/host-uris.ts +235 -0
- package/src/modes/rpc/rpc-client.ts +963 -0
- package/src/modes/rpc/rpc-mode.ts +947 -0
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +458 -0
- package/src/modes/runtime-init.ts +116 -0
- package/src/modes/session-observer-registry.ts +146 -0
- package/src/modes/setup-version.ts +11 -0
- package/src/modes/setup-wizard/index.ts +99 -0
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +96 -0
- package/src/modes/setup-wizard/scenes/outro.ts +35 -0
- package/src/modes/setup-wizard/scenes/providers.ts +69 -0
- package/src/modes/setup-wizard/scenes/sign-in.ts +205 -0
- package/src/modes/setup-wizard/scenes/splash.ts +201 -0
- package/src/modes/setup-wizard/scenes/theme.ts +299 -0
- package/src/modes/setup-wizard/scenes/types.ts +48 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +129 -0
- package/src/modes/setup-wizard/wizard-overlay.ts +275 -0
- package/src/modes/shared.ts +47 -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 +142 -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 +142 -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 +29 -0
- package/src/modes/theme/shimmer.ts +235 -0
- package/src/modes/theme/theme-schema.json +459 -0
- package/src/modes/theme/theme.ts +2676 -0
- package/src/modes/turn-budget.ts +31 -0
- package/src/modes/types.ts +359 -0
- package/src/modes/ultrathink.ts +41 -0
- package/src/modes/utils/context-usage.ts +339 -0
- package/src/modes/utils/copy-targets.ts +360 -0
- package/src/modes/utils/hotkeys-markdown.ts +61 -0
- package/src/modes/utils/keybinding-matchers.ts +51 -0
- package/src/modes/utils/tools-markdown.ts +27 -0
- package/src/modes/utils/ui-helpers.ts +801 -0
- package/src/modes/workflow.ts +42 -0
- package/src/plan-mode/approved-plan.ts +186 -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 +41 -0
- package/src/prompts/agents/designer.md +66 -0
- package/src/prompts/agents/explore.md +58 -0
- package/src/prompts/agents/frontmatter.md +11 -0
- package/src/prompts/agents/init.md +33 -0
- package/src/prompts/agents/librarian.md +119 -0
- package/src/prompts/agents/oracle.md +55 -0
- package/src/prompts/agents/plan.md +48 -0
- package/src/prompts/agents/reviewer.md +140 -0
- package/src/prompts/agents/task.md +16 -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/memories/consolidation.md +30 -0
- package/src/prompts/memories/read-path.md +11 -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 +22 -0
- package/src/prompts/review-headless-request.md +16 -0
- package/src/prompts/review-request.md +69 -0
- package/src/prompts/steering/user-interjection.md +10 -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 +12 -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/custom-system-prompt.md +64 -0
- package/src/prompts/system/eager-todo.md +13 -0
- package/src/prompts/system/empty-stop-retry.md +6 -0
- package/src/prompts/system/irc-incoming.md +7 -0
- package/src/prompts/system/manual-continue.md +7 -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/omfg-user.md +50 -0
- package/src/prompts/system/orchestrate-notice.md +40 -0
- package/src/prompts/system/plan-mode-active.md +109 -0
- package/src/prompts/system/plan-mode-approved.md +25 -0
- package/src/prompts/system/plan-mode-compact-instructions.md +16 -0
- package/src/prompts/system/plan-mode-reference.md +11 -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/project-prompt.md +52 -0
- package/src/prompts/system/subagent-system-prompt.md +64 -0
- package/src/prompts/system/subagent-user-prompt.md +3 -0
- package/src/prompts/system/subagent-yield-reminder.md +12 -0
- package/src/prompts/system/system-prompt.md +258 -0
- package/src/prompts/system/tiny-title-system.md +8 -0
- package/src/prompts/system/title-system.md +16 -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/web-search.md +25 -0
- package/src/prompts/system/workflow-notice.md +70 -0
- package/src/prompts/tools/apply-patch.md +65 -0
- package/src/prompts/tools/ask.md +30 -0
- package/src/prompts/tools/ast-edit.md +39 -0
- package/src/prompts/tools/ast-grep.md +42 -0
- package/src/prompts/tools/async-result.md +8 -0
- package/src/prompts/tools/bash.md +46 -0
- package/src/prompts/tools/browser.md +73 -0
- package/src/prompts/tools/checkpoint.md +16 -0
- package/src/prompts/tools/debug.md +34 -0
- package/src/prompts/tools/eval.md +92 -0
- package/src/prompts/tools/find.md +36 -0
- package/src/prompts/tools/github.md +21 -0
- package/src/prompts/tools/goal.md +18 -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 +32 -0
- package/src/prompts/tools/irc.md +59 -0
- package/src/prompts/tools/job.md +19 -0
- package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
- package/src/prompts/tools/lsp.md +42 -0
- package/src/prompts/tools/memory-edit.md +8 -0
- package/src/prompts/tools/patch.md +70 -0
- package/src/prompts/tools/read.md +84 -0
- package/src/prompts/tools/recall.md +5 -0
- package/src/prompts/tools/reflect.md +5 -0
- package/src/prompts/tools/render-mermaid.md +9 -0
- package/src/prompts/tools/replace.md +30 -0
- package/src/prompts/tools/resolve.md +9 -0
- package/src/prompts/tools/retain.md +6 -0
- package/src/prompts/tools/rewind.md +13 -0
- package/src/prompts/tools/search-tool-bm25.md +32 -0
- package/src/prompts/tools/search.md +24 -0
- package/src/prompts/tools/ssh.md +31 -0
- package/src/prompts/tools/task-summary.md +17 -0
- package/src/prompts/tools/task.md +88 -0
- package/src/prompts/tools/todo.md +62 -0
- package/src/prompts/tools/web-search.md +10 -0
- package/src/prompts/tools/write.md +14 -0
- package/src/registry/agent-lifecycle.ts +218 -0
- package/src/registry/agent-registry.ts +151 -0
- package/src/sdk.ts +2558 -0
- package/src/secrets/index.ts +123 -0
- package/src/secrets/obfuscator.ts +298 -0
- package/src/secrets/regex.ts +21 -0
- package/src/session/agent-session.ts +10121 -0
- package/src/session/agent-storage.ts +455 -0
- package/src/session/artifacts.ts +135 -0
- package/src/session/auth-broker-config.ts +131 -0
- package/src/session/auth-storage.ts +29 -0
- package/src/session/blob-store.ts +255 -0
- package/src/session/client-bridge.ts +85 -0
- package/src/session/history-storage.ts +348 -0
- package/src/session/indexed-session-storage.ts +430 -0
- package/src/session/messages.ts +541 -0
- package/src/session/redis-session-storage.ts +170 -0
- package/src/session/session-dump-format.ts +209 -0
- package/src/session/session-history-format.ts +246 -0
- package/src/session/session-manager.ts +3676 -0
- package/src/session/session-storage.ts +529 -0
- package/src/session/shake-types.ts +43 -0
- package/src/session/sql-session-storage.ts +314 -0
- package/src/session/streaming-output.ts +1330 -0
- package/src/session/tool-choice-queue.ts +213 -0
- package/src/session/yield-queue.ts +173 -0
- package/src/slash-commands/acp-builtins.ts +70 -0
- package/src/slash-commands/builtin-registry.ts +1798 -0
- package/src/slash-commands/helpers/context-report.ts +39 -0
- package/src/slash-commands/helpers/format.ts +46 -0
- package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
- package/src/slash-commands/helpers/mcp.ts +532 -0
- package/src/slash-commands/helpers/parse.ts +85 -0
- package/src/slash-commands/helpers/ssh.ts +195 -0
- package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
- package/src/slash-commands/helpers/todo.ts +279 -0
- package/src/slash-commands/helpers/usage-report.ts +95 -0
- package/src/slash-commands/marketplace-install-parser.ts +99 -0
- package/src/slash-commands/types.ts +135 -0
- package/src/ssh/config-writer.ts +183 -0
- package/src/ssh/connection-manager.ts +509 -0
- package/src/ssh/ssh-executor.ts +189 -0
- package/src/ssh/sshfs-mount.ts +140 -0
- package/src/ssh/utils.ts +8 -0
- package/src/stt/downloader.ts +71 -0
- package/src/stt/index.ts +3 -0
- package/src/stt/recorder.ts +351 -0
- package/src/stt/setup.ts +52 -0
- package/src/stt/stt-controller.ts +160 -0
- package/src/stt/transcribe.py +70 -0
- package/src/stt/transcriber.ts +91 -0
- package/src/stubs/natives/index.ts +814 -0
- package/src/stubs/natives/package.json +7 -0
- package/src/stubs/tui/index.ts +282 -0
- package/src/stubs/tui/package.json +7 -0
- package/src/system-prompt.ts +611 -0
- package/src/task/agents.ts +167 -0
- package/src/task/commands.ts +132 -0
- package/src/task/discovery.ts +122 -0
- package/src/task/executor.ts +2133 -0
- package/src/task/index.ts +1419 -0
- package/src/task/name-generator.ts +1577 -0
- package/src/task/omp-command.ts +26 -0
- package/src/task/output-manager.ts +88 -0
- package/src/task/parallel.ts +116 -0
- package/src/task/render.ts +1381 -0
- package/src/task/repair-args.ts +129 -0
- package/src/task/subprocess-tool-registry.ts +88 -0
- package/src/task/types.ts +336 -0
- package/src/task/worktree.ts +514 -0
- package/src/telemetry-export.ts +144 -0
- package/src/thinking.ts +167 -0
- package/src/tiny/compiled-runtime.ts +179 -0
- package/src/tiny/device.ts +111 -0
- package/src/tiny/dtype.ts +101 -0
- package/src/tiny/models.ts +242 -0
- package/src/tiny/text.ts +165 -0
- package/src/tiny/title-client.ts +543 -0
- package/src/tiny/title-protocol.ts +56 -0
- package/src/tiny/worker.ts +568 -0
- package/src/tool-discovery/mode.ts +24 -0
- package/src/tool-discovery/tool-index.ts +256 -0
- package/src/tools/approval.ts +189 -0
- package/src/tools/archive-reader.ts +721 -0
- package/src/tools/ask.ts +928 -0
- package/src/tools/ast-edit.ts +642 -0
- package/src/tools/ast-grep.ts +452 -0
- package/src/tools/auto-generated-guard.ts +322 -0
- package/src/tools/bash-command-fixup.ts +37 -0
- package/src/tools/bash-interactive.ts +408 -0
- package/src/tools/bash-interceptor.ts +67 -0
- package/src/tools/bash-pty-selection.ts +14 -0
- package/src/tools/bash-skill-urls.ts +248 -0
- package/src/tools/bash.ts +1386 -0
- package/src/tools/browser/attach.ts +175 -0
- package/src/tools/browser/launch.ts +660 -0
- package/src/tools/browser/readable.ts +112 -0
- package/src/tools/browser/registry.ts +197 -0
- package/src/tools/browser/render.ts +216 -0
- package/src/tools/browser/tab-protocol.ts +105 -0
- package/src/tools/browser/tab-supervisor.ts +628 -0
- package/src/tools/browser/tab-worker-entry.ts +21 -0
- package/src/tools/browser/tab-worker.ts +1226 -0
- package/src/tools/browser.ts +343 -0
- package/src/tools/checkpoint.ts +136 -0
- package/src/tools/conflict-detect.ts +718 -0
- package/src/tools/context.ts +39 -0
- package/src/tools/debug.ts +1067 -0
- package/src/tools/eval-backends.ts +27 -0
- package/src/tools/eval-render.ts +752 -0
- package/src/tools/eval.ts +577 -0
- package/src/tools/fetch.ts +1926 -0
- package/src/tools/file-recorder.ts +35 -0
- package/src/tools/find.ts +609 -0
- package/src/tools/fs-cache-invalidation.ts +28 -0
- package/src/tools/gh-cache-invalidation.ts +255 -0
- package/src/tools/gh-format.ts +12 -0
- package/src/tools/gh-renderer.ts +481 -0
- package/src/tools/gh.ts +3720 -0
- package/src/tools/github-cache.ts +637 -0
- package/src/tools/grouped-file-output.ts +210 -0
- package/src/tools/image-gen.ts +1517 -0
- package/src/tools/index.ts +599 -0
- package/src/tools/inspect-image-renderer.ts +132 -0
- package/src/tools/inspect-image.ts +174 -0
- package/src/tools/irc.ts +723 -0
- package/src/tools/job.ts +557 -0
- package/src/tools/json-tree.ts +243 -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/list-limit.ts +40 -0
- package/src/tools/match-line-format.ts +20 -0
- package/src/tools/memory-edit.ts +59 -0
- package/src/tools/memory-recall.ts +100 -0
- package/src/tools/memory-reflect.ts +88 -0
- package/src/tools/memory-render.ts +202 -0
- package/src/tools/memory-retain.ts +91 -0
- package/src/tools/output-meta.ts +754 -0
- package/src/tools/output-schema-validator.ts +132 -0
- package/src/tools/path-utils.ts +1054 -0
- package/src/tools/plan-mode-guard.ts +108 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
- package/src/tools/read.ts +2929 -0
- package/src/tools/render-mermaid.ts +69 -0
- package/src/tools/render-utils.ts +838 -0
- package/src/tools/renderers.ts +77 -0
- package/src/tools/report-tool-issue.ts +534 -0
- package/src/tools/resolve.ts +276 -0
- package/src/tools/review.ts +253 -0
- package/src/tools/search-tool-bm25.ts +351 -0
- package/src/tools/search.ts +1580 -0
- package/src/tools/sqlite-reader.ts +828 -0
- package/src/tools/ssh.ts +349 -0
- package/src/tools/todo.ts +982 -0
- package/src/tools/tool-errors.ts +62 -0
- package/src/tools/tool-result.ts +94 -0
- package/src/tools/tool-timeouts.ts +30 -0
- package/src/tools/tts.ts +133 -0
- package/src/tools/write.ts +1217 -0
- package/src/tools/yield.ts +269 -0
- package/src/tui/code-cell.ts +216 -0
- package/src/tui/file-list.ts +55 -0
- package/src/tui/hyperlink.ts +175 -0
- package/src/tui/index.ts +12 -0
- package/src/tui/output-block.ts +240 -0
- package/src/tui/status-line.ts +54 -0
- package/src/tui/tree-list.ts +84 -0
- package/src/tui/types.ts +15 -0
- package/src/tui/utils.ts +103 -0
- package/src/utils/block-context.ts +312 -0
- package/src/utils/changelog.ts +132 -0
- package/src/utils/clipboard.ts +193 -0
- package/src/utils/command-args.ts +76 -0
- package/src/utils/commit-message-generator.ts +151 -0
- package/src/utils/edit-mode.ts +41 -0
- package/src/utils/enhanced-paste.ts +230 -0
- package/src/utils/event-bus.ts +33 -0
- package/src/utils/external-editor.ts +65 -0
- package/src/utils/file-display-mode.ts +45 -0
- package/src/utils/file-mentions.ts +281 -0
- package/src/utils/git.ts +1833 -0
- package/src/utils/image-loading.ts +132 -0
- package/src/utils/image-resize.ts +309 -0
- package/src/utils/jj.ts +248 -0
- package/src/utils/lang-from-path.ts +239 -0
- package/src/utils/markit.ts +89 -0
- package/src/utils/open.ts +55 -0
- package/src/utils/session-color.ts +68 -0
- package/src/utils/shell-snapshot.ts +187 -0
- package/src/utils/sixel.ts +69 -0
- package/src/utils/title-generator.ts +373 -0
- package/src/utils/tool-choice.ts +33 -0
- package/src/utils/tools-manager.ts +363 -0
- package/src/web/kagi.ts +305 -0
- package/src/web/parallel.ts +353 -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 +653 -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 +704 -0
- package/src/web/scrapers/gitlab.ts +401 -0
- package/src/web/scrapers/go-pkg.ts +266 -0
- package/src/web/scrapers/hackage.ts +140 -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 +120 -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 +397 -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 +292 -0
- package/src/web/search/provider.ts +157 -0
- package/src/web/search/providers/anthropic.ts +318 -0
- package/src/web/search/providers/base.ts +89 -0
- package/src/web/search/providers/brave.ts +152 -0
- package/src/web/search/providers/codex.ts +591 -0
- package/src/web/search/providers/exa.ts +400 -0
- package/src/web/search/providers/gemini.ts +460 -0
- package/src/web/search/providers/jina.ts +111 -0
- package/src/web/search/providers/kagi.ts +86 -0
- package/src/web/search/providers/kimi.ts +196 -0
- package/src/web/search/providers/parallel.ts +225 -0
- package/src/web/search/providers/perplexity.ts +730 -0
- package/src/web/search/providers/searxng.ts +313 -0
- package/src/web/search/providers/synthetic.ts +114 -0
- package/src/web/search/providers/tavily.ts +176 -0
- package/src/web/search/providers/utils.ts +128 -0
- package/src/web/search/providers/zai.ts +333 -0
- package/src/web/search/render.ts +262 -0
- package/src/web/search/types.ts +482 -0
- package/src/web/search/utils.ts +17 -0
- package/src/workspace-tree.ts +286 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom message types and transformers for the coding agent.
|
|
3
|
+
*
|
|
4
|
+
* Extends the base AgentMessage type with coding-agent specific message types,
|
|
5
|
+
* and provides a transformer to convert them to LLM-compatible messages.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
8
|
+
import {
|
|
9
|
+
type BranchSummaryMessage,
|
|
10
|
+
type CompactionSummaryMessage,
|
|
11
|
+
convertMessageToLlm,
|
|
12
|
+
} from "@oh-my-pi/pi-agent-core/compaction/messages";
|
|
13
|
+
import type {
|
|
14
|
+
AssistantMessage,
|
|
15
|
+
ImageContent,
|
|
16
|
+
Message,
|
|
17
|
+
MessageAttribution,
|
|
18
|
+
TextContent,
|
|
19
|
+
UserMessage,
|
|
20
|
+
} from "@oh-my-pi/pi-ai";
|
|
21
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
22
|
+
import userInterjectionTemplate from "../prompts/steering/user-interjection.md" with { type: "text" };
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
type BranchSummaryMessage,
|
|
26
|
+
type CompactionSummaryMessage,
|
|
27
|
+
createBranchSummaryMessage,
|
|
28
|
+
createCompactionSummaryMessage,
|
|
29
|
+
createCustomMessage,
|
|
30
|
+
} from "@oh-my-pi/pi-agent-core/compaction/messages";
|
|
31
|
+
|
|
32
|
+
import type { OutputMeta } from "../tools/output-meta";
|
|
33
|
+
import { formatOutputNotice } from "../tools/output-meta";
|
|
34
|
+
|
|
35
|
+
export const SKILL_PROMPT_MESSAGE_TYPE = "skill-prompt";
|
|
36
|
+
export const LSP_LATE_DIAGNOSTIC_MESSAGE_TYPE = "lsp-late-diagnostic";
|
|
37
|
+
|
|
38
|
+
export interface SkillPromptDetails {
|
|
39
|
+
name: string;
|
|
40
|
+
path: string;
|
|
41
|
+
args?: string;
|
|
42
|
+
lineCount: number;
|
|
43
|
+
/** Internal: tag used by AgentSession to remove the pending-display chip
|
|
44
|
+
* from `#steeringMessages` / `#followUpMessages` when the agent consumes
|
|
45
|
+
* this message. Not surfaced to renderers; the `__` prefix signals
|
|
46
|
+
* "private". Optional — non-streaming skill prompts never set it. Stripped
|
|
47
|
+
* from persisted `details` by `SessionManager.appendCustomMessageEntry`
|
|
48
|
+
* via the `INTERNAL_DETAILS_FIELDS` allowlist below. */
|
|
49
|
+
__pendingDisplayTag?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Sentinel value for `AssistantMessage.errorMessage` indicating that the abort
|
|
53
|
+
* was an *expected internal transition* (plan-mode → execution compaction)
|
|
54
|
+
* and must NOT surface as a red "Operation aborted" line. Distinct from
|
|
55
|
+
* `undefined` (default) so user-cancel aborts with no errorMessage still
|
|
56
|
+
* render normally. Persists through SessionManager so history replay
|
|
57
|
+
* branches identically.
|
|
58
|
+
*
|
|
59
|
+
* Consumers: `AgentSession.#handleAgentEvent` (stamper) writes this value;
|
|
60
|
+
* `EventController.#handleMessageEnd`, `AssistantMessageComponent`,
|
|
61
|
+
* `ui-helpers.addMessageToChat` (renderers), `AgentHubOverlayComponent
|
|
62
|
+
* #buildTranscriptLines`, `runPrintMode`, and `AcpAgent#replayAssistantMessage`
|
|
63
|
+
* (fallback error emission) read it via `isSilentAbort`. */
|
|
64
|
+
export const SILENT_ABORT_MARKER = "__omp.silent_abort__";
|
|
65
|
+
|
|
66
|
+
/** Type-guard for `SILENT_ABORT_MARKER`. Renderers MUST branch on this rather
|
|
67
|
+
* than string-comparing inline so refactors to the marker constant (e.g.,
|
|
68
|
+
* namespacing changes) propagate through every consumer in lockstep. */
|
|
69
|
+
export function isSilentAbort(errorMessage: string | undefined): boolean {
|
|
70
|
+
return errorMessage === SILENT_ABORT_MARKER;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Reason threaded through `AbortController.abort(reason)` when the user aborts
|
|
74
|
+
* the turn with Esc (see `AgentSession.abort`). The agent keeps it on the
|
|
75
|
+
* aborted assistant message's `errorMessage` so queued follow-ups/tool-result
|
|
76
|
+
* placeholders can distinguish a deliberate interrupt from a bare lifecycle
|
|
77
|
+
* abort, but interactive renderers suppress this redundant transcript line. */
|
|
78
|
+
export const USER_INTERRUPT_LABEL = "Interrupted by user";
|
|
79
|
+
|
|
80
|
+
export function isUserInterruptAbort(errorMessage: string | undefined): boolean {
|
|
81
|
+
return errorMessage === USER_INTERRUPT_LABEL;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function shouldRenderAbortReason(errorMessage: string | undefined): boolean {
|
|
85
|
+
return !isSilentAbort(errorMessage) && !isUserInterruptAbort(errorMessage);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Sentinel `errorMessage` the agent stamps on any abort that carried no custom
|
|
89
|
+
* reason (bare `abort()`). Renderers treat it as "no specific reason given". */
|
|
90
|
+
const GENERIC_ABORT_SENTINEL = "Request was aborted";
|
|
91
|
+
|
|
92
|
+
/** Resolve the operator-facing label for an aborted assistant turn. A custom
|
|
93
|
+
* abort reason threaded onto `errorMessage` is returned verbatim; aborts with
|
|
94
|
+
* no threaded reason fall back to the retry-aware generic label. Call
|
|
95
|
+
* `shouldRenderAbortReason` before rendering when user interrupts should stay
|
|
96
|
+
* visually quiet. */
|
|
97
|
+
export function resolveAbortLabel(errorMessage: string | undefined, retryAttempt = 0): string {
|
|
98
|
+
if (errorMessage && errorMessage !== GENERIC_ABORT_SENTINEL && !isSilentAbort(errorMessage)) {
|
|
99
|
+
return errorMessage;
|
|
100
|
+
}
|
|
101
|
+
if (retryAttempt > 0) {
|
|
102
|
+
return `Aborted after ${retryAttempt} retry attempt${retryAttempt > 1 ? "s" : ""}`;
|
|
103
|
+
}
|
|
104
|
+
return "Operation aborted";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Extract the optional `__pendingDisplayTag` field from a CustomMessage's
|
|
108
|
+
* `details` blob. Safe over `unknown`; returns undefined when the field is
|
|
109
|
+
* absent or non-string. */
|
|
110
|
+
export function readPendingDisplayTag(details: unknown): string | undefined {
|
|
111
|
+
if (typeof details !== "object" || details === null) return undefined;
|
|
112
|
+
const candidate = (details as { __pendingDisplayTag?: unknown }).__pendingDisplayTag;
|
|
113
|
+
return typeof candidate === "string" ? candidate : undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Explicit allowlist of `details` field names that are AgentSession-internal
|
|
117
|
+
* transient bookkeeping and MUST be removed before SessionManager persists
|
|
118
|
+
* the CustomMessageEntry to disk. Scoped intentionally narrow: only fields
|
|
119
|
+
* declared here are stripped. Adding a new entry is a deliberate, reviewed
|
|
120
|
+
* change — unrelated future payload fields are never silently dropped. */
|
|
121
|
+
export const INTERNAL_DETAILS_FIELDS = ["__pendingDisplayTag"] as const;
|
|
122
|
+
|
|
123
|
+
/** Return a `details` copy with every key in `INTERNAL_DETAILS_FIELDS`
|
|
124
|
+
* removed. Returns the input unchanged when there is nothing to strip
|
|
125
|
+
* (null/non-object, or no listed fields present) so callers don't pay a
|
|
126
|
+
* clone cost on the common path. */
|
|
127
|
+
export function stripInternalDetailsFields<T>(details: T | undefined): T | undefined {
|
|
128
|
+
if (details == null || typeof details !== "object") return details;
|
|
129
|
+
const obj = details as Record<string, unknown>;
|
|
130
|
+
let hit = false;
|
|
131
|
+
for (const key of INTERNAL_DETAILS_FIELDS) {
|
|
132
|
+
if (key in obj) {
|
|
133
|
+
hit = true;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (!hit) return details;
|
|
138
|
+
const cleaned: Record<string, unknown> = { ...obj };
|
|
139
|
+
for (const key of INTERNAL_DETAILS_FIELDS) {
|
|
140
|
+
delete cleaned[key];
|
|
141
|
+
}
|
|
142
|
+
return cleaned as T;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function isSteeringUserMessage(message: AgentMessage | undefined): message is UserMessage & { steering: true } {
|
|
146
|
+
return message?.role === "user" && message.steering === true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function userMessageWithoutSteering(message: UserMessage): UserMessage {
|
|
150
|
+
const { steering, ...rest } = message;
|
|
151
|
+
void steering;
|
|
152
|
+
return rest;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function renderSteeringEnvelope(message: string): string {
|
|
156
|
+
return prompt.render(userInterjectionTemplate, { message });
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function getArrayContentText(content: (TextContent | ImageContent)[]): string {
|
|
160
|
+
let firstText: string | undefined;
|
|
161
|
+
let textParts: string[] | undefined;
|
|
162
|
+
for (const part of content) {
|
|
163
|
+
if (part.type !== "text") continue;
|
|
164
|
+
if (firstText === undefined) {
|
|
165
|
+
firstText = part.text;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (textParts === undefined) {
|
|
169
|
+
textParts = [firstText];
|
|
170
|
+
}
|
|
171
|
+
textParts.push(part.text);
|
|
172
|
+
}
|
|
173
|
+
return textParts === undefined ? (firstText ?? "") : textParts.join("\n");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getArrayContentImages(content: (TextContent | ImageContent)[]): ImageContent[] {
|
|
177
|
+
let images: ImageContent[] | undefined;
|
|
178
|
+
for (const part of content) {
|
|
179
|
+
if (part.type !== "image") continue;
|
|
180
|
+
if (images === undefined) images = [];
|
|
181
|
+
images.push(part);
|
|
182
|
+
}
|
|
183
|
+
return images ?? [];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function wrapSteeringUserMessage(message: UserMessage): UserMessage {
|
|
187
|
+
if (typeof message.content === "string") {
|
|
188
|
+
if (message.content.length === 0) return message;
|
|
189
|
+
return { ...userMessageWithoutSteering(message), content: renderSteeringEnvelope(message.content) };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const text = getArrayContentText(message.content);
|
|
193
|
+
if (text.length === 0) return message;
|
|
194
|
+
const content: (TextContent | ImageContent)[] = [{ type: "text", text: renderSteeringEnvelope(text) }];
|
|
195
|
+
content.push(...getArrayContentImages(message.content));
|
|
196
|
+
return { ...userMessageWithoutSteering(message), content };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function wrapSteeringForModel(messages: AgentMessage[]): AgentMessage[] {
|
|
200
|
+
const last = messages[messages.length - 1];
|
|
201
|
+
if (!isSteeringUserMessage(last)) return messages;
|
|
202
|
+
|
|
203
|
+
let firstSteer = messages.length - 1;
|
|
204
|
+
while (firstSteer > 0 && isSteeringUserMessage(messages[firstSteer - 1])) {
|
|
205
|
+
firstSteer--;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
let wrappedMessages: AgentMessage[] | undefined;
|
|
209
|
+
for (let i = firstSteer; i < messages.length; i++) {
|
|
210
|
+
const message = messages[i];
|
|
211
|
+
if (!isSteeringUserMessage(message)) continue;
|
|
212
|
+
const wrappedMessage = wrapSteeringUserMessage(message);
|
|
213
|
+
if (wrappedMessage === message) continue;
|
|
214
|
+
if (wrappedMessages === undefined) {
|
|
215
|
+
wrappedMessages = messages.slice();
|
|
216
|
+
}
|
|
217
|
+
wrappedMessages[i] = wrappedMessage;
|
|
218
|
+
}
|
|
219
|
+
return wrappedMessages ?? messages;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Result of filtering image blocks out of a `(TextContent | ImageContent)[]` array. */
|
|
223
|
+
interface StripContentResult {
|
|
224
|
+
content: (TextContent | ImageContent)[];
|
|
225
|
+
removed: number;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function stripImagesFromArrayContent(content: (TextContent | ImageContent)[]): StripContentResult {
|
|
229
|
+
let removed = 0;
|
|
230
|
+
const kept: (TextContent | ImageContent)[] = [];
|
|
231
|
+
for (const part of content) {
|
|
232
|
+
if (part.type === "image") {
|
|
233
|
+
removed++;
|
|
234
|
+
} else {
|
|
235
|
+
kept.push(part);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (removed === 0) {
|
|
239
|
+
return { content, removed };
|
|
240
|
+
}
|
|
241
|
+
// Avoid emitting an empty `content` array — providers reject zero-block user/tool
|
|
242
|
+
// messages and the LLM still needs to see *something* where the image used to be.
|
|
243
|
+
if (kept.length === 0) {
|
|
244
|
+
kept.push({ type: "text", text: "[image removed]" });
|
|
245
|
+
}
|
|
246
|
+
return { content: kept, removed };
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Strip image content blocks from `message` in place. Returns the count of
|
|
251
|
+
* images removed across `content` (every role that carries `ImageContent`) and
|
|
252
|
+
* any tool-result `details.images` payload. Callers MUST rewrite session
|
|
253
|
+
* entries (`SessionManager.rewriteEntries`) and replay them through
|
|
254
|
+
* `Agent.replaceMessages` afterwards so persisted state and provider-side
|
|
255
|
+
* caches stay aligned with the mutated tree — `stripImagesFromMessage` is a
|
|
256
|
+
* pure local mutation and intentionally does neither.
|
|
257
|
+
*/
|
|
258
|
+
export function stripImagesFromMessage(message: AgentMessage): number {
|
|
259
|
+
switch (message.role) {
|
|
260
|
+
case "user":
|
|
261
|
+
case "developer":
|
|
262
|
+
case "custom":
|
|
263
|
+
case "hookMessage": {
|
|
264
|
+
if (typeof message.content === "string") return 0;
|
|
265
|
+
const { content, removed } = stripImagesFromArrayContent(message.content);
|
|
266
|
+
if (removed > 0) {
|
|
267
|
+
// All four roles type `content` as `string | (TextContent | ImageContent)[]`;
|
|
268
|
+
// TypeScript can't narrow the assignment across the union, so cast once.
|
|
269
|
+
(message as { content: typeof content }).content = content;
|
|
270
|
+
}
|
|
271
|
+
return removed;
|
|
272
|
+
}
|
|
273
|
+
case "toolResult": {
|
|
274
|
+
let removed = 0;
|
|
275
|
+
const { content, removed: contentRemoved } = stripImagesFromArrayContent(message.content);
|
|
276
|
+
if (contentRemoved > 0) {
|
|
277
|
+
message.content = content;
|
|
278
|
+
removed += contentRemoved;
|
|
279
|
+
}
|
|
280
|
+
const details = message.details as { images?: unknown } | null | undefined;
|
|
281
|
+
if (details && Array.isArray(details.images)) {
|
|
282
|
+
const original = details.images as unknown[];
|
|
283
|
+
const kept: unknown[] = [];
|
|
284
|
+
for (const candidate of original) {
|
|
285
|
+
const looksLikeImageBlock =
|
|
286
|
+
!!candidate && typeof candidate === "object" && (candidate as { type?: unknown }).type === "image";
|
|
287
|
+
if (looksLikeImageBlock) {
|
|
288
|
+
removed++;
|
|
289
|
+
} else {
|
|
290
|
+
kept.push(candidate);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (kept.length !== original.length) {
|
|
294
|
+
details.images = kept;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return removed;
|
|
298
|
+
}
|
|
299
|
+
case "fileMention": {
|
|
300
|
+
let removed = 0;
|
|
301
|
+
for (const file of message.files) {
|
|
302
|
+
if (file.image) {
|
|
303
|
+
file.image = undefined;
|
|
304
|
+
removed++;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return removed;
|
|
308
|
+
}
|
|
309
|
+
default:
|
|
310
|
+
return 0;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Message type for bash executions via the ! command.
|
|
316
|
+
*/
|
|
317
|
+
export interface BashExecutionMessage {
|
|
318
|
+
role: "bashExecution";
|
|
319
|
+
command: string;
|
|
320
|
+
output: string;
|
|
321
|
+
exitCode: number | undefined;
|
|
322
|
+
cancelled: boolean;
|
|
323
|
+
truncated: boolean;
|
|
324
|
+
meta?: OutputMeta;
|
|
325
|
+
timestamp: number;
|
|
326
|
+
/** If true, this message is excluded from LLM context (!! prefix) */
|
|
327
|
+
excludeFromContext?: boolean;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Message type for user-initiated Python executions via the $ command.
|
|
332
|
+
* Shares the same kernel session as eval's Python backend.
|
|
333
|
+
*/
|
|
334
|
+
export interface PythonExecutionMessage {
|
|
335
|
+
role: "pythonExecution";
|
|
336
|
+
code: string;
|
|
337
|
+
output: string;
|
|
338
|
+
exitCode: number | undefined;
|
|
339
|
+
cancelled: boolean;
|
|
340
|
+
truncated: boolean;
|
|
341
|
+
meta?: OutputMeta;
|
|
342
|
+
timestamp: number;
|
|
343
|
+
/** If true, this message is excluded from LLM context ($$ prefix) */
|
|
344
|
+
excludeFromContext?: boolean;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Message type for extension-injected messages via sendMessage().
|
|
349
|
+
*/
|
|
350
|
+
export interface CustomMessage<T = unknown> {
|
|
351
|
+
role: "custom";
|
|
352
|
+
customType: string;
|
|
353
|
+
content: string | (TextContent | ImageContent)[];
|
|
354
|
+
display: boolean;
|
|
355
|
+
details?: T;
|
|
356
|
+
/** Who initiated this message for billing/attribution semantics. */
|
|
357
|
+
attribution?: MessageAttribution;
|
|
358
|
+
timestamp: number;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Legacy hook message type (pre-extensions). Kept for session migration.
|
|
363
|
+
*/
|
|
364
|
+
export interface HookMessage<T = unknown> {
|
|
365
|
+
role: "hookMessage";
|
|
366
|
+
customType: string;
|
|
367
|
+
content: string | (TextContent | ImageContent)[];
|
|
368
|
+
display: boolean;
|
|
369
|
+
details?: T;
|
|
370
|
+
/** Who initiated this message for billing/attribution semantics. */
|
|
371
|
+
attribution?: MessageAttribution;
|
|
372
|
+
timestamp: number;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Message type for auto-read file mentions via @filepath syntax.
|
|
377
|
+
*/
|
|
378
|
+
export interface FileMentionMessage {
|
|
379
|
+
role: "fileMention";
|
|
380
|
+
files: Array<{
|
|
381
|
+
path: string;
|
|
382
|
+
content: string;
|
|
383
|
+
lineCount?: number;
|
|
384
|
+
/** File size in bytes, if known. */
|
|
385
|
+
byteSize?: number;
|
|
386
|
+
/** Why the file contents were omitted from auto-read. */
|
|
387
|
+
skippedReason?: "tooLarge";
|
|
388
|
+
image?: ImageContent;
|
|
389
|
+
}>;
|
|
390
|
+
timestamp: number;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Extend CustomAgentMessages via declaration merging
|
|
394
|
+
// Legacy hookMessage is kept for migration; new code should use custom.
|
|
395
|
+
declare module "@oh-my-pi/pi-agent-core" {
|
|
396
|
+
interface CustomAgentMessages {
|
|
397
|
+
bashExecution: BashExecutionMessage;
|
|
398
|
+
pythonExecution: PythonExecutionMessage;
|
|
399
|
+
custom: CustomMessage;
|
|
400
|
+
hookMessage: HookMessage;
|
|
401
|
+
branchSummary: BranchSummaryMessage;
|
|
402
|
+
compactionSummary: CompactionSummaryMessage;
|
|
403
|
+
fileMention: FileMentionMessage;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Convert a BashExecutionMessage to user message text for LLM context.
|
|
409
|
+
*/
|
|
410
|
+
export function bashExecutionToText(msg: BashExecutionMessage): string {
|
|
411
|
+
let text = `Ran \`${msg.command}\`\n`;
|
|
412
|
+
if (msg.output) {
|
|
413
|
+
text += `\`\`\`\n${msg.output}\n\`\`\``;
|
|
414
|
+
} else {
|
|
415
|
+
text += "(no output)";
|
|
416
|
+
}
|
|
417
|
+
if (msg.cancelled) {
|
|
418
|
+
text += "\n\n(command cancelled)";
|
|
419
|
+
} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {
|
|
420
|
+
text += `\n\nCommand exited with code ${msg.exitCode}`;
|
|
421
|
+
}
|
|
422
|
+
text += formatOutputNotice(msg.meta);
|
|
423
|
+
return text;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Convert a PythonExecutionMessage to user message text for LLM context.
|
|
428
|
+
*/
|
|
429
|
+
export function pythonExecutionToText(msg: PythonExecutionMessage): string {
|
|
430
|
+
let text = `Ran Python:\n\`\`\`python\n${msg.code}\n\`\`\`\n`;
|
|
431
|
+
if (msg.output) {
|
|
432
|
+
text += `Output:\n\`\`\`\n${msg.output}\n\`\`\``;
|
|
433
|
+
} else {
|
|
434
|
+
text += "(no output)";
|
|
435
|
+
}
|
|
436
|
+
if (msg.cancelled) {
|
|
437
|
+
text += "\n\n(execution cancelled)";
|
|
438
|
+
} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {
|
|
439
|
+
text += `\n\nExecution failed with code ${msg.exitCode}`;
|
|
440
|
+
}
|
|
441
|
+
text += formatOutputNotice(msg.meta);
|
|
442
|
+
return text;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export function sanitizeRehydratedOpenAIResponsesAssistantMessage(message: AssistantMessage): AssistantMessage {
|
|
446
|
+
if (message.providerPayload?.type !== "openaiResponsesHistory") {
|
|
447
|
+
return message;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
let didSanitizeContent = false;
|
|
451
|
+
const sanitizedContent = message.content.map(block => {
|
|
452
|
+
if (block.type !== "thinking" || block.thinkingSignature === undefined) {
|
|
453
|
+
return block;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
didSanitizeContent = true;
|
|
457
|
+
return { ...block, thinkingSignature: undefined };
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// Strip the assistant-side native replay payload entirely.
|
|
461
|
+
// After rehydration it belongs to a previous live provider connection and
|
|
462
|
+
// replaying it on a warmed session causes 401 rejections from GitHub Copilot.
|
|
463
|
+
// User/developer payloads are preserved separately by the caller.
|
|
464
|
+
return {
|
|
465
|
+
...message,
|
|
466
|
+
...(didSanitizeContent ? { content: sanitizedContent } : {}),
|
|
467
|
+
providerPayload: undefined,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Transform AgentMessages (including custom types) to LLM-compatible Messages.
|
|
473
|
+
*
|
|
474
|
+
* This is used by:
|
|
475
|
+
* - Agent's transormToLlm option (for prompt calls and queued messages)
|
|
476
|
+
* - Compaction's generateSummary (for summarization)
|
|
477
|
+
* - Custom extensions and tools
|
|
478
|
+
*/
|
|
479
|
+
export function convertToLlm(messages: AgentMessage[]): Message[] {
|
|
480
|
+
return messages
|
|
481
|
+
.map((m): Message | undefined => {
|
|
482
|
+
switch (m.role) {
|
|
483
|
+
case "bashExecution":
|
|
484
|
+
if (m.excludeFromContext) {
|
|
485
|
+
return undefined;
|
|
486
|
+
}
|
|
487
|
+
return {
|
|
488
|
+
role: "user",
|
|
489
|
+
content: [{ type: "text", text: bashExecutionToText(m) }],
|
|
490
|
+
attribution: "user",
|
|
491
|
+
timestamp: m.timestamp,
|
|
492
|
+
};
|
|
493
|
+
case "pythonExecution":
|
|
494
|
+
if (m.excludeFromContext) {
|
|
495
|
+
return undefined;
|
|
496
|
+
}
|
|
497
|
+
return {
|
|
498
|
+
role: "user",
|
|
499
|
+
content: [{ type: "text", text: pythonExecutionToText(m) }],
|
|
500
|
+
attribution: "user",
|
|
501
|
+
timestamp: m.timestamp,
|
|
502
|
+
};
|
|
503
|
+
case "fileMention": {
|
|
504
|
+
const fileContents = m.files
|
|
505
|
+
.map(file => {
|
|
506
|
+
const inner = file.content ? `\n${file.content}\n` : "\n";
|
|
507
|
+
return `<file path="${file.path}">${inner}</file>`;
|
|
508
|
+
})
|
|
509
|
+
.join("\n");
|
|
510
|
+
const content: (TextContent | ImageContent)[] = [{ type: "text" as const, text: fileContents }];
|
|
511
|
+
for (const file of m.files) {
|
|
512
|
+
if (file.image) {
|
|
513
|
+
content.push(file.image);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return {
|
|
517
|
+
role: "developer",
|
|
518
|
+
content,
|
|
519
|
+
attribution: "user",
|
|
520
|
+
timestamp: m.timestamp,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
case "custom":
|
|
524
|
+
case "hookMessage":
|
|
525
|
+
case "branchSummary":
|
|
526
|
+
case "compactionSummary":
|
|
527
|
+
case "user":
|
|
528
|
+
case "developer":
|
|
529
|
+
case "assistant":
|
|
530
|
+
case "toolResult":
|
|
531
|
+
// Core roles share one transformer with agent-core —
|
|
532
|
+
// duplicating them here is how snapcompact frames once
|
|
533
|
+
// silently fell off the provider request.
|
|
534
|
+
return convertMessageToLlm(m);
|
|
535
|
+
default:
|
|
536
|
+
m satisfies never;
|
|
537
|
+
return undefined;
|
|
538
|
+
}
|
|
539
|
+
})
|
|
540
|
+
.filter(m => m !== undefined);
|
|
541
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { logger, toError } from "@oh-my-pi/pi-utils";
|
|
2
|
+
import {
|
|
3
|
+
IndexedSessionStorage,
|
|
4
|
+
type SessionStorageBackend,
|
|
5
|
+
type SessionStorageIndexEntry,
|
|
6
|
+
} from "./indexed-session-storage";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Minimal subset of the `bun:redis` `RedisClient` surface used by
|
|
10
|
+
* {@link RedisSessionStorage}. Keeping the contract narrow (and accepting any
|
|
11
|
+
* client that conforms) lets callers swap in test doubles or shared clients
|
|
12
|
+
* without dragging the entire Bun typings into this module.
|
|
13
|
+
*/
|
|
14
|
+
export interface RedisSessionStorageClient {
|
|
15
|
+
get(key: string): Promise<string | null>;
|
|
16
|
+
getrange(key: string, start: number, end: number): Promise<string>;
|
|
17
|
+
strlen(key: string): Promise<number>;
|
|
18
|
+
set(key: string, value: string): Promise<unknown>;
|
|
19
|
+
append(key: string, value: string): Promise<number>;
|
|
20
|
+
del(...keys: string[]): Promise<number>;
|
|
21
|
+
rename(src: string, dst: string): Promise<unknown>;
|
|
22
|
+
scan(cursor: string, ...args: string[]): Promise<[string, string[]]>;
|
|
23
|
+
hset(key: string, field: string, value: string): Promise<unknown>;
|
|
24
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
25
|
+
hdel(key: string, ...fields: string[]): Promise<unknown>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface RedisSessionStorageOptions {
|
|
29
|
+
/** A connected `bun:redis` RedisClient (or any compatible adapter). */
|
|
30
|
+
client: RedisSessionStorageClient;
|
|
31
|
+
/**
|
|
32
|
+
* Key prefix applied to every Redis key this storage owns. Default `omp:sessions:`.
|
|
33
|
+
* Trailing colon is preserved verbatim — set to a project-scoped prefix to share
|
|
34
|
+
* one Redis instance between multiple agents.
|
|
35
|
+
*/
|
|
36
|
+
prefix?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Maximum number of keys returned per SCAN batch when warming the metadata index.
|
|
39
|
+
* Default 500.
|
|
40
|
+
*/
|
|
41
|
+
scanCount?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const DEFAULT_PREFIX = "omp:sessions:";
|
|
45
|
+
const DEFAULT_SCAN_COUNT = 500;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Redis-backed implementation of {@link SessionStorage}. Each session JSONL
|
|
49
|
+
* file maps to a Redis STRING key, with per-key metadata (mtime) tracked in a
|
|
50
|
+
* single sibling HASH. This process keeps only a metadata index (`size`,
|
|
51
|
+
* `mtimeMs`) in memory so synchronous `existsSync` / `statSync` /
|
|
52
|
+
* `listFilesSync` calls remain available without mirroring full content.
|
|
53
|
+
*/
|
|
54
|
+
export class RedisSessionStorage extends IndexedSessionStorage {
|
|
55
|
+
/**
|
|
56
|
+
* Warm the metadata index with every existing session key under the configured
|
|
57
|
+
* prefix and return the ready-to-use storage. Must be awaited before passing
|
|
58
|
+
* the storage into `SessionManager.create()` so synchronous lookups (session
|
|
59
|
+
* resume, recent sessions, EPERM-backup recovery) see the existing keyspace.
|
|
60
|
+
*/
|
|
61
|
+
static async create(options: RedisSessionStorageOptions): Promise<RedisSessionStorage> {
|
|
62
|
+
const storage = new RedisSessionStorage(new RedisSessionStorageBackend(options));
|
|
63
|
+
await storage.initialize();
|
|
64
|
+
return storage;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
class RedisSessionStorageBackend implements SessionStorageBackend {
|
|
69
|
+
readonly #client: RedisSessionStorageClient;
|
|
70
|
+
readonly #prefix: string;
|
|
71
|
+
readonly #scanCount: number;
|
|
72
|
+
|
|
73
|
+
constructor(options: RedisSessionStorageOptions) {
|
|
74
|
+
this.#client = options.client;
|
|
75
|
+
this.#prefix = options.prefix ?? DEFAULT_PREFIX;
|
|
76
|
+
this.#scanCount = options.scanCount ?? DEFAULT_SCAN_COUNT;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
init(): Promise<void> {
|
|
80
|
+
return Promise.resolve();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async loadIndex(): Promise<SessionStorageIndexEntry[]> {
|
|
84
|
+
const filePrefix = this.#fileKey("");
|
|
85
|
+
const metaRaw = await this.#client.hgetall(this.#metaKey());
|
|
86
|
+
const meta: Record<string, string> = metaRaw ?? {};
|
|
87
|
+
|
|
88
|
+
const seen = new Set<string>();
|
|
89
|
+
let cursor = "0";
|
|
90
|
+
do {
|
|
91
|
+
const [next, batch] = await this.#client.scan(
|
|
92
|
+
cursor,
|
|
93
|
+
"MATCH",
|
|
94
|
+
`${filePrefix}*`,
|
|
95
|
+
"COUNT",
|
|
96
|
+
String(this.#scanCount),
|
|
97
|
+
);
|
|
98
|
+
cursor = next;
|
|
99
|
+
for (const key of batch) seen.add(key);
|
|
100
|
+
} while (cursor !== "0");
|
|
101
|
+
|
|
102
|
+
const fallbackMtimeMs = Date.now();
|
|
103
|
+
return Promise.all(
|
|
104
|
+
Array.from(seen, async key => {
|
|
105
|
+
const path = key.slice(filePrefix.length);
|
|
106
|
+
const size = await this.#client.strlen(key);
|
|
107
|
+
const rawMtime = meta[path];
|
|
108
|
+
const parsedMtime = rawMtime === undefined ? Number.NaN : Number(rawMtime);
|
|
109
|
+
return {
|
|
110
|
+
path,
|
|
111
|
+
size,
|
|
112
|
+
mtimeMs: Number.isFinite(parsedMtime) ? parsedMtime : fallbackMtimeMs,
|
|
113
|
+
};
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
readFull(path: string): Promise<string | null> {
|
|
119
|
+
return this.#client.get(this.#fileKey(path));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async readSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]> {
|
|
123
|
+
const key = this.#fileKey(path);
|
|
124
|
+
const head = prefixBytes > 0 ? this.#client.getrange(key, 0, prefixBytes - 1) : Promise.resolve("");
|
|
125
|
+
const tail = suffixBytes > 0 ? this.#client.getrange(key, -suffixBytes, -1) : Promise.resolve("");
|
|
126
|
+
return Promise.all([head, tail]);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async writeFull(path: string, content: string, mtimeMs: number): Promise<void> {
|
|
130
|
+
await this.#client.set(this.#fileKey(path), content);
|
|
131
|
+
await this.#client.hset(this.#metaKey(), path, String(mtimeMs));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async append(path: string, line: string, mtimeMs: number): Promise<void> {
|
|
135
|
+
await this.#client.append(this.#fileKey(path), line);
|
|
136
|
+
await this.#client.hset(this.#metaKey(), path, String(mtimeMs));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async truncate(path: string, mtimeMs: number): Promise<void> {
|
|
140
|
+
await this.writeFull(path, "", mtimeMs);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async remove(paths: string[]): Promise<void> {
|
|
144
|
+
if (paths.length === 0) return;
|
|
145
|
+
await this.#client.del(...paths.map(path => this.#fileKey(path)));
|
|
146
|
+
await this.#client.hdel(this.#metaKey(), ...paths);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async move(src: string, dst: string, mtimeMs: number): Promise<void> {
|
|
150
|
+
await this.#client.rename(this.#fileKey(src), this.#fileKey(dst));
|
|
151
|
+
try {
|
|
152
|
+
await this.#client.hdel(this.#metaKey(), src);
|
|
153
|
+
await this.#client.hset(this.#metaKey(), dst, String(mtimeMs));
|
|
154
|
+
} catch (err) {
|
|
155
|
+
logger.warn("Redis session storage meta rename failed", {
|
|
156
|
+
src,
|
|
157
|
+
dst,
|
|
158
|
+
error: toError(err).message,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#fileKey(path: string): string {
|
|
164
|
+
return `${this.#prefix}file:${path}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#metaKey(): string {
|
|
168
|
+
return `${this.#prefix}meta`;
|
|
169
|
+
}
|
|
170
|
+
}
|