@opengsd/gsd-pi 1.0.2-dev.867e002 → 1.0.2-dev.aed3486

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 (328) hide show
  1. package/dist/onboarding.js +22 -3
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/context7/index.js +12 -2
  4. package/dist/resources/extensions/get-secrets-from-user.js +16 -16
  5. package/dist/resources/extensions/google-cli/index.js +30 -0
  6. package/dist/resources/extensions/google-cli/models.js +55 -0
  7. package/dist/resources/extensions/google-cli/package.json +11 -0
  8. package/dist/resources/extensions/google-cli/readiness.js +12 -0
  9. package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
  10. package/dist/resources/extensions/gsd/auto/loop.js +62 -1
  11. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
  12. package/dist/resources/extensions/gsd/auto/phases.js +37 -0
  13. package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
  14. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +21 -11
  17. package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
  18. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  19. package/dist/resources/extensions/gsd/auto-start.js +232 -49
  20. package/dist/resources/extensions/gsd/auto.js +6 -1
  21. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
  22. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
  23. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
  24. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -7
  25. package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
  26. package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
  27. package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
  28. package/dist/resources/extensions/gsd/commands-usage.js +105 -1
  29. package/dist/resources/extensions/gsd/config-overlay.js +20 -14
  30. package/dist/resources/extensions/gsd/context-overlay.js +22 -16
  31. package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
  32. package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
  33. package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
  34. package/dist/resources/extensions/gsd/doctor.js +6 -1
  35. package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
  36. package/dist/resources/extensions/gsd/guided-flow.js +5 -6
  37. package/dist/resources/extensions/gsd/key-manager.js +45 -13
  38. package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
  39. package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
  40. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
  41. package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
  42. package/dist/resources/extensions/gsd/preferences.js +14 -2
  43. package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
  44. package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
  45. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  46. package/dist/resources/extensions/gsd/prompts/system.md +1 -3
  47. package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
  48. package/dist/resources/extensions/gsd/repository-registry.js +3 -1
  49. package/dist/resources/extensions/gsd/safety/evidence-collector.js +11 -4
  50. package/dist/resources/extensions/gsd/skill-activation.js +233 -0
  51. package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
  52. package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
  53. package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
  54. package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
  55. package/dist/resources/extensions/gsd/skill-scope.js +52 -0
  56. package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
  57. package/dist/resources/extensions/gsd/skills.js +60 -0
  58. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
  59. package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
  60. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
  61. package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
  62. package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
  63. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
  64. package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
  65. package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
  66. package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
  67. package/dist/resources/extensions/gsd/vision-ask.js +22 -0
  68. package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
  69. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
  70. package/dist/resources/extensions/search-the-web/native-search.js +57 -8
  71. package/dist/resources/extensions/shared/confirm-ui.js +9 -6
  72. package/dist/resources/extensions/shared/dialog-frame.js +42 -0
  73. package/dist/resources/extensions/shared/interview-ui.js +42 -30
  74. package/dist/resources/extensions/shared/next-action-ui.js +6 -6
  75. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  76. package/dist/web/standalone/.next/BUILD_ID +1 -1
  77. package/dist/web/standalone/.next/app-path-routes-manifest.json +4 -4
  78. package/dist/web/standalone/.next/build-manifest.json +2 -2
  79. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  80. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/index.html +1 -1
  97. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app-paths-manifest.json +4 -4
  104. package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
  105. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  107. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  108. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  109. package/package.json +1 -1
  110. package/packages/cloud-mcp-gateway/package.json +2 -2
  111. package/packages/contracts/package.json +1 -1
  112. package/packages/daemon/package.json +4 -4
  113. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
  114. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  115. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
  116. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  117. package/packages/gsd-agent-core/package.json +5 -5
  118. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
  119. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
  120. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
  121. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
  122. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
  123. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  124. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
  125. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
  126. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
  127. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  128. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
  129. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
  130. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
  131. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  132. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
  133. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
  134. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
  135. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
  136. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
  137. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
  138. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  139. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  140. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
  141. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  142. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
  143. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  144. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
  145. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  146. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  147. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -1
  148. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  149. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
  150. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  151. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
  152. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  153. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
  154. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
  155. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
  156. package/packages/gsd-agent-modes/package.json +7 -7
  157. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  158. package/packages/mcp-server/dist/workflow-tools.js +10 -5
  159. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  160. package/packages/mcp-server/package.json +3 -3
  161. package/packages/native/package.json +1 -1
  162. package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
  163. package/packages/pi-agent-core/dist/harness/skills.js +6 -0
  164. package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
  165. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
  166. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
  167. package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
  168. package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
  169. package/packages/pi-agent-core/package.json +1 -1
  170. package/packages/pi-ai/dist/models.generated.d.ts +8 -59
  171. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  172. package/packages/pi-ai/dist/models.generated.js +21 -72
  173. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  174. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  175. package/packages/pi-ai/dist/providers/anthropic.js +50 -0
  176. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  177. package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  178. package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
  179. package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  180. package/packages/pi-ai/dist/types.d.ts +2 -0
  181. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  182. package/packages/pi-ai/dist/types.js.map +1 -1
  183. package/packages/pi-ai/package.json +1 -1
  184. package/packages/pi-coding-agent/README.md +1 -1
  185. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
  186. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  188. package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
  189. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  190. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
  192. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
  194. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/skills.js +3 -0
  196. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  197. package/packages/pi-coding-agent/package.json +7 -7
  198. package/packages/pi-tui/package.json +1 -1
  199. package/packages/rpc-client/package.json +2 -2
  200. package/pkg/package.json +1 -1
  201. package/src/resources/extensions/context7/index.ts +15 -2
  202. package/src/resources/extensions/get-secrets-from-user.ts +17 -16
  203. package/src/resources/extensions/google-cli/index.ts +34 -0
  204. package/src/resources/extensions/google-cli/models.ts +57 -0
  205. package/src/resources/extensions/google-cli/package.json +11 -0
  206. package/src/resources/extensions/google-cli/readiness.ts +15 -0
  207. package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
  208. package/src/resources/extensions/gsd/auto/loop.ts +74 -1
  209. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
  210. package/src/resources/extensions/gsd/auto/phases.ts +46 -0
  211. package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
  212. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  213. package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
  214. package/src/resources/extensions/gsd/auto-post-unit.ts +43 -14
  215. package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
  216. package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
  217. package/src/resources/extensions/gsd/auto-start.ts +307 -56
  218. package/src/resources/extensions/gsd/auto.ts +6 -1
  219. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
  220. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
  221. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
  222. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -6
  223. package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
  224. package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
  225. package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
  226. package/src/resources/extensions/gsd/commands-usage.ts +110 -5
  227. package/src/resources/extensions/gsd/config-overlay.ts +19 -16
  228. package/src/resources/extensions/gsd/context-overlay.ts +24 -19
  229. package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
  230. package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
  231. package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
  232. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  233. package/src/resources/extensions/gsd/doctor.ts +6 -1
  234. package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
  235. package/src/resources/extensions/gsd/guided-flow.ts +5 -6
  236. package/src/resources/extensions/gsd/key-manager.ts +57 -14
  237. package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
  238. package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
  239. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
  240. package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
  241. package/src/resources/extensions/gsd/preferences.ts +17 -2
  242. package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
  243. package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
  244. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  245. package/src/resources/extensions/gsd/prompts/system.md +1 -3
  246. package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
  247. package/src/resources/extensions/gsd/repository-registry.ts +3 -1
  248. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -4
  249. package/src/resources/extensions/gsd/skill-activation.ts +292 -0
  250. package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
  251. package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
  252. package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
  253. package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
  254. package/src/resources/extensions/gsd/skill-scope.ts +63 -0
  255. package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
  256. package/src/resources/extensions/gsd/skills.ts +75 -0
  257. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
  258. package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
  259. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
  260. package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
  261. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
  262. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +21 -0
  263. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
  264. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
  265. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
  266. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
  267. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
  268. package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
  269. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
  270. package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
  271. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
  272. package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
  273. package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
  274. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
  275. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
  276. package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
  277. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
  278. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
  279. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
  280. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
  281. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
  282. package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
  283. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
  284. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
  285. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
  286. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
  287. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
  288. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
  289. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
  290. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
  291. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
  292. package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
  293. package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
  294. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
  295. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
  296. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +19 -0
  297. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
  298. package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
  299. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
  300. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
  301. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
  302. package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
  303. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
  304. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +74 -1
  305. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
  306. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
  307. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
  308. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
  309. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
  310. package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
  311. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
  312. package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
  313. package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
  314. package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
  315. package/src/resources/extensions/gsd/vision-ask.ts +28 -0
  316. package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
  317. package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
  318. package/src/resources/extensions/search-the-web/native-search.ts +60 -8
  319. package/src/resources/extensions/shared/confirm-ui.ts +8 -12
  320. package/src/resources/extensions/shared/dialog-frame.ts +71 -0
  321. package/src/resources/extensions/shared/interview-ui.ts +43 -42
  322. package/src/resources/extensions/shared/next-action-ui.ts +6 -6
  323. package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
  324. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
  325. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
  326. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  327. /package/dist/web/standalone/.next/static/{praHP_OATcjBkvAVejjGK → _LIEWYP8ISVAPKAEEXxFr}/_buildManifest.js +0 -0
  328. /package/dist/web/standalone/.next/static/{praHP_OATcjBkvAVejjGK → _LIEWYP8ISVAPKAEEXxFr}/_ssgManifest.js +0 -0
