@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.75048e7

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 (452) hide show
  1. package/dist/cli.js +3 -2
  2. package/dist/help-text.js +10 -6
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
  5. package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
  6. package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
  7. package/dist/resources/extensions/browser-tools/index.js +57 -9
  8. package/dist/resources/extensions/browser-tools/package.json +5 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
  10. package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
  11. package/dist/resources/extensions/gsd/auto/phases.js +4 -3
  12. package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
  13. package/dist/resources/extensions/gsd/auto-dispatch.js +55 -0
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
  15. package/dist/resources/extensions/gsd/auto-prompts.js +72 -22
  16. package/dist/resources/extensions/gsd/auto-recovery.js +7 -8
  17. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  18. package/dist/resources/extensions/gsd/auto-start.js +94 -15
  19. package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
  20. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -65
  21. package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
  22. package/dist/resources/extensions/gsd/auto.js +31 -6
  23. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -4
  24. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +56 -20
  26. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +33 -38
  27. package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
  28. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
  29. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  30. package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
  31. package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
  32. package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
  33. package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
  34. package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
  35. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
  36. package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
  37. package/dist/resources/extensions/gsd/config-overlay.js +2 -1
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
  41. package/dist/resources/extensions/gsd/error-classifier.js +2 -1
  42. package/dist/resources/extensions/gsd/escalation.js +4 -4
  43. package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
  44. package/dist/resources/extensions/gsd/forensics.js +74 -2
  45. package/dist/resources/extensions/gsd/gsd-db.js +42 -6
  46. package/dist/resources/extensions/gsd/guided-flow.js +119 -176
  47. package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
  48. package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
  49. package/dist/resources/extensions/gsd/memory-store.js +4 -1
  50. package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
  51. package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
  52. package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
  53. package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
  54. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  55. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  56. package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
  57. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  58. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  59. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  61. package/dist/resources/extensions/gsd/prompts/run-uat.md +33 -23
  62. package/dist/resources/extensions/gsd/prompts/system.md +3 -1
  63. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  64. package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
  65. package/dist/resources/extensions/gsd/rule-registry.js +428 -52
  66. package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
  67. package/dist/resources/extensions/gsd/skill-activation.js +20 -3
  68. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
  69. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
  70. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
  71. package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
  72. package/dist/resources/extensions/gsd/state.js +17 -14
  73. package/dist/resources/extensions/gsd/templates/plan.md +3 -1
  74. package/dist/resources/extensions/gsd/tool-contract.js +5 -0
  75. package/dist/resources/extensions/gsd/tool-presentation-plan.js +143 -0
  76. package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
  77. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
  78. package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
  79. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
  80. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  81. package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
  82. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +483 -6
  83. package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
  84. package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
  85. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  86. package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
  87. package/dist/resources/extensions/gsd/verification-gate.js +72 -1
  88. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
  89. package/dist/resources/extensions/gsd/workflow-mcp.js +5 -73
  90. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
  91. package/dist/resources/extensions/mcp-client/manager.js +31 -1
  92. package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
  93. package/dist/rtk.d.ts +7 -1
  94. package/dist/rtk.js +27 -11
  95. package/dist/update-check.d.ts +15 -1
  96. package/dist/update-check.js +87 -12
  97. package/dist/update-cmd.d.ts +1 -0
  98. package/dist/update-cmd.js +53 -2
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  101. package/dist/web/standalone/.next/build-manifest.json +2 -2
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/index.html +1 -1
  121. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  128. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  129. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  131. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  132. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  133. package/package.json +5 -3
  134. package/packages/cloud-mcp-gateway/package.json +2 -2
  135. package/packages/contracts/dist/workflow.d.ts +14 -0
  136. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  137. package/packages/contracts/dist/workflow.js +16 -0
  138. package/packages/contracts/dist/workflow.js.map +1 -1
  139. package/packages/contracts/package.json +1 -1
  140. package/packages/daemon/package.json +4 -4
  141. package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
  142. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  143. package/packages/gsd-agent-core/dist/agent-session.js +32 -0
  144. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  145. package/packages/gsd-agent-core/dist/index.d.ts +1 -0
  146. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  147. package/packages/gsd-agent-core/dist/index.js +1 -0
  148. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  149. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
  150. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
  151. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
  152. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
  153. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
  154. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  155. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  156. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  157. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
  158. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  159. package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
  160. package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
  161. package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
  162. package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
  163. package/packages/gsd-agent-core/package.json +6 -6
  164. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
  165. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
  167. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
  168. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  169. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  171. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  172. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  173. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
  176. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  177. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
  178. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  179. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  180. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
  186. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  188. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  190. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  196. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
  197. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  198. package/packages/gsd-agent-modes/package.json +7 -7
  199. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  200. package/packages/mcp-server/dist/remote-questions.js +23 -9
  201. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  203. package/packages/mcp-server/dist/workflow-tools.js +84 -2
  204. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  205. package/packages/mcp-server/package.json +3 -3
  206. package/packages/native/package.json +1 -1
  207. package/packages/pi-agent-core/dist/agent-loop.js +42 -3
  208. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  209. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  210. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  211. package/packages/pi-agent-core/dist/agent.js +2 -0
  212. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  213. package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  214. package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
  215. package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  216. package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
  217. package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  218. package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
  219. package/packages/pi-agent-core/dist/types.d.ts +6 -1
  220. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  221. package/packages/pi-agent-core/dist/types.js.map +1 -1
  222. package/packages/pi-agent-core/package.json +1 -1
  223. package/packages/pi-ai/dist/api-registry.d.ts +2 -0
  224. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  225. package/packages/pi-ai/dist/api-registry.js +23 -0
  226. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  227. package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
  228. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  229. package/packages/pi-ai/dist/image-models.generated.js +15 -0
  230. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  231. package/packages/pi-ai/dist/models.generated.d.ts +411 -39
  232. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  233. package/packages/pi-ai/dist/models.generated.js +504 -153
  234. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  235. package/packages/pi-ai/dist/stream.js +6 -6
  236. package/packages/pi-ai/dist/stream.js.map +1 -1
  237. package/packages/pi-ai/package.json +1 -1
  238. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
  239. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  243. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  245. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  247. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
  249. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
  252. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
  254. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
  256. package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
  259. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  260. package/packages/pi-coding-agent/package.json +7 -7
  261. package/packages/pi-tui/dist/terminal.d.ts +1 -0
  262. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  263. package/packages/pi-tui/dist/terminal.js +8 -4
  264. package/packages/pi-tui/dist/terminal.js.map +1 -1
  265. package/packages/pi-tui/package.json +1 -1
  266. package/packages/rpc-client/package.json +2 -2
  267. package/pkg/package.json +1 -1
  268. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
  269. package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
  270. package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
  271. package/src/resources/extensions/browser-tools/index.ts +60 -9
  272. package/src/resources/extensions/browser-tools/package.json +5 -1
  273. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
  274. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
  275. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
  276. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
  277. package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
  278. package/src/resources/extensions/gsd/auto/phases.ts +5 -3
  279. package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
  280. package/src/resources/extensions/gsd/auto-dispatch.ts +67 -0
  281. package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
  282. package/src/resources/extensions/gsd/auto-prompts.ts +106 -15
  283. package/src/resources/extensions/gsd/auto-recovery.ts +7 -7
  284. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  285. package/src/resources/extensions/gsd/auto-start.ts +112 -17
  286. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  287. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -73
  288. package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
  289. package/src/resources/extensions/gsd/auto.ts +47 -5
  290. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +96 -4
  291. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
  292. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +81 -25
  293. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +70 -63
  294. package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
  295. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
  296. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  297. package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
  298. package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
  299. package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
  300. package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
  301. package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
  302. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
  303. package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
  304. package/src/resources/extensions/gsd/config-overlay.ts +3 -1
  305. package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
  306. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  307. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
  308. package/src/resources/extensions/gsd/error-classifier.ts +2 -1
  309. package/src/resources/extensions/gsd/escalation.ts +4 -4
  310. package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
  311. package/src/resources/extensions/gsd/forensics.ts +99 -5
  312. package/src/resources/extensions/gsd/gsd-db.ts +46 -8
  313. package/src/resources/extensions/gsd/guided-flow.ts +215 -217
  314. package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
  315. package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
  316. package/src/resources/extensions/gsd/memory-store.ts +4 -1
  317. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  318. package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
  319. package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
  320. package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
  321. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  322. package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
  323. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  324. package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
  325. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  326. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  327. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  328. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  329. package/src/resources/extensions/gsd/prompts/run-uat.md +33 -23
  330. package/src/resources/extensions/gsd/prompts/system.md +3 -1
  331. package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  332. package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
  333. package/src/resources/extensions/gsd/rule-registry.ts +558 -58
  334. package/src/resources/extensions/gsd/rule-types.ts +2 -0
  335. package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
  336. package/src/resources/extensions/gsd/skill-activation.ts +20 -2
  337. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
  338. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
  339. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
  340. package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
  341. package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
  342. package/src/resources/extensions/gsd/state.ts +18 -14
  343. package/src/resources/extensions/gsd/templates/plan.md +3 -1
  344. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
  345. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
  346. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
  347. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
  348. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
  349. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
  350. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
  351. package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
  352. package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
  353. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
  354. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
  355. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
  356. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
  357. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
  358. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  359. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
  360. package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
  361. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
  362. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
  363. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
  364. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
  365. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
  366. package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
  367. package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
  368. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
  369. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
  370. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
  371. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
  372. package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
  373. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
  374. package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
  375. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
  376. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
  377. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
  378. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
  379. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
  380. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
  381. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
  382. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
  383. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
  384. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +72 -10
  385. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
  386. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
  387. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
  388. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
  389. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
  390. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
  391. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
  392. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
  393. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
  394. package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
  395. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
  396. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
  397. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
  398. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
  399. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
  400. package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
  401. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +83 -1
  402. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
  403. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
  404. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
  405. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
  406. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +79 -0
  407. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
  408. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
  409. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
  410. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -0
  411. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
  412. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
  413. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
  414. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  415. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
  416. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  417. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
  418. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
  419. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
  420. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
  421. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
  422. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
  423. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
  424. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
  425. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
  426. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +493 -0
  427. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +40 -0
  428. package/src/resources/extensions/gsd/tool-contract.ts +6 -0
  429. package/src/resources/extensions/gsd/tool-presentation-plan.ts +223 -0
  430. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
  431. package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
  432. package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
  433. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
  434. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  435. package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
  436. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +589 -8
  437. package/src/resources/extensions/gsd/types.ts +69 -5
  438. package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
  439. package/src/resources/extensions/gsd/unit-tool-contracts.ts +186 -0
  440. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  441. package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
  442. package/src/resources/extensions/gsd/verification-gate.ts +87 -1
  443. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
  444. package/src/resources/extensions/gsd/workflow-mcp.ts +5 -73
  445. package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
  446. package/src/resources/extensions/mcp-client/manager.ts +33 -1
  447. package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
  448. package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
  449. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
  450. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
  451. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_buildManifest.js +0 -0
  452. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_ssgManifest.js +0 -0
