@opengsd/gsd-pi 1.0.2-dev.e70300c → 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 (480) 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 +34 -1
  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-state-projection.js +29 -0
  94. package/dist/resources/extensions/search-the-web/native-search.js +57 -8
  95. package/dist/resources/extensions/shared/confirm-ui.js +9 -6
  96. package/dist/resources/extensions/shared/dialog-frame.js +42 -0
  97. package/dist/resources/extensions/shared/interview-ui.js +42 -30
  98. package/dist/resources/extensions/shared/next-action-ui.js +6 -6
  99. package/dist/resources/extensions/subagent/index.js +8 -15
  100. package/dist/resources/shared/package-manager-detection.js +36 -0
  101. package/dist/resources/skills/agent-browser/SKILL.md +1 -1
  102. package/dist/resources/skills/api-design/SKILL.md +1 -1
  103. package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
  104. package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
  105. package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
  106. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  107. package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  108. package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  109. package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
  110. package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
  111. package/dist/resources/skills/forensics/SKILL.md +2 -2
  112. package/dist/resources/skills/grill-me/SKILL.md +1 -1
  113. package/dist/resources/skills/handoff/SKILL.md +1 -1
  114. package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  115. package/dist/resources/skills/observability/SKILL.md +1 -1
  116. package/dist/resources/skills/security-review/SKILL.md +1 -1
  117. package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
  118. package/dist/resources/skills/tdd/SKILL.md +1 -1
  119. package/dist/resources/skills/write-docs/SKILL.md +1 -1
  120. package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
  121. package/dist/update-check.d.ts +6 -2
  122. package/dist/update-check.js +7 -3
  123. package/dist/web/standalone/.next/BUILD_ID +1 -1
  124. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  125. package/dist/web/standalone/.next/build-manifest.json +2 -2
  126. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/index.html +1 -1
  145. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  152. package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
  153. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  155. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  156. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  157. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  158. package/package.json +5 -2
  159. package/packages/cloud-mcp-gateway/package.json +2 -2
  160. package/packages/contracts/dist/rpc.test.js +5 -0
  161. package/packages/contracts/dist/rpc.test.js.map +1 -1
  162. package/packages/contracts/dist/workflow.d.ts +15 -0
  163. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  164. package/packages/contracts/dist/workflow.js +16 -0
  165. package/packages/contracts/dist/workflow.js.map +1 -1
  166. package/packages/contracts/dist/workflow.test.js +1 -0
  167. package/packages/contracts/dist/workflow.test.js.map +1 -1
  168. package/packages/contracts/package.json +1 -1
  169. package/packages/daemon/package.json +4 -4
  170. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
  171. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  172. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
  173. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  174. package/packages/gsd-agent-core/package.json +5 -5
  175. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
  176. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
  177. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
  178. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
  179. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
  180. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
  182. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
  184. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
  186. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
  187. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  196. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
  198. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
  202. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  204. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
  205. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  206. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
  208. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  209. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
  210. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  211. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
  212. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  213. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  214. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
  215. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  216. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
  217. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  218. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
  219. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  220. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
  221. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
  222. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
  223. package/packages/gsd-agent-modes/package.json +7 -7
  224. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  225. package/packages/mcp-server/dist/server.js +7 -1
  226. package/packages/mcp-server/dist/server.js.map +1 -1
  227. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +47 -8
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/package.json +3 -3
  232. package/packages/native/package.json +1 -1
  233. package/packages/pi-agent-core/dist/agent-loop.js +16 -14
  234. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  235. package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
  236. package/packages/pi-agent-core/dist/harness/skills.js +6 -0
  237. package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
  238. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
  239. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
  240. package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
  241. package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
  242. package/packages/pi-agent-core/package.json +1 -1
  243. package/packages/pi-ai/dist/models.generated.d.ts +48 -206
  244. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  245. package/packages/pi-ai/dist/models.generated.js +67 -220
  246. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  247. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  248. package/packages/pi-ai/dist/providers/anthropic.js +50 -0
  249. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  250. package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
  252. package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/types.d.ts +2 -0
  254. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/types.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js +29 -1
  257. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
  258. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
  259. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
  261. package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
  262. package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
  263. package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
  264. package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
  265. package/packages/pi-ai/package.json +1 -1
  266. package/packages/pi-coding-agent/README.md +1 -1
  267. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
  268. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
  271. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
  274. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
  276. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/skills.js +3 -0
  278. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
  281. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
  283. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
  285. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
  288. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  289. package/packages/pi-coding-agent/package.json +8 -8
  290. package/packages/pi-tui/package.json +1 -1
  291. package/packages/rpc-client/package.json +2 -2
  292. package/pkg/package.json +1 -1
  293. package/scripts/install/detect-existing.js +17 -3
  294. package/scripts/install/npm-global.js +103 -33
  295. package/scripts/install.js +1 -0
  296. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
  297. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
  298. package/src/resources/extensions/context7/index.ts +15 -2
  299. package/src/resources/extensions/get-secrets-from-user.ts +17 -16
  300. package/src/resources/extensions/google-cli/index.ts +34 -0
  301. package/src/resources/extensions/google-cli/models.ts +57 -0
  302. package/src/resources/extensions/google-cli/package.json +11 -0
  303. package/src/resources/extensions/google-cli/readiness.ts +15 -0
  304. package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
  305. package/src/resources/extensions/gsd/auto/loop.ts +96 -1
  306. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
  307. package/src/resources/extensions/gsd/auto/phases.ts +47 -1
  308. package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
  309. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  310. package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
  311. package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
  312. package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
  313. package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
  314. package/src/resources/extensions/gsd/auto-start.ts +307 -56
  315. package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
  316. package/src/resources/extensions/gsd/auto-verification.ts +18 -2
  317. package/src/resources/extensions/gsd/auto-worktree.ts +45 -1
  318. package/src/resources/extensions/gsd/auto.ts +50 -2
  319. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
  320. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
  321. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
  322. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
  323. package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
  324. package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
  325. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  326. package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
  327. package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
  328. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  329. package/src/resources/extensions/gsd/commands-usage.ts +110 -5
  330. package/src/resources/extensions/gsd/config-overlay.ts +19 -16
  331. package/src/resources/extensions/gsd/context-overlay.ts +24 -19
  332. package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
  333. package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
  334. package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
  335. package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
  336. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  337. package/src/resources/extensions/gsd/doctor.ts +7 -2
  338. package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
  339. package/src/resources/extensions/gsd/guided-flow.ts +5 -6
  340. package/src/resources/extensions/gsd/key-manager.ts +57 -14
  341. package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
  342. package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
  343. package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
  344. package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
  345. package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
  346. package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
  347. package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
  348. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
  349. package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
  350. package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
  351. package/src/resources/extensions/gsd/preferences.ts +17 -2
  352. package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
  353. package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
  354. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  355. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  356. package/src/resources/extensions/gsd/prompts/system.md +3 -20
  357. package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
  358. package/src/resources/extensions/gsd/repo-identity.ts +35 -7
  359. package/src/resources/extensions/gsd/repository-registry.ts +3 -1
  360. package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
  361. package/src/resources/extensions/gsd/skill-activation.ts +292 -0
  362. package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
  363. package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
  364. package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
  365. package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
  366. package/src/resources/extensions/gsd/skill-scope.ts +63 -0
  367. package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
  368. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
  369. package/src/resources/extensions/gsd/skills.ts +75 -0
  370. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
  371. package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
  372. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
  373. package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
  374. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
  375. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
  376. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
  377. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
  378. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
  379. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
  380. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
  381. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
  382. package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
  383. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
  384. package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
  385. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
  386. package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
  387. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
  388. package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
  389. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
  390. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
  391. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
  392. package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
  393. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
  394. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
  395. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
  396. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
  397. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
  398. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
  399. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
  400. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
  401. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
  402. package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
  403. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
  404. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
  405. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
  406. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
  407. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
  408. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
  409. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
  410. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
  411. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
  412. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
  413. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
  414. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
  415. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
  416. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
  417. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
  418. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
  419. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
  420. package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
  421. package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
  422. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
  423. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
  424. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
  425. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
  426. package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
  427. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
  428. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
  429. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
  430. package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
  431. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
  432. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
  433. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
  434. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
  435. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
  436. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
  437. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
  438. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
  439. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
  440. package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
  441. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
  442. package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
  443. package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
  444. package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
  445. package/src/resources/extensions/gsd/vision-ask.ts +28 -0
  446. package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
  447. package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
  448. package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
  449. package/src/resources/extensions/search-the-web/native-search.ts +60 -8
  450. package/src/resources/extensions/shared/confirm-ui.ts +8 -12
  451. package/src/resources/extensions/shared/dialog-frame.ts +71 -0
  452. package/src/resources/extensions/shared/interview-ui.ts +43 -42
  453. package/src/resources/extensions/shared/next-action-ui.ts +6 -6
  454. package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
  455. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
  456. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
  457. package/src/resources/extensions/subagent/index.ts +8 -15
  458. package/src/resources/shared/package-manager-detection.ts +39 -0
  459. package/src/resources/skills/agent-browser/SKILL.md +1 -1
  460. package/src/resources/skills/api-design/SKILL.md +1 -1
  461. package/src/resources/skills/code-optimizer/SKILL.md +6 -11
  462. package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
  463. package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
  464. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  465. package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  466. package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  467. package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
  468. package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
  469. package/src/resources/skills/forensics/SKILL.md +2 -2
  470. package/src/resources/skills/grill-me/SKILL.md +1 -1
  471. package/src/resources/skills/handoff/SKILL.md +1 -1
  472. package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  473. package/src/resources/skills/observability/SKILL.md +1 -1
  474. package/src/resources/skills/security-review/SKILL.md +1 -1
  475. package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
  476. package/src/resources/skills/tdd/SKILL.md +1 -1
  477. package/src/resources/skills/write-docs/SKILL.md +1 -1
  478. package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
  479. /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
  480. /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
