gsd-pi 2.29.0-dev.953d788 → 2.29.0-dev.f08b4fe

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 (316) hide show
  1. package/README.md +24 -17
  2. package/dist/extension-registry.d.ts +63 -0
  3. package/dist/extension-registry.js +166 -0
  4. package/dist/headless.js +4 -0
  5. package/dist/loader.js +10 -1
  6. package/dist/resource-loader.js +11 -1
  7. package/dist/resources/extensions/async-jobs/extension-manifest.json +13 -0
  8. package/dist/resources/extensions/bg-shell/extension-manifest.json +14 -0
  9. package/dist/resources/extensions/bg-shell/process-manager.ts +13 -0
  10. package/dist/resources/extensions/browser-tools/extension-manifest.json +37 -0
  11. package/dist/resources/extensions/context7/extension-manifest.json +12 -0
  12. package/dist/resources/extensions/google-search/extension-manifest.json +12 -0
  13. package/dist/resources/extensions/gsd/auto-dashboard.ts +217 -65
  14. package/dist/resources/extensions/gsd/auto-dispatch.ts +32 -3
  15. package/dist/resources/extensions/gsd/auto-post-unit.ts +45 -13
  16. package/dist/resources/extensions/gsd/auto-prompts.ts +40 -17
  17. package/dist/resources/extensions/gsd/auto-recovery.ts +18 -23
  18. package/dist/resources/extensions/gsd/auto-start.ts +18 -32
  19. package/dist/resources/extensions/gsd/auto-worktree.ts +21 -182
  20. package/dist/resources/extensions/gsd/auto.ts +2 -24
  21. package/dist/resources/extensions/gsd/captures.ts +4 -10
  22. package/dist/resources/extensions/gsd/commands-extensions.ts +328 -0
  23. package/dist/resources/extensions/gsd/commands-handlers.ts +22 -2
  24. package/dist/resources/extensions/gsd/commands-logs.ts +13 -14
  25. package/dist/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
  26. package/dist/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
  27. package/dist/resources/extensions/gsd/commands.ts +108 -24
  28. package/dist/resources/extensions/gsd/dashboard-overlay.ts +2 -1
  29. package/dist/resources/extensions/gsd/detection.ts +2 -1
  30. package/dist/resources/extensions/gsd/doctor-checks.ts +49 -1
  31. package/dist/resources/extensions/gsd/doctor-types.ts +3 -1
  32. package/dist/resources/extensions/gsd/extension-manifest.json +18 -0
  33. package/dist/resources/extensions/gsd/forensics.ts +2 -2
  34. package/dist/resources/extensions/gsd/git-service.ts +3 -2
  35. package/dist/resources/extensions/gsd/gitignore.ts +9 -63
  36. package/dist/resources/extensions/gsd/gsd-db.ts +1 -165
  37. package/dist/resources/extensions/gsd/guided-flow.ts +8 -5
  38. package/dist/resources/extensions/gsd/index.ts +3 -3
  39. package/dist/resources/extensions/gsd/json-persistence.ts +16 -1
  40. package/dist/resources/extensions/gsd/md-importer.ts +3 -2
  41. package/dist/resources/extensions/gsd/mechanical-completion.ts +430 -0
  42. package/dist/resources/extensions/gsd/migrate/command.ts +3 -2
  43. package/dist/resources/extensions/gsd/migrate/writer.ts +2 -1
  44. package/dist/resources/extensions/gsd/migrate-external.ts +123 -0
  45. package/dist/resources/extensions/gsd/paths.ts +24 -2
  46. package/dist/resources/extensions/gsd/post-unit-hooks.ts +6 -5
  47. package/dist/resources/extensions/gsd/preferences-models.ts +7 -1
  48. package/dist/resources/extensions/gsd/preferences-validation.ts +2 -1
  49. package/dist/resources/extensions/gsd/preferences.ts +10 -5
  50. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
  51. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  52. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
  53. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -1
  54. package/dist/resources/extensions/gsd/prompts/workflow-start.md +28 -0
  55. package/dist/resources/extensions/gsd/queue-order.ts +10 -11
  56. package/dist/resources/extensions/gsd/repo-identity.ts +148 -0
  57. package/dist/resources/extensions/gsd/resource-version.ts +99 -0
  58. package/dist/resources/extensions/gsd/session-forensics.ts +4 -3
  59. package/dist/resources/extensions/gsd/session-status-io.ts +23 -41
  60. package/dist/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
  61. package/dist/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
  62. package/dist/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
  63. package/dist/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
  64. package/dist/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
  65. package/dist/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
  66. package/dist/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
  67. package/dist/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
  68. package/dist/resources/extensions/gsd/tests/git-service.test.ts +10 -37
  69. package/dist/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
  70. package/dist/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
  71. package/dist/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
  72. package/dist/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
  73. package/dist/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
  74. package/dist/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
  75. package/dist/resources/extensions/gsd/triage-resolution.ts +2 -1
  76. package/dist/resources/extensions/gsd/types.ts +2 -0
  77. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
  78. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
  79. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
  80. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
  81. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
  82. package/dist/resources/extensions/gsd/workflow-templates/registry.json +85 -0
  83. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
  84. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
  85. package/dist/resources/extensions/gsd/workflow-templates/spike.md +69 -0
  86. package/dist/resources/extensions/gsd/workflow-templates.ts +241 -0
  87. package/dist/resources/extensions/gsd/worktree-command.ts +1 -11
  88. package/dist/resources/extensions/gsd/worktree-manager.ts +3 -2
  89. package/dist/resources/extensions/gsd/worktree.ts +42 -5
  90. package/dist/resources/extensions/mac-tools/extension-manifest.json +16 -0
  91. package/dist/resources/extensions/mcp-client/index.ts +459 -0
  92. package/dist/resources/extensions/mcporter/extension-manifest.json +12 -0
  93. package/dist/resources/extensions/remote-questions/discord-adapter.ts +8 -19
  94. package/dist/resources/extensions/remote-questions/extension-manifest.json +11 -0
  95. package/dist/resources/extensions/remote-questions/http-client.ts +76 -0
  96. package/dist/resources/extensions/remote-questions/slack-adapter.ts +11 -17
  97. package/dist/resources/extensions/remote-questions/telegram-adapter.ts +8 -19
  98. package/dist/resources/extensions/search-the-web/extension-manifest.json +13 -0
  99. package/dist/resources/extensions/slash-commands/extension-manifest.json +11 -0
  100. package/dist/resources/extensions/subagent/extension-manifest.json +13 -0
  101. package/dist/resources/extensions/ttsr/extension-manifest.json +11 -0
  102. package/dist/resources/extensions/universal-config/extension-manifest.json +13 -0
  103. package/dist/resources/extensions/voice/extension-manifest.json +12 -0
  104. package/dist/resources/skills/create-gsd-extension/SKILL.md +87 -0
  105. package/dist/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
  106. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
  107. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
  108. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
  109. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
  110. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
  111. package/dist/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
  112. package/dist/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
  113. package/dist/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
  114. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
  115. package/dist/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
  116. package/dist/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
  117. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
  118. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
  119. package/dist/resources/skills/create-gsd-extension/references/state-management.md +70 -0
  120. package/dist/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
  121. package/dist/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
  122. package/dist/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
  123. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
  124. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
  125. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
  126. package/dist/resources/skills/create-skill/SKILL.md +184 -0
  127. package/dist/resources/skills/create-skill/references/api-security.md +226 -0
  128. package/dist/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
  129. package/dist/resources/skills/create-skill/references/common-patterns.md +595 -0
  130. package/dist/resources/skills/create-skill/references/core-principles.md +437 -0
  131. package/dist/resources/skills/create-skill/references/executable-code.md +175 -0
  132. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
  133. package/dist/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
  134. package/dist/resources/skills/create-skill/references/recommended-structure.md +168 -0
  135. package/dist/resources/skills/create-skill/references/skill-structure.md +372 -0
  136. package/dist/resources/skills/create-skill/references/use-xml-tags.md +466 -0
  137. package/dist/resources/skills/create-skill/references/using-scripts.md +113 -0
  138. package/dist/resources/skills/create-skill/references/using-templates.md +112 -0
  139. package/dist/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
  140. package/dist/resources/skills/create-skill/templates/router-skill.md +73 -0
  141. package/dist/resources/skills/create-skill/templates/simple-skill.md +33 -0
  142. package/dist/resources/skills/create-skill/workflows/add-reference.md +96 -0
  143. package/dist/resources/skills/create-skill/workflows/add-script.md +93 -0
  144. package/dist/resources/skills/create-skill/workflows/add-template.md +74 -0
  145. package/dist/resources/skills/create-skill/workflows/add-workflow.md +120 -0
  146. package/dist/resources/skills/create-skill/workflows/audit-skill.md +148 -0
  147. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
  148. package/dist/resources/skills/create-skill/workflows/get-guidance.md +121 -0
  149. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
  150. package/dist/resources/skills/create-skill/workflows/verify-skill.md +204 -0
  151. package/dist/resources/skills/react-best-practices/SKILL.md +1 -1
  152. package/package.json +1 -1
  153. package/packages/native/dist/native.d.ts +2 -0
  154. package/packages/native/dist/native.js +19 -5
  155. package/packages/native/src/native.ts +23 -9
  156. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/extensions/loader.js +13 -0
  158. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  159. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -0
  161. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  162. package/packages/pi-coding-agent/src/core/extensions/loader.ts +13 -0
  163. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -0
  164. package/src/resources/extensions/async-jobs/extension-manifest.json +13 -0
  165. package/src/resources/extensions/bg-shell/extension-manifest.json +14 -0
  166. package/src/resources/extensions/bg-shell/process-manager.ts +13 -0
  167. package/src/resources/extensions/browser-tools/extension-manifest.json +37 -0
  168. package/src/resources/extensions/context7/extension-manifest.json +12 -0
  169. package/src/resources/extensions/google-search/extension-manifest.json +12 -0
  170. package/src/resources/extensions/gsd/auto-dashboard.ts +217 -65
  171. package/src/resources/extensions/gsd/auto-dispatch.ts +32 -3
  172. package/src/resources/extensions/gsd/auto-post-unit.ts +45 -13
  173. package/src/resources/extensions/gsd/auto-prompts.ts +40 -17
  174. package/src/resources/extensions/gsd/auto-recovery.ts +18 -23
  175. package/src/resources/extensions/gsd/auto-start.ts +18 -32
  176. package/src/resources/extensions/gsd/auto-worktree.ts +21 -182
  177. package/src/resources/extensions/gsd/auto.ts +2 -24
  178. package/src/resources/extensions/gsd/captures.ts +4 -10
  179. package/src/resources/extensions/gsd/commands-extensions.ts +328 -0
  180. package/src/resources/extensions/gsd/commands-handlers.ts +22 -2
  181. package/src/resources/extensions/gsd/commands-logs.ts +13 -14
  182. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
  183. package/src/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
  184. package/src/resources/extensions/gsd/commands.ts +108 -24
  185. package/src/resources/extensions/gsd/dashboard-overlay.ts +2 -1
  186. package/src/resources/extensions/gsd/detection.ts +2 -1
  187. package/src/resources/extensions/gsd/doctor-checks.ts +49 -1
  188. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  189. package/src/resources/extensions/gsd/extension-manifest.json +18 -0
  190. package/src/resources/extensions/gsd/forensics.ts +2 -2
  191. package/src/resources/extensions/gsd/git-service.ts +3 -2
  192. package/src/resources/extensions/gsd/gitignore.ts +9 -63
  193. package/src/resources/extensions/gsd/gsd-db.ts +1 -165
  194. package/src/resources/extensions/gsd/guided-flow.ts +8 -5
  195. package/src/resources/extensions/gsd/index.ts +3 -3
  196. package/src/resources/extensions/gsd/json-persistence.ts +16 -1
  197. package/src/resources/extensions/gsd/md-importer.ts +3 -2
  198. package/src/resources/extensions/gsd/mechanical-completion.ts +430 -0
  199. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  200. package/src/resources/extensions/gsd/migrate/writer.ts +2 -1
  201. package/src/resources/extensions/gsd/migrate-external.ts +123 -0
  202. package/src/resources/extensions/gsd/paths.ts +24 -2
  203. package/src/resources/extensions/gsd/post-unit-hooks.ts +6 -5
  204. package/src/resources/extensions/gsd/preferences-models.ts +7 -1
  205. package/src/resources/extensions/gsd/preferences-validation.ts +2 -1
  206. package/src/resources/extensions/gsd/preferences.ts +10 -5
  207. package/src/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
  208. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  209. package/src/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
  210. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -1
  211. package/src/resources/extensions/gsd/prompts/workflow-start.md +28 -0
  212. package/src/resources/extensions/gsd/queue-order.ts +10 -11
  213. package/src/resources/extensions/gsd/repo-identity.ts +148 -0
  214. package/src/resources/extensions/gsd/resource-version.ts +99 -0
  215. package/src/resources/extensions/gsd/session-forensics.ts +4 -3
  216. package/src/resources/extensions/gsd/session-status-io.ts +23 -41
  217. package/src/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
  218. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
  219. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
  220. package/src/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
  221. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
  222. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
  223. package/src/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
  224. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
  225. package/src/resources/extensions/gsd/tests/git-service.test.ts +10 -37
  226. package/src/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
  227. package/src/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
  228. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
  229. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
  230. package/src/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
  231. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
  232. package/src/resources/extensions/gsd/triage-resolution.ts +2 -1
  233. package/src/resources/extensions/gsd/types.ts +2 -0
  234. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
  235. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
  236. package/src/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
  237. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
  238. package/src/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
  239. package/src/resources/extensions/gsd/workflow-templates/registry.json +85 -0
  240. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
  241. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
  242. package/src/resources/extensions/gsd/workflow-templates/spike.md +69 -0
  243. package/src/resources/extensions/gsd/workflow-templates.ts +241 -0
  244. package/src/resources/extensions/gsd/worktree-command.ts +1 -11
  245. package/src/resources/extensions/gsd/worktree-manager.ts +3 -2
  246. package/src/resources/extensions/gsd/worktree.ts +42 -5
  247. package/src/resources/extensions/mac-tools/extension-manifest.json +16 -0
  248. package/src/resources/extensions/mcp-client/index.ts +459 -0
  249. package/src/resources/extensions/mcporter/extension-manifest.json +12 -0
  250. package/src/resources/extensions/remote-questions/discord-adapter.ts +8 -19
  251. package/src/resources/extensions/remote-questions/extension-manifest.json +11 -0
  252. package/src/resources/extensions/remote-questions/http-client.ts +76 -0
  253. package/src/resources/extensions/remote-questions/slack-adapter.ts +11 -17
  254. package/src/resources/extensions/remote-questions/telegram-adapter.ts +8 -19
  255. package/src/resources/extensions/search-the-web/extension-manifest.json +13 -0
  256. package/src/resources/extensions/slash-commands/extension-manifest.json +11 -0
  257. package/src/resources/extensions/subagent/extension-manifest.json +13 -0
  258. package/src/resources/extensions/ttsr/extension-manifest.json +11 -0
  259. package/src/resources/extensions/universal-config/extension-manifest.json +13 -0
  260. package/src/resources/extensions/voice/extension-manifest.json +12 -0
  261. package/src/resources/skills/create-gsd-extension/SKILL.md +87 -0
  262. package/src/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
  263. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
  264. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
  265. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
  266. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
  267. package/src/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
  268. package/src/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
  269. package/src/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
  270. package/src/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
  271. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
  272. package/src/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
  273. package/src/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
  274. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
  275. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
  276. package/src/resources/skills/create-gsd-extension/references/state-management.md +70 -0
  277. package/src/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
  278. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
  279. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
  280. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
  281. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
  282. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
  283. package/src/resources/skills/create-skill/SKILL.md +184 -0
  284. package/src/resources/skills/create-skill/references/api-security.md +226 -0
  285. package/src/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
  286. package/src/resources/skills/create-skill/references/common-patterns.md +595 -0
  287. package/src/resources/skills/create-skill/references/core-principles.md +437 -0
  288. package/src/resources/skills/create-skill/references/executable-code.md +175 -0
  289. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
  290. package/src/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
  291. package/src/resources/skills/create-skill/references/recommended-structure.md +168 -0
  292. package/src/resources/skills/create-skill/references/skill-structure.md +372 -0
  293. package/src/resources/skills/create-skill/references/use-xml-tags.md +466 -0
  294. package/src/resources/skills/create-skill/references/using-scripts.md +113 -0
  295. package/src/resources/skills/create-skill/references/using-templates.md +112 -0
  296. package/src/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
  297. package/src/resources/skills/create-skill/templates/router-skill.md +73 -0
  298. package/src/resources/skills/create-skill/templates/simple-skill.md +33 -0
  299. package/src/resources/skills/create-skill/workflows/add-reference.md +96 -0
  300. package/src/resources/skills/create-skill/workflows/add-script.md +93 -0
  301. package/src/resources/skills/create-skill/workflows/add-template.md +74 -0
  302. package/src/resources/skills/create-skill/workflows/add-workflow.md +120 -0
  303. package/src/resources/skills/create-skill/workflows/audit-skill.md +148 -0
  304. package/src/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
  305. package/src/resources/skills/create-skill/workflows/get-guidance.md +121 -0
  306. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
  307. package/src/resources/skills/create-skill/workflows/verify-skill.md +204 -0
  308. package/src/resources/skills/react-best-practices/SKILL.md +1 -1
  309. package/dist/resources/extensions/gsd/auto-worktree-sync.ts +0 -198
  310. package/dist/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
  311. package/dist/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
  312. package/dist/resources/extensions/mcporter/index.ts +0 -525
  313. package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -198
  314. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
  315. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
  316. package/src/resources/extensions/mcporter/index.ts +0 -525
