@opengsd/gsd-pi 1.4.0 → 1.5.0-dev.4fb2d460

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 (657) hide show
  1. package/README.md +11 -11
  2. package/dist/onboarding.js +11 -0
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/GSD-WORKFLOW.md +20 -25
  5. package/dist/resources/extensions/ask-user-questions.js +1 -1
  6. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +118 -53
  7. package/dist/resources/extensions/cursor-cli/index.js +16 -0
  8. package/dist/resources/extensions/cursor-cli/models.js +63 -0
  9. package/dist/resources/extensions/cursor-cli/package.json +11 -0
  10. package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
  11. package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
  12. package/dist/resources/extensions/gsd/activity-log.js +4 -1
  13. package/dist/resources/extensions/gsd/artifact-verification.js +25 -9
  14. package/dist/resources/extensions/gsd/auto/closeout.js +137 -42
  15. package/dist/resources/extensions/gsd/auto/finalize.js +9 -0
  16. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
  17. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +5 -2
  19. package/dist/resources/extensions/gsd/auto/schedule-wakeup.js +3 -0
  20. package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +12 -3
  22. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +31 -7
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
  25. package/dist/resources/extensions/gsd/auto-prompts.js +76 -2
  26. package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
  27. package/dist/resources/extensions/gsd/auto-start.js +8 -6
  28. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
  30. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
  31. package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
  32. package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
  33. package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
  34. package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
  35. package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
  36. package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
  37. package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
  38. package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
  39. package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
  40. package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
  41. package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
  42. package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
  43. package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
  44. package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
  45. package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
  46. package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
  47. package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
  48. package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
  49. package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
  50. package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
  51. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
  52. package/dist/resources/extensions/gsd/auto-worktree.js +20 -2046
  53. package/dist/resources/extensions/gsd/auto.js +31 -5
  54. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -0
  55. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
  56. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +134 -7
  57. package/dist/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.js +58 -9
  58. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  59. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +194 -28
  60. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +14 -1
  61. package/dist/resources/extensions/gsd/codebase-generator.js +164 -20
  62. package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
  63. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  64. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +153 -1
  65. package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
  66. package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
  67. package/dist/resources/extensions/gsd/db/queries.js +48 -9
  68. package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
  69. package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
  70. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -2
  71. package/dist/resources/extensions/gsd/doctor-engine-checks.js +292 -18
  72. package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
  73. package/dist/resources/extensions/gsd/doctor.js +93 -3
  74. package/dist/resources/extensions/gsd/exec-sandbox.js +6 -2
  75. package/dist/resources/extensions/gsd/flat-phase-migration.js +106 -26
  76. package/dist/resources/extensions/gsd/forensics.js +1 -1
  77. package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
  78. package/dist/resources/extensions/gsd/git-service.js +59 -18
  79. package/dist/resources/extensions/gsd/gsd-db.js +75 -11
  80. package/dist/resources/extensions/gsd/guidance.js +1 -0
  81. package/dist/resources/extensions/gsd/guided-flow.js +62 -19
  82. package/dist/resources/extensions/gsd/key-manager.js +1 -0
  83. package/dist/resources/extensions/gsd/markdown-renderer.js +40 -11
  84. package/dist/resources/extensions/gsd/md-importer.js +89 -23
  85. package/dist/resources/extensions/gsd/migrate-external.js +24 -7
  86. package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
  87. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +14 -3
  88. package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
  89. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  90. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
  91. package/dist/resources/extensions/gsd/paths.js +17 -3
  92. package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
  93. package/dist/resources/extensions/gsd/preferences-models.js +6 -4
  94. package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
  95. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  96. package/dist/resources/extensions/gsd/preferences-validation.js +107 -2
  97. package/dist/resources/extensions/gsd/preferences.js +49 -2
  98. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  99. package/dist/resources/extensions/gsd/prompts/system.md +6 -6
  100. package/dist/resources/extensions/gsd/quick.js +12 -3
  101. package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
  102. package/dist/resources/extensions/gsd/repo-identity.js +16 -0
  103. package/dist/resources/extensions/gsd/repository-registry.js +6 -1
  104. package/dist/resources/extensions/gsd/root-write-leak-guard.js +4 -2
  105. package/dist/resources/extensions/gsd/safe-fs.js +23 -2
  106. package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
  107. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  108. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
  109. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
  110. package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
  111. package/dist/resources/extensions/gsd/tool-contract.js +14 -0
  112. package/dist/resources/extensions/gsd/tools/plan-task.js +76 -8
  113. package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
  114. package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
  115. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
  116. package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
  117. package/dist/resources/extensions/gsd/unit-registry.js +37 -2
  118. package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
  119. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
  120. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
  121. package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
  122. package/dist/resources/extensions/gsd/workspace.js +26 -8
  123. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  124. package/dist/resources/extensions/gsd/worktree-lifecycle.js +81 -14
  125. package/dist/resources/extensions/gsd/worktree-manager.js +97 -4
  126. package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
  127. package/dist/resources/extensions/shared/interview-ui.js +62 -9
  128. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  129. package/dist/web/standalone/.next/BUILD_ID +1 -1
  130. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  131. package/dist/web/standalone/.next/build-manifest.json +3 -3
  132. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  133. package/dist/web/standalone/.next/required-server-files.json +3 -3
  134. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  135. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  145. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  147. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  149. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  151. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  161. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  173. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  195. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  205. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  211. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  227. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  231. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/app/index.html +1 -1
  241. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  242. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  243. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  244. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  245. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  246. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  247. package/dist/web/standalone/.next/server/app/page.js +2 -2
  248. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  249. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  250. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  251. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  252. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  253. package/dist/web/standalone/.next/server/middleware.js +3 -3
  254. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  255. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  256. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  257. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  259. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  260. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  261. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  262. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  263. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  264. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  265. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  266. package/dist/web/standalone/server.js +1 -1
  267. package/dist/wizard.d.ts +8 -0
  268. package/dist/wizard.js +8 -1
  269. package/integrations/hermes/CONTEXT.md +47 -0
  270. package/integrations/hermes/README.md +21 -0
  271. package/integrations/hermes/__init__.py +31 -0
  272. package/integrations/hermes/docs/issue-1162-grilling.md +197 -0
  273. package/integrations/hermes/docs/setup.md +4 -0
  274. package/integrations/hermes/open_gsd_hermes/commands.py +141 -0
  275. package/integrations/hermes/open_gsd_hermes/config.py +2 -0
  276. package/integrations/hermes/open_gsd_hermes/gsd_client.py +591 -39
  277. package/integrations/hermes/open_gsd_hermes/notifications.py +10 -1
  278. package/integrations/hermes/plugin.yaml +4 -0
  279. package/integrations/hermes/tests/test_config.py +6 -0
  280. package/integrations/hermes/tests/test_directory_loader.py +37 -0
  281. package/integrations/hermes/tests/test_gsd_client_cache.py +3 -0
  282. package/integrations/hermes/tests/test_gsd_client_execute.py +35 -0
  283. package/integrations/hermes/tests/test_gsd_client_process_cwd.py +22 -0
  284. package/integrations/hermes/tests/test_gsd_client_timeout.py +98 -0
  285. package/integrations/hermes/tests/test_milestone_client.py +447 -0
  286. package/integrations/hermes/tests/test_new_milestone_command.py +313 -0
  287. package/integrations/hermes/tests/test_supervisor_fsm.py +40 -0
  288. package/package.json +8 -8
  289. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
  290. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
  291. package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
  292. package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
  293. package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
  294. package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
  295. package/packages/cloud-mcp-gateway/package.json +2 -2
  296. package/packages/contracts/package.json +1 -1
  297. package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
  298. package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
  299. package/packages/daemon/dist/cloud-runtime.js +25 -1
  300. package/packages/daemon/dist/cloud-runtime.js.map +1 -1
  301. package/packages/daemon/dist/cloud-runtime.test.js +51 -0
  302. package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
  303. package/packages/daemon/dist/message-batcher.d.ts +7 -0
  304. package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
  305. package/packages/daemon/dist/message-batcher.js +13 -0
  306. package/packages/daemon/dist/message-batcher.js.map +1 -1
  307. package/packages/daemon/dist/message-batcher.test.js +48 -0
  308. package/packages/daemon/dist/message-batcher.test.js.map +1 -1
  309. package/packages/daemon/dist/session-manager.js +1 -1
  310. package/packages/daemon/dist/session-manager.js.map +1 -1
  311. package/packages/daemon/package.json +5 -5
  312. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
  313. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  314. package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
  315. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  316. package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
  317. package/packages/gsd-agent-core/dist/session/agent-session-navigation.d.ts.map +1 -1
  318. package/packages/gsd-agent-core/dist/session/agent-session-navigation.js +4 -1
  319. package/packages/gsd-agent-core/dist/session/agent-session-navigation.js.map +1 -1
  320. package/packages/gsd-agent-core/package.json +5 -5
  321. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  322. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
  323. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  324. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -1
  325. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +1 -0
  326. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -1
  327. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +1 -1
  328. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  329. package/packages/gsd-agent-modes/package.json +7 -7
  330. package/packages/mcp-server/dist/server.d.ts +18 -5
  331. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  332. package/packages/mcp-server/dist/server.js +46 -5
  333. package/packages/mcp-server/dist/server.js.map +1 -1
  334. package/packages/mcp-server/dist/session-manager.js +1 -1
  335. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  336. package/packages/mcp-server/package.json +4 -4
  337. package/packages/native/package.json +1 -1
  338. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  339. package/packages/pi-agent-core/dist/agent-loop.js +14 -9
  340. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  341. package/packages/pi-agent-core/package.json +1 -1
  342. package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  343. package/packages/pi-ai/dist/env-api-keys.js +3 -0
  344. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  345. package/packages/pi-ai/dist/index.d.ts +1 -0
  346. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  347. package/packages/pi-ai/dist/index.js +1 -0
  348. package/packages/pi-ai/dist/index.js.map +1 -1
  349. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  350. package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
  351. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  352. package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
  353. package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
  354. package/packages/pi-ai/dist/tool-result-content.js +62 -0
  355. package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
  356. package/packages/pi-ai/dist/types.d.ts +10 -22
  357. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  358. package/packages/pi-ai/dist/types.js.map +1 -1
  359. package/packages/pi-ai/package.json +1 -1
  360. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  361. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  362. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
  364. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
  366. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
  368. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
  370. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +1 -0
  372. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/session-manager.js +3 -0
  376. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
  378. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
  379. package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
  380. package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
  381. package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
  382. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  384. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  386. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/index.js +1 -0
  388. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  389. package/packages/pi-coding-agent/package.json +7 -7
  390. package/packages/pi-tui/package.json +2 -2
  391. package/packages/rpc-client/dist/rpc-client.js +1 -1
  392. package/packages/rpc-client/dist/rpc-client.js.map +1 -1
  393. package/packages/rpc-client/package.json +2 -2
  394. package/pkg/dist/core/export-html/template.js +53 -4
  395. package/pkg/package.json +1 -1
  396. package/scripts/link-workspace-packages.cjs +14 -4
  397. package/src/resources/GSD-WORKFLOW.md +20 -25
  398. package/src/resources/extensions/ask-user-questions.ts +1 -1
  399. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +130 -51
  400. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +371 -39
  401. package/src/resources/extensions/cursor-cli/index.ts +18 -0
  402. package/src/resources/extensions/cursor-cli/models.ts +65 -0
  403. package/src/resources/extensions/cursor-cli/package.json +11 -0
  404. package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
  405. package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
  406. package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
  407. package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
  408. package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
  409. package/src/resources/extensions/gsd/activity-log.ts +4 -1
  410. package/src/resources/extensions/gsd/artifact-verification.ts +25 -9
  411. package/src/resources/extensions/gsd/auto/closeout.ts +163 -58
  412. package/src/resources/extensions/gsd/auto/finalize.ts +8 -0
  413. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  414. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
  415. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
  416. package/src/resources/extensions/gsd/auto/run-unit.ts +5 -2
  417. package/src/resources/extensions/gsd/auto/schedule-wakeup.ts +8 -0
  418. package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
  419. package/src/resources/extensions/gsd/auto-artifact-paths.ts +12 -3
  420. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
  421. package/src/resources/extensions/gsd/auto-dispatch.ts +35 -7
  422. package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
  423. package/src/resources/extensions/gsd/auto-prompts.ts +73 -2
  424. package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
  425. package/src/resources/extensions/gsd/auto-start.ts +9 -6
  426. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +4 -0
  427. package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
  428. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
  429. package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
  430. package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
  431. package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
  432. package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
  433. package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
  434. package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
  435. package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
  436. package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
  437. package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
  438. package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
  439. package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
  440. package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
  441. package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
  442. package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
  443. package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
  444. package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
  445. package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
  446. package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
  447. package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
  448. package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
  449. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
  450. package/src/resources/extensions/gsd/auto-worktree.ts +69 -2390
  451. package/src/resources/extensions/gsd/auto.ts +32 -19
  452. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -0
  453. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
  454. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +148 -7
  455. package/src/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.ts +80 -12
  456. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  457. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +229 -28
  458. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +23 -1
  459. package/src/resources/extensions/gsd/codebase-generator.ts +186 -19
  460. package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
  461. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  462. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +135 -1
  463. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
  464. package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
  465. package/src/resources/extensions/gsd/db/queries.ts +49 -9
  466. package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
  467. package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
  468. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -2
  469. package/src/resources/extensions/gsd/doctor-engine-checks.ts +372 -22
  470. package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
  471. package/src/resources/extensions/gsd/doctor-types.ts +5 -1
  472. package/src/resources/extensions/gsd/doctor.ts +95 -3
  473. package/src/resources/extensions/gsd/exec-sandbox.ts +6 -2
  474. package/src/resources/extensions/gsd/flat-phase-migration.ts +132 -25
  475. package/src/resources/extensions/gsd/forensics.ts +1 -1
  476. package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
  477. package/src/resources/extensions/gsd/git-service.ts +67 -17
  478. package/src/resources/extensions/gsd/gsd-db.ts +105 -11
  479. package/src/resources/extensions/gsd/guidance.ts +2 -0
  480. package/src/resources/extensions/gsd/guided-flow.ts +71 -20
  481. package/src/resources/extensions/gsd/key-manager.ts +1 -0
  482. package/src/resources/extensions/gsd/markdown-renderer.ts +40 -10
  483. package/src/resources/extensions/gsd/md-importer.ts +93 -22
  484. package/src/resources/extensions/gsd/migrate-external.ts +23 -6
  485. package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
  486. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +19 -4
  487. package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
  488. package/src/resources/extensions/gsd/model-router.ts +4 -5
  489. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  490. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
  491. package/src/resources/extensions/gsd/paths.ts +21 -3
  492. package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
  493. package/src/resources/extensions/gsd/preferences-models.ts +6 -3
  494. package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
  495. package/src/resources/extensions/gsd/preferences-types.ts +30 -0
  496. package/src/resources/extensions/gsd/preferences-validation.ts +97 -2
  497. package/src/resources/extensions/gsd/preferences.ts +58 -4
  498. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  499. package/src/resources/extensions/gsd/prompts/system.md +6 -6
  500. package/src/resources/extensions/gsd/quick.ts +11 -3
  501. package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
  502. package/src/resources/extensions/gsd/repo-identity.ts +17 -0
  503. package/src/resources/extensions/gsd/repository-registry.ts +7 -1
  504. package/src/resources/extensions/gsd/root-write-leak-guard.ts +3 -2
  505. package/src/resources/extensions/gsd/safe-fs.ts +22 -2
  506. package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
  507. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  508. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
  509. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
  510. package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
  511. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
  512. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
  513. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -5
  514. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
  515. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
  516. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +43 -1
  517. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +111 -0
  518. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
  519. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
  520. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
  521. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
  522. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
  523. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
  524. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +10 -1
  525. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
  526. package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
  527. package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
  528. package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
  529. package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
  530. package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
  531. package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
  532. package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
  533. package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
  534. package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
  535. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
  536. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
  537. package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
  538. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
  539. package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
  540. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
  541. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +387 -0
  542. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
  543. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
  544. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
  545. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
  546. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +571 -5
  547. package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
  548. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
  549. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +109 -2
  550. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
  551. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
  552. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
  553. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
  554. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
  555. package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
  556. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
  557. package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
  558. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
  559. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
  560. package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
  561. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
  562. package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
  563. package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
  564. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
  565. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
  566. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  567. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
  568. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
  569. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
  570. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +4 -4
  572. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
  573. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
  574. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +116 -0
  575. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
  576. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +592 -23
  577. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +25 -1
  578. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
  579. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
  580. package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
  581. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
  582. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +50 -6
  583. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +17 -0
  584. package/src/resources/extensions/gsd/tests/plan-task.test.ts +264 -1
  585. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
  586. package/src/resources/extensions/gsd/tests/preferences.test.ts +169 -0
  587. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +147 -0
  588. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
  589. package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
  590. package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
  591. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +275 -0
  592. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
  593. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
  594. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
  595. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +31 -9
  596. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
  597. package/src/resources/extensions/gsd/tests/schedule-wakeup-tool.test.ts +167 -0
  598. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
  599. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
  600. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -0
  601. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
  602. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
  603. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -1
  604. package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
  605. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
  606. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
  607. package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
  608. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
  609. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
  610. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
  611. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
  612. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +259 -0
  613. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
  614. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
  615. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +81 -0
  616. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  617. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +52 -0
  618. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
  619. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +208 -1
  620. package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
  621. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
  622. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
  623. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
  624. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
  625. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
  626. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +4 -4
  627. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +2 -2
  628. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
  629. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
  630. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
  631. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +36 -3
  632. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
  633. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
  634. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
  635. package/src/resources/extensions/gsd/tool-contract.ts +29 -0
  636. package/src/resources/extensions/gsd/tools/plan-task.ts +107 -9
  637. package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
  638. package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
  639. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
  640. package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
  641. package/src/resources/extensions/gsd/unit-registry.ts +48 -2
  642. package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
  643. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
  644. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
  645. package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
  646. package/src/resources/extensions/gsd/workspace.ts +42 -8
  647. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  648. package/src/resources/extensions/gsd/worktree-lifecycle.ts +154 -26
  649. package/src/resources/extensions/gsd/worktree-manager.ts +143 -5
  650. package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
  651. package/src/resources/extensions/shared/interview-ui.ts +58 -11
  652. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
  653. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  656. /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_buildManifest.js +0 -0
  657. /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_ssgManifest.js +0 -0
