@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.9bb7453

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 (395) 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 +44 -0
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
  15. package/dist/resources/extensions/gsd/auto-prompts.js +68 -22
  16. package/dist/resources/extensions/gsd/auto-recovery.js +4 -4
  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 +2 -1
  21. package/dist/resources/extensions/gsd/auto.js +31 -6
  22. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +83 -4
  23. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
  24. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +39 -14
  25. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -10
  26. package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
  27. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
  29. package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
  30. package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
  31. package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
  32. package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
  33. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
  34. package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
  35. package/dist/resources/extensions/gsd/config-overlay.js +2 -1
  36. package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
  37. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  38. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
  39. package/dist/resources/extensions/gsd/error-classifier.js +2 -1
  40. package/dist/resources/extensions/gsd/escalation.js +4 -4
  41. package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
  42. package/dist/resources/extensions/gsd/forensics.js +74 -2
  43. package/dist/resources/extensions/gsd/gsd-db.js +42 -6
  44. package/dist/resources/extensions/gsd/guided-flow.js +30 -69
  45. package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
  46. package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
  47. package/dist/resources/extensions/gsd/memory-store.js +4 -1
  48. package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
  49. package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
  50. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  51. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  52. package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
  53. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  54. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  55. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  56. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  57. package/dist/resources/extensions/gsd/prompts/run-uat.md +48 -24
  58. package/dist/resources/extensions/gsd/prompts/system.md +3 -1
  59. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  60. package/dist/resources/extensions/gsd/rule-registry.js +428 -52
  61. package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
  62. package/dist/resources/extensions/gsd/skill-activation.js +20 -3
  63. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
  64. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
  65. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
  66. package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
  67. package/dist/resources/extensions/gsd/state.js +17 -14
  68. package/dist/resources/extensions/gsd/templates/plan.md +3 -1
  69. package/dist/resources/extensions/gsd/tool-presentation-plan.js +120 -0
  70. package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
  71. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
  72. package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
  73. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
  74. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  75. package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
  76. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +403 -3
  77. package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
  78. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  79. package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
  80. package/dist/resources/extensions/gsd/verification-gate.js +72 -1
  81. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
  82. package/dist/resources/extensions/gsd/workflow-mcp.js +5 -1
  83. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
  84. package/dist/resources/extensions/mcp-client/manager.js +31 -1
  85. package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
  86. package/dist/rtk.d.ts +7 -1
  87. package/dist/rtk.js +27 -11
  88. package/dist/update-check.d.ts +15 -1
  89. package/dist/update-check.js +87 -12
  90. package/dist/update-cmd.d.ts +1 -0
  91. package/dist/update-cmd.js +53 -2
  92. package/dist/web/standalone/.next/BUILD_ID +1 -1
  93. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  94. package/dist/web/standalone/.next/build-manifest.json +2 -2
  95. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  96. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/index.html +1 -1
  114. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  121. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  122. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  124. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  125. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  126. package/package.json +5 -3
  127. package/packages/cloud-mcp-gateway/package.json +2 -2
  128. package/packages/contracts/dist/workflow.d.ts +14 -0
  129. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  130. package/packages/contracts/dist/workflow.js +16 -0
  131. package/packages/contracts/dist/workflow.js.map +1 -1
  132. package/packages/contracts/package.json +1 -1
  133. package/packages/daemon/package.json +4 -4
  134. package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
  135. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  136. package/packages/gsd-agent-core/dist/agent-session.js +32 -0
  137. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  138. package/packages/gsd-agent-core/dist/index.d.ts +1 -0
  139. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  140. package/packages/gsd-agent-core/dist/index.js +1 -0
  141. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  142. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
  143. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
  144. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
  145. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
  146. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
  147. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  148. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  149. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  150. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
  151. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  152. package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
  153. package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
  154. package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
  155. package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
  156. package/packages/gsd-agent-core/package.json +6 -6
  157. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
  158. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
  159. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
  160. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
  161. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  162. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  163. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  164. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  165. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  167. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
  168. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  169. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
  171. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  172. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
  173. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
  176. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
  177. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  178. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
  179. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  180. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  186. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  188. package/packages/gsd-agent-modes/package.json +7 -7
  189. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  190. package/packages/mcp-server/dist/remote-questions.js +23 -9
  191. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  192. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  193. package/packages/mcp-server/dist/workflow-tools.js +84 -2
  194. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  195. package/packages/mcp-server/package.json +3 -3
  196. package/packages/native/package.json +1 -1
  197. package/packages/pi-agent-core/dist/agent-loop.js +38 -0
  198. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  199. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  200. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  201. package/packages/pi-agent-core/dist/agent.js +2 -0
  202. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  203. package/packages/pi-agent-core/dist/types.d.ts +3 -0
  204. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  205. package/packages/pi-agent-core/dist/types.js.map +1 -1
  206. package/packages/pi-agent-core/package.json +1 -1
  207. package/packages/pi-ai/dist/api-registry.d.ts +2 -0
  208. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  209. package/packages/pi-ai/dist/api-registry.js +23 -0
  210. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  211. package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
  212. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  213. package/packages/pi-ai/dist/image-models.generated.js +15 -0
  214. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  215. package/packages/pi-ai/dist/models.generated.d.ts +406 -17
  216. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  217. package/packages/pi-ai/dist/models.generated.js +484 -116
  218. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  219. package/packages/pi-ai/dist/stream.js +6 -6
  220. package/packages/pi-ai/dist/stream.js.map +1 -1
  221. package/packages/pi-ai/package.json +1 -1
  222. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  224. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  226. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  227. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  228. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  229. package/packages/pi-coding-agent/package.json +7 -7
  230. package/packages/pi-tui/dist/terminal.d.ts +1 -0
  231. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  232. package/packages/pi-tui/dist/terminal.js +8 -4
  233. package/packages/pi-tui/dist/terminal.js.map +1 -1
  234. package/packages/pi-tui/package.json +1 -1
  235. package/packages/rpc-client/package.json +2 -2
  236. package/pkg/package.json +1 -1
  237. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
  238. package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
  239. package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
  240. package/src/resources/extensions/browser-tools/index.ts +60 -9
  241. package/src/resources/extensions/browser-tools/package.json +5 -1
  242. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
  243. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
  244. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
  245. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
  246. package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
  247. package/src/resources/extensions/gsd/auto/phases.ts +5 -3
  248. package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
  249. package/src/resources/extensions/gsd/auto-dispatch.ts +53 -0
  250. package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
  251. package/src/resources/extensions/gsd/auto-prompts.ts +102 -15
  252. package/src/resources/extensions/gsd/auto-recovery.ts +4 -4
  253. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  254. package/src/resources/extensions/gsd/auto-start.ts +112 -17
  255. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  256. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +2 -1
  257. package/src/resources/extensions/gsd/auto.ts +47 -5
  258. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +90 -4
  259. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
  260. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +60 -19
  261. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +21 -10
  262. package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
  263. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  264. package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
  265. package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
  266. package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
  267. package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
  268. package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
  269. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
  270. package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
  271. package/src/resources/extensions/gsd/config-overlay.ts +3 -1
  272. package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
  273. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  274. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
  275. package/src/resources/extensions/gsd/error-classifier.ts +2 -1
  276. package/src/resources/extensions/gsd/escalation.ts +4 -4
  277. package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
  278. package/src/resources/extensions/gsd/forensics.ts +99 -5
  279. package/src/resources/extensions/gsd/gsd-db.ts +46 -8
  280. package/src/resources/extensions/gsd/guided-flow.ts +91 -83
  281. package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
  282. package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
  283. package/src/resources/extensions/gsd/memory-store.ts +4 -1
  284. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  285. package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
  286. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  287. package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
  288. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  289. package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
  290. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  291. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  292. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  293. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  294. package/src/resources/extensions/gsd/prompts/run-uat.md +48 -24
  295. package/src/resources/extensions/gsd/prompts/system.md +3 -1
  296. package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  297. package/src/resources/extensions/gsd/rule-registry.ts +558 -58
  298. package/src/resources/extensions/gsd/rule-types.ts +2 -0
  299. package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
  300. package/src/resources/extensions/gsd/skill-activation.ts +20 -2
  301. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
  302. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
  303. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
  304. package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
  305. package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
  306. package/src/resources/extensions/gsd/state.ts +18 -14
  307. package/src/resources/extensions/gsd/templates/plan.md +3 -1
  308. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
  309. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
  310. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
  311. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
  312. package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
  313. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
  314. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
  315. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
  316. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  317. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
  318. package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
  319. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
  320. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
  321. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
  322. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
  323. package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
  324. package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
  325. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
  326. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
  327. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
  328. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
  329. package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
  330. package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
  331. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
  332. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
  333. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
  334. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
  335. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
  336. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +66 -10
  337. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
  338. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
  339. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
  340. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
  341. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
  342. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
  343. package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
  344. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
  345. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
  346. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
  347. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
  348. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
  349. package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
  350. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +53 -1
  351. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
  352. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
  353. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
  354. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
  355. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +35 -0
  356. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
  357. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
  358. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
  359. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
  360. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
  361. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  362. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
  363. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  364. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
  365. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
  366. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
  367. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
  368. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
  369. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
  370. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
  371. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
  372. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
  373. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +213 -0
  374. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +25 -0
  375. package/src/resources/extensions/gsd/tool-presentation-plan.ts +167 -0
  376. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
  377. package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
  378. package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
  379. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
  380. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  381. package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
  382. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +489 -3
  383. package/src/resources/extensions/gsd/types.ts +69 -5
  384. package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
  385. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  386. package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
  387. package/src/resources/extensions/gsd/verification-gate.ts +87 -1
  388. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
  389. package/src/resources/extensions/gsd/workflow-mcp.ts +5 -1
  390. package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
  391. package/src/resources/extensions/mcp-client/manager.ts +33 -1
  392. package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
  393. package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
  394. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_buildManifest.js +0 -0
  395. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_ssgManifest.js +0 -0
