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.
Files changed (279) hide show
  1. package/README.md +12 -0
  2. package/dist/cli.js +21 -18
  3. package/dist/help-text.d.ts +2 -0
  4. package/dist/help-text.js +47 -0
  5. package/dist/loader.js +2 -16
  6. package/dist/mcp-server.d.ts +18 -0
  7. package/dist/mcp-server.js +53 -0
  8. package/dist/onboarding.d.ts +0 -6
  9. package/dist/onboarding.js +0 -28
  10. package/dist/resources/agents/javascript-pro.md +280 -0
  11. package/dist/resources/agents/typescript-pro.md +255 -0
  12. package/dist/resources/extensions/bg-shell/index.ts +14 -2
  13. package/dist/resources/extensions/bg-shell/utilities.ts +14 -0
  14. package/dist/resources/extensions/browser-tools/{core.js → core.ts} +329 -190
  15. package/dist/resources/extensions/gsd/auto-dashboard.ts +2 -1
  16. package/dist/resources/extensions/gsd/auto-prompts.ts +42 -1
  17. package/dist/resources/extensions/gsd/auto-worktree.ts +35 -2
  18. package/dist/resources/extensions/gsd/auto.ts +116 -10
  19. package/dist/resources/extensions/gsd/claude-import.ts +656 -0
  20. package/dist/resources/extensions/gsd/collision-diagnostics.ts +332 -0
  21. package/dist/resources/extensions/gsd/commands.ts +60 -7
  22. package/dist/resources/extensions/gsd/diff-context.ts +220 -0
  23. package/dist/resources/extensions/gsd/docs/claude-marketplace-import.md +214 -0
  24. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -1
  25. package/dist/resources/extensions/gsd/doctor.ts +12 -4
  26. package/dist/resources/extensions/gsd/file-watcher.ts +97 -0
  27. package/dist/resources/extensions/gsd/files.ts +1 -1
  28. package/dist/resources/extensions/gsd/forensics.ts +596 -0
  29. package/dist/resources/extensions/gsd/git-service.ts +2 -1
  30. package/dist/resources/extensions/gsd/github-client.ts +235 -0
  31. package/dist/resources/extensions/gsd/gitignore.ts +1 -0
  32. package/dist/resources/extensions/gsd/marketplace-discovery.ts +507 -0
  33. package/dist/resources/extensions/gsd/mcp-server.ts +87 -0
  34. package/dist/resources/extensions/gsd/namespaced-registry.ts +467 -0
  35. package/dist/resources/extensions/gsd/namespaced-resolver.ts +307 -0
  36. package/dist/resources/extensions/gsd/plugin-importer.ts +410 -0
  37. package/dist/resources/extensions/gsd/preferences.ts +14 -3
  38. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  39. package/dist/resources/extensions/gsd/prompts/forensics.md +71 -0
  40. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  41. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  42. package/dist/resources/extensions/gsd/prompts/system.md +12 -3
  43. package/dist/resources/extensions/gsd/roadmap-slices.ts +1 -1
  44. package/dist/resources/extensions/gsd/session-forensics.ts +5 -5
  45. package/dist/resources/extensions/gsd/tests/claude-import-tui.test.ts +351 -0
  46. package/dist/resources/extensions/gsd/tests/collision-diagnostics.test.ts +705 -0
  47. package/dist/resources/extensions/gsd/tests/context-compression.test.ts +13 -0
  48. package/dist/resources/extensions/gsd/tests/diff-context.test.ts +136 -0
  49. package/dist/resources/extensions/gsd/tests/doctor-git.test.ts +118 -0
  50. package/dist/resources/extensions/gsd/tests/marketplace-discovery.test.ts +202 -0
  51. package/dist/resources/extensions/gsd/tests/marketplace-test-fixtures.ts +91 -0
  52. package/dist/resources/extensions/gsd/tests/namespaced-registry.test.ts +1027 -0
  53. package/dist/resources/extensions/gsd/tests/namespaced-resolver.test.ts +671 -0
  54. package/dist/resources/extensions/gsd/tests/none-mode-gates.test.ts +105 -0
  55. package/dist/resources/extensions/gsd/tests/plugin-importer-live.test.ts +481 -0
  56. package/dist/resources/extensions/gsd/tests/plugin-importer.test.ts +1383 -0
  57. package/dist/resources/extensions/gsd/tests/preferences-git.test.ts +21 -2
  58. package/dist/resources/extensions/gsd/tests/preferences-schema-validation.test.ts +8 -1
  59. package/dist/resources/extensions/gsd/tests/visualizer-data.test.ts +11 -0
  60. package/dist/resources/extensions/gsd/tests/worktree-bugfix.test.ts +120 -0
  61. package/dist/resources/extensions/gsd/token-counter.ts +45 -0
  62. package/dist/resources/extensions/gsd/visualizer-data.ts +2 -2
  63. package/dist/resources/extensions/gsd/worktree-manager.ts +29 -1
  64. package/dist/resources/extensions/gsd/worktree.ts +3 -0
  65. package/dist/resources/extensions/mcporter/index.ts +90 -7
  66. package/dist/resources/extensions/search-the-web/native-search.ts +2 -0
  67. package/dist/resources/extensions/search-the-web/tool-fetch-page.ts +9 -1
  68. package/dist/resources/extensions/search-the-web/url-utils.ts +35 -1
  69. package/dist/resources/extensions/shared/terminal.ts +1 -1
  70. package/dist/resources/extensions/universal-config/discovery.ts +4 -0
  71. package/dist/resources/extensions/universal-config/format.ts +35 -4
  72. package/dist/resources/extensions/universal-config/index.ts +5 -3
  73. package/dist/resources/extensions/universal-config/scanners.ts +65 -2
  74. package/dist/resources/extensions/universal-config/tests/discovery.test.ts +9 -1
  75. package/dist/resources/extensions/universal-config/tests/format.test.ts +22 -6
  76. package/dist/resources/extensions/universal-config/tests/scanners.test.ts +18 -0
  77. package/dist/resources/extensions/universal-config/types.ts +20 -1
  78. package/dist/resources/skills/lint/SKILL.md +141 -0
  79. package/dist/resources/skills/review/SKILL.md +214 -0
  80. package/dist/resources/skills/test/SKILL.md +201 -0
  81. package/dist/tool-bootstrap.js +2 -1
  82. package/dist/wizard.js +2 -0
  83. package/package.json +12 -7
  84. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  85. package/packages/pi-ai/dist/providers/azure-openai-responses.js +12 -1
  86. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  87. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  88. package/packages/pi-ai/dist/providers/openai-responses.js +12 -1
  89. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  90. package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +201 -0
  91. package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +9 -0
  92. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +762 -0
  93. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +19 -0
  94. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +1 -0
  95. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +9 -0
  96. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +3 -0
  97. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +230 -0
  98. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +87 -0
  99. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +32 -0
  100. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +169 -0
  101. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +21 -0
  102. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +88 -0
  103. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +36 -0
  104. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +21 -0
  105. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +22 -0
  106. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +23 -0
  107. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +8 -0
  108. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +41 -0
  109. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +21 -0
  110. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +4 -0
  111. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +63 -0
  112. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +10 -0
  113. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +5 -0
  114. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +4 -0
  115. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +3 -0
  116. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +46 -0
  117. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +24 -0
  118. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +12 -0
  119. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +63 -0
  120. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +13 -0
  121. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +12 -0
  122. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +2 -0
  123. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +6 -0
  124. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +6 -0
  125. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +2 -0
  126. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +5 -0
  127. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +6 -0
  128. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +13 -0
  129. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +8 -0
  130. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +10 -0
  131. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +5 -0
  132. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +4 -0
  133. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +3 -0
  134. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +46 -0
  135. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +24 -0
  136. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +12 -0
  137. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +63 -0
  138. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +13 -0
  139. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +12 -0
  140. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +2 -0
  141. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +6 -0
  142. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +6 -0
  143. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +2 -0
  144. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +5 -0
  145. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +6 -0
  146. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +13 -0
  147. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +8 -0
  148. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +12 -0
  149. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +12 -0
  150. package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +68 -0
  151. package/packages/pi-ai/package.json +3 -0
  152. package/packages/pi-ai/pnpm-lock.yaml +2022 -0
  153. package/packages/pi-ai/src/providers/azure-openai-responses.ts +12 -1
  154. package/packages/pi-ai/src/providers/openai-responses.ts +12 -1
  155. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  156. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  158. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  159. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +1 -0
  160. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  161. package/packages/pi-coding-agent/dist/core/extensions/loader.js +12 -1
  162. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/extensions/loader.test.d.ts +2 -0
  164. package/packages/pi-coding-agent/dist/core/extensions/loader.test.d.ts.map +1 -0
  165. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +113 -0
  166. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -0
  167. package/packages/pi-coding-agent/dist/core/extensions/project-trust.d.ts +4 -0
  168. package/packages/pi-coding-agent/dist/core/extensions/project-trust.d.ts.map +1 -0
  169. package/packages/pi-coding-agent/dist/core/extensions/project-trust.js +42 -0
  170. package/packages/pi-coding-agent/dist/core/extensions/project-trust.js.map +1 -0
  171. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts +1 -0
  172. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/resolve-config-value.js +18 -0
  174. package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.d.ts +2 -0
  176. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.d.ts.map +1 -0
  177. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +114 -0
  178. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -0
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  180. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +8 -2
  181. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  182. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts +2 -0
  183. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  184. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +23 -9
  185. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.d.ts +2 -0
  187. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.d.ts.map +1 -0
  188. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +67 -0
  189. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -0
  190. package/packages/pi-coding-agent/package.json +1 -1
  191. package/packages/pi-coding-agent/pnpm-lock.yaml +454 -0
  192. package/packages/pi-coding-agent/scripts/copy-assets.cjs +24 -0
  193. package/packages/pi-coding-agent/src/core/extensions/index.ts +3 -0
  194. package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +141 -0
  195. package/packages/pi-coding-agent/src/core/extensions/loader.ts +14 -1
  196. package/packages/pi-coding-agent/src/core/extensions/project-trust.ts +51 -0
  197. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +132 -0
  198. package/packages/pi-coding-agent/src/core/resolve-config-value.ts +20 -0
  199. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +7 -2
  200. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +98 -0
  201. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +24 -9
  202. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  203. package/packages/pi-tui/dist/tui.js +2 -2
  204. package/packages/pi-tui/dist/tui.js.map +1 -1
  205. package/packages/pi-tui/package.json +3 -1
  206. package/packages/pi-tui/src/tui.ts +2 -2
  207. package/src/resources/agents/javascript-pro.md +280 -0
  208. package/src/resources/agents/typescript-pro.md +255 -0
  209. package/src/resources/extensions/bg-shell/index.ts +14 -2
  210. package/src/resources/extensions/bg-shell/utilities.ts +14 -0
  211. package/src/resources/extensions/browser-tools/{core.js → core.ts} +329 -190
  212. package/src/resources/extensions/gsd/auto-dashboard.ts +2 -1
  213. package/src/resources/extensions/gsd/auto-prompts.ts +42 -1
  214. package/src/resources/extensions/gsd/auto-worktree.ts +35 -2
  215. package/src/resources/extensions/gsd/auto.ts +116 -10
  216. package/src/resources/extensions/gsd/claude-import.ts +656 -0
  217. package/src/resources/extensions/gsd/collision-diagnostics.ts +332 -0
  218. package/src/resources/extensions/gsd/commands.ts +60 -7
  219. package/src/resources/extensions/gsd/diff-context.ts +220 -0
  220. package/src/resources/extensions/gsd/docs/claude-marketplace-import.md +214 -0
  221. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -1
  222. package/src/resources/extensions/gsd/doctor.ts +12 -4
  223. package/src/resources/extensions/gsd/file-watcher.ts +97 -0
  224. package/src/resources/extensions/gsd/files.ts +1 -1
  225. package/src/resources/extensions/gsd/forensics.ts +596 -0
  226. package/src/resources/extensions/gsd/git-service.ts +2 -1
  227. package/src/resources/extensions/gsd/github-client.ts +235 -0
  228. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  229. package/src/resources/extensions/gsd/marketplace-discovery.ts +507 -0
  230. package/src/resources/extensions/gsd/mcp-server.ts +87 -0
  231. package/src/resources/extensions/gsd/namespaced-registry.ts +467 -0
  232. package/src/resources/extensions/gsd/namespaced-resolver.ts +307 -0
  233. package/src/resources/extensions/gsd/plugin-importer.ts +410 -0
  234. package/src/resources/extensions/gsd/preferences.ts +14 -3
  235. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  236. package/src/resources/extensions/gsd/prompts/forensics.md +71 -0
  237. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  238. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  239. package/src/resources/extensions/gsd/prompts/system.md +12 -3
  240. package/src/resources/extensions/gsd/roadmap-slices.ts +1 -1
  241. package/src/resources/extensions/gsd/session-forensics.ts +5 -5
  242. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +351 -0
  243. package/src/resources/extensions/gsd/tests/collision-diagnostics.test.ts +705 -0
  244. package/src/resources/extensions/gsd/tests/context-compression.test.ts +13 -0
  245. package/src/resources/extensions/gsd/tests/diff-context.test.ts +136 -0
  246. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +118 -0
  247. package/src/resources/extensions/gsd/tests/marketplace-discovery.test.ts +202 -0
  248. package/src/resources/extensions/gsd/tests/marketplace-test-fixtures.ts +91 -0
  249. package/src/resources/extensions/gsd/tests/namespaced-registry.test.ts +1027 -0
  250. package/src/resources/extensions/gsd/tests/namespaced-resolver.test.ts +671 -0
  251. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +105 -0
  252. package/src/resources/extensions/gsd/tests/plugin-importer-live.test.ts +481 -0
  253. package/src/resources/extensions/gsd/tests/plugin-importer.test.ts +1383 -0
  254. package/src/resources/extensions/gsd/tests/preferences-git.test.ts +21 -2
  255. package/src/resources/extensions/gsd/tests/preferences-schema-validation.test.ts +8 -1
  256. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +11 -0
  257. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +120 -0
  258. package/src/resources/extensions/gsd/token-counter.ts +45 -0
  259. package/src/resources/extensions/gsd/visualizer-data.ts +2 -2
  260. package/src/resources/extensions/gsd/worktree-manager.ts +29 -1
  261. package/src/resources/extensions/gsd/worktree.ts +3 -0
  262. package/src/resources/extensions/mcporter/index.ts +90 -7
  263. package/src/resources/extensions/search-the-web/native-search.ts +2 -0
  264. package/src/resources/extensions/search-the-web/tool-fetch-page.ts +9 -1
  265. package/src/resources/extensions/search-the-web/url-utils.ts +35 -1
  266. package/src/resources/extensions/shared/terminal.ts +1 -1
  267. package/src/resources/extensions/universal-config/discovery.ts +4 -0
  268. package/src/resources/extensions/universal-config/format.ts +35 -4
  269. package/src/resources/extensions/universal-config/index.ts +5 -3
  270. package/src/resources/extensions/universal-config/scanners.ts +65 -2
  271. package/src/resources/extensions/universal-config/tests/discovery.test.ts +9 -1
  272. package/src/resources/extensions/universal-config/tests/format.test.ts +22 -6
  273. package/src/resources/extensions/universal-config/tests/scanners.test.ts +18 -0
  274. package/src/resources/extensions/universal-config/types.ts +20 -1
  275. package/src/resources/skills/lint/SKILL.md +141 -0
  276. package/src/resources/skills/review/SKILL.md +214 -0
  277. package/src/resources/skills/test/SKILL.md +201 -0
  278. package/dist/resources/extensions/browser-tools/core.d.ts +0 -205
  279. package/src/resources/extensions/browser-tools/core.d.ts +0 -205
