gsd-pi 2.20.0 → 2.22.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/README.md +12 -0
- package/dist/cli.js +21 -18
- package/dist/help-text.d.ts +2 -0
- package/dist/help-text.js +47 -0
- package/dist/loader.js +2 -16
- package/dist/mcp-server.d.ts +18 -0
- package/dist/mcp-server.js +53 -0
- package/dist/onboarding.d.ts +0 -6
- package/dist/onboarding.js +0 -28
- package/dist/resources/agents/javascript-pro.md +280 -0
- package/dist/resources/agents/typescript-pro.md +255 -0
- package/dist/resources/extensions/bg-shell/index.ts +14 -2
- package/dist/resources/extensions/bg-shell/utilities.ts +14 -0
- package/dist/resources/extensions/browser-tools/{core.js → core.ts} +329 -190
- package/dist/resources/extensions/gsd/auto-dashboard.ts +2 -1
- package/dist/resources/extensions/gsd/auto-prompts.ts +42 -1
- package/dist/resources/extensions/gsd/auto-worktree.ts +35 -2
- package/dist/resources/extensions/gsd/auto.ts +116 -10
- package/dist/resources/extensions/gsd/claude-import.ts +656 -0
- package/dist/resources/extensions/gsd/collision-diagnostics.ts +332 -0
- package/dist/resources/extensions/gsd/commands.ts +60 -7
- package/dist/resources/extensions/gsd/diff-context.ts +220 -0
- package/dist/resources/extensions/gsd/docs/claude-marketplace-import.md +214 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -1
- package/dist/resources/extensions/gsd/doctor.ts +12 -4
- package/dist/resources/extensions/gsd/file-watcher.ts +97 -0
- package/dist/resources/extensions/gsd/files.ts +1 -1
- package/dist/resources/extensions/gsd/forensics.ts +596 -0
- package/dist/resources/extensions/gsd/git-service.ts +2 -1
- package/dist/resources/extensions/gsd/github-client.ts +235 -0
- package/dist/resources/extensions/gsd/gitignore.ts +1 -0
- package/dist/resources/extensions/gsd/marketplace-discovery.ts +507 -0
- package/dist/resources/extensions/gsd/mcp-server.ts +87 -0
- package/dist/resources/extensions/gsd/namespaced-registry.ts +467 -0
- package/dist/resources/extensions/gsd/namespaced-resolver.ts +307 -0
- package/dist/resources/extensions/gsd/plugin-importer.ts +410 -0
- package/dist/resources/extensions/gsd/preferences.ts +14 -3
- package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +71 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/system.md +12 -3
- package/dist/resources/extensions/gsd/roadmap-slices.ts +1 -1
- package/dist/resources/extensions/gsd/session-forensics.ts +5 -5
- package/dist/resources/extensions/gsd/tests/claude-import-tui.test.ts +351 -0
- package/dist/resources/extensions/gsd/tests/collision-diagnostics.test.ts +705 -0
- package/dist/resources/extensions/gsd/tests/context-compression.test.ts +13 -0
- package/dist/resources/extensions/gsd/tests/diff-context.test.ts +136 -0
- package/dist/resources/extensions/gsd/tests/doctor-git.test.ts +118 -0
- package/dist/resources/extensions/gsd/tests/marketplace-discovery.test.ts +202 -0
- package/dist/resources/extensions/gsd/tests/marketplace-test-fixtures.ts +91 -0
- package/dist/resources/extensions/gsd/tests/namespaced-registry.test.ts +1027 -0
- package/dist/resources/extensions/gsd/tests/namespaced-resolver.test.ts +671 -0
- package/dist/resources/extensions/gsd/tests/none-mode-gates.test.ts +105 -0
- package/dist/resources/extensions/gsd/tests/plugin-importer-live.test.ts +481 -0
- package/dist/resources/extensions/gsd/tests/plugin-importer.test.ts +1383 -0
- package/dist/resources/extensions/gsd/tests/preferences-git.test.ts +21 -2
- package/dist/resources/extensions/gsd/tests/preferences-schema-validation.test.ts +8 -1
- package/dist/resources/extensions/gsd/tests/visualizer-data.test.ts +11 -0
- package/dist/resources/extensions/gsd/tests/worktree-bugfix.test.ts +120 -0
- package/dist/resources/extensions/gsd/token-counter.ts +45 -0
- package/dist/resources/extensions/gsd/visualizer-data.ts +2 -2
- package/dist/resources/extensions/gsd/worktree-manager.ts +29 -1
- package/dist/resources/extensions/gsd/worktree.ts +3 -0
- package/dist/resources/extensions/mcporter/index.ts +90 -7
- package/dist/resources/extensions/search-the-web/native-search.ts +2 -0
- package/dist/resources/extensions/search-the-web/tool-fetch-page.ts +9 -1
- package/dist/resources/extensions/search-the-web/url-utils.ts +35 -1
- package/dist/resources/extensions/shared/terminal.ts +1 -1
- package/dist/resources/extensions/universal-config/discovery.ts +4 -0
- package/dist/resources/extensions/universal-config/format.ts +35 -4
- package/dist/resources/extensions/universal-config/index.ts +5 -3
- package/dist/resources/extensions/universal-config/scanners.ts +65 -2
- package/dist/resources/extensions/universal-config/tests/discovery.test.ts +9 -1
- package/dist/resources/extensions/universal-config/tests/format.test.ts +22 -6
- package/dist/resources/extensions/universal-config/tests/scanners.test.ts +18 -0
- package/dist/resources/extensions/universal-config/types.ts +20 -1
- package/dist/resources/skills/lint/SKILL.md +141 -0
- package/dist/resources/skills/review/SKILL.md +214 -0
- package/dist/resources/skills/test/SKILL.md +201 -0
- package/dist/tool-bootstrap.js +2 -1
- package/dist/wizard.js +2 -0
- package/package.json +12 -7
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js +12 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +12 -1
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +201 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +9 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +762 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +19 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +1 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +9 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +3 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +230 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +87 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +32 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +169 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +21 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +88 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +36 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +21 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +22 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +23 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +8 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +41 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +21 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +4 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +63 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +10 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +5 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +4 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +3 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +46 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +24 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +12 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +63 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +13 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +12 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +2 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +6 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +6 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +2 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +5 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +6 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +13 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +8 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +10 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +5 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +4 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +3 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +46 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +24 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +12 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +63 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +13 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +12 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +2 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +6 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +6 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +2 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +5 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +6 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +13 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +8 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +12 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +12 -0
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +68 -0
- package/packages/pi-ai/package.json +3 -0
- package/packages/pi-ai/pnpm-lock.yaml +2022 -0
- package/packages/pi-ai/src/providers/azure-openai-responses.ts +12 -1
- package/packages/pi-ai/src/providers/openai-responses.ts +12 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +12 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +113 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/project-trust.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/project-trust.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/project-trust.js +42 -0
- package/packages/pi-coding-agent/dist/core/extensions/project-trust.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js +18 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +114 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +8 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +23 -9
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +67 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/pnpm-lock.yaml +454 -0
- package/packages/pi-coding-agent/scripts/copy-assets.cjs +24 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +141 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +14 -1
- package/packages/pi-coding-agent/src/core/extensions/project-trust.ts +51 -0
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +132 -0
- package/packages/pi-coding-agent/src/core/resolve-config-value.ts +20 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +7 -2
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +98 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +24 -9
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +2 -2
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +3 -1
- package/packages/pi-tui/src/tui.ts +2 -2
- package/src/resources/agents/javascript-pro.md +280 -0
- package/src/resources/agents/typescript-pro.md +255 -0
- package/src/resources/extensions/bg-shell/index.ts +14 -2
- package/src/resources/extensions/bg-shell/utilities.ts +14 -0
- package/src/resources/extensions/browser-tools/{core.js → core.ts} +329 -190
- package/src/resources/extensions/gsd/auto-dashboard.ts +2 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +42 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +35 -2
- package/src/resources/extensions/gsd/auto.ts +116 -10
- package/src/resources/extensions/gsd/claude-import.ts +656 -0
- package/src/resources/extensions/gsd/collision-diagnostics.ts +332 -0
- package/src/resources/extensions/gsd/commands.ts +60 -7
- package/src/resources/extensions/gsd/diff-context.ts +220 -0
- package/src/resources/extensions/gsd/docs/claude-marketplace-import.md +214 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -1
- package/src/resources/extensions/gsd/doctor.ts +12 -4
- package/src/resources/extensions/gsd/file-watcher.ts +97 -0
- package/src/resources/extensions/gsd/files.ts +1 -1
- package/src/resources/extensions/gsd/forensics.ts +596 -0
- package/src/resources/extensions/gsd/git-service.ts +2 -1
- package/src/resources/extensions/gsd/github-client.ts +235 -0
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/marketplace-discovery.ts +507 -0
- package/src/resources/extensions/gsd/mcp-server.ts +87 -0
- package/src/resources/extensions/gsd/namespaced-registry.ts +467 -0
- package/src/resources/extensions/gsd/namespaced-resolver.ts +307 -0
- package/src/resources/extensions/gsd/plugin-importer.ts +410 -0
- package/src/resources/extensions/gsd/preferences.ts +14 -3
- package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +71 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/system.md +12 -3
- package/src/resources/extensions/gsd/roadmap-slices.ts +1 -1
- package/src/resources/extensions/gsd/session-forensics.ts +5 -5
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +351 -0
- package/src/resources/extensions/gsd/tests/collision-diagnostics.test.ts +705 -0
- package/src/resources/extensions/gsd/tests/context-compression.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/diff-context.test.ts +136 -0
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/marketplace-discovery.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/marketplace-test-fixtures.ts +91 -0
- package/src/resources/extensions/gsd/tests/namespaced-registry.test.ts +1027 -0
- package/src/resources/extensions/gsd/tests/namespaced-resolver.test.ts +671 -0
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/plugin-importer-live.test.ts +481 -0
- package/src/resources/extensions/gsd/tests/plugin-importer.test.ts +1383 -0
- package/src/resources/extensions/gsd/tests/preferences-git.test.ts +21 -2
- package/src/resources/extensions/gsd/tests/preferences-schema-validation.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +120 -0
- package/src/resources/extensions/gsd/token-counter.ts +45 -0
- package/src/resources/extensions/gsd/visualizer-data.ts +2 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +29 -1
- package/src/resources/extensions/gsd/worktree.ts +3 -0
- package/src/resources/extensions/mcporter/index.ts +90 -7
- package/src/resources/extensions/search-the-web/native-search.ts +2 -0
- package/src/resources/extensions/search-the-web/tool-fetch-page.ts +9 -1
- package/src/resources/extensions/search-the-web/url-utils.ts +35 -1
- package/src/resources/extensions/shared/terminal.ts +1 -1
- package/src/resources/extensions/universal-config/discovery.ts +4 -0
- package/src/resources/extensions/universal-config/format.ts +35 -4
- package/src/resources/extensions/universal-config/index.ts +5 -3
- package/src/resources/extensions/universal-config/scanners.ts +65 -2
- package/src/resources/extensions/universal-config/tests/discovery.test.ts +9 -1
- package/src/resources/extensions/universal-config/tests/format.test.ts +22 -6
- package/src/resources/extensions/universal-config/tests/scanners.test.ts +18 -0
- package/src/resources/extensions/universal-config/types.ts +20 -1
- package/src/resources/skills/lint/SKILL.md +141 -0
- package/src/resources/skills/review/SKILL.md +214 -0
- package/src/resources/skills/test/SKILL.md +201 -0
- package/dist/resources/extensions/browser-tools/core.d.ts +0 -205
- package/src/resources/extensions/browser-tools/core.d.ts +0 -205
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marketplace Discovery Module
|
|
3
|
+
*
|
|
4
|
+
* Reads marketplace.json from Claude marketplace repos, resolves plugin source paths,
|
|
5
|
+
* parses plugin.json manifests, and inventories available components (skills, agents, commands, MCP servers, LSP servers, hooks).
|
|
6
|
+
*
|
|
7
|
+
* Marketplace roots should reflect the Claude Code model documented by Anthropic:
|
|
8
|
+
* users add a marketplace source with `/plugin marketplace add ...`, Claude stores
|
|
9
|
+
* marketplace sources under `~/.claude/plugins/marketplaces/`, and installed plugin
|
|
10
|
+
* payloads are copied into `~/.claude/plugins/cache/`.
|
|
11
|
+
*
|
|
12
|
+
* Handles two marketplace catalog shapes observed in the wild:
|
|
13
|
+
* 1. jamie-style: marketplace.json has {name, source} entries; plugins have .claude-plugin/plugin.json
|
|
14
|
+
* 2. official-style: marketplace.json entries contain inline metadata
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import * as fs from 'node:fs';
|
|
18
|
+
import * as path from 'node:path';
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Type Definitions
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/** Owner information in marketplace manifest */
|
|
25
|
+
export interface MarketplaceOwner {
|
|
26
|
+
name: string;
|
|
27
|
+
email?: string;
|
|
28
|
+
url?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Marketplace metadata */
|
|
32
|
+
export interface MarketplaceMetadata {
|
|
33
|
+
description?: string;
|
|
34
|
+
version?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Source can be a relative path or a complex object (github, url, git-subdir) */
|
|
38
|
+
export type PluginSource = string | {
|
|
39
|
+
source?: string;
|
|
40
|
+
repo?: string;
|
|
41
|
+
url?: string;
|
|
42
|
+
path?: string;
|
|
43
|
+
sha?: string;
|
|
44
|
+
ref?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** Marketplace plugin entry - minimal info from marketplace.json */
|
|
48
|
+
export interface MarketplacePluginEntry {
|
|
49
|
+
name: string;
|
|
50
|
+
source: PluginSource;
|
|
51
|
+
// Optional inline metadata (official-style)
|
|
52
|
+
description?: string;
|
|
53
|
+
version?: string;
|
|
54
|
+
author?: MarketplaceOwner;
|
|
55
|
+
category?: string;
|
|
56
|
+
homepage?: string;
|
|
57
|
+
strict?: boolean;
|
|
58
|
+
mcpServers?: Record<string, unknown>;
|
|
59
|
+
lspServers?: Record<string, unknown>;
|
|
60
|
+
tags?: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Complete marketplace manifest */
|
|
64
|
+
export interface MarketplaceManifest {
|
|
65
|
+
$schema?: string;
|
|
66
|
+
name: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
owner?: MarketplaceOwner;
|
|
69
|
+
metadata?: MarketplaceMetadata;
|
|
70
|
+
plugins: MarketplacePluginEntry[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Plugin manifest from .claude-plugin/plugin.json */
|
|
74
|
+
export interface PluginManifest {
|
|
75
|
+
name: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
version?: string;
|
|
78
|
+
author?: MarketplaceOwner;
|
|
79
|
+
homepage?: string;
|
|
80
|
+
mcpServers?: Record<string, unknown>;
|
|
81
|
+
lspServers?: Record<string, unknown>;
|
|
82
|
+
// Additional fields that might be present
|
|
83
|
+
[key: string]: unknown;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Inventory of components in a plugin */
|
|
87
|
+
export interface PluginComponentInventory {
|
|
88
|
+
skills: string[];
|
|
89
|
+
agents: string[];
|
|
90
|
+
commands: string[];
|
|
91
|
+
mcpServers: Record<string, unknown>;
|
|
92
|
+
lspServers: Record<string, unknown>;
|
|
93
|
+
hooks?: string[];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Discovered plugin with all metadata and inventory */
|
|
97
|
+
export interface DiscoveredPlugin {
|
|
98
|
+
name: string;
|
|
99
|
+
canonicalName: string;
|
|
100
|
+
source: PluginSource;
|
|
101
|
+
resolvedPath: string | null;
|
|
102
|
+
status: 'ok' | 'error';
|
|
103
|
+
error?: string;
|
|
104
|
+
// Metadata sources
|
|
105
|
+
manifestSource: 'plugin.json' | 'marketplace-inline' | 'derived';
|
|
106
|
+
description?: string;
|
|
107
|
+
version?: string;
|
|
108
|
+
author?: MarketplaceOwner;
|
|
109
|
+
category?: string;
|
|
110
|
+
homepage?: string;
|
|
111
|
+
// Component inventory
|
|
112
|
+
inventory: PluginComponentInventory;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Result of marketplace discovery */
|
|
116
|
+
export interface MarketplaceDiscoveryResult {
|
|
117
|
+
status: 'ok' | 'error';
|
|
118
|
+
error?: string;
|
|
119
|
+
marketplacePath: string;
|
|
120
|
+
marketplaceName: string;
|
|
121
|
+
pluginFormat: 'jamie-style' | 'official-style' | 'unknown';
|
|
122
|
+
plugins: DiscoveredPlugin[];
|
|
123
|
+
summary: {
|
|
124
|
+
total: number;
|
|
125
|
+
ok: number;
|
|
126
|
+
error: number;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ============================================================================
|
|
131
|
+
// Helper Functions
|
|
132
|
+
// ============================================================================
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Check if a source path is a relative local path (not a URL or complex source)
|
|
136
|
+
*/
|
|
137
|
+
function isLocalSource(source: PluginSource): source is string {
|
|
138
|
+
if (typeof source === 'string') {
|
|
139
|
+
return !source.startsWith('http://') &&
|
|
140
|
+
!source.startsWith('https://') &&
|
|
141
|
+
!source.startsWith('git@') &&
|
|
142
|
+
!source.includes('://');
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Resolve a relative source path to an absolute directory path
|
|
149
|
+
*/
|
|
150
|
+
export function resolvePluginRoot(repoRoot: string, source: PluginSource): string | null {
|
|
151
|
+
if (!isLocalSource(source)) {
|
|
152
|
+
// External source (URL, git repo) - can't resolve locally
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Handle both ./plugins/name and plugins/name formats
|
|
157
|
+
let resolvedPath = source;
|
|
158
|
+
if (source.startsWith('./')) {
|
|
159
|
+
resolvedPath = source.slice(2);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const absolutePath = path.resolve(repoRoot, resolvedPath);
|
|
163
|
+
return absolutePath;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ============================================================================
|
|
167
|
+
// Core Functions
|
|
168
|
+
// ============================================================================
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Parse marketplace.json from a marketplace repository root
|
|
172
|
+
*
|
|
173
|
+
* @param repoRoot - Absolute path to the marketplace repository root
|
|
174
|
+
* @returns Parsed marketplace manifest or error
|
|
175
|
+
*/
|
|
176
|
+
export function parseMarketplaceJson(repoRoot: string):
|
|
177
|
+
| { success: true; manifest: MarketplaceManifest }
|
|
178
|
+
| { success: false; error: string } {
|
|
179
|
+
|
|
180
|
+
const marketplacePath = path.join(repoRoot, '.claude-plugin', 'marketplace.json');
|
|
181
|
+
|
|
182
|
+
// Check if file exists
|
|
183
|
+
if (!fs.existsSync(marketplacePath)) {
|
|
184
|
+
return {
|
|
185
|
+
success: false,
|
|
186
|
+
error: `marketplace.json not found at ${marketplacePath}`
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Read and parse JSON
|
|
191
|
+
let content: string;
|
|
192
|
+
try {
|
|
193
|
+
content = fs.readFileSync(marketplacePath, 'utf-8');
|
|
194
|
+
} catch (err) {
|
|
195
|
+
return {
|
|
196
|
+
success: false,
|
|
197
|
+
error: `Failed to read marketplace.json: ${err instanceof Error ? err.message : String(err)}`
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
let parsed: unknown;
|
|
202
|
+
try {
|
|
203
|
+
parsed = JSON.parse(content);
|
|
204
|
+
} catch (err) {
|
|
205
|
+
return {
|
|
206
|
+
success: false,
|
|
207
|
+
error: `Failed to parse marketplace.json: ${err instanceof Error ? err.message : String(err)}`
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Validate structure
|
|
212
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
213
|
+
return {
|
|
214
|
+
success: false,
|
|
215
|
+
error: 'marketplace.json is not a valid JSON object'
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const manifest = parsed as MarketplaceManifest;
|
|
220
|
+
|
|
221
|
+
if (!manifest.name) {
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
error: 'marketplace.json missing required field: name'
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!Array.isArray(manifest.plugins)) {
|
|
229
|
+
return {
|
|
230
|
+
success: false,
|
|
231
|
+
error: 'marketplace.json missing or invalid field: plugins (must be array)'
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return { success: true, manifest };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Inspect a plugin directory to extract metadata and inventory
|
|
240
|
+
*
|
|
241
|
+
* @param pluginDir - Absolute path to the plugin directory
|
|
242
|
+
* @param marketplaceEntry - Optional marketplace entry for inline metadata fallback
|
|
243
|
+
* @returns Discovered plugin information
|
|
244
|
+
*/
|
|
245
|
+
export function inspectPlugin(
|
|
246
|
+
pluginDir: string,
|
|
247
|
+
marketplaceEntry?: MarketplacePluginEntry
|
|
248
|
+
): DiscoveredPlugin {
|
|
249
|
+
const result: DiscoveredPlugin = {
|
|
250
|
+
name: marketplaceEntry?.name || path.basename(pluginDir),
|
|
251
|
+
canonicalName: marketplaceEntry?.name || path.basename(pluginDir),
|
|
252
|
+
source: marketplaceEntry?.source || './',
|
|
253
|
+
resolvedPath: pluginDir,
|
|
254
|
+
status: 'ok',
|
|
255
|
+
manifestSource: 'derived',
|
|
256
|
+
inventory: {
|
|
257
|
+
skills: [],
|
|
258
|
+
agents: [],
|
|
259
|
+
commands: [],
|
|
260
|
+
mcpServers: {},
|
|
261
|
+
lspServers: {},
|
|
262
|
+
hooks: []
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// Check if directory exists
|
|
267
|
+
if (!fs.existsSync(pluginDir)) {
|
|
268
|
+
result.status = 'error';
|
|
269
|
+
result.error = `Plugin directory not found: ${pluginDir}`;
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Try to read plugin.json from .claude-plugin/
|
|
274
|
+
const pluginJsonPath = path.join(pluginDir, '.claude-plugin', 'plugin.json');
|
|
275
|
+
|
|
276
|
+
if (fs.existsSync(pluginJsonPath)) {
|
|
277
|
+
try {
|
|
278
|
+
const content = fs.readFileSync(pluginJsonPath, 'utf-8');
|
|
279
|
+
const manifest = JSON.parse(content) as PluginManifest;
|
|
280
|
+
|
|
281
|
+
// Extract metadata from plugin.json
|
|
282
|
+
result.manifestSource = 'plugin.json';
|
|
283
|
+
result.description = manifest.description;
|
|
284
|
+
result.version = manifest.version;
|
|
285
|
+
result.author = manifest.author;
|
|
286
|
+
result.homepage = manifest.homepage;
|
|
287
|
+
|
|
288
|
+
if (manifest.mcpServers) {
|
|
289
|
+
result.inventory.mcpServers = manifest.mcpServers;
|
|
290
|
+
}
|
|
291
|
+
if (manifest.lspServers) {
|
|
292
|
+
result.inventory.lspServers = manifest.lspServers;
|
|
293
|
+
}
|
|
294
|
+
} catch (err) {
|
|
295
|
+
// Fall back to marketplace inline or derived
|
|
296
|
+
result.error = `Failed to parse plugin.json: ${err instanceof Error ? err.message : String(err)}`;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// If no plugin.json, use marketplace inline metadata
|
|
301
|
+
if (result.manifestSource === 'derived' && marketplaceEntry) {
|
|
302
|
+
result.manifestSource = 'marketplace-inline';
|
|
303
|
+
result.description = marketplaceEntry.description;
|
|
304
|
+
result.version = marketplaceEntry.version;
|
|
305
|
+
result.author = marketplaceEntry.author;
|
|
306
|
+
result.category = marketplaceEntry.category;
|
|
307
|
+
result.homepage = marketplaceEntry.homepage;
|
|
308
|
+
|
|
309
|
+
if (marketplaceEntry.mcpServers) {
|
|
310
|
+
result.inventory.mcpServers = marketplaceEntry.mcpServers;
|
|
311
|
+
}
|
|
312
|
+
if (marketplaceEntry.lspServers) {
|
|
313
|
+
result.inventory.lspServers = marketplaceEntry.lspServers;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Try to read plugin.json in root (alternative location)
|
|
318
|
+
const altPluginJsonPath = path.join(pluginDir, 'plugin.json');
|
|
319
|
+
if (fs.existsSync(altPluginJsonPath) && result.manifestSource === 'derived') {
|
|
320
|
+
try {
|
|
321
|
+
const content = fs.readFileSync(altPluginJsonPath, 'utf-8');
|
|
322
|
+
const manifest = JSON.parse(content) as PluginManifest;
|
|
323
|
+
|
|
324
|
+
result.manifestSource = 'plugin.json';
|
|
325
|
+
if (!result.description && manifest.description) {
|
|
326
|
+
result.description = manifest.description;
|
|
327
|
+
}
|
|
328
|
+
if (!result.version && manifest.version) {
|
|
329
|
+
result.version = manifest.version;
|
|
330
|
+
}
|
|
331
|
+
if (!result.author && manifest.author) {
|
|
332
|
+
result.author = manifest.author;
|
|
333
|
+
}
|
|
334
|
+
} catch {
|
|
335
|
+
// Ignore parse errors for alternative location
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Inventory component directories
|
|
340
|
+
const skillsDir = path.join(pluginDir, 'skills');
|
|
341
|
+
if (fs.existsSync(skillsDir) && fs.statSync(skillsDir).isDirectory()) {
|
|
342
|
+
try {
|
|
343
|
+
result.inventory.skills = fs.readdirSync(skillsDir)
|
|
344
|
+
.filter(item => {
|
|
345
|
+
const itemPath = path.join(skillsDir, item);
|
|
346
|
+
return fs.statSync(itemPath).isDirectory() || item.endsWith('.md');
|
|
347
|
+
});
|
|
348
|
+
} catch {
|
|
349
|
+
// Ignore read errors
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const agentsDir = path.join(pluginDir, 'agents');
|
|
354
|
+
if (fs.existsSync(agentsDir) && fs.statSync(agentsDir).isDirectory()) {
|
|
355
|
+
try {
|
|
356
|
+
result.inventory.agents = fs.readdirSync(agentsDir)
|
|
357
|
+
.filter(item => {
|
|
358
|
+
const itemPath = path.join(agentsDir, item);
|
|
359
|
+
return fs.statSync(itemPath).isDirectory() || item.endsWith('.md');
|
|
360
|
+
});
|
|
361
|
+
} catch {
|
|
362
|
+
// Ignore read errors
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const commandsDir = path.join(pluginDir, 'commands');
|
|
367
|
+
if (fs.existsSync(commandsDir) && fs.statSync(commandsDir).isDirectory()) {
|
|
368
|
+
try {
|
|
369
|
+
result.inventory.commands = fs.readdirSync(commandsDir)
|
|
370
|
+
.filter(item => {
|
|
371
|
+
const itemPath = path.join(commandsDir, item);
|
|
372
|
+
return fs.statSync(itemPath).isDirectory() || item.endsWith('.md');
|
|
373
|
+
});
|
|
374
|
+
} catch {
|
|
375
|
+
// Ignore read errors
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Also check for hooks at root level (jamie-style uses 'hooks/', not '.claude-plugin/hooks')
|
|
380
|
+
const rootHooksDir = path.join(pluginDir, 'hooks');
|
|
381
|
+
if (fs.existsSync(rootHooksDir) && fs.statSync(rootHooksDir).isDirectory()) {
|
|
382
|
+
try {
|
|
383
|
+
const rootHooks = fs.readdirSync(rootHooksDir)
|
|
384
|
+
.filter(item => {
|
|
385
|
+
const itemPath = path.join(rootHooksDir, item);
|
|
386
|
+
return fs.statSync(itemPath).isDirectory() || item.endsWith('.md') || item.endsWith('.json');
|
|
387
|
+
});
|
|
388
|
+
const mergedHooks = [...(result.inventory.hooks || []), ...rootHooks];
|
|
389
|
+
result.inventory.hooks = Array.from(new Set(mergedHooks));
|
|
390
|
+
} catch {
|
|
391
|
+
// Ignore read errors
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// Also check .claude-plugin/hooks (official-style)
|
|
396
|
+
const hooksDir = path.join(pluginDir, '.claude-plugin', 'hooks');
|
|
397
|
+
if (fs.existsSync(hooksDir) && fs.statSync(hooksDir).isDirectory()) {
|
|
398
|
+
try {
|
|
399
|
+
const pluginHooks = fs.readdirSync(hooksDir)
|
|
400
|
+
.filter(item => {
|
|
401
|
+
const itemPath = path.join(hooksDir, item);
|
|
402
|
+
return fs.statSync(itemPath).isDirectory() || item.endsWith('.md');
|
|
403
|
+
});
|
|
404
|
+
const mergedHooks = [...(result.inventory.hooks || []), ...pluginHooks];
|
|
405
|
+
result.inventory.hooks = Array.from(new Set(mergedHooks));
|
|
406
|
+
} catch {
|
|
407
|
+
// Ignore read errors
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return result;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Discover all plugins in a marketplace repository
|
|
416
|
+
*
|
|
417
|
+
* @param repoRoot - Absolute or relative path to the marketplace repository
|
|
418
|
+
* @returns Marketplace discovery result with all plugins
|
|
419
|
+
*/
|
|
420
|
+
export function discoverMarketplace(repoRoot: string): MarketplaceDiscoveryResult {
|
|
421
|
+
// Resolve to absolute path
|
|
422
|
+
const absoluteRepoRoot = path.resolve(repoRoot);
|
|
423
|
+
|
|
424
|
+
// Parse marketplace.json
|
|
425
|
+
const parseResult = parseMarketplaceJson(absoluteRepoRoot);
|
|
426
|
+
|
|
427
|
+
if (parseResult.success === false) {
|
|
428
|
+
return {
|
|
429
|
+
status: 'error',
|
|
430
|
+
error: parseResult.error,
|
|
431
|
+
marketplacePath: path.join(absoluteRepoRoot, '.claude-plugin', 'marketplace.json'),
|
|
432
|
+
marketplaceName: path.basename(absoluteRepoRoot),
|
|
433
|
+
pluginFormat: 'unknown',
|
|
434
|
+
plugins: [],
|
|
435
|
+
summary: { total: 0, ok: 0, error: 0 }
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const manifest = parseResult.manifest;
|
|
440
|
+
|
|
441
|
+
// Determine plugin format based on structure
|
|
442
|
+
const pluginFormat: 'jamie-style' | 'official-style' | 'unknown' =
|
|
443
|
+
manifest.plugins.every(p => p.source && !p.description && !p.version && !p.lspServers)
|
|
444
|
+
? 'jamie-style'
|
|
445
|
+
: manifest.plugins.every(p => p.source && (p.description || p.version || p.lspServers))
|
|
446
|
+
? 'official-style'
|
|
447
|
+
: 'unknown';
|
|
448
|
+
|
|
449
|
+
// Discover each plugin
|
|
450
|
+
const plugins: DiscoveredPlugin[] = manifest.plugins.map(entry => {
|
|
451
|
+
const resolvedPath = resolvePluginRoot(absoluteRepoRoot, entry.source);
|
|
452
|
+
|
|
453
|
+
if (!resolvedPath) {
|
|
454
|
+
// External source - can't resolve locally
|
|
455
|
+
return {
|
|
456
|
+
name: entry.name,
|
|
457
|
+
canonicalName: entry.name,
|
|
458
|
+
source: entry.source,
|
|
459
|
+
resolvedPath: null,
|
|
460
|
+
status: 'ok',
|
|
461
|
+
manifestSource: 'marketplace-inline',
|
|
462
|
+
description: entry.description,
|
|
463
|
+
version: entry.version,
|
|
464
|
+
author: entry.author,
|
|
465
|
+
category: entry.category,
|
|
466
|
+
homepage: entry.homepage,
|
|
467
|
+
inventory: {
|
|
468
|
+
skills: [],
|
|
469
|
+
agents: [],
|
|
470
|
+
commands: [],
|
|
471
|
+
mcpServers: entry.mcpServers || {},
|
|
472
|
+
lspServers: entry.lspServers || {},
|
|
473
|
+
hooks: []
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return inspectPlugin(resolvedPath, entry);
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// Calculate summary
|
|
482
|
+
const summary = {
|
|
483
|
+
total: plugins.length,
|
|
484
|
+
ok: plugins.filter(p => p.status === 'ok').length,
|
|
485
|
+
error: plugins.filter(p => p.status === 'error').length
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
return {
|
|
489
|
+
status: summary.error > 0 ? 'error' : 'ok',
|
|
490
|
+
marketplacePath: path.join(absoluteRepoRoot, '.claude-plugin', 'marketplace.json'),
|
|
491
|
+
marketplaceName: manifest.name,
|
|
492
|
+
pluginFormat,
|
|
493
|
+
plugins,
|
|
494
|
+
summary
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// ============================================================================
|
|
499
|
+
// Export all types and functions
|
|
500
|
+
// ============================================================================
|
|
501
|
+
|
|
502
|
+
export default {
|
|
503
|
+
parseMarketplaceJson,
|
|
504
|
+
inspectPlugin,
|
|
505
|
+
discoverMarketplace,
|
|
506
|
+
resolvePluginRoot
|
|
507
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// @ts-ignore — @modelcontextprotocol/sdk types may not be in extensions tsconfig
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server'
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio'
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types'
|
|
7
|
+
|
|
8
|
+
interface McpTool {
|
|
9
|
+
name: string
|
|
10
|
+
description: string
|
|
11
|
+
parameters: Record<string, unknown>
|
|
12
|
+
execute(toolCallId: string, params: Record<string, unknown>, signal?: AbortSignal, onUpdate?: unknown): Promise<{ content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> }>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function startMcpServer(options: {
|
|
16
|
+
tools: McpTool[]
|
|
17
|
+
version?: string
|
|
18
|
+
}): Promise<void> {
|
|
19
|
+
const { tools, version = '0.0.0' } = options
|
|
20
|
+
|
|
21
|
+
const toolMap = new Map<string, McpTool>()
|
|
22
|
+
for (const tool of tools) {
|
|
23
|
+
toolMap.set(tool.name, tool)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const server = new Server(
|
|
27
|
+
{ name: 'gsd', version },
|
|
28
|
+
{ capabilities: { tools: {} } },
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
32
|
+
return {
|
|
33
|
+
tools: tools.map((t) => ({
|
|
34
|
+
name: t.name,
|
|
35
|
+
description: t.description,
|
|
36
|
+
inputSchema: t.parameters,
|
|
37
|
+
})),
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
server.setRequestHandler(CallToolRequestSchema, async (request: any) => {
|
|
42
|
+
const { name, arguments: args } = request.params
|
|
43
|
+
const tool = toolMap.get(name)
|
|
44
|
+
if (!tool) {
|
|
45
|
+
return {
|
|
46
|
+
isError: true,
|
|
47
|
+
content: [{ type: 'text' as const, text: `Unknown tool: ${name}` }],
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const result = await tool.execute(
|
|
53
|
+
`mcp-${Date.now()}`,
|
|
54
|
+
args ?? {},
|
|
55
|
+
undefined,
|
|
56
|
+
undefined,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const content = result.content.map((block) => {
|
|
60
|
+
if (block.type === 'text') {
|
|
61
|
+
return { type: 'text' as const, text: block.text }
|
|
62
|
+
}
|
|
63
|
+
if (block.type === 'image') {
|
|
64
|
+
return {
|
|
65
|
+
type: 'image' as const,
|
|
66
|
+
data: block.data,
|
|
67
|
+
mimeType: block.mimeType,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { type: 'text' as const, text: JSON.stringify(block) }
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
return { content }
|
|
74
|
+
} catch (err: unknown) {
|
|
75
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
76
|
+
return {
|
|
77
|
+
isError: true,
|
|
78
|
+
content: [{ type: 'text' as const, text: message }],
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const transport = new StdioServerTransport()
|
|
84
|
+
await server.connect(transport)
|
|
85
|
+
|
|
86
|
+
process.stderr.write(`[gsd] MCP server started (v${version})\n`)
|
|
87
|
+
}
|