@@ -6,7 +6,7 @@
6
6
 
7
7
  import test from "node:test";
8
8
  import assert from "node:assert/strict";
9
- import { existsSync, mkdtempSync, mkdirSync, readdirSync, rmSync, utimesSync, writeFileSync, readFileSync } from "node:fs";
9
+ import { existsSync, mkdtempSync, mkdirSync, readdirSync, realpathSync, rmSync, utimesSync, writeFileSync, readFileSync } from "node:fs";
10
10
  import { join, dirname } from "node:path";
11
11
  import { tmpdir } from "node:os";
12
12
  import { fileURLToPath } from "node:url";
@@ -18,7 +18,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
18
18
  // ── Helpers ──────────────────────────────────────────────────────────────────
19
19
 
20
20
  function createTmpDir(): string {
21
- return mkdtempSync(join(tmpdir(), "gsd-activity-test-"));
21
+ return realpathSync(mkdtempSync(join(tmpdir(), "gsd-activity-test-")));
22
22
  }
23
23
 
24
24
  function writeActivityFile(dir: string, seq: string, name: string): string {
@@ -5,7 +5,7 @@ import {
5
5
  getBudgetAlertLevel,
6
6
  getBudgetEnforcementAction,
7
7
  getNewBudgetAlertLevel,
8
- } from "../auto.js";
8
+ } from "../auto-budget.js";
9
9
 