@@ -0,0 +1,467 @@
1
+ /**
2
+ * Namespaced Component Registry Module
3
+ *
4
+ * Provides the canonical identity model for imported plugin components.
5
+ * Supports both namespaced (plugin:component) and flat (bare name) components,
6
+ * detects collisions at registration time, and provides lookup by canonical name
7
+ * or namespace listing.
8
+ *
9
+ * This registry serves as the bridge between S01's plugin discovery output
10
+ * and Pi's internal component resolution system.
11
+ */
12
+
13
+ import type { DiscoveredPlugin } from './marketplace-discovery.js';
14
+
15
+ // ============================================================================
16
+ // Type Definitions
17
+ // ============================================================================
18
+
19
+ /**
20
+ * Component type enumeration.
21
+ * Matches the component categories discovered by S01.
22
+ */
23
+ export type ComponentType = 'skill' | 'agent';
24
+
25
+ /**
26
+ * A component entry in the namespaced registry.
27
+ *
28
+ * Components can be:
29
+ * - Namespaced: `${namespace}:${name}` (e.g., "my-plugin:code-review")
30
+ * - Flat: `${name}` (e.g., "code-review" for backward compatibility)
31
+ */
32
+ export interface NamespacedComponent {
33
+ /** The component's local name (e.g., "code-review") */
34
+ name: string;
35
+
36
+ /** The plugin namespace (e.g., "my-plugin"). Undefined for flat components. */
37
+ namespace: string | undefined;
38
+
39
+ /** The computed canonical identifier: `${namespace}:${name}` or bare `name` */
40
+ canonicalName: string;
41
+
42
+ /** Component type: skill or agent */
43
+ type: ComponentType;
44
+
45
+ /** Absolute path to the component's definition file */
46
+ filePath: string;
47
+
48
+ /** Source identifier (e.g., "plugin:my-plugin", "user", "project") */
49
+ source: string;
50
+
51
+ /** Optional description from the component's frontmatter */
52
+ description: string | undefined;
53
+
54
+ /** Extensible metadata bag for plugin origin info */
55
+ metadata: {
56
+ /** Plugin version if available */
57
+ pluginVersion?: string;
58
+ /** Plugin author if available */
59
+ pluginAuthor?: string;
60
+ /** Plugin homepage if available */
61
+ pluginHomepage?: string;
62
+ /** Plugin category if available */
63
+ pluginCategory?: string;
64
+ /** Original component directory name */
65
+ componentDir?: string;
66
+ /** Additional plugin-specific metadata */
67
+ [key: string]: unknown;
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Collision information for registry diagnostics.
73
+ * Mirrors the ResourceCollision pattern from pi-coding-agent.
74
+ */
75
+ export interface RegistryCollision {
76
+ /** The canonical name that collided (e.g., "my-plugin:code-review") */
77
+ canonicalName: string;
78
+
79
+ /** Path to the component that won (first registered) */
80
+ winnerPath: string;
81
+
82
+ /** Path to the component that lost (subsequent duplicate) */
83
+ loserPath: string;
84
+
85
+ /** Source of the winning component */
86
+ winnerSource?: string;
87
+
88
+ /** Source of the losing component */
89
+ loserSource?: string;
90
+ }
91
+
92
+ /**
93
+ * Diagnostic entry for registry operations.
94
+ * Currently only reports collisions, but extensible for future diagnostics.
95
+ */
96
+ export interface RegistryDiagnostic {
97
+ /** Diagnostic type */
98
+ type: 'collision';
99
+
100
+ /** Human-readable message */
101
+ message: string;
102
+
103
+ /** Collision details */
104
+ collision: RegistryCollision;
105
+ }
106
+
107
+ /**
108
+ * Result of an alias registration attempt.
109
+ * Successful registrations return success: true.
110
+ * Failed registrations return success: false with a reason.
111
+ */
112
+ export interface AliasRegistrationResult {
113
+ /** Whether the registration succeeded */
114
+ success: boolean;
115
+
116
+ /** On failure, the reason for rejection */
117
+ reason?: 'canonical-not-found' | 'shadows-canonical' | 'duplicate-alias';
118
+
119
+ /** Human-readable message */
120
+ message?: string;
121
+ }
122
+
123
+ // ============================================================================
124
+ // NamespacedRegistry Class
125
+ // ============================================================================
126
+
127
+ /**
128
+ * Registry for namespaced plugin components.
129
+ *
130
+ * Features:
131
+ * - Computes canonical names from namespace + name
132
+ * - Detects and reports collisions at registration time
133
+ * - First registration wins; subsequent duplicates return diagnostic
134
+ * - Lookup by canonical name or namespace listing
135
+ * - Compatible with both namespaced and flat (non-namespaced) components
136
+ *
137
+ * Usage:
138
+ * ```typescript
139
+ * const registry = new NamespacedRegistry();
140
+ *
141
+ * // Register a namespaced component
142
+ * const diag = registry.register({
143
+ * name: 'code-review',
144
+ * namespace: 'my-plugin',
145
+ * type: 'skill',
146
+ * filePath: '/plugins/my-plugin/skills/code-review/SKILL.md',
147
+ * source: 'plugin:my-plugin',
148
+ * description: 'Reviews code for quality issues',
149
+ * metadata: { pluginVersion: '1.0.0' }
150
+ * });
151
+ *
152
+ * // Lookup by canonical name
153
+ * const skill = registry.getByCanonical('my-plugin:code-review');
154
+ *
155
+ * // List all components in a namespace
156
+ * const allSkills = registry.getByNamespace('my-plugin');
157
+ * ```
158
+ */
159
+ export class NamespacedRegistry {
160
+ /** Internal storage: canonicalName -> component */
161
+ private components = new Map<string, NamespacedComponent>();
162
+
163
+ /** Internal storage: alias -> canonicalName */
164
+ private aliasMap = new Map<string, string>();
165
+
166
+ /** Collision diagnostics collected during registration */
167
+ private diagnostics: RegistryDiagnostic[] = [];
168
+
169
+ /**
170
+ * Register a component in the registry.
171
+ *
172
+ * Computes the canonical name as `${namespace}:${name}` when namespace is present,
173
+ * or bare `name` otherwise. Returns a diagnostic if the canonical name already exists.
174
+ *
175
+ * @param component - Component data (without canonicalName, which is computed)
176
+ * @returns Diagnostic if collision detected, undefined otherwise
177
+ */
178
+ register(component: Omit<NamespacedComponent, 'canonicalName'>): RegistryDiagnostic | undefined {
179
+ // Compute canonical name
180
+ const canonicalName = component.namespace
181
+ ? `${component.namespace}:${component.name}`
182
+ : component.name;
183
+
184
+ // Create full component with canonical name
185
+ const fullComponent: NamespacedComponent = {
186
+ ...component,
187
+ canonicalName,
188
+ };
189
+
190
+ // Check for collision
191
+ const existing = this.components.get(canonicalName);
192
+ if (existing) {
193
+ const diagnostic: RegistryDiagnostic = {
194
+ type: 'collision',
195
+ message: `canonical name "${canonicalName}" collision`,
196
+ collision: {
197
+ canonicalName,
198
+ winnerPath: existing.filePath,
199
+ loserPath: component.filePath,
200
+ winnerSource: existing.source,
201
+ loserSource: component.source,
202
+ },
203
+ };
204
+ this.diagnostics.push(diagnostic);
205
+ return diagnostic;
206
+ }
207
+
208
+ // Register the component
209
+ this.components.set(canonicalName, fullComponent);
210
+ return undefined;
211
+ }
212
+
213
+ /**
214
+ * Get a component by its canonical name.
215
+ *
216
+ * @param canonicalName - The canonical name (e.g., "my-plugin:code-review" or "code-review")
217
+ * @returns The component if found, undefined otherwise
218
+ */
219
+ getByCanonical(canonicalName: string): NamespacedComponent | undefined {
220
+ return this.components.get(canonicalName);
221
+ }
222
+
223
+ /**
224
+ * Get all components belonging to a specific namespace.
225
+ *
226
+ * @param namespace - The namespace to filter by (e.g., "my-plugin")
227
+ * @returns Array of components in that namespace
228
+ */
229
+ getByNamespace(namespace: string): NamespacedComponent[] {
230
+ const results: NamespacedComponent[] = [];
231
+ for (const component of this.components.values()) {
232
+ if (component.namespace === namespace) {
233
+ results.push(component);
234
+ }
235
+ }
236
+ return results;
237
+ }
238
+
239
+ /**
240
+ * Get all registered components.
241
+ *
242
+ * @returns Array of all components
243
+ */
244
+ getAll(): NamespacedComponent[] {
245
+ return Array.from(this.components.values());
246
+ }
247
+
248
+ /**
249
+ * Get all diagnostics collected during registration.
250
+ *
251
+ * Returns deep copies to prevent external mutation of internal state.
252
+ *
253
+ * @returns Array of diagnostics (collisions, etc.)
254
+ */
255
+ getDiagnostics(): RegistryDiagnostic[] {
256
+ return this.diagnostics.map((d) => ({
257
+ type: d.type,
258
+ message: d.message,
259
+ collision: { ...d.collision },
260
+ }));
261
+ }
262
+
263
+ /**
264
+ * Check if a canonical name is already registered.
265
+ *
266
+ * @param canonicalName - The canonical name to check
267
+ * @returns true if registered, false otherwise
268
+ */
269
+ has(canonicalName: string): boolean {
270
+ return this.components.has(canonicalName);
271
+ }
272
+
273
+ /**
274
+ * Get the count of registered components.
275
+ *
276
+ * @returns Number of components
277
+ */
278
+ get size(): number {
279
+ return this.components.size;
280
+ }
281
+
282
+ // ============================================================================
283
+ // Alias Management
284
+ // ============================================================================
285
+
286
+ /**
287
+ * Register an alias for a canonical name.
288
+ *
289
+ * Validates:
290
+ * 1. The target canonical name must exist
291
+ * 2. The alias cannot shadow an existing canonical name
292
+ * 3. The alias cannot already exist pointing to a different target
293
+ *
294
+ * @param alias - The short alias (e.g., "py3d")
295
+ * @param canonicalName - The target canonical name (e.g., "python-tools:3d-visualizer")
296
+ * @returns Result indicating success or failure with reason
297
+ */
298
+ registerAlias(alias: string, canonicalName: string): AliasRegistrationResult {
299
+ // Check that target canonical name exists
300
+ if (!this.components.has(canonicalName)) {
301
+ return {
302
+ success: false,
303
+ reason: 'canonical-not-found',
304
+ message: `Cannot create alias "${alias}": target canonical name "${canonicalName}" does not exist`,
305
+ };
306
+ }
307
+
308
+ // Check that alias doesn't shadow an existing canonical name
309
+ if (this.components.has(alias)) {
310
+ return {
311
+ success: false,
312
+ reason: 'shadows-canonical',
313
+ message: `Cannot create alias "${alias}": it shadows an existing canonical name`,
314
+ };
315
+ }
316
+
317
+ // Check for duplicate alias pointing to different target
318
+ const existingTarget = this.aliasMap.get(alias);
319
+ if (existingTarget !== undefined && existingTarget !== canonicalName) {
320
+ return {
321
+ success: false,
322
+ reason: 'duplicate-alias',
323
+ message: `Cannot create alias "${alias}": already exists pointing to "${existingTarget}"`,
324
+ };
325
+ }
326
+
327
+ // Register the alias (idempotent if same target)
328
+ this.aliasMap.set(alias, canonicalName);
329
+
330
+ return { success: true };
331
+ }
332
+
333
+ /**
334
+ * Remove an alias.
335
+ *
336
+ * @param alias - The alias to remove
337
+ * @returns true if the alias existed and was removed, false otherwise
338
+ */
339
+ removeAlias(alias: string): boolean {
340
+ return this.aliasMap.delete(alias);
341
+ }
342
+
343
+ /**
344
+ * Resolve an alias to its canonical name.
345
+ *
346
+ * @param alias - The alias to resolve
347
+ * @returns The canonical name if alias exists, undefined otherwise
348
+ */
349
+ resolveAlias(alias: string): string | undefined {
350
+ return this.aliasMap.get(alias);
351
+ }
352
+
353
+ /**
354
+ * Get all registered aliases.
355
+ *
356
+ * @returns A copy of the alias map (alias -> canonicalName)
357
+ */
358
+ getAliases(): Map<string, string> {
359
+ return new Map(this.aliasMap);
360
+ }
361
+
362
+ /**
363
+ * Check if an alias exists.
364
+ *
365
+ * @param alias - The alias to check
366
+ * @returns true if the alias exists, false otherwise
367
+ */
368
+ hasAlias(alias: string): boolean {
369
+ return this.aliasMap.has(alias);
370
+ }
371
+ }
372
+
373
+ // ============================================================================
374
+ // Discovery Bridge Helper
375
+ // ============================================================================
376
+
377
+ /**
378
+ * Convert a discovered plugin's inventory into registerable component entries.
379
+ *
380
+ * This helper bridges S01's discovery output (DiscoveredPlugin) with the
381
+ * namespaced registry. It maps skill and agent directory names to component
382
+ * entries with the plugin's namespace.
383
+ *
384
+ * @param plugin - A discovered plugin from S01's discovery process
385
+ * @returns Array of registerable component entries (without canonicalName)
386
+ */
387
+ export function componentsFromDiscovery(
388
+ plugin: DiscoveredPlugin
389
+ ): Omit<NamespacedComponent, 'canonicalName'>[] {
390
+ const components: Omit<NamespacedComponent, 'canonicalName'>[] = [];
391
+
392
+ // Use the plugin's canonical name as the namespace
393
+ const namespace = plugin.canonicalName;
394
+
395
+ // Extract common metadata from the plugin
396
+ const commonMetadata: NamespacedComponent['metadata'] = {
397
+ pluginVersion: plugin.version,
398
+ pluginAuthor: plugin.author?.name,
399
+ pluginHomepage: plugin.homepage,
400
+ pluginCategory: plugin.category,
401
+ };
402
+
403
+ // Process skills
404
+ for (const skillName of plugin.inventory.skills) {
405
+ // Resolve the skill file path
406
+ // Skills are in <plugin>/skills/<name>/SKILL.md or <plugin>/skills/<name>.md
407
+ let filePath: string;
408
+ if (plugin.resolvedPath) {
409
+ const skillDirPath = `${plugin.resolvedPath}/skills/${skillName}`;
410
+ // Prefer direct markdown file entries, otherwise directory with SKILL.md
411
+ filePath = skillName.endsWith('.md')
412
+ ? `${plugin.resolvedPath}/skills/${skillName}`
413
+ : `${skillDirPath}/SKILL.md`;
414
+ } else {
415
+ // External plugin - use placeholder path
416
+ filePath = `<external>/${namespace}/skills/${skillName}/SKILL.md`;
417
+ }
418
+
419
+ components.push({
420
+ name: skillName.replace(/\.md$/, ''), // Strip .md if present
421
+ namespace,
422
+ type: 'skill',
423
+ filePath,
424
+ source: `plugin:${namespace}`,
425
+ description: undefined, // Would require reading the file
426
+ metadata: {
427
+ ...commonMetadata,
428
+ componentDir: skillName,
429
+ },
430
+ });
431
+ }
432
+
433
+ // Process agents
434
+ for (const agentName of plugin.inventory.agents) {
435
+ // Resolve the agent file path
436
+ let filePath: string;
437
+ if (plugin.resolvedPath) {
438
+ const agentDirPath = `${plugin.resolvedPath}/agents/${agentName}`;
439
+ filePath = agentName.endsWith('.md')
440
+ ? `${plugin.resolvedPath}/agents/${agentName}`
441
+ : `${agentDirPath}/AGENT.md`;
442
+ } else {
443
+ filePath = `<external>/${namespace}/agents/${agentName}/AGENT.md`;
444
+ }
445
+
446
+ components.push({
447
+ name: agentName.replace(/\.md$/, ''), // Strip .md if present
448
+ namespace,
449
+ type: 'agent',
450
+ filePath,
451
+ source: `plugin:${namespace}`,
452
+ description: undefined, // Would require reading the file
453
+ metadata: {
454
+ ...commonMetadata,
455
+ componentDir: agentName,
456
+ },
457
+ });
458
+ }
459
+
460
+ return components;
461
+ }
462
+
463
+ // ============================================================================
464
+ // Exports
465
+ // ============================================================================
466
+
467
+ export default NamespacedRegistry;