@@ -0,0 +1,353 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createAssistantMessageEventStream } from "@gsd/pi-ai";
3
+ import { buildCursorAgentSpawnInvocation } from "./readiness.js";
4
+ const ZERO_USAGE = {
5
+ input: 0,
6
+ output: 0,
7
+ cacheRead: 0,
8
+ cacheWrite: 0,
9
+ totalTokens: 0,
10
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
11
+ };
12
+ function textBlocks(content) {
13
+ return content
14
+ .map((block) => block.type === "text" ? block.text : `[${block.type} omitted]`)
15
+ .join("\n");
16
+ }
17
+ function messageToText(message) {
18
+ if (message.role === "user") {
19
+ const content = typeof message.content === "string" ? message.content : textBlocks(message.content);
20
+ return `User:\n${content}`;
21
+ }
22
+ if (message.role === "assistant") {
23
+ const text = message.content
24
+ .map((block) => {
25
+ if (block.type === "text")
26
+ return block.text;
27
+ if (block.type === "thinking")
28
+ return "[thinking omitted]";
29
+ if (block.type === "toolCall")
30
+ return `[tool call: ${block.name}]`;
31
+ if (block.type === "serverToolUse")
32
+ return `[server tool: ${block.name}]`;
33
+ if (block.type === "webSearchResult")
34
+ return "[web search result omitted]";
35
+ return `[${block.type} omitted]`;
36
+ })
37
+ .join("\n");
38
+ return `Assistant:\n${text}`;
39
+ }
40
+ return `Tool result (${message.toolName}):\n${textBlocks(message.content)}`;
41
+ }
42
+ export function buildCursorPrompt(context) {
43
+ const parts = [];
44
+ if (context.systemPrompt?.trim())
45
+ parts.push(`System instructions:\n${context.systemPrompt.trim()}`);
46
+ if (context.messages.length > 0)
47
+ parts.push(context.messages.map(messageToText).join("\n\n"));
48
+ if (context.tools?.length) {
49
+ parts.push(`The external Cursor agent may execute its own tools. ` +
50
+ `GSD will not redispatch Cursor-owned internal tool events locally. ` +
51
+ `Requested GSD tools: ${context.tools.map((tool) => tool.name).join(", ")}`);
52
+ }
53
+ return parts.join("\n\n").trim();
54
+ }
55
+ export function buildCursorSpawnInvocation(command, args, platform = process.platform) {
56
+ return buildCursorAgentSpawnInvocation(command, args, platform);
57
+ }
58
+ export function buildCursorAgentRunPlan(modelId, prompt, cwd, platform = process.platform) {
59
+ return buildCursorSpawnInvocation(process.env.CURSOR_AGENT_BIN?.trim() || "cursor-agent", ["-p", prompt, "--output-format", "stream-json", "--model", modelId, "--workspace", cwd, "--trust"], platform);
60
+ }
61
+ function emitCompleteLines(chunk, pending, onLine) {
62
+ pending.value += chunk;
63
+ const lines = pending.value.split(/\r?\n/);
64
+ pending.value = lines.pop() ?? "";
65
+ for (const line of lines)
66
+ onLine(line);
67
+ }
68
+ function flushPendingLine(pending, onLine) {
69
+ if (!pending.value)
70
+ return;
71
+ onLine(pending.value);
72
+ pending.value = "";
73
+ }
74
+ function runCursorAgent(plan, options, onLine) {
75
+ return new Promise((resolve, reject) => {
76
+ const child = spawn(plan.command, plan.args, {
77
+ cwd: options?.cwd || process.cwd(),
78
+ env: process.env,
79
+ stdio: ["ignore", "pipe", "pipe"],
80
+ });
81
+ let stdout = "";
82
+ let stderr = "";
83
+ let settled = false;
84
+ const pendingStdout = { value: "" };
85
+ const settle = (fn) => {
86
+ if (settled)
87
+ return;
88
+ settled = true;
89
+ options?.signal?.removeEventListener("abort", onAbort);
90
+ fn();
91
+ };
92
+ const onAbort = () => {
93
+ child.kill("SIGTERM");
94
+ settle(() => reject(new Error("Request was aborted")));
95
+ };
96
+ if (options?.signal?.aborted) {
97
+ onAbort();
98
+ return;
99
+ }
100
+ options?.signal?.addEventListener("abort", onAbort);
101
+ child.stdout?.setEncoding("utf8");
102
+ child.stderr?.setEncoding("utf8");
103
+ child.stdout?.on("data", (chunk) => {
104
+ stdout += chunk;
105
+ try {
106
+ emitCompleteLines(chunk, pendingStdout, onLine);
107
+ }
108
+ catch (error) {
109
+ child.kill("SIGTERM");
110
+ settle(() => reject(error));
111
+ }
112
+ });
113
+ child.stderr?.on("data", (chunk) => { stderr += chunk; });
114
+ child.on("error", (error) => settle(() => reject(error)));
115
+ child.on("close", (code, signal) => settle(() => {
116
+ try {
117
+ flushPendingLine(pendingStdout, onLine);
118
+ }
119
+ catch (error) {
120
+ reject(error);
121
+ return;
122
+ }
123
+ resolve({ stdout, stderr, code, signal });
124
+ }));
125
+ });
126
+ }
127
+ function stringValue(...values) {
128
+ for (const value of values) {
129
+ if (typeof value === "string" && value.length > 0)
130
+ return value;
131
+ }
132
+ return undefined;
133
+ }
134
+ function objectValue(value) {
135
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
136
+ }
137
+ function extractText(value) {
138
+ if (typeof value === "string")
139
+ return value;
140
+ if (Array.isArray(value)) {
141
+ return value
142
+ .map((item) => stringValue(objectValue(item)?.text, objectValue(item)?.content, item))
143
+ .filter((item) => Boolean(item))
144
+ .join("\n");
145
+ }
146
+ const obj = objectValue(value);
147
+ if (!obj)
148
+ return "";
149
+ return stringValue(obj.text, obj.content, obj.message, obj.result) ?? "";
150
+ }
151
+ function mapUsage(raw) {
152
+ const input = Number(raw.input_tokens ?? raw.input ?? raw.prompt_tokens ?? 0);
153
+ const output = Number(raw.output_tokens ?? raw.output ?? raw.completion_tokens ?? 0);
154
+ const cacheRead = Number(raw.cache_read_input_tokens ?? raw.cacheRead ?? 0);
155
+ const cacheWrite = Number(raw.cache_creation_input_tokens ?? raw.cacheWrite ?? 0);
156
+ return {
157
+ input,
158
+ output,
159
+ cacheRead,
160
+ cacheWrite,
161
+ };
162
+ }
163
+ function normalizeToolArguments(input) {
164
+ return objectValue(input) ?? { input };
165
+ }
166
+ function normalizeToolResult(raw) {
167
+ const text = extractText(raw.content ?? raw.result ?? raw.output);
168
+ return {
169
+ content: text ? [{ type: "text", text }] : [],
170
+ isError: Boolean(raw.is_error ?? raw.isError ?? raw.error),
171
+ };
172
+ }
173
+ export function parseCursorAgentLine(line) {
174
+ const trimmed = line.trim();
175
+ if (!trimmed)
176
+ return { type: "ignore" };
177
+ let event;
178
+ try {
179
+ event = JSON.parse(trimmed);
180
+ }
181
+ catch {
182
+ return { type: "text", text: trimmed };
183
+ }
184
+ const type = stringValue(event.type, event.event) ?? "";
185
+ if (type === "error") {
186
+ return { type: "error", message: stringValue(event.message, event.error) ?? "cursor_agent_error" };
187
+ }
188
+ if (type === "tool_call") {
189
+ if (event.call_id || event.subtype || event.tool_call)
190
+ return { type: "ignore" };
191
+ const id = stringValue(event.id, event.tool_call_id) ?? `cursor_tool_${Date.now()}`;
192
+ const name = stringValue(event.name, event.tool_name) ?? "cursor_tool";
193
+ return {
194
+ type: "tool_call",
195
+ toolCall: { type: "toolCall", id, name, arguments: normalizeToolArguments(event.input ?? event.arguments) },
196
+ };
197
+ }
198
+ if (type === "tool_result") {
199
+ return {
200
+ type: "tool_result",
201
+ toolCallId: stringValue(event.tool_call_id, event.id) ?? "",
202
+ result: normalizeToolResult(event),
203
+ };
204
+ }
205
+ if (type === "result") {
206
+ const usage = objectValue(event.usage);
207
+ return usage ? { type: "usage", usage: mapUsage(usage) } : { type: "ignore" };
208
+ }
209
+ const text = extractText(event.delta ?? event.text ?? event.content ?? objectValue(event.message)?.content ?? event.message);
210
+ if (text)
211
+ return { type: "text", text };
212
+ const usage = objectValue(event.usage);
213
+ if (usage)
214
+ return { type: "usage", usage: mapUsage(usage) };
215
+ return { type: "ignore" };
216
+ }
217
+ function createUsage(partial) {
218
+ const input = partial?.input ?? 0;
219
+ const output = partial?.output ?? 0;
220
+ const cacheRead = partial?.cacheRead ?? 0;
221
+ const cacheWrite = partial?.cacheWrite ?? 0;
222
+ return {
223
+ ...ZERO_USAGE,
224
+ input,
225
+ output,
226
+ cacheRead,
227
+ cacheWrite,
228
+ totalTokens: input + output + cacheWrite,
229
+ cost: { ...ZERO_USAGE.cost },
230
+ };
231
+ }
232
+ function buildAssistantMessage(model, content, usage, stopReason = "stop", errorMessage) {
233
+ return {
234
+ role: "assistant",
235
+ content,
236
+ api: model.api,
237
+ provider: model.provider,
238
+ model: model.id,
239
+ usage: createUsage(usage),
240
+ stopReason,
241
+ ...(errorMessage ? { errorMessage } : {}),
242
+ timestamp: Date.now(),
243
+ };
244
+ }
245
+ function emitDone(stream, message, text) {
246
+ stream.push({ type: "start", partial: { ...message, content: [] } });
247
+ if (text) {
248
+ stream.push({ type: "text_start", contentIndex: 0, partial: message });
249
+ stream.push({ type: "text_delta", contentIndex: 0, delta: text, partial: message });
250
+ stream.push({ type: "text_end", contentIndex: 0, content: text, partial: message });
251
+ }
252
+ message.content.forEach((block, index) => {
253
+ if (block.type !== "toolCall")
254
+ return;
255
+ stream.push({ type: "toolcall_start", contentIndex: index, partial: message });
256
+ stream.push({ type: "toolcall_end", contentIndex: index, toolCall: block, partial: message });
257
+ });
258
+ stream.push({ type: "done", reason: "stop", message });
259
+ stream.end(message);
260
+ }
261
+ function emitError(stream, model, error) {
262
+ const message = error instanceof Error ? error.message : String(error);
263
+ const output = buildAssistantMessage(model, [], undefined, "error", message);
264
+ stream.push({ type: "error", reason: "error", error: output });
265
+ stream.end(output);
266
+ }
267
+ export function streamViaCursorAgent(model, context, options) {
268
+ const stream = createAssistantMessageEventStream();
269
+ queueMicrotask(async () => {
270
+ try {
271
+ const cwd = options?.cwd || process.cwd();
272
+ const prompt = buildCursorPrompt(context);
273
+ const plan = buildCursorAgentRunPlan(model.id, prompt, cwd);
274
+ const runForTest = options?._cursorAgentRunnerForTest;
275
+ let text = "";
276
+ let usage;
277
+ let streamStarted = false;
278
+ let textStarted = false;
279
+ const toolCalls = new Map();
280
+ const content = [];
281
+ const partialMessage = () => {
282
+ const partialContent = text ? [{ type: "text", text }, ...content] : [...content];
283
+ return buildAssistantMessage(model, partialContent, usage);
284
+ };
285
+ const ensureStart = () => {
286
+ if (streamStarted)
287
+ return;
288
+ streamStarted = true;
289
+ stream.push({ type: "start", partial: buildAssistantMessage(model, []) });
290
+ };
291
+ const handleLine = (line) => {
292
+ const parsed = parseCursorAgentLine(line);
293
+ if (parsed.type === "ignore")
294
+ return;
295
+ if (parsed.type === "error")
296
+ throw new Error(parsed.message);
297
+ if (parsed.type === "text") {
298
+ ensureStart();
299
+ if (!textStarted) {
300
+ textStarted = true;
301
+ stream.push({ type: "text_start", contentIndex: 0, partial: partialMessage() });
302
+ }
303
+ text += parsed.text;
304
+ stream.push({ type: "text_delta", contentIndex: 0, delta: parsed.text, partial: partialMessage() });
305
+ return;
306
+ }
307
+ if (parsed.type === "usage") {
308
+ usage = { ...(usage ?? {}), ...parsed.usage };
309
+ return;
310
+ }
311
+ if (parsed.type === "tool_call") {
312
+ ensureStart();
313
+ toolCalls.set(parsed.toolCall.id, parsed.toolCall);
314
+ content.push(parsed.toolCall);
315
+ const index = text ? content.length : content.length - 1;
316
+ const partial = partialMessage();
317
+ stream.push({ type: "toolcall_start", contentIndex: index, partial });
318
+ stream.push({ type: "toolcall_end", contentIndex: index, toolCall: parsed.toolCall, partial });
319
+ return;
320
+ }
321
+ if (parsed.type === "tool_result") {
322
+ const toolCall = toolCalls.get(parsed.toolCallId);
323
+ if (toolCall)
324
+ toolCall.externalResult = parsed.result;
325
+ }
326
+ };
327
+ const result = runForTest
328
+ ? await runForTest(plan, options, handleLine)
329
+ : await runCursorAgent(plan, options, handleLine);
330
+ if (runForTest) {
331
+ for (const line of result.stdout.split(/\r?\n/))
332
+ handleLine(line);
333
+ }
334
+ if (result.code !== 0) {
335
+ throw new Error((result.stderr || result.stdout || `cursor-agent exited with code ${result.code}`).trim());
336
+ }
337
+ const finalContent = text ? [{ type: "text", text }, ...content] : content;
338
+ const finalMessage = buildAssistantMessage(model, finalContent, usage);
339
+ if (!streamStarted) {
340
+ emitDone(stream, finalMessage, text);
341
+ return;
342
+ }
343
+ if (textStarted)
344
+ stream.push({ type: "text_end", contentIndex: 0, content: text, partial: finalMessage });
345
+ stream.push({ type: "done", reason: "stop", message: finalMessage });
346
+ stream.end(finalMessage);
347
+ }
348
+ catch (error) {
349
+ emitError(stream, model, error);
350
+ }
351
+ });
352
+ return stream;
353
+ }
@@ -13,6 +13,7 @@ import { join } from "node:path";
13
13
  import { GSDError, GSD_IO_ERROR } from "./errors.js";
