@phi-code-admin/phi-code 0.74.3 → 0.75.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 +1186 -4
- package/README.md +478 -379
- package/dist/bun/cli.d.ts +3 -0
- package/dist/bun/cli.d.ts.map +1 -0
- package/dist/bun/cli.js +9 -0
- package/dist/bun/cli.js.map +1 -0
- package/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/bun/register-bedrock.d.ts.map +1 -0
- package/dist/bun/register-bedrock.js +4 -0
- package/dist/bun/register-bedrock.js.map +1 -0
- package/dist/bun/restore-sandbox-env.d.ts +13 -0
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
- package/dist/bun/restore-sandbox-env.js +32 -0
- package/dist/bun/restore-sandbox-env.js.map +1 -0
- package/dist/cli/args.d.ts +12 -7
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +87 -45
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +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 +4 -0
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +18 -0
- package/dist/cli/initial-message.d.ts.map +1 -0
- package/dist/cli/initial-message.js +22 -0
- package/dist/cli/initial-message.js.map +1 -0
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +7 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js +2 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +9 -5
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +226 -30
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +117 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -0
- package/dist/core/agent-session-runtime.js +300 -0
- package/dist/core/agent-session-runtime.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +86 -0
- package/dist/core/agent-session-services.d.ts.map +1 -0
- package/dist/core/agent-session-services.js +117 -0
- package/dist/core/agent-session-services.js.map +1 -0
- package/dist/core/agent-session.d.ts +63 -82
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +674 -628
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/api-key-store.d.ts +87 -0
- package/dist/core/api-key-store.d.ts.map +1 -0
- package/dist/core/api-key-store.js +168 -0
- package/dist/core/api-key-store.js.map +1 -0
- package/dist/core/auth-guidance.d.ts +5 -0
- package/dist/core/auth-guidance.d.ts.map +1 -0
- package/dist/core/auth-guidance.js +21 -0
- package/dist/core/auth-guidance.js.map +1 -0
- package/dist/core/auth-storage.d.ts +12 -5
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +34 -8
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts +0 -15
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +28 -129
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -4
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +32 -27
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/config-watcher.d.ts +47 -0
- package/dist/core/config-watcher.d.ts.map +1 -0
- package/dist/core/config-watcher.js +135 -0
- package/dist/core/config-watcher.js.map +1 -0
- package/dist/core/default-models.json +80 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +7 -3
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts +7 -4
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +15 -13
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.css +112 -17
- package/dist/core/export-html/template.html +1 -0
- package/dist/core/export-html/template.js +312 -64
- package/dist/core/export-html/tool-renderer.d.ts +9 -10
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +61 -16
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +5 -4
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +2 -2
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +0 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +98 -18
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +27 -14
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +299 -115
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +200 -44
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +10 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +4 -11
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +7 -87
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +22 -2
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +225 -49
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/index.d.ts +5 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +5 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +348 -50
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +276 -132
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +41 -5
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +316 -136
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +6 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +70 -37
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/output-guard.d.ts +6 -0
- package/dist/core/output-guard.d.ts.map +1 -0
- package/dist/core/output-guard.js +59 -0
- package/dist/core/output-guard.js.map +1 -0
- package/dist/core/package-manager.d.ts +49 -7
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +655 -122
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +12 -10
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +37 -38
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-display-names.d.ts +2 -0
- package/dist/core/provider-display-names.d.ts.map +1 -0
- package/dist/core/provider-display-names.js +33 -0
- package/dist/core/provider-display-names.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +6 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +75 -8
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +18 -8
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +217 -123
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +25 -8
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +84 -37
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts +19 -0
- package/dist/core/session-cwd.d.ts.map +1 -0
- package/dist/core/session-cwd.js +38 -0
- package/dist/core/session-cwd.js.map +1 -0
- package/dist/core/session-manager.d.ts +11 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +42 -27
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +34 -5
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +113 -13
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +13 -11
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +59 -19
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +2 -3
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +9 -6
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +18 -0
- package/dist/core/source-info.d.ts.map +1 -0
- package/dist/core/source-info.js +19 -0
- package/dist/core/source-info.js.map +1 -0
- package/dist/core/system-prompt.d.ts +3 -3
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +16 -55
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts +3 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +9 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/timings.d.ts +1 -0
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +6 -0
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +27 -14
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +301 -208
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +23 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +154 -59
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +22 -12
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +243 -65
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +37 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/find.d.ts +10 -14
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +202 -110
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +14 -22
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +100 -35
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +27 -60
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +96 -45
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +8 -11
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +66 -15
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +50 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -0
- package/dist/core/tools/output-accumulator.js +178 -0
- package/dist/core/tools/output-accumulator.js.map +1 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +1 -1
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts +9 -13
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +175 -52
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +21 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -0
- package/dist/core/tools/render-utils.js +49 -0
- package/dist/core/tools/render-utils.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.js +34 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts +8 -11
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +167 -32
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +12 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +5 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +326 -404
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +2 -2
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +24 -4
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +10 -6
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +5 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +32 -3
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +31 -12
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +7 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +5 -3
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +5 -3
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +49 -16
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +5 -0
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +14 -7
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +6 -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 +8 -6
- 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 +1 -0
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
- package/dist/modes/interactive/components/earendil-announcement.js +40 -0
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +16 -10
- 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 +13 -7
- 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 +18 -11
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +1 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +7 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +8 -36
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +23 -48
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +5 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +35 -14
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +41 -22
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +18 -6
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +104 -31
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +5 -12
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +61 -42
- package/dist/modes/interactive/components/scoped-models-selector.js.map +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 +2 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +109 -73
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +9 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +84 -4
- 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 +6 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +5 -3
- 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 +7 -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 +6 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +20 -34
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +158 -636
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +21 -2
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +224 -52
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts +2 -2
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +20 -16
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +1 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +8 -6
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +67 -39
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1556 -680
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -1
- package/dist/modes/interactive/theme/light.json +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +3 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +101 -72
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +2 -2
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +107 -77
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts +17 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -0
- package/dist/modes/rpc/jsonl.js +49 -0
- package/dist/modes/rpc/jsonl.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +8 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +22 -16
- 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 +184 -94
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +14 -4
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts +4 -0
- package/dist/package-manager-cli.d.ts.map +1 -0
- package/dist/package-manager-cli.js +460 -0
- package/dist/package-manager-cli.js.map +1 -0
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts +12 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +86 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +94 -11
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +96 -46
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts +5 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -0
- package/dist/utils/exif-orientation.js +158 -0
- package/dist/utils/exif-orientation.js.map +1 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts +5 -0
- package/dist/utils/fs-watch.d.ts.map +1 -0
- package/dist/utils/fs-watch.js +25 -0
- package/dist/utils/fs-watch.js.map +1 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js +5 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize.d.ts +5 -5
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +51 -95
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/paths.d.ts +16 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +50 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts +2 -0
- package/dist/utils/pi-user-agent.d.ts.map +1 -0
- package/dist/utils/pi-user-agent.js +5 -0
- package/dist/utils/pi-user-agent.js.map +1 -0
- package/dist/utils/shell.d.ts +10 -6
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +29 -25
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +11 -6
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +14 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +77 -0
- package/dist/utils/version-check.js.map +1 -0
- package/docs/compaction.md +394 -0
- package/docs/custom-provider.md +646 -0
- package/docs/development.md +71 -0
- package/docs/docs.json +148 -0
- package/docs/extensions.md +2596 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +70 -0
- package/docs/json.md +82 -0
- package/docs/keybindings.md +197 -0
- package/docs/models.md +474 -0
- package/docs/packages.md +223 -0
- package/docs/prompt-templates.md +88 -0
- package/docs/providers.md +243 -0
- package/docs/quickstart.md +142 -0
- package/docs/rpc.md +1407 -0
- package/docs/sdk.md +1149 -0
- package/docs/session-format.md +412 -0
- package/docs/sessions.md +137 -0
- package/docs/settings.md +279 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +232 -0
- package/docs/terminal-setup.md +106 -0
- package/docs/termux.md +127 -0
- package/docs/themes.md +295 -0
- package/docs/tmux.md +61 -0
- package/docs/tui.md +918 -0
- package/docs/usage.md +277 -0
- package/docs/windows.md +17 -0
- package/examples/README.md +25 -0
- package/examples/extensions/README.md +208 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/border-status-editor.ts +150 -0
- package/examples/extensions/built-in-tool-renderer.ts +249 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +72 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +127 -0
- package/examples/extensions/custom-footer.ts +64 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +132 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +15 -0
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/github-issue-autocomplete.ts +185 -0
- package/examples/extensions/handoff.ts +191 -0
- package/examples/extensions/hello.ts +26 -0
- package/examples/extensions/hidden-thinking-label.ts +53 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +426 -0
- package/examples/extensions/modal-editor.ts +85 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +55 -0
- package/examples/extensions/overlay-qa-tests.ts +1348 -0
- package/examples/extensions/overlay-test.ts +150 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +340 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +430 -0
- package/examples/extensions/prompt-customizer.ts +97 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/provider-payload.ts +18 -0
- package/examples/extensions/qna.ts +122 -0
- package/examples/extensions/question.ts +264 -0
- package/examples/extensions/questionnaire.ts +427 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +118 -0
- package/examples/extensions/sandbox/index.ts +321 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +343 -0
- package/examples/extensions/space-invaders.ts +560 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/status-line.ts +32 -0
- package/examples/extensions/structured-output.ts +65 -0
- package/examples/extensions/subagent/README.md +172 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +987 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +206 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/tic-tac-toe.ts +1008 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +297 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +141 -0
- package/examples/extensions/trigger-compact.ts +50 -0
- package/examples/extensions/truncated-tool.ts +195 -0
- package/examples/extensions/widget-placement.ts +9 -0
- package/examples/extensions/with-deps/index.ts +32 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/extensions/working-indicator.ts +123 -0
- package/examples/extensions/working-message-test.ts +25 -0
- package/examples/rpc-extension-ui.ts +632 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +62 -0
- package/examples/sdk/04-skills.ts +55 -0
- package/examples/sdk/05-tools.ts +44 -0
- package/examples/sdk/06-extensions.ts +90 -0
- package/examples/sdk/07-context-files.ts +42 -0
- package/examples/sdk/08-prompt-templates.ts +51 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
- package/examples/sdk/10-settings.ts +53 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +73 -0
- package/examples/sdk/13-session-runtime.ts +67 -0
- package/examples/sdk/README.md +147 -0
- package/extensions/phi/init.ts +15 -1
- package/extensions/phi/keys.ts +186 -0
- package/extensions/phi/providers/alibaba.ts +126 -0
- package/extensions/phi/providers/opencode-go.ts +204 -0
- package/extensions/phi/setup.ts +692 -0
- package/extensions/phi/smart-router.ts +8 -0
- package/package.json +17 -12
- package/scripts/copy-assets.sh +0 -0
- package/scripts/migrate-sessions.sh +0 -0
|
@@ -2,18 +2,61 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { homedir, tmpdir } from "node:os";
|
|
5
|
+
function getEnv() {
|
|
6
|
+
if (process.platform !== "linux" || Object.keys(process.env).length > 0) {
|
|
7
|
+
return process.env;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
const data = readFileSync("/proc/self/environ", "utf-8");
|
|
11
|
+
const env = {};
|
|
12
|
+
for (const entry of data.split("\0")) {
|
|
13
|
+
const idx = entry.indexOf("=");
|
|
14
|
+
if (idx > 0) {
|
|
15
|
+
env[entry.slice(0, idx)] = entry.slice(idx + 1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return env;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return process.env;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
5
24
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
25
|
+
import { globSync } from "glob";
|
|
6
26
|
import ignore from "ignore";
|
|
7
27
|
import { minimatch } from "minimatch";
|
|
8
28
|
import { CONFIG_DIR_NAME } from "../config.js";
|
|
29
|
+
import { shouldUseWindowsShell } from "../utils/child-process.js";
|
|
9
30
|
import { parseGitUrl } from "../utils/git.js";
|
|
31
|
+
import { canonicalizePath, isLocalPath } from "../utils/paths.js";
|
|
32
|
+
import { isStdoutTakenOver } from "./output-guard.js";
|
|
10
33
|
const NETWORK_TIMEOUT_MS = 10000;
|
|
34
|
+
const UPDATE_CHECK_CONCURRENCY = 4;
|
|
35
|
+
const GIT_UPDATE_CONCURRENCY = 4;
|
|
11
36
|
function isOfflineModeEnabled() {
|
|
12
37
|
const value = process.env.PI_OFFLINE;
|
|
13
38
|
if (!value)
|
|
14
39
|
return false;
|
|
15
40
|
return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
|
|
16
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute a numeric precedence rank for a resource based on its metadata.
|
|
44
|
+
* Lower rank = higher precedence. Used to sort resolved resources so that
|
|
45
|
+
* name-collision resolution ("first wins") produces the correct outcome.
|
|
46
|
+
*
|
|
47
|
+
* Precedence (highest to lowest):
|
|
48
|
+
* 0 project + settings entry (source: "local", scope: "project")
|
|
49
|
+
* 1 project + auto-discovered (source: "auto", scope: "project")
|
|
50
|
+
* 2 user + settings entry (source: "local", scope: "user")
|
|
51
|
+
* 3 user + auto-discovered (source: "auto", scope: "user")
|
|
52
|
+
* 4 package resource (origin: "package")
|
|
53
|
+
*/
|
|
54
|
+
function resourcePrecedenceRank(m) {
|
|
55
|
+
if (m.origin === "package")
|
|
56
|
+
return 4;
|
|
57
|
+
const scopeBase = m.scope === "project" ? 0 : 2;
|
|
58
|
+
return scopeBase + (m.source === "local" ? 0 : 1);
|
|
59
|
+
}
|
|
17
60
|
const RESOURCE_TYPES = ["extensions", "skills", "prompts", "themes"];
|
|
18
61
|
const FILE_PATTERNS = {
|
|
19
62
|
extensions: /\.(ts|js)$/,
|
|
@@ -25,6 +68,9 @@ const IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
|
|
|
25
68
|
function toPosixPath(p) {
|
|
26
69
|
return p.split(sep).join("/");
|
|
27
70
|
}
|
|
71
|
+
function getHomeDir() {
|
|
72
|
+
return process.env.HOME || homedir();
|
|
73
|
+
}
|
|
28
74
|
function prefixIgnorePattern(line, prefix) {
|
|
29
75
|
const trimmed = line.trim();
|
|
30
76
|
if (!trimmed)
|
|
@@ -69,6 +115,12 @@ function addIgnoreRules(ig, dir, rootDir) {
|
|
|
69
115
|
function isPattern(s) {
|
|
70
116
|
return s.startsWith("!") || s.startsWith("+") || s.startsWith("-") || s.includes("*") || s.includes("?");
|
|
71
117
|
}
|
|
118
|
+
function isOverridePattern(s) {
|
|
119
|
+
return s.startsWith("!") || s.startsWith("+") || s.startsWith("-");
|
|
120
|
+
}
|
|
121
|
+
function hasGlobPattern(s) {
|
|
122
|
+
return s.includes("*") || s.includes("?");
|
|
123
|
+
}
|
|
72
124
|
function splitPatterns(entries) {
|
|
73
125
|
const plain = [];
|
|
74
126
|
const patterns = [];
|
|
@@ -126,7 +178,7 @@ function collectFiles(dir, filePattern, skipNodeModules = true, ignoreMatcher, r
|
|
|
126
178
|
}
|
|
127
179
|
return files;
|
|
128
180
|
}
|
|
129
|
-
function collectSkillEntries(dir,
|
|
181
|
+
function collectSkillEntries(dir, mode, ignoreMatcher, rootDir) {
|
|
130
182
|
const entries = [];
|
|
131
183
|
if (!existsSync(dir))
|
|
132
184
|
return entries;
|
|
@@ -135,6 +187,26 @@ function collectSkillEntries(dir, includeRootFiles = true, ignoreMatcher, rootDi
|
|
|
135
187
|
addIgnoreRules(ig, dir, root);
|
|
136
188
|
try {
|
|
137
189
|
const dirEntries = readdirSync(dir, { withFileTypes: true });
|
|
190
|
+
for (const entry of dirEntries) {
|
|
191
|
+
if (entry.name !== "SKILL.md") {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const fullPath = join(dir, entry.name);
|
|
195
|
+
let isFile = entry.isFile();
|
|
196
|
+
if (entry.isSymbolicLink()) {
|
|
197
|
+
try {
|
|
198
|
+
isFile = statSync(fullPath).isFile();
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const relPath = toPosixPath(relative(root, fullPath));
|
|
205
|
+
if (isFile && !ig.ignores(relPath)) {
|
|
206
|
+
entries.push(fullPath);
|
|
207
|
+
return entries;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
138
210
|
for (const entry of dirEntries) {
|
|
139
211
|
if (entry.name.startsWith("."))
|
|
140
212
|
continue;
|
|
@@ -154,19 +226,15 @@ function collectSkillEntries(dir, includeRootFiles = true, ignoreMatcher, rootDi
|
|
|
154
226
|
}
|
|
155
227
|
}
|
|
156
228
|
const relPath = toPosixPath(relative(root, fullPath));
|
|
157
|
-
|
|
158
|
-
|
|
229
|
+
if (mode === "pi" && dir === root && isFile && entry.name.endsWith(".md") && !ig.ignores(relPath)) {
|
|
230
|
+
entries.push(fullPath);
|
|
159
231
|
continue;
|
|
160
|
-
if (isDir) {
|
|
161
|
-
entries.push(...collectSkillEntries(fullPath, false, ig, root));
|
|
162
|
-
}
|
|
163
|
-
else if (isFile) {
|
|
164
|
-
const isRootMd = includeRootFiles && entry.name.endsWith(".md");
|
|
165
|
-
const isSkillMd = !includeRootFiles && entry.name === "SKILL.md";
|
|
166
|
-
if (isRootMd || isSkillMd) {
|
|
167
|
-
entries.push(fullPath);
|
|
168
|
-
}
|
|
169
232
|
}
|
|
233
|
+
if (!isDir)
|
|
234
|
+
continue;
|
|
235
|
+
if (ig.ignores(`${relPath}/`))
|
|
236
|
+
continue;
|
|
237
|
+
entries.push(...collectSkillEntries(fullPath, mode, ig, root));
|
|
170
238
|
}
|
|
171
239
|
}
|
|
172
240
|
catch {
|
|
@@ -174,8 +242,8 @@ function collectSkillEntries(dir, includeRootFiles = true, ignoreMatcher, rootDi
|
|
|
174
242
|
}
|
|
175
243
|
return entries;
|
|
176
244
|
}
|
|
177
|
-
function collectAutoSkillEntries(dir,
|
|
178
|
-
return collectSkillEntries(dir,
|
|
245
|
+
function collectAutoSkillEntries(dir, mode) {
|
|
246
|
+
return collectSkillEntries(dir, mode);
|
|
179
247
|
}
|
|
180
248
|
function findGitRepoRoot(startDir) {
|
|
181
249
|
let dir = resolve(startDir);
|
|
@@ -375,7 +443,7 @@ function collectAutoExtensionEntries(dir) {
|
|
|
375
443
|
*/
|
|
376
444
|
function collectResourceFiles(dir, resourceType) {
|
|
377
445
|
if (resourceType === "skills") {
|
|
378
|
-
return collectSkillEntries(dir);
|
|
446
|
+
return collectSkillEntries(dir, "pi");
|
|
379
447
|
}
|
|
380
448
|
if (resourceType === "extensions") {
|
|
381
449
|
return collectAutoExtensionEntries(dir);
|
|
@@ -383,43 +451,50 @@ function collectResourceFiles(dir, resourceType) {
|
|
|
383
451
|
return collectFiles(dir, FILE_PATTERNS[resourceType]);
|
|
384
452
|
}
|
|
385
453
|
function matchesAnyPattern(filePath, patterns, baseDir) {
|
|
386
|
-
const rel = relative(baseDir, filePath);
|
|
454
|
+
const rel = toPosixPath(relative(baseDir, filePath));
|
|
387
455
|
const name = basename(filePath);
|
|
456
|
+
const filePathPosix = toPosixPath(filePath);
|
|
388
457
|
const isSkillFile = name === "SKILL.md";
|
|
389
458
|
const parentDir = isSkillFile ? dirname(filePath) : undefined;
|
|
390
|
-
const parentRel = isSkillFile ? relative(baseDir, parentDir) : undefined;
|
|
459
|
+
const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
|
|
391
460
|
const parentName = isSkillFile ? basename(parentDir) : undefined;
|
|
461
|
+
const parentDirPosix = isSkillFile ? toPosixPath(parentDir) : undefined;
|
|
392
462
|
return patterns.some((pattern) => {
|
|
393
|
-
|
|
463
|
+
const normalizedPattern = toPosixPath(pattern);
|
|
464
|
+
if (minimatch(rel, normalizedPattern) ||
|
|
465
|
+
minimatch(name, normalizedPattern) ||
|
|
466
|
+
minimatch(filePathPosix, normalizedPattern)) {
|
|
394
467
|
return true;
|
|
395
468
|
}
|
|
396
469
|
if (!isSkillFile)
|
|
397
470
|
return false;
|
|
398
|
-
return minimatch(parentRel,
|
|
471
|
+
return (minimatch(parentRel, normalizedPattern) ||
|
|
472
|
+
minimatch(parentName, normalizedPattern) ||
|
|
473
|
+
minimatch(parentDirPosix, normalizedPattern));
|
|
399
474
|
});
|
|
400
475
|
}
|
|
401
476
|
function normalizeExactPattern(pattern) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
return pattern;
|
|
477
|
+
const normalized = pattern.startsWith("./") || pattern.startsWith(".\\") ? pattern.slice(2) : pattern;
|
|
478
|
+
return toPosixPath(normalized);
|
|
406
479
|
}
|
|
407
480
|
function matchesAnyExactPattern(filePath, patterns, baseDir) {
|
|
408
481
|
if (patterns.length === 0)
|
|
409
482
|
return false;
|
|
410
|
-
const rel = relative(baseDir, filePath);
|
|
483
|
+
const rel = toPosixPath(relative(baseDir, filePath));
|
|
411
484
|
const name = basename(filePath);
|
|
485
|
+
const filePathPosix = toPosixPath(filePath);
|
|
412
486
|
const isSkillFile = name === "SKILL.md";
|
|
413
487
|
const parentDir = isSkillFile ? dirname(filePath) : undefined;
|
|
414
|
-
const parentRel = isSkillFile ? relative(baseDir, parentDir) : undefined;
|
|
488
|
+
const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
|
|
489
|
+
const parentDirPosix = isSkillFile ? toPosixPath(parentDir) : undefined;
|
|
415
490
|
return patterns.some((pattern) => {
|
|
416
491
|
const normalized = normalizeExactPattern(pattern);
|
|
417
|
-
if (normalized === rel || normalized ===
|
|
492
|
+
if (normalized === rel || normalized === filePathPosix) {
|
|
418
493
|
return true;
|
|
419
494
|
}
|
|
420
495
|
if (!isSkillFile)
|
|
421
496
|
return false;
|
|
422
|
-
return normalized === parentRel || normalized ===
|
|
497
|
+
return normalized === parentRel || normalized === parentDirPosix;
|
|
423
498
|
});
|
|
424
499
|
}
|
|
425
500
|
function getOverridePatterns(entries) {
|
|
@@ -496,6 +571,12 @@ function applyPatterns(allPaths, patterns, baseDir) {
|
|
|
496
571
|
return new Set(result);
|
|
497
572
|
}
|
|
498
573
|
export class DefaultPackageManager {
|
|
574
|
+
cwd;
|
|
575
|
+
agentDir;
|
|
576
|
+
settingsManager;
|
|
577
|
+
globalNpmRoot;
|
|
578
|
+
globalNpmRootCommandKey;
|
|
579
|
+
progressCallback;
|
|
499
580
|
constructor(options) {
|
|
500
581
|
this.cwd = options.cwd;
|
|
501
582
|
this.agentDir = options.agentDir;
|
|
@@ -613,6 +694,30 @@ export class DefaultPackageManager {
|
|
|
613
694
|
await this.resolvePackageSources(packageSources, accumulator);
|
|
614
695
|
return this.toResolvedPaths(accumulator);
|
|
615
696
|
}
|
|
697
|
+
listConfiguredPackages() {
|
|
698
|
+
const globalSettings = this.settingsManager.getGlobalSettings();
|
|
699
|
+
const projectSettings = this.settingsManager.getProjectSettings();
|
|
700
|
+
const configuredPackages = [];
|
|
701
|
+
for (const pkg of globalSettings.packages ?? []) {
|
|
702
|
+
const source = typeof pkg === "string" ? pkg : pkg.source;
|
|
703
|
+
configuredPackages.push({
|
|
704
|
+
source,
|
|
705
|
+
scope: "user",
|
|
706
|
+
filtered: typeof pkg === "object",
|
|
707
|
+
installedPath: this.getInstalledPath(source, "user"),
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
for (const pkg of projectSettings.packages ?? []) {
|
|
711
|
+
const source = typeof pkg === "string" ? pkg : pkg.source;
|
|
712
|
+
configuredPackages.push({
|
|
713
|
+
source,
|
|
714
|
+
scope: "project",
|
|
715
|
+
filtered: typeof pkg === "object",
|
|
716
|
+
installedPath: this.getInstalledPath(source, "project"),
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
return configuredPackages;
|
|
720
|
+
}
|
|
616
721
|
async install(source, options) {
|
|
617
722
|
const parsed = this.parseSource(source);
|
|
618
723
|
const scope = options?.local ? "project" : "user";
|
|
@@ -635,6 +740,10 @@ export class DefaultPackageManager {
|
|
|
635
740
|
throw new Error(`Unsupported install source: ${source}`);
|
|
636
741
|
});
|
|
637
742
|
}
|
|
743
|
+
async installAndPersist(source, options) {
|
|
744
|
+
await this.install(source, options);
|
|
745
|
+
this.addSourceToSettings(source, options);
|
|
746
|
+
}
|
|
638
747
|
async remove(source, options) {
|
|
639
748
|
const parsed = this.parseSource(source);
|
|
640
749
|
const scope = options?.local ? "project" : "user";
|
|
@@ -653,44 +762,178 @@ export class DefaultPackageManager {
|
|
|
653
762
|
throw new Error(`Unsupported remove source: ${source}`);
|
|
654
763
|
});
|
|
655
764
|
}
|
|
765
|
+
async removeAndPersist(source, options) {
|
|
766
|
+
await this.remove(source, options);
|
|
767
|
+
return this.removeSourceFromSettings(source, options);
|
|
768
|
+
}
|
|
656
769
|
async update(source) {
|
|
657
770
|
const globalSettings = this.settingsManager.getGlobalSettings();
|
|
658
771
|
const projectSettings = this.settingsManager.getProjectSettings();
|
|
659
772
|
const identity = source ? this.getPackageIdentity(source) : undefined;
|
|
773
|
+
let matched = false;
|
|
774
|
+
const updateSources = [];
|
|
660
775
|
for (const pkg of globalSettings.packages ?? []) {
|
|
661
776
|
const sourceStr = typeof pkg === "string" ? pkg : pkg.source;
|
|
662
777
|
if (identity && this.getPackageIdentity(sourceStr, "user") !== identity)
|
|
663
778
|
continue;
|
|
664
|
-
|
|
779
|
+
matched = true;
|
|
780
|
+
updateSources.push({ source: sourceStr, scope: "user" });
|
|
665
781
|
}
|
|
666
782
|
for (const pkg of projectSettings.packages ?? []) {
|
|
667
783
|
const sourceStr = typeof pkg === "string" ? pkg : pkg.source;
|
|
668
784
|
if (identity && this.getPackageIdentity(sourceStr, "project") !== identity)
|
|
669
785
|
continue;
|
|
670
|
-
|
|
786
|
+
matched = true;
|
|
787
|
+
updateSources.push({ source: sourceStr, scope: "project" });
|
|
788
|
+
}
|
|
789
|
+
if (source && !matched) {
|
|
790
|
+
throw new Error(this.buildNoMatchingPackageMessage(source, [
|
|
791
|
+
...(globalSettings.packages ?? []),
|
|
792
|
+
...(projectSettings.packages ?? []),
|
|
793
|
+
]));
|
|
671
794
|
}
|
|
795
|
+
await this.updateConfiguredSources(updateSources);
|
|
672
796
|
}
|
|
673
|
-
async
|
|
674
|
-
if (isOfflineModeEnabled()) {
|
|
797
|
+
async updateConfiguredSources(sources) {
|
|
798
|
+
if (isOfflineModeEnabled() || sources.length === 0) {
|
|
675
799
|
return;
|
|
676
800
|
}
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
}
|
|
801
|
+
const npmCandidates = [];
|
|
802
|
+
const gitCandidates = [];
|
|
803
|
+
for (const entry of sources) {
|
|
804
|
+
const parsed = this.parseSource(entry.source);
|
|
805
|
+
if (parsed.type === "local" || parsed.pinned) {
|
|
806
|
+
continue;
|
|
807
|
+
}
|
|
808
|
+
if (parsed.type === "npm") {
|
|
809
|
+
npmCandidates.push({ ...entry, parsed });
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
gitCandidates.push({ ...entry, parsed });
|
|
813
|
+
}
|
|
814
|
+
const npmCheckTasks = npmCandidates.map((entry) => async () => ({
|
|
815
|
+
entry,
|
|
816
|
+
shouldUpdate: await this.shouldUpdateNpmSource(entry.parsed, entry.scope),
|
|
817
|
+
}));
|
|
818
|
+
const npmCheckResults = await this.runWithConcurrency(npmCheckTasks, UPDATE_CHECK_CONCURRENCY);
|
|
819
|
+
const userNpmUpdates = [];
|
|
820
|
+
const projectNpmUpdates = [];
|
|
821
|
+
for (const result of npmCheckResults) {
|
|
822
|
+
if (!result.shouldUpdate) {
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
if (result.entry.scope === "user") {
|
|
826
|
+
userNpmUpdates.push(result.entry);
|
|
827
|
+
}
|
|
828
|
+
else {
|
|
829
|
+
projectNpmUpdates.push(result.entry);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
const tasks = [];
|
|
833
|
+
if (userNpmUpdates.length > 0) {
|
|
834
|
+
tasks.push(this.updateNpmBatch(userNpmUpdates, "user"));
|
|
835
|
+
}
|
|
836
|
+
if (projectNpmUpdates.length > 0) {
|
|
837
|
+
tasks.push(this.updateNpmBatch(projectNpmUpdates, "project"));
|
|
838
|
+
}
|
|
839
|
+
if (gitCandidates.length > 0) {
|
|
840
|
+
const gitTasks = gitCandidates.map((entry) => async () => this.withProgress("update", entry.source, `Updating ${entry.source}...`, async () => {
|
|
841
|
+
await this.updateGit(entry.parsed, entry.scope);
|
|
842
|
+
}));
|
|
843
|
+
tasks.push(this.runWithConcurrency(gitTasks, GIT_UPDATE_CONCURRENCY).then(() => { }));
|
|
844
|
+
}
|
|
845
|
+
await Promise.all(tasks);
|
|
846
|
+
}
|
|
847
|
+
async shouldUpdateNpmSource(source, scope) {
|
|
848
|
+
const installedPath = this.getNpmInstallPath(source, scope);
|
|
849
|
+
const installedVersion = existsSync(installedPath) ? this.getInstalledNpmVersion(installedPath) : undefined;
|
|
850
|
+
if (!installedVersion) {
|
|
851
|
+
return true;
|
|
852
|
+
}
|
|
853
|
+
try {
|
|
854
|
+
const latestVersion = await this.getLatestNpmVersion(source.name);
|
|
855
|
+
return latestVersion !== installedVersion;
|
|
856
|
+
}
|
|
857
|
+
catch {
|
|
858
|
+
// Preserve existing update behavior when version lookup fails.
|
|
859
|
+
return true;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
async updateNpmBatch(sources, scope) {
|
|
863
|
+
if (sources.length === 0) {
|
|
684
864
|
return;
|
|
685
865
|
}
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
866
|
+
const sourceLabel = sources.length === 1 ? sources[0].source : `${scope} npm packages`;
|
|
867
|
+
const message = sources.length === 1 ? `Updating ${sources[0].source}...` : `Updating ${scope} npm packages...`;
|
|
868
|
+
const specs = sources.map((entry) => `${entry.parsed.name}@latest`);
|
|
869
|
+
await this.withProgress("update", sourceLabel, message, async () => {
|
|
870
|
+
await this.installNpmBatch(specs, scope);
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
async installNpmBatch(specs, scope) {
|
|
874
|
+
if (scope === "user") {
|
|
875
|
+
await this.runNpmCommand(["install", "-g", ...specs]);
|
|
692
876
|
return;
|
|
693
877
|
}
|
|
878
|
+
const installRoot = this.getNpmInstallRoot(scope, false);
|
|
879
|
+
this.ensureNpmProject(installRoot);
|
|
880
|
+
await this.runNpmCommand(["install", ...specs, "--prefix", installRoot]);
|
|
881
|
+
}
|
|
882
|
+
async checkForAvailableUpdates() {
|
|
883
|
+
if (isOfflineModeEnabled()) {
|
|
884
|
+
return [];
|
|
885
|
+
}
|
|
886
|
+
const globalSettings = this.settingsManager.getGlobalSettings();
|
|
887
|
+
const projectSettings = this.settingsManager.getProjectSettings();
|
|
888
|
+
const allPackages = [];
|
|
889
|
+
for (const pkg of projectSettings.packages ?? []) {
|
|
890
|
+
allPackages.push({ pkg, scope: "project" });
|
|
891
|
+
}
|
|
892
|
+
for (const pkg of globalSettings.packages ?? []) {
|
|
893
|
+
allPackages.push({ pkg, scope: "user" });
|
|
894
|
+
}
|
|
895
|
+
const packageSources = this.dedupePackages(allPackages);
|
|
896
|
+
const checks = packageSources
|
|
897
|
+
.filter((entry) => entry.scope !== "temporary")
|
|
898
|
+
.map((entry) => async () => {
|
|
899
|
+
const source = typeof entry.pkg === "string" ? entry.pkg : entry.pkg.source;
|
|
900
|
+
const parsed = this.parseSource(source);
|
|
901
|
+
if (parsed.type === "local" || parsed.pinned) {
|
|
902
|
+
return undefined;
|
|
903
|
+
}
|
|
904
|
+
if (parsed.type === "npm") {
|
|
905
|
+
const installedPath = this.getNpmInstallPath(parsed, entry.scope);
|
|
906
|
+
if (!existsSync(installedPath)) {
|
|
907
|
+
return undefined;
|
|
908
|
+
}
|
|
909
|
+
const hasUpdate = await this.npmHasAvailableUpdate(parsed, installedPath);
|
|
910
|
+
if (!hasUpdate) {
|
|
911
|
+
return undefined;
|
|
912
|
+
}
|
|
913
|
+
return {
|
|
914
|
+
source,
|
|
915
|
+
displayName: parsed.name,
|
|
916
|
+
type: "npm",
|
|
917
|
+
scope: entry.scope,
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
const installedPath = this.getGitInstallPath(parsed, entry.scope);
|
|
921
|
+
if (!existsSync(installedPath)) {
|
|
922
|
+
return undefined;
|
|
923
|
+
}
|
|
924
|
+
const hasUpdate = await this.gitHasAvailableUpdate(installedPath);
|
|
925
|
+
if (!hasUpdate) {
|
|
926
|
+
return undefined;
|
|
927
|
+
}
|
|
928
|
+
return {
|
|
929
|
+
source,
|
|
930
|
+
displayName: `${parsed.host}/${parsed.path}`,
|
|
931
|
+
type: "git",
|
|
932
|
+
scope: entry.scope,
|
|
933
|
+
};
|
|
934
|
+
});
|
|
935
|
+
const results = await this.runWithConcurrency(checks, UPDATE_CHECK_CONCURRENCY);
|
|
936
|
+
return results.filter((result) => result !== undefined);
|
|
694
937
|
}
|
|
695
938
|
async resolvePackageSources(sources, accumulator, onMissing) {
|
|
696
939
|
for (const { pkg, scope } of sources) {
|
|
@@ -721,7 +964,8 @@ export class DefaultPackageManager {
|
|
|
721
964
|
};
|
|
722
965
|
if (parsed.type === "npm") {
|
|
723
966
|
const installedPath = this.getNpmInstallPath(parsed, scope);
|
|
724
|
-
const needsInstall = !existsSync(installedPath) ||
|
|
967
|
+
const needsInstall = !existsSync(installedPath) ||
|
|
968
|
+
(parsed.pinned && !(await this.installedNpmMatchesPinnedVersion(parsed, installedPath)));
|
|
725
969
|
if (needsInstall) {
|
|
726
970
|
const installed = await installMissing();
|
|
727
971
|
if (!installed)
|
|
@@ -804,6 +1048,35 @@ export class DefaultPackageManager {
|
|
|
804
1048
|
const baseDir = this.getBaseDirForScope(scope);
|
|
805
1049
|
return `local:${this.resolvePathFromBase(parsed.path, baseDir)}`;
|
|
806
1050
|
}
|
|
1051
|
+
buildNoMatchingPackageMessage(source, configuredPackages) {
|
|
1052
|
+
const suggestion = this.findSuggestedConfiguredSource(source, configuredPackages);
|
|
1053
|
+
if (!suggestion) {
|
|
1054
|
+
return `No matching package found for ${source}`;
|
|
1055
|
+
}
|
|
1056
|
+
return `No matching package found for ${source}. Did you mean ${suggestion}?`;
|
|
1057
|
+
}
|
|
1058
|
+
findSuggestedConfiguredSource(source, configuredPackages) {
|
|
1059
|
+
const trimmedSource = source.trim();
|
|
1060
|
+
const suggestions = new Set();
|
|
1061
|
+
for (const pkg of configuredPackages) {
|
|
1062
|
+
const sourceStr = this.getPackageSourceString(pkg);
|
|
1063
|
+
const parsed = this.parseSource(sourceStr);
|
|
1064
|
+
if (parsed.type === "npm") {
|
|
1065
|
+
if (trimmedSource === parsed.name || trimmedSource === parsed.spec) {
|
|
1066
|
+
suggestions.add(sourceStr);
|
|
1067
|
+
}
|
|
1068
|
+
continue;
|
|
1069
|
+
}
|
|
1070
|
+
if (parsed.type === "git") {
|
|
1071
|
+
const shorthand = `${parsed.host}/${parsed.path}`;
|
|
1072
|
+
const shorthandWithRef = parsed.ref ? `${shorthand}@${parsed.ref}` : undefined;
|
|
1073
|
+
if (trimmedSource === shorthand || (shorthandWithRef && trimmedSource === shorthandWithRef)) {
|
|
1074
|
+
suggestions.add(sourceStr);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
return suggestions.values().next().value;
|
|
1079
|
+
}
|
|
807
1080
|
packageSourcesMatch(existing, inputSource, scope) {
|
|
808
1081
|
const left = this.getSourceMatchKeyForSettings(this.getPackageSourceString(existing), scope);
|
|
809
1082
|
const right = this.getSourceMatchKeyForInput(inputSource);
|
|
@@ -830,14 +1103,7 @@ export class DefaultPackageManager {
|
|
|
830
1103
|
pinned: Boolean(version),
|
|
831
1104
|
};
|
|
832
1105
|
}
|
|
833
|
-
|
|
834
|
-
const isWindowsAbsolutePath = /^[A-Za-z]:[\\/]|^\\\\/.test(trimmed);
|
|
835
|
-
const isLocalPathLike = trimmed.startsWith(".") ||
|
|
836
|
-
trimmed.startsWith("/") ||
|
|
837
|
-
trimmed === "~" ||
|
|
838
|
-
trimmed.startsWith("~/") ||
|
|
839
|
-
isWindowsAbsolutePath;
|
|
840
|
-
if (isLocalPathLike) {
|
|
1106
|
+
if (isLocalPath(source)) {
|
|
841
1107
|
return { type: "local", path: source };
|
|
842
1108
|
}
|
|
843
1109
|
// Try parsing as git URL
|
|
@@ -847,30 +1113,30 @@ export class DefaultPackageManager {
|
|
|
847
1113
|
}
|
|
848
1114
|
return { type: "local", path: source };
|
|
849
1115
|
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
1116
|
+
async installedNpmMatchesPinnedVersion(source, installedPath) {
|
|
1117
|
+
const installedVersion = this.getInstalledNpmVersion(installedPath);
|
|
1118
|
+
if (!installedVersion) {
|
|
1119
|
+
return false;
|
|
1120
|
+
}
|
|
1121
|
+
const { version: pinnedVersion } = this.parseNpmSpec(source.spec);
|
|
1122
|
+
if (!pinnedVersion) {
|
|
1123
|
+
return true;
|
|
1124
|
+
}
|
|
1125
|
+
return installedVersion === pinnedVersion;
|
|
1126
|
+
}
|
|
1127
|
+
async npmHasAvailableUpdate(source, installedPath) {
|
|
856
1128
|
if (isOfflineModeEnabled()) {
|
|
857
1129
|
return false;
|
|
858
1130
|
}
|
|
859
1131
|
const installedVersion = this.getInstalledNpmVersion(installedPath);
|
|
860
|
-
if (!installedVersion)
|
|
861
|
-
return
|
|
862
|
-
const { version: pinnedVersion } = this.parseNpmSpec(source.spec);
|
|
863
|
-
if (pinnedVersion) {
|
|
864
|
-
// Pinned: check if installed matches pinned (exact match for now)
|
|
865
|
-
return installedVersion !== pinnedVersion;
|
|
1132
|
+
if (!installedVersion) {
|
|
1133
|
+
return false;
|
|
866
1134
|
}
|
|
867
|
-
// Unpinned: check registry for latest version
|
|
868
1135
|
try {
|
|
869
1136
|
const latestVersion = await this.getLatestNpmVersion(source.name);
|
|
870
1137
|
return latestVersion !== installedVersion;
|
|
871
1138
|
}
|
|
872
1139
|
catch {
|
|
873
|
-
// If we can't check registry, assume it's fine
|
|
874
1140
|
return false;
|
|
875
1141
|
}
|
|
876
1142
|
}
|
|
@@ -888,13 +1154,151 @@ export class DefaultPackageManager {
|
|
|
888
1154
|
}
|
|
889
1155
|
}
|
|
890
1156
|
async getLatestNpmVersion(packageName) {
|
|
891
|
-
const
|
|
892
|
-
|
|
1157
|
+
const npmCommand = this.getNpmCommand();
|
|
1158
|
+
const stdout = await this.runCommandCapture(npmCommand.command, [...npmCommand.args, "view", packageName, "version", "--json"], { cwd: this.cwd, timeoutMs: NETWORK_TIMEOUT_MS });
|
|
1159
|
+
const raw = stdout.trim();
|
|
1160
|
+
if (!raw)
|
|
1161
|
+
throw new Error("Empty response from npm view");
|
|
1162
|
+
return JSON.parse(raw);
|
|
1163
|
+
}
|
|
1164
|
+
async gitHasAvailableUpdate(installedPath) {
|
|
1165
|
+
if (isOfflineModeEnabled()) {
|
|
1166
|
+
return false;
|
|
1167
|
+
}
|
|
1168
|
+
try {
|
|
1169
|
+
const localHead = await this.runCommandCapture("git", ["rev-parse", "HEAD"], {
|
|
1170
|
+
cwd: installedPath,
|
|
1171
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1172
|
+
});
|
|
1173
|
+
const remoteHead = await this.getRemoteGitHead(installedPath);
|
|
1174
|
+
return localHead.trim() !== remoteHead.trim();
|
|
1175
|
+
}
|
|
1176
|
+
catch {
|
|
1177
|
+
return false;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
async getRemoteGitHead(installedPath) {
|
|
1181
|
+
const upstreamRef = await this.getGitUpstreamRef(installedPath);
|
|
1182
|
+
if (upstreamRef) {
|
|
1183
|
+
const remoteHead = await this.runGitRemoteCommand(installedPath, ["ls-remote", "origin", upstreamRef]);
|
|
1184
|
+
const match = remoteHead.match(/^([0-9a-f]{40})\s+/m);
|
|
1185
|
+
if (match?.[1]) {
|
|
1186
|
+
return match[1];
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
const remoteHead = await this.runGitRemoteCommand(installedPath, ["ls-remote", "origin", "HEAD"]);
|
|
1190
|
+
const match = remoteHead.match(/^([0-9a-f]{40})\s+HEAD$/m);
|
|
1191
|
+
if (!match?.[1]) {
|
|
1192
|
+
throw new Error("Failed to determine remote HEAD");
|
|
1193
|
+
}
|
|
1194
|
+
return match[1];
|
|
1195
|
+
}
|
|
1196
|
+
async getLocalGitUpdateTarget(installedPath) {
|
|
1197
|
+
try {
|
|
1198
|
+
const upstream = await this.runCommandCapture("git", ["rev-parse", "--abbrev-ref", "@{upstream}"], {
|
|
1199
|
+
cwd: installedPath,
|
|
1200
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1201
|
+
});
|
|
1202
|
+
const trimmedUpstream = upstream.trim();
|
|
1203
|
+
if (!trimmedUpstream.startsWith("origin/")) {
|
|
1204
|
+
throw new Error(`Unsupported upstream remote: ${trimmedUpstream}`);
|
|
1205
|
+
}
|
|
1206
|
+
const branch = trimmedUpstream.slice("origin/".length);
|
|
1207
|
+
if (!branch) {
|
|
1208
|
+
throw new Error("Missing upstream branch name");
|
|
1209
|
+
}
|
|
1210
|
+
const head = await this.runCommandCapture("git", ["rev-parse", "@{upstream}"], {
|
|
1211
|
+
cwd: installedPath,
|
|
1212
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1213
|
+
});
|
|
1214
|
+
return {
|
|
1215
|
+
ref: "@{upstream}",
|
|
1216
|
+
head,
|
|
1217
|
+
fetchArgs: [
|
|
1218
|
+
"fetch",
|
|
1219
|
+
"--prune",
|
|
1220
|
+
"--no-tags",
|
|
1221
|
+
"origin",
|
|
1222
|
+
`+refs/heads/${branch}:refs/remotes/origin/${branch}`,
|
|
1223
|
+
],
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
catch {
|
|
1227
|
+
await this.runCommand("git", ["remote", "set-head", "origin", "-a"], { cwd: installedPath }).catch(() => { });
|
|
1228
|
+
const head = await this.runCommandCapture("git", ["rev-parse", "origin/HEAD"], {
|
|
1229
|
+
cwd: installedPath,
|
|
1230
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1231
|
+
});
|
|
1232
|
+
const originHeadRef = await this.runCommandCapture("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
|
|
1233
|
+
cwd: installedPath,
|
|
1234
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1235
|
+
}).catch(() => "");
|
|
1236
|
+
const branch = originHeadRef.trim().replace(/^refs\/remotes\/origin\//, "");
|
|
1237
|
+
if (branch) {
|
|
1238
|
+
return {
|
|
1239
|
+
ref: "origin/HEAD",
|
|
1240
|
+
head,
|
|
1241
|
+
fetchArgs: [
|
|
1242
|
+
"fetch",
|
|
1243
|
+
"--prune",
|
|
1244
|
+
"--no-tags",
|
|
1245
|
+
"origin",
|
|
1246
|
+
`+refs/heads/${branch}:refs/remotes/origin/${branch}`,
|
|
1247
|
+
],
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
return {
|
|
1251
|
+
ref: "origin/HEAD",
|
|
1252
|
+
head,
|
|
1253
|
+
fetchArgs: ["fetch", "--prune", "--no-tags", "origin", "+HEAD:refs/remotes/origin/HEAD"],
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
async getGitUpstreamRef(installedPath) {
|
|
1258
|
+
try {
|
|
1259
|
+
const upstream = await this.runCommandCapture("git", ["rev-parse", "--abbrev-ref", "@{upstream}"], {
|
|
1260
|
+
cwd: installedPath,
|
|
1261
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1262
|
+
});
|
|
1263
|
+
const trimmed = upstream.trim();
|
|
1264
|
+
if (!trimmed.startsWith("origin/")) {
|
|
1265
|
+
return undefined;
|
|
1266
|
+
}
|
|
1267
|
+
const branch = trimmed.slice("origin/".length);
|
|
1268
|
+
return branch ? `refs/heads/${branch}` : undefined;
|
|
1269
|
+
}
|
|
1270
|
+
catch {
|
|
1271
|
+
return undefined;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
runGitRemoteCommand(installedPath, args) {
|
|
1275
|
+
return this.runCommandCapture("git", args, {
|
|
1276
|
+
cwd: installedPath,
|
|
1277
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1278
|
+
env: {
|
|
1279
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
1280
|
+
},
|
|
893
1281
|
});
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
1282
|
+
}
|
|
1283
|
+
async runWithConcurrency(tasks, limit) {
|
|
1284
|
+
if (tasks.length === 0) {
|
|
1285
|
+
return [];
|
|
1286
|
+
}
|
|
1287
|
+
const results = new Array(tasks.length);
|
|
1288
|
+
let nextIndex = 0;
|
|
1289
|
+
const workerCount = Math.max(1, Math.min(limit, tasks.length));
|
|
1290
|
+
const worker = async () => {
|
|
1291
|
+
while (true) {
|
|
1292
|
+
const index = nextIndex;
|
|
1293
|
+
nextIndex += 1;
|
|
1294
|
+
if (index >= tasks.length) {
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
results[index] = await tasks[index]();
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
await Promise.all(Array.from({ length: workerCount }, () => worker()));
|
|
1301
|
+
return results;
|
|
898
1302
|
}
|
|
899
1303
|
/**
|
|
900
1304
|
* Get a unique identity for a package, ignoring version/ref.
|
|
@@ -948,25 +1352,51 @@ export class DefaultPackageManager {
|
|
|
948
1352
|
const version = match[2];
|
|
949
1353
|
return { name, version };
|
|
950
1354
|
}
|
|
1355
|
+
getNpmCommand() {
|
|
1356
|
+
const configuredCommand = this.settingsManager.getNpmCommand();
|
|
1357
|
+
if (!configuredCommand || configuredCommand.length === 0) {
|
|
1358
|
+
return { command: "npm", args: [] };
|
|
1359
|
+
}
|
|
1360
|
+
const [command, ...args] = configuredCommand;
|
|
1361
|
+
if (!command) {
|
|
1362
|
+
throw new Error("Invalid npmCommand: first array entry must be a non-empty command");
|
|
1363
|
+
}
|
|
1364
|
+
return { command, args };
|
|
1365
|
+
}
|
|
1366
|
+
async runNpmCommand(args, options) {
|
|
1367
|
+
const npmCommand = this.getNpmCommand();
|
|
1368
|
+
await this.runCommand(npmCommand.command, [...npmCommand.args, ...args], options);
|
|
1369
|
+
}
|
|
1370
|
+
getGitDependencyInstallArgs() {
|
|
1371
|
+
const configuredCommand = this.settingsManager.getNpmCommand();
|
|
1372
|
+
if (configuredCommand && configuredCommand.length > 0) {
|
|
1373
|
+
return ["install"];
|
|
1374
|
+
}
|
|
1375
|
+
return ["install", "--omit=dev"];
|
|
1376
|
+
}
|
|
1377
|
+
runNpmCommandSync(args) {
|
|
1378
|
+
const npmCommand = this.getNpmCommand();
|
|
1379
|
+
return this.runCommandSync(npmCommand.command, [...npmCommand.args, ...args]);
|
|
1380
|
+
}
|
|
951
1381
|
async installNpm(source, scope, temporary) {
|
|
952
1382
|
if (scope === "user" && !temporary) {
|
|
953
|
-
await this.
|
|
1383
|
+
await this.runNpmCommand(["install", "-g", source.spec]);
|
|
954
1384
|
return;
|
|
955
1385
|
}
|
|
956
1386
|
const installRoot = this.getNpmInstallRoot(scope, temporary);
|
|
957
1387
|
this.ensureNpmProject(installRoot);
|
|
958
|
-
await this.
|
|
1388
|
+
await this.runNpmCommand(["install", source.spec, "--prefix", installRoot]);
|
|
959
1389
|
}
|
|
960
1390
|
async uninstallNpm(source, scope) {
|
|
961
1391
|
if (scope === "user") {
|
|
962
|
-
await this.
|
|
1392
|
+
await this.runNpmCommand(["uninstall", "-g", source.name]);
|
|
963
1393
|
return;
|
|
964
1394
|
}
|
|
965
1395
|
const installRoot = this.getNpmInstallRoot(scope, false);
|
|
966
1396
|
if (!existsSync(installRoot)) {
|
|
967
1397
|
return;
|
|
968
1398
|
}
|
|
969
|
-
await this.
|
|
1399
|
+
await this.runNpmCommand(["uninstall", source.name, "--prefix", installRoot]);
|
|
970
1400
|
}
|
|
971
1401
|
async installGit(source, scope) {
|
|
972
1402
|
const targetDir = this.getGitInstallPath(source, scope);
|
|
@@ -984,7 +1414,7 @@ export class DefaultPackageManager {
|
|
|
984
1414
|
}
|
|
985
1415
|
const packageJsonPath = join(targetDir, "package.json");
|
|
986
1416
|
if (existsSync(packageJsonPath)) {
|
|
987
|
-
await this.
|
|
1417
|
+
await this.runNpmCommand(this.getGitDependencyInstallArgs(), { cwd: targetDir });
|
|
988
1418
|
}
|
|
989
1419
|
}
|
|
990
1420
|
async updateGit(source, scope) {
|
|
@@ -993,21 +1423,26 @@ export class DefaultPackageManager {
|
|
|
993
1423
|
await this.installGit(source, scope);
|
|
994
1424
|
return;
|
|
995
1425
|
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1426
|
+
const target = await this.getLocalGitUpdateTarget(targetDir);
|
|
1427
|
+
// Fetch only the ref we will reset to, avoiding unrelated branch/tag noise.
|
|
1428
|
+
await this.runCommand("git", target.fetchArgs, { cwd: targetDir });
|
|
1429
|
+
const localHead = await this.runCommandCapture("git", ["rev-parse", "HEAD"], {
|
|
1430
|
+
cwd: targetDir,
|
|
1431
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1432
|
+
});
|
|
1433
|
+
const refreshedTargetHead = await this.runCommandCapture("git", ["rev-parse", target.ref], {
|
|
1434
|
+
cwd: targetDir,
|
|
1435
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1436
|
+
});
|
|
1437
|
+
if (localHead.trim() === refreshedTargetHead.trim()) {
|
|
1438
|
+
return;
|
|
1005
1439
|
}
|
|
1440
|
+
await this.runCommand("git", ["reset", "--hard", target.ref], { cwd: targetDir });
|
|
1006
1441
|
// Clean untracked files (extensions should be pristine)
|
|
1007
1442
|
await this.runCommand("git", ["clean", "-fdx"], { cwd: targetDir });
|
|
1008
1443
|
const packageJsonPath = join(targetDir, "package.json");
|
|
1009
1444
|
if (existsSync(packageJsonPath)) {
|
|
1010
|
-
await this.
|
|
1445
|
+
await this.runNpmCommand(this.getGitDependencyInstallArgs(), { cwd: targetDir });
|
|
1011
1446
|
}
|
|
1012
1447
|
}
|
|
1013
1448
|
async refreshTemporaryGitSource(source, sourceStr) {
|
|
@@ -1083,11 +1518,20 @@ export class DefaultPackageManager {
|
|
|
1083
1518
|
return join(this.getGlobalNpmRoot(), "..");
|
|
1084
1519
|
}
|
|
1085
1520
|
getGlobalNpmRoot() {
|
|
1086
|
-
|
|
1521
|
+
const npmCommand = this.getNpmCommand();
|
|
1522
|
+
const commandKey = [npmCommand.command, ...npmCommand.args].join("\0");
|
|
1523
|
+
if (this.globalNpmRoot && this.globalNpmRootCommandKey === commandKey) {
|
|
1087
1524
|
return this.globalNpmRoot;
|
|
1088
1525
|
}
|
|
1089
|
-
const
|
|
1090
|
-
|
|
1526
|
+
const isBunPackageManager = npmCommand.command === "bun";
|
|
1527
|
+
if (isBunPackageManager) {
|
|
1528
|
+
const binDir = this.runNpmCommandSync(["pm", "bin", "-g"]).trim();
|
|
1529
|
+
this.globalNpmRoot = join(dirname(binDir), "install", "global", "node_modules");
|
|
1530
|
+
}
|
|
1531
|
+
else {
|
|
1532
|
+
this.globalNpmRoot = this.runNpmCommandSync(["root", "-g"]).trim();
|
|
1533
|
+
}
|
|
1534
|
+
this.globalNpmRootCommandKey = commandKey;
|
|
1091
1535
|
return this.globalNpmRoot;
|
|
1092
1536
|
}
|
|
1093
1537
|
getNpmInstallPath(source, scope) {
|
|
@@ -1136,21 +1580,21 @@ export class DefaultPackageManager {
|
|
|
1136
1580
|
resolvePath(input) {
|
|
1137
1581
|
const trimmed = input.trim();
|
|
1138
1582
|
if (trimmed === "~")
|
|
1139
|
-
return
|
|
1583
|
+
return getHomeDir();
|
|
1140
1584
|
if (trimmed.startsWith("~/"))
|
|
1141
|
-
return join(
|
|
1585
|
+
return join(getHomeDir(), trimmed.slice(2));
|
|
1142
1586
|
if (trimmed.startsWith("~"))
|
|
1143
|
-
return join(
|
|
1587
|
+
return join(getHomeDir(), trimmed.slice(1));
|
|
1144
1588
|
return resolve(this.cwd, trimmed);
|
|
1145
1589
|
}
|
|
1146
1590
|
resolvePathFromBase(input, baseDir) {
|
|
1147
1591
|
const trimmed = input.trim();
|
|
1148
1592
|
if (trimmed === "~")
|
|
1149
|
-
return
|
|
1593
|
+
return getHomeDir();
|
|
1150
1594
|
if (trimmed.startsWith("~/"))
|
|
1151
|
-
return join(
|
|
1595
|
+
return join(getHomeDir(), trimmed.slice(2));
|
|
1152
1596
|
if (trimmed.startsWith("~"))
|
|
1153
|
-
return join(
|
|
1597
|
+
return join(getHomeDir(), trimmed.slice(1));
|
|
1154
1598
|
return resolve(baseDir, trimmed);
|
|
1155
1599
|
}
|
|
1156
1600
|
collectPackageResources(packageRoot, accumulator, filter, metadata) {
|
|
@@ -1231,7 +1675,7 @@ export class DefaultPackageManager {
|
|
|
1231
1675
|
const entries = manifest?.[resourceType];
|
|
1232
1676
|
if (entries && entries.length > 0) {
|
|
1233
1677
|
const allFiles = this.collectFilesFromManifestEntries(entries, packageRoot, resourceType);
|
|
1234
|
-
const manifestPatterns = entries.filter(
|
|
1678
|
+
const manifestPatterns = entries.filter(isOverridePattern);
|
|
1235
1679
|
const enabledByManifest = manifestPatterns.length > 0 ? applyPatterns(allFiles, manifestPatterns, packageRoot) : new Set(allFiles);
|
|
1236
1680
|
return { allFiles: Array.from(enabledByManifest), enabledByManifest };
|
|
1237
1681
|
}
|
|
@@ -1260,7 +1704,7 @@ export class DefaultPackageManager {
|
|
|
1260
1704
|
if (!entries)
|
|
1261
1705
|
return;
|
|
1262
1706
|
const allFiles = this.collectFilesFromManifestEntries(entries, root, resourceType);
|
|
1263
|
-
const patterns = entries.filter(
|
|
1707
|
+
const patterns = entries.filter(isOverridePattern);
|
|
1264
1708
|
const enabledPaths = applyPatterns(allFiles, patterns, root);
|
|
1265
1709
|
for (const f of allFiles) {
|
|
1266
1710
|
if (enabledPaths.has(f)) {
|
|
@@ -1269,8 +1713,18 @@ export class DefaultPackageManager {
|
|
|
1269
1713
|
}
|
|
1270
1714
|
}
|
|
1271
1715
|
collectFilesFromManifestEntries(entries, root, resourceType) {
|
|
1272
|
-
const
|
|
1273
|
-
const resolved =
|
|
1716
|
+
const sourceEntries = entries.filter((entry) => !isOverridePattern(entry));
|
|
1717
|
+
const resolved = sourceEntries.flatMap((entry) => {
|
|
1718
|
+
if (!hasGlobPattern(entry)) {
|
|
1719
|
+
return [resolve(root, entry)];
|
|
1720
|
+
}
|
|
1721
|
+
return globSync(entry, {
|
|
1722
|
+
cwd: root,
|
|
1723
|
+
absolute: true,
|
|
1724
|
+
dot: false,
|
|
1725
|
+
nodir: false,
|
|
1726
|
+
}).map((match) => resolve(match));
|
|
1727
|
+
});
|
|
1274
1728
|
return this.collectFilesFromPaths(resolved, resourceType);
|
|
1275
1729
|
}
|
|
1276
1730
|
resolveLocalEntries(entries, resourceType, target, metadata, baseDir) {
|
|
@@ -1324,8 +1778,8 @@ export class DefaultPackageManager {
|
|
|
1324
1778
|
prompts: join(projectBaseDir, "prompts"),
|
|
1325
1779
|
themes: join(projectBaseDir, "themes"),
|
|
1326
1780
|
};
|
|
1327
|
-
const userAgentsSkillsDir = join(
|
|
1328
|
-
const projectAgentsSkillDirs = collectAncestorAgentsSkillDirs(this.cwd);
|
|
1781
|
+
const userAgentsSkillsDir = join(getHomeDir(), ".agents", "skills");
|
|
1782
|
+
const projectAgentsSkillDirs = collectAncestorAgentsSkillDirs(this.cwd).filter((dir) => resolve(dir) !== resolve(userAgentsSkillsDir));
|
|
1329
1783
|
const addResources = (resourceType, paths, metadata, overrides, baseDir) => {
|
|
1330
1784
|
const target = this.getTargetMap(accumulator, resourceType);
|
|
1331
1785
|
for (const path of paths) {
|
|
@@ -1333,15 +1787,32 @@ export class DefaultPackageManager {
|
|
|
1333
1787
|
this.addResource(target, path, metadata, enabled);
|
|
1334
1788
|
}
|
|
1335
1789
|
};
|
|
1790
|
+
// Project extensions from .pi/
|
|
1336
1791
|
addResources("extensions", collectAutoExtensionEntries(projectDirs.extensions), projectMetadata, projectOverrides.extensions, projectBaseDir);
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1792
|
+
// Project skills from .pi/
|
|
1793
|
+
addResources("skills", collectAutoSkillEntries(projectDirs.skills, "pi"), projectMetadata, projectOverrides.skills, projectBaseDir);
|
|
1794
|
+
// Project skills from .agents/ (each with its own baseDir)
|
|
1795
|
+
for (const agentsSkillsDir of projectAgentsSkillDirs) {
|
|
1796
|
+
const agentsBaseDir = dirname(agentsSkillsDir); // the .agents directory
|
|
1797
|
+
const agentsMetadata = {
|
|
1798
|
+
...projectMetadata,
|
|
1799
|
+
baseDir: agentsBaseDir,
|
|
1800
|
+
};
|
|
1801
|
+
addResources("skills", collectAutoSkillEntries(agentsSkillsDir, "agents"), agentsMetadata, projectOverrides.skills, agentsBaseDir);
|
|
1802
|
+
}
|
|
1341
1803
|
addResources("prompts", collectAutoPromptEntries(projectDirs.prompts), projectMetadata, projectOverrides.prompts, projectBaseDir);
|
|
1342
1804
|
addResources("themes", collectAutoThemeEntries(projectDirs.themes), projectMetadata, projectOverrides.themes, projectBaseDir);
|
|
1805
|
+
// User extensions from ~/.pi/agent/
|
|
1343
1806
|
addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
|
|
1344
|
-
|
|
1807
|
+
// User skills from ~/.pi/agent/
|
|
1808
|
+
addResources("skills", collectAutoSkillEntries(userDirs.skills, "pi"), userMetadata, userOverrides.skills, globalBaseDir);
|
|
1809
|
+
// User skills from ~/.agents/ (with its own baseDir)
|
|
1810
|
+
const userAgentsBaseDir = dirname(userAgentsSkillsDir);
|
|
1811
|
+
const userAgentsMetadata = {
|
|
1812
|
+
...userMetadata,
|
|
1813
|
+
baseDir: userAgentsBaseDir,
|
|
1814
|
+
};
|
|
1815
|
+
addResources("skills", collectAutoSkillEntries(userAgentsSkillsDir, "agents"), userAgentsMetadata, userOverrides.skills, userAgentsBaseDir);
|
|
1345
1816
|
addResources("prompts", collectAutoPromptEntries(userDirs.prompts), userMetadata, userOverrides.prompts, globalBaseDir);
|
|
1346
1817
|
addResources("themes", collectAutoThemeEntries(userDirs.themes), userMetadata, userOverrides.themes, globalBaseDir);
|
|
1347
1818
|
}
|
|
@@ -1395,27 +1866,88 @@ export class DefaultPackageManager {
|
|
|
1395
1866
|
};
|
|
1396
1867
|
}
|
|
1397
1868
|
toResolvedPaths(accumulator) {
|
|
1398
|
-
const
|
|
1399
|
-
|
|
1869
|
+
const mapToResolved = (entries) => {
|
|
1870
|
+
const resolved = Array.from(entries.entries()).map(([path, { metadata, enabled }]) => ({
|
|
1400
1871
|
path,
|
|
1401
1872
|
enabled,
|
|
1402
1873
|
metadata,
|
|
1403
1874
|
}));
|
|
1875
|
+
resolved.sort((a, b) => resourcePrecedenceRank(a.metadata) - resourcePrecedenceRank(b.metadata));
|
|
1876
|
+
const seen = new Set();
|
|
1877
|
+
return resolved.filter((entry) => {
|
|
1878
|
+
const canonicalPath = canonicalizePath(entry.path);
|
|
1879
|
+
if (seen.has(canonicalPath))
|
|
1880
|
+
return false;
|
|
1881
|
+
seen.add(canonicalPath);
|
|
1882
|
+
return true;
|
|
1883
|
+
});
|
|
1404
1884
|
};
|
|
1405
1885
|
return {
|
|
1406
|
-
extensions:
|
|
1407
|
-
skills:
|
|
1408
|
-
prompts:
|
|
1409
|
-
themes:
|
|
1886
|
+
extensions: mapToResolved(accumulator.extensions),
|
|
1887
|
+
skills: mapToResolved(accumulator.skills),
|
|
1888
|
+
prompts: mapToResolved(accumulator.prompts),
|
|
1889
|
+
themes: mapToResolved(accumulator.themes),
|
|
1410
1890
|
};
|
|
1411
1891
|
}
|
|
1412
|
-
|
|
1892
|
+
spawnCommand(command, args, options) {
|
|
1893
|
+
return spawn(command, args, {
|
|
1894
|
+
cwd: options?.cwd,
|
|
1895
|
+
stdio: isStdoutTakenOver() ? ["ignore", 2, 2] : "inherit",
|
|
1896
|
+
shell: shouldUseWindowsShell(command),
|
|
1897
|
+
env: getEnv(),
|
|
1898
|
+
});
|
|
1899
|
+
}
|
|
1900
|
+
spawnCaptureCommand(command, args, options) {
|
|
1901
|
+
const baseEnv = getEnv();
|
|
1902
|
+
return spawn(command, args, {
|
|
1903
|
+
cwd: options?.cwd,
|
|
1904
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1905
|
+
shell: shouldUseWindowsShell(command),
|
|
1906
|
+
env: options?.env ? { ...baseEnv, ...options.env } : baseEnv,
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
runCommandCapture(command, args, options) {
|
|
1413
1910
|
return new Promise((resolvePromise, reject) => {
|
|
1414
|
-
const child =
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1911
|
+
const child = this.spawnCaptureCommand(command, args, options);
|
|
1912
|
+
let stdout = "";
|
|
1913
|
+
let stderr = "";
|
|
1914
|
+
let timedOut = false;
|
|
1915
|
+
const timeout = typeof options?.timeoutMs === "number"
|
|
1916
|
+
? setTimeout(() => {
|
|
1917
|
+
timedOut = true;
|
|
1918
|
+
child.kill();
|
|
1919
|
+
}, options.timeoutMs)
|
|
1920
|
+
: undefined;
|
|
1921
|
+
child.stdout?.on("data", (data) => {
|
|
1922
|
+
stdout += data.toString();
|
|
1923
|
+
});
|
|
1924
|
+
child.stderr?.on("data", (data) => {
|
|
1925
|
+
stderr += data.toString();
|
|
1418
1926
|
});
|
|
1927
|
+
child.once("error", (error) => {
|
|
1928
|
+
if (timeout)
|
|
1929
|
+
clearTimeout(timeout);
|
|
1930
|
+
reject(error);
|
|
1931
|
+
});
|
|
1932
|
+
child.once("close", (code, signal) => {
|
|
1933
|
+
if (timeout)
|
|
1934
|
+
clearTimeout(timeout);
|
|
1935
|
+
if (timedOut) {
|
|
1936
|
+
reject(new Error(`${command} ${args.join(" ")} timed out after ${options?.timeoutMs}ms`));
|
|
1937
|
+
return;
|
|
1938
|
+
}
|
|
1939
|
+
if (code === 0) {
|
|
1940
|
+
resolvePromise(stdout.trim());
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1943
|
+
const exitStatus = code === null ? `signal ${signal ?? "unknown"}` : `code ${code}`;
|
|
1944
|
+
reject(new Error(`${command} ${args.join(" ")} failed with ${exitStatus}: ${stderr || stdout}`));
|
|
1945
|
+
});
|
|
1946
|
+
});
|
|
1947
|
+
}
|
|
1948
|
+
runCommand(command, args, options) {
|
|
1949
|
+
return new Promise((resolvePromise, reject) => {
|
|
1950
|
+
const child = this.spawnCommand(command, args, options);
|
|
1419
1951
|
child.on("error", reject);
|
|
1420
1952
|
child.on("exit", (code) => {
|
|
1421
1953
|
if (code === 0) {
|
|
@@ -1431,10 +1963,11 @@ export class DefaultPackageManager {
|
|
|
1431
1963
|
const result = spawnSync(command, args, {
|
|
1432
1964
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1433
1965
|
encoding: "utf-8",
|
|
1434
|
-
shell:
|
|
1966
|
+
shell: shouldUseWindowsShell(command),
|
|
1967
|
+
env: getEnv(),
|
|
1435
1968
|
});
|
|
1436
|
-
if (result.status !== 0) {
|
|
1437
|
-
throw new Error(`Failed to run ${command} ${args.join(" ")}: ${result.stderr || result.stdout}`);
|
|
1969
|
+
if (result.error || result.status !== 0) {
|
|
1970
|
+
throw new Error(`Failed to run ${command} ${args.join(" ")}: ${result.error?.message || result.stderr || result.stdout}`);
|
|
1438
1971
|
}
|
|
1439
1972
|
return (result.stdout || result.stderr || "").trim();
|
|
1440
1973
|
}
|