10
10
  test("getBudgetAlertLevel returns the expected threshold bucket", () => {
11
11
  assert.equal(getBudgetAlertLevel(0.10), 0);
@@ -308,8 +308,8 @@ test("loadPersistedKeys unions keys from project root and worktree", () => {
308
308
  });
309
309
 
310
310
  test("completed-units.json set-union merge produces correct result", () => {
311
- // Verify that a manual set-union merge (as done in syncStateToProjectRoot)
312
- // correctly merges two JSON arrays of keys.
311
+ // Verify that a manual set-union merge correctly merges two JSON arrays
312
+ // of completed-unit keys.
313
313
  const projectRoot = makeTmpBase();
314
314
  const worktree = makeTmpBase();
315
315
  try {
@@ -320,7 +320,7 @@ test("completed-units.json set-union merge produces correct result", () => {
320
320
  writeFileSync(prKeysFile, JSON.stringify(["a", "b"]));
321
321
  writeFileSync(wtKeysFile, JSON.stringify(["b", "c", "d"]));
322
322
 
323
- // Perform the same merge logic used in syncStateToProjectRoot
323
+ // Perform a set-union merge of two JSON key arrays
324
324
  const srcKeys: string[] = JSON.parse(readFileSync(wtKeysFile, "utf8"));
325
325
  let dstKeys: string[] = [];
326
326
  if (existsSync(prKeysFile)) {
@@ -17,8 +17,8 @@ import { tmpdir } from "node:os";
17
17
  import {
18
18
  _getUnitConsecutiveSkips,
19
19
  _resetUnitConsecutiveSkips,
20
- MAX_CONSECUTIVE_SKIPS,
21
20
  } from "../auto.ts";
21
+ import { MAX_CONSECUTIVE_SKIPS } from "../auto/session.ts";
22
22
  import { persistCompletedKey, removePersistedKey, loadPersistedKeys } from "../auto-recovery.ts";
23
23
  import { createTestContext } from "./test-helpers.ts";
24
24
 
@@ -153,64 +153,6 @@ async function main(): Promise<void> {
153
153
  // After teardown, originalBase should be null
154
154
  assertEq(getAutoWorktreeOriginalBase(), null, "no split-brain: originalBase cleared");
155
155
 
156
- // ─── #778: reconcile plan checkboxes on re-attach ─────────────────
157
- console.log("\n=== #778: reconcile plan checkboxes on re-attach ===");
158
- {
159
- // Simulate: T01 [x] was committed to milestone branch, T02 [x] was
160
- // written to project root by syncStateToProjectRoot() but the
161
- // auto-commit crashed before it fired. On restart the worktree is
162
- // re-created from the milestone branch HEAD (T02 still [ ]).
163
- // reconcilePlanCheckboxes should forward-apply T02 [x] from the root.
164
-
165
- const planRelPath = join(".gsd", "milestones", "M004", "slices", "S01", "S01-PLAN.md");
166
- const planDir = join(tempDir, ".gsd", "milestones", "M004", "slices", "S01");
167
- const { mkdirSync: mkdir, writeFileSync: write, readFileSync: read } = await import("node:fs");
168
-
169
- // Plan on integration branch (project root): T01 [x], T02 [x]
170
- mkdir(planDir, { recursive: true });
171
- write(
172
- join(tempDir, planRelPath),
173
- "# S01 Plan\n- [x] **T01:** task one\n- [x] **T02:** task two\n- [ ] **T03:** task three\n",
174
- );
175
-
176
- // Write integration-branch plan to git so milestone branch starts from it
177
- run(`git add .`, tempDir);
178
- run(`git commit -m "add plan with T01 and T02 checked" --allow-empty`, tempDir);
179
-
180
- // Create milestone branch with only T01 [x] (simulating crash before T02 commit)
181
- const milestoneBranch = "milestone/M004";
182
- run(`git checkout -b ${milestoneBranch}`, tempDir);
183
- mkdir(planDir, { recursive: true });
184
- write(
185
- join(tempDir, planRelPath),
186
- "# S01 Plan\n- [x] **T01:** task one\n- [ ] **T02:** task two\n- [ ] **T03:** task three\n",
187
- );
188
- run(`git add .`, tempDir);
189
- run(`git commit -m "milestone: only T01 checked"`, tempDir);
190
- run(`git checkout main`, tempDir);
191
-
192
- // Restore project root plan (T01+T02 [x]) — simulates syncStateToProjectRoot
193
- write(
194
- join(tempDir, planRelPath),
195
- "# S01 Plan\n- [x] **T01:** task one\n- [x] **T02:** task two\n- [ ] **T03:** task three\n",
196
- );
197
-
198
- // Create worktree re-attached to existing milestone branch (T02 still [ ] in branch)
199
- const wtPath = createAutoWorktree(tempDir, "M004");
200
-
201
- try {
202
- const wtPlanPath = join(wtPath, planRelPath);
203
- assertTrue(existsSync(wtPlanPath), "plan file exists in worktree after re-attach");
204
-
205
- const wtPlan = read(wtPlanPath, "utf-8");
206
- assertTrue(wtPlan.includes("- [x] **T02:"), "T02 should be [x] after reconciliation (was [ ] on branch)");
207
- assertTrue(wtPlan.includes("- [x] **T01:"), "T01 stays [x]");
208
- assertTrue(wtPlan.includes("- [ ] **T03:"), "T03 stays [ ] (not in root either)");
209
- } finally {
210
- teardownAutoWorktree(tempDir, "M004");
211
- }
212
- }
213
-
214
156
  } finally {
215
157
  // Always restore cwd and clean up
216
158
  process.chdir(savedCwd);
@@ -231,15 +231,14 @@ None
231
231
  const detect = await runGSDDoctor(dir);
232
232
  const gitignoreIssues = detect.issues.filter(i => i.code === "gitignore_missing_patterns");
233
233
  assertTrue(gitignoreIssues.length > 0, "detects missing gitignore patterns");
234
- assertTrue(gitignoreIssues[0]?.message.includes(".gsd/activity/"), "message lists missing patterns");
234
+ assertTrue(gitignoreIssues[0]?.message.includes(".gsd"), "message lists missing .gsd pattern");
235
235
 
236
236
  const fixed = await runGSDDoctor(dir, { fix: true });
237
237
  assertTrue(fixed.fixesApplied.some(f => f.includes("added missing GSD runtime patterns")), "fix adds patterns");
238
238
 
239
- // Verify patterns were added
239
+ // Verify .gsd entry was added (external state symlink)
240
240
  const content = readFileSync(join(dir, ".gitignore"), "utf-8");
241
- assertTrue(content.includes(".gsd/activity/"), "gitignore now has activity pattern");
242
- assertTrue(content.includes(".gsd/auto.lock"), "gitignore now has auto.lock pattern");
241
+ assertTrue(content.includes(".gsd"), "gitignore now has .gsd entry");
243
242
  }
244
243
  } else {
245
244
  console.log("\n=== gitignore_missing_patterns (skipped on Windows) ===");
@@ -1,4 +1,6 @@
1
- // Tests for the SEPARATOR_PREFIX convention used by ExtensionSelectorComponent.
1
+ // Tests for the SEPARATOR_PREFIX convention used by ExtensionSelectorComponent
2
+ // and the two-step provider→model picker in configureModels.
3
+ //
2
4
  // We cannot import the component directly in node:test because its transitive
3
5
  // dependency (countdown-timer.ts) uses TypeScript parameter properties which
4
6
  // are unsupported under --experimental-strip-types. Instead we duplicate the
@@ -69,16 +71,17 @@ describe("separator detection", () => {
69
71
  });
70
72
  });
71
73
 
72
- describe("model grouping", () => {
73
- test("groups models by provider with separator headers", () => {
74
- // Simulate the grouping logic from configureModels
75
- const availableModels = [
76
- { id: "claude-opus-4-6", provider: "anthropic" },
77
- { id: "gpt-4o", provider: "openai" },
78
- { id: "claude-sonnet-4-5", provider: "anthropic" },
79
- { id: "o3-mini", provider: "openai" },
80
- ];
74
+ describe("two-step provider→model picker", () => {
75
+ // Simulate the grouping logic from configureModels
76
+ const availableModels = [
77
+ { id: "claude-opus-4-6", provider: "anthropic" },
78
+ { id: "gpt-4o", provider: "openai" },
79
+ { id: "claude-sonnet-4-5", provider: "anthropic" },
80
+ { id: "o3-mini", provider: "openai" },
81
+ { id: "claude-haiku-4-5", provider: "anthropic" },
82
+ ];
81
83
 
84
+ function buildProviderGroups() {
82
85
  const byProvider = new Map<string, typeof availableModels>();
83
86
  for (const m of availableModels) {
84
87
  let group = byProvider.get(m.provider);
@@ -89,34 +92,53 @@ describe("model grouping", () => {
89
92
  group.push(m);
90
93
  }
91
94
  const providers = Array.from(byProvider.keys()).sort((a, b) => a.localeCompare(b));
92
-
93
- const modelOptions: string[] = [];
94
- for (const provider of providers) {
95
- const group = byProvider.get(provider)!;
96
- modelOptions.push(`${SEPARATOR_PREFIX} ${provider} (${group.length}) ${SEPARATOR_PREFIX}`);
97
- for (const m of group) {
98
- modelOptions.push(`${m.id} · ${m.provider}`);
99
- }
95
+ for (const group of byProvider.values()) {
96
+ group.sort((a, b) => a.id.localeCompare(b.id));
100
97
  }
101
- modelOptions.push("(keep current)", "(clear)");
102
-
103
- // Verify structure
104
- assert.strictEqual(modelOptions[0], `${SEPARATOR_PREFIX} anthropic (2) ${SEPARATOR_PREFIX}`);
105
- assert.strictEqual(modelOptions[1], "claude-opus-4-6 · anthropic");
106
- assert.strictEqual(modelOptions[2], "claude-sonnet-4-5 · anthropic");
107
- assert.strictEqual(modelOptions[3], `${SEPARATOR_PREFIX} openai (2) ${SEPARATOR_PREFIX}`);
108
- assert.strictEqual(modelOptions[4], "gpt-4o · openai");
109
- assert.strictEqual(modelOptions[5], "o3-mini · openai");
110
- assert.strictEqual(modelOptions[6], "(keep current)");
111
- assert.strictEqual(modelOptions[7], "(clear)");
112
-
113
- // Verify separators are correctly detected
114
- assert.ok(isSeparator(modelOptions, 0));
115
- assert.ok(!isSeparator(modelOptions, 1));
116
- assert.ok(isSeparator(modelOptions, 3));
117
- assert.ok(!isSeparator(modelOptions, 6));
118
-
119
- // Verify first selectable is index 1, not the separator at 0
120
- assert.strictEqual(nextSelectable(modelOptions, 0, 1), 1);
98
+ return { byProvider, providers };
99
+ }
100
+
101
+ test("provider menu lists providers with model counts", () => {
102
+ const { providers, byProvider } = buildProviderGroups();
103
+ const providerOptions = providers.map(p => {
104
+ const count = byProvider.get(p)!.length;
105
+ return `${p} (${count} models)`;
106
+ });
107
+ providerOptions.push("(keep current)", "(clear)", "(type manually)");
108
+
109
+ assert.strictEqual(providerOptions[0], "anthropic (3 models)");
110
+ assert.strictEqual(providerOptions[1], "openai (2 models)");
111
+ assert.strictEqual(providerOptions[2], "(keep current)");
112
+ assert.strictEqual(providerOptions[3], "(clear)");
113
+ assert.strictEqual(providerOptions[4], "(type manually)");
114
+ });
115
+
116
+ test("model menu for a provider is sorted alphabetically", () => {
117
+ const { byProvider } = buildProviderGroups();
118
+ const anthropicModels = byProvider.get("anthropic")!;
119
+ const modelOptions = anthropicModels.map(m => m.id);
120
+
121
+ assert.strictEqual(modelOptions[0], "claude-haiku-4-5");
122
+ assert.strictEqual(modelOptions[1], "claude-opus-4-6");
123
+ assert.strictEqual(modelOptions[2], "claude-sonnet-4-5");
124
+ });
125
+
126
+ test("provider name is extracted correctly from choice string", () => {
127
+ const choice = "anthropic (3 models)";
128
+ const providerName = choice.replace(/ \(\d+ models?\)$/, "");
129
+ assert.strictEqual(providerName, "anthropic");
130
+
131
+ const singleChoice = "ollama (1 model)";
132
+ const singleProvider = singleChoice.replace(/ \(\d+ models?\)$/, "");
133
+ assert.strictEqual(singleProvider, "ollama");
134
+ });
135
+
136
+ test("openai models are sorted within their group", () => {
137
+ const { byProvider } = buildProviderGroups();
138
+ const openaiModels = byProvider.get("openai")!;
139
+ const modelOptions = openaiModels.map(m => m.id);
140
+
141
+ assert.strictEqual(modelOptions[0], "gpt-4o");
142
+ assert.strictEqual(modelOptions[1], "o3-mini");
121
143
  });
122
144
  });
@@ -311,7 +311,7 @@ async function main(): Promise<void> {
311
311
  // Test 2: Uncommitted .gsd/ planning files are available in worktree
312
312
  //
313
313
  // When auto-mode starts, .gsd/ files may be untracked/uncommitted.
314
- // copyPlanningArtifacts should carry them into the worktree even if
314
+ // Planning artifacts should be carried into the worktree even if
315
315
  // they weren't committed on the feature branch.
316
316
  // ================================================================
317
317
  console.log("\n=== Untracked planning files copied to worktree ===");
@@ -341,23 +341,10 @@ async function main(): Promise<void> {
341
341
  const wtPath = createAutoWorktree(repo, milestoneId);
342
342
  tempDirs.push(wtPath);
343
343
 
344
- // Planning files should exist in the worktree (via copyPlanningArtifacts)
345
- assertTrue(
346
- existsSync(join(wtPath, ".gsd", "milestones", milestoneId, `${milestoneId}-ROADMAP.md`)),
347
- "ROADMAP.md copied to worktree",
348
- );
349
- assertTrue(
350
- existsSync(join(wtPath, ".gsd", "milestones", milestoneId, "slices", "S01", "S01-PLAN.md")),
351
- "S01-PLAN.md copied to worktree",
352
- );
353
- assertTrue(
354
- existsSync(join(wtPath, ".gsd", "PROJECT.md")),
355
- "PROJECT.md copied to worktree",
356
- );
357
- assertTrue(
358
- existsSync(join(wtPath, ".gsd", "DECISIONS.md")),
359
- "DECISIONS.md copied to worktree",
360
- );
344
+ // With external state, worktree .gsd is a symlink to shared state.
345
+ // Verify symlink was created (planning files are shared, not copied).
346
+ const wtGsd = join(wtPath, ".gsd");
347
+ assertTrue(existsSync(wtGsd), "worktree .gsd exists (symlink or dir)");
361
348
 
362
349
  // Clean up: chdir back before teardown
363
350
  process.chdir(savedCwd);
@@ -1167,53 +1167,26 @@ async function main(): Promise<void> {
1167
1167
  rmSync(repo, { recursive: true, force: true });
1168
1168
  }
1169
1169
 
1170
- // ─── ensureGitignore: commit_docs false adds blanket .gsd/ ──────────
1170
+ // ─── ensureGitignore: always adds .gsd to gitignore ──────────────────
1171
1171
 
1172
- console.log("\n=== ensureGitignore: commit_docs false ===");
1172
+ console.log("\n=== ensureGitignore: adds .gsd entry ===");
1173
1173
 
1174
1174
  {
1175
1175
  const { ensureGitignore } = await import("../gitignore.ts");
1176
- const repo = mkdtempSync(join(tmpdir(), "gsd-gitignore-commit-docs-"));
1176
+ const repo = mkdtempSync(join(tmpdir(), "gsd-gitignore-external-state-"));
1177
1177
 
1178
- // When commit_docs is false, should add blanket .gsd/ to gitignore
1179
- const modified = ensureGitignore(repo, { commitDocs: false });
1180
- assertTrue(modified, "commit_docs=false: gitignore was modified");
1178
+ // Should add .gsd to gitignore (external state dir is a symlink)
1179
+ const modified = ensureGitignore(repo);
1180
+ assertTrue(modified, "ensureGitignore: gitignore was modified");
1181
1181
 
1182
1182
  const { readFileSync } = await import("node:fs");
1183
1183
  const content = readFileSync(join(repo, ".gitignore"), "utf-8");
1184
- assertTrue(content.includes(".gsd/"), "commit_docs=false: .gitignore contains blanket .gsd/");
1185
- assertTrue(content.includes("commit_docs: false"), "commit_docs=false: .gitignore contains explanatory comment");
1186
-
1187
- // Should NOT contain individual runtime patterns (those are subsumed by blanket .gsd/)
1188
- // But it's OK if it does — the blanket .gsd/ covers everything
1184
+ const lines = content.split("\n").map(l => l.trim()).filter(l => l && !l.startsWith("#"));
1185
+ assertTrue(lines.includes(".gsd"), "ensureGitignore: .gitignore contains .gsd");
1189
1186
 
1190
1187
  // Idempotent — calling again doesn't add duplicates
1191
- const modified2 = ensureGitignore(repo, { commitDocs: false });
1192
- assertTrue(!modified2, "commit_docs=false: second call is idempotent");
1193
-
1194
- rmSync(repo, { recursive: true, force: true });
1195
- }
1196
-
1197
- // ─── ensureGitignore: commit_docs true removes blanket .gsd/ ────────
1198
-
1199
- console.log("\n=== ensureGitignore: commit_docs true self-heals ===");
1200
-
1201
- {
1202
- const { ensureGitignore } = await import("../gitignore.ts");
1203
- const repo = mkdtempSync(join(tmpdir(), "gsd-gitignore-selfheal-"));
1204
-
1205
- // Start with a gitignore that has a blanket .gsd/ (e.g., user switched setting)
1206
- writeFileSync(join(repo, ".gitignore"), ".gsd/\n");
1207
-
1208
- const modified = ensureGitignore(repo, { commitDocs: true });
1209
- assertTrue(modified, "commit_docs=true: gitignore was modified");
1210
-
1211
- const { readFileSync } = await import("node:fs");
1212
- const content = readFileSync(join(repo, ".gitignore"), "utf-8");
1213
- // Blanket .gsd/ should be removed
1214
- const lines = content.split("\n").map(l => l.trim()).filter(l => l && !l.startsWith("#"));
1215
- assertTrue(!lines.includes(".gsd/"), "commit_docs=true: blanket .gsd/ was removed");
1216
- assertTrue(!lines.includes(".gsd"), "commit_docs=true: blanket .gsd was removed");
1188
+ const modified2 = ensureGitignore(repo);
1189
+ assertTrue(!modified2, "ensureGitignore: second call is idempotent");
1217
1190
 
1218
1191
  rmSync(repo, { recursive: true, force: true });
1219
1192
  }
@@ -10,7 +10,7 @@
10
10
 
11
11
  import test from 'node:test';
12
12
  import assert from 'node:assert/strict';
13
- import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync } from 'node:fs';
13
+ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync, realpathSync } from 'node:fs';
14
14
  import { join } from 'node:path';
15
15
  import { tmpdir } from 'node:os';
16
16
  import { GSD_ROOT_FILES, resolveGsdRootFile } from '../paths.ts';
@@ -27,7 +27,7 @@ test('knowledge: KNOWLEDGE key exists in GSD_ROOT_FILES', () => {
27
27
  // ─── resolveGsdRootFile resolves KNOWLEDGE.md ───────────────────────────────
28
28
 
29
29
  test('knowledge: resolveGsdRootFile returns canonical path when KNOWLEDGE.md exists', () => {
30
- const tmp = mkdtempSync(join(tmpdir(), 'gsd-knowledge-'));
30
+ const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-knowledge-')));
31
31
  const gsdDir = join(tmp, '.gsd');
32
32
  mkdirSync(gsdDir, { recursive: true });
33
33
  writeFileSync(join(gsdDir, 'KNOWLEDGE.md'), '# Project Knowledge\n');
@@ -39,7 +39,7 @@ test('knowledge: resolveGsdRootFile returns canonical path when KNOWLEDGE.md exi
39
39
  });
40
40
 
41
41
  test('knowledge: resolveGsdRootFile resolves when legacy knowledge.md exists', () => {
42
- const tmp = mkdtempSync(join(tmpdir(), 'gsd-knowledge-'));
42
+ const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-knowledge-')));
43
43
  const gsdDir = join(tmp, '.gsd');
44
44
  mkdirSync(gsdDir, { recursive: true });
45
45
  writeFileSync(join(gsdDir, 'knowledge.md'), '# Project Knowledge\n');
@@ -58,7 +58,7 @@ test('knowledge: resolveGsdRootFile resolves when legacy knowledge.md exists', (
58
58
  });
59
59
 
60
60
  test('knowledge: resolveGsdRootFile returns canonical path when file does not exist', () => {
61
- const tmp = mkdtempSync(join(tmpdir(), 'gsd-knowledge-'));
61
+ const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-knowledge-')));
62
62
  const gsdDir = join(tmp, '.gsd');
63
63
  mkdirSync(gsdDir, { recursive: true });
64
64