@@ -1,11 +1,14 @@
1
1
  /**
2
2
  * GSD Maintenance — cleanup, skip, dry-run, and recover handlers.
3
3
  *
4
- * Contains: handleCleanupBranches, handleCleanupSnapshots, handleCleanupWorktrees, handleSkip, handleDryRun, handleRecover
4
+ * Contains: handleCleanupBranches, handleCleanupSnapshots, handleCleanupWorktrees, handleSkip, handleDryRun, handleRecover, handleRebuild
5
5
  */
6
6
 
7
7
  import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
8
+ import { existsSync, mkdirSync, renameSync } from "node:fs";
9
+ import { dirname, isAbsolute, join, relative } from "node:path";
8
10
  import { deriveState } from "./state.js";
11
+ import { gsdProjectionRoot, gsdRoot } from "./paths.js";
9
12
  import { nativeBranchList, nativeDetectMainBranch, nativeBranchListMerged, nativeBranchDelete, nativeForEachRef, nativeUpdateRef } from "./native-git-bridge.js";
10
13
  import { logWarning } from "./workflow-logger.js";
11
14
 
@@ -478,6 +481,39 @@ export async function handleCleanupProjects(args: string, ctx: ExtensionCommandC
478
481
  ctx.ui.notify(lines.join("\n"), "info");
479
482
  }