@@ -241,6 +241,36 @@ test('executeGsdExec: enforces per-call timeout override end-to-end', async () =
241
241
  }
242
242
  });
243
243
 
244
+ test('executeGsdExec: defaults to bash and accepts command alias', async () => {
245
+ const base = freshBase();
246
+ try {
247
+ const result = await executeGsdExec(
248
+ { command: 'echo command-alias-defaults-to-bash' },
249
+ { baseDir: base, preferences: { context_mode: { enabled: true } } },
250
+ );
251
+ assert.equal(result.isError, false);
252
+ assert.equal(result.details.runtime, 'bash');
253
+ assert.ok(result.content[0].text.includes('command-alias-defaults-to-bash'));
254
+ } finally {
255
+ cleanup(base);
256
+ }
257
+ });
258
+
259
+ test('executeGsdExec: accepts common runtime aliases', async () => {
260
+ const base = freshBase();
261
+ try {
262
+ const result = await executeGsdExec(
263
+ { runtime: 'js', code: 'console.log("runtime-alias-node")' },
264
+ { baseDir: base, preferences: { context_mode: { enabled: true } } },
265
+ );
266
+ assert.equal(result.isError, false);
267
+ assert.equal(result.details.runtime, 'node');
268
+ assert.ok(result.content[0].text.includes('runtime-alias-node'));
269
+ } finally {
270
+ cleanup(base);
271
+ }
272
+ });
273
+
244
274
  test('executeGsdExec: rejects empty script', async () => {
245
275
  const base = freshBase();
246
276
  try {
@@ -6,6 +6,7 @@ import assert from "node:assert/strict";
6
6
  import { mkdtempSync, rmSync } from "node:fs";
7
7
  import { tmpdir } from "node:os";
8
8
  import { join } from "node:path";
9
+ import { VISION_ASK_VARIANTS } from "../vision-ask.ts";
9
10
 
10
11
  test("guided milestone prompt renders compact interview and context guidance", async (t) => {
11
12
  const previousGsdHome = process.env.GSD_HOME;
@@ -31,6 +32,11 @@ test("guided milestone prompt renders compact interview and context guidance", a
31
32
 
32
33
  assert.match(prompt, /M001 context written/);
33
34
  assert.match(prompt, /Project Shape/);
35
+ assert.ok(
36
+ VISION_ASK_VARIANTS.some((opener) => prompt.includes(opener)),
37
+ "prompt should render a conversational opener variant",
38
+ );
39
+ assert.doesNotMatch(prompt, /\{\{visionAsk\}\}/);
34
40
  assert.match(prompt, /default to `complex`/i);
35
41
  assert.match(prompt, /3 or 4 concrete, researched options/);
36
42
  assert.match(prompt, /"Other — let me discuss"/);
@@ -92,10 +92,10 @@ test('loadAndValidateAnswerFile — wrong types (non-string secret value)', (t)
92
92
  // AnswerInjector — observeEvent + tryHandle
93
93
  // ---------------------------------------------------------------------------
94
94
 
95
- function makeToolExecutionStart(questions: Record<string, unknown>[]) {
95
+ function makeToolExecutionStart(questions: Record<string, unknown>[], toolName = 'ask_user_questions') {
96
96
  return {
97
97
  type: 'tool_execution_start',
98
- toolName: 'ask_user_questions',
98
+ toolName,
99
99
  input: { questions },
100
100
  };
101
101
  }
@@ -140,6 +140,25 @@ test('observeEvent stores metadata', (t) => {
140
140
  assert.strictEqual(injector.getStats().questionsDefaulted, 1);
141
141
  });
142
142
 
143
+ test('observeEvent stores metadata for MCP-scoped ask_user_questions', (t) => {
144
+ const injector = new AnswerInjector({ questions: { deploy_target: 'GCP' } });
145
+
146
+ injector.observeEvent(makeToolExecutionStart([{
147
+ id: 'deploy_target',
148
+ header: 'Deploy',
149
+ question: 'Where to deploy?',
150
+ options: [{ label: 'AWS' }, { label: 'GCP' }],
151
+ }], 'mcp__custom-workflow__ask_user_questions'));
152
+
153
+ const captured: string[] = [];
154
+ const captureStdin = (data: string) => { captured.push(data); };
155
+ const event = makeSelectEvent('req-1', 'Deploy: Where to deploy?', ['AWS', 'GCP']);
156
+ const handled = injector.tryHandle(event, captureStdin);
157
+
158
+ assert.strictEqual(handled, true);
159
+ assert.strictEqual(captured.length, 1);
160
+ });
161
+
143
162
  test('tryHandle matches by question ID — single select', (t) => {
144
163
  const injector = new AnswerInjector({ questions: { deploy_target: 'GCP' } });
145
164
 
@@ -312,7 +331,7 @@ test('tryHandle deferred resolution — observeEvent after tryHandle', async (t)
312
331
  // ---------------------------------------------------------------------------
313
332
 
314
333
  test('getSecretEnvVars returns secrets map', (t) => {
315
- const secrets = { API_KEY: 'sk-123', DB_URL: 'postgres://localhost/db' };
334
+ const secrets = { API_KEY: 'sk-123', DB_URL: 'db-local-fixture' };
316
335
  const injector = new AnswerInjector({ secrets });
317
336
 
318
337
  assert.deepStrictEqual(injector.getSecretEnvVars(), secrets);
@@ -370,6 +370,49 @@ test("mergeCompletedMilestone — synthesizes roadmap from DB when projection is
370
370
  }
371
371
  });
372
372
 
373
+ test("mergeCompletedMilestone — stale worktree marker does not auto-commit dirty root overlap", async () => {
374
+ const savedCwd = process.cwd();
375
+ const repo = createTempRepo();
376
+
377
+ try {
378
+ setupWorktreeIsolation(repo);
379
+ setupRoadmap(repo, "M011", "Dirty Root Recovery", ["S01: App shell"]);
380
+
381
+ createMilestoneBranch(repo, "M011", [
382
+ { name: "index.html", content: "<h1>M011</h1>\n" },
383
+ ]);
384
+
385
+ // Stale marker without a registered git worktree. Recovery must not treat
386
+ // the project root as a worktree and auto-commit this overlapping file to
387
+ // main before attempting the milestone merge.
388
+ mkdirSync(join(repo, ".gsd", "worktrees", "M011", ".gsd"), { recursive: true });
389
+ writeFileSync(join(repo, "index.html"), "<h1>local root draft</h1>\n");
390
+
391
+ process.chdir(repo);
392
+ const result = await mergeCompletedMilestone(repo, "M011");
393
+
394
+ assert.equal(result.success, false, "dirty overlap should block branch-mode recovery");
395
+ assert.match(
396
+ result.error ?? "",
397
+ /checkout|overwritten|untracked|would be overwritten/i,
398
+ "error should explain that checkout/dirty root state blocked recovery",
399
+ );
400
+
401
+ const subjects = run("git log --format=%s", repo);
402
+ assert.ok(
403
+ !subjects.includes("chore: auto-commit before milestone merge"),
404
+ "recovery must not auto-commit project-root overlap to main",
405
+ );
406
+ assert.equal(run("git branch --show-current", repo), "main");
407
+ assert.equal(run("git branch --list milestone/M011", repo).trim(), "milestone/M011");
408
+ assert.equal(run("git status --short -- index.html", repo), "?? index.html");
409
+ } finally {
410
+ process.chdir(savedCwd);
411
+ try { run("git reset --hard HEAD", repo); } catch { /* */ }
412
+ cleanup(repo);
413
+ }
414
+ });
415
+
373
416
  test("mergeCompletedMilestone — clean merge, session status cleaned up", async () => {
374
417
  const savedCwd = process.cwd();
375
418
  const repo = createTempRepo();
@@ -43,6 +43,14 @@ describe("hasInteractiveToolInFlight", () => {
43
43
  assert.equal(hasInteractiveToolInFlight(), true);
44
44
  });
45
45
 
46
+ test("returns true when MCP-scoped interactive tools are in-flight", () => {
47
+ markToolStart("call-1", true, "mcp__custom-workflow__ask_user_questions");
48
+ assert.equal(hasInteractiveToolInFlight(), true);
49
+ clearInFlightTools();
50
+ markToolStart("call-2", true, "mcp__custom-workflow__secure_env_collect");
51
+ assert.equal(hasInteractiveToolInFlight(), true);
52
+ });
53
+
46
54
  test("returns false after interactive tool completes", () => {
47
55
  markToolStart("call-1", true, "ask_user_questions");
48
56
  assert.equal(hasInteractiveToolInFlight(), true);
@@ -10,9 +10,10 @@ import {
10
10
  formatKeyDashboard,
11
11
  formatTestResults,
12
12
  runKeyDoctor,
13
- formatDoctorFindings,
14
- PROVIDER_REGISTRY,
15
- } from "../key-manager.ts";
13
+ formatDoctorFindings,
14
+ PROVIDER_REGISTRY,
15
+ getProviderAuthMode,
16
+ } from "../key-manager.ts";
16
17
 
17
18
  function makeAuth(data: Record<string, any> = {}): AuthStorage {
18
19
  return AuthStorage.inMemory(data);
@@ -76,6 +77,12 @@ test("describeCredential describes an empty API key", () => {
76
77
  assert.equal(describeCredential({ type: "api_key", key: "" }), "empty key");
77
78
  });
78
79
 
80
+ test("describeCredential describes external CLI sentinels without calling them API keys", () => {
81
+ const provider = PROVIDER_REGISTRY.find((p) => p.id === "claude-code");
82
+ assert.ok(provider);
83
+ assert.equal(describeCredential({ type: "api_key", key: "cli" }, provider), "external CLI");
84
+ });
85
+
79
86
  test("describeCredential describes an OAuth token with expiry", () => {
80
87
  const result = describeCredential({
81
88
  type: "oauth",
@@ -149,7 +156,19 @@ test("PROVIDER_REGISTRY includes claude-code as a first-class LLM provider (#454
149
156
  const entry = PROVIDER_REGISTRY.find((p) => p.id === "claude-code");
150
157
  assert.ok(entry, "claude-code must be in PROVIDER_REGISTRY");
151
158
  assert.equal(entry!.category, "llm");
152
- assert.ok(entry!.hasOAuth, "claude-code uses OAuth (CLI auth)");
159
+ assert.equal(getProviderAuthMode(entry!), "externalCli");
160
+ });
161
+
162
+ test("PROVIDER_REGISTRY classifies only Copilot and Codex as browser OAuth LLM providers", () => {
163
+ const modes = Object.fromEntries(
164
+ PROVIDER_REGISTRY.filter((p) => p.category === "llm").map((p) => [p.id, getProviderAuthMode(p)]),
165
+ );
166
+ assert.equal(modes.anthropic, "apiKey");
167
+ assert.equal(modes["github-copilot"], "browserOAuth");
168
+ assert.equal(modes["openai-codex"], "browserOAuth");
169
+ assert.equal(modes["claude-code"], "externalCli");
170
+ assert.equal(modes["google-gemini-cli"], "externalCli");
171
+ assert.equal(modes["google-antigravity"], "externalCli");
153
172
  });
154
173
 
155
174
  test("PROVIDER_REGISTRY includes all tool/search providers", () => {
@@ -4,7 +4,7 @@ import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
 
7
- import { discoverMcpServerNames, computeMcpDisallowedTools } from "../mcp-filter.ts";
7
+ import { discoverMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools } from "../mcp-filter.ts";
8
8
  import type { ClaudeCodeMcpConfig } from "../preferences-types.ts";
9
9
 
10
10
  // ─── discoverMcpServerNames ────────────────────────────────────────────────
@@ -57,6 +57,24 @@ describe("discoverMcpServerNames", () => {
57
57
  const result = discoverMcpServerNames(dir);
58
58
  assert.deepEqual(result, ["only-server"]);
59
59
  });
60
+
61
+ it("discovers workflow server names by config signature", () => {
62
+ const dir = mkdtempSync(join(tmpdir(), "mcp-filter-test-"));
63
+ writeFileSync(
64
+ join(dir, ".mcp.json"),
65
+ JSON.stringify({
66
+ mcpServers: {
67
+ "custom-workflow": {
68
+ command: "node",
69
+ args: ["custom-cli.js"],
70
+ env: { GSD_WORKFLOW_PROJECT_ROOT: dir },
71
+ },
72
+ unrelated: { command: "npx", args: ["other"] },
73
+ },
74
+ }),
75
+ );
76
+ assert.equal(discoverWorkflowMcpServerName(dir), "custom-workflow");
77
+ });
60
78
  });
61
79
 
62
80
  // ─── computeMcpDisallowedTools ─────────────────────────────────────────────
@@ -72,6 +72,30 @@ test("ensureProjectWorkflowMcpConfig preserves existing mcp servers", () => {
72
72
  }
73
73
  });
74
74
 
75
+ test("ensureProjectWorkflowMcpConfig uses custom workflow server name from env", () => {
76
+ const projectRoot = mkdtempSync(join(tmpdir(), "gsd-mcp-init-"));
77
+ mkdirSync(join(projectRoot, ".gsd"), { recursive: true });
78
+
79
+ try {
80
+ const result = ensureProjectWorkflowMcpConfig(projectRoot, {
81
+ GSD_WORKFLOW_MCP_COMMAND: "node",
82
+ GSD_WORKFLOW_MCP_NAME: "custom-workflow",
83
+ GSD_WORKFLOW_MCP_ARGS: JSON.stringify(["server.js"]),
84
+ GSD_WORKFLOW_MCP_CWD: projectRoot,
85
+ });
86
+ assert.equal(result.status, "created");
87
+ assert.equal(result.serverName, "custom-workflow");
88
+
89
+ const parsed = JSON.parse(readFileSync(result.configPath, "utf-8")) as {
90
+ mcpServers?: Record<string, { command?: string; args?: string[] }>;
91
+ };
92
+ assert.ok(parsed.mcpServers?.["custom-workflow"]);
93
+ assert.equal(parsed.mcpServers?.[GSD_WORKFLOW_MCP_SERVER_NAME], undefined);
94
+ } finally {
95
+ rmSync(projectRoot, { recursive: true, force: true });
96
+ }
97
+ });
98
+
75
99
  test("ensureProjectWorkflowMcpConfig is idempotent when config is already current", () => {
76
100
  const projectRoot = mkdtempSync(join(tmpdir(), "gsd-mcp-init-"));
77
101
  mkdirSync(join(projectRoot, ".gsd"), { recursive: true });
@@ -1,5 +1,6 @@
1
1
  import assert from "node:assert/strict";
2
- import { mkdtempSync, rmSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { copyFileSync, mkdtempSync, renameSync, rmSync } from "node:fs";
3
4
  import { join } from "node:path";
4
5
  import { tmpdir } from "node:os";
5
6
  import test from "node:test";
@@ -7,7 +8,9 @@ import test from "node:test";
7
8
  import { ensureDbOpen } from "../bootstrap/dynamic-tools.ts";
8
9
  import {
9
10
  closeDatabase,
11
+ checkpointDatabase,
10
12
  getAllMilestones,
13
+ _getAdapter,
11
14
  insertMilestone,
12
15
  insertSlice,
13
16
  insertTask,
@@ -20,6 +23,20 @@ import {
20
23
  import { writeGSDDirectory } from "../migrate/writer.ts";
21
24
  import type { GSDProject } from "../migrate/types.ts";
22
25
 
26
+ const _require = createRequire(import.meta.url);
27
+
28
+ function openRawSqliteForTest(dbPath: string): { exec(sql: string): void; close(): void } {
29
+ try {
30
+ const mod = _require("node:sqlite") as { DatabaseSync: new (path: string) => { exec(sql: string): void; close(): void } };
31
+ return new mod.DatabaseSync(dbPath);
32
+ } catch {
33
+ type SqliteCtor = new (path: string) => { exec(sql: string): void; close(): void };
34
+ const mod = _require("better-sqlite3") as SqliteCtor | { default: SqliteCtor };
35
+ const DatabaseCtor: SqliteCtor = typeof mod === "function" ? mod : mod.default;
36
+ return new DatabaseCtor(dbPath);
37
+ }
38
+ }
39
+
23
40
  function makeBase(): string {
24
41
  return mkdtempSync(join(tmpdir(), "gsd-migration-auto-check-"));
25
42
  }
@@ -133,3 +150,41 @@ test("migration auto-check leaves matching DB hierarchy alone", async () => {
133
150
  cleanup(base);
134
151
  }
135
152
  });
153
+
154
+ test("migration auto-check refreshes a stale open DB handle before comparing", async () => {
155
+ const base = makeBase();
156
+ try {
157
+ await writeGSDDirectory(projectFixture(), base);
158
+ assert.equal(await ensureDbOpen(base), true);
159
+ insertMilestone({ id: "M001", title: "Legacy Milestone", status: "active" });
160
+ checkpointDatabase();
161
+
162
+ const dbPath = join(base, ".gsd", "gsd.db");
163
+ const replacementPath = join(base, ".gsd", "gsd-replacement.db");
164
+ copyFileSync(dbPath, replacementPath);
165
+
166
+ const replacement = openRawSqliteForTest(replacementPath);
167
+ try {
168
+ replacement.exec(`
169
+ INSERT INTO slices (milestone_id, id, title, status, risk, depends, demo, created_at, sequence)
170
+ VALUES ('M001', 'S01', 'Legacy Slice', 'pending', 'medium', '[]', 'Legacy slice demo', '', 1);
171
+ INSERT INTO tasks (milestone_id, slice_id, id, title, status, sequence)
172
+ VALUES ('M001', 'S01', 'T01', 'Legacy Task', 'pending', 1);
173
+ `);
174
+ } finally {
175
+ replacement.close();
176
+ }
177
+
178
+ const staleAdapter = _getAdapter();
179
+ renameSync(replacementPath, dbPath);
180
+
181
+ const result = await checkMarkdownHierarchyAgainstDb(base);
182
+ assert.notEqual(_getAdapter(), staleAdapter, "startup comparison must reopen the active DB handle");
183
+ assert.equal(result.action, "none");
184
+ assert.equal(result.reason, "in-sync");
185
+ assert.deepEqual(result.markdown, { milestones: 1, slices: 1, tasks: 1 });
186
+ assert.deepEqual(result.beforeDb, { milestones: 1, slices: 1, tasks: 1 });
187
+ } finally {
188
+ cleanup(base);
189
+ }
190
+ });
@@ -11,6 +11,7 @@ import { visibleWidth } from "@gsd/pi-tui";
11
11
  import { appendNotification, initNotificationStore, _resetNotificationStore } from "../notification-store.ts";
12
12
  import { GSDNotificationOverlay, notificationOverlayOptions } from "../notification-overlay.ts";
13
13
  import { wrapVisibleText } from "../tui/render-kit.ts";
14
+ import { assertFullOuterBorder } from "./tui-border-assertions.ts";
14
15
 
15
16
  const fakeTheme = {
16
17
  fg: (_color: string, text: string) => text,
@@ -92,7 +93,11 @@ describe("notification overlay — wrapText", () => {
92
93
  t.after(() => overlay.dispose());
93
94
 
94
95
  for (const width of [40, 80, 120]) {
95
- assertLinesFit(overlay.render(width), width);
96
+ const rendered = overlay.render(width);
97
+ assertLinesFit(rendered, width);
98
+ assertFullOuterBorder(rendered, width);
99
+ assert.match(rendered[0] ?? "", /^╭─ Notifications /);
100
+ assert.match(rendered.at(-1) ?? "", /^╰─+╯$/);
96
101
  overlay.invalidate();
97
102
  }
98
103
  });
@@ -48,20 +48,27 @@ describe("auditOrphanedMilestoneBranches", () => {
48
48
  const result = auditOrphanedMilestoneBranches(dir, "worktree");
49
49
  assert.deepStrictEqual(result.recovered, []);
50
50
  assert.deepStrictEqual(result.warnings, []);
51
+ assert.deepStrictEqual(result.actions, []);
52
+ assert.equal(result.blockingStrandedWork, null);
51
53
  });
52
54
 
53
- test("skips in none isolation mode", () => {
54
- // Create a milestone branch that would otherwise be detected
55
+ test("runs in none isolation mode and cleans safe completed residue", () => {
55
56
  run("git branch milestone/M001", dir);
56
57
  insertMilestone({ id: "M001", title: "Test", status: "complete" });
57
58
 
58
59
  const result = auditOrphanedMilestoneBranches(dir, "none");
59
- assert.deepStrictEqual(result.recovered, []);
60
+ assert.ok(
61
+ result.recovered.some((r) => r.includes("Deleted merged branch milestone/M001")),
62
+ `should clean merged completed residue even in none mode; got: ${JSON.stringify(result.recovered)}`,
63
+ );
60
64
  assert.deepStrictEqual(result.warnings, []);
65
+ assert.ok(
66
+ result.actions.some((action) => action.kind === "complete-merged-branch"),
67
+ "should record structured cleanup action",
68
+ );
61
69
 
62
- // Branch should still exist
63
70
  const branches = run("git branch --list milestone/M001", dir);
64
- assert.ok(branches.includes("milestone/M001"), "branch should be preserved in none mode");
71
+ assert.equal(branches, "", "safe completed branch should be cleaned in none mode");
65
72
  });
66
73
 
67
74
  test("deletes merged branch for completed milestone", () => {
@@ -149,9 +156,12 @@ describe("auditOrphanedMilestoneBranches", () => {
149
156
  // Must surface a warning so the user knows the worktree holds uncollapsed work
150
157
  assert.ok(result.warnings.length > 0, "should warn about in-progress orphan");
151
158
  assert.ok(
152
- result.warnings.some(w => w.includes("milestone/M001") && w.includes("in-progress")),
153
- `warning should mention milestone/M001 and in-progress state; got: ${JSON.stringify(result.warnings)}`,
159
+ result.warnings.some(w => w.includes("Stranded work") && w.includes("milestone/M001") && w.includes("in-progress")),
160
+ `warning should mention stranded milestone/M001 and in-progress state; got: ${JSON.stringify(result.warnings)}`,
154
161
  );
162
+ assert.equal(result.blockingStrandedWork?.milestoneId, "M001");
163
+ assert.equal(result.blockingStrandedWork?.recoveryMode, "branch");
164
+ assert.equal(result.blockingStrandedWork?.commitsAhead, 1);
155
165
 
156
166
  // Branch must still exist
157
167
  const branches = run("git branch --list milestone/M001", dir);
@@ -184,6 +194,53 @@ describe("auditOrphanedMilestoneBranches", () => {
184
194
  result.warnings.some(w => w.includes(".gsd/worktrees/M001") || w.includes("worktree")),
185
195
  `warning should reference the worktree location; got: ${JSON.stringify(result.warnings)}`,
186
196
  );
197
+ assert.equal(result.blockingStrandedWork?.recoveryMode, "worktree");
198
+ });
199
+
200
+ test("detects dirty in-progress worktree even when branch has no commits ahead", () => {
201
+ run("git branch milestone/M001", dir);
202
+
203
+ const wtDir = join(dir, ".gsd", "worktrees", "M001");
204
+ mkdirSync(wtDir, { recursive: true });
205
+ writeFileSync(join(wtDir, ".git"), `gitdir: ${join(dir, ".git", "worktrees", "M001")}\n`);
206
+ writeFileSync(join(wtDir, "dirty.txt"), "uncommitted work\n");
207
+
208
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
209
+
210
+ const result = auditOrphanedMilestoneBranches(dir, "worktree", {
211
+ hasChanges: (basePath) => basePath === wtDir,
212
+ });
213
+
214
+ assert.deepStrictEqual(result.recovered, []);
215
+ assert.ok(
216
+ result.warnings.some((w) => w.includes("uncommitted changes")),
217
+ `dirty worktree should be treated as stranded work; got: ${JSON.stringify(result.warnings)}`,
218
+ );
219
+ assert.equal(result.blockingStrandedWork?.milestoneId, "M001");
220
+ assert.equal(result.blockingStrandedWork?.dirtyWorktree, true);
221
+ assert.equal(result.blockingStrandedWork?.recoveryMode, "worktree");
222
+ });
223
+
224
+ test("detects dirty in-progress worktree even when milestone branch is absent", () => {
225
+ const wtDir = join(dir, ".gsd", "worktrees", "M001");
226
+ mkdirSync(wtDir, { recursive: true });
227
+ writeFileSync(join(wtDir, ".git"), `gitdir: ${join(dir, ".git", "worktrees", "M001")}\n`);
228
+ writeFileSync(join(wtDir, "dirty.txt"), "branchless work\n");
229
+
230
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
231
+
232
+ const result = auditOrphanedMilestoneBranches(dir, "none", {
233
+ hasChanges: (basePath) => basePath === wtDir,
234
+ });
235
+
236
+ assert.deepStrictEqual(result.recovered, []);
237
+ assert.ok(
238
+ result.warnings.some((w) => w.includes("Stranded work") && w.includes("M001")),
239
+ `branchless dirty worktree should block; got: ${JSON.stringify(result.warnings)}`,
240
+ );
241
+ assert.equal(result.blockingStrandedWork?.branch, undefined);
242
+ assert.equal(result.blockingStrandedWork?.dirtyWorktree, true);
243
+ assert.equal(result.blockingStrandedWork?.recoveryMode, "worktree");
187
244
  });
188
245
 
189
246
  test("cleans up orphaned worktree directory for merged milestone", () => {
@@ -359,7 +416,7 @@ describe("auditOrphanedMilestoneBranches", () => {
359
416
  assert.ok(existsSync(wtDir), "active milestone worktree dir must be preserved");
360
417
  });
361
418
 
362
- test("#5879 — skips branch-less orphan in 'none' isolation mode", () => {
419
+ test("#5879 — cleans branch-less complete orphan in 'none' isolation mode", () => {
363
420
  insertMilestone({ id: "M001", title: "Test", status: "complete" });
364
421
 
365
422
  const wtDir = join(dir, ".gsd", "worktrees", "M001");
@@ -368,7 +425,10 @@ describe("auditOrphanedMilestoneBranches", () => {
368
425
 
369
426
  const result = auditOrphanedMilestoneBranches(dir, "none");
370
427
 
371
- assert.deepStrictEqual(result.recovered, []);
372
- assert.ok(existsSync(wtDir), "'none' mode must not touch worktree dirs");
428
+ assert.ok(
429
+ result.recovered.some((r) => r.includes("M001") && r.includes("branch already deleted")),
430
+ `none mode should still clean safe completed residue; got: ${JSON.stringify(result.recovered)}`,
431
+ );
432
+ assert.ok(!existsSync(wtDir), "completed orphan worktree dir should be cleaned in none mode");
373
433
  });
374
434
  });
@@ -5,6 +5,7 @@ import { describe, it } from "node:test";
5
5
  import assert from "node:assert/strict";
6
6
 
7
7
  import { visibleWidth } from "@gsd/pi-tui";
8
+ import { assertFullOuterBorder } from "./tui-border-assertions.ts";
8
9
 
9
10
  function assertLinesFit(lines: string[], width: number): void {
10
11
  for (const line of lines) {
@@ -51,6 +52,9 @@ describe("parallel-monitor-overlay", () => {
51
52
  const joined = lines.join("\n");
52
53
  assert.ok(joined.includes("Parallel Monitor"), "should include title");
53
54
  assert.ok(joined.includes("No parallel workers found"), "should show empty state");
55
+ assertFullOuterBorder(lines, 80);
56
+ assert.match(lines[0] ?? "", /^╭─ GSD Parallel Monitor /);
57
+ assert.match(lines.at(-1) ?? "", /^╰─+╯$/);
54
58
 
55
59
  // Dispose should not throw
56
60
  overlay.dispose();
@@ -105,7 +109,9 @@ describe("parallel-monitor-overlay", () => {
105
109
  );
106
110
 
107
111
  for (const width of [40, 80, 120]) {
108
- assertLinesFit(overlay.render(width), width);
112
+ const lines = overlay.render(width);
113
+ assertLinesFit(lines, width);
114
+ assertFullOuterBorder(lines, width);
109
115
  overlay.invalidate();
110
116
  }
111
117
 
@@ -19,6 +19,7 @@ import {
19
19
  openDatabase,
20
20
  } from "../gsd-db.ts";
21
21
  import { createWorktree } from "../worktree-manager.ts";
22
+ import { _resetLogs, drainLogs, setStderrLoggingEnabled } from "../workflow-logger.ts";
22
23
 
23
24
  // ─── Fixture Helpers ───────────────────────────────────────────────────────
24
25
 
@@ -190,7 +191,9 @@ test('getActiveMilestoneId skips parked', async () => {
190
191
  // ─── Test 10: discardMilestone removes directory ──────────────────────
191
192
  test('discardMilestone removes directory', async () => {
192
193
  const base = createFixtureBase();
194
+ const previousStderr = setStderrLoggingEnabled(false);
193
195
  try {
196
+ _resetLogs();
194
197
  createMilestone(base, 'M001', { withRoadmap: true });
195
198
  clearCaches();
196
199
 
@@ -200,7 +203,13 @@ test('discardMilestone removes directory', async () => {
200
203
  const success = discardMilestone(base, 'M001');
201
204
  assert.ok(success, 'discardMilestone returns true');
202
205
  assert.ok(!existsSync(mDir), 'milestone dir removed after discard');
206
+ const logs = drainLogs();
207
+ assert.ok(
208
+ logs.some((entry) => entry.message.includes('discardMilestone DB cleanup skipped for M001: database unavailable')),
209
+ 'discardMilestone warns when DB cleanup is skipped',
210
+ );
203
211
  } finally {
212
+ setStderrLoggingEnabled(previousStderr);
204
213
  cleanup(base);
205
214
  }
206
215
  });