@sheason/pi-coding-agent 0.74.1-sheason.0 → 0.78.0-sheason.0.6.0-alpha.2
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 +256 -4
- package/README.md +16 -8
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/cli/args.d.ts +7 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +49 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts +2 -2
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -3
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -6
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +61 -32
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-proxy.d.ts +268 -0
- package/dist/core/agent-session-proxy.d.ts.map +1 -0
- package/dist/core/agent-session-proxy.js +2 -0
- package/dist/core/agent-session-proxy.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts +10 -10
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +14 -14
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +8 -7
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +4 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +60 -27
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +303 -177
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +3 -3
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +5 -5
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -37
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts +3 -3
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +8 -6
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.js +23 -6
- package/dist/core/export-html/tool-renderer.d.ts +2 -2
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +8 -8
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +2 -2
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +17 -34
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +12 -7
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +36 -2
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +26 -24
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +3 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +4 -0
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +21 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -0
- package/dist/core/http-dispatcher.js +48 -0
- package/dist/core/http-dispatcher.js.map +1 -0
- package/dist/core/index.d.ts +8 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/local-agent-session-proxy.d.ts +82 -0
- package/dist/core/local-agent-session-proxy.d.ts.map +1 -0
- package/dist/core/local-agent-session-proxy.js +531 -0
- package/dist/core/local-agent-session-proxy.js.map +1 -0
- package/dist/core/messages.d.ts +0 -9
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +0 -10
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +4 -4
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +72 -16
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/output-guard.d.ts +1 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js +52 -22
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts +7 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +129 -64
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +12 -24
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +0 -1
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +9 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +134 -11
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +13 -10
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +41 -33
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +15 -13
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +24 -17
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +20 -10
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +201 -106
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +5 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +31 -13
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +2 -2
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +10 -27
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +1 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +16 -9
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +55 -54
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +3 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +8 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +5 -3
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +51 -91
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +27 -12
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -2
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +2 -3
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +2 -2
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +3 -3
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +17 -17
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +2 -2
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +10 -12
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +3 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +9 -3
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +2 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +39 -21
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts +2 -2
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +15 -15
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +5 -2
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +17 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +12 -2
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +25 -41
- package/dist/core/tools/write.js.map +1 -1
- package/dist/d-pi-worker.d.ts +12 -0
- package/dist/d-pi-worker.d.ts.map +1 -0
- package/dist/d-pi-worker.js +9 -0
- package/dist/d-pi-worker.js.map +1 -0
- package/dist/index.d.ts +30 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +100 -39
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +118 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/connect/auth-headers.d.ts +2 -0
- package/dist/modes/connect/auth-headers.d.ts.map +1 -0
- package/dist/modes/connect/auth-headers.js +2 -0
- package/dist/modes/connect/auth-headers.js.map +1 -0
- package/dist/modes/connect/client-extension-sync.d.ts +13 -0
- package/dist/modes/connect/client-extension-sync.d.ts.map +1 -0
- package/dist/modes/connect/client-extension-sync.js +51 -0
- package/dist/modes/connect/client-extension-sync.js.map +1 -0
- package/dist/modes/connect/connect-mode.d.ts +6 -0
- package/dist/modes/connect/connect-mode.d.ts.map +1 -0
- package/dist/modes/connect/connect-mode.js +29 -0
- package/dist/modes/connect/connect-mode.js.map +1 -0
- package/dist/modes/connect/remote-agent-session-proxy.d.ts +81 -0
- package/dist/modes/connect/remote-agent-session-proxy.d.ts.map +1 -0
- package/dist/modes/connect/remote-agent-session-proxy.js +326 -0
- package/dist/modes/connect/remote-agent-session-proxy.js.map +1 -0
- package/dist/modes/connect/sse-client.d.ts +18 -0
- package/dist/modes/connect/sse-client.d.ts.map +1 -0
- package/dist/modes/connect/sse-client.js +90 -0
- package/dist/modes/connect/sse-client.js.map +1 -0
- package/dist/modes/index.d.ts +5 -5
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +4 -4
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +8 -5
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +2 -2
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +2 -2
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +2 -2
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +0 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +14 -6
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +15 -4
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +126 -8
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +31 -31
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +7 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +28 -5
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -2
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +3 -3
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +15 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +53 -7
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1247 -205
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +5 -4
- package/dist/modes/interactive/theme/light.json +5 -4
- package/dist/modes/interactive/theme/theme.d.ts +22 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +130 -69
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +8 -5
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +65 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +2 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +18 -4
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +5 -4
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/serve/api-handlers.d.ts +4 -0
- package/dist/modes/serve/api-handlers.d.ts.map +1 -0
- package/dist/modes/serve/api-handlers.js +324 -0
- package/dist/modes/serve/api-handlers.js.map +1 -0
- package/dist/modes/serve/http-server.d.ts +14 -0
- package/dist/modes/serve/http-server.d.ts.map +1 -0
- package/dist/modes/serve/http-server.js +94 -0
- package/dist/modes/serve/http-server.js.map +1 -0
- package/dist/modes/serve/serve-mode.d.ts +10 -0
- package/dist/modes/serve/serve-mode.d.ts.map +1 -0
- package/dist/modes/serve/serve-mode.js +217 -0
- package/dist/modes/serve/serve-mode.js.map +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +62 -7
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +47 -72
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts +5 -2
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +9 -7
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +3 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js +14 -8
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/deprecation.d.ts +4 -0
- package/dist/utils/deprecation.d.ts.map +1 -0
- package/dist/utils/deprecation.js +13 -0
- package/dist/utils/deprecation.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +40 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +124 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +7 -27
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +75 -131
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts +3 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/paths.d.ts +16 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +49 -7
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +6 -1
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -0
- package/dist/utils/syntax-highlight.js +118 -0
- package/dist/utils/syntax-highlight.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +4 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +2 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +9 -4
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/utils/windows-self-update.d.ts.map +1 -0
- package/dist/utils/windows-self-update.js +77 -0
- package/dist/utils/windows-self-update.js.map +1 -0
- package/docs/custom-provider.md +111 -21
- package/docs/development.md +1 -1
- package/docs/extensions.md +13 -7
- package/docs/index.md +13 -3
- package/docs/models.md +32 -13
- package/docs/packages.md +9 -6
- package/docs/providers.md +13 -5
- package/docs/quickstart.md +24 -1
- package/docs/rpc.md +2 -1
- package/docs/sdk.md +8 -0
- package/docs/session-format.md +1 -1
- package/docs/sessions.md +8 -0
- package/docs/settings.md +8 -6
- package/docs/skills.md +3 -4
- package/docs/terminal-setup.md +8 -0
- package/docs/termux.md +3 -3
- package/docs/tui.md +2 -2
- package/docs/usage.md +13 -2
- package/examples/extensions/README.md +1 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
- package/examples/extensions/doom-overlay/doom-component.ts +2 -2
- package/examples/extensions/doom-overlay/index.ts +3 -3
- package/examples/extensions/git-merge-and-resolve.ts +115 -0
- package/examples/extensions/input-transform-streaming.ts +39 -0
- package/examples/extensions/overlay-qa-tests.ts +97 -66
- package/examples/extensions/overlay-test.ts +7 -4
- package/examples/extensions/plan-mode/index.ts +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/subagent/README.md +3 -0
- package/examples/extensions/subagent/index.ts +42 -20
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +3 -3
- package/npm-shrinkwrap.json +1790 -0
- package/package.json +39 -32
- package/dist/utils/uuid.d.ts +0 -2
- package/dist/utils/uuid.d.ts.map +0 -1
- package/dist/utils/uuid.js +0 -40
- package/dist/utils/uuid.js.map +0 -1
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { APP_NAME, getChangelogPath, VERSION } from "../../config.js";
|
|
2
|
+
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
3
|
+
import { LocalAgentSessionProxy } from "../../core/local-agent-session-proxy.js";
|
|
4
|
+
import { getNewEntries, parseChangelog } from "../../utils/changelog.js";
|
|
5
|
+
import { formatKeyText } from "../interactive/components/keybinding-hints.js";
|
|
6
|
+
import { AgentHttpServer } from "./http-server.js";
|
|
7
|
+
const DEFAULT_PORT = 8080;
|
|
8
|
+
/** Get the display text for a keybinding (theme-independent). */
|
|
9
|
+
function keyText(kb, keybinding) {
|
|
10
|
+
const keys = kb.getKeys(keybinding);
|
|
11
|
+
if (keys.length === 0)
|
|
12
|
+
return "";
|
|
13
|
+
return formatKeyText(keys.join("/"));
|
|
14
|
+
}
|
|
15
|
+
/** Generate structured banner data for serve/connect. */
|
|
16
|
+
export function generateBanner(session) {
|
|
17
|
+
// Use the app's KeybindingsManager which includes app-specific bindings
|
|
18
|
+
const kb = KeybindingsManager.create();
|
|
19
|
+
const expandedHints = [
|
|
20
|
+
{ key: keyText(kb, "app.interrupt"), description: "to interrupt" },
|
|
21
|
+
{ key: keyText(kb, "app.clear"), description: "to clear" },
|
|
22
|
+
{ key: `${keyText(kb, "app.clear")} twice`, description: "to exit" },
|
|
23
|
+
{ key: keyText(kb, "app.exit"), description: "to exit (empty)" },
|
|
24
|
+
{ key: keyText(kb, "app.suspend"), description: "to suspend" },
|
|
25
|
+
{ key: keyText(kb, "tui.editor.deleteToLineEnd"), description: "to delete to end" },
|
|
26
|
+
{ key: keyText(kb, "app.thinking.cycle"), description: "to cycle thinking level" },
|
|
27
|
+
{
|
|
28
|
+
key: `${keyText(kb, "app.model.cycleForward")}/${keyText(kb, "app.model.cycleBackward")}`,
|
|
29
|
+
description: "to cycle models",
|
|
30
|
+
},
|
|
31
|
+
{ key: keyText(kb, "app.model.select"), description: "to select model" },
|
|
32
|
+
{ key: keyText(kb, "app.tools.expand"), description: "to expand tools" },
|
|
33
|
+
{ key: keyText(kb, "app.thinking.toggle"), description: "to expand thinking" },
|
|
34
|
+
{ key: keyText(kb, "app.editor.external"), description: "for external editor" },
|
|
35
|
+
{ key: "/", description: "for commands" },
|
|
36
|
+
{ key: "!", description: "to run bash" },
|
|
37
|
+
{ key: "!!", description: "to run bash (no context)" },
|
|
38
|
+
{ key: keyText(kb, "app.message.followUp"), description: "to queue follow-up" },
|
|
39
|
+
{ key: keyText(kb, "app.message.dequeue"), description: "to edit all queued messages" },
|
|
40
|
+
{ key: keyText(kb, "app.clipboard.pasteImage"), description: "to paste image" },
|
|
41
|
+
{ key: "drop files", description: "to attach" },
|
|
42
|
+
];
|
|
43
|
+
const compactHints = [
|
|
44
|
+
{ key: keyText(kb, "app.interrupt"), description: "interrupt" },
|
|
45
|
+
{ key: `${keyText(kb, "app.clear")}/${keyText(kb, "app.exit")}`, description: "clear/exit" },
|
|
46
|
+
{ key: "/", description: "commands" },
|
|
47
|
+
{ key: "!", description: "bash" },
|
|
48
|
+
{ key: keyText(kb, "app.tools.expand"), description: "more" },
|
|
49
|
+
];
|
|
50
|
+
const compactOnboarding = `Press ${keyText(kb, "app.tools.expand")} to show full startup help and loaded resources.`;
|
|
51
|
+
const onboarding = `Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.`;
|
|
52
|
+
// Gather loaded resources from the session
|
|
53
|
+
const loadedResources = [];
|
|
54
|
+
const rl = session.resourceLoader;
|
|
55
|
+
// Context files
|
|
56
|
+
const contextFiles = rl.getAgentsFiles().agentsFiles;
|
|
57
|
+
if (contextFiles.length > 0) {
|
|
58
|
+
loadedResources.push({
|
|
59
|
+
name: "Context",
|
|
60
|
+
compactList: contextFiles.map((f) => f.path).join(", "),
|
|
61
|
+
expandedList: contextFiles.map((f) => f.path).join("\n"),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Skills
|
|
65
|
+
const skills = rl.getSkills().skills;
|
|
66
|
+
if (skills.length > 0) {
|
|
67
|
+
loadedResources.push({
|
|
68
|
+
name: "Skills",
|
|
69
|
+
compactList: skills
|
|
70
|
+
.map((s) => s.name)
|
|
71
|
+
.sort()
|
|
72
|
+
.join(", "),
|
|
73
|
+
expandedList: skills.map((s) => s.filePath).join("\n"),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Prompts (templates)
|
|
77
|
+
const templates = session.promptTemplates;
|
|
78
|
+
if (templates.length > 0) {
|
|
79
|
+
loadedResources.push({
|
|
80
|
+
name: "Prompts",
|
|
81
|
+
compactList: templates
|
|
82
|
+
.map((t) => `/${t.name}`)
|
|
83
|
+
.sort()
|
|
84
|
+
.join(", "),
|
|
85
|
+
expandedList: templates.map((t) => t.filePath).join("\n"),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Extensions — tool registration and events work, UI calls degrade to no-ops
|
|
89
|
+
const extensions = rl.getExtensions().extensions;
|
|
90
|
+
if (extensions.length > 0) {
|
|
91
|
+
loadedResources.push({
|
|
92
|
+
name: "Extensions",
|
|
93
|
+
compactList: extensions.map((e) => e.path.split("/").pop() ?? e.path).join(", "),
|
|
94
|
+
expandedList: extensions.map((e) => e.path).join("\n"),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// Themes (custom only)
|
|
98
|
+
const themes = rl.getThemes().themes.filter((t) => t.sourcePath);
|
|
99
|
+
if (themes.length > 0) {
|
|
100
|
+
loadedResources.push({
|
|
101
|
+
name: "Themes",
|
|
102
|
+
compactList: themes
|
|
103
|
+
.map((t) => t.name ?? "")
|
|
104
|
+
.filter(Boolean)
|
|
105
|
+
.sort()
|
|
106
|
+
.join(", "),
|
|
107
|
+
expandedList: themes.map((t) => t.sourcePath).join("\n"),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Diagnostics
|
|
111
|
+
const diagnostics = [];
|
|
112
|
+
const skillDiagnostics = rl.getSkills().diagnostics;
|
|
113
|
+
if (skillDiagnostics.length > 0) {
|
|
114
|
+
diagnostics.push({ label: "Skill conflicts", entries: skillDiagnostics });
|
|
115
|
+
}
|
|
116
|
+
const promptDiagnostics = rl.getPrompts().diagnostics;
|
|
117
|
+
if (promptDiagnostics.length > 0) {
|
|
118
|
+
diagnostics.push({ label: "Prompt conflicts", entries: promptDiagnostics });
|
|
119
|
+
}
|
|
120
|
+
const extensionErrors = rl.getExtensions().errors;
|
|
121
|
+
if (extensionErrors.length > 0) {
|
|
122
|
+
diagnostics.push({
|
|
123
|
+
label: "Extension issues",
|
|
124
|
+
entries: extensionErrors.map((e) => ({
|
|
125
|
+
type: "error",
|
|
126
|
+
message: e.error,
|
|
127
|
+
path: e.path,
|
|
128
|
+
})),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// Changelog — only show new entries since last seen version (same logic as local mode)
|
|
132
|
+
let changelogMarkdown;
|
|
133
|
+
const lastVersion = session.settingsManager.getLastChangelogVersion();
|
|
134
|
+
const changelogEntries = parseChangelog(getChangelogPath());
|
|
135
|
+
if (lastVersion && changelogEntries.length > 0) {
|
|
136
|
+
const newEntries = getNewEntries(changelogEntries, lastVersion);
|
|
137
|
+
if (newEntries.length > 0) {
|
|
138
|
+
changelogMarkdown = newEntries.map((e) => e.content).join("\n\n");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
appName: APP_NAME,
|
|
143
|
+
version: VERSION,
|
|
144
|
+
expandedHints,
|
|
145
|
+
compactHints,
|
|
146
|
+
compactOnboarding,
|
|
147
|
+
onboarding,
|
|
148
|
+
loadedResources,
|
|
149
|
+
diagnostics,
|
|
150
|
+
changelogMarkdown,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export async function runServeMode(runtime, options = {}) {
|
|
154
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
155
|
+
const proxy = new LocalAgentSessionProxy(runtime);
|
|
156
|
+
// Generate and set banner data for connect clients
|
|
157
|
+
proxy.setBanner(generateBanner(runtime.session));
|
|
158
|
+
const server = new AgentHttpServer(proxy);
|
|
159
|
+
// Bind extensions — no UI context (hasUI() === false), tool registration
|
|
160
|
+
// and event subscriptions work normally. UI calls degrade to no-ops.
|
|
161
|
+
const rebindSession = async () => {
|
|
162
|
+
const session = runtime.session;
|
|
163
|
+
await session.bindExtensions({
|
|
164
|
+
commandContextActions: {
|
|
165
|
+
waitForIdle: () => session.agent.waitForIdle(),
|
|
166
|
+
newSession: async (newSessionOptions) => runtime.newSession(newSessionOptions),
|
|
167
|
+
fork: async (entryId, forkOptions) => {
|
|
168
|
+
const result = await runtime.fork(entryId, forkOptions);
|
|
169
|
+
return { cancelled: result.cancelled };
|
|
170
|
+
},
|
|
171
|
+
navigateTree: async (targetId, navigateOptions) => {
|
|
172
|
+
const result = await session.navigateTree(targetId, {
|
|
173
|
+
summarize: navigateOptions?.summarize,
|
|
174
|
+
customInstructions: navigateOptions?.customInstructions,
|
|
175
|
+
replaceInstructions: navigateOptions?.replaceInstructions,
|
|
176
|
+
label: navigateOptions?.label,
|
|
177
|
+
});
|
|
178
|
+
return { cancelled: result.cancelled };
|
|
179
|
+
},
|
|
180
|
+
switchSession: async (sessionPath, switchOptions) => {
|
|
181
|
+
return runtime.switchSession(sessionPath, switchOptions);
|
|
182
|
+
},
|
|
183
|
+
reload: async () => {
|
|
184
|
+
await session.reload();
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
abortHandler: () => {
|
|
188
|
+
// No UI to reset in serve mode
|
|
189
|
+
},
|
|
190
|
+
onError: (err) => {
|
|
191
|
+
process.stderr.write(`[serve] Extension error (${err.extensionPath}): ${err.error}\n`);
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
// Set up beforeSessionInvalidate callback
|
|
196
|
+
runtime.setBeforeSessionInvalidate(() => {
|
|
197
|
+
// No UI to reset in serve mode
|
|
198
|
+
});
|
|
199
|
+
// Set up rebindSession — must call bindExtensions for each new session
|
|
200
|
+
// so extension event handlers (session_start, etc.) fire correctly.
|
|
201
|
+
// Also re-subscribe proxy listeners so SSE events keep flowing.
|
|
202
|
+
runtime.setRebindSession(async (session, reason) => {
|
|
203
|
+
proxy.resubscribe(reason);
|
|
204
|
+
await rebindSession();
|
|
205
|
+
// Update banner after session replacement
|
|
206
|
+
proxy.setBanner(generateBanner(session));
|
|
207
|
+
});
|
|
208
|
+
// Initial bind for the first session
|
|
209
|
+
await rebindSession();
|
|
210
|
+
await server.start(port);
|
|
211
|
+
// Log to stderr so stdout stays clean
|
|
212
|
+
process.stderr.write(`[serve] Listening on port ${port}\n`);
|
|
213
|
+
process.stderr.write(`[serve] Connect with: pi --mode connect --url http://localhost:${port}\n`);
|
|
214
|
+
// Keep process alive
|
|
215
|
+
return new Promise(() => { });
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=serve-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-mode.js","sourceRoot":"","sources":["../../../src/modes/serve/serve-mode.ts"],"names":[],"mappings":"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","sourcesContent":["import { APP_NAME, getChangelogPath, VERSION } from \"../../config.ts\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport type {\n\tBannerData,\n\tBannerKeyHint,\n\tLoadedResourceSection,\n\tResourceDiagnosticEntry,\n} from \"../../core/agent-session-proxy.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport { type AppKeybinding, KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { LocalAgentSessionProxy } from \"../../core/local-agent-session-proxy.ts\";\nimport { getNewEntries, parseChangelog } from \"../../utils/changelog.ts\";\nimport { formatKeyText } from \"../interactive/components/keybinding-hints.ts\";\nimport { AgentHttpServer } from \"./http-server.ts\";\n\nexport interface ServeModeOptions {\n\tport?: number;\n}\n\nconst DEFAULT_PORT = 8080;\n\n/** Get the display text for a keybinding (theme-independent). */\nfunction keyText(kb: KeybindingsManager, keybinding: string): string {\n\tconst keys = kb.getKeys(keybinding as AppKeybinding);\n\tif (keys.length === 0) return \"\";\n\treturn formatKeyText(keys.join(\"/\"));\n}\n\n/** Generate structured banner data for serve/connect. */\nexport function generateBanner(session: AgentSession): BannerData {\n\t// Use the app's KeybindingsManager which includes app-specific bindings\n\tconst kb = KeybindingsManager.create();\n\n\tconst expandedHints: BannerKeyHint[] = [\n\t\t{ key: keyText(kb, \"app.interrupt\"), description: \"to interrupt\" },\n\t\t{ key: keyText(kb, \"app.clear\"), description: \"to clear\" },\n\t\t{ key: `${keyText(kb, \"app.clear\")} twice`, description: \"to exit\" },\n\t\t{ key: keyText(kb, \"app.exit\"), description: \"to exit (empty)\" },\n\t\t{ key: keyText(kb, \"app.suspend\"), description: \"to suspend\" },\n\t\t{ key: keyText(kb, \"tui.editor.deleteToLineEnd\"), description: \"to delete to end\" },\n\t\t{ key: keyText(kb, \"app.thinking.cycle\"), description: \"to cycle thinking level\" },\n\t\t{\n\t\t\tkey: `${keyText(kb, \"app.model.cycleForward\")}/${keyText(kb, \"app.model.cycleBackward\")}`,\n\t\t\tdescription: \"to cycle models\",\n\t\t},\n\t\t{ key: keyText(kb, \"app.model.select\"), description: \"to select model\" },\n\t\t{ key: keyText(kb, \"app.tools.expand\"), description: \"to expand tools\" },\n\t\t{ key: keyText(kb, \"app.thinking.toggle\"), description: \"to expand thinking\" },\n\t\t{ key: keyText(kb, \"app.editor.external\"), description: \"for external editor\" },\n\t\t{ key: \"/\", description: \"for commands\" },\n\t\t{ key: \"!\", description: \"to run bash\" },\n\t\t{ key: \"!!\", description: \"to run bash (no context)\" },\n\t\t{ key: keyText(kb, \"app.message.followUp\"), description: \"to queue follow-up\" },\n\t\t{ key: keyText(kb, \"app.message.dequeue\"), description: \"to edit all queued messages\" },\n\t\t{ key: keyText(kb, \"app.clipboard.pasteImage\"), description: \"to paste image\" },\n\t\t{ key: \"drop files\", description: \"to attach\" },\n\t];\n\tconst compactHints: BannerKeyHint[] = [\n\t\t{ key: keyText(kb, \"app.interrupt\"), description: \"interrupt\" },\n\t\t{ key: `${keyText(kb, \"app.clear\")}/${keyText(kb, \"app.exit\")}`, description: \"clear/exit\" },\n\t\t{ key: \"/\", description: \"commands\" },\n\t\t{ key: \"!\", description: \"bash\" },\n\t\t{ key: keyText(kb, \"app.tools.expand\"), description: \"more\" },\n\t];\n\tconst compactOnboarding = `Press ${keyText(kb, \"app.tools.expand\")} to show full startup help and loaded resources.`;\n\tconst onboarding = `Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.`;\n\n\t// Gather loaded resources from the session\n\tconst loadedResources: LoadedResourceSection[] = [];\n\tconst rl = session.resourceLoader;\n\n\t// Context files\n\tconst contextFiles = rl.getAgentsFiles().agentsFiles;\n\tif (contextFiles.length > 0) {\n\t\tloadedResources.push({\n\t\t\tname: \"Context\",\n\t\t\tcompactList: contextFiles.map((f) => f.path).join(\", \"),\n\t\t\texpandedList: contextFiles.map((f) => f.path).join(\"\\n\"),\n\t\t});\n\t}\n\n\t// Skills\n\tconst skills = rl.getSkills().skills;\n\tif (skills.length > 0) {\n\t\tloadedResources.push({\n\t\t\tname: \"Skills\",\n\t\t\tcompactList: skills\n\t\t\t\t.map((s) => s.name)\n\t\t\t\t.sort()\n\t\t\t\t.join(\", \"),\n\t\t\texpandedList: skills.map((s) => s.filePath).join(\"\\n\"),\n\t\t});\n\t}\n\n\t// Prompts (templates)\n\tconst templates = session.promptTemplates;\n\tif (templates.length > 0) {\n\t\tloadedResources.push({\n\t\t\tname: \"Prompts\",\n\t\t\tcompactList: templates\n\t\t\t\t.map((t) => `/${t.name}`)\n\t\t\t\t.sort()\n\t\t\t\t.join(\", \"),\n\t\t\texpandedList: templates.map((t) => t.filePath).join(\"\\n\"),\n\t\t});\n\t}\n\n\t// Extensions — tool registration and events work, UI calls degrade to no-ops\n\tconst extensions = rl.getExtensions().extensions;\n\tif (extensions.length > 0) {\n\t\tloadedResources.push({\n\t\t\tname: \"Extensions\",\n\t\t\tcompactList: extensions.map((e) => e.path.split(\"/\").pop() ?? e.path).join(\", \"),\n\t\t\texpandedList: extensions.map((e) => e.path).join(\"\\n\"),\n\t\t});\n\t}\n\n\t// Themes (custom only)\n\tconst themes = rl.getThemes().themes.filter((t) => t.sourcePath);\n\tif (themes.length > 0) {\n\t\tloadedResources.push({\n\t\t\tname: \"Themes\",\n\t\t\tcompactList: themes\n\t\t\t\t.map((t) => t.name ?? \"\")\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.sort()\n\t\t\t\t.join(\", \"),\n\t\t\texpandedList: themes.map((t) => t.sourcePath!).join(\"\\n\"),\n\t\t});\n\t}\n\n\t// Diagnostics\n\tconst diagnostics: Array<{ label: string; entries: ResourceDiagnosticEntry[] }> = [];\n\n\tconst skillDiagnostics = rl.getSkills().diagnostics;\n\tif (skillDiagnostics.length > 0) {\n\t\tdiagnostics.push({ label: \"Skill conflicts\", entries: skillDiagnostics as ResourceDiagnosticEntry[] });\n\t}\n\n\tconst promptDiagnostics = rl.getPrompts().diagnostics;\n\tif (promptDiagnostics.length > 0) {\n\t\tdiagnostics.push({ label: \"Prompt conflicts\", entries: promptDiagnostics as ResourceDiagnosticEntry[] });\n\t}\n\n\tconst extensionErrors = rl.getExtensions().errors;\n\tif (extensionErrors.length > 0) {\n\t\tdiagnostics.push({\n\t\t\tlabel: \"Extension issues\",\n\t\t\tentries: extensionErrors.map((e) => ({\n\t\t\t\ttype: \"error\" as const,\n\t\t\t\tmessage: e.error,\n\t\t\t\tpath: e.path,\n\t\t\t})),\n\t\t});\n\t}\n\n\t// Changelog — only show new entries since last seen version (same logic as local mode)\n\tlet changelogMarkdown: string | undefined;\n\tconst lastVersion = session.settingsManager.getLastChangelogVersion();\n\tconst changelogEntries = parseChangelog(getChangelogPath());\n\tif (lastVersion && changelogEntries.length > 0) {\n\t\tconst newEntries = getNewEntries(changelogEntries, lastVersion);\n\t\tif (newEntries.length > 0) {\n\t\t\tchangelogMarkdown = newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t}\n\n\treturn {\n\t\tappName: APP_NAME,\n\t\tversion: VERSION,\n\t\texpandedHints,\n\t\tcompactHints,\n\t\tcompactOnboarding,\n\t\tonboarding,\n\t\tloadedResources,\n\t\tdiagnostics,\n\t\tchangelogMarkdown,\n\t};\n}\n\nexport async function runServeMode(runtime: AgentSessionRuntime, options: ServeModeOptions = {}): Promise<void> {\n\tconst port = options.port ?? DEFAULT_PORT;\n\tconst proxy = new LocalAgentSessionProxy(runtime);\n\n\t// Generate and set banner data for connect clients\n\tproxy.setBanner(generateBanner(runtime.session));\n\n\tconst server = new AgentHttpServer(proxy);\n\n\t// Bind extensions — no UI context (hasUI() === false), tool registration\n\t// and event subscriptions work normally. UI calls degrade to no-ops.\n\tconst rebindSession = async (): Promise<void> => {\n\t\tconst session = runtime.session;\n\t\tawait session.bindExtensions({\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.agent.waitForIdle(),\n\t\t\t\tnewSession: async (newSessionOptions) => runtime.newSession(newSessionOptions),\n\t\t\t\tfork: async (entryId, forkOptions) => {\n\t\t\t\t\tconst result = await runtime.fork(entryId, forkOptions);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, navigateOptions) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, {\n\t\t\t\t\t\tsummarize: navigateOptions?.summarize,\n\t\t\t\t\t\tcustomInstructions: navigateOptions?.customInstructions,\n\t\t\t\t\t\treplaceInstructions: navigateOptions?.replaceInstructions,\n\t\t\t\t\t\tlabel: navigateOptions?.label,\n\t\t\t\t\t});\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: async (sessionPath, switchOptions) => {\n\t\t\t\t\treturn runtime.switchSession(sessionPath, switchOptions);\n\t\t\t\t},\n\t\t\t\treload: async () => {\n\t\t\t\t\tawait session.reload();\n\t\t\t\t},\n\t\t\t},\n\t\t\tabortHandler: () => {\n\t\t\t\t// No UI to reset in serve mode\n\t\t\t},\n\t\t\tonError: (err) => {\n\t\t\t\tprocess.stderr.write(`[serve] Extension error (${err.extensionPath}): ${err.error}\\n`);\n\t\t\t},\n\t\t});\n\t};\n\n\t// Set up beforeSessionInvalidate callback\n\truntime.setBeforeSessionInvalidate(() => {\n\t\t// No UI to reset in serve mode\n\t});\n\n\t// Set up rebindSession — must call bindExtensions for each new session\n\t// so extension event handlers (session_start, etc.) fire correctly.\n\t// Also re-subscribe proxy listeners so SSE events keep flowing.\n\truntime.setRebindSession(async (session, reason) => {\n\t\tproxy.resubscribe(reason);\n\t\tawait rebindSession();\n\t\t// Update banner after session replacement\n\t\tproxy.setBanner(generateBanner(session));\n\t});\n\n\t// Initial bind for the first session\n\tawait rebindSession();\n\n\tawait server.start(port);\n\n\t// Log to stderr so stdout stays clean\n\tprocess.stderr.write(`[serve] Listening on port ${port}\\n`);\n\tprocess.stderr.write(`[serve] Connect with: pi --mode connect --url http://localhost:${port}\\n`);\n\n\t// Keep process alive\n\treturn new Promise(() => {});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-manager-cli.d.ts","sourceRoot":"","sources":["../src/package-manager-cli.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAkUtE,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAoB1E;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAiK3E","sourcesContent":["import chalk from \"chalk\";\nimport { spawn } from \"child_process\";\nimport { selectConfig } from \"./cli/config-selector.js\";\nimport {\n\tAPP_NAME,\n\tgetAgentDir,\n\tgetSelfUpdateCommand,\n\tgetSelfUpdateUnavailableInstruction,\n\tPACKAGE_NAME,\n\ttype SelfUpdateCommand,\n\tVERSION,\n} from \"./config.js\";\nimport { DefaultPackageManager } from \"./core/package-manager.js\";\nimport { SettingsManager } from \"./core/settings-manager.js\";\nimport { shouldUseWindowsShell } from \"./utils/child-process.js\";\nimport { getLatestPiRelease, isNewerPackageVersion } from \"./utils/version-check.js\";\n\nexport type PackageCommand = \"install\" | \"remove\" | \"update\" | \"list\";\n\ntype UpdateTarget = { type: \"all\" } | { type: \"self\" } | { type: \"extensions\"; source?: string };\n\ninterface PackageCommandOptions {\n\tcommand: PackageCommand;\n\tsource?: string;\n\tupdateTarget?: UpdateTarget;\n\tlocal: boolean;\n\tforce: boolean;\n\thelp: boolean;\n\tinvalidOption?: string;\n\tinvalidArgument?: string;\n\tmissingOptionValue?: string;\n\tconflictingOptions?: string;\n}\n\nfunction reportSettingsErrors(settingsManager: SettingsManager, context: string): void {\n\tconst errors = settingsManager.drainErrors();\n\tfor (const { scope, error } of errors) {\n\t\tconsole.error(chalk.yellow(`Warning (${context}, ${scope} settings): ${error.message}`));\n\t\tif (error.stack) {\n\t\t\tconsole.error(chalk.dim(error.stack));\n\t\t}\n\t}\n}\n\nfunction getPackageCommandUsage(command: PackageCommand): string {\n\tswitch (command) {\n\t\tcase \"install\":\n\t\t\treturn `${APP_NAME} install <source> [-l]`;\n\t\tcase \"remove\":\n\t\t\treturn `${APP_NAME} remove <source> [-l]`;\n\t\tcase \"update\":\n\t\t\treturn `${APP_NAME} update [source|self|pi] [--self] [--extensions] [--extension <source>] [--force]`;\n\t\tcase \"list\":\n\t\t\treturn `${APP_NAME} list`;\n\t}\n}\n\nfunction printPackageCommandHelp(command: PackageCommand): void {\n\tswitch (command) {\n\t\tcase \"install\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"install\")}\n\nInstall a package and add it to settings.\n\nOptions:\n -l, --local Install project-locally (.pi/settings.json)\n\nExamples:\n ${APP_NAME} install npm:@foo/bar\n ${APP_NAME} install git:github.com/user/repo\n ${APP_NAME} install git:git@github.com:user/repo\n ${APP_NAME} install https://github.com/user/repo\n ${APP_NAME} install ssh://git@github.com/user/repo\n ${APP_NAME} install ./local/path\n`);\n\t\t\treturn;\n\n\t\tcase \"remove\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"remove\")}\n\nRemove a package and its source from settings.\nAlias: ${APP_NAME} uninstall <source> [-l]\n\nOptions:\n -l, --local Remove from project settings (.pi/settings.json)\n\nExamples:\n ${APP_NAME} remove npm:@foo/bar\n ${APP_NAME} uninstall npm:@foo/bar\n`);\n\t\t\treturn;\n\n\t\tcase \"update\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"update\")}\n\nUpdate pi and installed packages.\n\nOptions:\n --self Update pi only\n --extensions Update installed packages only\n --extension <source> Update one package only\n --force Reinstall pi even if the current version is latest\n\nShort forms:\n ${APP_NAME} update Update pi and all extensions\n ${APP_NAME} update <source> Update one package\n ${APP_NAME} update pi Update pi only (self works as alias to pi)\n`);\n\t\t\treturn;\n\n\t\tcase \"list\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"list\")}\n\nList installed packages from user and project settings.\n`);\n\t\t\treturn;\n\t}\n}\n\nfunction parsePackageCommand(args: string[]): PackageCommandOptions | undefined {\n\tconst [rawCommand, ...rest] = args;\n\tlet command: PackageCommand | undefined;\n\tif (rawCommand === \"uninstall\") {\n\t\tcommand = \"remove\";\n\t} else if (rawCommand === \"install\" || rawCommand === \"remove\" || rawCommand === \"update\" || rawCommand === \"list\") {\n\t\tcommand = rawCommand;\n\t}\n\tif (!command) {\n\t\treturn undefined;\n\t}\n\n\tlet local = false;\n\tlet force = false;\n\tlet help = false;\n\tlet invalidOption: string | undefined;\n\tlet invalidArgument: string | undefined;\n\tlet missingOptionValue: string | undefined;\n\tlet conflictingOptions: string | undefined;\n\tlet source: string | undefined;\n\tlet selfFlag = false;\n\tlet extensionsFlag = false;\n\tlet extensionFlagSource: string | undefined;\n\n\tfor (let index = 0; index < rest.length; index++) {\n\t\tconst arg = rest[index];\n\t\tif (arg === \"-h\" || arg === \"--help\") {\n\t\t\thelp = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"-l\" || arg === \"--local\") {\n\t\t\tif (command === \"install\" || command === \"remove\") {\n\t\t\t\tlocal = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--self\") {\n\t\t\tif (command === \"update\") {\n\t\t\t\tselfFlag = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--extensions\") {\n\t\t\tif (command === \"update\") {\n\t\t\t\textensionsFlag = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--force\") {\n\t\t\tif (command === \"update\") {\n\t\t\t\tforce = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--extension\") {\n\t\t\tif (command !== \"update\") {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst value = rest[index + 1];\n\t\t\tif (!value || value.startsWith(\"-\")) {\n\t\t\t\tmissingOptionValue = missingOptionValue ?? arg;\n\t\t\t} else if (extensionFlagSource) {\n\t\t\t\tconflictingOptions = conflictingOptions ?? \"--extension can only be provided once\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\textensionFlagSource = value;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg.startsWith(\"-\")) {\n\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!source) {\n\t\t\tsource = arg;\n\t\t} else {\n\t\t\tinvalidArgument = invalidArgument ?? arg;\n\t\t}\n\t}\n\n\tlet updateTarget: UpdateTarget | undefined;\n\tif (command === \"update\") {\n\t\tif (extensionFlagSource) {\n\t\t\tif (selfFlag || extensionsFlag) {\n\t\t\t\tconflictingOptions = conflictingOptions ?? \"--extension cannot be combined with --self or --extensions\";\n\t\t\t}\n\t\t\tif (source) {\n\t\t\t\tconflictingOptions = conflictingOptions ?? \"--extension cannot be combined with a positional source\";\n\t\t\t}\n\t\t\tupdateTarget = { type: \"extensions\", source: extensionFlagSource };\n\t\t} else if (source) {\n\t\t\tconst sourceIsSelf = source === \"self\" || source === \"pi\";\n\t\t\tif (sourceIsSelf) {\n\t\t\t\tupdateTarget = extensionsFlag ? { type: \"all\" } : { type: \"self\" };\n\t\t\t} else {\n\t\t\t\tif (extensionsFlag || selfFlag) {\n\t\t\t\t\tconflictingOptions =\n\t\t\t\t\t\tconflictingOptions ?? \"positional update targets cannot be combined with --self or --extensions\";\n\t\t\t\t}\n\t\t\t\tupdateTarget = { type: \"extensions\", source };\n\t\t\t}\n\t\t} else if (selfFlag && extensionsFlag) {\n\t\t\tupdateTarget = { type: \"all\" };\n\t\t} else if (selfFlag) {\n\t\t\tupdateTarget = { type: \"self\" };\n\t\t} else if (extensionsFlag) {\n\t\t\tupdateTarget = { type: \"extensions\" };\n\t\t} else {\n\t\t\tupdateTarget = { type: \"all\" };\n\t\t}\n\t}\n\n\treturn {\n\t\tcommand,\n\t\tsource,\n\t\tupdateTarget,\n\t\tlocal,\n\t\tforce,\n\t\thelp,\n\t\tinvalidOption,\n\t\tinvalidArgument,\n\t\tmissingOptionValue,\n\t\tconflictingOptions,\n\t};\n}\n\nfunction updateTargetIncludesSelf(target: UpdateTarget): boolean {\n\treturn target.type === \"all\" || target.type === \"self\";\n}\n\nfunction updateTargetIncludesExtensions(target: UpdateTarget): boolean {\n\treturn target.type === \"all\" || target.type === \"extensions\";\n}\n\nfunction printSelfUpdateUnavailable(npmCommand?: string[], updatePackageName = PACKAGE_NAME): void {\n\tconsole.error(`error: ${APP_NAME} cannot self-update this installation.`);\n\tconsole.error(getSelfUpdateUnavailableInstruction(PACKAGE_NAME, npmCommand, updatePackageName));\n\n\tconst entrypoint = process.argv[1];\n\tif (entrypoint) {\n\t\tconsole.error(\"\");\n\t\tconsole.error(`Location of pi executable: ${entrypoint}`);\n\t}\n}\n\nfunction printSelfUpdateFallback(command: SelfUpdateCommand): void {\n\tconsole.error(chalk.dim(`If this keeps failing, run this command yourself: ${command.display}`));\n}\n\ninterface SelfUpdatePlan {\n\tpackageName: string;\n\tshouldRun: boolean;\n}\n\nasync function getSelfUpdatePlan(force: boolean): Promise<SelfUpdatePlan> {\n\tif (force) {\n\t\treturn { packageName: PACKAGE_NAME, shouldRun: true };\n\t}\n\n\ttry {\n\t\tconst latestRelease = await getLatestPiRelease(VERSION);\n\t\tconst packageName = latestRelease?.packageName ?? PACKAGE_NAME;\n\t\tif (!latestRelease || packageName !== PACKAGE_NAME || isNewerPackageVersion(latestRelease.version, VERSION)) {\n\t\t\treturn { packageName, shouldRun: true };\n\t\t}\n\t} catch {\n\t\treturn { packageName: PACKAGE_NAME, shouldRun: true };\n\t}\n\n\tconsole.log(chalk.green(`${APP_NAME} is already up to date (v${VERSION})`));\n\treturn { packageName: PACKAGE_NAME, shouldRun: false };\n}\n\nasync function runSelfUpdate(command: SelfUpdateCommand): Promise<void> {\n\tconsole.log(chalk.dim(`Updating ${APP_NAME} with ${command.display}...`));\n\tfor (const step of command.steps ?? [command]) {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t// Windows package managers are commonly .cmd shims. Use the shell so Node can execute them.\n\t\t\tconst child = spawn(step.command, step.args, {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t\tshell: shouldUseWindowsShell(step.command),\n\t\t\t});\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\treject(error);\n\t\t\t});\n\t\t\tchild.on(\"close\", (code, signal) => {\n\t\t\t\tif (code === 0) {\n\t\t\t\t\tresolve();\n\t\t\t\t} else if (signal) {\n\t\t\t\t\treject(new Error(`${step.display} terminated by signal ${signal}`));\n\t\t\t\t} else {\n\t\t\t\t\treject(new Error(`${step.display} exited with code ${code ?? \"unknown\"}`));\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n}\n\nexport async function handleConfigCommand(args: string[]): Promise<boolean> {\n\tif (args[0] !== \"config\") {\n\t\treturn false;\n\t}\n\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settingsManager = SettingsManager.create(cwd, agentDir);\n\treportSettingsErrors(settingsManager, \"config command\");\n\tconst packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });\n\tconst resolvedPaths = await packageManager.resolve();\n\n\tawait selectConfig({\n\t\tresolvedPaths,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tagentDir,\n\t});\n\n\tprocess.exit(0);\n}\n\nexport async function handlePackageCommand(args: string[]): Promise<boolean> {\n\tconst options = parsePackageCommand(args);\n\tif (!options) {\n\t\treturn false;\n\t}\n\n\tif (options.help) {\n\t\tprintPackageCommandHelp(options.command);\n\t\treturn true;\n\t}\n\n\tif (options.invalidOption) {\n\t\tconsole.error(chalk.red(`Unknown option ${options.invalidOption} for \"${options.command}\".`));\n\t\tconsole.error(chalk.dim(`Use \"${APP_NAME} --help\" or \"${getPackageCommandUsage(options.command)}\".`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tif (options.missingOptionValue) {\n\t\tconsole.error(chalk.red(`Missing value for ${options.missingOptionValue}.`));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tif (options.invalidArgument) {\n\t\tconsole.error(chalk.red(`Unexpected argument ${options.invalidArgument}.`));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tif (options.conflictingOptions) {\n\t\tconsole.error(chalk.red(options.conflictingOptions));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tconst source = options.source;\n\tif ((options.command === \"install\" || options.command === \"remove\") && !source) {\n\t\tconsole.error(chalk.red(`Missing ${options.command} source.`));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settingsManager = SettingsManager.create(cwd, agentDir);\n\treportSettingsErrors(settingsManager, \"package command\");\n\tconst selfUpdateNpmCommand = settingsManager.getGlobalSettings().npmCommand;\n\n\tconst packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });\n\n\tpackageManager.setProgressCallback((event) => {\n\t\tif (event.type === \"start\") {\n\t\t\tprocess.stdout.write(chalk.dim(`${event.message}\\n`));\n\t\t}\n\t});\n\n\ttry {\n\t\tswitch (options.command) {\n\t\t\tcase \"install\":\n\t\t\t\tawait packageManager.installAndPersist(source!, { local: options.local });\n\t\t\t\tconsole.log(chalk.green(`Installed ${source}`));\n\t\t\t\treturn true;\n\n\t\t\tcase \"remove\": {\n\t\t\t\tconst removed = await packageManager.removeAndPersist(source!, { local: options.local });\n\t\t\t\tif (!removed) {\n\t\t\t\t\tconsole.error(chalk.red(`No matching package found for ${source}`));\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tconsole.log(chalk.green(`Removed ${source}`));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst configuredPackages = packageManager.listConfiguredPackages();\n\t\t\t\tconst userPackages = configuredPackages.filter((pkg) => pkg.scope === \"user\");\n\t\t\t\tconst projectPackages = configuredPackages.filter((pkg) => pkg.scope === \"project\");\n\n\t\t\t\tif (configuredPackages.length === 0) {\n\t\t\t\t\tconsole.log(chalk.dim(\"No packages installed.\"));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tconst formatPackage = (pkg: (typeof configuredPackages)[number]) => {\n\t\t\t\t\tconst display = pkg.filtered ? `${pkg.source} (filtered)` : pkg.source;\n\t\t\t\t\tconsole.log(` ${display}`);\n\t\t\t\t\tif (pkg.installedPath) {\n\t\t\t\t\t\tconsole.log(chalk.dim(` ${pkg.installedPath}`));\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (userPackages.length > 0) {\n\t\t\t\t\tconsole.log(chalk.bold(\"User packages:\"));\n\t\t\t\t\tfor (const pkg of userPackages) {\n\t\t\t\t\t\tformatPackage(pkg);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (projectPackages.length > 0) {\n\t\t\t\t\tif (userPackages.length > 0) console.log();\n\t\t\t\t\tconsole.log(chalk.bold(\"Project packages:\"));\n\t\t\t\t\tfor (const pkg of projectPackages) {\n\t\t\t\t\t\tformatPackage(pkg);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\tconst target = options.updateTarget ?? { type: \"all\" };\n\t\t\t\tif (updateTargetIncludesExtensions(target)) {\n\t\t\t\t\tconst updateSource = target.type === \"extensions\" ? target.source : undefined;\n\t\t\t\t\tawait packageManager.update(updateSource);\n\t\t\t\t\tif (updateSource) {\n\t\t\t\t\t\tconsole.log(chalk.green(`Updated ${updateSource}`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(chalk.green(\"Updated packages\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (updateTargetIncludesSelf(target)) {\n\t\t\t\t\tconst selfUpdatePlan = await getSelfUpdatePlan(options.force);\n\t\t\t\t\tif (!selfUpdatePlan.shouldRun) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tconst selfUpdateCommand = getSelfUpdateCommand(\n\t\t\t\t\t\tPACKAGE_NAME,\n\t\t\t\t\t\tselfUpdateNpmCommand,\n\t\t\t\t\t\tselfUpdatePlan.packageName,\n\t\t\t\t\t);\n\t\t\t\t\tif (!selfUpdateCommand) {\n\t\t\t\t\t\tprintSelfUpdateUnavailable(selfUpdateNpmCommand, selfUpdatePlan.packageName);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait runSelfUpdate(selfUpdateCommand);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tconst message = error instanceof Error ? error.message : \"Unknown package command error\";\n\t\t\t\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\t\t\t\tprintSelfUpdateFallback(selfUpdateCommand);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tconsole.log(chalk.green(`Updated ${APP_NAME}`));\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : \"Unknown package command error\";\n\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"package-manager-cli.d.ts","sourceRoot":"","sources":["../src/package-manager-cli.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAgXtE,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAoB1E;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAgL3E","sourcesContent":["import { Markdown, type MarkdownTheme } from \"@sheason/pi-tui\";\nimport chalk from \"chalk\";\nimport { selectConfig } from \"./cli/config-selector.ts\";\nimport {\n\tAPP_NAME,\n\tdetectInstallMethod,\n\tgetAgentDir,\n\tgetPackageDir,\n\tgetSelfUpdateCommand,\n\tgetSelfUpdateUnavailableInstruction,\n\tPACKAGE_NAME,\n\ttype SelfUpdateCommand,\n\tVERSION,\n} from \"./config.ts\";\nimport { DefaultPackageManager } from \"./core/package-manager.ts\";\nimport { SettingsManager } from \"./core/settings-manager.ts\";\nimport { spawnProcess } from \"./utils/child-process.ts\";\nimport { getLatestPiRelease, isNewerPackageVersion } from \"./utils/version-check.ts\";\nimport {\n\tcleanupWindowsSelfUpdateQuarantine,\n\tquarantineWindowsNativeDependencies,\n} from \"./utils/windows-self-update.ts\";\n\nexport type PackageCommand = \"install\" | \"remove\" | \"update\" | \"list\";\n\ntype UpdateTarget = { type: \"all\" } | { type: \"self\" } | { type: \"extensions\"; source?: string };\n\nconst SELF_UPDATE_NOTE_MARKDOWN_THEME: MarkdownTheme = {\n\theading: (text) => chalk.bold(chalk.yellow(text)),\n\tlink: (text) => chalk.cyan(text),\n\tlinkUrl: (text) => chalk.dim(text),\n\tcode: (text) => chalk.yellow(text),\n\tcodeBlock: (text) => chalk.dim(text),\n\tcodeBlockBorder: (text) => chalk.dim(text),\n\tquote: (text) => chalk.dim(text),\n\tquoteBorder: (text) => chalk.dim(text),\n\thr: (text) => chalk.dim(text),\n\tlistBullet: (text) => chalk.yellow(text),\n\tbold: (text) => chalk.bold(text),\n\titalic: (text) => chalk.italic(text),\n\tstrikethrough: (text) => chalk.strikethrough(text),\n\tunderline: (text) => chalk.underline(text),\n};\n\ninterface PackageCommandOptions {\n\tcommand: PackageCommand;\n\tsource?: string;\n\tupdateTarget?: UpdateTarget;\n\tlocal: boolean;\n\tforce: boolean;\n\thelp: boolean;\n\tinvalidOption?: string;\n\tinvalidArgument?: string;\n\tmissingOptionValue?: string;\n\tconflictingOptions?: string;\n}\n\nfunction reportSettingsErrors(settingsManager: SettingsManager, context: string): void {\n\tconst errors = settingsManager.drainErrors();\n\tfor (const { scope, error } of errors) {\n\t\tconsole.error(chalk.yellow(`Warning (${context}, ${scope} settings): ${error.message}`));\n\t\tif (error.stack) {\n\t\t\tconsole.error(chalk.dim(error.stack));\n\t\t}\n\t}\n}\n\nfunction getPackageCommandUsage(command: PackageCommand): string {\n\tswitch (command) {\n\t\tcase \"install\":\n\t\t\treturn `${APP_NAME} install <source> [-l]`;\n\t\tcase \"remove\":\n\t\t\treturn `${APP_NAME} remove <source> [-l]`;\n\t\tcase \"update\":\n\t\t\treturn `${APP_NAME} update [source|self|pi] [--self] [--extensions] [--extension <source>] [--force]`;\n\t\tcase \"list\":\n\t\t\treturn `${APP_NAME} list`;\n\t}\n}\n\nfunction printPackageCommandHelp(command: PackageCommand): void {\n\tswitch (command) {\n\t\tcase \"install\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"install\")}\n\nInstall a package and add it to settings.\n\nOptions:\n -l, --local Install project-locally (.pi/settings.json)\n\nExamples:\n ${APP_NAME} install npm:@foo/bar\n ${APP_NAME} install git:github.com/user/repo\n ${APP_NAME} install git:git@github.com:user/repo\n ${APP_NAME} install https://github.com/user/repo\n ${APP_NAME} install ssh://git@github.com/user/repo\n ${APP_NAME} install ./local/path\n`);\n\t\t\treturn;\n\n\t\tcase \"remove\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"remove\")}\n\nRemove a package and its source from settings.\nAlias: ${APP_NAME} uninstall <source> [-l]\n\nOptions:\n -l, --local Remove from project settings (.pi/settings.json)\n\nExamples:\n ${APP_NAME} remove npm:@foo/bar\n ${APP_NAME} uninstall npm:@foo/bar\n`);\n\t\t\treturn;\n\n\t\tcase \"update\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"update\")}\n\nUpdate pi and installed packages.\n\nOptions:\n --self Update pi only\n --extensions Update installed packages only\n --extension <source> Update one package only\n --force Reinstall pi even if the current version is latest\n\nShort forms:\n ${APP_NAME} update Update pi and all extensions\n ${APP_NAME} update <source> Update one package\n ${APP_NAME} update pi Update pi only (self works as alias to pi)\n`);\n\t\t\treturn;\n\n\t\tcase \"list\":\n\t\t\tconsole.log(`${chalk.bold(\"Usage:\")}\n ${getPackageCommandUsage(\"list\")}\n\nList installed packages from user and project settings.\n`);\n\t\t\treturn;\n\t}\n}\n\nfunction parsePackageCommand(args: string[]): PackageCommandOptions | undefined {\n\tconst [rawCommand, ...rest] = args;\n\tlet command: PackageCommand | undefined;\n\tif (rawCommand === \"uninstall\") {\n\t\tcommand = \"remove\";\n\t} else if (rawCommand === \"install\" || rawCommand === \"remove\" || rawCommand === \"update\" || rawCommand === \"list\") {\n\t\tcommand = rawCommand;\n\t}\n\tif (!command) {\n\t\treturn undefined;\n\t}\n\n\tlet local = false;\n\tlet force = false;\n\tlet help = false;\n\tlet invalidOption: string | undefined;\n\tlet invalidArgument: string | undefined;\n\tlet missingOptionValue: string | undefined;\n\tlet conflictingOptions: string | undefined;\n\tlet source: string | undefined;\n\tlet selfFlag = false;\n\tlet extensionsFlag = false;\n\tlet extensionFlagSource: string | undefined;\n\n\tfor (let index = 0; index < rest.length; index++) {\n\t\tconst arg = rest[index];\n\t\tif (arg === \"-h\" || arg === \"--help\") {\n\t\t\thelp = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"-l\" || arg === \"--local\") {\n\t\t\tif (command === \"install\" || command === \"remove\") {\n\t\t\t\tlocal = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--self\") {\n\t\t\tif (command === \"update\") {\n\t\t\t\tselfFlag = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--extensions\") {\n\t\t\tif (command === \"update\") {\n\t\t\t\textensionsFlag = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--force\") {\n\t\t\tif (command === \"update\") {\n\t\t\t\tforce = true;\n\t\t\t} else {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--extension\") {\n\t\t\tif (command !== \"update\") {\n\t\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst value = rest[index + 1];\n\t\t\tif (!value || value.startsWith(\"-\")) {\n\t\t\t\tmissingOptionValue = missingOptionValue ?? arg;\n\t\t\t} else if (extensionFlagSource) {\n\t\t\t\tconflictingOptions = conflictingOptions ?? \"--extension can only be provided once\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\textensionFlagSource = value;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg.startsWith(\"-\")) {\n\t\t\tinvalidOption = invalidOption ?? arg;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!source) {\n\t\t\tsource = arg;\n\t\t} else {\n\t\t\tinvalidArgument = invalidArgument ?? arg;\n\t\t}\n\t}\n\n\tlet updateTarget: UpdateTarget | undefined;\n\tif (command === \"update\") {\n\t\tif (extensionFlagSource) {\n\t\t\tif (selfFlag || extensionsFlag) {\n\t\t\t\tconflictingOptions = conflictingOptions ?? \"--extension cannot be combined with --self or --extensions\";\n\t\t\t}\n\t\t\tif (source) {\n\t\t\t\tconflictingOptions = conflictingOptions ?? \"--extension cannot be combined with a positional source\";\n\t\t\t}\n\t\t\tupdateTarget = { type: \"extensions\", source: extensionFlagSource };\n\t\t} else if (source) {\n\t\t\tconst sourceIsSelf = source === \"self\" || source === \"pi\";\n\t\t\tif (sourceIsSelf) {\n\t\t\t\tupdateTarget = extensionsFlag ? { type: \"all\" } : { type: \"self\" };\n\t\t\t} else {\n\t\t\t\tif (extensionsFlag || selfFlag) {\n\t\t\t\t\tconflictingOptions =\n\t\t\t\t\t\tconflictingOptions ?? \"positional update targets cannot be combined with --self or --extensions\";\n\t\t\t\t}\n\t\t\t\tupdateTarget = { type: \"extensions\", source };\n\t\t\t}\n\t\t} else if (selfFlag && extensionsFlag) {\n\t\t\tupdateTarget = { type: \"all\" };\n\t\t} else if (selfFlag) {\n\t\t\tupdateTarget = { type: \"self\" };\n\t\t} else if (extensionsFlag) {\n\t\t\tupdateTarget = { type: \"extensions\" };\n\t\t} else {\n\t\t\tupdateTarget = { type: \"all\" };\n\t\t}\n\t}\n\n\treturn {\n\t\tcommand,\n\t\tsource,\n\t\tupdateTarget,\n\t\tlocal,\n\t\tforce,\n\t\thelp,\n\t\tinvalidOption,\n\t\tinvalidArgument,\n\t\tmissingOptionValue,\n\t\tconflictingOptions,\n\t};\n}\n\nfunction updateTargetIncludesSelf(target: UpdateTarget): boolean {\n\treturn target.type === \"all\" || target.type === \"self\";\n}\n\nfunction updateTargetIncludesExtensions(target: UpdateTarget): boolean {\n\treturn target.type === \"all\" || target.type === \"extensions\";\n}\n\nfunction printSelfUpdateUnavailable(npmCommand?: string[], updatePackageName = PACKAGE_NAME): void {\n\tconsole.error(`error: ${APP_NAME} cannot self-update this installation.`);\n\tconsole.error(getSelfUpdateUnavailableInstruction(PACKAGE_NAME, npmCommand, updatePackageName));\n\n\tconst entrypoint = process.argv[1];\n\tif (entrypoint) {\n\t\tconsole.error(\"\");\n\t\tconsole.error(`Location of pi executable: ${entrypoint}`);\n\t}\n}\n\nfunction printSelfUpdateFallback(command: SelfUpdateCommand): void {\n\tconsole.error(chalk.dim(`If this keeps failing, run this command yourself: ${command.display}`));\n}\n\nfunction printSelfUpdateNote(note: string): void {\n\tconst trimmedNote = note.trim();\n\tif (!trimmedNote) {\n\t\treturn;\n\t}\n\n\tconsole.log();\n\tconsole.log(chalk.bold(chalk.yellow(\"Update note\")));\n\ttry {\n\t\tconst width = Math.max(20, process.stdout.columns ?? 80);\n\t\tconst renderedLines = new Markdown(trimmedNote, 0, 0, SELF_UPDATE_NOTE_MARKDOWN_THEME)\n\t\t\t.render(width)\n\t\t\t.map((line) => line.trimEnd());\n\t\tconsole.log(renderedLines.join(\"\\n\"));\n\t} catch {\n\t\tconsole.log(trimmedNote);\n\t}\n\tconsole.log();\n}\n\ninterface SelfUpdatePlan {\n\tpackageName: string;\n\tshouldRun: boolean;\n\tnote?: string;\n}\n\nasync function getSelfUpdatePlan(force: boolean): Promise<SelfUpdatePlan> {\n\tif (force) {\n\t\treturn { packageName: PACKAGE_NAME, shouldRun: true };\n\t}\n\n\ttry {\n\t\tconst latestRelease = await getLatestPiRelease(VERSION);\n\t\tconst packageName = latestRelease?.packageName ?? PACKAGE_NAME;\n\t\tif (!latestRelease || packageName !== PACKAGE_NAME || isNewerPackageVersion(latestRelease.version, VERSION)) {\n\t\t\treturn { packageName, shouldRun: true, ...(latestRelease?.note ? { note: latestRelease.note } : {}) };\n\t\t}\n\t} catch {\n\t\treturn { packageName: PACKAGE_NAME, shouldRun: true };\n\t}\n\n\tconsole.log(chalk.green(`${APP_NAME} is already up to date (v${VERSION})`));\n\treturn { packageName: PACKAGE_NAME, shouldRun: false };\n}\n\nasync function runSelfUpdate(command: SelfUpdateCommand): Promise<void> {\n\tconsole.log(chalk.dim(`Updating ${APP_NAME} with ${command.display}...`));\n\tfor (const step of command.steps ?? [command]) {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst child = spawnProcess(step.command, step.args, {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t});\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\treject(error);\n\t\t\t});\n\t\t\tchild.on(\"close\", (code, signal) => {\n\t\t\t\tif (code === 0) {\n\t\t\t\t\tresolve();\n\t\t\t\t} else if (signal) {\n\t\t\t\t\treject(new Error(`${step.display} terminated by signal ${signal}`));\n\t\t\t\t} else {\n\t\t\t\t\treject(new Error(`${step.display} exited with code ${code ?? \"unknown\"}`));\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n}\n\nfunction prepareWindowsNpmSelfUpdate(): void {\n\tif (process.platform !== \"win32\") {\n\t\treturn;\n\t}\n\n\tconst packageDir = getPackageDir();\n\tcleanupWindowsSelfUpdateQuarantine(packageDir);\n\tquarantineWindowsNativeDependencies(packageDir);\n}\n\nexport async function handleConfigCommand(args: string[]): Promise<boolean> {\n\tif (args[0] !== \"config\") {\n\t\treturn false;\n\t}\n\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settingsManager = SettingsManager.create(cwd, agentDir);\n\treportSettingsErrors(settingsManager, \"config command\");\n\tconst packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });\n\tconst resolvedPaths = await packageManager.resolve();\n\n\tawait selectConfig({\n\t\tresolvedPaths,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tagentDir,\n\t});\n\n\tprocess.exit(0);\n}\n\nexport async function handlePackageCommand(args: string[]): Promise<boolean> {\n\tconst options = parsePackageCommand(args);\n\tif (!options) {\n\t\treturn false;\n\t}\n\n\tif (options.help) {\n\t\tprintPackageCommandHelp(options.command);\n\t\treturn true;\n\t}\n\n\tif (options.invalidOption) {\n\t\tconsole.error(chalk.red(`Unknown option ${options.invalidOption} for \"${options.command}\".`));\n\t\tconsole.error(chalk.dim(`Use \"${APP_NAME} --help\" or \"${getPackageCommandUsage(options.command)}\".`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tif (options.missingOptionValue) {\n\t\tconsole.error(chalk.red(`Missing value for ${options.missingOptionValue}.`));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tif (options.invalidArgument) {\n\t\tconsole.error(chalk.red(`Unexpected argument ${options.invalidArgument}.`));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tif (options.conflictingOptions) {\n\t\tconsole.error(chalk.red(options.conflictingOptions));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tconst source = options.source;\n\tif ((options.command === \"install\" || options.command === \"remove\") && !source) {\n\t\tconsole.error(chalk.red(`Missing ${options.command} source.`));\n\t\tconsole.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settingsManager = SettingsManager.create(cwd, agentDir);\n\treportSettingsErrors(settingsManager, \"package command\");\n\tconst selfUpdateNpmCommand = settingsManager.getGlobalSettings().npmCommand;\n\n\tconst packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });\n\n\tpackageManager.setProgressCallback((event) => {\n\t\tif (event.type === \"start\") {\n\t\t\tprocess.stdout.write(chalk.dim(`${event.message}\\n`));\n\t\t}\n\t});\n\n\ttry {\n\t\tswitch (options.command) {\n\t\t\tcase \"install\":\n\t\t\t\tawait packageManager.installAndPersist(source!, { local: options.local });\n\t\t\t\tconsole.log(chalk.green(`Installed ${source}`));\n\t\t\t\treturn true;\n\n\t\t\tcase \"remove\": {\n\t\t\t\tconst removed = await packageManager.removeAndPersist(source!, { local: options.local });\n\t\t\t\tif (!removed) {\n\t\t\t\t\tconsole.error(chalk.red(`No matching package found for ${source}`));\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tconsole.log(chalk.green(`Removed ${source}`));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst configuredPackages = packageManager.listConfiguredPackages();\n\t\t\t\tconst userPackages = configuredPackages.filter((pkg) => pkg.scope === \"user\");\n\t\t\t\tconst projectPackages = configuredPackages.filter((pkg) => pkg.scope === \"project\");\n\n\t\t\t\tif (configuredPackages.length === 0) {\n\t\t\t\t\tconsole.log(chalk.dim(\"No packages installed.\"));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tconst formatPackage = (pkg: (typeof configuredPackages)[number]) => {\n\t\t\t\t\tconst display = pkg.filtered ? `${pkg.source} (filtered)` : pkg.source;\n\t\t\t\t\tconsole.log(` ${display}`);\n\t\t\t\t\tif (pkg.installedPath) {\n\t\t\t\t\t\tconsole.log(chalk.dim(` ${pkg.installedPath}`));\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (userPackages.length > 0) {\n\t\t\t\t\tconsole.log(chalk.bold(\"User packages:\"));\n\t\t\t\t\tfor (const pkg of userPackages) {\n\t\t\t\t\t\tformatPackage(pkg);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (projectPackages.length > 0) {\n\t\t\t\t\tif (userPackages.length > 0) console.log();\n\t\t\t\t\tconsole.log(chalk.bold(\"Project packages:\"));\n\t\t\t\t\tfor (const pkg of projectPackages) {\n\t\t\t\t\t\tformatPackage(pkg);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\tconst target = options.updateTarget ?? { type: \"all\" };\n\t\t\t\tif (updateTargetIncludesExtensions(target)) {\n\t\t\t\t\tconst updateSource = target.type === \"extensions\" ? target.source : undefined;\n\t\t\t\t\tawait packageManager.update(updateSource);\n\t\t\t\t\tif (updateSource) {\n\t\t\t\t\t\tconsole.log(chalk.green(`Updated ${updateSource}`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(chalk.green(\"Updated packages\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (updateTargetIncludesSelf(target)) {\n\t\t\t\t\tconst selfUpdatePlan = await getSelfUpdatePlan(options.force);\n\t\t\t\t\tif (!selfUpdatePlan.shouldRun) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tconst installMethod = detectInstallMethod();\n\t\t\t\t\tif (process.platform === \"win32\" && installMethod !== \"npm\" && installMethod !== \"pnpm\") {\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\tchalk.red(`${APP_NAME} self-update on Windows is only supported for npm and pnpm installs.`),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconsole.error(chalk.dim(`Detected install method: ${installMethod}. Update ${APP_NAME} manually.`));\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tconst selfUpdateCommand = getSelfUpdateCommand(\n\t\t\t\t\t\tPACKAGE_NAME,\n\t\t\t\t\t\tselfUpdateNpmCommand,\n\t\t\t\t\t\tselfUpdatePlan.packageName,\n\t\t\t\t\t);\n\t\t\t\t\tif (!selfUpdateCommand) {\n\t\t\t\t\t\tprintSelfUpdateUnavailable(selfUpdateNpmCommand, selfUpdatePlan.packageName);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tif (selfUpdatePlan.note) {\n\t\t\t\t\t\tprintSelfUpdateNote(selfUpdatePlan.note);\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (installMethod === \"npm\") {\n\t\t\t\t\t\t\tprepareWindowsNpmSelfUpdate();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait runSelfUpdate(selfUpdateCommand);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tconst message = error instanceof Error ? error.message : \"Unknown package command error\";\n\t\t\t\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\t\t\t\tprintSelfUpdateFallback(selfUpdateCommand);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tconsole.log(chalk.green(`Updated ${APP_NAME}`));\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : \"Unknown package command error\";\n\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\tprocess.exitCode = 1;\n\t\treturn true;\n\t}\n}\n"]}
|
|
@@ -1,11 +1,28 @@
|
|
|
1
|
+
import { Markdown } from "@sheason/pi-tui";
|
|
1
2
|
import chalk from "chalk";
|
|
2
|
-
import { spawn } from "child_process";
|
|
3
3
|
import { selectConfig } from "./cli/config-selector.js";
|
|
4
|
-
import { APP_NAME, getAgentDir, getSelfUpdateCommand, getSelfUpdateUnavailableInstruction, PACKAGE_NAME, VERSION, } from "./config.js";
|
|
4
|
+
import { APP_NAME, detectInstallMethod, getAgentDir, getPackageDir, getSelfUpdateCommand, getSelfUpdateUnavailableInstruction, PACKAGE_NAME, VERSION, } from "./config.js";
|
|
5
5
|
import { DefaultPackageManager } from "./core/package-manager.js";
|
|
6
6
|
import { SettingsManager } from "./core/settings-manager.js";
|
|
7
|
-
import {
|
|
7
|
+
import { spawnProcess } from "./utils/child-process.js";
|
|
8
8
|
import { getLatestPiRelease, isNewerPackageVersion } from "./utils/version-check.js";
|
|
9
|
+
import { cleanupWindowsSelfUpdateQuarantine, quarantineWindowsNativeDependencies, } from "./utils/windows-self-update.js";
|
|
10
|
+
const SELF_UPDATE_NOTE_MARKDOWN_THEME = {
|
|
11
|
+
heading: (text) => chalk.bold(chalk.yellow(text)),
|
|
12
|
+
link: (text) => chalk.cyan(text),
|
|
13
|
+
linkUrl: (text) => chalk.dim(text),
|
|
14
|
+
code: (text) => chalk.yellow(text),
|
|
15
|
+
codeBlock: (text) => chalk.dim(text),
|
|
16
|
+
codeBlockBorder: (text) => chalk.dim(text),
|
|
17
|
+
quote: (text) => chalk.dim(text),
|
|
18
|
+
quoteBorder: (text) => chalk.dim(text),
|
|
19
|
+
hr: (text) => chalk.dim(text),
|
|
20
|
+
listBullet: (text) => chalk.yellow(text),
|
|
21
|
+
bold: (text) => chalk.bold(text),
|
|
22
|
+
italic: (text) => chalk.italic(text),
|
|
23
|
+
strikethrough: (text) => chalk.strikethrough(text),
|
|
24
|
+
underline: (text) => chalk.underline(text),
|
|
25
|
+
};
|
|
9
26
|
function reportSettingsErrors(settingsManager, context) {
|
|
10
27
|
const errors = settingsManager.drainErrors();
|
|
11
28
|
for (const { scope, error } of errors) {
|
|
@@ -252,6 +269,25 @@ function printSelfUpdateUnavailable(npmCommand, updatePackageName = PACKAGE_NAME
|
|
|
252
269
|
function printSelfUpdateFallback(command) {
|
|
253
270
|
console.error(chalk.dim(`If this keeps failing, run this command yourself: ${command.display}`));
|
|
254
271
|
}
|
|
272
|
+
function printSelfUpdateNote(note) {
|
|
273
|
+
const trimmedNote = note.trim();
|
|
274
|
+
if (!trimmedNote) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
console.log();
|
|
278
|
+
console.log(chalk.bold(chalk.yellow("Update note")));
|
|
279
|
+
try {
|
|
280
|
+
const width = Math.max(20, process.stdout.columns ?? 80);
|
|
281
|
+
const renderedLines = new Markdown(trimmedNote, 0, 0, SELF_UPDATE_NOTE_MARKDOWN_THEME)
|
|
282
|
+
.render(width)
|
|
283
|
+
.map((line) => line.trimEnd());
|
|
284
|
+
console.log(renderedLines.join("\n"));
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
console.log(trimmedNote);
|
|
288
|
+
}
|
|
289
|
+
console.log();
|
|
290
|
+
}
|
|
255
291
|
async function getSelfUpdatePlan(force) {
|
|
256
292
|
if (force) {
|
|
257
293
|
return { packageName: PACKAGE_NAME, shouldRun: true };
|
|
@@ -260,7 +296,7 @@ async function getSelfUpdatePlan(force) {
|
|
|
260
296
|
const latestRelease = await getLatestPiRelease(VERSION);
|
|
261
297
|
const packageName = latestRelease?.packageName ?? PACKAGE_NAME;
|
|
262
298
|
if (!latestRelease || packageName !== PACKAGE_NAME || isNewerPackageVersion(latestRelease.version, VERSION)) {
|
|
263
|
-
return { packageName, shouldRun: true };
|
|
299
|
+
return { packageName, shouldRun: true, ...(latestRelease?.note ? { note: latestRelease.note } : {}) };
|
|
264
300
|
}
|
|
265
301
|
}
|
|
266
302
|
catch {
|
|
@@ -273,10 +309,8 @@ async function runSelfUpdate(command) {
|
|
|
273
309
|
console.log(chalk.dim(`Updating ${APP_NAME} with ${command.display}...`));
|
|
274
310
|
for (const step of command.steps ?? [command]) {
|
|
275
311
|
await new Promise((resolve, reject) => {
|
|
276
|
-
|
|
277
|
-
const child = spawn(step.command, step.args, {
|
|
312
|
+
const child = spawnProcess(step.command, step.args, {
|
|
278
313
|
stdio: "inherit",
|
|
279
|
-
shell: shouldUseWindowsShell(step.command),
|
|
280
314
|
});
|
|
281
315
|
child.on("error", (error) => {
|
|
282
316
|
reject(error);
|
|
@@ -295,6 +329,14 @@ async function runSelfUpdate(command) {
|
|
|
295
329
|
});
|
|
296
330
|
}
|
|
297
331
|
}
|
|
332
|
+
function prepareWindowsNpmSelfUpdate() {
|
|
333
|
+
if (process.platform !== "win32") {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const packageDir = getPackageDir();
|
|
337
|
+
cleanupWindowsSelfUpdateQuarantine(packageDir);
|
|
338
|
+
quarantineWindowsNativeDependencies(packageDir);
|
|
339
|
+
}
|
|
298
340
|
export async function handleConfigCommand(args) {
|
|
299
341
|
if (args[0] !== "config") {
|
|
300
342
|
return false;
|
|
@@ -428,13 +470,26 @@ export async function handlePackageCommand(args) {
|
|
|
428
470
|
if (!selfUpdatePlan.shouldRun) {
|
|
429
471
|
return true;
|
|
430
472
|
}
|
|
473
|
+
const installMethod = detectInstallMethod();
|
|
474
|
+
if (process.platform === "win32" && installMethod !== "npm" && installMethod !== "pnpm") {
|
|
475
|
+
console.error(chalk.red(`${APP_NAME} self-update on Windows is only supported for npm and pnpm installs.`));
|
|
476
|
+
console.error(chalk.dim(`Detected install method: ${installMethod}. Update ${APP_NAME} manually.`));
|
|
477
|
+
process.exitCode = 1;
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
431
480
|
const selfUpdateCommand = getSelfUpdateCommand(PACKAGE_NAME, selfUpdateNpmCommand, selfUpdatePlan.packageName);
|
|
432
481
|
if (!selfUpdateCommand) {
|
|
433
482
|
printSelfUpdateUnavailable(selfUpdateNpmCommand, selfUpdatePlan.packageName);
|
|
434
483
|
process.exitCode = 1;
|
|
435
484
|
return true;
|
|
436
485
|
}
|
|
486
|
+
if (selfUpdatePlan.note) {
|
|
487
|
+
printSelfUpdateNote(selfUpdatePlan.note);
|
|
488
|
+
}
|
|
437
489
|
try {
|
|
490
|
+
if (installMethod === "npm") {
|
|
491
|
+
prepareWindowsNpmSelfUpdate();
|
|
492
|
+
}
|
|
438
493
|
await runSelfUpdate(selfUpdateCommand);
|
|
439
494
|
}
|
|
440
495
|
catch (error) {
|