@@ -2,6 +2,7 @@ import { execSync } from "node:child_process";
2
2
  import { existsSync, realpathSync } from "node:fs";
3
3
  import { dirname, resolve, sep } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
+ import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "./tool-presentation-plan.js";
5
6
  /** Session cwd may be a milestone worktree; MCP config and server discovery use the project root. */
6
7
  export function resolveWorkflowMcpProjectRoot(sessionCwd) {
7
8
  let resolved;
@@ -77,6 +78,8 @@ const MCP_WORKFLOW_TOOL_SURFACE = new Set([
77
78
  "gsd_task_complete",
78
79
  "gsd_task_reopen",
79
80
  "gsd_update_requirement",
81
+ "gsd_uat_exec",
82
+ "gsd_uat_result_save",
80
83
  "gsd_validate_milestone",
81
84
  ]);
82
85
  /** Workflow MCP tools are validated by transport compatibility, not pi tool-compat profiles. */
@@ -397,8 +400,9 @@ export function getRequiredWorkflowToolsForAutoUnit(unitType) {
397
400
  ];
398
401
  case "research-milestone":
399
402
  case "research-slice":
400
- case "run-uat":
401
403
  return ["gsd_summary_save"];
404
+ case "run-uat":
405
+ return [...RUN_UAT_WORKFLOW_TOOL_NAMES];
402
406
  case "plan-milestone":
403
407
  return ["gsd_plan_milestone"];
404
408
  case "plan-slice":
@@ -34,6 +34,8 @@ import { getCollapseCadence, getMilestoneResquash, resquashMilestoneOnMain, } fr
34
34
  import { loadEffectiveGSDPreferences, getIsolationMode } from "./preferences.js";
35
35
  import { invalidateAllCaches } from "./cache.js";
36
36
  import { resolveMilestoneFile } from "./paths.js";
37
+ import { getMilestone, insertMilestone, isDbAvailable, updateMilestoneStatus } from "./gsd-db.js";
38
+ import { isClosedStatus } from "./status-guards.js";
37
39
  import { createWorkspace, scopeMilestone } from "./workspace.js";
38
40
  // ADR-016 phase 2 / C1 (#5624): file-system + git-CLI leaf primitives
39
41
  // inlined as direct imports rather than injected through `WorktreeLifecycleDeps`.
@@ -55,6 +57,26 @@ const MERGE_FAILURE_DEDUPE_MS = 60_000;
55
57
  export function resetRecentWorktreeMergeFailuresForTest() {
56
58
  recentWorktreeMergeFailures.clear();
57
59
  }
60
+ function markMilestoneClosedAfterMerge(milestoneId, completedAt) {
61
+ if (!isDbAvailable())
62
+ return;
63
+ try {
64
+ const existing = getMilestone(milestoneId);
65
+ if (!existing) {
66
+ insertMilestone({ id: milestoneId, title: milestoneId, status: "complete" });
67
+ updateMilestoneStatus(milestoneId, "complete", completedAt);
68
+ invalidateAllCaches();
69
+ return;
70
+ }
71
+ if (!isClosedStatus(existing.status)) {
72
+ updateMilestoneStatus(milestoneId, "complete", completedAt);
73
+ invalidateAllCaches();
74
+ }
75
+ }
76
+ catch (err) {
77
+ logWarning("worktree", `Merged ${milestoneId} but failed to mark milestone complete in DB: ${err instanceof Error ? err.message : String(err)}`);
78
+ }
79
+ }
58
80
  /**
59
81
  * Internal sentinel — thrown by `_mergeBranchMode` when it has already
60
82
  * emitted a user-visible error. The outer `mergeAndExit` catches the type
@@ -1195,6 +1217,8 @@ export class WorktreeLifecycle {
1195
1217
  }
1196
1218
  // #4764 — record merge completion. Only reaches here when an actual
1197
1219
  // merge ran; failure paths throw out before this point.
1220
+ const mergeCompletedAt = new Date().toISOString();
1221
+ markMilestoneClosedAfterMerge(milestoneId, mergeCompletedAt);
1198
1222
  try {
1199
1223
  emitWorktreeMerged(this.s.originalBasePath || this.s.basePath, milestoneId, {
1200
1224
  reason: "milestone-complete",
@@ -29,6 +29,7 @@ const CHILD_ENV_ALLOWLIST = new Set([
29
29
  "XDG_CONFIG_HOME",
30
30
  "XDG_CACHE_HOME",
31
31
  ]);
32
+ const MCP_STDERR_MAX_BYTES = 4096;
32
33
  let cachedStatus = null;
33
34
  let cachedStatusKey = "";
34
35
  export function clearMcpConfigCache() {
@@ -126,6 +127,33 @@ export function resolveMcpEnv(env) {
126
127
  export function resolveMcpString(value) {
127
128
  return value.replace(/\$\{([^}]+)\}/g, (_match, varName) => process.env[varName] ?? "");
128
129
  }
130
+ function captureTransportStderr(transport) {
131
+ const chunks = [];
132
+ let totalBytes = 0;
133
+ const stderr = transport.stderr;
134
+ stderr?.on("data", (chunk) => {
135
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
136
+ totalBytes += buffer.byteLength;
137
+ chunks.push(buffer);
138
+ while (chunks.reduce((sum, entry) => sum + entry.byteLength, 0) > MCP_STDERR_MAX_BYTES) {
139
+ chunks.shift();
140
+ }
141
+ });
142
+ return () => {
143
+ const captured = Buffer.concat(chunks).toString("utf-8").trim();
144
+ if (!captured)
145
+ return "";
146
+ return totalBytes > MCP_STDERR_MAX_BYTES
147
+ ? `[stderr truncated to last ${MCP_STDERR_MAX_BYTES} bytes]\n${captured}`
148
+ : captured;
149
+ };
150
+ }
151
+ function formatConnectionError(error, stderr) {
152
+ const message = error instanceof Error ? error.message : String(error);
153
+ if (!stderr)
154
+ return message;
155
+ return `${message}\nStderr:\n${stderr}`;
156
+ }
129
157
  export function upsertProjectLocalMcpServer(input, options = {}) {
130
158
  const projectDir = options.projectDir ?? process.cwd();
131
159
  const nextName = input.name.trim();
@@ -224,6 +252,7 @@ export async function testMcpServerConnection(nameOrConfig, options = {}) {
224
252
  }
225
253
  const client = new Client({ name: "gsd", version: "1.0.0" });
226
254
  let transport;
255
+ let readCapturedStderr;
227
256
  const timeout = options.timeoutMs ?? 30_000;
228
257
  try {
229
258
  if (config.transport === "stdio") {
@@ -234,6 +263,7 @@ export async function testMcpServerConnection(nameOrConfig, options = {}) {
234
263
  cwd: config.cwd,
235
264
  stderr: "pipe",
236
265
  });
266
+ readCapturedStderr = captureTransportStderr(transport);
237
267
  }
238
268
  else {
239
269
  const resolvedUrl = resolveMcpString(config.url ?? "");
@@ -259,7 +289,7 @@ export async function testMcpServerConnection(nameOrConfig, options = {}) {
259
289
  toolCount: 0,
260
290
  tools: [],
261
291
  warnings: config.envWarnings,
262
- error: error instanceof Error ? error.message : String(error),
292
+ error: formatConnectionError(error, readCapturedStderr?.() ?? ""),
263
293
  };
264
294
  }
265
295
  finally {
@@ -0,0 +1,145 @@
1
+ import { createHash } from "node:crypto";
2
+ import { execFileSync } from "node:child_process";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { createRequire } from "node:module";
5
+ import { basename, resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ export const GSD_BROWSER_MCP_SERVER_NAME = "gsd-browser";
8
+ function parseJsonEnv(env, name) {
9
+ const raw = env[name];
10
+ if (!raw)
11
+ return undefined;
12
+ try {
13
+ return JSON.parse(raw);
14
+ }
15
+ catch {
16
+ throw new Error(`Invalid JSON in ${name}`);
17
+ }
18
+ }
19
+ function sanitizeSessionSegment(value) {
20
+ return value
21
+ .replace(/[^a-zA-Z0-9._-]+/g, "-")
22
+ .replace(/^-+|-+$/g, "")
23
+ .slice(0, 40);
24
+ }
25
+ function compareSemverLocal(a, b) {
26
+ const left = a.split(".").map(Number);
27
+ const right = b.split(".").map(Number);
28
+ for (let index = 0; index < Math.max(left.length, right.length); index++) {
29
+ const leftValue = left[index] || 0;
30
+ const rightValue = right[index] || 0;
31
+ if (leftValue > rightValue)
32
+ return 1;
33
+ if (leftValue < rightValue)
34
+ return -1;
35
+ }
36
+ return 0;
37
+ }
38
+ function parseGsdBrowserVersion(output) {
39
+ return output.match(/\b(\d+\.\d+\.\d+)\b/)?.[1] ?? null;
40
+ }
41
+ function resolveBundledGsdBrowserPackageVersion() {
42
+ try {
43
+ const requireFromHere = createRequire(import.meta.url);
44
+ const packageJsonPath = requireFromHere.resolve("@opengsd/gsd-browser/package.json");
45
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
46
+ return typeof pkg.version === "string" ? parseGsdBrowserVersion(pkg.version) : null;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ function resolvePathGsdBrowserVersion(env) {
53
+ const explicit = env.GSD_BROWSER_PATH_VERSION?.trim();
54
+ if (explicit)
55
+ return parseGsdBrowserVersion(explicit);
56
+ try {
57
+ return parseGsdBrowserVersion(execFileSync("gsd-browser", ["--version"], {
58
+ encoding: "utf-8",
59
+ env,
60
+ stdio: ["ignore", "pipe", "ignore"],
61
+ timeout: 2000,
62
+ }));
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ function shouldPreferPathGsdBrowser(env) {
69
+ const pathVersion = resolvePathGsdBrowserVersion(env);
70
+ if (!pathVersion)
71
+ return false;
72
+ const bundledVersion = resolveBundledGsdBrowserPackageVersion();
73
+ return !bundledVersion || compareSemverLocal(pathVersion, bundledVersion) > 0;
74
+ }
75
+ export function resolveBundledGsdBrowserCliPath(env = process.env) {
76
+ const explicit = env.GSD_BROWSER_CLI_PATH?.trim() || env.GSD_BROWSER_BIN_PATH?.trim();
77
+ if (explicit)
78
+ return explicit;
79
+ try {
80
+ const requireFromHere = createRequire(import.meta.url);
81
+ const packageJsonPath = requireFromHere.resolve("@opengsd/gsd-browser/package.json");
82
+ const candidate = resolve(packageJsonPath, "..", "bin", "gsd-browser");
83
+ if (existsSync(candidate))
84
+ return candidate;
85
+ }
86
+ catch {
87
+ // Fall through to path candidates for source/dist layouts.
88
+ }
89
+ const candidates = [
90
+ resolve(fileURLToPath(new URL("../../../../node_modules/@opengsd/gsd-browser/bin/gsd-browser", import.meta.url))),
91
+ resolve(fileURLToPath(new URL("../../../../node_modules/.bin/gsd-browser", import.meta.url))),
92
+ ];
93
+ for (const candidate of candidates) {
94
+ if (existsSync(candidate))
95
+ return candidate;
96
+ }
97
+ return null;
98
+ }
99
+ export function buildGsdBrowserSessionName(projectRoot, suffix) {
100
+ const resolvedProjectRoot = resolve(projectRoot);
101
+ const base = sanitizeSessionSegment(basename(resolvedProjectRoot)) || "project";
102
+ const hash = createHash("sha1").update(resolvedProjectRoot).digest("hex").slice(0, 8);
103
+ const cleanSuffix = suffix ? sanitizeSessionSegment(suffix) : "";
104
+ return cleanSuffix ? `gsd-${base}-${hash}-${cleanSuffix}` : `gsd-${base}-${hash}`;
105
+ }
106
+ export function resolveGsdBrowserMcpLaunchConfig(projectRoot, env = process.env, options = {}) {
107
+ const resolvedProjectRoot = resolve(projectRoot);
108
+ const serverName = env.GSD_BROWSER_MCP_NAME?.trim() || GSD_BROWSER_MCP_SERVER_NAME;
109
+ const explicitArgs = parseJsonEnv(env, "GSD_BROWSER_MCP_ARGS");
110
+ const explicitEnv = parseJsonEnv(env, "GSD_BROWSER_MCP_ENV");
111
+ const explicitCommand = env.GSD_BROWSER_MCP_COMMAND?.trim();
112
+ const explicitCliPath = env.GSD_BROWSER_CLI_PATH?.trim() || env.GSD_BROWSER_BIN_PATH?.trim();
113
+ const preferPathCli = !explicitCommand && !explicitCliPath && shouldPreferPathGsdBrowser(env);
114
+ const bundledCliPath = !explicitCommand && !explicitCliPath && !preferPathCli
115
+ ? resolveBundledGsdBrowserCliPath(env)
116
+ : null;
117
+ const sessionName = options.sessionName?.trim() || buildGsdBrowserSessionName(resolvedProjectRoot, options.sessionSuffix);
118
+ const command = explicitCommand
119
+ || explicitCliPath
120
+ || (preferPathCli ? "gsd-browser" : undefined)
121
+ || (bundledCliPath ? process.execPath : undefined)
122
+ || "gsd-browser";
123
+ const args = Array.isArray(explicitArgs) && explicitArgs.length > 0
124
+ ? explicitArgs.map(String)
125
+ : [
126
+ ...(bundledCliPath ? [bundledCliPath] : []),
127
+ "mcp",
128
+ "--session",
129
+ sessionName,
130
+ "--identity-scope",
131
+ "project",
132
+ "--identity-project",
133
+ resolvedProjectRoot,
134
+ ];
135
+ const cwd = env.GSD_BROWSER_MCP_CWD?.trim() || resolvedProjectRoot;
136
+ return {
137
+ serverName,
138
+ command,
139
+ args,
140
+ cwd,
141
+ ...(explicitEnv ? { env: explicitEnv } : {}),
142
+ projectRoot: resolvedProjectRoot,
143
+ sessionName,
144
+ };
145
+ }
package/dist/rtk.d.ts CHANGED
@@ -40,6 +40,12 @@ export interface ValidateRtkBinaryOptions {
40
40
  spawnSyncImpl?: typeof spawnSync;
41
41
  env?: NodeJS.ProcessEnv;
42
42
  }
43
- export declare function validateRtkBinary(binaryPath: string, options?: ValidateRtkBinaryOptions): boolean;
43
+ export type ValidateRtkBinaryResult = {
44
+ valid: true;
45
+ } | {
46
+ valid: false;
47
+ error: string;
48
+ };
49
+ export declare function validateRtkBinary(binaryPath: string, options?: ValidateRtkBinaryOptions): ValidateRtkBinaryResult;
44
50
  export declare function ensureRtkAvailable(options?: EnsureRtkOptions): Promise<EnsureRtkResult>;
45
51
  export declare function bootstrapRtk(options?: EnsureRtkOptions): Promise<EnsureRtkResult>;
package/dist/rtk.js CHANGED
@@ -162,19 +162,28 @@ export function rewriteCommandWithRtk(command, options = {}) {
162
162
  const rewritten = (result.stdout ?? "").trimEnd();
163
163
  return rewritten || command;
164
164
  }
165
+ function trimSpawnOutput(output) {
166
+ return output?.toString().trim() ?? "";
167
+ }
165
168
  export function validateRtkBinary(binaryPath, options = {}) {
166
169
  const run = options.spawnSyncImpl ?? spawnSync;
167
170
  const result = run(binaryPath, ["rewrite", "git status"], {
168
171
  encoding: "utf-8",
169
172
  env: buildRtkEnv(options.env ?? process.env),
170
- stdio: ["ignore", "pipe", "ignore"],
173
+ stdio: ["ignore", "pipe", "pipe"],
171
174
  timeout: RTK_REWRITE_TIMEOUT_MS,
172
175
  });
173
176
  if (result.error)
174
- return false;
175
- if (result.status !== 0)
176
- return false;
177
- return (result.stdout ?? "").trim() === "rtk git status";
177
+ return { valid: false, error: result.error.message };
178
+ if (result.status !== 0) {
179
+ const stderr = trimSpawnOutput(result.stderr);
180
+ return { valid: false, error: stderr || `exit code ${result.status ?? "unknown"}` };
181
+ }
182
+ const stdout = trimSpawnOutput(result.stdout);
183
+ if (stdout !== "rtk git status") {
184
+ return { valid: false, error: stdout ? `unexpected output: ${stdout}` : "unexpected empty output" };
185
+ }
186
+ return { valid: true };
178
187
  }
179
188
  export async function ensureRtkAvailable(options = {}) {
180
189
  const env = options.env ?? process.env;
@@ -190,12 +199,18 @@ export async function ensureRtkAvailable(options = {}) {
190
199
  }
191
200
  const targetDir = options.targetDir ?? getManagedRtkDir(env);
192
201
  const managedPath = getManagedRtkPath(process.platform, targetDir);
193
- if (existsSync(managedPath) && validateRtkBinary(managedPath, { env })) {
194
- return { enabled: true, supported: true, available: true, source: "managed", binaryPath: managedPath };
202
+ if (existsSync(managedPath)) {
203
+ const managedValidation = validateRtkBinary(managedPath, { env });
204
+ if (managedValidation.valid) {
205
+ return { enabled: true, supported: true, available: true, source: "managed", binaryPath: managedPath };
206
+ }
195
207
  }
196
208
  const systemPath = resolveSystemRtkPath(options.pathValue ?? getPathValue(env));
197
- if (systemPath && validateRtkBinary(systemPath, { env })) {
198
- return { enabled: true, supported: true, available: true, source: "system", binaryPath: systemPath };
209
+ if (systemPath) {
210
+ const systemValidation = validateRtkBinary(systemPath, { env });
211
+ if (systemValidation.valid) {
212
+ return { enabled: true, supported: true, available: true, source: "system", binaryPath: systemPath };
213
+ }
199
214
  }
200
215
  const version = options.releaseVersion ?? RTK_VERSION;
201
216
  const assetName = resolveRtkAssetName(process.platform, osArch(), version);
@@ -241,9 +256,10 @@ export async function ensureRtkAvailable(options = {}) {
241
256
  if (process.platform !== "win32") {
242
257
  chmodSync(managedPath, 0o755);
243
258
  }
244
- if (!validateRtkBinary(managedPath, { env })) {
259
+ const downloadedValidation = validateRtkBinary(managedPath, { env });
260
+ if (!downloadedValidation.valid) {
245
261
  rmSync(managedPath, { force: true });
246
- throw new Error("downloaded RTK binary failed validation");
262
+ throw new Error(`downloaded RTK binary failed validation: ${downloadedValidation.error}`);
247
263
  }
248
264
  options.log?.(`installed RTK ${version} to ${managedPath}`);
249
265
  return { enabled: true, supported: true, available: true, source: "downloaded", binaryPath: managedPath };
@@ -1,5 +1,9 @@
1
1
  import { isPnpmInstall } from './resources/shared/package-manager-detection.js';
2
2
  export { isPnpmInstall };
3
+ export declare const GSD_PI_PACKAGE_NAME = "@opengsd/gsd-pi";
4
+ export declare const GSD_BROWSER_PACKAGE_NAME = "@opengsd/gsd-browser";
5
+ export declare const DEFAULT_REGISTRY_URL = "https://registry.npmjs.org/@opengsd%2fgsd-pi/latest";
6
+ export declare const GSD_BROWSER_REGISTRY_URL = "https://registry.npmjs.org/@opengsd%2fgsd-browser/latest";
3
7
  interface UpdateCheckCache {
4
8
  lastCheck: number;
5
9
  latestVersion: string;
@@ -13,6 +17,14 @@ export declare function readUpdateCache(cachePath?: string, packageName?: string
13
17
  export declare function writeUpdateCache(cache: Omit<UpdateCheckCache, 'packageName'> & {
14
18
  packageName?: string;
15
19
  }, cachePath?: string, packageName?: string): void;
20
+ export declare function resolveInstalledPackageVersion(packageName: string): string | null;
21
+ /**
22
+ * Resolves the gsd-browser version from PATH (via `gsd-browser --version`).
23
+ * Respects GSD_BROWSER_PATH_VERSION env override for testing.
24
+ * Returns null if gsd-browser is not on PATH or times out.
25
+ */
26
+ export declare function resolveGsdBrowserPathVersion(env?: NodeJS.ProcessEnv): string | null;
27
+ export declare function pickHigherVersion(a: string | null, b: string | null): string | null;
16
28
  export declare function fetchLatestVersionFromRegistry(registryUrl?: string, fetchTimeoutMs?: number): Promise<string | null>;
17
29
  /**
18
30
  * Detects whether the currently-running gsd binary was installed via `bun add -g`.
@@ -29,18 +41,20 @@ export declare function resolveInstallCommand(pkg: string, options?: {
29
41
  env?: NodeJS.ProcessEnv;
30
42
  }): string;
31
43
  export interface UpdateCheckOptions {
44
+ packageName?: string;
32
45
  currentVersion?: string;
33
46
  cachePath?: string;
34
47
  registryUrl?: string;
35
48
  checkIntervalMs?: number;
36
49
  fetchTimeoutMs?: number;
37
- onUpdate?: (current: string, latest: string) => void;
50
+ onUpdate?: (current: string, latest: string, packageName: string) => void;
38
51
  }
39
52
  /**
40
53
  * Non-blocking update check. Queries npm registry at most once per 24h,
41
54
  * caches the result, and prints a banner if a newer version is available.
42
55
  */
43
56
  export declare function checkForUpdates(options?: UpdateCheckOptions): Promise<void>;
57
+ export declare function checkForGsdBrowserUpdates(options?: UpdateCheckOptions): Promise<void>;
44
58
  /**
45
59
  * Interactive update prompt shown at startup when a newer version is available.
46
60
  * Fetches the latest version (with cache), then asks the user whether to
@@ -1,16 +1,21 @@
1
1
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
2
- import { execSync } from 'node:child_process';
2
+ import { execSync, execFileSync } from 'node:child_process';
3
3
  import { dirname, join, resolve as resolvePath, sep } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
+ import { createRequire } from 'node:module';
5
6
  import chalk from 'chalk';
6
7
  import { appRoot } from './app-paths.js';
7
8
  import { isPnpmInstall } from './resources/shared/package-manager-detection.js';
8
9
  export { isPnpmInstall };
10
+ export const GSD_PI_PACKAGE_NAME = '@opengsd/gsd-pi';
11
+ export const GSD_BROWSER_PACKAGE_NAME = '@opengsd/gsd-browser';
9
12
  const CACHE_FILE = join(appRoot, '.update-check');
10
- const NPM_PACKAGE_NAME = '@opengsd/gsd-pi';
13
+ const GSD_BROWSER_CACHE_FILE = join(appRoot, '.update-check-gsd-browser');
14
+ const NPM_PACKAGE_NAME = GSD_PI_PACKAGE_NAME;
11
15
  const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
12
16
  const FETCH_TIMEOUT_MS = 5000;
13
- const DEFAULT_REGISTRY_URL = `https://registry.npmjs.org/@opengsd%2fgsd-pi/latest`;
17
+ export const DEFAULT_REGISTRY_URL = `https://registry.npmjs.org/@opengsd%2fgsd-pi/latest`;
18
+ export const GSD_BROWSER_REGISTRY_URL = `https://registry.npmjs.org/@opengsd%2fgsd-browser/latest`;
14
19
  /**
15
20
  * Compares two semver strings. Returns 1 if a > b, -1 if a < b, 0 if equal.
16
21
  */
@@ -55,6 +60,46 @@ function normalizeLatestVersion(version) {
55
60
  const trimmed = version.trim().replace(/^v/, '');
56
61
  return trimmed.length > 0 ? trimmed : null;
57
62
  }
63
+ export function resolveInstalledPackageVersion(packageName) {
64
+ try {
65
+ const requireFromHere = createRequire(import.meta.url);
66
+ const packageJsonPath = requireFromHere.resolve(`${packageName}/package.json`);
67
+ const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
68
+ return normalizeLatestVersion(pkg.version);
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ /**
75
+ * Resolves the gsd-browser version from PATH (via `gsd-browser --version`).
76
+ * Respects GSD_BROWSER_PATH_VERSION env override for testing.
77
+ * Returns null if gsd-browser is not on PATH or times out.
78
+ */
79
+ export function resolveGsdBrowserPathVersion(env = process.env) {
80
+ const explicit = env.GSD_BROWSER_PATH_VERSION?.trim();
81
+ if (explicit)
82
+ return explicit.match(/\b(\d+\.\d+\.\d+)\b/)?.[1] ?? null;
83
+ try {
84
+ const out = execFileSync('gsd-browser', ['--version'], {
85
+ encoding: 'utf-8',
86
+ env,
87
+ stdio: ['ignore', 'pipe', 'ignore'],
88
+ timeout: 2000,
89
+ });
90
+ return out.match(/\b(\d+\.\d+\.\d+)\b/)?.[1] ?? null;
91
+ }
92
+ catch {
93
+ return null;
94
+ }
95
+ }
96
+ export function pickHigherVersion(a, b) {
97
+ if (!a)
98
+ return b;
99
+ if (!b)
100
+ return a;
101
+ return compareSemver(a, b) >= 0 ? a : b;
102
+ }
58
103
  export async function fetchLatestVersionFromRegistry(registryUrl = DEFAULT_REGISTRY_URL, fetchTimeoutMs = FETCH_TIMEOUT_MS) {
59
104
  const controller = new AbortController();
60
105
  const timeout = setTimeout(() => controller.abort(), fetchTimeoutMs);
@@ -100,27 +145,51 @@ export function resolveInstallCommand(pkg, options = {}) {
100
145
  return `pnpm add -g ${pkg}`;
101
146
  return `npm install -g ${pkg}`;
102
147
  }
103
- function printUpdateBanner(current, latest) {
104
- const installCmd = resolveInstallCommand('@opengsd/gsd-pi@latest');
148
+ function printUpdateBanner(current, latest, packageName = GSD_PI_PACKAGE_NAME) {
149
+ if (packageName === GSD_BROWSER_PACKAGE_NAME) {
150
+ process.stderr.write(` ${chalk.yellow('gsd-browser update available:')} ${chalk.dim(`v${current}`)} → ${chalk.bold(`v${latest}`)}\n` +
151
+ ` ${chalk.dim('Run')} gsd update browser ${chalk.dim('to upgrade browser automation')}\n\n`);
152
+ return;
153
+ }
154
+ const installCmd = resolveInstallCommand(`${GSD_PI_PACKAGE_NAME}@latest`);
105
155
  process.stderr.write(` ${chalk.yellow('Update available:')} ${chalk.dim(`v${current}`)} → ${chalk.bold(`v${latest}`)}\n` +
106
156
  ` ${chalk.dim('Run')} ${installCmd} ${chalk.dim('or')} /gsd upgrade ${chalk.dim('to upgrade')}\n\n`);
107
157
  }
158
+ function defaultCurrentVersion(packageName) {
159
+ if (packageName === GSD_PI_PACKAGE_NAME) {
160
+ return process.env.GSD_VERSION || '0.0.0';
161
+ }
162
+ const bundled = resolveInstalledPackageVersion(packageName);
163
+ if (packageName === GSD_BROWSER_PACKAGE_NAME) {
164
+ return pickHigherVersion(bundled, resolveGsdBrowserPathVersion());
165
+ }
166
+ return bundled;
167
+ }
168
+ function defaultCachePath(packageName) {
169
+ return packageName === GSD_BROWSER_PACKAGE_NAME ? GSD_BROWSER_CACHE_FILE : CACHE_FILE;
170
+ }
171
+ function defaultRegistryUrl(packageName) {
172
+ return packageName === GSD_BROWSER_PACKAGE_NAME ? GSD_BROWSER_REGISTRY_URL : DEFAULT_REGISTRY_URL;
173
+ }
108
174
  /**
109
175
  * Non-blocking update check. Queries npm registry at most once per 24h,
110
176
  * caches the result, and prints a banner if a newer version is available.
111
177
  */
112
178
  export async function checkForUpdates(options = {}) {
113
- const currentVersion = options.currentVersion || process.env.GSD_VERSION || '0.0.0';
114
- const cachePath = options.cachePath || CACHE_FILE;
115
- const registryUrl = options.registryUrl || DEFAULT_REGISTRY_URL;
179
+ const packageName = options.packageName || GSD_PI_PACKAGE_NAME;
180
+ const currentVersion = options.currentVersion || defaultCurrentVersion(packageName);
181
+ if (!currentVersion)
182
+ return;
183
+ const cachePath = options.cachePath || defaultCachePath(packageName);
184
+ const registryUrl = options.registryUrl || defaultRegistryUrl(packageName);
116
185
  const checkIntervalMs = options.checkIntervalMs ?? CHECK_INTERVAL_MS;
117
186
  const fetchTimeoutMs = options.fetchTimeoutMs ?? FETCH_TIMEOUT_MS;
118
187
  const onUpdate = options.onUpdate || printUpdateBanner;
119
188
  // Check cache — skip network if checked recently
120
- const cache = readUpdateCache(cachePath);
189
+ const cache = readUpdateCache(cachePath, packageName);
121
190
  if (cache && Date.now() - cache.lastCheck < checkIntervalMs) {
122
191
  if (compareSemver(cache.latestVersion, currentVersion) > 0) {
123
- onUpdate(currentVersion, cache.latestVersion);
192
+ onUpdate(currentVersion, cache.latestVersion, packageName);
124
193
  }
125
194
  return;
126
195
  }
@@ -128,15 +197,21 @@ export async function checkForUpdates(options = {}) {
128
197
  const latestVersion = await fetchLatestVersionFromRegistry(registryUrl, fetchTimeoutMs);
129
198
  if (!latestVersion)
130
199
  return;
131
- writeUpdateCache({ lastCheck: Date.now(), latestVersion }, cachePath);
200
+ writeUpdateCache({ lastCheck: Date.now(), latestVersion }, cachePath, packageName);
132
201
  if (compareSemver(latestVersion, currentVersion) > 0) {
133
- onUpdate(currentVersion, latestVersion);
202
+ onUpdate(currentVersion, latestVersion, packageName);
134
203
  }
135
204
  }
136
205
  catch {
137
206
  // Network error or timeout — silently ignore, don't block startup
138
207
  }
139
208
  }
209
+ export async function checkForGsdBrowserUpdates(options = {}) {
210
+ await checkForUpdates({
211
+ ...options,
212
+ packageName: GSD_BROWSER_PACKAGE_NAME,
213
+ });
214
+ }
140
215
  const PROMPT_TIMEOUT_MS = 30_000;
141
216
  /**
142
217
  * Interactive update prompt shown at startup when a newer version is available.
@@ -1,6 +1,7 @@
1
1
  interface RunUpdateOptions {
2
2
  agentDir?: string;
3
3
  skillsDir?: string;
4
+ target?: string;
4
5
  }
5
6
  export declare function runUpdate(options?: RunUpdateOptions): Promise<void>;
6
7
  export {};
@@ -1,9 +1,60 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import { agentDir as defaultAgentDir } from './app-paths.js';
3
3
  import { initResources } from './resource-loader.js';
4
- import { compareSemver, fetchLatestVersionFromRegistry, resolveInstallCommand } from './update-check.js';
5
- const NPM_PACKAGE = '@opengsd/gsd-pi';
4
+ import { compareSemver, fetchLatestVersionFromRegistry, GSD_BROWSER_PACKAGE_NAME, GSD_BROWSER_REGISTRY_URL, GSD_PI_PACKAGE_NAME, pickHigherVersion, resolveGsdBrowserPathVersion, resolveInstallCommand, resolveInstalledPackageVersion, } from './update-check.js';
5
+ const NPM_PACKAGE = GSD_PI_PACKAGE_NAME;
6
+ function formatCurrentVersion(version) {
7
+ return version ? `v${version}` : 'unknown';
8
+ }
9
+ async function runBrowserUpdate() {
10
+ const bundled = resolveInstalledPackageVersion(GSD_BROWSER_PACKAGE_NAME);
11
+ const current = pickHigherVersion(bundled, resolveGsdBrowserPathVersion());
12
+ const bold = '\x1b[1m';
13
+ const dim = '\x1b[2m';
14
+ const green = '\x1b[32m';
15
+ const yellow = '\x1b[33m';
16
+ const reset = '\x1b[0m';
17
+ process.stdout.write(`${dim}Current gsd-browser version:${reset} ${formatCurrentVersion(current)}\n`);
18
+ process.stdout.write(`${dim}Checking npm registry...${reset}\n`);
19
+ const latest = await fetchLatestVersionFromRegistry(GSD_BROWSER_REGISTRY_URL);
20
+ if (!latest) {
21
+ process.stderr.write(`${yellow}Failed to reach npm registry.${reset}\n`);
22
+ process.exit(1);
23
+ }
24
+ process.stdout.write(`${dim}Latest gsd-browser version:${reset} v${latest}\n`);
25
+ if (current && compareSemver(latest, current) <= 0) {
26
+ process.stdout.write(`${green}gsd-browser is already up to date.${reset}\n`);
27
+ return;
28
+ }
29
+ process.stdout.write(`${dim}Updating gsd-browser:${reset} ${formatCurrentVersion(current)} → ${bold}v${latest}${reset}\n`);
30
+ const installCmd = resolveInstallCommand(`${GSD_BROWSER_PACKAGE_NAME}@latest`);
31
+ try {
32
+ execSync(installCmd, {
33
+ stdio: 'inherit',
34
+ });
35
+ process.stdout.write(`\n${green}${bold}Updated gsd-browser to v${latest}${reset}\n`);
36
+ // Verify the new version is reachable via PATH (MCP prefers PATH binary when newer)
37
+ const newPathVersion = resolveGsdBrowserPathVersion();
38
+ if (!newPathVersion || compareSemver(newPathVersion, latest) < 0) {
39
+ process.stdout.write(`${yellow}Note:${reset} ${dim}Ensure the npm global bin directory is on your PATH` +
40
+ ` so MCP automation uses the updated binary.${reset}\n`);
41
+ }
42
+ }
43
+ catch {
44
+ process.stderr.write(`\n${yellow}gsd-browser update failed. Try manually: ${installCmd}${reset}\n`);
45
+ process.exit(1);
46
+ }
47
+ }
6
48
  export async function runUpdate(options = {}) {
49
+ if (options.target === 'browser' || options.target === 'gsd-browser') {
50
+ await runBrowserUpdate();
51
+ return;
52
+ }
53
+ if (options.target) {
54
+ process.stderr.write(`Unknown update target: ${options.target}\n`);
55
+ process.stderr.write('Usage: gsd update [browser]\n');
56
+ process.exit(1);
57
+ }
7
58
  const current = process.env.GSD_VERSION || '0.0.0';
8
59
  const bold = '\x1b[1m';
9
60
  const dim = '\x1b[2m';
@@ -1 +1 @@
1
- L9N5SPFi7f-Ne4u2uXzCe
1
+ jBtwT9v1u2lUA3UEOy_ZH