480
483
 
484
+ function recoverConfirmed(args: string): boolean {
485
+ return args
486
+ .split(/\s+/)
487
+ .map((part) => part.trim().toLowerCase())
488
+ .some((part) => part === "--confirm" || part === "--yes" || part === "confirm");
489
+ }
490
+
491
+ async function confirmRecover(ctx: ExtensionCommandContext, args: string): Promise<boolean> {
492
+ if (recoverConfirmed(args)) return true;
493
+
494
+ const warning = [
495
+ "gsd recover imports markdown into the database.",
496
+ "It clears and reconstructs milestone, slice, and task hierarchy rows from rendered markdown.",
497
+ "Use /gsd rebuild markdown for normal DB-to-markdown realignment.",
498
+ ].join("\n");
499
+
500
+ if (typeof ctx.ui.confirm === "function") {
501
+ const confirmed = await ctx.ui.confirm(
502
+ "Import markdown into the DB?",
503
+ `${warning}\n\nContinue only if the DB is lost or corrupt and markdown is the source you intend to import.`,
504
+ );
505
+ if (confirmed) return true;
506
+ ctx.ui.notify("gsd recover cancelled. No database changes made.", "info");
507
+ return false;
508
+ }
509
+
510
+ ctx.ui.notify(
511
+ `${warning}\n\nNo database changes made. Re-run /gsd recover --confirm to proceed.`,
512
+ "warning",
513
+ );
514
+ return false;
515
+ }
516
+
481
517
  /**
482
518
  * `gsd recover` — Reconstruct DB hierarchy state from rendered markdown on disk.
483
519
  *
@@ -487,7 +523,7 @@ export async function handleCleanupProjects(args: string, ctx: ExtensionCommandC
487
523
  *
488
524
  * Prints counts of recovered items and the resulting project phase.
489
525
  */