@@ -2,21 +2,17 @@
2
2
  * GSD Skill Discovery
3
3
  *
4
4
  * Detects skills installed during auto-mode by comparing the current
5
- * skills directory against a snapshot taken at auto-mode start.
5
+ * installed catalog and skill directories against a snapshot taken at auto-mode start.
6
6
  *
7
- * New skills are injected into the system prompt via before_agent_start,
8
- * making them visible to all subsequent units without requiring a reload.
7
+ * New skills are surfaced via resource reload when possible, with a fallback
8
+ * prompt block when reload fails before the next agent turn.
9
9
  */
10
10
 
11
- import { existsSync, readdirSync, readFileSync } from "node:fs";
12
- import { join } from "node:path";
11
+ import { existsSync, readdirSync, readFileSync, type Dirent } from "node:fs";
13
12
  import { homedir } from "node:os";
13
+ import { join } from "node:path";
14
14
  import { gsdHome } from "./gsd-home.js";
15
-
16
- /** Skills directories — GSD bundled, skills.sh ecosystem, and Claude Code official */
17
- const GSD_SKILLS_DIR = join(gsdHome(), "agent", "skills");
18
- const SKILLS_DIR = join(homedir(), ".agents", "skills");
19
- const CLAUDE_SKILLS_DIR = join(homedir(), ".claude", "skills");
15
+ import { getInstalledSkills, normalizeSkillName } from "./skills.js";
20
16
 
