@opengsd/gsd-pi 1.0.2-dev.e9a1b49 → 1.0.2-dev.fb7ddf1

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 (490) hide show
  1. package/README.md +63 -12
  2. package/dist/headless-answers.js +2 -1
  3. package/dist/headless-events.d.ts +1 -0
  4. package/dist/headless-events.js +8 -1
  5. package/dist/onboarding.js +22 -3
  6. package/dist/resource-loader.d.ts +7 -0
  7. package/dist/resource-loader.js +44 -9
  8. package/dist/resources/.managed-resources-content-hash +1 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -11
  10. package/dist/resources/extensions/context7/index.js +12 -2
  11. package/dist/resources/extensions/get-secrets-from-user.js +16 -16
  12. package/dist/resources/extensions/google-cli/index.js +30 -0
  13. package/dist/resources/extensions/google-cli/models.js +55 -0
  14. package/dist/resources/extensions/google-cli/package.json +11 -0
  15. package/dist/resources/extensions/google-cli/readiness.js +12 -0
  16. package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +81 -1
  18. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
  19. package/dist/resources/extensions/gsd/auto/phases.js +38 -1
  20. package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
  21. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
  23. package/dist/resources/extensions/gsd/auto-post-unit.js +65 -16
  24. package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
  25. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  26. package/dist/resources/extensions/gsd/auto-start.js +232 -49
  27. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -1
  28. package/dist/resources/extensions/gsd/auto-verification.js +14 -2
  29. package/dist/resources/extensions/gsd/auto-worktree.js +36 -55
  30. package/dist/resources/extensions/gsd/auto.js +40 -2
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
  32. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
  33. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +107 -27
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
  36. package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +4 -4
  37. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  38. package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
  40. package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
  41. package/dist/resources/extensions/gsd/commands-usage.js +105 -1
  42. package/dist/resources/extensions/gsd/config-overlay.js +20 -14
  43. package/dist/resources/extensions/gsd/context-overlay.js +22 -16
  44. package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
  45. package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
  46. package/dist/resources/extensions/gsd/doctor-git-checks.js +70 -5
  47. package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
  48. package/dist/resources/extensions/gsd/doctor.js +7 -2
  49. package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
  50. package/dist/resources/extensions/gsd/guided-flow.js +5 -6
  51. package/dist/resources/extensions/gsd/key-manager.js +45 -13
  52. package/dist/resources/extensions/gsd/mcp-filter.js +57 -18
  53. package/dist/resources/extensions/gsd/mcp-project-config.js +15 -9
  54. package/dist/resources/extensions/gsd/migration-auto-check.js +5 -1
  55. package/dist/resources/extensions/gsd/milestone-actions.js +3 -0
  56. package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
  57. package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
  58. package/dist/resources/extensions/gsd/parallel-merge.js +6 -4
  59. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
  60. package/dist/resources/extensions/gsd/post-execution-checks.js +5 -4
  61. package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
  62. package/dist/resources/extensions/gsd/preferences.js +14 -2
  63. package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
  64. package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
  65. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  66. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  67. package/dist/resources/extensions/gsd/prompts/system.md +3 -20
  68. package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
  69. package/dist/resources/extensions/gsd/repo-identity.js +36 -6
  70. package/dist/resources/extensions/gsd/repository-registry.js +3 -1
  71. package/dist/resources/extensions/gsd/safety/evidence-collector.js +13 -6
  72. package/dist/resources/extensions/gsd/skill-activation.js +233 -0
  73. package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
  74. package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
  75. package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
  76. package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
  77. package/dist/resources/extensions/gsd/skill-scope.js +52 -0
  78. package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
  79. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
  80. package/dist/resources/extensions/gsd/skills.js +60 -0
  81. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
  82. package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
  83. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
  84. package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
  85. package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
  86. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
  87. package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
  88. package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
  89. package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
  90. package/dist/resources/extensions/gsd/vision-ask.js +22 -0
  91. package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
  92. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
  93. package/dist/resources/extensions/gsd/worktree-post-create-hook.js +117 -0
  94. package/dist/resources/extensions/gsd/worktree-state-projection.js +29 -0
  95. package/dist/resources/extensions/search-the-web/native-search.js +57 -8
  96. package/dist/resources/extensions/shared/confirm-ui.js +9 -6
  97. package/dist/resources/extensions/shared/dialog-frame.js +42 -0
  98. package/dist/resources/extensions/shared/interview-ui.js +42 -30
  99. package/dist/resources/extensions/shared/next-action-ui.js +6 -6
  100. package/dist/resources/extensions/subagent/index.js +8 -15
  101. package/dist/resources/shared/package-manager-detection.js +36 -0
  102. package/dist/resources/skills/agent-browser/SKILL.md +1 -1
  103. package/dist/resources/skills/api-design/SKILL.md +1 -1
  104. package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
  105. package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
  106. package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
  107. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  108. package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  109. package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  110. package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
  111. package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
  112. package/dist/resources/skills/forensics/SKILL.md +2 -2
  113. package/dist/resources/skills/grill-me/SKILL.md +1 -1
  114. package/dist/resources/skills/handoff/SKILL.md +1 -1
  115. package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  116. package/dist/resources/skills/observability/SKILL.md +1 -1
  117. package/dist/resources/skills/security-review/SKILL.md +1 -1
  118. package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
  119. package/dist/resources/skills/tdd/SKILL.md +1 -1
  120. package/dist/resources/skills/write-docs/SKILL.md +1 -1
  121. package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
  122. package/dist/update-check.d.ts +6 -2
  123. package/dist/update-check.js +7 -3
  124. package/dist/web/standalone/.next/BUILD_ID +1 -1
  125. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  126. package/dist/web/standalone/.next/build-manifest.json +2 -2
  127. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  128. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/index.html +1 -1
  146. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  153. package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
  154. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  156. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  157. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  158. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  159. package/dist/worktree-cli.d.ts +0 -2
  160. package/dist/worktree-cli.js +21 -9
  161. package/package.json +5 -2
  162. package/packages/cloud-mcp-gateway/bin/gsd-cloud-mcp-gateway.js +14 -0
  163. package/packages/cloud-mcp-gateway/package.json +4 -3
  164. package/packages/contracts/dist/rpc.test.js +5 -0
  165. package/packages/contracts/dist/rpc.test.js.map +1 -1
  166. package/packages/contracts/dist/workflow.d.ts +15 -0
  167. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  168. package/packages/contracts/dist/workflow.js +16 -0
  169. package/packages/contracts/dist/workflow.js.map +1 -1
  170. package/packages/contracts/dist/workflow.test.js +1 -0
  171. package/packages/contracts/dist/workflow.test.js.map +1 -1
  172. package/packages/contracts/package.json +1 -1
  173. package/packages/daemon/package.json +4 -4
  174. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
  175. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  176. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
  177. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  178. package/packages/gsd-agent-core/package.json +5 -5
  179. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
  180. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
  181. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
  182. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
  183. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
  184. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
  186. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
  187. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
  198. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
  202. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
  204. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  205. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
  206. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  208. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
  209. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  210. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  211. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
  212. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  213. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
  214. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  215. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
  216. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  217. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  218. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
  219. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  220. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
  221. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  222. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
  223. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  224. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
  225. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
  226. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
  227. package/packages/gsd-agent-modes/package.json +7 -7
  228. package/packages/mcp-server/bin/gsd-mcp-server.js +14 -0
  229. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  230. package/packages/mcp-server/dist/server.js +7 -1
  231. package/packages/mcp-server/dist/server.js.map +1 -1
  232. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  233. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  234. package/packages/mcp-server/dist/workflow-tools.js +47 -8
  235. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  236. package/packages/mcp-server/package.json +5 -4
  237. package/packages/native/package.json +1 -1
  238. package/packages/pi-agent-core/dist/agent-loop.js +16 -14
  239. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  240. package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
  241. package/packages/pi-agent-core/dist/harness/skills.js +6 -0
  242. package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
  243. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
  244. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
  245. package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
  246. package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
  247. package/packages/pi-agent-core/package.json +1 -1
  248. package/packages/pi-ai/bin/pi-ai.js +14 -0
  249. package/packages/pi-ai/dist/models.generated.d.ts +48 -206
  250. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/models.generated.js +73 -226
  252. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  253. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/providers/anthropic.js +50 -0
  255. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  256. package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  257. package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
  258. package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  259. package/packages/pi-ai/dist/types.d.ts +2 -0
  260. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  261. package/packages/pi-ai/dist/types.js.map +1 -1
  262. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js +29 -1
  263. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
  264. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
  265. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
  266. package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
  267. package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
  268. package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
  269. package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
  270. package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
  271. package/packages/pi-ai/package.json +3 -2
  272. package/packages/pi-coding-agent/README.md +1 -1
  273. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
  274. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
  277. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  278. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
  280. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
  282. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/skills.js +3 -0
  284. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
  287. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
  289. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
  291. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
  294. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  295. package/packages/pi-coding-agent/package.json +8 -8
  296. package/packages/pi-tui/package.json +1 -1
  297. package/packages/rpc-client/package.json +2 -2
  298. package/pkg/package.json +1 -1
  299. package/scripts/install/deps.js +10 -0
  300. package/scripts/install/detect-existing.js +17 -3
  301. package/scripts/install/npm-global.js +103 -33
  302. package/scripts/install.js +1 -0
  303. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
  304. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
  305. package/src/resources/extensions/context7/index.ts +15 -2
  306. package/src/resources/extensions/get-secrets-from-user.ts +17 -16
  307. package/src/resources/extensions/google-cli/index.ts +34 -0
  308. package/src/resources/extensions/google-cli/models.ts +57 -0
  309. package/src/resources/extensions/google-cli/package.json +11 -0
  310. package/src/resources/extensions/google-cli/readiness.ts +15 -0
  311. package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
  312. package/src/resources/extensions/gsd/auto/loop.ts +96 -1
  313. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
  314. package/src/resources/extensions/gsd/auto/phases.ts +47 -1
  315. package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
  316. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  317. package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
  318. package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
  319. package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
  320. package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
  321. package/src/resources/extensions/gsd/auto-start.ts +307 -56
  322. package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
  323. package/src/resources/extensions/gsd/auto-verification.ts +18 -2
  324. package/src/resources/extensions/gsd/auto-worktree.ts +47 -57
  325. package/src/resources/extensions/gsd/auto.ts +50 -2
  326. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
  327. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
  328. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
  329. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
  330. package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
  331. package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
  332. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  333. package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
  334. package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
  335. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  336. package/src/resources/extensions/gsd/commands-usage.ts +110 -5
  337. package/src/resources/extensions/gsd/config-overlay.ts +19 -16
  338. package/src/resources/extensions/gsd/context-overlay.ts +24 -19
  339. package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
  340. package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
  341. package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
  342. package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
  343. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  344. package/src/resources/extensions/gsd/doctor.ts +7 -2
  345. package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
  346. package/src/resources/extensions/gsd/guided-flow.ts +5 -6
  347. package/src/resources/extensions/gsd/key-manager.ts +57 -14
  348. package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
  349. package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
  350. package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
  351. package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
  352. package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
  353. package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
  354. package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
  355. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
  356. package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
  357. package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
  358. package/src/resources/extensions/gsd/preferences.ts +17 -2
  359. package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
  360. package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
  361. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  362. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  363. package/src/resources/extensions/gsd/prompts/system.md +3 -20
  364. package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
  365. package/src/resources/extensions/gsd/repo-identity.ts +35 -7
  366. package/src/resources/extensions/gsd/repository-registry.ts +3 -1
  367. package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
  368. package/src/resources/extensions/gsd/skill-activation.ts +292 -0
  369. package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
  370. package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
  371. package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
  372. package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
  373. package/src/resources/extensions/gsd/skill-scope.ts +63 -0
  374. package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
  375. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
  376. package/src/resources/extensions/gsd/skills.ts +75 -0
  377. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
  378. package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
  379. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
  380. package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
  381. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
  382. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
  383. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
  384. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
  385. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
  386. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
  387. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
  388. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
  389. package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
  390. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
  391. package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
  392. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
  393. package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
  394. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
  395. package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
  396. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
  397. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
  398. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
  399. package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
  400. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
  401. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
  402. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
  403. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
  404. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
  405. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
  406. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
  407. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
  408. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
  409. package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
  410. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
  411. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
  412. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
  413. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
  414. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
  415. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
  416. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
  417. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
  418. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
  419. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
  420. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
  421. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
  422. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
  423. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
  424. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
  425. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
  426. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
  427. package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
  428. package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
  429. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
  430. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
  431. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
  432. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
  433. package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
  434. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
  435. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
  436. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
  437. package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
  438. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
  439. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
  440. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
  441. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
  442. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
  443. package/src/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +141 -1
  444. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
  445. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
  446. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
  447. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
  448. package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
  449. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
  450. package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
  451. package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
  452. package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
  453. package/src/resources/extensions/gsd/vision-ask.ts +28 -0
  454. package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
  455. package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
  456. package/src/resources/extensions/gsd/worktree-post-create-hook.ts +127 -0
  457. package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
  458. package/src/resources/extensions/search-the-web/native-search.ts +60 -8
  459. package/src/resources/extensions/shared/confirm-ui.ts +8 -12
  460. package/src/resources/extensions/shared/dialog-frame.ts +71 -0
  461. package/src/resources/extensions/shared/interview-ui.ts +43 -42
  462. package/src/resources/extensions/shared/next-action-ui.ts +6 -6
  463. package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
  464. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
  465. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
  466. package/src/resources/extensions/subagent/index.ts +8 -15
  467. package/src/resources/shared/package-manager-detection.ts +39 -0
  468. package/src/resources/skills/agent-browser/SKILL.md +1 -1
  469. package/src/resources/skills/api-design/SKILL.md +1 -1
  470. package/src/resources/skills/code-optimizer/SKILL.md +6 -11
  471. package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
  472. package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
  473. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  474. package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  475. package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  476. package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
  477. package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
  478. package/src/resources/skills/forensics/SKILL.md +2 -2
  479. package/src/resources/skills/grill-me/SKILL.md +1 -1
  480. package/src/resources/skills/handoff/SKILL.md +1 -1
  481. package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  482. package/src/resources/skills/observability/SKILL.md +1 -1
  483. package/src/resources/skills/security-review/SKILL.md +1 -1
  484. package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
  485. package/src/resources/skills/tdd/SKILL.md +1 -1
  486. package/src/resources/skills/write-docs/SKILL.md +1 -1
  487. package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
  488. package/dist/tsconfig.extensions.tsbuildinfo +0 -1
  489. /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
  490. /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
