indusagi-coding-agent 0.1.38 → 0.1.40
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 +22 -7
- package/{LICENSE.md → LICENSE} +0 -1
- package/README.md +2 -4
- package/dist/cli/args.d.ts +6 -128
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +277 -472
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts +9 -62
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +31 -146
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/file-processor.d.ts +1 -69
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +36 -267
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/list-models.d.ts +0 -60
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +53 -246
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/session-picker.d.ts +1 -72
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js +57 -231
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.js +25 -31
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +0 -42
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +62 -97
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +26 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +78 -66
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +4 -95
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +233 -288
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts +0 -323
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +126 -359
- 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.js +16 -16
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +3 -3
- package/dist/core/compaction/compaction.js +40 -40
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts +32 -4
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +30 -4
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +1 -19
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +92 -113
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/discover-packages.d.ts +0 -4
- package/dist/core/discover-packages.d.ts.map +1 -1
- package/dist/core/discover-packages.js +41 -44
- package/dist/core/discover-packages.js.map +1 -1
- package/dist/core/event-bus.d.ts +1 -147
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +17 -106
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts +0 -16
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +18 -27
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.ts +262 -0
- package/dist/core/export-html/index.ts +433 -0
- package/dist/core/export-html/template.html +48 -26
- package/dist/core/export-html/tool-renderer.d.ts +0 -21
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +35 -51
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/export-html/tool-renderer.ts +80 -0
- package/dist/core/export-html/vendor/highlight.min.js +401 -370
- package/dist/core/export-html/vendor/marked.min.js +71 -3
- package/dist/core/extensions/index.d.ts +7 -4
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +17 -3
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +0 -6
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +60 -56
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +48 -80
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +50 -23
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/footer-data-provider.d.ts +2 -15
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +21 -33
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/hooks/loader.js +2 -2
- package/dist/core/hooks/loader.js.map +1 -1
- package/dist/core/index.d.ts +29 -10
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +29 -10
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +2 -179
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +64 -238
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-registry.d.ts +26 -181
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +228 -407
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +0 -139
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +34 -215
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts +25 -57
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +326 -964
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +2 -34
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +122 -170
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/resource-loader.d.ts +19 -12
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +353 -467
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -61
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +184 -252
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +447 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +1176 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +9 -12
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +170 -398
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +2 -27
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +149 -212
- package/dist/core/skills.js.map +1 -1
- package/dist/core/subagents.d.ts +2 -2
- package/dist/core/subagents.d.ts.map +1 -1
- package/dist/core/subagents.js +21 -14
- package/dist/core/subagents.js.map +1 -1
- package/dist/core/system-prompt.d.ts +0 -11
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +168 -139
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/timings.d.ts +1 -4
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +34 -18
- package/dist/core/timings.js.map +1 -1
- package/dist/core/todo-store.d.ts +20 -0
- package/dist/core/todo-store.d.ts.map +1 -0
- package/dist/core/todo-store.js +60 -0
- package/dist/core/todo-store.js.map +1 -0
- package/dist/core/tools/bash.d.ts +2 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +2 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/bg-process.d.ts +1 -6
- package/dist/core/tools/bg-process.d.ts.map +1 -1
- package/dist/core/tools/bg-process.js +4 -18
- package/dist/core/tools/bg-process.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +9 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +2 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +2 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +2 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/find.d.ts +2 -0
- package/dist/core/tools/find.d.ts.map +1 -0
- package/dist/core/tools/find.js +2 -0
- package/dist/core/tools/find.js.map +1 -0
- package/dist/core/tools/grep.d.ts +2 -0
- package/dist/core/tools/grep.d.ts.map +1 -0
- package/dist/core/tools/grep.js +2 -0
- package/dist/core/tools/grep.js.map +1 -0
- package/dist/core/tools/index.d.ts +8 -2
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/ls.d.ts +2 -0
- package/dist/core/tools/ls.d.ts.map +1 -0
- package/dist/core/tools/ls.js +2 -0
- package/dist/core/tools/ls.js.map +1 -0
- package/dist/core/tools/memory.d.ts +50 -1
- package/dist/core/tools/memory.d.ts.map +1 -1
- package/dist/core/tools/memory.js +11 -7
- package/dist/core/tools/memory.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +2 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -0
- package/dist/core/tools/path-utils.js +2 -0
- package/dist/core/tools/path-utils.js.map +1 -0
- package/dist/core/tools/read.d.ts +2 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +2 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/registry.d.ts +0 -15
- package/dist/core/tools/registry.d.ts.map +1 -1
- package/dist/core/tools/registry.js +13 -37
- package/dist/core/tools/registry.js.map +1 -1
- package/dist/core/tools/task.d.ts +17 -23
- package/dist/core/tools/task.d.ts.map +1 -1
- package/dist/core/tools/task.js +43 -82
- package/dist/core/tools/task.js.map +1 -1
- package/dist/core/tools/todo.d.ts +17 -20
- package/dist/core/tools/todo.d.ts.map +1 -1
- package/dist/core/tools/todo.js +79 -58
- package/dist/core/tools/todo.js.map +1 -1
- package/dist/core/tools/truncate.d.ts +2 -0
- package/dist/core/tools/truncate.d.ts.map +1 -0
- package/dist/core/tools/truncate.js +2 -0
- package/dist/core/tools/truncate.js.map +1 -0
- package/dist/core/tools/webfetch.d.ts +2 -0
- package/dist/core/tools/webfetch.d.ts.map +1 -0
- package/dist/core/tools/webfetch.js +2 -0
- package/dist/core/tools/webfetch.js.map +1 -0
- package/dist/core/tools/websearch.d.ts +2 -0
- package/dist/core/tools/websearch.d.ts.map +1 -0
- package/dist/core/tools/websearch.js +2 -0
- package/dist/core/tools/websearch.js.map +1 -0
- package/dist/core/tools/write.d.ts +2 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +2 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/index.d.ts +35 -29
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -41
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +237 -225
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +0 -25
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +129 -180
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts +13 -6
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +11 -5
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts +8 -23
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +217 -266
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +2 -168
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +61 -216
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +6 -313
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +86 -403
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -3
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +59 -29
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +3 -3
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +30 -17
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +3 -3
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +35 -18
- 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 +60 -68
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +2 -6
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +32 -18
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -5
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +45 -37
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +5 -6
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +43 -53
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts +0 -3
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js +101 -108
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts +7 -2
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +24 -4
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +5 -9
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +43 -46
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +4 -9
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +45 -28
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +7 -12
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +54 -32
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +2 -11
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +135 -183
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +79 -30
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +73 -31
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +0 -18
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +24 -31
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +11 -24
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +89 -86
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +15 -19
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +104 -157
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +5 -5
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +12 -22
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +111 -132
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +3 -3
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +92 -103
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +28 -39
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +111 -203
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +17 -19
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +3 -3
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +29 -19
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts +2 -2
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +20 -25
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +19 -20
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +12 -10
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +14 -8
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +53 -60
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts +3 -9
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +57 -68
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts +0 -12
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js +14 -22
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +6 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +118 -113
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +189 -39
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- 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 +88 -59
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +24 -46
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +75 -409
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +21 -360
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/observability/core/config.d.ts +28 -0
- package/dist/observability/core/config.d.ts.map +1 -0
- package/dist/observability/core/config.js +150 -0
- package/dist/observability/core/config.js.map +1 -0
- package/dist/observability/core/event-bus.d.ts +15 -0
- package/dist/observability/core/event-bus.d.ts.map +1 -0
- package/dist/observability/core/event-bus.js +37 -0
- package/dist/observability/core/event-bus.js.map +1 -0
- package/dist/observability/core/index.d.ts +12 -0
- package/dist/observability/core/index.d.ts.map +1 -0
- package/dist/observability/core/index.js +14 -0
- package/dist/observability/core/index.js.map +1 -0
- package/dist/observability/core/observability.d.ts +63 -0
- package/dist/observability/core/observability.d.ts.map +1 -0
- package/dist/observability/core/observability.js +127 -0
- package/dist/observability/core/observability.js.map +1 -0
- package/dist/observability/core/span.d.ts +37 -0
- package/dist/observability/core/span.d.ts.map +1 -0
- package/dist/observability/core/span.js +90 -0
- package/dist/observability/core/span.js.map +1 -0
- package/dist/observability/core/tracer.d.ts +22 -0
- package/dist/observability/core/tracer.d.ts.map +1 -0
- package/dist/observability/core/tracer.js +79 -0
- package/dist/observability/core/tracer.js.map +1 -0
- package/dist/observability/core/types.d.ts +155 -0
- package/dist/observability/core/types.d.ts.map +1 -0
- package/dist/observability/core/types.js +38 -0
- package/dist/observability/core/types.js.map +1 -0
- package/dist/observability/exporters/base-exporter.d.ts +16 -0
- package/dist/observability/exporters/base-exporter.d.ts.map +1 -0
- package/dist/observability/exporters/base-exporter.js +26 -0
- package/dist/observability/exporters/base-exporter.js.map +1 -0
- package/dist/observability/exporters/console-exporter.d.ts +22 -0
- package/dist/observability/exporters/console-exporter.d.ts.map +1 -0
- package/dist/observability/exporters/console-exporter.js +80 -0
- package/dist/observability/exporters/console-exporter.js.map +1 -0
- package/dist/observability/exporters/file-exporter.d.ts +31 -0
- package/dist/observability/exporters/file-exporter.d.ts.map +1 -0
- package/dist/observability/exporters/file-exporter.js +120 -0
- package/dist/observability/exporters/file-exporter.js.map +1 -0
- package/dist/observability/exporters/index.d.ts +12 -0
- package/dist/observability/exporters/index.d.ts.map +1 -0
- package/dist/observability/exporters/index.js +11 -0
- package/dist/observability/exporters/index.js.map +1 -0
- package/dist/observability/exporters/langfuse-exporter.d.ts +27 -0
- package/dist/observability/exporters/langfuse-exporter.d.ts.map +1 -0
- package/dist/observability/exporters/langfuse-exporter.js +146 -0
- package/dist/observability/exporters/langfuse-exporter.js.map +1 -0
- package/dist/observability/exporters/sentry-exporter.d.ts +22 -0
- package/dist/observability/exporters/sentry-exporter.d.ts.map +1 -0
- package/dist/observability/exporters/sentry-exporter.js +121 -0
- package/dist/observability/exporters/sentry-exporter.js.map +1 -0
- package/dist/observability/index.d.ts +3 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +3 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/utils/changelog.d.ts +1 -2
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +53 -61
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +77 -83
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +62 -49
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/image-convert.d.ts +6 -6
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js +29 -23
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize.d.ts +0 -17
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +100 -138
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/mime.d.ts +1 -0
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js +35 -15
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/photon.d.ts +4 -15
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js +71 -60
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/shell.d.ts +4 -21
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +101 -124
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js +32 -8
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +4 -2
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +96 -122
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/PI_MONO_MIT_REMOVAL_GUIDE.md +2132 -0
- package/docs/SAME_TO_SAME_PARITY_REPORT.md +312 -0
- package/examples/README.md +12 -0
- package/package.json +62 -88
- package/dist/modes/interactive/theme/dark.json +0 -85
- package/dist/modes/interactive/theme/light.json +0 -84
- package/dist/modes/interactive/theme/theme-schema.json +0 -335
- package/docs/FEATURES.md +0 -306
- package/docs/MCP.md +0 -341
- package/docs/MEMORY.md +0 -443
- package/examples/mcp-servers.example.json +0 -50
|
@@ -1,253 +1,50 @@
|
|
|
1
1
|
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
|
-
import {
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
5
|
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
6
6
|
import { minimatch } from "minimatch";
|
|
7
7
|
import { CONFIG_DIR_NAME } from "../config.js";
|
|
8
|
-
import { looksLikeGitUrl } from "../utils/git.js";
|
|
9
8
|
const RESOURCE_TYPES = ["extensions", "hooks", "skills", "prompts", "themes"];
|
|
10
9
|
const FILE_PATTERNS = {
|
|
11
|
-
extensions: /\.(ts|js)$/,
|
|
12
|
-
hooks: /\.(ts|js)$/,
|
|
10
|
+
extensions: /\.(ts|js|mjs|cjs)$/,
|
|
11
|
+
hooks: /\.(ts|js|mjs|cjs)$/,
|
|
13
12
|
skills: /\.md$/,
|
|
14
13
|
prompts: /\.md$/,
|
|
15
14
|
themes: /\.json$/,
|
|
16
15
|
};
|
|
17
|
-
function
|
|
18
|
-
|
|
16
|
+
function looksLikeGitUrl(source) {
|
|
17
|
+
const normalized = source.replace(/^https?:\/\//, "");
|
|
18
|
+
return ["github.com", "gitlab.com", "bitbucket.org", "codeberg.org"].some((host) => normalized.startsWith(`${host}/`));
|
|
19
19
|
}
|
|
20
|
-
function
|
|
21
|
-
const plain = [];
|
|
22
|
-
const patterns = [];
|
|
23
|
-
for (const entry of entries) {
|
|
24
|
-
if (isPattern(entry)) {
|
|
25
|
-
patterns.push(entry);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
plain.push(entry);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return { plain, patterns };
|
|
32
|
-
}
|
|
33
|
-
function collectFiles(dir, filePattern, skipNodeModules = true) {
|
|
34
|
-
const files = [];
|
|
35
|
-
if (!existsSync(dir))
|
|
36
|
-
return files;
|
|
20
|
+
function readManifest(packageJsonPath) {
|
|
37
21
|
try {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
if (entry.name.startsWith("."))
|
|
41
|
-
continue;
|
|
42
|
-
if (skipNodeModules && entry.name === "node_modules")
|
|
43
|
-
continue;
|
|
44
|
-
const fullPath = join(dir, entry.name);
|
|
45
|
-
let isDir = entry.isDirectory();
|
|
46
|
-
let isFile = entry.isFile();
|
|
47
|
-
if (entry.isSymbolicLink()) {
|
|
48
|
-
try {
|
|
49
|
-
const stats = statSync(fullPath);
|
|
50
|
-
isDir = stats.isDirectory();
|
|
51
|
-
isFile = stats.isFile();
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (isDir) {
|
|
58
|
-
files.push(...collectFiles(fullPath, filePattern, skipNodeModules));
|
|
59
|
-
}
|
|
60
|
-
else if (isFile && filePattern.test(entry.name)) {
|
|
61
|
-
files.push(fullPath);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
22
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
23
|
+
return parsed.indusagi ?? null;
|
|
64
24
|
}
|
|
65
25
|
catch {
|
|
66
|
-
|
|
26
|
+
return null;
|
|
67
27
|
}
|
|
68
|
-
return files;
|
|
69
28
|
}
|
|
70
|
-
function
|
|
71
|
-
const entries = [];
|
|
72
|
-
if (!existsSync(dir))
|
|
73
|
-
return entries;
|
|
29
|
+
function safeReaddir(dir) {
|
|
74
30
|
try {
|
|
75
|
-
|
|
76
|
-
for (const entry of dirEntries) {
|
|
77
|
-
if (entry.name.startsWith("."))
|
|
78
|
-
continue;
|
|
79
|
-
if (entry.name === "node_modules")
|
|
80
|
-
continue;
|
|
81
|
-
const fullPath = join(dir, entry.name);
|
|
82
|
-
let isDir = entry.isDirectory();
|
|
83
|
-
let isFile = entry.isFile();
|
|
84
|
-
if (entry.isSymbolicLink()) {
|
|
85
|
-
try {
|
|
86
|
-
const stats = statSync(fullPath);
|
|
87
|
-
isDir = stats.isDirectory();
|
|
88
|
-
isFile = stats.isFile();
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (isDir) {
|
|
95
|
-
entries.push(...collectSkillEntries(fullPath, false));
|
|
96
|
-
}
|
|
97
|
-
else if (isFile) {
|
|
98
|
-
const isRootMd = includeRootFiles && entry.name.endsWith(".md");
|
|
99
|
-
const isSkillMd = !includeRootFiles && entry.name === "SKILL.md";
|
|
100
|
-
if (isRootMd || isSkillMd) {
|
|
101
|
-
entries.push(fullPath);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
31
|
+
return readdirSync(dir);
|
|
105
32
|
}
|
|
106
33
|
catch {
|
|
107
|
-
|
|
34
|
+
return [];
|
|
108
35
|
}
|
|
109
|
-
return entries;
|
|
110
|
-
}
|
|
111
|
-
function collectAutoSkillEntries(dir, includeRootFiles = true) {
|
|
112
|
-
return collectSkillEntries(dir, includeRootFiles);
|
|
113
36
|
}
|
|
114
|
-
function
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return entries;
|
|
118
|
-
try {
|
|
119
|
-
const dirEntries = readdirSync(dir, { withFileTypes: true });
|
|
120
|
-
for (const entry of dirEntries) {
|
|
121
|
-
if (entry.name.startsWith("."))
|
|
122
|
-
continue;
|
|
123
|
-
if (entry.name === "node_modules")
|
|
124
|
-
continue;
|
|
125
|
-
const fullPath = join(dir, entry.name);
|
|
126
|
-
let isFile = entry.isFile();
|
|
127
|
-
if (entry.isSymbolicLink()) {
|
|
128
|
-
try {
|
|
129
|
-
isFile = statSync(fullPath).isFile();
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (isFile && entry.name.endsWith(".md")) {
|
|
136
|
-
entries.push(fullPath);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
37
|
+
function collectFiles(dir, filePattern) {
|
|
38
|
+
if (!existsSync(dir)) {
|
|
39
|
+
return [];
|
|
139
40
|
}
|
|
140
|
-
|
|
141
|
-
// Ignore errors
|
|
142
|
-
}
|
|
143
|
-
return entries;
|
|
144
|
-
}
|
|
145
|
-
function collectAutoThemeEntries(dir) {
|
|
146
|
-
const entries = [];
|
|
147
|
-
if (!existsSync(dir))
|
|
148
|
-
return entries;
|
|
41
|
+
const results = [];
|
|
149
42
|
try {
|
|
150
|
-
const
|
|
151
|
-
for (const entry of
|
|
152
|
-
if (entry.name.startsWith("."))
|
|
153
|
-
continue;
|
|
154
|
-
if (entry.name === "node_modules")
|
|
43
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
155
46
|
continue;
|
|
156
|
-
const fullPath = join(dir, entry.name);
|
|
157
|
-
let isFile = entry.isFile();
|
|
158
|
-
if (entry.isSymbolicLink()) {
|
|
159
|
-
try {
|
|
160
|
-
isFile = statSync(fullPath).isFile();
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (isFile && entry.name.endsWith(".json")) {
|
|
167
|
-
entries.push(fullPath);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
// Ignore errors
|
|
173
|
-
}
|
|
174
|
-
return entries;
|
|
175
|
-
}
|
|
176
|
-
function readIndusagiManifestFile(packageJsonPath) {
|
|
177
|
-
try {
|
|
178
|
-
const content = readFileSync(packageJsonPath, "utf-8");
|
|
179
|
-
const pkg = JSON.parse(content);
|
|
180
|
-
return pkg.indusagi ?? null;
|
|
181
|
-
}
|
|
182
|
-
catch {
|
|
183
|
-
return null;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function resolveExtensionEntries(dir) {
|
|
187
|
-
const packageJsonPath = join(dir, "package.json");
|
|
188
|
-
if (existsSync(packageJsonPath)) {
|
|
189
|
-
const manifest = readIndusagiManifestFile(packageJsonPath);
|
|
190
|
-
if (manifest?.extensions?.length) {
|
|
191
|
-
const entries = [];
|
|
192
|
-
for (const extPath of manifest.extensions) {
|
|
193
|
-
const resolvedExtPath = resolve(dir, extPath);
|
|
194
|
-
if (existsSync(resolvedExtPath)) {
|
|
195
|
-
entries.push(resolvedExtPath);
|
|
196
|
-
}
|
|
197
47
|
}
|
|
198
|
-
if (entries.length > 0) {
|
|
199
|
-
return entries;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const indexTs = join(dir, "index.ts");
|
|
204
|
-
const indexJs = join(dir, "index.js");
|
|
205
|
-
if (existsSync(indexTs)) {
|
|
206
|
-
return [indexTs];
|
|
207
|
-
}
|
|
208
|
-
if (existsSync(indexJs)) {
|
|
209
|
-
return [indexJs];
|
|
210
|
-
}
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
function resolveHookEntries(dir) {
|
|
214
|
-
const packageJsonPath = join(dir, "package.json");
|
|
215
|
-
if (existsSync(packageJsonPath)) {
|
|
216
|
-
const manifest = readIndusagiManifestFile(packageJsonPath);
|
|
217
|
-
if (manifest?.hooks?.length) {
|
|
218
|
-
const entries = [];
|
|
219
|
-
for (const hookPath of manifest.hooks) {
|
|
220
|
-
const resolvedHookPath = resolve(dir, hookPath);
|
|
221
|
-
if (existsSync(resolvedHookPath)) {
|
|
222
|
-
entries.push(resolvedHookPath);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
if (entries.length > 0) {
|
|
226
|
-
return entries;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
const indexTs = join(dir, "index.ts");
|
|
231
|
-
const indexJs = join(dir, "index.js");
|
|
232
|
-
if (existsSync(indexTs)) {
|
|
233
|
-
return [indexTs];
|
|
234
|
-
}
|
|
235
|
-
if (existsSync(indexJs)) {
|
|
236
|
-
return [indexJs];
|
|
237
|
-
}
|
|
238
|
-
return null;
|
|
239
|
-
}
|
|
240
|
-
function collectAutoExtensionEntries(dir) {
|
|
241
|
-
const entries = [];
|
|
242
|
-
if (!existsSync(dir))
|
|
243
|
-
return entries;
|
|
244
|
-
try {
|
|
245
|
-
const dirEntries = readdirSync(dir, { withFileTypes: true });
|
|
246
|
-
for (const entry of dirEntries) {
|
|
247
|
-
if (entry.name.startsWith("."))
|
|
248
|
-
continue;
|
|
249
|
-
if (entry.name === "node_modules")
|
|
250
|
-
continue;
|
|
251
48
|
const fullPath = join(dir, entry.name);
|
|
252
49
|
let isDir = entry.isDirectory();
|
|
253
50
|
let isFile = entry.isFile();
|
|
@@ -261,33 +58,30 @@ function collectAutoExtensionEntries(dir) {
|
|
|
261
58
|
continue;
|
|
262
59
|
}
|
|
263
60
|
}
|
|
264
|
-
if (
|
|
265
|
-
|
|
61
|
+
if (isDir) {
|
|
62
|
+
results.push(...collectFiles(fullPath, filePattern));
|
|
266
63
|
}
|
|
267
|
-
else if (
|
|
268
|
-
|
|
269
|
-
if (resolvedEntries) {
|
|
270
|
-
entries.push(...resolvedEntries);
|
|
271
|
-
}
|
|
64
|
+
else if (isFile && filePattern.test(entry.name)) {
|
|
65
|
+
results.push(fullPath);
|
|
272
66
|
}
|
|
273
67
|
}
|
|
274
68
|
}
|
|
275
69
|
catch {
|
|
276
|
-
|
|
70
|
+
return results;
|
|
277
71
|
}
|
|
278
|
-
return
|
|
72
|
+
return results;
|
|
279
73
|
}
|
|
280
|
-
function
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
74
|
+
function collectSkillEntries(dir, includeRootFiles = true) {
|
|
75
|
+
if (!existsSync(dir)) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
const results = [];
|
|
284
79
|
try {
|
|
285
|
-
const
|
|
286
|
-
for (const entry of
|
|
287
|
-
if (entry.name.startsWith("."))
|
|
288
|
-
continue;
|
|
289
|
-
if (entry.name === "node_modules")
|
|
80
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
290
83
|
continue;
|
|
84
|
+
}
|
|
291
85
|
const fullPath = join(dir, entry.name);
|
|
292
86
|
let isDir = entry.isDirectory();
|
|
293
87
|
let isFile = entry.isFile();
|
|
@@ -301,134 +95,40 @@ function collectAutoHookEntries(dir) {
|
|
|
301
95
|
continue;
|
|
302
96
|
}
|
|
303
97
|
}
|
|
304
|
-
if (
|
|
305
|
-
|
|
98
|
+
if (isDir) {
|
|
99
|
+
results.push(...collectSkillEntries(fullPath, false));
|
|
306
100
|
}
|
|
307
|
-
else if (
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
101
|
+
else if (isFile) {
|
|
102
|
+
const isRootMd = includeRootFiles && entry.name.endsWith(".md");
|
|
103
|
+
const isSkillMd = !includeRootFiles && entry.name === "SKILL.md";
|
|
104
|
+
if (isRootMd || isSkillMd) {
|
|
105
|
+
results.push(fullPath);
|
|
311
106
|
}
|
|
312
107
|
}
|
|
313
108
|
}
|
|
314
109
|
}
|
|
315
110
|
catch {
|
|
316
|
-
|
|
111
|
+
return results;
|
|
317
112
|
}
|
|
318
|
-
return
|
|
113
|
+
return results;
|
|
319
114
|
}
|
|
320
|
-
function
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const isSkillFile = name === "SKILL.md";
|
|
324
|
-
const parentDir = isSkillFile ? dirname(filePath) : undefined;
|
|
325
|
-
const parentRel = isSkillFile ? relative(baseDir, parentDir) : undefined;
|
|
326
|
-
const parentName = isSkillFile ? basename(parentDir) : undefined;
|
|
327
|
-
return patterns.some((pattern) => {
|
|
328
|
-
if (minimatch(rel, pattern) || minimatch(name, pattern) || minimatch(filePath, pattern)) {
|
|
329
|
-
return true;
|
|
330
|
-
}
|
|
331
|
-
if (!isSkillFile)
|
|
332
|
-
return false;
|
|
333
|
-
return minimatch(parentRel, pattern) || minimatch(parentName, pattern) || minimatch(parentDir, pattern);
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
function normalizeExactPattern(pattern) {
|
|
337
|
-
if (pattern.startsWith("./") || pattern.startsWith(".\\")) {
|
|
338
|
-
return pattern.slice(2);
|
|
115
|
+
function matchesFilter(filePath, baseDir, patterns) {
|
|
116
|
+
if (!patterns || patterns.length === 0) {
|
|
117
|
+
return true;
|
|
339
118
|
}
|
|
340
|
-
return pattern;
|
|
341
|
-
}
|
|
342
|
-
function matchesAnyExactPattern(filePath, patterns, baseDir) {
|
|
343
|
-
if (patterns.length === 0)
|
|
344
|
-
return false;
|
|
345
119
|
const rel = relative(baseDir, filePath);
|
|
346
120
|
const name = basename(filePath);
|
|
347
|
-
const isSkillFile = name === "SKILL.md";
|
|
348
|
-
const parentDir = isSkillFile ? dirname(filePath) : undefined;
|
|
349
|
-
const parentRel = isSkillFile ? relative(baseDir, parentDir) : undefined;
|
|
350
121
|
return patterns.some((pattern) => {
|
|
351
|
-
const normalized =
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
return normalized === parentRel || normalized === parentDir;
|
|
122
|
+
const normalized = pattern.replace(/^\.\//, "");
|
|
123
|
+
return (minimatch(rel, normalized, { nocase: true }) ||
|
|
124
|
+
minimatch(name, normalized, { nocase: true }) ||
|
|
125
|
+
minimatch(filePath, normalized, { nocase: true }) ||
|
|
126
|
+
rel === normalized ||
|
|
127
|
+
name === normalized);
|
|
358
128
|
});
|
|
359
129
|
}
|
|
360
|
-
function
|
|
361
|
-
return
|
|
362
|
-
}
|
|
363
|
-
function isEnabledByOverrides(filePath, patterns, baseDir) {
|
|
364
|
-
const overrides = getOverridePatterns(patterns);
|
|
365
|
-
const excludes = overrides.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
366
|
-
const forceIncludes = overrides.filter((pattern) => pattern.startsWith("+")).map((pattern) => pattern.slice(1));
|
|
367
|
-
const forceExcludes = overrides.filter((pattern) => pattern.startsWith("-")).map((pattern) => pattern.slice(1));
|
|
368
|
-
let enabled = true;
|
|
369
|
-
if (excludes.length > 0 && matchesAnyPattern(filePath, excludes, baseDir)) {
|
|
370
|
-
enabled = false;
|
|
371
|
-
}
|
|
372
|
-
if (forceIncludes.length > 0 && matchesAnyExactPattern(filePath, forceIncludes, baseDir)) {
|
|
373
|
-
enabled = true;
|
|
374
|
-
}
|
|
375
|
-
if (forceExcludes.length > 0 && matchesAnyExactPattern(filePath, forceExcludes, baseDir)) {
|
|
376
|
-
enabled = false;
|
|
377
|
-
}
|
|
378
|
-
return enabled;
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* Apply patterns to paths and return a Set of enabled paths.
|
|
382
|
-
* Pattern types:
|
|
383
|
-
* - Plain patterns: include matching paths
|
|
384
|
-
* - `!pattern`: exclude matching paths
|
|
385
|
-
* - `+path`: force-include exact path (overrides exclusions)
|
|
386
|
-
* - `-path`: force-exclude exact path (overrides force-includes)
|
|
387
|
-
*/
|
|
388
|
-
function applyPatterns(allPaths, patterns, baseDir) {
|
|
389
|
-
const includes = [];
|
|
390
|
-
const excludes = [];
|
|
391
|
-
const forceIncludes = [];
|
|
392
|
-
const forceExcludes = [];
|
|
393
|
-
for (const p of patterns) {
|
|
394
|
-
if (p.startsWith("+")) {
|
|
395
|
-
forceIncludes.push(p.slice(1));
|
|
396
|
-
}
|
|
397
|
-
else if (p.startsWith("-")) {
|
|
398
|
-
forceExcludes.push(p.slice(1));
|
|
399
|
-
}
|
|
400
|
-
else if (p.startsWith("!")) {
|
|
401
|
-
excludes.push(p.slice(1));
|
|
402
|
-
}
|
|
403
|
-
else {
|
|
404
|
-
includes.push(p);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
// Step 1: Apply includes (or all if no includes)
|
|
408
|
-
let result;
|
|
409
|
-
if (includes.length === 0) {
|
|
410
|
-
result = [...allPaths];
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
result = allPaths.filter((filePath) => matchesAnyPattern(filePath, includes, baseDir));
|
|
414
|
-
}
|
|
415
|
-
// Step 2: Apply excludes
|
|
416
|
-
if (excludes.length > 0) {
|
|
417
|
-
result = result.filter((filePath) => !matchesAnyPattern(filePath, excludes, baseDir));
|
|
418
|
-
}
|
|
419
|
-
// Step 3: Force-include (add back from allPaths, overriding exclusions)
|
|
420
|
-
if (forceIncludes.length > 0) {
|
|
421
|
-
for (const filePath of allPaths) {
|
|
422
|
-
if (!result.includes(filePath) && matchesAnyExactPattern(filePath, forceIncludes, baseDir)) {
|
|
423
|
-
result.push(filePath);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
// Step 4: Force-exclude (remove even if included or force-included)
|
|
428
|
-
if (forceExcludes.length > 0) {
|
|
429
|
-
result = result.filter((filePath) => !matchesAnyExactPattern(filePath, forceExcludes, baseDir));
|
|
430
|
-
}
|
|
431
|
-
return new Set(result);
|
|
130
|
+
function pickPatterns(filter, resourceType) {
|
|
131
|
+
return filter?.[resourceType];
|
|
432
132
|
}
|
|
433
133
|
export class DefaultPackageManager {
|
|
434
134
|
constructor(options) {
|
|
@@ -441,40 +141,21 @@ export class DefaultPackageManager {
|
|
|
441
141
|
}
|
|
442
142
|
getInstalledPath(source, scope) {
|
|
443
143
|
const parsed = this.parseSource(source);
|
|
444
|
-
if (parsed.type === "npm") {
|
|
445
|
-
const path = this.getNpmInstallPath(parsed, scope);
|
|
446
|
-
return existsSync(path) ? path : undefined;
|
|
447
|
-
}
|
|
448
|
-
if (parsed.type === "git") {
|
|
449
|
-
const path = this.getGitInstallPath(parsed, scope);
|
|
450
|
-
return existsSync(path) ? path : undefined;
|
|
451
|
-
}
|
|
452
144
|
if (parsed.type === "local") {
|
|
453
|
-
const
|
|
454
|
-
return existsSync(
|
|
455
|
-
}
|
|
456
|
-
return undefined;
|
|
457
|
-
}
|
|
458
|
-
emitProgress(event) {
|
|
459
|
-
this.progressCallback?.(event);
|
|
460
|
-
}
|
|
461
|
-
async withProgress(action, source, message, operation) {
|
|
462
|
-
this.emitProgress({ type: "start", action, source, message });
|
|
463
|
-
try {
|
|
464
|
-
await operation();
|
|
465
|
-
this.emitProgress({ type: "complete", action, source });
|
|
145
|
+
const resolved = this.resolveLocalPath(parsed.path);
|
|
146
|
+
return existsSync(resolved) ? resolved : undefined;
|
|
466
147
|
}
|
|
467
|
-
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
throw error;
|
|
148
|
+
if (parsed.type === "npm") {
|
|
149
|
+
const installedPath = this.getNpmInstallPath(parsed, scope);
|
|
150
|
+
return existsSync(installedPath) ? installedPath : undefined;
|
|
471
151
|
}
|
|
152
|
+
const installedPath = this.getGitInstallPath(parsed, scope);
|
|
153
|
+
return existsSync(installedPath) ? installedPath : undefined;
|
|
472
154
|
}
|
|
473
155
|
async resolve(onMissing) {
|
|
474
156
|
const accumulator = this.createAccumulator();
|
|
475
157
|
const globalSettings = this.settingsManager.getGlobalSettings();
|
|
476
158
|
const projectSettings = this.settingsManager.getProjectSettings();
|
|
477
|
-
// Collect all packages with scope
|
|
478
159
|
const allPackages = [];
|
|
479
160
|
for (const pkg of globalSettings.packages ?? []) {
|
|
480
161
|
allPackages.push({ pkg, scope: "user" });
|
|
@@ -482,42 +163,38 @@ export class DefaultPackageManager {
|
|
|
482
163
|
for (const pkg of projectSettings.packages ?? []) {
|
|
483
164
|
allPackages.push({ pkg, scope: "project" });
|
|
484
165
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
const
|
|
489
|
-
const
|
|
166
|
+
for (const entry of this.dedupePackages(allPackages)) {
|
|
167
|
+
await this.resolvePackageSource(entry.pkg, entry.scope, accumulator, onMissing);
|
|
168
|
+
}
|
|
169
|
+
const globalBase = this.agentDir;
|
|
170
|
+
const projectBase = join(this.cwd, CONFIG_DIR_NAME);
|
|
490
171
|
for (const resourceType of RESOURCE_TYPES) {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
const projectEntries = (projectSettings[resourceType] ?? []);
|
|
494
|
-
this.resolveLocalEntries(globalEntries, resourceType, target, {
|
|
495
|
-
source: "local",
|
|
496
|
-
scope: "user",
|
|
497
|
-
origin: "top-level",
|
|
498
|
-
}, globalBaseDir);
|
|
499
|
-
this.resolveLocalEntries(projectEntries, resourceType, target, {
|
|
500
|
-
source: "local",
|
|
501
|
-
scope: "project",
|
|
502
|
-
origin: "top-level",
|
|
503
|
-
}, projectBaseDir);
|
|
172
|
+
this.resolveTopLevelEntries((globalSettings[resourceType] ?? []), resourceType, accumulator, { source: "local", scope: "user", origin: "top-level", baseDir: globalBase }, globalBase);
|
|
173
|
+
this.resolveTopLevelEntries((projectSettings[resourceType] ?? []), resourceType, accumulator, { source: "local", scope: "project", origin: "top-level", baseDir: projectBase }, projectBase);
|
|
504
174
|
}
|
|
505
|
-
this.
|
|
175
|
+
this.addConventionalResources(accumulator, this.agentDir, { source: "local", scope: "user", origin: "top-level", baseDir: this.agentDir });
|
|
176
|
+
this.addConventionalResources(accumulator, join(this.cwd, CONFIG_DIR_NAME), {
|
|
177
|
+
source: "local",
|
|
178
|
+
scope: "project",
|
|
179
|
+
origin: "top-level",
|
|
180
|
+
baseDir: join(this.cwd, CONFIG_DIR_NAME),
|
|
181
|
+
});
|
|
506
182
|
return this.toResolvedPaths(accumulator);
|
|
507
183
|
}
|
|
508
184
|
async resolveExtensionSources(sources, options) {
|
|
509
185
|
const accumulator = this.createAccumulator();
|
|
510
186
|
const scope = options?.temporary ? "temporary" : options?.local ? "project" : "user";
|
|
511
|
-
const
|
|
512
|
-
|
|
187
|
+
for (const source of sources) {
|
|
188
|
+
await this.resolvePackageSource(source, scope, accumulator);
|
|
189
|
+
}
|
|
513
190
|
return this.toResolvedPaths(accumulator);
|
|
514
191
|
}
|
|
515
192
|
async install(source, options) {
|
|
516
193
|
const parsed = this.parseSource(source);
|
|
517
194
|
const scope = options?.local ? "project" : "user";
|
|
518
|
-
await this.withProgress("install", source,
|
|
195
|
+
await this.withProgress("install", source, async () => {
|
|
519
196
|
if (parsed.type === "npm") {
|
|
520
|
-
await this.installNpm(parsed, scope
|
|
197
|
+
await this.installNpm(parsed, scope);
|
|
521
198
|
return;
|
|
522
199
|
}
|
|
523
200
|
if (parsed.type === "git") {
|
|
@@ -530,13 +207,13 @@ export class DefaultPackageManager {
|
|
|
530
207
|
async remove(source, options) {
|
|
531
208
|
const parsed = this.parseSource(source);
|
|
532
209
|
const scope = options?.local ? "project" : "user";
|
|
533
|
-
await this.withProgress("remove", source,
|
|
210
|
+
await this.withProgress("remove", source, async () => {
|
|
534
211
|
if (parsed.type === "npm") {
|
|
535
212
|
await this.uninstallNpm(parsed, scope);
|
|
536
213
|
return;
|
|
537
214
|
}
|
|
538
215
|
if (parsed.type === "git") {
|
|
539
|
-
|
|
216
|
+
this.removeGit(parsed, scope);
|
|
540
217
|
return;
|
|
541
218
|
}
|
|
542
219
|
throw new Error(`Unsupported remove source: ${source}`);
|
|
@@ -550,239 +227,250 @@ export class DefaultPackageManager {
|
|
|
550
227
|
}
|
|
551
228
|
const globalSettings = this.settingsManager.getGlobalSettings();
|
|
552
229
|
const projectSettings = this.settingsManager.getProjectSettings();
|
|
553
|
-
for (const
|
|
554
|
-
await this.updateSourceForScope(
|
|
230
|
+
for (const pkg of globalSettings.packages ?? []) {
|
|
231
|
+
await this.updateSourceForScope(typeof pkg === "string" ? pkg : pkg.source, "user");
|
|
555
232
|
}
|
|
556
|
-
for (const
|
|
557
|
-
await this.updateSourceForScope(
|
|
233
|
+
for (const pkg of projectSettings.packages ?? []) {
|
|
234
|
+
await this.updateSourceForScope(typeof pkg === "string" ? pkg : pkg.source, "project");
|
|
558
235
|
}
|
|
559
236
|
}
|
|
560
|
-
async
|
|
237
|
+
async resolvePackageSource(pkg, scope, accumulator, onMissing) {
|
|
238
|
+
const source = typeof pkg === "string" ? pkg : pkg.source;
|
|
239
|
+
const filter = typeof pkg === "string" ? undefined : pkg;
|
|
561
240
|
const parsed = this.parseSource(source);
|
|
562
|
-
|
|
563
|
-
|
|
241
|
+
const metadata = { source, scope, origin: "package" };
|
|
242
|
+
if (parsed.type === "local") {
|
|
243
|
+
const localPath = this.resolveLocalPath(parsed.path);
|
|
244
|
+
if (!existsSync(localPath)) {
|
|
564
245
|
return;
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
246
|
+
}
|
|
247
|
+
metadata.baseDir = statSync(localPath).isDirectory() ? localPath : dirname(localPath);
|
|
248
|
+
this.collectSourceResources(localPath, accumulator, filter, metadata);
|
|
568
249
|
return;
|
|
569
250
|
}
|
|
570
|
-
|
|
571
|
-
|
|
251
|
+
const installedPath = this.getInstalledPath(source, scope === "temporary" ? "project" : scope);
|
|
252
|
+
if (!installedPath) {
|
|
253
|
+
const action = onMissing ? await onMissing(source) : "install";
|
|
254
|
+
if (action === "skip") {
|
|
572
255
|
return;
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
256
|
+
}
|
|
257
|
+
if (action === "error") {
|
|
258
|
+
throw new Error(`Missing source: ${source}`);
|
|
259
|
+
}
|
|
260
|
+
await this.installParsedSource(parsed, scope);
|
|
261
|
+
}
|
|
262
|
+
const resolvedPath = this.getInstalledPath(source, scope === "temporary" ? "project" : scope);
|
|
263
|
+
if (!resolvedPath) {
|
|
576
264
|
return;
|
|
577
265
|
}
|
|
266
|
+
metadata.baseDir = resolvedPath;
|
|
267
|
+
this.collectSourceResources(resolvedPath, accumulator, filter, metadata);
|
|
578
268
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
}
|
|
594
|
-
const action = await onMissing(sourceStr);
|
|
595
|
-
if (action === "skip")
|
|
596
|
-
return false;
|
|
597
|
-
if (action === "error")
|
|
598
|
-
throw new Error(`Missing source: ${sourceStr}`);
|
|
599
|
-
await this.installParsedSource(parsed, scope);
|
|
600
|
-
return true;
|
|
601
|
-
};
|
|
602
|
-
if (parsed.type === "npm") {
|
|
603
|
-
const installedPath = this.getNpmInstallPath(parsed, scope);
|
|
604
|
-
const needsInstall = !existsSync(installedPath) || (await this.npmNeedsUpdate(parsed, installedPath));
|
|
605
|
-
if (needsInstall) {
|
|
606
|
-
const installed = await installMissing();
|
|
607
|
-
if (!installed)
|
|
608
|
-
continue;
|
|
269
|
+
collectSourceResources(sourcePath, accumulator, filter, metadata) {
|
|
270
|
+
const stats = statSync(sourcePath);
|
|
271
|
+
if (stats.isFile()) {
|
|
272
|
+
this.addResource(accumulator.extensions, sourcePath, metadata, true);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const manifest = readManifest(join(sourcePath, "package.json"));
|
|
276
|
+
const indusagiRoot = existsSync(join(sourcePath, ".indusagi")) ? join(sourcePath, ".indusagi") : sourcePath;
|
|
277
|
+
for (const resourceType of RESOURCE_TYPES) {
|
|
278
|
+
const configuredEntries = manifest?.[resourceType] ?? [];
|
|
279
|
+
const patterns = pickPatterns(filter, resourceType);
|
|
280
|
+
if (configuredEntries.length > 0) {
|
|
281
|
+
for (const entry of configuredEntries) {
|
|
282
|
+
this.addResolvedEntry(resolve(sourcePath, entry), resourceType, accumulator, { ...metadata, baseDir: sourcePath }, patterns);
|
|
609
283
|
}
|
|
610
|
-
metadata.baseDir = installedPath;
|
|
611
|
-
this.collectPackageResources(installedPath, accumulator, filter, metadata);
|
|
612
284
|
continue;
|
|
613
285
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
if (!existsSync(installedPath)) {
|
|
617
|
-
const installed = await installMissing();
|
|
618
|
-
if (!installed)
|
|
619
|
-
continue;
|
|
620
|
-
}
|
|
621
|
-
metadata.baseDir = installedPath;
|
|
622
|
-
this.collectPackageResources(installedPath, accumulator, filter, metadata);
|
|
623
|
-
}
|
|
286
|
+
const conventionalDir = join(indusagiRoot, resourceType);
|
|
287
|
+
this.addResolvedEntry(conventionalDir, resourceType, accumulator, { ...metadata, baseDir: indusagiRoot }, patterns);
|
|
624
288
|
}
|
|
625
289
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
if (!existsSync(resolved)) {
|
|
290
|
+
addResolvedEntry(entryPath, resourceType, accumulator, metadata, patterns) {
|
|
291
|
+
if (!existsSync(entryPath)) {
|
|
629
292
|
return;
|
|
630
293
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
if (
|
|
634
|
-
|
|
635
|
-
this.addResource(accumulator.extensions, resolved, metadata, true);
|
|
636
|
-
return;
|
|
294
|
+
const stats = statSync(entryPath);
|
|
295
|
+
if (stats.isFile()) {
|
|
296
|
+
if (FILE_PATTERNS[resourceType].test(basename(entryPath)) && matchesFilter(entryPath, metadata.baseDir ?? dirname(entryPath), patterns)) {
|
|
297
|
+
this.addResource(this.getTargetMap(accumulator, resourceType), entryPath, metadata, true);
|
|
637
298
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const files = this.collectResourceFiles(entryPath, resourceType);
|
|
302
|
+
for (const filePath of files) {
|
|
303
|
+
if (matchesFilter(filePath, metadata.baseDir ?? entryPath, patterns)) {
|
|
304
|
+
this.addResource(this.getTargetMap(accumulator, resourceType), filePath, metadata, true);
|
|
644
305
|
}
|
|
645
306
|
}
|
|
646
|
-
|
|
307
|
+
}
|
|
308
|
+
resolveTopLevelEntries(entries, resourceType, accumulator, metadata, baseDir) {
|
|
309
|
+
for (const entry of entries) {
|
|
310
|
+
if (!entry || entry.startsWith("!") || entry.startsWith("+") || entry.startsWith("-")) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
this.addResolvedEntry(resolve(baseDir, entry), resourceType, accumulator, metadata);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
addConventionalResources(accumulator, baseDir, metadata) {
|
|
317
|
+
if (!existsSync(baseDir)) {
|
|
647
318
|
return;
|
|
648
319
|
}
|
|
320
|
+
for (const resourceType of RESOURCE_TYPES) {
|
|
321
|
+
this.addResolvedEntry(join(baseDir, resourceType), resourceType, accumulator, metadata);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
collectResourceFiles(baseDir, resourceType) {
|
|
325
|
+
if (resourceType === "skills") {
|
|
326
|
+
return collectSkillEntries(baseDir);
|
|
327
|
+
}
|
|
328
|
+
return collectFiles(baseDir, FILE_PATTERNS[resourceType]);
|
|
329
|
+
}
|
|
330
|
+
addResource(target, resourcePath, metadata, enabled) {
|
|
331
|
+
if (!target.has(resourcePath)) {
|
|
332
|
+
target.set(resourcePath, { metadata: { ...metadata }, enabled });
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const existing = target.get(resourcePath);
|
|
336
|
+
if (metadata.scope === "project" && existing.metadata.scope === "user") {
|
|
337
|
+
target.set(resourcePath, { metadata: { ...metadata }, enabled });
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
getTargetMap(accumulator, resourceType) {
|
|
341
|
+
return accumulator[resourceType];
|
|
342
|
+
}
|
|
343
|
+
createAccumulator() {
|
|
344
|
+
return {
|
|
345
|
+
extensions: new Map(),
|
|
346
|
+
hooks: new Map(),
|
|
347
|
+
skills: new Map(),
|
|
348
|
+
prompts: new Map(),
|
|
349
|
+
themes: new Map(),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
toResolvedPaths(accumulator) {
|
|
353
|
+
const toList = (map) => Array.from(map.entries()).map(([path, value]) => ({ path, enabled: value.enabled, metadata: value.metadata }));
|
|
354
|
+
return {
|
|
355
|
+
extensions: toList(accumulator.extensions),
|
|
356
|
+
hooks: toList(accumulator.hooks),
|
|
357
|
+
skills: toList(accumulator.skills),
|
|
358
|
+
prompts: toList(accumulator.prompts),
|
|
359
|
+
themes: toList(accumulator.themes),
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
async updateSourceForScope(source, scope) {
|
|
363
|
+
const parsed = this.parseSource(source);
|
|
364
|
+
if (parsed.type === "npm") {
|
|
365
|
+
if (parsed.pinned) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
await this.withProgress("update", source, async () => {
|
|
369
|
+
await this.installNpm(parsed, scope);
|
|
370
|
+
});
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (parsed.type === "git") {
|
|
374
|
+
if (parsed.pinned) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
await this.withProgress("update", source, async () => {
|
|
378
|
+
await this.updateGit(parsed, scope);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
649
381
|
}
|
|
650
382
|
async installParsedSource(parsed, scope) {
|
|
651
383
|
if (parsed.type === "npm") {
|
|
652
|
-
await this.installNpm(parsed, scope
|
|
384
|
+
await this.installNpm(parsed, scope);
|
|
653
385
|
return;
|
|
654
386
|
}
|
|
655
387
|
if (parsed.type === "git") {
|
|
656
388
|
await this.installGit(parsed, scope);
|
|
657
|
-
return;
|
|
658
389
|
}
|
|
659
390
|
}
|
|
660
391
|
parseSource(source) {
|
|
661
392
|
if (source.startsWith("npm:")) {
|
|
662
|
-
const spec = source.slice(
|
|
393
|
+
const spec = source.slice(4).trim();
|
|
663
394
|
const { name, version } = this.parseNpmSpec(spec);
|
|
664
|
-
return {
|
|
665
|
-
type: "npm",
|
|
666
|
-
spec,
|
|
667
|
-
name,
|
|
668
|
-
pinned: Boolean(version),
|
|
669
|
-
};
|
|
395
|
+
return { type: "npm", spec, name, pinned: Boolean(version) };
|
|
670
396
|
}
|
|
671
397
|
if (source.startsWith("git:") || looksLikeGitUrl(source)) {
|
|
672
|
-
const repoSpec = source.startsWith("git:") ? source.slice(
|
|
398
|
+
const repoSpec = source.startsWith("git:") ? source.slice(4).trim() : source;
|
|
673
399
|
const [repo, ref] = repoSpec.split("@");
|
|
674
400
|
const normalized = repo.replace(/^https?:\/\//, "").replace(/\.git$/, "");
|
|
675
|
-
|
|
676
|
-
const host = parts.shift() ?? "";
|
|
677
|
-
const repoPath = parts.join("/");
|
|
678
|
-
return {
|
|
679
|
-
type: "git",
|
|
680
|
-
repo: normalized,
|
|
681
|
-
host,
|
|
682
|
-
path: repoPath,
|
|
683
|
-
ref,
|
|
684
|
-
pinned: Boolean(ref),
|
|
685
|
-
};
|
|
401
|
+
return { type: "git", repo: normalized, ref, pinned: Boolean(ref) };
|
|
686
402
|
}
|
|
687
403
|
return { type: "local", path: source };
|
|
688
404
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
*/
|
|
694
|
-
async npmNeedsUpdate(source, installedPath) {
|
|
695
|
-
const installedVersion = this.getInstalledNpmVersion(installedPath);
|
|
696
|
-
if (!installedVersion)
|
|
697
|
-
return true;
|
|
698
|
-
const { version: pinnedVersion } = this.parseNpmSpec(source.spec);
|
|
699
|
-
if (pinnedVersion) {
|
|
700
|
-
// Pinned: check if installed matches pinned (exact match for now)
|
|
701
|
-
return installedVersion !== pinnedVersion;
|
|
405
|
+
parseNpmSpec(spec) {
|
|
406
|
+
const match = spec.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);
|
|
407
|
+
if (!match) {
|
|
408
|
+
return { name: spec };
|
|
702
409
|
}
|
|
703
|
-
|
|
410
|
+
return { name: match[1] ?? spec, version: match[2] };
|
|
411
|
+
}
|
|
412
|
+
resolveLocalPath(inputPath) {
|
|
413
|
+
return resolve(this.cwd, inputPath);
|
|
414
|
+
}
|
|
415
|
+
async withProgress(action, source, operation) {
|
|
416
|
+
this.progressCallback?.({ type: "start", action, source });
|
|
704
417
|
try {
|
|
705
|
-
|
|
706
|
-
|
|
418
|
+
await operation();
|
|
419
|
+
this.progressCallback?.({ type: "complete", action, source });
|
|
707
420
|
}
|
|
708
|
-
catch {
|
|
709
|
-
|
|
710
|
-
|
|
421
|
+
catch (error) {
|
|
422
|
+
this.progressCallback?.({
|
|
423
|
+
type: "error",
|
|
424
|
+
action,
|
|
425
|
+
source,
|
|
426
|
+
message: error instanceof Error ? error.message : String(error),
|
|
427
|
+
});
|
|
428
|
+
throw error;
|
|
711
429
|
}
|
|
712
430
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
return undefined;
|
|
717
|
-
try {
|
|
718
|
-
const content = readFileSync(packageJsonPath, "utf-8");
|
|
719
|
-
const pkg = JSON.parse(content);
|
|
720
|
-
return pkg.version;
|
|
431
|
+
getNpmInstallRoot(scope) {
|
|
432
|
+
if (scope === "project") {
|
|
433
|
+
return join(this.cwd, CONFIG_DIR_NAME, "packages", "node");
|
|
721
434
|
}
|
|
722
|
-
|
|
723
|
-
|
|
435
|
+
if (scope === "temporary") {
|
|
436
|
+
const hash = createHash("sha1").update(this.cwd).digest("hex").slice(0, 12);
|
|
437
|
+
return join(tmpdir(), `indusagi-screth-packages-${hash}`);
|
|
724
438
|
}
|
|
439
|
+
return this.agentDir;
|
|
725
440
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (!response.ok)
|
|
729
|
-
throw new Error(`Failed to fetch npm registry: ${response.status}`);
|
|
730
|
-
const data = (await response.json());
|
|
731
|
-
return data.version;
|
|
441
|
+
getProjectNpmNodeModules(scope) {
|
|
442
|
+
return join(this.getNpmInstallRoot(scope), "node_modules");
|
|
732
443
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
*/
|
|
737
|
-
getPackageIdentity(source) {
|
|
738
|
-
const parsed = this.parseSource(source);
|
|
739
|
-
if (parsed.type === "npm") {
|
|
740
|
-
return `npm:${parsed.name}`;
|
|
741
|
-
}
|
|
742
|
-
if (parsed.type === "git") {
|
|
743
|
-
return `git:${parsed.repo}`;
|
|
444
|
+
getNpmInstallPath(source, scope) {
|
|
445
|
+
if (scope === "user") {
|
|
446
|
+
return join(this.getGlobalNpmRoot(), source.name);
|
|
744
447
|
}
|
|
745
|
-
|
|
746
|
-
return `local:${this.resolvePath(parsed.path)}`;
|
|
448
|
+
return join(this.getProjectNpmNodeModules("project"), source.name);
|
|
747
449
|
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
const existing = seen.get(identity);
|
|
758
|
-
if (!existing) {
|
|
759
|
-
seen.set(identity, entry);
|
|
760
|
-
}
|
|
761
|
-
else if (entry.scope === "project" && existing.scope === "user") {
|
|
762
|
-
// Project wins over user
|
|
763
|
-
seen.set(identity, entry);
|
|
450
|
+
getGlobalNpmRoot() {
|
|
451
|
+
if (this.globalNpmRoot) {
|
|
452
|
+
return this.globalNpmRoot;
|
|
453
|
+
}
|
|
454
|
+
let output = "";
|
|
455
|
+
try {
|
|
456
|
+
const result = spawnSync("npm", ["root", "-g"], { encoding: "utf-8" });
|
|
457
|
+
if (result.status === 0 && result.stdout.trim()) {
|
|
458
|
+
output = result.stdout.trim();
|
|
764
459
|
}
|
|
765
|
-
// If existing is project and new is global, keep existing (project)
|
|
766
|
-
// If both are same scope, keep first one
|
|
767
460
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
parseNpmSpec(spec) {
|
|
771
|
-
const match = spec.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);
|
|
772
|
-
if (!match) {
|
|
773
|
-
return { name: spec };
|
|
461
|
+
catch {
|
|
462
|
+
// Ignore and fall back.
|
|
774
463
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
return { name, version };
|
|
464
|
+
this.globalNpmRoot = output || join(this.agentDir, "node_modules");
|
|
465
|
+
return this.globalNpmRoot;
|
|
778
466
|
}
|
|
779
|
-
async installNpm(source, scope
|
|
780
|
-
if (scope === "user"
|
|
467
|
+
async installNpm(source, scope) {
|
|
468
|
+
if (scope === "user") {
|
|
781
469
|
await this.runCommand("npm", ["install", "-g", source.spec]);
|
|
782
470
|
return;
|
|
783
471
|
}
|
|
784
|
-
const installRoot = this.getNpmInstallRoot(scope
|
|
785
|
-
this.
|
|
472
|
+
const installRoot = this.getNpmInstallRoot(scope);
|
|
473
|
+
this.ensureNodeProject(installRoot);
|
|
786
474
|
await this.runCommand("npm", ["install", source.spec, "--prefix", installRoot]);
|
|
787
475
|
}
|
|
788
476
|
async uninstallNpm(source, scope) {
|
|
@@ -790,432 +478,106 @@ export class DefaultPackageManager {
|
|
|
790
478
|
await this.runCommand("npm", ["uninstall", "-g", source.name]);
|
|
791
479
|
return;
|
|
792
480
|
}
|
|
793
|
-
const installRoot = this.getNpmInstallRoot(scope
|
|
481
|
+
const installRoot = this.getNpmInstallRoot(scope);
|
|
794
482
|
if (!existsSync(installRoot)) {
|
|
795
483
|
return;
|
|
796
484
|
}
|
|
797
485
|
await this.runCommand("npm", ["uninstall", source.name, "--prefix", installRoot]);
|
|
798
486
|
}
|
|
487
|
+
getGitInstallPath(source, scope) {
|
|
488
|
+
const base = scope === "project" ? join(this.cwd, CONFIG_DIR_NAME, "packages", "git") : join(this.agentDir, "packages", "git");
|
|
489
|
+
const hash = createHash("sha1").update(source.repo).digest("hex").slice(0, 12);
|
|
490
|
+
const safeName = source.repo.split("/").pop() || "repo";
|
|
491
|
+
return join(base, `${safeName}-${hash}`);
|
|
492
|
+
}
|
|
799
493
|
async installGit(source, scope) {
|
|
800
|
-
const targetDir = this.getGitInstallPath(source, scope);
|
|
494
|
+
const targetDir = this.getGitInstallPath(source, scope === "temporary" ? "project" : scope);
|
|
801
495
|
if (existsSync(targetDir)) {
|
|
802
496
|
return;
|
|
803
497
|
}
|
|
804
|
-
const gitRoot = this.getGitInstallRoot(scope);
|
|
805
|
-
if (gitRoot) {
|
|
806
|
-
this.ensureGitIgnore(gitRoot);
|
|
807
|
-
}
|
|
808
498
|
mkdirSync(dirname(targetDir), { recursive: true });
|
|
809
499
|
const cloneUrl = source.repo.startsWith("http") ? source.repo : `https://${source.repo}`;
|
|
810
500
|
await this.runCommand("git", ["clone", cloneUrl, targetDir]);
|
|
811
501
|
if (source.ref) {
|
|
812
502
|
await this.runCommand("git", ["checkout", source.ref], { cwd: targetDir });
|
|
813
503
|
}
|
|
814
|
-
|
|
815
|
-
if (existsSync(packageJsonPath)) {
|
|
504
|
+
if (existsSync(join(targetDir, "package.json"))) {
|
|
816
505
|
await this.runCommand("npm", ["install"], { cwd: targetDir });
|
|
817
506
|
}
|
|
818
507
|
}
|
|
819
508
|
async updateGit(source, scope) {
|
|
820
|
-
const targetDir = this.getGitInstallPath(source, scope);
|
|
509
|
+
const targetDir = this.getGitInstallPath(source, scope === "temporary" ? "project" : scope);
|
|
821
510
|
if (!existsSync(targetDir)) {
|
|
822
511
|
await this.installGit(source, scope);
|
|
823
512
|
return;
|
|
824
513
|
}
|
|
825
514
|
await this.runCommand("git", ["pull"], { cwd: targetDir });
|
|
826
|
-
|
|
827
|
-
if (existsSync(packageJsonPath)) {
|
|
515
|
+
if (existsSync(join(targetDir, "package.json"))) {
|
|
828
516
|
await this.runCommand("npm", ["install"], { cwd: targetDir });
|
|
829
517
|
}
|
|
830
518
|
}
|
|
831
|
-
|
|
832
|
-
const targetDir = this.getGitInstallPath(source, scope);
|
|
833
|
-
if (
|
|
834
|
-
|
|
835
|
-
rmSync(targetDir, { recursive: true, force: true });
|
|
836
|
-
}
|
|
837
|
-
ensureNpmProject(installRoot) {
|
|
838
|
-
if (!existsSync(installRoot)) {
|
|
839
|
-
mkdirSync(installRoot, { recursive: true });
|
|
840
|
-
}
|
|
841
|
-
this.ensureGitIgnore(installRoot);
|
|
842
|
-
const packageJsonPath = join(installRoot, "package.json");
|
|
843
|
-
if (!existsSync(packageJsonPath)) {
|
|
844
|
-
const pkgJson = { name: "indusagi-extensions", private: true };
|
|
845
|
-
writeFileSync(packageJsonPath, JSON.stringify(pkgJson, null, 2), "utf-8");
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
ensureGitIgnore(dir) {
|
|
849
|
-
if (!existsSync(dir)) {
|
|
850
|
-
mkdirSync(dir, { recursive: true });
|
|
851
|
-
}
|
|
852
|
-
const ignorePath = join(dir, ".gitignore");
|
|
853
|
-
if (!existsSync(ignorePath)) {
|
|
854
|
-
writeFileSync(ignorePath, "*\n!.gitignore\n", "utf-8");
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
getNpmInstallRoot(scope, temporary) {
|
|
858
|
-
if (temporary) {
|
|
859
|
-
return this.getTemporaryDir("npm");
|
|
860
|
-
}
|
|
861
|
-
if (scope === "project") {
|
|
862
|
-
return join(this.cwd, CONFIG_DIR_NAME, "npm");
|
|
863
|
-
}
|
|
864
|
-
return join(this.getGlobalNpmRoot(), "..");
|
|
865
|
-
}
|
|
866
|
-
getGlobalNpmRoot() {
|
|
867
|
-
if (this.globalNpmRoot) {
|
|
868
|
-
return this.globalNpmRoot;
|
|
869
|
-
}
|
|
870
|
-
const result = this.runCommandSync("npm", ["root", "-g"]);
|
|
871
|
-
this.globalNpmRoot = result.trim();
|
|
872
|
-
return this.globalNpmRoot;
|
|
873
|
-
}
|
|
874
|
-
getNpmInstallPath(source, scope) {
|
|
875
|
-
if (scope === "temporary") {
|
|
876
|
-
return join(this.getTemporaryDir("npm"), "node_modules", source.name);
|
|
877
|
-
}
|
|
878
|
-
if (scope === "project") {
|
|
879
|
-
return join(this.cwd, CONFIG_DIR_NAME, "npm", "node_modules", source.name);
|
|
880
|
-
}
|
|
881
|
-
return join(this.getGlobalNpmRoot(), source.name);
|
|
882
|
-
}
|
|
883
|
-
getGitInstallPath(source, scope) {
|
|
884
|
-
if (scope === "temporary") {
|
|
885
|
-
return this.getTemporaryDir(`git-${source.host}`, source.path);
|
|
886
|
-
}
|
|
887
|
-
if (scope === "project") {
|
|
888
|
-
return join(this.cwd, CONFIG_DIR_NAME, "git", source.host, source.path);
|
|
889
|
-
}
|
|
890
|
-
return join(this.agentDir, "git", source.host, source.path);
|
|
891
|
-
}
|
|
892
|
-
getGitInstallRoot(scope) {
|
|
893
|
-
if (scope === "temporary") {
|
|
894
|
-
return undefined;
|
|
895
|
-
}
|
|
896
|
-
if (scope === "project") {
|
|
897
|
-
return join(this.cwd, CONFIG_DIR_NAME, "git");
|
|
898
|
-
}
|
|
899
|
-
return join(this.agentDir, "git");
|
|
900
|
-
}
|
|
901
|
-
getTemporaryDir(prefix, suffix) {
|
|
902
|
-
const hash = createHash("sha256")
|
|
903
|
-
.update(`${prefix}-${suffix ?? ""}`)
|
|
904
|
-
.digest("hex")
|
|
905
|
-
.slice(0, 8);
|
|
906
|
-
return join(tmpdir(), "indusagi-extensions", prefix, hash, suffix ?? "");
|
|
907
|
-
}
|
|
908
|
-
resolvePath(input) {
|
|
909
|
-
const trimmed = input.trim();
|
|
910
|
-
if (trimmed === "~")
|
|
911
|
-
return homedir();
|
|
912
|
-
if (trimmed.startsWith("~/"))
|
|
913
|
-
return join(homedir(), trimmed.slice(2));
|
|
914
|
-
if (trimmed.startsWith("~"))
|
|
915
|
-
return join(homedir(), trimmed.slice(1));
|
|
916
|
-
return resolve(this.cwd, trimmed);
|
|
917
|
-
}
|
|
918
|
-
resolvePathFromBase(input, baseDir) {
|
|
919
|
-
const trimmed = input.trim();
|
|
920
|
-
if (trimmed === "~")
|
|
921
|
-
return homedir();
|
|
922
|
-
if (trimmed.startsWith("~/"))
|
|
923
|
-
return join(homedir(), trimmed.slice(2));
|
|
924
|
-
if (trimmed.startsWith("~"))
|
|
925
|
-
return join(homedir(), trimmed.slice(1));
|
|
926
|
-
return resolve(baseDir, trimmed);
|
|
927
|
-
}
|
|
928
|
-
collectPackageResources(packageRoot, accumulator, filter, metadata) {
|
|
929
|
-
if (filter) {
|
|
930
|
-
for (const resourceType of RESOURCE_TYPES) {
|
|
931
|
-
const patterns = filter[resourceType];
|
|
932
|
-
const target = this.getTargetMap(accumulator, resourceType);
|
|
933
|
-
if (patterns !== undefined) {
|
|
934
|
-
this.applyPackageFilter(packageRoot, patterns, resourceType, target, metadata);
|
|
935
|
-
}
|
|
936
|
-
else {
|
|
937
|
-
this.collectDefaultResources(packageRoot, resourceType, target, metadata);
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
return true;
|
|
941
|
-
}
|
|
942
|
-
const manifest = this.readIndusagiManifest(packageRoot);
|
|
943
|
-
if (manifest) {
|
|
944
|
-
for (const resourceType of RESOURCE_TYPES) {
|
|
945
|
-
const entries = manifest[resourceType];
|
|
946
|
-
this.addManifestEntries(entries, packageRoot, resourceType, this.getTargetMap(accumulator, resourceType), metadata);
|
|
947
|
-
}
|
|
948
|
-
return true;
|
|
949
|
-
}
|
|
950
|
-
let hasAnyDir = false;
|
|
951
|
-
for (const resourceType of RESOURCE_TYPES) {
|
|
952
|
-
const dir = join(packageRoot, resourceType);
|
|
953
|
-
if (existsSync(dir)) {
|
|
954
|
-
// Collect all files from the directory (all enabled by default)
|
|
955
|
-
const files = resourceType === "skills" ? collectSkillEntries(dir) : collectFiles(dir, FILE_PATTERNS[resourceType]);
|
|
956
|
-
for (const f of files) {
|
|
957
|
-
this.addResource(this.getTargetMap(accumulator, resourceType), f, metadata, true);
|
|
958
|
-
}
|
|
959
|
-
hasAnyDir = true;
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
return hasAnyDir;
|
|
963
|
-
}
|
|
964
|
-
collectDefaultResources(packageRoot, resourceType, target, metadata) {
|
|
965
|
-
const manifest = this.readIndusagiManifest(packageRoot);
|
|
966
|
-
const entries = manifest?.[resourceType];
|
|
967
|
-
if (entries) {
|
|
968
|
-
this.addManifestEntries(entries, packageRoot, resourceType, target, metadata);
|
|
969
|
-
return;
|
|
970
|
-
}
|
|
971
|
-
const dir = join(packageRoot, resourceType);
|
|
972
|
-
if (existsSync(dir)) {
|
|
973
|
-
// Collect all files from the directory (all enabled by default)
|
|
974
|
-
const files = resourceType === "skills" ? collectSkillEntries(dir) : collectFiles(dir, FILE_PATTERNS[resourceType]);
|
|
975
|
-
for (const f of files) {
|
|
976
|
-
this.addResource(target, f, metadata, true);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
applyPackageFilter(packageRoot, userPatterns, resourceType, target, metadata) {
|
|
981
|
-
const { allFiles, enabledByManifest } = this.collectManifestFiles(packageRoot, resourceType);
|
|
982
|
-
if (userPatterns.length === 0) {
|
|
983
|
-
// No user patterns, just use manifest filtering
|
|
984
|
-
for (const f of allFiles) {
|
|
985
|
-
this.addResource(target, f, metadata, enabledByManifest.has(f));
|
|
986
|
-
}
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
// Apply user patterns on top of manifest-enabled files
|
|
990
|
-
const enabledByUser = applyPatterns(allFiles, userPatterns, packageRoot);
|
|
991
|
-
for (const f of allFiles) {
|
|
992
|
-
const enabled = enabledByUser.has(f);
|
|
993
|
-
this.addResource(target, f, metadata, enabled);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Collect all files from a package for a resource type, applying manifest patterns.
|
|
998
|
-
* Returns { allFiles, enabledByManifest } where enabledByManifest is the set of files
|
|
999
|
-
* that pass the manifest's own patterns.
|
|
1000
|
-
*/
|
|
1001
|
-
collectManifestFiles(packageRoot, resourceType) {
|
|
1002
|
-
const manifest = this.readIndusagiManifest(packageRoot);
|
|
1003
|
-
const entries = manifest?.[resourceType];
|
|
1004
|
-
if (entries && entries.length > 0) {
|
|
1005
|
-
const allFiles = this.collectFilesFromManifestEntries(entries, packageRoot, resourceType);
|
|
1006
|
-
const manifestPatterns = entries.filter(isPattern);
|
|
1007
|
-
const enabledByManifest = manifestPatterns.length > 0 ? applyPatterns(allFiles, manifestPatterns, packageRoot) : new Set(allFiles);
|
|
1008
|
-
return { allFiles: Array.from(enabledByManifest), enabledByManifest };
|
|
1009
|
-
}
|
|
1010
|
-
const conventionDir = join(packageRoot, resourceType);
|
|
1011
|
-
if (!existsSync(conventionDir)) {
|
|
1012
|
-
return { allFiles: [], enabledByManifest: new Set() };
|
|
519
|
+
removeGit(source, scope) {
|
|
520
|
+
const targetDir = this.getGitInstallPath(source, scope === "temporary" ? "project" : scope);
|
|
521
|
+
if (existsSync(targetDir)) {
|
|
522
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
1013
523
|
}
|
|
1014
|
-
const allFiles = resourceType === "skills"
|
|
1015
|
-
? collectSkillEntries(conventionDir)
|
|
1016
|
-
: collectFiles(conventionDir, FILE_PATTERNS[resourceType]);
|
|
1017
|
-
return { allFiles, enabledByManifest: new Set(allFiles) };
|
|
1018
524
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
525
|
+
ensureNodeProject(dir) {
|
|
526
|
+
mkdirSync(dir, { recursive: true });
|
|
527
|
+
const packageJsonPath = join(dir, "package.json");
|
|
1021
528
|
if (!existsSync(packageJsonPath)) {
|
|
1022
|
-
|
|
1023
|
-
}
|
|
1024
|
-
try {
|
|
1025
|
-
const content = readFileSync(packageJsonPath, "utf-8");
|
|
1026
|
-
const pkg = JSON.parse(content);
|
|
1027
|
-
return pkg.indusagi ?? null;
|
|
1028
|
-
}
|
|
1029
|
-
catch {
|
|
1030
|
-
return null;
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
addManifestEntries(entries, root, resourceType, target, metadata) {
|
|
1034
|
-
if (!entries)
|
|
1035
|
-
return;
|
|
1036
|
-
const allFiles = this.collectFilesFromManifestEntries(entries, root, resourceType);
|
|
1037
|
-
const patterns = entries.filter(isPattern);
|
|
1038
|
-
const enabledPaths = applyPatterns(allFiles, patterns, root);
|
|
1039
|
-
for (const f of allFiles) {
|
|
1040
|
-
if (enabledPaths.has(f)) {
|
|
1041
|
-
this.addResource(target, f, metadata, true);
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
collectFilesFromManifestEntries(entries, root, resourceType) {
|
|
1046
|
-
const plain = entries.filter((entry) => !isPattern(entry));
|
|
1047
|
-
const resolved = plain.map((entry) => resolve(root, entry));
|
|
1048
|
-
return this.collectFilesFromPaths(resolved, resourceType);
|
|
1049
|
-
}
|
|
1050
|
-
resolveLocalEntries(entries, resourceType, target, metadata, baseDir) {
|
|
1051
|
-
if (entries.length === 0)
|
|
1052
|
-
return;
|
|
1053
|
-
// Collect all files from plain entries (non-pattern entries)
|
|
1054
|
-
const { plain, patterns } = splitPatterns(entries);
|
|
1055
|
-
const resolvedPlain = plain.map((p) => this.resolvePathFromBase(p, baseDir));
|
|
1056
|
-
const allFiles = this.collectFilesFromPaths(resolvedPlain, resourceType);
|
|
1057
|
-
// Determine which files are enabled based on patterns
|
|
1058
|
-
const enabledPaths = applyPatterns(allFiles, patterns, baseDir);
|
|
1059
|
-
// Add all files with their enabled state
|
|
1060
|
-
for (const f of allFiles) {
|
|
1061
|
-
this.addResource(target, f, metadata, enabledPaths.has(f));
|
|
529
|
+
writeFileSync(packageJsonPath, JSON.stringify({ name: "indusagi-screth-packages", private: true }, null, 2), "utf-8");
|
|
1062
530
|
}
|
|
1063
531
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
source: "auto",
|
|
1067
|
-
scope: "user",
|
|
1068
|
-
origin: "top-level",
|
|
1069
|
-
baseDir: globalBaseDir,
|
|
1070
|
-
};
|
|
1071
|
-
const projectMetadata = {
|
|
1072
|
-
source: "auto",
|
|
1073
|
-
scope: "project",
|
|
1074
|
-
origin: "top-level",
|
|
1075
|
-
baseDir: projectBaseDir,
|
|
1076
|
-
};
|
|
1077
|
-
const userOverrides = {
|
|
1078
|
-
extensions: (globalSettings.extensions ?? []),
|
|
1079
|
-
hooks: (globalSettings.hooks ?? []),
|
|
1080
|
-
skills: (globalSettings.skills ?? []),
|
|
1081
|
-
prompts: (globalSettings.prompts ?? []),
|
|
1082
|
-
themes: (globalSettings.themes ?? []),
|
|
1083
|
-
};
|
|
1084
|
-
const projectOverrides = {
|
|
1085
|
-
extensions: (projectSettings.extensions ?? []),
|
|
1086
|
-
hooks: (projectSettings.hooks ?? []),
|
|
1087
|
-
skills: (projectSettings.skills ?? []),
|
|
1088
|
-
prompts: (projectSettings.prompts ?? []),
|
|
1089
|
-
themes: (projectSettings.themes ?? []),
|
|
1090
|
-
};
|
|
1091
|
-
const userDirs = {
|
|
1092
|
-
extensions: join(globalBaseDir, "extensions"),
|
|
1093
|
-
hooks: join(globalBaseDir, "hooks"),
|
|
1094
|
-
skills: join(globalBaseDir, "skills"),
|
|
1095
|
-
prompts: join(globalBaseDir, "prompts"),
|
|
1096
|
-
themes: join(globalBaseDir, "themes"),
|
|
1097
|
-
};
|
|
1098
|
-
const projectDirs = {
|
|
1099
|
-
extensions: join(projectBaseDir, "extensions"),
|
|
1100
|
-
hooks: join(projectBaseDir, "hooks"),
|
|
1101
|
-
skills: join(projectBaseDir, "skills"),
|
|
1102
|
-
prompts: join(projectBaseDir, "prompts"),
|
|
1103
|
-
themes: join(projectBaseDir, "themes"),
|
|
1104
|
-
};
|
|
1105
|
-
const addResources = (resourceType, paths, metadata, overrides, baseDir) => {
|
|
1106
|
-
const target = this.getTargetMap(accumulator, resourceType);
|
|
1107
|
-
for (const path of paths) {
|
|
1108
|
-
const enabled = isEnabledByOverrides(path, overrides, baseDir);
|
|
1109
|
-
this.addResource(target, path, metadata, enabled);
|
|
1110
|
-
}
|
|
1111
|
-
};
|
|
1112
|
-
addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
|
|
1113
|
-
addResources("hooks", collectAutoHookEntries(userDirs.hooks), userMetadata, userOverrides.hooks, globalBaseDir);
|
|
1114
|
-
addResources("skills", collectAutoSkillEntries(userDirs.skills), userMetadata, userOverrides.skills, globalBaseDir);
|
|
1115
|
-
addResources("prompts", collectAutoPromptEntries(userDirs.prompts), userMetadata, userOverrides.prompts, globalBaseDir);
|
|
1116
|
-
addResources("themes", collectAutoThemeEntries(userDirs.themes), userMetadata, userOverrides.themes, globalBaseDir);
|
|
1117
|
-
addResources("extensions", collectAutoExtensionEntries(projectDirs.extensions), projectMetadata, projectOverrides.extensions, projectBaseDir);
|
|
1118
|
-
addResources("hooks", collectAutoHookEntries(projectDirs.hooks), projectMetadata, projectOverrides.hooks, projectBaseDir);
|
|
1119
|
-
addResources("skills", collectAutoSkillEntries(projectDirs.skills), projectMetadata, projectOverrides.skills, projectBaseDir);
|
|
1120
|
-
addResources("prompts", collectAutoPromptEntries(projectDirs.prompts), projectMetadata, projectOverrides.prompts, projectBaseDir);
|
|
1121
|
-
addResources("themes", collectAutoThemeEntries(projectDirs.themes), projectMetadata, projectOverrides.themes, projectBaseDir);
|
|
1122
|
-
}
|
|
1123
|
-
collectFilesFromPaths(paths, resourceType) {
|
|
1124
|
-
const files = [];
|
|
1125
|
-
for (const p of paths) {
|
|
1126
|
-
if (!existsSync(p))
|
|
1127
|
-
continue;
|
|
1128
|
-
try {
|
|
1129
|
-
const stats = statSync(p);
|
|
1130
|
-
if (stats.isFile()) {
|
|
1131
|
-
files.push(p);
|
|
1132
|
-
}
|
|
1133
|
-
else if (stats.isDirectory()) {
|
|
1134
|
-
if (resourceType === "skills") {
|
|
1135
|
-
files.push(...collectSkillEntries(p));
|
|
1136
|
-
}
|
|
1137
|
-
else {
|
|
1138
|
-
files.push(...collectFiles(p, FILE_PATTERNS[resourceType]));
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
catch {
|
|
1143
|
-
// Ignore errors
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
return files;
|
|
1147
|
-
}
|
|
1148
|
-
getTargetMap(accumulator, resourceType) {
|
|
1149
|
-
switch (resourceType) {
|
|
1150
|
-
case "extensions":
|
|
1151
|
-
return accumulator.extensions;
|
|
1152
|
-
case "hooks":
|
|
1153
|
-
return accumulator.hooks;
|
|
1154
|
-
case "skills":
|
|
1155
|
-
return accumulator.skills;
|
|
1156
|
-
case "prompts":
|
|
1157
|
-
return accumulator.prompts;
|
|
1158
|
-
case "themes":
|
|
1159
|
-
return accumulator.themes;
|
|
1160
|
-
default:
|
|
1161
|
-
throw new Error(`Unknown resource type: ${resourceType}`);
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
addResource(map, path, metadata, enabled) {
|
|
1165
|
-
if (!path)
|
|
1166
|
-
return;
|
|
1167
|
-
if (!map.has(path)) {
|
|
1168
|
-
map.set(path, { metadata, enabled });
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
createAccumulator() {
|
|
1172
|
-
return {
|
|
1173
|
-
extensions: new Map(),
|
|
1174
|
-
hooks: new Map(),
|
|
1175
|
-
skills: new Map(),
|
|
1176
|
-
prompts: new Map(),
|
|
1177
|
-
themes: new Map(),
|
|
1178
|
-
};
|
|
1179
|
-
}
|
|
1180
|
-
toResolvedPaths(accumulator) {
|
|
1181
|
-
const toResolved = (entries) => {
|
|
1182
|
-
return Array.from(entries.entries()).map(([path, { metadata, enabled }]) => ({
|
|
1183
|
-
path,
|
|
1184
|
-
enabled,
|
|
1185
|
-
metadata,
|
|
1186
|
-
}));
|
|
1187
|
-
};
|
|
1188
|
-
return {
|
|
1189
|
-
extensions: toResolved(accumulator.extensions),
|
|
1190
|
-
hooks: toResolved(accumulator.hooks),
|
|
1191
|
-
skills: toResolved(accumulator.skills),
|
|
1192
|
-
prompts: toResolved(accumulator.prompts),
|
|
1193
|
-
themes: toResolved(accumulator.themes),
|
|
1194
|
-
};
|
|
1195
|
-
}
|
|
1196
|
-
runCommand(command, args, options) {
|
|
1197
|
-
return new Promise((resolvePromise, reject) => {
|
|
532
|
+
async runCommand(command, args, options) {
|
|
533
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
1198
534
|
const child = spawn(command, args, {
|
|
1199
|
-
cwd: options?.cwd,
|
|
1200
|
-
stdio: "
|
|
535
|
+
cwd: options?.cwd ?? this.cwd,
|
|
536
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1201
537
|
});
|
|
1202
|
-
|
|
1203
|
-
child.on("
|
|
538
|
+
let stderr = "";
|
|
539
|
+
child.stderr?.on("data", (data) => {
|
|
540
|
+
stderr += data.toString();
|
|
541
|
+
this.progressCallback?.({
|
|
542
|
+
type: "progress",
|
|
543
|
+
action: command === "git" && args[0] === "clone" ? "clone" : command === "git" ? "pull" : "install",
|
|
544
|
+
source: args.join(" "),
|
|
545
|
+
message: data.toString().trim(),
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
child.on("close", (code) => {
|
|
1204
549
|
if (code === 0) {
|
|
1205
550
|
resolvePromise();
|
|
551
|
+
return;
|
|
1206
552
|
}
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
553
|
+
rejectPromise(new Error(stderr.trim() || `${command} ${args.join(" ")} failed with code ${code}`));
|
|
554
|
+
});
|
|
555
|
+
child.on("error", (error) => {
|
|
556
|
+
rejectPromise(error);
|
|
1210
557
|
});
|
|
1211
558
|
});
|
|
1212
559
|
}
|
|
1213
|
-
|
|
1214
|
-
const
|
|
1215
|
-
if (
|
|
1216
|
-
|
|
560
|
+
getPackageIdentity(source) {
|
|
561
|
+
const parsed = this.parseSource(source);
|
|
562
|
+
if (parsed.type === "npm") {
|
|
563
|
+
return `npm:${parsed.name}`;
|
|
564
|
+
}
|
|
565
|
+
if (parsed.type === "git") {
|
|
566
|
+
return `git:${parsed.repo}`;
|
|
567
|
+
}
|
|
568
|
+
return `local:${this.resolveLocalPath(parsed.path)}`;
|
|
569
|
+
}
|
|
570
|
+
dedupePackages(packages) {
|
|
571
|
+
const seen = new Map();
|
|
572
|
+
for (const entry of packages) {
|
|
573
|
+
const source = typeof entry.pkg === "string" ? entry.pkg : entry.pkg.source;
|
|
574
|
+
const identity = this.getPackageIdentity(source);
|
|
575
|
+
const existing = seen.get(identity);
|
|
576
|
+
if (!existing || (entry.scope === "project" && existing.scope === "user")) {
|
|
577
|
+
seen.set(identity, entry);
|
|
578
|
+
}
|
|
1217
579
|
}
|
|
1218
|
-
return (
|
|
580
|
+
return Array.from(seen.values());
|
|
1219
581
|
}
|
|
1220
582
|
}
|
|
1221
583
|
//# sourceMappingURL=package-manager.js.map
|