14
14
  const SEQ_PREFIX_RE = /^(\d+)-/;
15
15
  import { gsdRoot } from "./paths.js";
16
+ import { redactSecrets } from "./redact-secrets.js";
16
17
  import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
17
18
  import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
18
19
  const activityLogState = new Map();
@@ -104,7 +105,9 @@ export function saveActivityLog(ctx, basePath, unitType, unitId) {
104
105
  const fd = openSync(filePath, "w");
105
106
  try {
106
107
  for (const entry of entries) {
107
- writeSync(fd, JSON.stringify(entry) + "\n");
108
+ // Redact secret-shaped substrings before persisting; .gsd/ is skipped by
109
+ // the secret scanner, so raw LLM/tool content could otherwise leak keys.
110
+ writeSync(fd, redactSecrets(JSON.stringify(entry)) + "\n");
108
111
  }
109
112
  }
110
113
  finally {
@@ -47,6 +47,10 @@ function parseRoadmapForRecovery(content) {
47
47
  return _roadmapParserFn(content);
48
48
  return parseLegacyRoadmap(content);
49
49
  }
50
+ /** Slice count for plan-milestone verification; shared by scoped and legacy paths. */
51
+ export function countPlanMilestoneRoadmapSlices(content) {
52
+ return parseRoadmapForRecovery(content).slices.length;
53
+ }
50
54
  export function diagnoseWorktreeIntegrityFailure(basePath) {
51
55
  if (!isGsdWorktreePath(basePath))
52
56
  return null;
@@ -294,8 +298,7 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
294
298
  }
295
299
  if (unitType === "plan-milestone") {
296
300
  try {
297
- const roadmap = parseRoadmapForRecovery(readFileSync(absPath, "utf-8"));
298
- if (roadmap.slices.length === 0) {
301
+ if (countPlanMilestoneRoadmapSlices(readFileSync(absPath, "utf-8")) === 0) {
299
302
  logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap has zero slices at ${absPath}`);
300
303
  return false;
301
304
  }
@@ -311,6 +314,19 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
311
314
  try {
312
315
  let taskIds = null;
313
316
  let dbPrimary = false;
317
+ const planContent = readFileSync(absPath, "utf-8");
318
+ let parsedTaskIds = null;
319
+ const getParsedTaskIds = () => {
320
+ if (parsedTaskIds)
321
+ return parsedTaskIds;
322
+ parsedTaskIds = parseLegacyPlan(planContent).tasks.map((t) => t.id);
323
+ return parsedTaskIds;
324
+ };
325
+ const tasksBlockMatch = planContent.match(/<tasks>([\s\S]*?)<\/tasks>/i);
326
+ const tasksBlock = tasksBlockMatch?.[1] ?? "";
327
+ const hasEmbeddedTaskEntries = tasksBlock.length > 0 &&
328
+ (/^\s*- \[[xX ]\] \*\*T\d+/m.test(tasksBlock) ||
329
+ /^\s*#{2,4}\s+T\d+\s*(?:--|—|:)/m.test(tasksBlock));
314
330
  if (isDbAvailable()) {
315
331
  const refreshed = refreshWorkflowDatabaseFromDisk();
316
332
  if (refreshed) {
@@ -322,24 +338,24 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
322
338
  }
323
339
  }
324
340
  if (!taskIds) {
325
- const planContent = readFileSync(absPath, "utf-8");
326
341
  const hasCheckboxTask = /^\s*- \[[xX ]\] \*\*T\d+/m.test(planContent);
327
342
  const hasHeadingTask = /^\s*#{2,4}\s+T\d+\s*(?:--|—|:)/m.test(planContent);
328
343
  if (!hasCheckboxTask && !hasHeadingTask) {
329
344
  logWarning("recovery", `verify-fail ${unitType} ${unitId}: plan has no task checkbox/heading (len=${planContent.length}) at ${absPath}`);
330
345
  return false;
331
346
  }
332
- const plan = parseLegacyPlan(planContent);
333
- if (plan.tasks.length > 0)
334
- taskIds = plan.tasks.map((t) => t.id);
347
+ const parsedIds = getParsedTaskIds();
348
+ if (parsedIds.length > 0)
349
+ taskIds = parsedIds;
335
350
  }
336
- if (taskIds && taskIds.length > 0) {
351
+ if (taskIds && taskIds.length > 0 && !hasEmbeddedTaskEntries) {
337
352
  const tasksDir = join(dirname(absPath), "tasks");
338
353
  if (existsSync(tasksDir)) {
339
354
  for (const tid of taskIds) {
340
355
  const taskPlanFile = join(tasksDir, `${tid}-PLAN.md`);
341
- if (!existsSync(taskPlanFile)) {
342
- logWarning("recovery", `verify-fail ${unitType} ${unitId}: task plan missing ${taskPlanFile}`);
356
+ const taskSummaryFile = join(tasksDir, `${tid}-SUMMARY.md`);
357
+ if (!existsSync(taskPlanFile) && !existsSync(taskSummaryFile)) {
358
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: task artifact missing for ${tid}`);
343
359
  return false;
344
360
  }
345
361
  }
@@ -1,12 +1,17 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Auto-loop closeout, milestone report, and merge helpers.
3
3
  import { importExtensionModule } from "@gsd/pi-coding-agent";
4
+ import { execFileSync } from "node:child_process";
5
+ import { createHash } from "node:crypto";
6
+ import { join, basename } from "node:path";
7
+ import { readFileSync } from "node:fs";
4
8
  import { MergeConflictError } from "../git-service.js";
5
9
  import { findUnmergedCompletedMilestones } from "../unmerged-milestone-guard.js";
6
10
  import { getIsolationMode } from "../preferences.js";
7
11
  import { isDbAvailable, getMilestone } from "../gsd-db.js";
8
12
  import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
9
13
  import { isClosedStatus } from "../status-guards.js";
14
+ import { PLANNING_ARTIFACT_SUFFIXES } from "../paths.js";
10
15
  import { logWarning, logError } from "../workflow-logger.js";
11
16
  import { debugLog } from "../debug-logger.js";
12
17
  import { _resolveReportBasePath } from "./phase-helpers.js";
@@ -37,62 +42,59 @@ export async function restorePreflightStashOrStop(ic, preflight, milestoneId) {
37
42
  return stopOnPostflightRecoveryNeeded(ic, result, milestoneId);
38
43
  }
39
44
  /**
40
- * Run a milestone merge surrounded by preflight stash + always-on postflight
41
- * pop. The previous code popped the stash only after a successful merge, which
42
- * leaked `gsd-preflight-stash:M00x:*` entries whenever `mergeAndExit` threw —
43
- * leaving the user's pre-merge working tree silently stashed away after a
44
- * merge-conflict or other merge error. This helper restores the stash on
45
- * every exit path, then surfaces the merge or stash failure (in priority
46
- * order) as the loop's stop reason.
45
+ * Run a milestone merge through Worktree Lifecycle's guarded merge option,
46
+ * which surrounds the inner merge with preflight stash + always-on postflight
47
+ * pop. The previous closeout code popped the stash only after a successful
48
+ * merge, which leaked `gsd-preflight-stash:M00x:*` entries whenever
49
+ * `mergeAndExit` threw leaving the user's pre-merge working tree silently
50
+ * stashed away after a merge-conflict or other merge error. Lifecycle now
51
+ * restores the stash on every attempted merge path, then this adapter surfaces
52
+ * the merge or stash failure (in priority order) as the loop's stop reason.
47
53
  *
48
54
  * Returns a `break` action when auto-mode must stop, or `null` when the merge
49
55
  * succeeded and the stash (if any) was restored cleanly.
50
56
  */
51
57
  export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, options = {}) {
52
58
  const { ctx, pi, s, deps } = ic;
53
- const preflight = deps.preflightCleanRoot(s.originalBasePath || s.basePath, milestoneId, ctx.ui.notify.bind(ctx.ui));
54
- if (preflight.blocked) {
55
- const reason = preflight.blockedReason === "unmerged-conflicts"
59
+ // Resolve the project root once, before the merge can flip session path
60
+ // pointers (worktree teardown mutates s.basePath / s.scope). The guarded
61
+ // merge's preflight/postflight stash restore, the pre-merge ignored-markdown
62
+ // snapshot, the dirty-projection check, and the rebuild must all target this
63
+ // same tree; otherwise `.gsd` markdown restored on one tree can be silently
64
+ // overwritten by a rebuild on another. canonicalProjectRoot is the
65
+ // authoritative `.gsd`/DB writer path (see AutoSession.canonicalProjectRoot).
66
+ const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
67
+ const ignoredProjectionSnapshot = snapshotIgnoredGsdMarkdownProjections(projectRoot);
68
+ const mergeResult = deps.lifecycle.exitMilestone(milestoneId, {
69
+ merge: true,
70
+ guardedMerge: {
71
+ projectRoot,
72
+ preflightCleanRoot: deps.preflightCleanRoot,
73
+ postflightPopStash: deps.postflightPopStash,
74
+ },
75
+ }, ctx.ui);
76
+ if (mergeResult.ok) {
77
+ await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
78
+ return null;
79
+ }
80
+ if (mergeResult.reason === "postflight-stash-restore-failed") {
81
+ await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
82
+ }
83
+ if (mergeResult.reason === "preflight-dirty-overlap" || mergeResult.reason === "preflight-unmerged-conflicts") {
84
+ const reason = mergeResult.reason === "preflight-unmerged-conflicts"
56
85
  ? `Pre-merge unresolved Git conflicts block milestone ${milestoneId}`
57
86
  : `Pre-merge dirty working tree overlaps milestone ${milestoneId}`;
58
87
  await deps.stopAuto(ctx, pi, reason, {
59
88
  preserveCompletedMilestoneBranch: true,
60
89
  preserveCloseoutTranscript: options.preserveCloseoutTranscript,
61
90
  });
62
- return {
63
- action: "break",
64
- reason: preflight.blockedReason === "unmerged-conflicts"
65
- ? "preflight-unmerged-conflicts"
66
- : "preflight-dirty-overlap",
67
- };
68
- }
69
- let mergeError = null;
70
- const exitResult = deps.lifecycle.exitMilestone(milestoneId, { merge: true }, ctx.ui);
71
- if (exitResult.ok) {
72
- s.milestoneMergedInPhases = true;
73
- try {
74
- const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
75
- const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
76
- await rebuildMarkdownProjectionsFromDb(projectRoot);
77
- }
78
- catch (err) {
79
- logWarning("engine", `markdown projection rebuild after milestone merge failed: ${err instanceof Error ? err.message : String(err)}`);
80
- }
81
- }
82
- else {
83
- mergeError = exitResult.cause ?? new Error(`exit ${exitResult.reason}`);
84
- }
85
- // Always attempt to restore the stashed working tree, even on merge error.
86
- // postflightPopStash itself does not throw; failures surface via the
87
- // PostflightResult.needsManualRecovery flag.
88
- let stashResult = null;
89
- if (preflight.stashPushed) {
90
- stashResult = deps.postflightPopStash(s.originalBasePath || s.basePath, milestoneId, preflight.stashMarker, ctx.ui.notify.bind(ctx.ui));
91
+ return { action: "break", reason: mergeResult.reason };
91
92
  }
92
93
  // Merge failure takes priority over stash recovery — the merge is the
93
94
  // authoritative gate. If the stash also needed manual recovery, the user
94
95
  // already saw the postflightPopStash notify above.
95
- if (mergeError) {
96
+ if (mergeResult.reason === "merge-conflict") {
97
+ const mergeError = mergeResult.cause;
96
98
  if (mergeError instanceof MergeConflictError) {
97
99
  // A merge conflict is a recoverable human checkpoint, not an
98
100
  // infrastructure failure — the user resolves the conflict and runs
@@ -109,6 +111,9 @@ export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, option
109
111
  });
110
112
  return { action: "break", reason: "merge-conflict" };
111
113
  }
114
+ }
115
+ if (mergeResult.reason === "merge-failed" || mergeResult.reason === "merge-conflict") {
116
+ const mergeError = mergeResult.cause;
112
117
  logError("engine", "Milestone merge failed with non-conflict error", {
113
118
  milestone: milestoneId,
114
119
  error: String(mergeError),
@@ -125,11 +130,101 @@ export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, option
125
130
  });
126
131
  return { action: "break", reason: "merge-failed" };
127
132
  }
128
- if (stashResult) {
129
- return stopOnPostflightRecoveryNeeded(ic, stashResult, milestoneId);
133
+ if (mergeResult.postflight) {
134
+ return stopOnPostflightRecoveryNeeded(ic, mergeResult.postflight, milestoneId);
130
135
  }
131
136
  return null;
132
137
  }
138
+ async function markMilestoneMergedAndRebuild(s, rebuildBasePath, ignoredProjectionSnapshot) {
139
+ s.milestoneMergedInPhases = true;
140
+ if (hasDirtyGsdMarkdownProjections(rebuildBasePath, ignoredProjectionSnapshot)) {
141
+ logWarning("engine", "skipping markdown projection rebuild after milestone merge because restored .gsd edits are dirty");
142
+ return;
143
+ }
144
+ try {
145
+ const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
146
+ await rebuildMarkdownProjectionsFromDb(rebuildBasePath);
147
+ }
148
+ catch (err) {
149
+ logWarning("engine", `markdown projection rebuild after milestone merge failed: ${err instanceof Error ? err.message : String(err)}`);
150
+ }
151
+ }
152
+ function hasDirtyGsdMarkdownProjections(basePath, ignoredProjectionSnapshot) {
153
+ try {
154
+ const output = execFileSync("git", ["status", "--porcelain", "-z", "--untracked-files=all", "--", ".gsd"], { cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
155
+ const entries = output.split("\0").filter(Boolean);
156
+ for (let i = 0; i < entries.length; i++) {
157
+ const entry = entries[i];
158
+ if (entry.length <= 3)
159
+ continue;
160
+ const status = entry.slice(0, 2);
161
+ const path = entry.slice(3);
162
+ if (isGeneratedGsdMarkdownProjection(path))
163
+ return true;
164
+ if ((status === "R " || status === "C ") && i + 1 < entries.length) {
165
+ const dest = entries[++i];
166
+ if (isGeneratedGsdMarkdownProjection(dest))
167
+ return true;
168
+ }
169
+ }
170
+ }
171
+ catch (err) {
172
+ void err;
173
+ // Fall through to ignored-file snapshot comparison below.
174
+ }
175
+ return ignoredGsdMarkdownProjectionSnapshotChanged(basePath, ignoredProjectionSnapshot);
176
+ }
177
+ function isGeneratedGsdMarkdownProjection(path) {
178
+ const normalized = path.replace(/\\/g, "/");
179
+ if (normalized === ".gsd/DECISIONS.md")
180
+ return true;
181
+ if (!normalized.startsWith(".gsd/milestones/") && !normalized.startsWith(".gsd/phases/")) {
182
+ return false;
183
+ }
184
+ return isGeneratedPlanningArtifactFileName(basename(normalized));
185
+ }
186
+ function isGeneratedPlanningArtifactFileName(fileName) {
187
+ if (!fileName.endsWith(".md"))
188
+ return false;
189
+ const stem = fileName.slice(0, -".md".length).toUpperCase();
190
+ for (const suffix of PLANNING_ARTIFACT_SUFFIXES) {
191
+ if (!stem.endsWith(`-${suffix}`))
192
+ continue;
193
+ const idPrefix = stem.slice(0, -suffix.length - 1);
194
+ return /^(?:[MST]\d+|\d{2,})(?:-[A-Z0-9]+)*$/.test(idPrefix);
195
+ }
196
+ return false;
197
+ }
198
+ function snapshotIgnoredGsdMarkdownProjections(basePath) {
199
+ try {
200
+ const output = execFileSync("git", ["ls-files", "--others", "--ignored", "--exclude-standard", "-z", "--", ".gsd"], { cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
201
+ const snapshot = new Map();
202
+ for (const path of output.split("\0")) {
203
+ if (!isGeneratedGsdMarkdownProjection(path))
204
+ continue;
205
+ snapshot.set(path, hashFile(join(basePath, path)));
206
+ }
207
+ return snapshot;
208
+ }
209
+ catch {
210
+ return null;
211
+ }
212
+ }
213
+ function hashFile(path) {
214
+ return createHash("sha256").update(readFileSync(path)).digest("hex");
215
+ }
216
+ function ignoredGsdMarkdownProjectionSnapshotChanged(basePath, before) {
217
+ if (!before)
218
+ return true;
219
+ const after = snapshotIgnoredGsdMarkdownProjections(basePath);
220
+ if (!after || after.size !== before.size)
221
+ return true;
222
+ for (const [path, hash] of before) {
223
+ if (after.get(path) !== hash)
224
+ return true;
225
+ }
226
+ return false;
227
+ }
133
228
  export async function _runMilestoneMergeOnceWithStashRestore(ic, milestoneId, options = {}) {
134
229
  if (ic.s.milestoneMergedInPhases) {
135
230
  debugLog("autoLoop", {