490
- export async function handleRecover(ctx: ExtensionCommandContext, basePath: string): Promise<void> {
526
+ export async function handleRecover(ctx: ExtensionCommandContext, basePath: string, args = ""): Promise<void> {
491
527
  const { isDbAvailable: dbAvailable, clearEngineHierarchy, transaction: dbTransaction } = await import("./gsd-db.js");
492
528
  const { migrateHierarchyToDb } = await import("./md-importer.js");
493
529
  const { invalidateStateCache } = await import("./state.js");
@@ -497,6 +533,8 @@ export async function handleRecover(ctx: ExtensionCommandContext, basePath: stri
497
533
  return;
498
534
  }
499
535
 
536
+ if (!(await confirmRecover(ctx, args))) return;
537
+
500
538
  try {
501
539
  // 1. Delete + re-populate inside a single transaction for atomicity.
502
540
  // clearEngineHierarchy() uses transaction() internally but transaction()
@@ -542,3 +580,160 @@ export async function handleRecover(ctx: ExtensionCommandContext, basePath: stri
542
580
  ctx.ui.notify(`gsd recover failed: ${msg}`, "error");
543
581
  }
544
582
  }
583
+
584
+ function normalizeArtifactPath(value: string): string {
585
+ return value.replace(/\\/g, "/");
586
+ }
587
+
588
+ function pathWithin(root: string, candidate: string): boolean {
589
+ const rel = relative(root, candidate);
590
+ return rel.length === 0 || (!rel.startsWith("..") && !isAbsolute(rel));
591
+ }
592
+
593
+ function artifactPathForDb(basePath: string, absPath: string): string {
594
+ const projectionRoot = gsdProjectionRoot(basePath);
595
+ const root = pathWithin(projectionRoot, absPath) ? projectionRoot : gsdRoot(basePath);
596
+ return normalizeArtifactPath(relative(root, absPath));
597
+ }
598
+
599
+ function quarantineRelativePath(basePath: string, absPath: string): string {
600
+ for (const root of [gsdProjectionRoot(basePath), gsdRoot(basePath)]) {
601
+ if (pathWithin(root, absPath)) {
602
+ return normalizeArtifactPath(relative(root, absPath));
603
+ }
604
+ }
605
+ return normalizeArtifactPath(absPath.replace(/^[/\\]+/, ""));
606
+ }
607
+
608
+ function uniquePath(path: string): string {
609
+ if (!existsSync(path)) return path;
610
+ let idx = 2;
611
+ while (existsSync(`${path}.${idx}`)) idx++;
612
+ return `${path}.${idx}`;
613
+ }
614
+
615
+ function resolveDiskArtifactPath(basePath: string, artifactPath: string): string {
616
+ if (isAbsolute(artifactPath)) return artifactPath;
617
+ const candidates = [
618
+ join(gsdProjectionRoot(basePath), artifactPath),
619
+ join(gsdRoot(basePath), artifactPath),
620
+ ];
621
+ return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0]!;
622
+ }
623
+
624
+ function quarantineProjectionFile(basePath: string, absPath: string, stamp: string): string {
625
+ const rel = quarantineRelativePath(basePath, absPath);
626
+ const target = uniquePath(join(gsdProjectionRoot(basePath), "quarantine", "projections", stamp, rel));
627
+ mkdirSync(dirname(target), { recursive: true });
628
+ renameSync(absPath, target);
629
+ return target;
630
+ }
631
+
632
+ type RebuildTarget = "markdown" | "database" | "usage";
633
+
634
+ function parseRebuildTarget(args: string): RebuildTarget {
635
+ const trimmed = args.trim().toLowerCase();
636
+ if (!trimmed || trimmed === "markdown") return "markdown";
637
+ if (trimmed === "database" || trimmed === "db") return "database";
638
+ return "usage";
639
+ }
640
+
641
+ /**
642
+ * `gsd rebuild markdown` — Re-render markdown projections from the authoritative DB.
643
+ *
644
+ * This is the DB-first realignment command. It does not import markdown into
645
+ * the DB. Completion SUMMARY files that contradict open DB rows are preserved
646
+ * under `.gsd/quarantine/projections/` before DB projections are rendered.
647
+ */
648
+ export async function handleRebuild(ctx: ExtensionCommandContext, basePath: string, args = ""): Promise<void> {
649
+ const { isDbAvailable: dbAvailable, deleteArtifactByPath } = await import("./gsd-db.js");
650
+ const { detectArtifactDbDrift } = await import("./state-reconciliation/drift/artifact-db.js");
651
+ const { renderAllFromDb } = await import("./markdown-renderer.js");
652
+ const { invalidateStateCache } = await import("./state.js");
653
+
654
+ const target = parseRebuildTarget(args);
655
+ if (target === "usage") {
656
+ ctx.ui.notify(
657
+ [
658
+ "Usage:",
659
+ " /gsd rebuild markdown Rebuild markdown projections from the canonical DB",
660
+ " /gsd rebuild database Reserved for DB-native rebuilds; does not import markdown",
661
+ ].join("\n"),
662
+ "warning",
663
+ );
664
+ return;
665
+ }
666
+
667
+ if (target === "database") {
668
+ ctx.ui.notify(
669
+ [
670
+ "gsd rebuild database is reserved for DB-native rebuilds.",
671
+ "It will not import markdown projections into the DB.",
672
+ "For normal realignment, run /gsd rebuild markdown.",
673
+ "If the DB is lost or corrupt and markdown is the source to import, run /gsd recover --confirm.",
674
+ ].join("\n"),
675
+ "warning",
676
+ );
677
+ return;
678
+ }
679
+
680
+ if (!dbAvailable()) {
681
+ ctx.ui.notify("gsd rebuild markdown: No database open. Run a GSD command first to initialize the DB.", "error");
682
+ return;
683
+ }
684
+
685
+ try {
686
+ invalidateStateCache();
687
+ const state = await deriveState(basePath);
688
+ const drifts = detectArtifactDbDrift(state, { basePath, state });
689
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
690
+ const quarantined: string[] = [];
691
+ const seen = new Set<string>();
692
+
693
+ for (const drift of drifts) {
694
+ if (drift.kind !== "artifact-db-status-divergence") continue;
695
+ if (drift.artifactType !== "SUMMARY" || !drift.artifactPath) continue;
696
+ const absPath = resolveDiskArtifactPath(basePath, drift.artifactPath);
697
+ if (seen.has(absPath) || !existsSync(absPath)) continue;
698
+ seen.add(absPath);
699
+ const artifactDbPath = artifactPathForDb(basePath, absPath);
700
+ const target = quarantineProjectionFile(basePath, absPath, stamp);
701
+ deleteArtifactByPath(artifactDbPath);
702
+ quarantined.push(target);
703
+ }
704
+
705
+ const rendered = await renderAllFromDb(basePath);
706
+ invalidateStateCache();
707
+
708
+ const lines = [
709
+ "gsd rebuild markdown: rebuilt markdown projections from the canonical DB",
710
+ ` Rendered: ${rendered.rendered}`,
711
+ ` Skipped: ${rendered.skipped}`,
712
+ ` Quarantined: ${quarantined.length}`,
713
+ ];
714
+ if (rendered.errors.length > 0) {
715
+ lines.push(` Errors: ${rendered.errors.length}`);
716
+ for (const err of rendered.errors.slice(0, 5)) {
717
+ lines.push(` - ${err}`);
718
+ }
719
+ if (rendered.errors.length > 5) {
720
+ lines.push(` - ${rendered.errors.length - 5} more`);
721
+ }
722
+ }
723
+ if (quarantined.length > 0) {
724
+ lines.push("", " Quarantine:");
725
+ for (const target of quarantined.slice(0, 5)) {
726
+ lines.push(` - ${target}`);
727
+ }
728
+ if (quarantined.length > 5) {
729
+ lines.push(` - ${quarantined.length - 5} more`);
730
+ }
731
+ }
732
+
733
+ ctx.ui.notify(lines.join("\n"), rendered.errors.length > 0 ? "warning" : "success");
734
+ } catch (err) {
735
+ const msg = err instanceof Error ? err.message : String(err);
736
+ logWarning("command", `rebuild failed: ${msg}`);
737
+ ctx.ui.notify(`gsd rebuild failed: ${msg}`, "error");
738
+ }
739
+ }
@@ -7,6 +7,7 @@
7
7
  * /gsd mcp — Overview of all servers (alias: /gsd mcp status)
8
8
  * /gsd mcp status — Same as bare /gsd mcp
9
9
  * /gsd mcp check <srv> — Detailed status for a specific server
10
+ * /gsd mcp discover [srv] — Connect and list tools for a server
10
11
  * /gsd mcp test <srv> — Test handshake + tools/list for a server
11
12
  * /gsd mcp enable <srv> / disable <srv> — Toggle local server exposure
12
13
  * /gsd mcp import <srv> [as <name>] — Copy a discovered server into local config
@@ -34,6 +35,7 @@ export interface McpServerStatus {
34
35
  name: string;
35
36
  transport: ManagedMcpTransport;
36
37
  connected: boolean;
38
+ available?: boolean;
37
39
  toolCount: number;
38
40
  error: string | undefined;
39
41
  disabled?: boolean;
@@ -45,6 +47,8 @@ export interface McpServerDetail extends McpServerStatus {
45
47
  tools: string[];
46
48
  }
47
49
 
50
+ const MCP_STATUS_PROBE_TIMEOUT_MS = 10_000;
51
+
48
52
  export function hasHostMcpTool(systemPrompt: string, serverName: string): boolean {
49
53
  const marker = `mcp__${serverName}__`;
50
54
  return systemPrompt.includes(marker);
@@ -68,7 +72,8 @@ export function formatMcpInitResult(
68
72
  `Project: ${targetPath}`,
69
73
  `Config: ${configPath}`,
70
74
  "",
71
- "MCP-capable clients can now load the GSD workflow MCP server from this folder.",
75
+ "MCP-capable clients can now load the GSD workflow and gsd-browser MCP servers from this folder.",
76
+ "Pi Providers use the managed gsd-browser engine directly; this project config is for External MCP Clients.",
72
77
  "Restart or reconnect any client that already has this project open.",
73
78
  ].join("\n");
74
79
  }
@@ -89,13 +94,15 @@ export function formatMcpStatusReport(servers: McpServerStatus[]): string {
89
94
  const lines: string[] = [`MCP Server Status — ${servers.length} server(s)\n`];
90
95
 
91
96
  for (const s of servers) {
92
- const icon = s.disabled ? "⊘" : s.error ? "✗" : s.connected ? "✓" : "○";
97
+ const icon = s.disabled ? "⊘" : s.error ? "✗" : s.connected || s.available ? "✓" : "○";
93
98
  const status = s.disabled
94
99
  ? "disabled"
95
100
  : s.error
96
101
  ? `error: ${s.error}`
97
102
  : s.connected
98
103
  ? `connected — ${s.toolCount} tools`
104
+ : s.available
105
+ ? `available — ${s.toolCount} tools`
99
106
  : "disconnected";
100
107
  const warningText = s.envWarnings?.length ? ` — ${s.envWarnings.length} warning(s)` : "";
101
108
  lines.push(` ${icon} ${s.name} (${s.transport}) — ${status}${warningText}`);
@@ -103,8 +110,8 @@ export function formatMcpStatusReport(servers: McpServerStatus[]): string {
103
110
 
104
111
  lines.push("");
105
112
  lines.push("Use /gsd mcp check <server> for details on a specific server.");
113
+ lines.push("Use /gsd mcp discover <server> to connect and list tools.");
106
114
  lines.push("Use /gsd mcp test <server> to verify handshake and tool discovery.");
107
- lines.push("Use mcp_discover to connect and list tools for a server.");
108
115
 
109
116
  return lines.join("\n");
110
117
  }
@@ -120,8 +127,8 @@ export function formatMcpServerDetail(server: McpServerDetail): string {
120
127
  } else if (server.error) {
121
128
  lines.push(` Status: error`);
122
129
  lines.push(` Error: ${server.error}`);
123
- } else if (server.connected) {
124
- lines.push(` Status: connected`);
130
+ } else if (server.connected || server.available) {
131
+ lines.push(` Status: ${server.connected ? "connected" : "available"}`);
125
132
  lines.push(` Tools: ${server.toolCount}`);
126
133
  if (server.tools.length > 0) {
127
134
  lines.push("");
@@ -133,7 +140,7 @@ export function formatMcpServerDetail(server: McpServerDetail): string {
133
140
  } else {
134
141
  lines.push(` Status: disconnected`);
135
142
  lines.push("");
136
- lines.push(` Run mcp_discover("${server.name}") to connect and list tools.`);
143
+ lines.push(` Run /gsd mcp discover ${server.name} to connect and list tools.`);
137
144
  }
138
145
 
139
146
  if (server.envWarnings?.length) {
@@ -167,10 +174,93 @@ export function formatMcpConnectionTestResult(result: ManagedMcpConnectionTestRe
167
174
  ].join("\n");
168
175
  }
169
176
 
177
+ export function formatMcpDiscoveryResult(result: ManagedMcpConnectionTestResult): string {
178
+ if (result.ok) {
179
+ return [
180
+ `MCP discovery completed for ${result.server}.`,
181
+ "",
182
+ `Transport: ${result.transport}`,
183
+ `Tools: ${result.toolCount}`,
184
+ ...(result.tools.length > 0 ? ["", "Discovered tools:", ...result.tools.map((tool) => ` - ${tool}`)] : []),
185
+ "",
186
+ `Call with: mcp_call(server="${result.server}", tool="<tool_name>", args={...})`,
187
+ ].join("\n");
188
+ }
189
+
190
+ return [
191
+ `MCP discovery failed for ${result.server}.`,
192
+ "",
193
+ `Transport: ${result.transport}`,
194
+ `Error: ${result.error ?? "Unknown error"}`,
195
+ ...(result.warnings.length > 0 ? ["", "Warnings:", ...result.warnings.map((warning) => ` - ${warning}`)] : []),
196
+ ].join("\n");
197
+ }
198
+
199
+ async function readLiveConnectionStatus(serverName: string): Promise<{
200
+ connected: boolean;
201
+ tools: string[];
202
+ error?: string;
203
+ }> {
204
+ try {
205
+ const mcpClient = await import("../mcp-client/index.js");
206
+ const mod = mcpClient as Record<string, unknown>;
207
+ if (typeof mod.getConnectionStatus === "function") {
208
+ return (mod.getConnectionStatus as (name: string) => { connected: boolean; tools: string[]; error?: string })(serverName);
209
+ }
210
+ } catch {
211
+ // mcp-client may not expose status helpers in some hosts.
212
+ }
213
+ return { connected: false, tools: [] };
214
+ }
215
+
216
+ function shouldProbeConfiguredServer(config: { disabled?: boolean; transport: ManagedMcpTransport; envWarnings?: string[] }): boolean {
217
+ return !config.disabled && config.transport === "stdio" && (config.envWarnings?.length ?? 0) === 0;
218
+ }
219
+
220
+ async function resolveMcpRuntimeStatus(
221
+ config: {
222
+ name: string;
223
+ transport: ManagedMcpTransport;
224
+ disabled?: boolean;
225
+ envWarnings?: string[];
226
+ },
227
+ systemPrompt: string,
228
+ ): Promise<{
229
+ connected: boolean;
230
+ available: boolean;
231
+ tools: string[];
232
+ error?: string;
233
+ }> {
234
+ const live = await readLiveConnectionStatus(config.name);
235
+ let connected = live.connected;
236
+ let tools = live.tools;
237
+ let error = live.error;
238
+
239
+ if (!connected && !error && hasHostMcpTool(systemPrompt, config.name)) connected = true;
240
+
241
+ if (!connected && !error && shouldProbeConfiguredServer(config)) {
242
+ const probed = await testMcpServerConnection(config.name, { timeoutMs: MCP_STATUS_PROBE_TIMEOUT_MS });
243
+ if (probed.ok) {
244
+ return {
245
+ connected: false,
246
+ available: true,
247
+ tools: probed.tools,
248
+ };
249
+ }
250
+ error = probed.error;
251
+ }
252
+
253
+ return {
254
+ connected,
255
+ available: false,
256
+ tools,
257
+ error,
258
+ };
259
+ }
170
260
  // ─── Command handler ────────────────────────────────────────────────────────
171
261
 
172
262
  /**
173
- * Handle `/gsd mcp [status|check <server>]`.
263
+ * Handle `/gsd mcp [status|check <server>|discover [server]|...]`.
174
264
  */
175
265
  export async function handleMcpStatus(
176
266
  args: string,
@@ -200,6 +290,28 @@ export async function handleMcpStatus(
200
290
  return;
201
291
  }
202
292
 
293
+ // /gsd mcp discover [server]
294
+ if (lowered === "discover" || lowered.startsWith("discover ")) {
295
+ const requestedServerName = trimmed.slice("discover".length).trim();
296
+ let serverName = requestedServerName;
297
+ if (!serverName) {
298
+ if (configs.length === 1) {
299
+ serverName = configs[0]!.name;
300
+ } else {
301
+ const available = configs.map((config) => config.name).join(", ") || "(none)";
302
+ ctx.ui.notify(
303
+ `Usage: /gsd mcp discover <server>\n\nAvailable: ${available}`,
304
+ "warning",
305
+ );
306
+ return;
307
+ }
308
+ }
309
+
310
+ const result = await testMcpServerConnection(serverName);
311
+ ctx.ui.notify(formatMcpDiscoveryResult(result), result.ok ? "info" : "warning");
312
+ return;
313
+ }
314
+
203
315
  // /gsd mcp test <server>
204
316
  if (lowered.startsWith("test ")) {
205
317
  const serverName = trimmed.slice("test ".length).trim();
@@ -304,33 +416,17 @@ export async function handleMcpStatus(
304
416
  return;
305
417
  }
306
418
 
307
- // Try to get connection/tool info from the mcp-client module if available
308
- let connected = false;
309
- let toolNames: string[] = [];
310
- let error: string | undefined;
311
- try {
312
- const mcpClient = await import("../mcp-client/index.js");
313
- // Access the module's connection state if exported; fall back gracefully
314
- const mod = mcpClient as Record<string, unknown>;
315
- if (typeof mod.getConnectionStatus === "function") {
316
- const status = (mod.getConnectionStatus as (name: string) => { connected: boolean; tools: string[]; error?: string })(serverName);
317
- connected = status.connected;
318
- toolNames = status.tools;
319
- error = status.error;
320
- }
321
- } catch {
322
- // mcp-client may not expose status helpers — that's fine
323
- }
324
- if (!connected && !error && hasHostMcpTool(systemPrompt, serverName)) connected = true;
419
+ const runtime = await resolveMcpRuntimeStatus(config, systemPrompt);
325
420
 
326
421
  ctx.ui.notify(
327
422
  formatMcpServerDetail({
328
423
  name: config.name,
329
424
  transport: config.transport,
330
- connected,
331
- toolCount: toolNames.length,
332
- tools: toolNames,
333
- error,
425
+ connected: runtime.connected,
426
+ available: runtime.available,
427
+ toolCount: runtime.tools.length,
428
+ tools: runtime.tools,
429
+ error: runtime.error,
334
430
  disabled: config.disabled,
335
431
  sourcePath: config.sourcePath,
336
432
  envWarnings: config.envWarnings,
@@ -342,39 +438,20 @@ export async function handleMcpStatus(
342
438
 
343
439
  // /gsd mcp or /gsd mcp status
344
440
  if (!lowered || lowered === "status") {
345
- // Build status for each server
346
- const statuses: McpServerStatus[] = [];
347
-
348
- for (const config of configs) {
349
- let connected = false;
350
- let toolCount = 0;
351
- let error: string | undefined;
352
-
353
- try {
354
- const mcpClient = await import("../mcp-client/index.js");
355
- const mod = mcpClient as Record<string, unknown>;
356
- if (typeof mod.getConnectionStatus === "function") {
357
- const status = (mod.getConnectionStatus as (name: string) => { connected: boolean; tools: string[]; error?: string })(config.name);
358
- connected = status.connected;
359
- toolCount = status.tools.length;
360
- error = status.error;
361
- }
362
- } catch {
363
- // Fall back to unknown state
364
- }
365
- if (!connected && !error && hasHostMcpTool(systemPrompt, config.name)) connected = true;
366
-
367
- statuses.push({
441
+ const statuses: McpServerStatus[] = await Promise.all(configs.map(async (config) => {
442
+ const runtime = await resolveMcpRuntimeStatus(config, systemPrompt);
443
+ return {
368
444
  name: config.name,
369
445
  transport: config.transport,
370
- connected,
371
- toolCount,
372
- error,
446
+ connected: runtime.connected,
447
+ available: runtime.available,
448
+ toolCount: runtime.tools.length,
449
+ error: runtime.error,
373
450
  disabled: config.disabled,
374
451
  sourcePath: config.sourcePath,
375
452
  envWarnings: config.envWarnings,
376
- });
377
- }
453
+ };
454
+ }));
378
455
 
379
456
  const warningLines = [
380
457
  ...management.warnings,
@@ -389,9 +466,10 @@ export async function handleMcpStatus(
389
466
 
390
467
  // Unknown subcommand
391
468
  ctx.ui.notify(
392
- "Usage: /gsd mcp [status|check <server>|test <server>|enable <server>|disable <server>|delete <server> --confirm|import <server> [as <name>]|init [dir]]\n\n" +
469
+ "Usage: /gsd mcp [status|check <server>|discover [server]|test <server>|enable <server>|disable <server>|delete <server> --confirm|import <server> [as <name>]|init [dir]]\n\n" +
393
470
  " status Show all MCP server statuses (default)\n" +
394
471
  " check <server> Detailed status for a specific server\n" +
472
+ " discover [server] Connect and list tools for a server\n" +
395
473
  " test <server> Verify MCP handshake and tools/list\n" +
396
474
  " enable <server> Enable a local GSD-managed server\n" +
397
475
  " disable <server> Disable a local GSD-managed server\n" +
@@ -23,6 +23,9 @@ import {
23
23
  import { loadFile, saveFile, splitFrontmatter, parseFrontmatterMap } from "./files.js";
24
24
  import { runClaudeImportFlow } from "./claude-import.js";
25
25
 
26
+ const DEFAULT_WIDGET_MODE = "small";
27
+ const WIDGET_MODE_OPTIONS = [DEFAULT_WIDGET_MODE, "full", "min", "off"] as const;
28
+
26
29
  /** Extract body content after frontmatter closing delimiter, or null if none. */
27
30
  function extractBodyAfterFrontmatter(content: string): string | null {
28
31
  const closingIdx = content.indexOf("\n---", content.indexOf("---"));
@@ -1558,7 +1561,7 @@ async function configureAdvanced(ctx: ExtensionCommandContext, prefs: Record<str
1558
1561
  prefs.min_request_interval_ms = minRequestInterval;
1559
1562
  }
1560
1563
 
1561
- const widget = await promptEnum(ctx, "Auto-mode widget display", prefs.widget_mode, ["full", "small", "min", "off"], "full");
1564
+ const widget = await promptEnum(ctx, "Auto-mode widget display", prefs.widget_mode, WIDGET_MODE_OPTIONS, DEFAULT_WIDGET_MODE);
1562
1565
  if (widget !== undefined) prefs.widget_mode = widget;
1563
1566
 
1564
1567
  const experimental = (prefs.experimental as Record<string, unknown> | undefined) ?? {};
@@ -238,7 +238,7 @@ export async function handleVerdict(
238
238
 
239
239
  if (effectiveVerdict === "needs-remediation") {
240
240
  ctx.ui.notify(
241
- "Follow up with gsd_reassess_roadmap to add remediation slices, then re-run /gsd auto.",
241
+ "Follow up with /gsd dispatch reassess to add remediation slices, then re-run /gsd auto.",
242
242
  "info",
243
243
  );
244
244
  }
@@ -23,6 +23,8 @@ import {
23
23
  resolveAutoSupervisorConfig,
24
24
  } from "./preferences.js";
25
25
 
26
+ const DEFAULT_WIDGET_MODE = "small";
27
+
26
28
  // ─── Data Collection ──────────────────────────────────────────────────────
27
29
 
28
30
  interface ConfigSection {
@@ -160,7 +162,7 @@ function collectConfigSections(): ConfigSection[] {
160
162
  if (prefs?.service_tier) toggleRows.push({ label: "service_tier", value: prefs.service_tier });
161
163
  if (prefs?.search_provider && prefs.search_provider !== "auto") toggleRows.push({ label: "search_provider", value: prefs.search_provider });
162
164
  if (prefs?.context_selection) toggleRows.push({ label: "context_selection", value: prefs.context_selection });
163
- if (prefs?.widget_mode && prefs.widget_mode !== "full") toggleRows.push({ label: "widget_mode", value: prefs.widget_mode });
165
+ if (prefs?.widget_mode && prefs.widget_mode !== DEFAULT_WIDGET_MODE) toggleRows.push({ label: "widget_mode", value: prefs.widget_mode });
164
166
  if (prefs?.experimental?.rtk) toggleRows.push({ label: "experimental.rtk", value: "on" });
165
167
  if (toggleRows.length > 0) sections.push({ title: "Toggles", rows: toggleRows });
166
168
 
@@ -71,6 +71,14 @@ export class GSDDashboardOverlay {
71
71
  private refreshInFlight: Promise<void> | null = null;
72
72
  private disposed = false;
73
73
  private resizeHandler: (() => void) | null = null;
74
+ private cachedMetrics: {
75
+ totals: ReturnType<typeof getProjectTotals>;
76
+ promptStats: ReturnType<typeof getPromptSizeStats>;
77
+ phases: ReturnType<typeof aggregateByPhase>;
78
+ slices: ReturnType<typeof aggregateBySlice>;
79
+ models: ReturnType<typeof aggregateByModel>;
80
+ } | null = null;
81
+ private lastSeenUnitCount = -1;
74
82
 
75
83
  constructor(
76
84
  tui: { requestRender: () => void },
@@ -123,7 +131,8 @@ export class GSDDashboardOverlay {
123
131
  this.dashData = getAutoDashboardData();
124
132
  const nextIdentity = this.computeDashboardIdentity(this.dashData);
125
133
 
126
- if (initial || nextIdentity !== this.loadedDashboardIdentity) {
134
+ const identityChanged = initial || nextIdentity !== this.loadedDashboardIdentity;
135
+ if (identityChanged) {
127
136
  const loaded = await this.loadData();
128
137
  if (this.disposed) return;
129
138
  if (loaded) {
@@ -135,7 +144,9 @@ export class GSDDashboardOverlay {
135
144
  this.loading = false;
136
145
  }
137
146
 
138
- this.invalidate();
147
+ if (identityChanged) {
148
+ this.invalidate();
149
+ }
139
150
  this.tui.requestRender();
140
151
  }
141
152
 
@@ -459,7 +470,7 @@ export class GSDDashboardOverlay {
459
470
 
460
471
  const ledger = getLedger();
461
472
  if (ledger && ledger.units.length > 0) {
462
- const totals = getProjectTotals(ledger.units);
473
+ const { totals, promptStats, phases, slices, models } = this.ensureMetricsCache(ledger.units);
463
474
 
464
475
  lines.push(blank());
465
476
  lines.push(hr());
@@ -496,7 +507,6 @@ export class GSDDashboardOverlay {
496
507
  lines.push(row(budgetParts.join(` ${th.fg("dim", "·")} `)));
497
508
  }
498
509
 
499
- const promptStats = getPromptSizeStats(ledger.units);
500
510
  if (promptStats) {
501
511
  const promptParts = [
502
512
  `${th.fg("dim", "avg prompt:")} ${th.fg("text", formatCharCount(promptStats.averagePromptChars))}`,
@@ -508,7 +518,6 @@ export class GSDDashboardOverlay {
508
518
  lines.push(row(promptParts.join(` ${th.fg("dim", "·")} `)));
509
519
  }
510
520
 
511
- const phases = aggregateByPhase(ledger.units);
512
521
  if (phases.length > 0) {
513
522
  lines.push(blank());
514
523
  lines.push(row(th.fg("dim", "By Phase")));
@@ -520,7 +529,6 @@ export class GSDDashboardOverlay {
520
529
  }
521
530
  }
522
531
 
523
- const slices = aggregateBySlice(ledger.units);
524
532
  if (slices.length > 0) {
525
533
  lines.push(blank());
526
534
  lines.push(row(th.fg("dim", "By Slice")));
@@ -551,7 +559,6 @@ export class GSDDashboardOverlay {
551
559
  }
552
560
  }
553
561
 
554
- const models = aggregateByModel(ledger.units);
555
562
  if (models.length >= 1) {
556
563
  lines.push(blank());
557
564
  lines.push(row(th.fg("dim", "By Model")));
@@ -625,6 +632,20 @@ export class GSDDashboardOverlay {
625
632
  return `${th.fg("dim", labelText)}${" ".repeat(gap)}${bar}${" ".repeat(gap)}${th.fg("dim", rightText)}`;
626
633
  }
627
634
 
635
+ private ensureMetricsCache(units: UnitMetrics[]) {
636
+ if (!this.cachedMetrics || units.length !== this.lastSeenUnitCount) {
637
+ this.cachedMetrics = {
638
+ totals: getProjectTotals(units),
639
+ promptStats: getPromptSizeStats(units),
640
+ phases: aggregateByPhase(units),
641
+ slices: aggregateBySlice(units),
642
+ models: aggregateByModel(units),
643
+ };
644
+ this.lastSeenUnitCount = units.length;
645
+ }
646
+ return this.cachedMetrics!;
647
+ }
648
+
628
649
  invalidate(): void {
629
650
  this.cachedWidth = undefined;
630
651
  this.cachedLines = undefined;