@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
package/src/main.ts
ADDED
|
@@ -0,0 +1,1325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for the coding agent CLI.
|
|
3
|
+
*
|
|
4
|
+
* This file handles CLI argument parsing and translates them into
|
|
5
|
+
* createAgentSession() options. The SDK does the heavy lifting.
|
|
6
|
+
*/
|
|
7
|
+
import * as fsSync from "node:fs";
|
|
8
|
+
import * as os from "node:os";
|
|
9
|
+
import { createInterface } from "node:readline/promises";
|
|
10
|
+
import { EventLoopKeepalive } from "@oh-my-pi/pi-agent-core";
|
|
11
|
+
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
12
|
+
import {
|
|
13
|
+
$env,
|
|
14
|
+
getLogPath,
|
|
15
|
+
getProjectDir,
|
|
16
|
+
logger,
|
|
17
|
+
normalizePathForComparison,
|
|
18
|
+
postmortem,
|
|
19
|
+
setProjectDir,
|
|
20
|
+
VERSION,
|
|
21
|
+
} from "@oh-my-pi/pi-utils";
|
|
22
|
+
import chalk from "chalk";
|
|
23
|
+
import { reset as resetCapabilities } from "./capability";
|
|
24
|
+
import type { Args } from "./cli/args";
|
|
25
|
+
import { applyExtensionFlags, type ExtensionFlagSink } from "./cli/extension-flags";
|
|
26
|
+
import { processFileArguments } from "./cli/file-processor";
|
|
27
|
+
import { buildInitialMessage } from "./cli/initial-message";
|
|
28
|
+
import { runListModelsCommand } from "./cli/list-models";
|
|
29
|
+
import { selectSession } from "./cli/session-picker";
|
|
30
|
+
import { applyStartupCwd } from "./cli/startup-cwd";
|
|
31
|
+
import { findConfigFile } from "./config";
|
|
32
|
+
import { ModelRegistry } from "./config/model-registry";
|
|
33
|
+
import {
|
|
34
|
+
getModelMatchPreferences,
|
|
35
|
+
resolveCliModel,
|
|
36
|
+
resolveModelRoleValue,
|
|
37
|
+
resolveModelScope,
|
|
38
|
+
type ScopedModel,
|
|
39
|
+
} from "./config/model-resolver";
|
|
40
|
+
import { ModelsConfigFile } from "./config/models-config";
|
|
41
|
+
import { getDefault, type SettingPath, Settings, settings } from "./config/settings";
|
|
42
|
+
import { initializeWithSettings } from "./discovery";
|
|
43
|
+
import {
|
|
44
|
+
clearPluginRootsAndCaches,
|
|
45
|
+
injectPluginDirRoots,
|
|
46
|
+
preloadPluginRoots,
|
|
47
|
+
resolveActiveProjectRegistryPath,
|
|
48
|
+
} from "./discovery/helpers";
|
|
49
|
+
import { injectOmpExtensionCliRoots } from "./discovery/omp-extension-roots";
|
|
50
|
+
import { ExtensionRunner } from "./extensibility/extensions/runner";
|
|
51
|
+
import type { ExtensionUIContext } from "./extensibility/extensions/types";
|
|
52
|
+
import { scheduleMarketplaceAutoUpdate } from "./extensibility/plugins/marketplace-auto-update";
|
|
53
|
+
import type { MCPManager } from "./mcp";
|
|
54
|
+
import { InteractiveMode } from "./modes/interactive-mode";
|
|
55
|
+
import type { PrintModeOptions } from "./modes/print-mode";
|
|
56
|
+
import { CURRENT_SETUP_VERSION } from "./modes/setup-version";
|
|
57
|
+
import { initTheme, stopThemeWatcher } from "./modes/theme/theme";
|
|
58
|
+
import type { SubmittedUserInput } from "./modes/types";
|
|
59
|
+
import {
|
|
60
|
+
type CreateAgentSessionOptions,
|
|
61
|
+
type CreateAgentSessionResult,
|
|
62
|
+
createAgentSession,
|
|
63
|
+
discoverAuthStorage,
|
|
64
|
+
loadSessionExtensions,
|
|
65
|
+
} from "./sdk";
|
|
66
|
+
import type { AgentSession } from "./session/agent-session";
|
|
67
|
+
import type { AuthStorage } from "./session/auth-storage";
|
|
68
|
+
import { resolveResumableSession, type SessionInfo, SessionManager } from "./session/session-manager";
|
|
69
|
+
import { discoverTitleSystemPromptFile, resolvePromptInput } from "./system-prompt";
|
|
70
|
+
import { initTelemetryExport, isTelemetryExportEnabled } from "./telemetry-export";
|
|
71
|
+
import { AUTO_THINKING } from "./thinking";
|
|
72
|
+
import type { LspStartupServerInfo } from "./tools";
|
|
73
|
+
import {
|
|
74
|
+
getChangelogPath,
|
|
75
|
+
getNewEntries,
|
|
76
|
+
parseChangelog,
|
|
77
|
+
readLastChangelogVersion,
|
|
78
|
+
writeLastChangelogVersion,
|
|
79
|
+
} from "./utils/changelog";
|
|
80
|
+
import { EventBus } from "./utils/event-bus";
|
|
81
|
+
|
|
82
|
+
type RunAcpMode = (createSession: AcpSessionFactory) => Promise<never>;
|
|
83
|
+
type RunPrintMode = (session: AgentSession, options: PrintModeOptions) => Promise<void>;
|
|
84
|
+
type RunRpcMode = (
|
|
85
|
+
session: AgentSession,
|
|
86
|
+
setToolUIContext?: (uiContext: ExtensionUIContext, hasUI: boolean) => void,
|
|
87
|
+
eventBus?: EventBus,
|
|
88
|
+
) => Promise<never>;
|
|
89
|
+
|
|
90
|
+
function maybeShowStartupSplash(options: {
|
|
91
|
+
isInteractive: boolean;
|
|
92
|
+
resuming: boolean;
|
|
93
|
+
quiet: boolean;
|
|
94
|
+
version: string;
|
|
95
|
+
}): void {
|
|
96
|
+
if (!options.isInteractive) return;
|
|
97
|
+
if (options.resuming || options.quiet) return;
|
|
98
|
+
if ($env.PI_TIMING) return;
|
|
99
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
100
|
+
//process.stdout.write(`${chalk.dim(`omp ${options.version}`)}\n${chalk.dim("Initializing session…")}\n`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function checkForNewVersion(currentVersion: string): Promise<string | undefined> {
|
|
104
|
+
if (!settings.get("startup.checkUpdate")) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const response = await fetch("https://registry.npmjs.org/@oh-my-pi/pi-coding-agent/latest");
|
|
109
|
+
if (!response.ok) return undefined;
|
|
110
|
+
|
|
111
|
+
const data = (await response.json()) as { version?: string };
|
|
112
|
+
const latestVersion = data.version;
|
|
113
|
+
|
|
114
|
+
if (latestVersion && Bun.semver.order(latestVersion, currentVersion) > 0) {
|
|
115
|
+
return latestVersion;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return undefined;
|
|
119
|
+
} catch {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const HOST_DEFAULTED_SETTING_PATHS: SettingPath[] = [
|
|
125
|
+
"todo.enabled",
|
|
126
|
+
"todo.reminders",
|
|
127
|
+
"todo.reminders.max",
|
|
128
|
+
"todo.eager",
|
|
129
|
+
"task.isolation.mode",
|
|
130
|
+
"task.isolation.merge",
|
|
131
|
+
"task.isolation.commits",
|
|
132
|
+
"task.eager",
|
|
133
|
+
"task.batch",
|
|
134
|
+
"task.maxConcurrency",
|
|
135
|
+
"task.maxRecursionDepth",
|
|
136
|
+
"task.disabledAgents",
|
|
137
|
+
"task.agentModelOverrides",
|
|
138
|
+
// Memory subsystems are off-by-default for RPC/ACP hosts; embedders that want
|
|
139
|
+
// memory should opt in explicitly through their own settings layer.
|
|
140
|
+
"memory.backend",
|
|
141
|
+
"memories.enabled",
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
const RPC_BACKGROUND_DEFAULTED_SETTING_PATHS: SettingPath[] = [
|
|
145
|
+
"async.enabled",
|
|
146
|
+
"async.maxJobs",
|
|
147
|
+
"bash.autoBackground.enabled",
|
|
148
|
+
"bash.autoBackground.thresholdMs",
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
function applyDefaultSettingOverrides(settingPaths: SettingPath[], targetSettings: Settings): void {
|
|
152
|
+
for (const settingPath of settingPaths) {
|
|
153
|
+
targetSettings.override(settingPath, getDefault(settingPath));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function applyRpcDefaultSettingOverrides(targetSettings: Settings = settings): void {
|
|
158
|
+
applyDefaultSettingOverrides(HOST_DEFAULTED_SETTING_PATHS, targetSettings);
|
|
159
|
+
applyDefaultSettingOverrides(RPC_BACKGROUND_DEFAULTED_SETTING_PATHS, targetSettings);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function applyAcpDefaultSettingOverrides(targetSettings: Settings = settings): void {
|
|
163
|
+
applyDefaultSettingOverrides(HOST_DEFAULTED_SETTING_PATHS, targetSettings);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function readPipedInput(): Promise<string | undefined> {
|
|
167
|
+
if (process.stdin.isTTY !== false) return undefined;
|
|
168
|
+
// stdin is a pipe: a producer that never writes nor closes would block
|
|
169
|
+
// startup forever with zero output. Say what we're blocked on after 1s.
|
|
170
|
+
const notice = setTimeout(() => {
|
|
171
|
+
process.stderr.write(`${chalk.dim("Reading prompt from piped stdin (waiting for EOF; ctrl+c to abort)…")}\n`);
|
|
172
|
+
}, 1000);
|
|
173
|
+
notice.unref?.();
|
|
174
|
+
try {
|
|
175
|
+
const text = await Bun.stdin.text();
|
|
176
|
+
if (text.trim().length === 0) return undefined;
|
|
177
|
+
return text;
|
|
178
|
+
} catch {
|
|
179
|
+
return undefined;
|
|
180
|
+
} finally {
|
|
181
|
+
clearTimeout(notice);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
// Startup watchdog
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// Speculative-hang reporter: until startup hands off to a mode runner, print a
|
|
189
|
+
// stderr line every 10s naming the deepest in-flight startup phase. Turns
|
|
190
|
+
// zero-output indefinite hangs (stuck discovery read, network wait, stdin
|
|
191
|
+
// pipe) into self-diagnosing reports instead of "it just hangs" (see the
|
|
192
|
+
// PI_DEBUG_STARTUP markers for the synchronous-hang counterpart).
|
|
193
|
+
|
|
194
|
+
const STARTUP_WATCHDOG_INTERVAL_MS = 10_000;
|
|
195
|
+
let startupWatchdogTimer: NodeJS.Timeout | undefined;
|
|
196
|
+
let startupWatchdogActive = false;
|
|
197
|
+
let startupWatchdogStartedAt = 0;
|
|
198
|
+
|
|
199
|
+
function armStartupWatchdog(): void {
|
|
200
|
+
if (startupWatchdogTimer) return;
|
|
201
|
+
startupWatchdogTimer = setInterval(() => {
|
|
202
|
+
const elapsed = Math.round((Date.now() - startupWatchdogStartedAt) / 1000);
|
|
203
|
+
const phase = logger.openSpanPath().join(" > ") || "module load / pre-phase work";
|
|
204
|
+
process.stderr.write(
|
|
205
|
+
`${chalk.yellow(`Still starting after ${elapsed}s`)}${chalk.dim(` — phase: ${phase}`)}\n` +
|
|
206
|
+
`${chalk.dim(` logs: ${getLogPath()} · re-run with PI_DEBUG_STARTUP=1 for streaming phase markers`)}\n`,
|
|
207
|
+
);
|
|
208
|
+
}, STARTUP_WATCHDOG_INTERVAL_MS);
|
|
209
|
+
startupWatchdogTimer.unref?.();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function disarmStartupWatchdog(): void {
|
|
213
|
+
if (!startupWatchdogTimer) return;
|
|
214
|
+
clearInterval(startupWatchdogTimer);
|
|
215
|
+
startupWatchdogTimer = undefined;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Begin watching startup (idempotent). */
|
|
219
|
+
function startStartupWatchdog(): void {
|
|
220
|
+
startupWatchdogActive = true;
|
|
221
|
+
startupWatchdogStartedAt = Date.now();
|
|
222
|
+
armStartupWatchdog();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Permanently stop watching: a mode runner now owns the terminal. */
|
|
226
|
+
function stopStartupWatchdog(): void {
|
|
227
|
+
startupWatchdogActive = false;
|
|
228
|
+
disarmStartupWatchdog();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Pause while an interactive prompt legitimately waits on the user. */
|
|
232
|
+
function pauseStartupWatchdog(): void {
|
|
233
|
+
disarmStartupWatchdog();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Resume after an interactive prompt, if startup is still being watched. */
|
|
237
|
+
function resumeStartupWatchdog(): void {
|
|
238
|
+
if (startupWatchdogActive) armStartupWatchdog();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface InteractiveModeNotify {
|
|
242
|
+
kind: "warn" | "error" | "info";
|
|
243
|
+
message: string;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export async function submitInteractiveInput(
|
|
247
|
+
mode: Pick<
|
|
248
|
+
InteractiveMode,
|
|
249
|
+
"markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested"
|
|
250
|
+
>,
|
|
251
|
+
session: Pick<AgentSession, "prompt" | "promptCustomMessage">,
|
|
252
|
+
input: SubmittedUserInput,
|
|
253
|
+
): Promise<void> {
|
|
254
|
+
if (input.cancelled) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
using _keepalive = new EventLoopKeepalive();
|
|
260
|
+
// Continue shortcuts submit an already-started synthetic developer prompt with
|
|
261
|
+
// no optimistic user message.
|
|
262
|
+
if (!input.started && !mode.markPendingSubmissionStarted(input)) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (input.customType) {
|
|
266
|
+
await session.promptCustomMessage({
|
|
267
|
+
customType: input.customType,
|
|
268
|
+
content: input.text,
|
|
269
|
+
display: input.display ?? false,
|
|
270
|
+
attribution: "agent",
|
|
271
|
+
});
|
|
272
|
+
} else if (input.synthetic) {
|
|
273
|
+
await session.prompt(input.text, { synthetic: true, expandPromptTemplates: false });
|
|
274
|
+
} else {
|
|
275
|
+
await session.prompt(input.text, { images: input.images });
|
|
276
|
+
}
|
|
277
|
+
} catch (error: unknown) {
|
|
278
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
279
|
+
mode.showError(errorMessage);
|
|
280
|
+
} finally {
|
|
281
|
+
mode.finishPendingSubmission(input);
|
|
282
|
+
await mode.checkShutdownRequested();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
type AcpSessionFactory = (cwd: string) => Promise<AgentSession>;
|
|
287
|
+
|
|
288
|
+
export interface AcpSessionFactoryOptions {
|
|
289
|
+
baseOptions: CreateAgentSessionOptions;
|
|
290
|
+
settings: Settings;
|
|
291
|
+
sessionDir?: string;
|
|
292
|
+
authStorage: AuthStorage;
|
|
293
|
+
modelRegistry: ModelRegistry;
|
|
294
|
+
parsedArgs: Pick<Args, "apiKey">;
|
|
295
|
+
rawArgs: string[];
|
|
296
|
+
createSession: (options: CreateAgentSessionOptions) => Promise<CreateAgentSessionResult>;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Build the per-`session/new` factory used by ACP mode.
|
|
301
|
+
*
|
|
302
|
+
* MCP servers in ACP sessions are owned exclusively by the ACP client, which
|
|
303
|
+
* supplies them through `session/new.mcpServers` and re-applies them via
|
|
304
|
+
* {@link AcpAgent#configureMcpServers}. We therefore force `enableMCP: false`
|
|
305
|
+
* on every session created here so {@link createAgentSession} skips the on-disk
|
|
306
|
+
* `.mcp.json` discovery path — otherwise host MCP tools land in the session's
|
|
307
|
+
* tool registry and shadow the client-supplied servers (issue #1234).
|
|
308
|
+
*/
|
|
309
|
+
export function createAcpSessionFactory(args: AcpSessionFactoryOptions): AcpSessionFactory {
|
|
310
|
+
return async cwd => {
|
|
311
|
+
const nextSettings = await args.settings.cloneForCwd(cwd);
|
|
312
|
+
const nextSessionManager = SessionManager.create(cwd, args.sessionDir);
|
|
313
|
+
const agentId = `acp:${nextSessionManager.getSessionId()}`;
|
|
314
|
+
const { session: nextSession } = await args.createSession({
|
|
315
|
+
...args.baseOptions,
|
|
316
|
+
cwd,
|
|
317
|
+
sessionManager: nextSessionManager,
|
|
318
|
+
settings: nextSettings,
|
|
319
|
+
authStorage: args.authStorage,
|
|
320
|
+
modelRegistry: args.modelRegistry,
|
|
321
|
+
agentId,
|
|
322
|
+
hasUI: false,
|
|
323
|
+
enableMCP: false,
|
|
324
|
+
});
|
|
325
|
+
if (args.parsedArgs.apiKey && !args.baseOptions.model && nextSession.model) {
|
|
326
|
+
args.authStorage.setRuntimeApiKey(nextSession.model.provider, args.parsedArgs.apiKey);
|
|
327
|
+
}
|
|
328
|
+
applyExtensionFlags(nextSession.extensionRunner, args.rawArgs);
|
|
329
|
+
return nextSession;
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
async function runInteractiveMode(
|
|
334
|
+
session: AgentSession,
|
|
335
|
+
version: string,
|
|
336
|
+
changelogMarkdown: string | undefined,
|
|
337
|
+
notifs: (InteractiveModeNotify | null)[],
|
|
338
|
+
versionCheckPromise: Promise<string | undefined>,
|
|
339
|
+
initialMessages: string[],
|
|
340
|
+
setExtensionUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void,
|
|
341
|
+
lspServers: LspStartupServerInfo[] | undefined,
|
|
342
|
+
mcpManager: MCPManager | undefined,
|
|
343
|
+
resuming: boolean,
|
|
344
|
+
forceSetupWizard: boolean,
|
|
345
|
+
eventBus?: EventBus,
|
|
346
|
+
initialMessage?: string,
|
|
347
|
+
initialImages?: ImageContent[],
|
|
348
|
+
titleSystemPrompt?: string,
|
|
349
|
+
): Promise<void> {
|
|
350
|
+
const mode = new InteractiveMode(
|
|
351
|
+
session,
|
|
352
|
+
version,
|
|
353
|
+
changelogMarkdown,
|
|
354
|
+
setExtensionUIContext,
|
|
355
|
+
lspServers,
|
|
356
|
+
mcpManager,
|
|
357
|
+
eventBus,
|
|
358
|
+
titleSystemPrompt,
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
// Cold-launch gate: the full setup wizard (every scene + the overlay and
|
|
362
|
+
// their TUI/OAuth/search/theme deps) is heavy, yet the common case only needs
|
|
363
|
+
// to know whether the stored setup version is current. Lazy-load the wizard
|
|
364
|
+
// barrel only when setup is stale or forced; otherwise skip it entirely.
|
|
365
|
+
const storedSetupVersion = settings.get("setupVersion");
|
|
366
|
+
const setupWizard =
|
|
367
|
+
forceSetupWizard || storedSetupVersion < CURRENT_SETUP_VERSION ? await import("./modes/setup-wizard") : undefined;
|
|
368
|
+
const setupScenes = setupWizard
|
|
369
|
+
? await setupWizard.selectSetupScenes(storedSetupVersion, setupWizard.ALL_SCENES, mode, {
|
|
370
|
+
resuming,
|
|
371
|
+
isTTY: process.stdin.isTTY && process.stdout.isTTY,
|
|
372
|
+
setupWizardEnabled: settings.get("startup.setupWizard"),
|
|
373
|
+
force: forceSetupWizard,
|
|
374
|
+
})
|
|
375
|
+
: [];
|
|
376
|
+
|
|
377
|
+
await mode.init({
|
|
378
|
+
suppressWelcomeIntro: resuming || setupScenes.length > 0,
|
|
379
|
+
clearInitialTerminalHistory: true,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
if (setupWizard && setupScenes.length > 0) {
|
|
383
|
+
await setupWizard.runSetupWizard(mode, setupScenes);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
versionCheckPromise
|
|
387
|
+
.then(newVersion => {
|
|
388
|
+
if (!settings.get("startup.checkUpdate")) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (newVersion) {
|
|
392
|
+
mode.showNewVersionNotification(newVersion);
|
|
393
|
+
}
|
|
394
|
+
})
|
|
395
|
+
.catch(() => {});
|
|
396
|
+
|
|
397
|
+
// Cold-launch cleanup: the first paint already clears native history, and this
|
|
398
|
+
// replay replaces the welcome/startup frame with the resumed/new transcript.
|
|
399
|
+
// Every in-process session load also uses `clearTerminalHistory`; cold launch
|
|
400
|
+
// follows the same clean-cutover path instead of preserving a previous run's
|
|
401
|
+
// transcript above the fresh one.
|
|
402
|
+
mode.renderInitialMessages({ preserveExistingChat: true, clearTerminalHistory: true });
|
|
403
|
+
|
|
404
|
+
for (const notify of notifs) {
|
|
405
|
+
if (!notify) {
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
if (notify.kind === "warn") {
|
|
409
|
+
mode.showWarning(notify.message);
|
|
410
|
+
} else if (notify.kind === "error") {
|
|
411
|
+
mode.showError(notify.message);
|
|
412
|
+
} else if (notify.kind === "info") {
|
|
413
|
+
mode.showStatus(notify.message);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (initialMessage !== undefined) {
|
|
418
|
+
try {
|
|
419
|
+
using _keepalive = new EventLoopKeepalive();
|
|
420
|
+
await session.prompt(initialMessage, { images: initialImages });
|
|
421
|
+
} catch (error: unknown) {
|
|
422
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
423
|
+
mode.showError(errorMessage);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
for (const message of initialMessages) {
|
|
428
|
+
try {
|
|
429
|
+
using _keepalive = new EventLoopKeepalive();
|
|
430
|
+
await session.prompt(message);
|
|
431
|
+
} catch (error: unknown) {
|
|
432
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
433
|
+
mode.showError(errorMessage);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
while (true) {
|
|
438
|
+
const input = await mode.getUserInput();
|
|
439
|
+
await submitInteractiveInput(mode, session, input);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
type SessionPromptResult = "accepted" | "declined" | "unavailable";
|
|
444
|
+
|
|
445
|
+
type SessionPrompt = (session: SessionInfo) => Promise<SessionPromptResult>;
|
|
446
|
+
|
|
447
|
+
async function promptForkSession(session: SessionInfo): Promise<SessionPromptResult> {
|
|
448
|
+
if (!process.stdin.isTTY) {
|
|
449
|
+
return "unavailable";
|
|
450
|
+
}
|
|
451
|
+
const message = `Session found in different project: ${session.cwd}. Fork into current directory? [y/N] `;
|
|
452
|
+
pauseStartupWatchdog();
|
|
453
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
454
|
+
try {
|
|
455
|
+
const answer = (await rl.question(message)).trim().toLowerCase();
|
|
456
|
+
return answer === "y" || answer === "yes" ? "accepted" : "declined";
|
|
457
|
+
} finally {
|
|
458
|
+
rl.close();
|
|
459
|
+
resumeStartupWatchdog();
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
async function promptMoveSession(session: SessionInfo): Promise<SessionPromptResult> {
|
|
464
|
+
if (!process.stdin.isTTY) {
|
|
465
|
+
return "unavailable";
|
|
466
|
+
}
|
|
467
|
+
const message = `Session's directory no longer exists (${session.cwd}). Move (re-root) it into the current directory? [Y/n] `;
|
|
468
|
+
pauseStartupWatchdog();
|
|
469
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
470
|
+
try {
|
|
471
|
+
const answer = (await rl.question(message)).trim().toLowerCase();
|
|
472
|
+
return answer === "" || answer === "y" || answer === "yes" ? "accepted" : "declined";
|
|
473
|
+
} finally {
|
|
474
|
+
rl.close();
|
|
475
|
+
resumeStartupWatchdog();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Friendly CLI failure raised by {@link createSessionManager} when the user's
|
|
481
|
+
* session-resolution flags (`--resume`/`--fork`/cross-project prompts) cannot
|
|
482
|
+
* be satisfied. {@link runRootCommand} catches it and prints a clean stderr
|
|
483
|
+
* message instead of letting it surface as `[Uncaught Exception]`
|
|
484
|
+
* (see issue #2084).
|
|
485
|
+
*/
|
|
486
|
+
export class SessionResolutionError extends Error {
|
|
487
|
+
readonly hint?: string;
|
|
488
|
+
constructor(message: string, hint?: string) {
|
|
489
|
+
super(message);
|
|
490
|
+
this.name = "SessionResolutionError";
|
|
491
|
+
this.hint = hint;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
type MissingCwdMoveResult =
|
|
496
|
+
| { status: "not-needed" }
|
|
497
|
+
| { status: "declined" }
|
|
498
|
+
| { status: "moved"; manager: SessionManager };
|
|
499
|
+
|
|
500
|
+
async function moveMissingCwdSessionIfNeeded(
|
|
501
|
+
sessionArg: string,
|
|
502
|
+
session: SessionInfo,
|
|
503
|
+
cwd: string,
|
|
504
|
+
sessionDir: string | undefined,
|
|
505
|
+
askToMoveSession: SessionPrompt,
|
|
506
|
+
): Promise<MissingCwdMoveResult> {
|
|
507
|
+
const sourceCwd = session.cwd;
|
|
508
|
+
if (!sourceCwd || fsSync.existsSync(sourceCwd)) {
|
|
509
|
+
return { status: "not-needed" };
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const movePromptResult = await askToMoveSession(session);
|
|
513
|
+
if (movePromptResult === "unavailable") {
|
|
514
|
+
throw new SessionResolutionError(
|
|
515
|
+
`Session "${sessionArg}" belongs to a directory that no longer exists (${sourceCwd}); run interactively to move it into the current project.`,
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
if (movePromptResult === "declined") {
|
|
519
|
+
return { status: "declined" };
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const manager = await SessionManager.open(session.path, sessionDir);
|
|
523
|
+
await manager.moveTo(cwd, sessionDir);
|
|
524
|
+
return { status: "moved", manager };
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
async function getChangelogForDisplay(parsed: Args): Promise<string | undefined> {
|
|
528
|
+
if (parsed.continue || parsed.resume) {
|
|
529
|
+
return undefined;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const lastVersion = await readLastChangelogVersion();
|
|
533
|
+
if (lastVersion === VERSION) {
|
|
534
|
+
// Steady state: user already saw the current version's changelog. Skip the file read + parse.
|
|
535
|
+
return undefined;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const changelogPath = getChangelogPath();
|
|
539
|
+
const entries = await parseChangelog(changelogPath);
|
|
540
|
+
|
|
541
|
+
if (!lastVersion) {
|
|
542
|
+
if (entries.length > 0) {
|
|
543
|
+
await writeLastChangelogVersion(VERSION);
|
|
544
|
+
return entries.map(e => e.content).join("\n\n");
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
const newEntries = getNewEntries(entries, lastVersion);
|
|
548
|
+
if (newEntries.length > 0) {
|
|
549
|
+
await writeLastChangelogVersion(VERSION);
|
|
550
|
+
return newEntries.map(e => e.content).join("\n\n");
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
return undefined;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/** Resolves CLI session flags into an existing, forked, in-memory, or cancelled session manager. */
|
|
558
|
+
export async function createSessionManager(
|
|
559
|
+
parsed: Args,
|
|
560
|
+
cwd: string,
|
|
561
|
+
activeSettings: Settings = settings,
|
|
562
|
+
askToForkSession: SessionPrompt = promptForkSession,
|
|
563
|
+
askToMoveSession: SessionPrompt = promptMoveSession,
|
|
564
|
+
): Promise<SessionManager | undefined> {
|
|
565
|
+
if (parsed.fork) {
|
|
566
|
+
if (parsed.noSession) {
|
|
567
|
+
throw new SessionResolutionError("--fork requires session persistence");
|
|
568
|
+
}
|
|
569
|
+
const forkSource = parsed.fork;
|
|
570
|
+
if (forkSource.includes("/") || forkSource.includes("\\") || forkSource.endsWith(".jsonl")) {
|
|
571
|
+
return await SessionManager.forkFrom(forkSource, cwd, parsed.sessionDir);
|
|
572
|
+
}
|
|
573
|
+
const match = await resolveResumableSession(forkSource, cwd, parsed.sessionDir);
|
|
574
|
+
if (!match) {
|
|
575
|
+
throw new SessionResolutionError(
|
|
576
|
+
`Session "${forkSource}" not found.`,
|
|
577
|
+
"Run `omp --resume` without an argument to pick from recent sessions, or `omp` to start a new one.",
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
return await SessionManager.forkFrom(match.session.path, cwd, parsed.sessionDir);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
if (parsed.noSession) {
|
|
584
|
+
return SessionManager.inMemory();
|
|
585
|
+
}
|
|
586
|
+
if (typeof parsed.resume === "string") {
|
|
587
|
+
const sessionArg = parsed.resume;
|
|
588
|
+
if (sessionArg.includes("/") || sessionArg.includes("\\") || sessionArg.endsWith(".jsonl")) {
|
|
589
|
+
return await SessionManager.open(sessionArg, parsed.sessionDir);
|
|
590
|
+
}
|
|
591
|
+
const match = await resolveResumableSession(sessionArg, cwd, parsed.sessionDir);
|
|
592
|
+
if (!match) {
|
|
593
|
+
throw new SessionResolutionError(
|
|
594
|
+
`Session "${sessionArg}" not found.`,
|
|
595
|
+
"Run `omp --resume` without an argument to pick from recent sessions, or `omp` to start a new one.",
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
if (match.scope === "local") {
|
|
599
|
+
const moveResult = await moveMissingCwdSessionIfNeeded(
|
|
600
|
+
sessionArg,
|
|
601
|
+
match.session,
|
|
602
|
+
cwd,
|
|
603
|
+
parsed.sessionDir,
|
|
604
|
+
askToMoveSession,
|
|
605
|
+
);
|
|
606
|
+
if (moveResult.status === "moved") {
|
|
607
|
+
return moveResult.manager;
|
|
608
|
+
}
|
|
609
|
+
if (moveResult.status === "declined") {
|
|
610
|
+
return undefined;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
if (match.scope === "global") {
|
|
614
|
+
const normalizedCwd = normalizePathForComparison(cwd);
|
|
615
|
+
const normalizedMatchCwd = normalizePathForComparison(match.session.cwd || cwd);
|
|
616
|
+
if (normalizedCwd !== normalizedMatchCwd) {
|
|
617
|
+
const moveResult = await moveMissingCwdSessionIfNeeded(
|
|
618
|
+
sessionArg,
|
|
619
|
+
match.session,
|
|
620
|
+
cwd,
|
|
621
|
+
parsed.sessionDir,
|
|
622
|
+
askToMoveSession,
|
|
623
|
+
);
|
|
624
|
+
if (moveResult.status === "moved") {
|
|
625
|
+
return moveResult.manager;
|
|
626
|
+
}
|
|
627
|
+
if (moveResult.status === "declined") {
|
|
628
|
+
return undefined;
|
|
629
|
+
}
|
|
630
|
+
const forkPromptResult = await askToForkSession(match.session);
|
|
631
|
+
if (forkPromptResult === "unavailable") {
|
|
632
|
+
throw new SessionResolutionError(
|
|
633
|
+
`Session "${sessionArg}" is in another project (${match.session.cwd}); run interactively to fork it into the current project.`,
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
if (forkPromptResult === "declined") {
|
|
637
|
+
// User declined the cross-project fork prompt. Caller distinguishes
|
|
638
|
+
// this cancellation from the "default new session" undefined return
|
|
639
|
+
// by checking `typeof parsed.resume === "string"`.
|
|
640
|
+
return undefined;
|
|
641
|
+
}
|
|
642
|
+
return await SessionManager.forkFrom(match.session.path, cwd, parsed.sessionDir);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return await SessionManager.open(match.session.path, parsed.sessionDir);
|
|
646
|
+
}
|
|
647
|
+
if (parsed.continue) {
|
|
648
|
+
return await SessionManager.continueRecent(cwd, parsed.sessionDir);
|
|
649
|
+
}
|
|
650
|
+
// --resume without value is handled separately (needs picker UI)
|
|
651
|
+
// If --session-dir provided without --continue/--resume, create new session there
|
|
652
|
+
if (parsed.sessionDir) {
|
|
653
|
+
return SessionManager.create(cwd, parsed.sessionDir);
|
|
654
|
+
}
|
|
655
|
+
// Auto-resume: behave like --continue if the setting is enabled and a prior
|
|
656
|
+
// session exists. When a prior session is resumed, mark parsed.continue so
|
|
657
|
+
// buildSessionOptions restores the session's model/thinking instead of
|
|
658
|
+
// overriding them with CLI defaults.
|
|
659
|
+
if (activeSettings.get("autoResume")) {
|
|
660
|
+
const manager = await SessionManager.continueRecent(cwd, parsed.sessionDir);
|
|
661
|
+
if (manager.getEntries().length > 0) {
|
|
662
|
+
parsed.continue = true;
|
|
663
|
+
}
|
|
664
|
+
return manager;
|
|
665
|
+
}
|
|
666
|
+
// Default case (new session) returns undefined, SDK will create one
|
|
667
|
+
return undefined;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/** Discover SYSTEM.md file if no CLI system prompt was provided */
|
|
671
|
+
function discoverSystemPromptFile(): string | undefined {
|
|
672
|
+
// Check project-local first (.omp/SYSTEM.md, .pi/SYSTEM.md legacy)
|
|
673
|
+
const projectPath = findConfigFile("SYSTEM.md", { user: false });
|
|
674
|
+
if (projectPath) {
|
|
675
|
+
return projectPath;
|
|
676
|
+
}
|
|
677
|
+
// If not found, check SYSTEM.md file in the global directory.
|
|
678
|
+
const globalPath = findConfigFile("SYSTEM.md", { user: true });
|
|
679
|
+
if (globalPath) {
|
|
680
|
+
return globalPath;
|
|
681
|
+
}
|
|
682
|
+
return undefined;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/** Discover APPEND_SYSTEM.md file if no CLI append system prompt was provided */
|
|
686
|
+
function discoverAppendSystemPromptFile(): string | undefined {
|
|
687
|
+
const projectPath = findConfigFile("APPEND_SYSTEM.md", { user: false });
|
|
688
|
+
if (projectPath) {
|
|
689
|
+
return projectPath;
|
|
690
|
+
}
|
|
691
|
+
const globalPath = findConfigFile("APPEND_SYSTEM.md", { user: true });
|
|
692
|
+
if (globalPath) {
|
|
693
|
+
return globalPath;
|
|
694
|
+
}
|
|
695
|
+
return undefined;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
async function buildSessionOptions(
|
|
699
|
+
parsed: Args,
|
|
700
|
+
scopedModels: ScopedModel[],
|
|
701
|
+
sessionManager: SessionManager | undefined,
|
|
702
|
+
modelRegistry: ModelRegistry,
|
|
703
|
+
activeSettings: Settings,
|
|
704
|
+
): Promise<{ options: CreateAgentSessionOptions; titleSystemPrompt?: string }> {
|
|
705
|
+
const options: CreateAgentSessionOptions = {
|
|
706
|
+
cwd: parsed.cwd ?? getProjectDir(),
|
|
707
|
+
autoApprove: parsed.autoApprove ?? false,
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
// Auto-discover SYSTEM.md if no CLI system prompt provided
|
|
711
|
+
const systemPromptSource = parsed.systemPrompt ?? discoverSystemPromptFile();
|
|
712
|
+
const resolvedSystemPrompt = await resolvePromptInput(systemPromptSource, "system prompt");
|
|
713
|
+
const appendPromptSource = parsed.appendSystemPrompt ?? discoverAppendSystemPromptFile();
|
|
714
|
+
const resolvedAppendPrompt = await resolvePromptInput(appendPromptSource, "append system prompt");
|
|
715
|
+
const titleSystemPromptSource = discoverTitleSystemPromptFile();
|
|
716
|
+
const titleSystemPrompt = await resolvePromptInput(titleSystemPromptSource, "title system prompt");
|
|
717
|
+
|
|
718
|
+
if (sessionManager) {
|
|
719
|
+
options.sessionManager = sessionManager;
|
|
720
|
+
}
|
|
721
|
+
if (parsed.providerSessionId) {
|
|
722
|
+
options.providerSessionId = parsed.providerSessionId;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Model from CLI
|
|
726
|
+
// - supports --provider <name> --model <pattern>
|
|
727
|
+
// - supports --model <provider>/<pattern>
|
|
728
|
+
const modelMatchPreferences = getModelMatchPreferences(activeSettings);
|
|
729
|
+
if (parsed.model) {
|
|
730
|
+
const resolved = resolveCliModel({
|
|
731
|
+
cliProvider: parsed.provider,
|
|
732
|
+
cliModel: parsed.model,
|
|
733
|
+
modelRegistry,
|
|
734
|
+
preferences: modelMatchPreferences,
|
|
735
|
+
});
|
|
736
|
+
if (resolved.warning) {
|
|
737
|
+
process.stderr.write(`${chalk.yellow(`Warning: ${resolved.warning}`)}\n`);
|
|
738
|
+
}
|
|
739
|
+
if (resolved.error) {
|
|
740
|
+
if (!parsed.provider && !parsed.model.includes(":")) {
|
|
741
|
+
// Model not found in built-in registry — defer resolution to after extensions load
|
|
742
|
+
// (extensions may register additional providers/models via registerProvider)
|
|
743
|
+
options.modelPattern = parsed.model;
|
|
744
|
+
} else {
|
|
745
|
+
process.stderr.write(`${chalk.red(resolved.error)}\n`);
|
|
746
|
+
process.exit(1);
|
|
747
|
+
}
|
|
748
|
+
} else if (resolved.model) {
|
|
749
|
+
options.model = resolved.model;
|
|
750
|
+
activeSettings.overrideModelRoles({
|
|
751
|
+
default: resolved.selector ?? `${resolved.model.provider}/${resolved.model.id}`,
|
|
752
|
+
});
|
|
753
|
+
if (!parsed.thinking && resolved.thinkingLevel) {
|
|
754
|
+
options.thinkingLevel = resolved.thinkingLevel;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {
|
|
758
|
+
const remembered = activeSettings.getModelRole("default");
|
|
759
|
+
if (remembered) {
|
|
760
|
+
const rememberedSpec = resolveModelRoleValue(
|
|
761
|
+
remembered,
|
|
762
|
+
scopedModels.map(scopedModel => scopedModel.model),
|
|
763
|
+
{
|
|
764
|
+
settings: activeSettings,
|
|
765
|
+
matchPreferences: modelMatchPreferences,
|
|
766
|
+
modelRegistry,
|
|
767
|
+
},
|
|
768
|
+
);
|
|
769
|
+
const rememberedResolvedModel = rememberedSpec.model;
|
|
770
|
+
const rememberedModel = rememberedResolvedModel
|
|
771
|
+
? scopedModels.find(
|
|
772
|
+
scopedModel =>
|
|
773
|
+
scopedModel.model.provider === rememberedResolvedModel.provider &&
|
|
774
|
+
scopedModel.model.id === rememberedResolvedModel.id,
|
|
775
|
+
)
|
|
776
|
+
: scopedModels.find(scopedModel => scopedModel.model.id.toLowerCase() === remembered.toLowerCase());
|
|
777
|
+
if (rememberedModel) {
|
|
778
|
+
options.model = rememberedModel.model;
|
|
779
|
+
// Apply explicit thinking level from remembered role value
|
|
780
|
+
if (!parsed.thinking && rememberedSpec.explicitThinkingLevel && rememberedSpec.thinkingLevel) {
|
|
781
|
+
options.thinkingLevel = rememberedSpec.thinkingLevel;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (!options.model) options.model = scopedModels[0].model;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// Thinking level
|
|
789
|
+
if (parsed.thinking) {
|
|
790
|
+
options.thinkingLevel = parsed.thinking;
|
|
791
|
+
} else if (
|
|
792
|
+
scopedModels.length > 0 &&
|
|
793
|
+
scopedModels[0].explicitThinkingLevel === true &&
|
|
794
|
+
!parsed.continue &&
|
|
795
|
+
!parsed.resume
|
|
796
|
+
) {
|
|
797
|
+
options.thinkingLevel = scopedModels[0].thinkingLevel;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// Scoped models for Ctrl+P cycling - fill in default thinking levels when not explicit
|
|
801
|
+
if (scopedModels.length > 0) {
|
|
802
|
+
// `auto` is a session-level concept only; per-scoped-model (Ctrl+P) thinking
|
|
803
|
+
// overrides stay concrete, so coerce the auto default to "unset" here.
|
|
804
|
+
const defaultThinkingLevelSetting = activeSettings.get("defaultThinkingLevel");
|
|
805
|
+
const defaultThinkingLevel =
|
|
806
|
+
defaultThinkingLevelSetting === AUTO_THINKING ? undefined : defaultThinkingLevelSetting;
|
|
807
|
+
options.scopedModels = scopedModels.map(scopedModel => ({
|
|
808
|
+
model: scopedModel.model,
|
|
809
|
+
thinkingLevel: scopedModel.explicitThinkingLevel
|
|
810
|
+
? (scopedModel.thinkingLevel ?? defaultThinkingLevel)
|
|
811
|
+
: defaultThinkingLevel,
|
|
812
|
+
}));
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// API key from CLI - set in authStorage
|
|
816
|
+
// (handled by caller before createAgentSession)
|
|
817
|
+
|
|
818
|
+
// System prompt
|
|
819
|
+
if (resolvedSystemPrompt && resolvedAppendPrompt) {
|
|
820
|
+
options.systemPrompt = defaultPrompt => [resolvedSystemPrompt, resolvedAppendPrompt, ...defaultPrompt.slice(1)];
|
|
821
|
+
} else if (resolvedSystemPrompt) {
|
|
822
|
+
options.systemPrompt = defaultPrompt => [resolvedSystemPrompt, ...defaultPrompt.slice(1)];
|
|
823
|
+
} else if (resolvedAppendPrompt) {
|
|
824
|
+
options.systemPrompt = defaultPrompt => [...defaultPrompt, resolvedAppendPrompt];
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Tools
|
|
828
|
+
if (parsed.noTools) {
|
|
829
|
+
options.toolNames = parsed.tools && parsed.tools.length > 0 ? parsed.tools : [];
|
|
830
|
+
} else if (parsed.tools) {
|
|
831
|
+
options.toolNames = parsed.tools;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
if (parsed.noLsp) {
|
|
835
|
+
options.enableLsp = false;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// Skills
|
|
839
|
+
if (parsed.noSkills) {
|
|
840
|
+
options.skills = [];
|
|
841
|
+
} else if (parsed.skills && parsed.skills.length > 0) {
|
|
842
|
+
// Override includeSkills for this session
|
|
843
|
+
activeSettings.override("skills.includeSkills", parsed.skills as string[]);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
// Rules
|
|
847
|
+
if (parsed.noRules) {
|
|
848
|
+
options.rules = [];
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Additional extension paths from CLI
|
|
852
|
+
const cliExtensionPaths = parsed.noExtensions ? [] : [...(parsed.extensions ?? []), ...(parsed.hooks ?? [])];
|
|
853
|
+
if (cliExtensionPaths.length > 0) {
|
|
854
|
+
options.additionalExtensionPaths = cliExtensionPaths;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
if (parsed.noExtensions) {
|
|
858
|
+
options.disableExtensionDiscovery = true;
|
|
859
|
+
options.additionalExtensionPaths = [];
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
return { options, titleSystemPrompt };
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
interface RunRootCommandDependencies {
|
|
866
|
+
createAgentSession?: typeof createAgentSession;
|
|
867
|
+
discoverAuthStorage?: typeof discoverAuthStorage;
|
|
868
|
+
runAcpMode?: RunAcpMode;
|
|
869
|
+
settings?: Settings;
|
|
870
|
+
forceSetupWizard?: boolean;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
export async function runRootCommand(
|
|
874
|
+
parsed: Args,
|
|
875
|
+
rawArgs: string[],
|
|
876
|
+
deps: RunRootCommandDependencies = {},
|
|
877
|
+
): Promise<void> {
|
|
878
|
+
logger.startTiming();
|
|
879
|
+
startStartupWatchdog();
|
|
880
|
+
|
|
881
|
+
// Initialize theme early with defaults (CLI commands need symbols)
|
|
882
|
+
// Will be re-initialized with user preferences later
|
|
883
|
+
await logger.time("initTheme:initial", initTheme);
|
|
884
|
+
|
|
885
|
+
const parsedArgs = parsed;
|
|
886
|
+
await logger.time("applyStartupCwd", applyStartupCwd, parsedArgs);
|
|
887
|
+
|
|
888
|
+
const notifs: (InteractiveModeNotify | null)[] = [];
|
|
889
|
+
|
|
890
|
+
// Create AuthStorage and ModelRegistry upfront
|
|
891
|
+
const authStorage = await logger.time("discoverAuthStorage", deps.discoverAuthStorage ?? discoverAuthStorage);
|
|
892
|
+
const modelRegistry = new ModelRegistry(authStorage);
|
|
893
|
+
|
|
894
|
+
if (parsedArgs.version) {
|
|
895
|
+
process.stdout.write(`${VERSION}\n`);
|
|
896
|
+
process.exit(0);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if (parsedArgs.listModels !== undefined) {
|
|
900
|
+
const settingsInstance = await logger.time("settings:init:list-models", Settings.init, {
|
|
901
|
+
cwd: getProjectDir(),
|
|
902
|
+
configFiles: parsedArgs.config,
|
|
903
|
+
});
|
|
904
|
+
await modelRegistry.refresh("online");
|
|
905
|
+
const cliExtensionPaths = parsedArgs.noExtensions
|
|
906
|
+
? []
|
|
907
|
+
: [...(parsedArgs.extensions ?? []), ...(parsedArgs.hooks ?? [])];
|
|
908
|
+
const settingsExtensions = settingsInstance.get("extensions") ?? [];
|
|
909
|
+
const disabledExtensionIds = settingsInstance.get("disabledExtensions") ?? [];
|
|
910
|
+
const searchPattern = typeof parsedArgs.listModels === "string" ? parsedArgs.listModels : undefined;
|
|
911
|
+
await runListModelsCommand({
|
|
912
|
+
modelRegistry,
|
|
913
|
+
cwd: getProjectDir(),
|
|
914
|
+
additionalExtensionPaths: cliExtensionPaths,
|
|
915
|
+
settingsExtensions,
|
|
916
|
+
disabledExtensionIds,
|
|
917
|
+
disableExtensionDiscovery: Boolean(parsedArgs.noExtensions),
|
|
918
|
+
searchPattern,
|
|
919
|
+
});
|
|
920
|
+
process.exit(0);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
if (parsedArgs.export) {
|
|
924
|
+
let result: string;
|
|
925
|
+
try {
|
|
926
|
+
const outputPath = parsedArgs.messages.length > 0 ? parsedArgs.messages[0] : undefined;
|
|
927
|
+
const { exportFromFile } = await import("./export/html");
|
|
928
|
+
result = await exportFromFile(parsedArgs.export, outputPath);
|
|
929
|
+
} catch (error: unknown) {
|
|
930
|
+
const message = error instanceof Error ? error.message : "Failed to export session";
|
|
931
|
+
process.stderr.write(`${chalk.red(`Error: ${message}`)}\n`);
|
|
932
|
+
process.exit(1);
|
|
933
|
+
}
|
|
934
|
+
process.stdout.write(`Exported to: ${result}\n`);
|
|
935
|
+
process.exit(0);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
if ((parsedArgs.mode === "rpc" || parsedArgs.mode === "rpc-ui") && parsedArgs.fileArgs.length > 0) {
|
|
939
|
+
process.stderr.write(`${chalk.red("Error: @file arguments are not supported in RPC mode")}\n`);
|
|
940
|
+
process.exit(1);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// Kick off plugin-root preload in parallel with the remaining startup work.
|
|
944
|
+
// Awaited later (before extension/skill discovery in createAgentSession needs it).
|
|
945
|
+
const home = os.homedir();
|
|
946
|
+
const pluginPreloadPromise =
|
|
947
|
+
parsedArgs.pluginDirs && parsedArgs.pluginDirs.length > 0
|
|
948
|
+
? logger.time("injectPluginDirRoots", injectPluginDirRoots, home, parsedArgs.pluginDirs, getProjectDir())
|
|
949
|
+
: logger.time("preloadPluginRoots", preloadPluginRoots, home, getProjectDir());
|
|
950
|
+
// Mark the promise as handled so a synchronous failure does not surface as an unhandled-rejection
|
|
951
|
+
// warning before we reach the await site below.
|
|
952
|
+
pluginPreloadPromise.catch(() => {});
|
|
953
|
+
|
|
954
|
+
// Register CLI-provided extension package paths (`--extension`, `--hook`) so
|
|
955
|
+
// the `omp-plugins` discovery provider can surface their `skills/`, `hooks/`,
|
|
956
|
+
// `tools/`, `commands/`, `rules/`, `prompts/`, and `.mcp.json` sub-trees.
|
|
957
|
+
// `--no-extensions` short-circuits both the factory load and the sub-discovery.
|
|
958
|
+
if (!parsedArgs.noExtensions) {
|
|
959
|
+
const cliExtensions = [...(parsedArgs.extensions ?? []), ...(parsedArgs.hooks ?? [])];
|
|
960
|
+
if (cliExtensions.length > 0) {
|
|
961
|
+
injectOmpExtensionCliRoots(cliExtensions, home, getProjectDir());
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
let cwd = getProjectDir();
|
|
966
|
+
const settingsInstance =
|
|
967
|
+
deps.settings ?? (await logger.time("settings:init", Settings.init, { cwd, configFiles: parsedArgs.config }));
|
|
968
|
+
if (parsedArgs.approvalMode) {
|
|
969
|
+
// Runtime override (not persisted): every settings.get("tools.approvalMode") downstream
|
|
970
|
+
// sees this value. The wrapper still honours --auto-approve / --yolo on top of it.
|
|
971
|
+
settingsInstance.override("tools.approvalMode", parsedArgs.approvalMode);
|
|
972
|
+
} else if (parsedArgs.autoApprove) {
|
|
973
|
+
// --auto-approve / --yolo without an explicit --approval-mode: reflect in settings so
|
|
974
|
+
// setup-time checks (e.g. #wrapToolForAcpPermission) also see the yolo intent.
|
|
975
|
+
settingsInstance.override("tools.approvalMode", "yolo");
|
|
976
|
+
}
|
|
977
|
+
if (parsedArgs.mode === "rpc" || parsedArgs.mode === "rpc-ui") {
|
|
978
|
+
applyRpcDefaultSettingOverrides(settingsInstance);
|
|
979
|
+
} else if (parsedArgs.mode === "acp") {
|
|
980
|
+
applyAcpDefaultSettingOverrides(settingsInstance);
|
|
981
|
+
}
|
|
982
|
+
if (parsedArgs.noPty || parsedArgs.mode === "rpc-ui") {
|
|
983
|
+
Bun.env.PI_NO_PTY = "1";
|
|
984
|
+
}
|
|
985
|
+
if (parsedArgs.noTitle || parsedArgs.mode === "rpc" || parsedArgs.mode === "rpc-ui" || parsedArgs.mode === "acp") {
|
|
986
|
+
Bun.env.PI_NO_TITLE = "1";
|
|
987
|
+
}
|
|
988
|
+
const mode = parsedArgs.mode || "text";
|
|
989
|
+
const isProtocolMode = mode === "rpc" || mode === "rpc-ui" || mode === "acp";
|
|
990
|
+
// Protocol modes own stdin; treating it as prompt text would consume JSON-RPC frames before their transports start.
|
|
991
|
+
const pipedInput = isProtocolMode ? undefined : await logger.time("readPipedInput", readPipedInput);
|
|
992
|
+
const autoPrint = pipedInput !== undefined && !parsedArgs.print && parsedArgs.mode === undefined;
|
|
993
|
+
const isInteractive = !parsedArgs.print && !autoPrint && parsedArgs.mode === undefined;
|
|
994
|
+
|
|
995
|
+
// Initialize discovery system with settings for provider persistence
|
|
996
|
+
logger.time("initializeWithSettings", initializeWithSettings, settingsInstance);
|
|
997
|
+
|
|
998
|
+
// Apply model role overrides from CLI args or env vars (ephemeral, not persisted)
|
|
999
|
+
const smolModel = parsedArgs.smol ?? $env.PI_SMOL_MODEL;
|
|
1000
|
+
const slowModel = parsedArgs.slow ?? $env.PI_SLOW_MODEL;
|
|
1001
|
+
const planModel = parsedArgs.plan ?? $env.PI_PLAN_MODEL;
|
|
1002
|
+
if (smolModel || slowModel || planModel) {
|
|
1003
|
+
settingsInstance.overrideModelRoles({
|
|
1004
|
+
smol: smolModel,
|
|
1005
|
+
slow: slowModel,
|
|
1006
|
+
plan: planModel,
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Apply --hide-thinking CLI flag (ephemeral, not persisted)
|
|
1011
|
+
if (parsedArgs.hideThinking) {
|
|
1012
|
+
settingsInstance.override("hideThinkingBlock", true);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
await logger.time(
|
|
1016
|
+
"initTheme:final",
|
|
1017
|
+
initTheme,
|
|
1018
|
+
isInteractive,
|
|
1019
|
+
settingsInstance.get("symbolPreset"),
|
|
1020
|
+
settingsInstance.get("colorBlindMode"),
|
|
1021
|
+
settingsInstance.get("theme.dark"),
|
|
1022
|
+
settingsInstance.get("theme.light"),
|
|
1023
|
+
);
|
|
1024
|
+
|
|
1025
|
+
let scopedModels: ScopedModel[] = [];
|
|
1026
|
+
const modelPatterns = parsedArgs.models ?? settingsInstance.get("enabledModels");
|
|
1027
|
+
const modelMatchPreferences = getModelMatchPreferences(settingsInstance);
|
|
1028
|
+
if (modelPatterns && modelPatterns.length > 0) {
|
|
1029
|
+
scopedModels = await logger.time(
|
|
1030
|
+
"resolveModelScope",
|
|
1031
|
+
resolveModelScope,
|
|
1032
|
+
modelPatterns,
|
|
1033
|
+
modelRegistry,
|
|
1034
|
+
modelMatchPreferences,
|
|
1035
|
+
);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// Create session manager based on CLI flags. SessionResolutionError signals a
|
|
1039
|
+
// user-facing failure (unknown --resume/--fork id, non-interactive fork
|
|
1040
|
+
// prompt, --fork with --no-session): print + exit cleanly instead of letting
|
|
1041
|
+
// it surface as `[Uncaught Exception]` (see issue #2084).
|
|
1042
|
+
let sessionManager: SessionManager | undefined;
|
|
1043
|
+
try {
|
|
1044
|
+
sessionManager = await logger.time(
|
|
1045
|
+
"createSessionManager",
|
|
1046
|
+
createSessionManager,
|
|
1047
|
+
parsedArgs,
|
|
1048
|
+
cwd,
|
|
1049
|
+
settingsInstance,
|
|
1050
|
+
);
|
|
1051
|
+
} catch (error: unknown) {
|
|
1052
|
+
if (error instanceof SessionResolutionError) {
|
|
1053
|
+
process.stderr.write(`${chalk.red(`Error: ${error.message}`)}\n`);
|
|
1054
|
+
if (error.hint) {
|
|
1055
|
+
process.stderr.write(`${chalk.dim(error.hint)}\n`);
|
|
1056
|
+
}
|
|
1057
|
+
process.exit(1);
|
|
1058
|
+
}
|
|
1059
|
+
throw error;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
// User declined the cross-project fork prompt — exit cleanly with a friendly
|
|
1063
|
+
// message rather than letting the decline bubble up as an uncaught exception
|
|
1064
|
+
// (see issue #1668).
|
|
1065
|
+
if (typeof parsedArgs.resume === "string" && !sessionManager) {
|
|
1066
|
+
process.stdout.write(`${chalk.dim("Resume cancelled: session is in another project.")}\n`);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// Handle --resume (no value): show session picker
|
|
1071
|
+
if (parsedArgs.resume === true && !parsedArgs.fork) {
|
|
1072
|
+
const folderSessions = await logger.time("SessionManager.list", SessionManager.list, cwd, parsedArgs.sessionDir);
|
|
1073
|
+
let preloadedAllSessions: SessionInfo[] | undefined;
|
|
1074
|
+
let startInAllScope = false;
|
|
1075
|
+
if (folderSessions.length === 0) {
|
|
1076
|
+
// Nothing in the current folder — fall back to a global scan so the
|
|
1077
|
+
// picker can still open in all-projects scope instead of dead-ending.
|
|
1078
|
+
preloadedAllSessions = await logger.time("SessionManager.listAll", SessionManager.listAll);
|
|
1079
|
+
if (preloadedAllSessions.length === 0) {
|
|
1080
|
+
process.stdout.write(`${chalk.dim("No sessions found")}\n`);
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
startInAllScope = true;
|
|
1084
|
+
}
|
|
1085
|
+
pauseStartupWatchdog();
|
|
1086
|
+
const selected = await logger.time("selectSession", selectSession, folderSessions, {
|
|
1087
|
+
allSessions: preloadedAllSessions,
|
|
1088
|
+
startInAllScope,
|
|
1089
|
+
});
|
|
1090
|
+
resumeStartupWatchdog();
|
|
1091
|
+
if (!selected) {
|
|
1092
|
+
process.stdout.write(`${chalk.dim("No session selected")}\n`);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
// Resuming a session from another project: switch the process into that
|
|
1096
|
+
// project's directory and refresh cwd-derived caches before the session is
|
|
1097
|
+
// built, so settings discovery, plugins, and capabilities all scope to it.
|
|
1098
|
+
if (selected.cwd && normalizePathForComparison(selected.cwd) !== normalizePathForComparison(getProjectDir())) {
|
|
1099
|
+
// Let the original (launch-cwd) plugin-root preload settle first so its
|
|
1100
|
+
// late resolution can't clobber the re-warm we trigger below.
|
|
1101
|
+
await pluginPreloadPromise.catch(() => {});
|
|
1102
|
+
setProjectDir(selected.cwd);
|
|
1103
|
+
clearPluginRootsAndCaches();
|
|
1104
|
+
resetCapabilities();
|
|
1105
|
+
cwd = getProjectDir();
|
|
1106
|
+
// Re-scope project settings (.claude/settings.yml etc.) to the resumed
|
|
1107
|
+
// project in place so the session is built with its configuration.
|
|
1108
|
+
await settingsInstance.reloadForCwd(cwd);
|
|
1109
|
+
}
|
|
1110
|
+
sessionManager = await SessionManager.open(selected.path);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
await pluginPreloadPromise;
|
|
1114
|
+
|
|
1115
|
+
scheduleMarketplaceAutoUpdate({
|
|
1116
|
+
autoUpdate: settingsInstance.get("marketplace.autoUpdate"),
|
|
1117
|
+
resolveActiveProjectRegistryPath,
|
|
1118
|
+
clearPluginRootsCache: clearPluginRootsAndCaches,
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
const { options: sessionOptions, titleSystemPrompt } = await logger.time(
|
|
1122
|
+
"buildSessionOptions",
|
|
1123
|
+
buildSessionOptions,
|
|
1124
|
+
parsedArgs,
|
|
1125
|
+
scopedModels,
|
|
1126
|
+
sessionManager,
|
|
1127
|
+
modelRegistry,
|
|
1128
|
+
settingsInstance,
|
|
1129
|
+
);
|
|
1130
|
+
sessionOptions.authStorage = authStorage;
|
|
1131
|
+
sessionOptions.modelRegistry = modelRegistry;
|
|
1132
|
+
sessionOptions.hasUI = isInteractive || mode === "rpc-ui";
|
|
1133
|
+
sessionOptions.settings = settingsInstance;
|
|
1134
|
+
|
|
1135
|
+
// OTEL: register the global OTLP trace exporter when an OTLP endpoint is
|
|
1136
|
+
// configured via env, then switch on the agent loop's telemetry so its
|
|
1137
|
+
// GenAI spans (invoke_agent / chat / execute_tool) are actually emitted.
|
|
1138
|
+
// Both are no-ops when OTEL_EXPORTER_OTLP_ENDPOINT is unset. An empty config
|
|
1139
|
+
// is enough to enable telemetry — content capture is governed by the
|
|
1140
|
+
// standard OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT env var.
|
|
1141
|
+
await initTelemetryExport();
|
|
1142
|
+
if (isTelemetryExportEnabled()) {
|
|
1143
|
+
sessionOptions.telemetry = {};
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// Handle CLI --api-key as runtime override (not persisted)
|
|
1147
|
+
if (parsedArgs.apiKey) {
|
|
1148
|
+
if (!sessionOptions.model && !sessionOptions.modelPattern) {
|
|
1149
|
+
process.stderr.write(
|
|
1150
|
+
`${chalk.red("--api-key requires a model to be specified via --model, --provider/--model, or --models")}\n`,
|
|
1151
|
+
);
|
|
1152
|
+
process.exit(1);
|
|
1153
|
+
}
|
|
1154
|
+
if (sessionOptions.model) {
|
|
1155
|
+
authStorage.setRuntimeApiKey(sessionOptions.model.provider, parsedArgs.apiKey);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
const createAgentSessionImpl = deps.createAgentSession ?? createAgentSession;
|
|
1160
|
+
const createSession = async (options: CreateAgentSessionOptions): Promise<CreateAgentSessionResult> => {
|
|
1161
|
+
const result = await logger.time("createAgentSession", createAgentSessionImpl, options);
|
|
1162
|
+
// Kick off background model discovery only after createAgentSession finishes its parallel
|
|
1163
|
+
// discovery arms; running these concurrently contends for the event loop and stretches
|
|
1164
|
+
// every parallel arm by ~30ms.
|
|
1165
|
+
modelRegistry.refreshInBackground();
|
|
1166
|
+
return result;
|
|
1167
|
+
};
|
|
1168
|
+
|
|
1169
|
+
if (mode === "acp") {
|
|
1170
|
+
const createAcpSession = createAcpSessionFactory({
|
|
1171
|
+
baseOptions: sessionOptions,
|
|
1172
|
+
settings: settingsInstance,
|
|
1173
|
+
sessionDir: parsedArgs.sessionDir,
|
|
1174
|
+
authStorage,
|
|
1175
|
+
modelRegistry,
|
|
1176
|
+
parsedArgs,
|
|
1177
|
+
rawArgs,
|
|
1178
|
+
createSession,
|
|
1179
|
+
});
|
|
1180
|
+
// Branch-only protocol runner: keep ACP server code out of normal interactive startup.
|
|
1181
|
+
const runAcpMode = deps.runAcpMode ?? (await import("./modes/acp/acp-mode")).runAcpMode;
|
|
1182
|
+
stopStartupWatchdog();
|
|
1183
|
+
await runAcpMode(createAcpSession);
|
|
1184
|
+
} else {
|
|
1185
|
+
// Resolve extension-registered CLI flags before creating the session so a
|
|
1186
|
+
// bad `@file` fails fast WITHOUT leaving a junk session/breadcrumb
|
|
1187
|
+
// (createAgentSession writes the terminal breadcrumb eagerly). Loading the
|
|
1188
|
+
// extensions here also makes `@file` classification extension-aware — e.g. a
|
|
1189
|
+
// string-flag value such as `--target @notes.md` is the flag's value, not a
|
|
1190
|
+
// file — and the same result is handed to createAgentSession via
|
|
1191
|
+
// `preloadedExtensions` so the discovery work is not repeated.
|
|
1192
|
+
const eventBus = new EventBus();
|
|
1193
|
+
const extensionsResult = await loadSessionExtensions(sessionOptions, cwd, settingsInstance, eventBus);
|
|
1194
|
+
const extensionFlagSink: ExtensionFlagSink = {
|
|
1195
|
+
getFlags: () => ExtensionRunner.aggregateFlags(extensionsResult.extensions),
|
|
1196
|
+
setFlagValue: (name, value) => {
|
|
1197
|
+
extensionsResult.runtime.flagValues.set(name, value);
|
|
1198
|
+
},
|
|
1199
|
+
};
|
|
1200
|
+
const initialArgs = applyExtensionFlags(extensionFlagSink, rawArgs) ?? parsedArgs;
|
|
1201
|
+
const processedFiles =
|
|
1202
|
+
initialArgs.fileArgs.length > 0
|
|
1203
|
+
? await logger.time("processFileArguments", () =>
|
|
1204
|
+
processFileArguments(initialArgs.fileArgs, {
|
|
1205
|
+
autoResizeImages: settingsInstance.get("images.autoResize"),
|
|
1206
|
+
}),
|
|
1207
|
+
)
|
|
1208
|
+
: undefined;
|
|
1209
|
+
const { initialMessage, initialImages } = buildInitialMessage({
|
|
1210
|
+
parsed: initialArgs,
|
|
1211
|
+
fileText: processedFiles?.text,
|
|
1212
|
+
fileImages: processedFiles?.images,
|
|
1213
|
+
stdinContent: pipedInput,
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
maybeShowStartupSplash({
|
|
1217
|
+
isInteractive,
|
|
1218
|
+
resuming: Boolean(parsedArgs.continue || parsedArgs.resume || parsedArgs.fork),
|
|
1219
|
+
quiet: settingsInstance.get("startup.quiet"),
|
|
1220
|
+
version: VERSION,
|
|
1221
|
+
});
|
|
1222
|
+
|
|
1223
|
+
const { session, setToolUIContext, modelFallbackMessage, lspServers, mcpManager } = await createSession({
|
|
1224
|
+
...sessionOptions,
|
|
1225
|
+
eventBus,
|
|
1226
|
+
preloadedExtensions: extensionsResult,
|
|
1227
|
+
});
|
|
1228
|
+
if (parsedArgs.apiKey && !sessionOptions.model && session.model) {
|
|
1229
|
+
authStorage.setRuntimeApiKey(session.model.provider, parsedArgs.apiKey);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
if (modelFallbackMessage) {
|
|
1233
|
+
notifs.push({ kind: "warn", message: modelFallbackMessage });
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
const modelRegistryError = modelRegistry.getError();
|
|
1237
|
+
if (modelRegistryError) {
|
|
1238
|
+
notifs.push({ kind: "error", message: modelRegistryError.message });
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
if (!isInteractive && !session.model) {
|
|
1242
|
+
if (modelFallbackMessage) {
|
|
1243
|
+
process.stderr.write(`${chalk.red(modelFallbackMessage)}\n`);
|
|
1244
|
+
} else {
|
|
1245
|
+
process.stderr.write(`${chalk.red("No models available.")}\n`);
|
|
1246
|
+
}
|
|
1247
|
+
process.stderr.write(`${chalk.yellow("\nSet an API key environment variable:")}\n`);
|
|
1248
|
+
process.stderr.write(" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\n");
|
|
1249
|
+
process.stderr.write(`${chalk.yellow(`\nOr create ${ModelsConfigFile.path()}`)}\n`);
|
|
1250
|
+
process.exit(1);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
if (mode === "rpc" || mode === "rpc-ui") {
|
|
1254
|
+
// Branch-only protocol runner: keep RPC host code out of normal interactive startup.
|
|
1255
|
+
const runRpcMode: RunRpcMode = (await import("./modes/rpc/rpc-mode")).runRpcMode;
|
|
1256
|
+
stopStartupWatchdog();
|
|
1257
|
+
await runRpcMode(session, mode === "rpc-ui" ? setToolUIContext : undefined, eventBus);
|
|
1258
|
+
} else if (isInteractive) {
|
|
1259
|
+
const versionCheckPromise = checkForNewVersion(VERSION).catch(() => undefined);
|
|
1260
|
+
const changelogMarkdown = await logger.time("main:getChangelogForDisplay", getChangelogForDisplay, parsedArgs);
|
|
1261
|
+
|
|
1262
|
+
const scopedModelsForDisplay = sessionOptions.scopedModels ?? scopedModels;
|
|
1263
|
+
if (scopedModelsForDisplay.length > 0) {
|
|
1264
|
+
const modelList = scopedModelsForDisplay
|
|
1265
|
+
.map(scopedModel => {
|
|
1266
|
+
const thinkingStr = !scopedModel.thinkingLevel ? `:${scopedModel.thinkingLevel}` : "";
|
|
1267
|
+
return `${scopedModel.model.id}${thinkingStr}`;
|
|
1268
|
+
})
|
|
1269
|
+
.join(", ");
|
|
1270
|
+
// Routed through the TUI (not stdout): the startup capture owns the
|
|
1271
|
+
// terminal in raw mode here, and the TUI's first clearScrollback paint
|
|
1272
|
+
// would wipe a pre-TUI line anyway.
|
|
1273
|
+
notifs.push({ kind: "info", message: `Model scope: ${modelList} (Ctrl+P to cycle)` });
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
if ($env.PI_TIMING) {
|
|
1277
|
+
logger.printTimings();
|
|
1278
|
+
if (logger.shouldExitAfterTimings()) {
|
|
1279
|
+
process.exit(0);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
stopStartupWatchdog();
|
|
1284
|
+
logger.endTiming();
|
|
1285
|
+
await runInteractiveMode(
|
|
1286
|
+
session,
|
|
1287
|
+
VERSION,
|
|
1288
|
+
changelogMarkdown,
|
|
1289
|
+
notifs,
|
|
1290
|
+
versionCheckPromise,
|
|
1291
|
+
initialArgs.messages,
|
|
1292
|
+
setToolUIContext,
|
|
1293
|
+
lspServers,
|
|
1294
|
+
mcpManager,
|
|
1295
|
+
Boolean(parsedArgs.continue || parsedArgs.resume || parsedArgs.fork),
|
|
1296
|
+
deps.forceSetupWizard === true,
|
|
1297
|
+
eventBus,
|
|
1298
|
+
initialMessage,
|
|
1299
|
+
initialImages,
|
|
1300
|
+
titleSystemPrompt,
|
|
1301
|
+
);
|
|
1302
|
+
} else {
|
|
1303
|
+
// Branch-only single-shot runner: keep print-mode code out of normal interactive startup.
|
|
1304
|
+
stopStartupWatchdog();
|
|
1305
|
+
const runPrintMode: RunPrintMode = (await import("./modes/print-mode")).runPrintMode;
|
|
1306
|
+
await runPrintMode(session, {
|
|
1307
|
+
mode,
|
|
1308
|
+
messages: initialArgs.messages,
|
|
1309
|
+
initialMessage,
|
|
1310
|
+
initialImages,
|
|
1311
|
+
});
|
|
1312
|
+
if ($env.PI_TIMING) {
|
|
1313
|
+
logger.printTimings();
|
|
1314
|
+
}
|
|
1315
|
+
await session.dispose();
|
|
1316
|
+
stopThemeWatcher();
|
|
1317
|
+
await postmortem.quit(0);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
export async function main(args: string[]): Promise<void> {
|
|
1323
|
+
const { runCli } = await import("./cli");
|
|
1324
|
+
await runCli(args.length === 0 ? ["launch"] : args);
|
|
1325
|
+
}
|