21
17
  export interface DiscoveredSkill {
22
18
  name: string;
@@ -24,14 +20,14 @@ export interface DiscoveredSkill {
24
20
  location: string;
25
21
  }
26
22
 
27
- /** Snapshot of skill names at auto-mode start */
23
+ /** Snapshot of normalized skill names at auto-mode start */
28
24
  let baselineSkills: Set<string> | null = null;
29
25
 
30
26
  /**
31
- * Snapshot the current skills directory. Call at auto-mode start.
27
+ * Snapshot the current installed skill catalog. Call at auto-mode start.
32
28
  */
33
29
  export function snapshotSkills(): void {
34
- baselineSkills = new Set(listSkillDirs());
30
+ baselineSkills = snapshotCurrentSkillNames();
35
31
  }
36
32
 
37
33
  /**
@@ -50,82 +46,158 @@ export function hasSkillSnapshot(): boolean {
50
46
 
51
47
  /**
52
48
  * Detect skills installed since the snapshot was taken.
53
- * Returns skill metadata for any new skills found.
49
+ * Returns skill metadata for any new skills found in the loader catalog or on disk.
54
50
  */
55
51
  export function detectNewSkills(): DiscoveredSkill[] {
56
52
  if (!baselineSkills) return [];
57
53
 
58
- const current = listSkillDirs();
59
54
  const newSkills: DiscoveredSkill[] = [];
60
-
61
- for (const dir of current) {
62
- if (baselineSkills.has(dir)) continue;
63
-
64
- // Check both skill directories for the SKILL.md file
65
- const skillMdPath = resolveSkillMdPath(dir);
66
- if (!skillMdPath) continue;
67
-
68
- const meta = parseSkillFrontmatter(skillMdPath);
69
- if (meta) {
70
- newSkills.push({
71
- name: meta.name || dir,
72
- description: meta.description || `Skill: ${dir}`,
73
- location: skillMdPath,
74
- });
75
- }
55
+ for (const skill of getCurrentSkillsForDiscovery()) {
56
+ const normalized = normalizeSkillName(skill.name);
57
+ if (baselineSkills.has(normalized)) continue;
58
+ newSkills.push(skill);
76
59
  }
77
60
 
78
61
  return newSkills;
79
62
  }
80
63
 
81
64
  /**
82
- * Format discovered skills as an XML block matching pi's <available_skills> format.
83
- * This can be appended to the system prompt so the LLM sees them naturally.
65
+ * Reload the skill catalog when auto-mode detects newly installed skills.
66
+ * Returns discovered skills even if reload fails so callers can surface them
67
+ * in the prompt. Updates the snapshot baseline only after a successful reload
68
+ * so detection is retried after failures.
84
69
  */
85
- export function formatSkillsXml(skills: DiscoveredSkill[]): string {
86
- if (skills.length === 0) return "";
70
+ export async function refreshCatalogForNewSkills(options?: {
71
+ reload?: () => Promise<void>;
72
+ notify?: (message: string, level: "info" | "warning") => void;
73
+ }): Promise<DiscoveredSkill[]> {
74
+ const newSkills = detectNewSkills();
75
+ if (newSkills.length === 0) return [];
76
+
77
+ if (options?.reload) {
78
+ try {
79
+ await options.reload();
80
+ } catch (error) {
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ options.notify?.(`GSD: failed to reload skill catalog: ${message}`, "warning");
83
+ return newSkills;
84
+ }
85
+ }
87
86
 
88
- const entries = skills.map(s => ` <skill>
89
- <name>${escapeXml(s.name)}</name>
90
- <description>${escapeXml(s.description)}</description>
91
- <location>${escapeXml(s.location)}</location>
92
- </skill>`).join("\n");
87
+ snapshotSkills();
88
+ const names = newSkills.map((skill) => skill.name).join(", ");
89
+ options?.notify?.(`GSD: loaded new skills: ${names}`, "info");
90
+ return newSkills;
91
+ }
93
92
 
94
- return `\n<newly_discovered_skills>
95
- The following skills were installed during this auto-mode session.
96
- Use the read tool to load a skill's file when the task matches its description.
93
+ export function appendDiscoveredSkillsFallback(systemPrompt: string, skills: DiscoveredSkill[]): string {
94
+ const missingSkills = skills.filter(skill => !systemPrompt.includes(skill.location));
95
+ if (missingSkills.length === 0) return systemPrompt;
97
96
 
98
- ${entries}
99
- </newly_discovered_skills>`;
97
+ return `${systemPrompt}\n\n${formatDiscoveredSkillsXml(missingSkills)}`;
100
98
  }
101
99
 
102
100
  // ─── Internals ────────────────────────────────────────────────────────────────
103
101
 
104
- function listSkillDirsFrom(dir: string): string[] {
105
- if (!existsSync(dir)) return [];
106
- try {
107
- return readdirSync(dir, { withFileTypes: true })
108
- .filter(d => d.isDirectory())
109
- .map(d => d.name);
110
- } catch {
111
- return [];
102
+ function formatDiscoveredSkillsXml(skills: DiscoveredSkill[]): string {
103
+ const lines = [
104
+ "<newly_discovered_skills>",
105
+ " <note>These skills were detected after this session started and may be absent from &lt;available_skills&gt;. If relevant, read the skill file at its location before using it.</note>",
106
+ ];
107
+
108
+ for (const skill of skills) {
109
+ lines.push(
110
+ " <skill>",
111
+ ` <name>${escapeXml(skill.name)}</name>`,
112
+ ` <description>${escapeXml(skill.description)}</description>`,
113
+ ` <location>${escapeXml(skill.location)}</location>`,
114
+ " </skill>",
115
+ );
116
+ }
117
+
118
+ lines.push("</newly_discovered_skills>");
119
+ return lines.join("\n");
120
+ }
121
+
122
+ function escapeXml(value: string): string {
123
+ return value.replace(/[<>&'"]/g, (char) => {
124
+ switch (char) {
125
+ case "<": return "&lt;";
126
+ case ">": return "&gt;";
127
+ case "&": return "&amp;";
128
+ case "'": return "&apos;";
129
+ case "\"": return "&quot;";
130
+ default: return char;
131
+ }
132
+ });
133
+ }
134
+
135
+ function skillSearchDirs(): string[] {
136
+ return [
137
+ join(gsdHome(), "agent", "skills"),
138
+ join(homedir(), ".agents", "skills"),
139
+ join(homedir(), ".claude", "skills"),
140
+ ];
141
+ }
142
+
143
+ function snapshotCurrentSkillNames(): Set<string> {
144
+ return new Set(getCurrentSkillsForDiscovery().map(skill => normalizeSkillName(skill.name)));
145
+ }
146
+
147
+ function getCurrentSkillsForDiscovery(): DiscoveredSkill[] {
148
+ const skills = new Map<string, DiscoveredSkill>();
149
+ for (const skill of getInstalledSkills()) {
150
+ const normalized = normalizeSkillName(skill.name);
151
+ skills.set(normalized, {
152
+ name: skill.name,
153
+ description: skill.description || `Skill: ${skill.name}`,
154
+ location: skill.filePath,
155
+ });
156
+ }
157
+
158
+ for (const skill of getDiskSkills()) {
159
+ const normalized = normalizeSkillName(skill.name);
160
+ if (!skills.has(normalized)) skills.set(normalized, skill);
112
161
  }
162
+
163
+ return [...skills.values()];
113
164
  }
114
165
 
115
- function listSkillDirs(): string[] {
116
- const names = new Set<string>();
117
- for (const name of listSkillDirsFrom(GSD_SKILLS_DIR)) names.add(name);
118
- for (const name of listSkillDirsFrom(SKILLS_DIR)) names.add(name);
119
- for (const name of listSkillDirsFrom(CLAUDE_SKILLS_DIR)) names.add(name);
120
- return [...names];
166
+ function getDiskSkills(): DiscoveredSkill[] {
167
+ const skills = new Map<string, DiscoveredSkill>();
168
+ for (const dir of skillSearchDirs()) {
169
+ if (!existsSync(dir)) continue;
170
+ let entries: Dirent[];
171
+ try {
172
+ entries = readdirSync(dir, { withFileTypes: true });
173
+ } catch {
174
+ continue;
175
+ }
176
+
177
+ for (const entry of entries) {
178
+ if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
179
+ const skillMdPath = join(dir, entry.name, "SKILL.md");
180
+ if (!existsSync(skillMdPath)) continue;
181
+
182
+ const meta = parseSkillFrontmatter(skillMdPath);
183
+ const name = meta?.name || entry.name;
184
+ const normalized = normalizeSkillName(name);
185
+ if (skills.has(normalized)) continue;
186
+ skills.set(normalized, {
187
+ name,
188
+ description: meta?.description || `Skill: ${name}`,
189
+ location: skillMdPath,
190
+ });
191
+ }
192
+ }
193
+ return [...skills.values()];
121
194
  }
122
195
 
123
196
  function parseSkillFrontmatter(path: string): { name?: string; description?: string } | null {
124
197
  try {
125
198
  const content = readFileSync(path, "utf-8");
126
- // Use indexOf instead of [\s\S]*? regex to avoid backtracking (#468)
127
- if (!content.startsWith('---\n')) return null;
128
- const endIdx = content.indexOf('\n---', 4);
199
+ if (!content.startsWith("---\n")) return null;
200
+ const endIdx = content.indexOf("\n---", 4);
129
201
  if (endIdx === -1) return null;
130
202
 
131
203
  const fm = content.slice(4, endIdx);
@@ -142,19 +214,3 @@ function parseSkillFrontmatter(path: string): { name?: string; description?: str
142
214
  return null;
143
215
  }
144
216
  }
145
-
146
- function resolveSkillMdPath(skillName: string): string | null {
147
- for (const dir of [GSD_SKILLS_DIR, SKILLS_DIR, CLAUDE_SKILLS_DIR]) {
148
- const candidate = join(dir, skillName, "SKILL.md");
149
- if (existsSync(candidate)) return candidate;
150
- }
151
- return null;
152
- }
153
-
154
- function escapeXml(text: string): string {
155
- return text
156
- .replace(/&/g, "&amp;")
157
- .replace(/</g, "&lt;")
158
- .replace(/>/g, "&gt;")
159
- .replace(/"/g, "&quot;");
160
- }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Per-unit skill catalog scoping for GSD auto and workflow dispatch.
3
+ */
4
+
5
+ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
6
+
7
+ import { resolveSkillManifest } from "./skill-manifest.js";
8
+ import { normalizeSkillName } from "./skills.js";
9
+ import { resolveManifest } from "./unit-context-manifest.js";
10
+
11
+ /**
12
+ * Resolve which skill names should appear in `<available_skills>` for a unit.
13
+ * Returns `undefined` for full catalog, `[]` for suppressed catalog, or a
14
+ * name list for allowlist mode.
15
+ */
16
+ export function resolveVisibleSkillNames(unitType: string | undefined): string[] | undefined {
17
+ if (!unitType) return undefined;
18
+
19
+ const unitManifest = resolveManifest(unitType);
20
+ if (unitManifest) {
21
+ switch (unitManifest.skills.mode) {
22
+ case "none":
23
+ return [];
24
+ case "all":
25
+ return undefined;
26
+ case "allowlist":
27
+ return [...unitManifest.skills.skills];
28
+ }
29
+ }
30
+
31
+ const legacyAllowlist = resolveSkillManifest(unitType);
32
+ return legacyAllowlist ?? undefined;
33
+ }
34
+
35
+ /** Whether this unit narrows or suppresses the skill catalog (not mode "all"). */
36
+ export function unitHasSkillManifest(unitType: string | undefined): boolean {
37
+ if (!unitType) return false;
38
+ const unitManifest = resolveManifest(unitType);
39
+ if (unitManifest) {
40
+ return unitManifest.skills.mode !== "all";
41
+ }
42
+ return resolveSkillManifest(unitType) !== null;
43
+ }
44
+
45
+ /** Apply unit manifest skill policy via setVisibleSkills. */
46
+ export function applyUnitSkillVisibility(
47
+ pi: Pick<ExtensionAPI, "setVisibleSkills">,
48
+ unitType: string | undefined,
49
+ ): void {
50
+ pi.setVisibleSkills(resolveVisibleSkillNames(unitType));
51
+ }
52
+
53
+ /** Installed skill names visible for a unit per manifest policy. */
54
+ export function effectiveSkillNamesForUnit(
55
+ unitType: string | undefined,
56
+ installed: string[],
57
+ ): string[] {
58
+ const visible = resolveVisibleSkillNames(unitType);
59
+ if (visible === undefined) return installed;
60
+ if (visible.length === 0) return [];
61
+ const allowed = new Set(visible.map(normalizeSkillName));
62
+ return installed.filter((name) => allowed.has(normalizeSkillName(name)));
63
+ }
@@ -6,15 +6,12 @@
6
6
  * "actively loaded" skills (read via tool calls during execution).
7
7
  *
8
8
  * Data flow:
9
- * 1. At dispatch, captureAvailableSkills() records skills from the system prompt
9
+ * 1. At dispatch, captureAvailableSkills(names) records catalog skill names
10
10
  * 2. During execution, recordSkillRead() tracks explicit SKILL.md reads
11
11
  * 3. At unit completion, getAndClearSkills() returns the loaded list for metrics
12
12
  */
13
13
 
14
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
15
- import { join } from "node:path";
16
- import { gsdHome } from "./gsd-home.js";
17
- import { homedir } from "node:os";
14
+ import { getInstalledSkillNames } from "./skills.js";
18
15
 
19
16
  // ─── In-memory state ──────────────────────────────────────────────────────────
20
17
 
@@ -28,17 +25,10 @@ const activelyLoadedSkills = new Set<string>();
28
25
 
29
26
  /**
30
27
  * Capture the list of available skill names at dispatch time.
31
- * Called before each unit starts.
28
+ * Callers should pass names from resourceLoader / {@link getInstalledSkillNames}.
32
29
  */
33
- export function captureAvailableSkills(): void {
34
- const gsdSkillsDir = join(gsdHome(), "agent", "skills");
35
- const skillsDir = join(homedir(), ".agents", "skills");
36
- const claudeSkillsDir = join(homedir(), ".claude", "skills");
37
- const gsdNames = listSkillNames(gsdSkillsDir);
38
- const names = listSkillNames(skillsDir);
39
- const claudeNames = listSkillNames(claudeSkillsDir);
40
- const all = new Set([...gsdNames, ...names, ...claudeNames]);
41
- availableSkills = [...all];
30
+ export function captureAvailableSkills(skillNames: string[]): void {
31
+ availableSkills = [...skillNames];
42
32
  activelyLoadedSkills.clear();
43
33
  }
44
34
 
@@ -104,17 +94,7 @@ export function detectStaleSkills(
104
94
  const lastUsed = getSkillLastUsed(units);
105
95
  const cutoff = Date.now() - (thresholdDays * 24 * 60 * 60 * 1000);
106
96
  const stale: string[] = [];
107
-
108
- // Check all installed skills, not just those with usage data
109
- const gsdSkillsDir = join(gsdHome(), "agent", "skills");
110
- const skillsDir = join(homedir(), ".agents", "skills");
111
- const claudeSkillsDir = join(homedir(), ".claude", "skills");
112
- const installedSet = new Set([
113
- ...listSkillNames(gsdSkillsDir),
114
- ...listSkillNames(skillsDir),
115
- ...listSkillNames(claudeSkillsDir),
116
- ]);
117
- const installed = [...installedSet];
97
+ const installed = getInstalledSkillNames();
118
98
 
119
99
  for (const skill of installed) {
120
100
  const lastTs = lastUsed.get(skill);
@@ -125,17 +105,3 @@ export function detectStaleSkills(
125
105
 
126
106
  return stale;
127
107
  }
128
-
129
- // ─── Internals ────────────────────────────────────────────────────────────────
130
-
131
- function listSkillNames(skillsDir: string): string[] {
132
- if (!existsSync(skillsDir)) return [];
133
- try {
134
- return readdirSync(skillsDir, { withFileTypes: true })
135
- .filter(d => d.isDirectory() && !d.name.startsWith("."))
136
- .filter(d => existsSync(join(skillsDir, d.name, "SKILL.md")))
137
- .map(d => d.name);
138
- } catch {
139
- return [];
140
- }
141
- }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Canonical skill access for GSD extension code.
3
+ *
4
+ * Prefer {@link getInstalledSkills} (ResourceLoader / getLoadedSkills cache)
5
+ * over ad-hoc directory scans.
6
+ */
7
+
8
+ import { getLoadedSkills, type Skill } from "@gsd/pi-coding-agent";
9
+ import { resolveSkillReference, type SkillResolution } from "./preferences-skills.js";
10
+
11
+ /** Normalize a skill reference the same way preference matching does. */
12
+ export function normalizeSkillName(ref: string): string {
13
+ return ref.trim().toLowerCase();
14
+ }
15
+
16
+ /** Installed skills from the pi loader cache, or an explicit override (tests). */
17
+ export function getInstalledSkills(override?: Skill[]): Skill[] {
18
+ if (override) return override;
19
+ return typeof getLoadedSkills === "function" ? getLoadedSkills() : [];
20
+ }
21
+
22
+ /** Skill names from the installed catalog. */
23
+ export function getInstalledSkillNames(skills?: Skill[]): string[] {
24
+ return getInstalledSkills(skills).map((skill) => skill.name);
25
+ }
26
+
27
+ /** Snapshot normalized skill names for auto-mode diffing. */
28
+ export function snapshotInstalledSkillNames(skills?: Skill[]): Set<string> {
29
+ return new Set(getInstalledSkillNames(skills).map(normalizeSkillName));
30
+ }
31
+
32
+ /** Names present now but absent from `baseline`. */
33
+ export function detectNewlyInstalledSkills(baseline: Set<string>, skills?: Skill[]): string[] {
34
+ const current = snapshotInstalledSkillNames(skills);
35
+ return [...current].filter((name) => !baseline.has(name));
36
+ }
37
+
38
+ export type InstalledSkillResolution = SkillResolution & { skill?: Skill };
39
+
40
+ /**
41
+ * Resolve a preference skill reference to a path, validating against the
42
+ * installed catalog when loader data is available.
43
+ */
44
+ export function resolveInstalledSkill(
45
+ ref: string,
46
+ cwd: string,
47
+ skills?: Skill[],
48
+ ): InstalledSkillResolution {
49
+ const resolution = resolveSkillReference(ref, cwd);
50
+ const installed = getInstalledSkills(skills);
51
+ if (installed.length === 0) {
52
+ return resolution;
53
+ }
54
+
55
+ const byName = new Map(installed.map((skill) => [normalizeSkillName(skill.name), skill]));
56
+ const normalizedRef = normalizeSkillName(ref);
57
+ const byRef = byName.get(normalizedRef);
58
+ if (byRef) {
59
+ return {
60
+ ...resolution,
61
+ resolvedPath: byRef.filePath,
62
+ method: resolution.method === "unresolved" ? "user-skill" : resolution.method,
63
+ skill: byRef,
64
+ };
65
+ }
66
+
67
+ if (resolution.resolvedPath) {
68
+ const match = installed.find((skill) => skill.filePath === resolution.resolvedPath);
69
+ if (match) {
70
+ return { ...resolution, skill: match };
71
+ }
72
+ }
73
+
74
+ return resolution;
75
+ }