@@ -13,7 +13,7 @@ import { mkdtempSync, mkdirSync, rmSync, existsSync, writeFileSync, readFileSync
13
13
  import { join } from "node:path";
14
14
  import { tmpdir } from "node:os";
15
15
 
16
- import { runWorktreePostCreateHook } from "../auto-worktree.ts";
16
+ import { runWorktreePostCreateHook } from "../worktree-post-create-hook.ts";
17
17
 
18
18
  function makeTmpDir(): string {
19
19
  return mkdtempSync(join(tmpdir(), "gsd-wt-hook-test-"));
@@ -45,10 +45,150 @@ function writeNodeHookScript(filePath: string, code: string): void {
45
45
  test("returns null when no hook path is provided", () => {
46
46
  const src = makeTmpDir();
47
47
  const wt = makeTmpDir();
48
+ const previousGsdHome = process.env.GSD_HOME;
48
49
  try {
50
+ process.env.GSD_HOME = join(src, "empty-gsd-home");
49
51
  const result = runWorktreePostCreateHook(src, wt, undefined);
50
52
  assert.equal(result, null);
51
53
  } finally {
54
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
55
+ else process.env.GSD_HOME = previousGsdHome;
56
+ rmSync(src, { recursive: true, force: true });
57
+ rmSync(wt, { recursive: true, force: true });
58
+ }
59
+ });
60
+
61
+ test("reads git.worktree_post_create from project preferences without loading auto-worktree", () => {
62
+ const src = makeTmpDir();
63
+ const wt = makeTmpDir();
64
+ const previousGsdHome = process.env.GSD_HOME;
65
+ try {
66
+ process.env.GSD_HOME = join(src, "empty-gsd-home");
67
+ const hooksDir = join(src, ".gsd", "hooks");
68
+ mkdirSync(hooksDir, { recursive: true });
69
+ writeFileSync(
70
+ join(src, ".gsd", "PREFERENCES.md"),
71
+ [
72
+ "---",
73
+ "git:",
74
+ ` worktree_post_create: ${hookPath(".gsd/hooks/post-create")}`,
75
+ "---",
76
+ "",
77
+ ].join("\n"),
78
+ );
79
+ const hookFile = hookPath(join(hooksDir, "post-create"));
80
+ writeNodeHookScript(
81
+ hookFile,
82
+ `require("fs").writeFileSync(require("path").join(process.env.WORKTREE_DIR, "configured-hook-ran"), "ok");`,
83
+ );
84
+
85
+ const result = runWorktreePostCreateHook(src, wt);
86
+
87
+ assert.equal(result, null);
88
+ assert.ok(existsSync(join(wt, "configured-hook-ran")), "configured hook should run");
89
+ } finally {
90
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
91
+ else process.env.GSD_HOME = previousGsdHome;
92
+ rmSync(src, { recursive: true, force: true });
93
+ rmSync(wt, { recursive: true, force: true });
94
+ }
95
+ });
96
+
97
+ test("prefers canonical project PREFERENCES.md over legacy lowercase preferences.md", () => {
98
+ const src = makeTmpDir();
99
+ const wt = makeTmpDir();
100
+ const previousGsdHome = process.env.GSD_HOME;
101
+ try {
102
+ process.env.GSD_HOME = join(src, "empty-gsd-home");
103
+ const hooksDir = join(src, ".gsd", "hooks");
104
+ mkdirSync(hooksDir, { recursive: true });
105
+ writeFileSync(
106
+ join(src, ".gsd", "preferences.md"),
107
+ [
108
+ "---",
109
+ "git:",
110
+ ` worktree_post_create: ${hookPath(".gsd/hooks/legacy")}`,
111
+ "---",
112
+ "",
113
+ ].join("\n"),
114
+ );
115
+ writeFileSync(
116
+ join(src, ".gsd", "PREFERENCES.md"),
117
+ [
118
+ "---",
119
+ "git:",
120
+ ` worktree_post_create: ${hookPath(".gsd/hooks/canonical")}`,
121
+ "---",
122
+ "",
123
+ ].join("\n"),
124
+ );
125
+ writeNodeHookScript(
126
+ hookPath(join(hooksDir, "canonical")),
127
+ `require("fs").writeFileSync(require("path").join(process.env.WORKTREE_DIR, "configured-hook-ran"), "canonical");`,
128
+ );
129
+ writeNodeHookScript(
130
+ hookPath(join(hooksDir, "legacy")),
131
+ `require("fs").writeFileSync(require("path").join(process.env.WORKTREE_DIR, "configured-hook-ran"), "legacy");`,
132
+ );
133
+
134
+ const result = runWorktreePostCreateHook(src, wt);
135
+
136
+ assert.equal(result, null);
137
+ assert.equal(readFileSync(join(wt, "configured-hook-ran"), "utf-8"), "canonical");
138
+ } finally {
139
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
140
+ else process.env.GSD_HOME = previousGsdHome;
141
+ rmSync(src, { recursive: true, force: true });
142
+ rmSync(wt, { recursive: true, force: true });
143
+ }
144
+ });
145
+
146
+ test("prefers canonical global PREFERENCES.md over legacy lowercase preferences.md", () => {
147
+ const src = makeTmpDir();
148
+ const wt = makeTmpDir();
149
+ const previousGsdHome = process.env.GSD_HOME;
150
+ try {
151
+ const gsdHomeDir = join(src, "global-gsd-home");
152
+ process.env.GSD_HOME = gsdHomeDir;
153
+ const hooksDir = join(src, ".gsd", "hooks");
154
+ mkdirSync(hooksDir, { recursive: true });
155
+ mkdirSync(gsdHomeDir, { recursive: true });
156
+ writeFileSync(
157
+ join(gsdHomeDir, "preferences.md"),
158
+ [
159
+ "---",
160
+ "git:",
161
+ ` worktree_post_create: ${hookPath(".gsd/hooks/legacy")}`,
162
+ "---",
163
+ "",
164
+ ].join("\n"),
165
+ );
166
+ writeFileSync(
167
+ join(gsdHomeDir, "PREFERENCES.md"),
168
+ [
169
+ "---",
170
+ "git:",
171
+ ` worktree_post_create: ${hookPath(".gsd/hooks/canonical")}`,
172
+ "---",
173
+ "",
174
+ ].join("\n"),
175
+ );
176
+ writeNodeHookScript(
177
+ hookPath(join(hooksDir, "canonical")),
178
+ `require("fs").writeFileSync(require("path").join(process.env.WORKTREE_DIR, "configured-hook-ran"), "canonical");`,
179
+ );
180
+ writeNodeHookScript(
181
+ hookPath(join(hooksDir, "legacy")),
182
+ `require("fs").writeFileSync(require("path").join(process.env.WORKTREE_DIR, "configured-hook-ran"), "legacy");`,
183
+ );
184
+
185
+ const result = runWorktreePostCreateHook(src, wt);
186
+
187
+ assert.equal(result, null);
188
+ assert.equal(readFileSync(join(wt, "configured-hook-ran"), "utf-8"), "canonical");
189
+ } finally {
190
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
191
+ else process.env.GSD_HOME = previousGsdHome;
52
192
  rmSync(src, { recursive: true, force: true });
53
193
  rmSync(wt, { recursive: true, force: true });
54
194
  }
@@ -2,7 +2,7 @@
2
2
  // File Purpose: Worktree State Projection Module — typed-Interface contract tests for projectRootToWorktree (ADR-016).
3
3
  import test from "node:test";
4
4
  import assert from "node:assert/strict";
5
- import { mkdtempSync, rmSync, mkdirSync } from "node:fs";
5
+ import { existsSync, mkdtempSync, readFileSync, rmSync, mkdirSync, writeFileSync } from "node:fs";
6
6
  import { join } from "node:path";
7
7
  import { tmpdir } from "node:os";
8
8
  import { WorktreeStateProjection } from "../worktree-state-projection.js";
@@ -60,6 +60,43 @@ test("projectRootToWorktree is idempotent — repeated calls do not throw", () =
60
60
  }
61
61
  });
62
62
 
63
+ test("projectRootToWorktree forwards root PROJECT.md into isolated worktrees", () => {
64
+ const { dir, cleanup } = makeProjectRoot();
65
+ try {
66
+ const worktree = join(dir, ".gsd", "worktrees", "M001");
67
+ mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
68
+ mkdirSync(join(worktree, ".gsd"), { recursive: true });
69
+
70
+ const projectContent = [
71
+ "# Project",
72
+ "",
73
+ "## Milestone Sequence",
74
+ "",
75
+ "- [ ] M001: Foundation — Establish the runnable slice.",
76
+ "",
77
+ ].join("\n");
78
+ writeFileSync(join(dir, ".gsd", "PROJECT.md"), projectContent);
79
+ writeFileSync(join(dir, ".gsd", "REQUIREMENTS.md"), "# Requirements\n");
80
+ writeFileSync(join(dir, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "# M001\n");
81
+
82
+ const workspace = createWorkspace(worktree);
83
+ const scope = scopeMilestone(workspace, "M001");
84
+ const projection = new WorktreeStateProjection();
85
+
86
+ projection.projectRootToWorktree(scope);
87
+
88
+ const projectedProject = join(worktree, ".gsd", "PROJECT.md");
89
+ assert.ok(existsSync(projectedProject), "PROJECT.md is available to worktree-bound units");
90
+ assert.equal(readFileSync(projectedProject, "utf-8"), projectContent);
91
+ assert.ok(
92
+ existsSync(join(worktree, ".gsd", "milestones", "M001", "M001-ROADMAP.md")),
93
+ "milestone artifacts still project into the worktree",
94
+ );
95
+ } finally {
96
+ cleanup();
97
+ }
98
+ });
99
+
63
100
  // ─── projectWorktreeToRoot — Module contract ────────────────────────────────
64
101
 
65
102
  test("projectWorktreeToRoot exists and accepts a MilestoneScope", () => {
@@ -296,6 +296,11 @@ test('complete-slice closeout policy allows gsd_exec verification surface', () =
296
296
  assert.strictEqual(r.block, false);
297
297
  });
298
298
 
299
+ test('complete-slice closeout policy allows MCP-scoped gsd_exec verification surface', () => {
300
+ const r = shouldBlockPlanningUnit('mcp__custom-workflow__gsd_exec', '', BASE, 'complete-slice', PLANNING_DISPATCH_REVIEW);
301
+ assert.strictEqual(r.block, false);
302
+ });
303
+
299
304
  test('planning-dispatch: still blocks writes to user source (write isolation preserved)', () => {
300
305
  const r = shouldBlockPlanningUnit('write', join(BASE, 'src', 'main.ts'), BASE, 'plan-slice', PLANNING_DISPATCH);
301
306
  assert.strictEqual(r.block, true);
@@ -329,6 +334,11 @@ test('planning-unit: allows gsd_* MCP tools (own validation)', () => {
329
334
  assert.strictEqual(r.block, false);
330
335
  });
331
336
 
337
+ test('planning-unit: allows MCP-scoped gsd_* tools (own validation)', () => {
338
+ const r = shouldBlockPlanningUnit('mcp__custom-workflow__gsd_summary_save', '', BASE, 'discuss-milestone', PLANNING);
339
+ assert.strictEqual(r.block, false);
340
+ });
341
+
332
342
  test('planning-unit: allows web research tools', () => {
333
343
  const r = shouldBlockPlanningUnit('search-the-web', '', BASE, 'research-milestone', PLANNING);
334
344
  assert.strictEqual(r.block, false);
@@ -14,7 +14,7 @@
14
14
 
15
15
  import { test } from "node:test";
16
16
  import assert from "node:assert/strict";
17
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
17
+ import { existsSync, mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
18
18
  import { join } from "node:path";
19
19
  import { tmpdir } from "node:os";
20
20
 
@@ -79,3 +79,47 @@ test("#2942: injected existsFn — milestones/ alone is enough", () => {
79
79
  p === "/proj/.gsd" || p === "/proj/.gsd/milestones";
80
80
  assert.equal(hasGsdBootstrapArtifacts("/proj/.gsd", existsFn), true);
81
81
  });
82
+
83
+ test("bare /gsd routes zombie .gsd folders to project init before closeout/db checks", async (t) => {
84
+ const base = mkdtempSync(join(tmpdir(), "gsd-zombie-bare-command-"));
85
+ t.after(() => rmSync(base, { recursive: true, force: true }));
86
+ mkdirSync(join(base, ".gsd", "runtime"), { recursive: true });
87
+
88
+ const previousCwd = process.cwd();
89
+ const previousGsdHome = process.env.GSD_HOME;
90
+ const previousProjectRoot = process.env.GSD_PROJECT_ROOT;
91
+ try {
92
+ process.chdir(base);
93
+ process.env.GSD_HOME = join(base, ".test-gsd-home");
94
+ delete process.env.GSD_PROJECT_ROOT;
95
+
96
+ const notifications: string[] = [];
97
+ const ctx = {
98
+ hasUI: false,
99
+ ui: {
100
+ notify: (content: unknown) => notifications.push(String(content)),
101
+ setStatus: () => {},
102
+ setWidget: () => {},
103
+ },
104
+ };
105
+ const { handleAutoCommand } = await import("../commands/handlers/auto.ts");
106
+
107
+ await handleAutoCommand("", ctx as any, {} as any);
108
+
109
+ assert.ok(
110
+ notifications.some((message) => message.includes("/gsd init did not start")),
111
+ "bare /gsd should route unbootstrapped zombie folders to the init wizard",
112
+ );
113
+ assert.equal(
114
+ existsSync(join(base, ".gsd", "gsd.db")),
115
+ false,
116
+ "bare /gsd should not create the project DB before init has bootstrapped .gsd/",
117
+ );
118
+ } finally {
119
+ process.chdir(previousCwd);
120
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
121
+ else process.env.GSD_HOME = previousGsdHome;
122
+ if (previousProjectRoot === undefined) delete process.env.GSD_PROJECT_ROOT;
123
+ else process.env.GSD_PROJECT_ROOT = previousProjectRoot;
124
+ }
125
+ });
@@ -173,6 +173,15 @@ export async function handleCompleteTask(
173
173
  if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
174
174
  return { error: "milestoneId is required and must be a non-empty string" };
175
175
  }
176
+ if (!params.oneLiner || typeof params.oneLiner !== "string" || params.oneLiner.trim() === "") {
177
+ return { error: "oneLiner is required and must be a non-empty string" };
178
+ }
179
+ if (!params.narrative || typeof params.narrative !== "string" || params.narrative.trim() === "") {
180
+ return { error: "narrative is required and must be a non-empty string" };
181
+ }
182
+ if (!params.verification || typeof params.verification !== "string" || params.verification.trim() === "") {
183
+ return { error: "verification is required and must be a non-empty string" };
184
+ }
176
185
 
177
186
  const artifactBasePath = resolveCanonicalMilestoneRoot(basePath, params.milestoneId);
178
187
 
@@ -14,8 +14,11 @@ import { isContextModeEnabled, type ContextModeConfig } from "../preferences-typ
14
14
  import { contextModeDisabledResult, type ToolExecutionResult } from "./context-mode-tool-result.js";
15
15
 
16
16
  export interface ExecToolParams {
17
- runtime: ExecSandboxRequest["runtime"];
18
- script: string;
17
+ runtime?: unknown;
18
+ script?: unknown;
19
+ command?: unknown;
20
+ cmd?: unknown;
21
+ code?: unknown;
19
22
  purpose?: string;
20
23
  timeout_ms?: number;
21
24
  }
@@ -80,6 +83,39 @@ function paramError(message: string): ToolExecutionResult {
80
83
  };
81
84
  }
82
85
 
86
+ function normalizeRuntime(value: unknown): ExecSandboxRequest["runtime"] | ToolExecutionResult {
87
+ if (value === undefined || value === null || value === "") return "bash";
88
+ if (typeof value !== "string") {
89
+ return paramError(`invalid runtime "${String(value)}" — must be bash | node | python`);
90
+ }
91
+ const normalized = value.trim().toLowerCase();
92
+ if (normalized === "" || normalized === "bash" || normalized === "sh" || normalized === "shell") return "bash";
93
+ if (normalized === "node" || normalized === "nodejs" || normalized === "js" || normalized === "javascript") return "node";
94
+ if (normalized === "python" || normalized === "python3" || normalized === "py") return "python";
95
+ return paramError(`invalid runtime "${value}" — must be bash | node | python`);
96
+ }
97
+
98
+ function normalizeScript(params: ExecToolParams): string | ToolExecutionResult {
99
+ const candidates = [params.script, params.command, params.cmd, params.code];
100
+ let sawNonString = false;
101
+ for (const candidate of candidates) {
102
+ if (candidate === undefined || candidate === null) continue;
103
+ if (typeof candidate !== "string") {
104
+ sawNonString = true;
105
+ continue;
106
+ }
107
+ if (candidate.trim().length > 0) return candidate;
108
+ }
109
+ if (sawNonString) {
110
+ return paramError("script/command must be a non-empty string");
111
+ }
112
+ return paramError("script is required and must be a non-empty string");
113
+ }
114
+
115
+ function isToolExecutionResult(value: unknown): value is ToolExecutionResult {
116
+ return typeof value === "object" && value !== null && Array.isArray((value as { content?: unknown }).content);
117
+ }
118
+
83
119
  function escapeRegExp(value: string): string {
84
120
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
85
121
  }
@@ -201,14 +237,10 @@ export async function executeGsdExec(
201
237
  ): Promise<ToolExecutionResult> {
202
238
  if (!isEnabled(deps.preferences)) return contextModeDisabledResult("gsd_exec");
203
239
 
204
- const runtime = params.runtime;
205
- if (runtime !== "bash" && runtime !== "node" && runtime !== "python") {
206
- return paramError(`invalid runtime "${String(runtime)}" — must be bash | node | python`);
207
- }
208
- const script = typeof params.script === "string" ? params.script : "";
209
- if (script.trim().length === 0) {
210
- return paramError("script is required and must be a non-empty string");
211
- }
240
+ const runtime = normalizeRuntime(params.runtime);
241
+ if (isToolExecutionResult(runtime)) return runtime;
242
+ const script = normalizeScript(params);
243
+ if (isToolExecutionResult(script)) return script;
212
244
  if (Buffer.byteLength(script, "utf8") > 200_000) {
213
245
  return paramError("script exceeds the 200 KB length limit");
214
246
  }
@@ -15,8 +15,10 @@ import {
15
15
  } from "../gsd-db.js";
16
16
  import { GATE_REGISTRY } from "../gate-registry.js";
17
17
  import { generateRequirementsMd, saveArtifactToDb } from "../db-writer.js";
18
- import { resolveMilestoneFile, resolveSliceFile } from "../paths.js";
18
+ import { clearPathCache, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "../paths.js";
19
+ import { saveFile, clearParseCache } from "../files.js";
19
20
  import { unlinkSync } from "node:fs";
21
+ import { join } from "node:path";
20
22
  import type { CompleteMilestoneParams } from "./complete-milestone.js";
21
23
  import { handleCompleteMilestone } from "./complete-milestone.js";
22
24
  import { handleCompleteTask } from "./complete-task.js";
@@ -96,6 +98,28 @@ function registerProjectMilestoneSequence(content: string): string[] {
96
98
  return registered;
97
99
  }
98
100
 
101
+ async function mirrorArtifactToActiveWorktreeProjection(
102
+ basePath: string,
103
+ relativePath: string,
104
+ content: string,
105
+ ): Promise<void> {
106
+ const contract = resolveGsdPathContract(basePath);
107
+ if (!contract.worktreeGsd) return;
108
+ if (contract.worktreeGsd === contract.projectGsd) return;
109
+
110
+ const fullPath = join(contract.worktreeGsd, relativePath);
111
+ try {
112
+ await saveFile(fullPath, content);
113
+ clearPathCache();
114
+ clearParseCache();
115
+ invalidateStateCache();
116
+ } catch (err) {
117
+ logWarning("tool", `gsd_summary_save worktree projection mirror failed: ${(err as Error).message}`, {
118
+ path: relativePath,
119
+ });
120
+ }
121
+ }
122
+
99
123
  export async function executeSummarySave(
100
124
  params: SummarySaveParams,
101
125
  basePath: string = process.cwd(),
@@ -197,6 +221,7 @@ export async function executeSummarySave(
197
221
  },
198
222
  basePath,
199
223
  );
224
+ await mirrorArtifactToActiveWorktreeProjection(basePath, relativePath, contentToSave);
200
225
 
201
226
  let registeredMilestones: string[] = [];
202
227
  if (params.artifact_type === "PROJECT") {
@@ -306,7 +331,7 @@ export interface TaskCompleteParams {
306
331
  milestoneId: string;
307
332
  oneLiner: string;
308
333
  narrative: string;
309
- verification: string;
334
+ verification?: string;
310
335
  deviations?: string;
311
336
  knownIssues?: string;
312
337
  keyFiles?: string[];
@@ -315,6 +340,40 @@ export interface TaskCompleteParams {
315
340
  verificationEvidence?: VerificationEvidenceInput[];
316
341
  }
317
342
 
343
+ type NormalizedVerificationEvidence = {
344
+ command: string;
345
+ exitCode: number;
346
+ verdict: string;
347
+ durationMs: number;
348
+ };
349
+
350
+ function normalizeVerificationEvidence(
351
+ evidence: VerificationEvidenceInput[] | undefined,
352
+ ): NormalizedVerificationEvidence[] {
353
+ return (evidence ?? []).map((entry) =>
354
+ typeof entry === "string"
355
+ ? { command: entry, exitCode: -1, verdict: "unknown (coerced from string)", durationMs: 0 }
356
+ : entry,
357
+ );
358
+ }
359
+
360
+ function deriveVerificationSummary(
361
+ evidence: NormalizedVerificationEvidence[],
362
+ ): string | null {
363
+ if (evidence.length === 0) return null;
364
+
365
+ const rendered = evidence.slice(0, 3).map((entry) => {
366
+ const command = entry.command.trim() || "(unspecified command)";
367
+ const verdict = entry.verdict.trim() || "recorded";
368
+ return `\`${command}\` exited ${entry.exitCode} (${verdict})`;
369
+ });
370
+ const suffix = evidence.length > rendered.length
371
+ ? `; ${evidence.length - rendered.length} more check(s) recorded`
372
+ : "";
373
+
374
+ return `Verification evidence recorded: ${rendered.join("; ")}${suffix}.`;
375
+ }
376
+
318
377
  export type CompleteMilestoneExecutorParams = Partial<CompleteMilestoneParams> & Record<string, unknown>;
319
378
  export type SliceCompleteExecutorParams = CompleteSliceParams;
320
379
  export type PlanMilestoneExecutorParams = PlanMilestoneParams;
@@ -350,9 +409,27 @@ export async function executeTaskComplete(
350
409
  }
351
410
  try {
352
411
  const coerced = { ...params };
353
- coerced.verificationEvidence = (params.verificationEvidence ?? []).map((v) =>
354
- typeof v === "string" ? { command: v, exitCode: -1, verdict: "unknown (coerced from string)", durationMs: 0 } : v,
355
- );
412
+ const verificationEvidence = normalizeVerificationEvidence(params.verificationEvidence);
413
+ coerced.verificationEvidence = verificationEvidence;
414
+
415
+ const verification = typeof params.verification === "string" ? params.verification.trim() : "";
416
+ if (verification.length === 0) {
417
+ const derived = deriveVerificationSummary(verificationEvidence);
418
+ if (derived) {
419
+ coerced.verification = derived;
420
+ } else if (params.blockerDiscovered === true) {
421
+ coerced.verification = "Not run: blocker discovered before verification.";
422
+ } else {
423
+ return {
424
+ content: [{
425
+ type: "text",
426
+ text: "Error completing task: verification is required unless verificationEvidence is provided or blockerDiscovered is true.",
427
+ }],
428
+ details: { operation: "complete_task", error: "verification_required" },
429
+ isError: true,
430
+ };
431
+ }
432
+ }
356
433
 
357
434
  const result = await handleCompleteTask(coerced as any, basePath);
358
435
  if ("error" in result) {
@@ -151,3 +151,85 @@ export function renderFrame(
151
151
  lines.push(border("╰" + "─".repeat(width - 2) + "╯"));
152
152
  return lines.map((line) => safeLine(line, width, ""));
153
153
  }
154
+
155
+ export interface DialogFrameOptions {
156
+ borderColor?: string;
157
+ paddingX?: number;
158
+ footer?: string | string[];
159
+ scroll?: {
160
+ offset: number;
161
+ visibleRows: number;
162
+ totalRows: number;
163
+ trackOffset?: number;
164
+ trackRows?: number;
165
+ };
166
+ }
167
+
168
+ function renderTitledTopBorder(
169
+ theme: ThemeLike,
170
+ title: string,
171
+ width: number,
172
+ border: (text: string) => string,
173
+ ): string {
174
+ const trimmedTitle = title.trim();
175
+ if (!trimmedTitle || width < 10) {
176
+ return border("╭" + "─".repeat(width - 2) + "╮");
177
+ }
178
+
179
+ const maxTitleWidth = Math.max(0, width - 7);
180
+ const safeTitle = safeLine(trimmedTitle, maxTitleWidth);
181
+ const fill = Math.max(0, width - visibleWidth(safeTitle) - 5);
182
+ return border("╭─ ") + theme.bold(theme.fg("accent", safeTitle)) + border(" " + "─".repeat(fill) + "╮");
183
+ }
184
+
185
+ export function renderDialogFrame(
186
+ theme: ThemeLike,
187
+ title: string,
188
+ inner: string[],
189
+ width: number,
190
+ options: DialogFrameOptions = {},
191
+ ): string[] {
192
+ if (width < 4) return inner.map((line) => safeLine(line, width));
193
+
194
+ const borderColor = options.borderColor ?? "borderAccent";
195
+ const paddingX = Math.max(0, options.paddingX ?? 1);
196
+ const contentWidth = Math.max(0, width - 2 - paddingX * 2);
197
+ const border = (text: string) => theme.fg(borderColor, text);
198
+ const pad = " ".repeat(paddingX);
199
+ const lines = [renderTitledTopBorder(theme, title, width, border)];
200
+
201
+ const scroll = options.scroll;
202
+ const bodyRows = inner.length;
203
+ const trackOffset = Math.max(0, Math.min(scroll?.trackOffset ?? 0, bodyRows));
204
+ const trackRows = Math.max(0, Math.min(scroll?.trackRows ?? bodyRows, bodyRows - trackOffset));
205
+ const scrollable = !!scroll && scroll.totalRows > scroll.visibleRows && trackRows > 0;
206
+ const thumbLen = scrollable
207
+ ? Math.max(1, Math.round((scroll.visibleRows / scroll.totalRows) * trackRows))
208
+ : 0;
209
+ const maxThumbStart = Math.max(0, trackRows - thumbLen);
210
+ const maxScrollOffset = scrollable ? Math.max(1, scroll.totalRows - scroll.visibleRows) : 1;
211
+ const thumbStart = scrollable
212
+ ? trackOffset + Math.min(maxThumbStart, Math.round((scroll.offset / maxScrollOffset) * maxThumbStart))
213
+ : -1;
214
+
215
+ for (let i = 0; i < inner.length; i++) {
216
+ const line = inner[i] ?? "";
217
+ const rightBorder = scrollable && i >= thumbStart && i < thumbStart + thumbLen ? "┃" : "│";
218
+ lines.push(border("│") + pad + padRightVisible(line, contentWidth) + pad + border(rightBorder));
219
+ }
220
+
221
+ const footer = Array.isArray(options.footer)
222
+ ? options.footer
223
+ : options.footer
224
+ ? [options.footer]
225
+ : [];
226
+ if (footer.length > 0) {
227
+ lines.push(border("├" + "─".repeat(width - 2) + "┤"));
228
+ for (const line of footer) {
229
+ lines.push(border("│") + pad + padRightVisible(line, contentWidth) + pad + border("│"));
230
+ }
231
+ }
232
+
233
+ lines.push(border("╰" + "─".repeat(width - 2) + "╯"));
234
+ return lines.map((line) => safeLine(line, width, ""));
235
+ }