@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
@@ -7,6 +7,7 @@ import { test } from 'node:test';
7
7
  import assert from 'node:assert/strict';
8
8
  import {
9
9
  checkToolCallLoop,
10
+ configureToolCallLoopGuard,
10
11
  recordToolCallLoopMutation,
11
12
  resetToolCallLoopGuard,
12
13
  disableToolCallLoopGuard,
@@ -251,6 +252,99 @@ console.log('\n── Loop guard: mutation progress decays per-tool counts (#109
251
252
  }
252
253
  }
253
254
 
255
+ // ═══════════════════════════════════════════════════════════════════════════
256
+ // Successful shell/exec progress decays per-tool counts (#1206)
257
+ // ═══════════════════════════════════════════════════════════════════════════
258
+
259
+ console.log('\n── Loop guard: successful shell/exec progress decays per-tool counts (#1206) ──');
260
+
261
+ {
262
+ // A local model debugging a UAT scenario runs many varied bg_shell /
263
+ // gsd_uat_exec calls (restart server, npm install, curl an endpoint). Each
264
+ // successful call is state progression, so Guard 2 must decay and never
265
+ // block the productive turn — even past the repeatable cap.
266
+ for (const execTool of ['bg_shell', 'gsd_uat_exec', 'bash', 'gsd_exec']) {
267
+ resetToolCallLoopGuard();
268
+
269
+ for (let i = 1; i <= 20; i++) {
270
+ const result = checkToolCallLoop(execTool, { command: `step ${i}` });
271
+ assert.ok(result.block === false, `${execTool} call ${i} after exec progress should be allowed`);
272
+ assert.deepStrictEqual(getToolCallCountForTool(execTool), 1, `${execTool} count should decay before call ${i}`);
273
+
274
+ // A successful (non-error) exec call records progress, like a file mutation.
275
+ recordToolCallLoopMutation(execTool);
276
+ }
277
+ }
278
+ }
279
+
280
+ // ═══════════════════════════════════════════════════════════════════════════
281
+ // Failing exec loops still trip the per-tool cap (#783 vs #1206)
282
+ // ═══════════════════════════════════════════════════════════════════════════
283
+
284
+ console.log('\n── Loop guard: failing exec loop (no progress recorded) still trips the cap (#783) ──');
285
+
286
+ {
287
+ resetToolCallLoopGuard();
288
+
289
+ // The improvisation loop from #783: the model retries a missing tool through
290
+ // varied bash commands. Those fail (non-zero exit → isError), so the caller
291
+ // never records progress and the per-tool cap must still trip.
292
+ for (let i = 1; i <= 15; i++) {
293
+ const result = checkToolCallLoop('bash', { command: `try-missing-tool ${i}` });
294
+ assert.ok(result.block === false, `failing bash call ${i} should be allowed up to the cap`);
295
+ // No recordToolCallLoopMutation — the command errored.
296
+ }
297
+ const blocked = checkToolCallLoop('bash', { command: 'try-missing-tool 16' });
298
+ assert.ok(blocked.block === true, '16th failing bash call should be blocked by the per-tool cap');
299
+ assert.ok(blocked.reason?.includes('repeated tool'), 'reason should identify the per-tool guard');
300
+ }
301
+
302
+ // ═══════════════════════════════════════════════════════════════════════════
303
+ // bg_shell/async_bash false-success must not decay the per-tool cap (#783)
304
+ // ═══════════════════════════════════════════════════════════════════════════
305
+
306
+ console.log('\n── Loop guard: bg_shell failed run/start does not decay the cap (#783) ──');
307
+
308
+ {
309
+ resetToolCallLoopGuard();
310
+
311
+ for (let i = 1; i <= 15; i++) {
312
+ const result = checkToolCallLoop('bg_shell', { action: 'run', command: `try-missing-tool ${i}` });
313
+ assert.ok(result.block === false, `failing bg_shell run ${i} should be allowed up to the cap`);
314
+ recordToolCallLoopMutation('bg_shell', { action: 'run', exitCode: 1, timedOut: false });
315
+ }
316
+ const blocked = checkToolCallLoop('bg_shell', { action: 'run', command: 'try-missing-tool 16' });
317
+ assert.ok(blocked.block === true, '16th failing bg_shell run should be blocked by the per-tool cap');
318
+ }
319
+
320
+ {
321
+ resetToolCallLoopGuard();
322
+
323
+ for (let i = 1; i <= 15; i++) {
324
+ checkToolCallLoop('bg_shell', { action: 'start', command: `bad-server ${i}` });
325
+ recordToolCallLoopMutation('bg_shell', {
326
+ action: 'start',
327
+ process: { alive: false, exitCode: 1 },
328
+ });
329
+ }
330
+ const blocked = checkToolCallLoop('bg_shell', { action: 'start', command: 'bad-server 16' });
331
+ assert.ok(blocked.block === true, '16th dead bg_shell start should be blocked by the per-tool cap');
332
+ }
333
+
334
+ console.log('\n── Loop guard: async_bash job registration does not decay the cap (#783) ──');
335
+
336
+ {
337
+ resetToolCallLoopGuard();
338
+
339
+ for (let i = 1; i <= 6; i++) {
340
+ const result = checkToolCallLoop('async_bash', { command: `try-missing-tool ${i}` });
341
+ assert.ok(result.block === false, `async_bash call ${i} should be allowed up to the cap`);
342
+ recordToolCallLoopMutation('async_bash');
343
+ }
344
+ const blocked = checkToolCallLoop('async_bash', { command: 'try-missing-tool 7' });
345
+ assert.ok(blocked.block === true, '7th async_bash call should be blocked by the per-tool cap');
346
+ }
347
+
254
348
  // ═══════════════════════════════════════════════════════════════════════════
255
349
  // Distinct read-only navigation calls are context gathering, not repeated-tool loops.
256
350
  // ═══════════════════════════════════════════════════════════════════════════
@@ -385,3 +479,168 @@ console.log('\n── Loop guard: block reasons tell model to respond in text
385
479
  }
386
480
 
387
481
  // ═══════════════════════════════════════════════════════════════════════════
482
+ // Distinct-arg browser-automation calls are a legitimate UAT, not a loop (#1120)
483
+ // ═══════════════════════════════════════════════════════════════════════════
484
+
485
+ console.log('\n── Loop guard: distinct-arg browser automation calls are not capped by per-tool count (#1120) ──');
486
+
487
+ {
488
+ // A browser-backed UAT legitimately calls one browser verb many times with
489
+ // DIFFERENT arguments (read a validation message, count staged edits, inspect
490
+ // a control card, …). Guard 1's identical-signature streak never trips because
491
+ // the args vary; Guard 2's arg-independent per-tool cap must NOT block it.
492
+ for (const toolName of ['browser_evaluate', 'browser_act', 'browser_find']) {
493
+ resetToolCallLoopGuard();
494
+ for (let i = 1; i <= 12; i++) {
495
+ const result = checkToolCallLoop(toolName, { script: `step ${i}` });
496
+ assert.ok(result.block === false, `distinct ${toolName} call ${i} should be allowed`);
497
+ }
498
+ }
499
+
500
+ // MCP-prefixed browser tools canonicalize to `browser_*` and are exempt too.
501
+ resetToolCallLoopGuard();
502
+ for (let i = 1; i <= 12; i++) {
503
+ const result = checkToolCallLoop('mcp__agent-browser__browser_evaluate', { script: `step ${i}` });
504
+ assert.ok(result.block === false, `distinct MCP-prefixed browser_evaluate call ${i} should be allowed`);
505
+ }
506
+ }
507
+
508
+ // ═══════════════════════════════════════════════════════════════════════════
509
+ // Identical-arg browser loops are STILL caught by Guard 1 (#1120)
510
+ // ═══════════════════════════════════════════════════════════════════════════
511
+
512
+ console.log('\n── Loop guard: identical-arg browser loops are still caught by Guard 1 (#1120) ──');
513
+
514
+ {
515
+ resetToolCallLoopGuard();
516
+ for (let i = 1; i <= 4; i++) {
517
+ const result = checkToolCallLoop('browser_evaluate', { script: 'document.title' });
518
+ assert.ok(result.block === false, `identical browser_evaluate call ${i} should be allowed`);
519
+ }
520
+ const blocked = checkToolCallLoop('browser_evaluate', { script: 'document.title' });
521
+ assert.ok(blocked.block === true, '5th identical browser_evaluate call should be blocked by Guard 1');
522
+ assert.ok(blocked.reason?.includes('identical args'), 'identical browser loops should be caught by Guard 1, not Guard 2');
523
+ }
524
+
525
+ // ═══════════════════════════════════════════════════════════════════════════
526
+ // The browser exemption must NOT widen to other non-exempt tools (#1120)
527
+ // ═══════════════════════════════════════════════════════════════════════════
528
+
529
+ console.log('\n── Loop guard: browser exemption does not widen to other tools (#1120) ──');
530
+
531
+ {
532
+ // Negative invariant: an arbitrary non-exempt, non-browser tool called past
533
+ // the default cap with varied args must still be blocked by Guard 2.
534
+ resetToolCallLoopGuard();
535
+ for (let i = 1; i <= 6; i++) {
536
+ const result = checkToolCallLoop('some_workflow_tool', { arg: `v${i}` });
537
+ assert.ok(result.block === false, `non-exempt tool call ${i} should be allowed`);
538
+ }
539
+ const blocked = checkToolCallLoop('some_workflow_tool', { arg: 'v7' });
540
+ assert.ok(blocked.block === true, '7th varied-arg non-exempt call must still trip Guard 2');
541
+ assert.ok(blocked.reason?.includes('repeated tool'), 'non-exempt overflow should be caught by Guard 2');
542
+ }
543
+
544
+ // ═══════════════════════════════════════════════════════════════════════════
545
+ // Configurable thresholds (#1198)
546
+ // ═══════════════════════════════════════════════════════════════════════════
547
+
548
+ console.log('\n── Loop guard: master switch disables both guards (#1198) ──');
549
+
550
+ {
551
+ configureToolCallLoopGuard({ enabled: false });
552
+ resetToolCallLoopGuard();
553
+ // Neither identical-args nor per-tool cap should ever trip while disabled.
554
+ for (let i = 1; i <= 30; i++) {
555
+ const result = checkToolCallLoop('gsd_complete_milestone', { same: 'args' });
556
+ assert.ok(result.block === false, `disabled guard should allow call ${i}`);
557
+ }
558
+ // Restore defaults for subsequent tests.
559
+ configureToolCallLoopGuard(null);
560
+ }
561
+
562
+ console.log('\n── Loop guard: repeated_tool disabled keeps identical-args protection (#1198) ──');
563
+
564
+ {
565
+ configureToolCallLoopGuard({ repeated_tool: { enabled: false } });
566
+ resetToolCallLoopGuard();
567
+ // Per-tool cap is off: many varied-arg calls are allowed.
568
+ for (let i = 1; i <= 20; i++) {
569
+ const result = checkToolCallLoop('gsd_exec', { cmd: `run-${i}` });
570
+ assert.ok(result.block === false, `repeated_tool disabled should allow varied call ${i}`);
571
+ }
572
+ // Identical-args guard is still active.
573
+ resetToolCallLoopGuard();
574
+ for (let i = 1; i <= 4; i++) {
575
+ assert.ok(checkToolCallLoop('gsd_exec', { cmd: 'same' }).block === false);
576
+ }
577
+ const blocked = checkToolCallLoop('gsd_exec', { cmd: 'same' });
578
+ assert.ok(blocked.block === true, 'identical-args guard should still trip when repeated_tool is off');
579
+ assert.ok(blocked.reason?.includes('identical args'));
580
+ configureToolCallLoopGuard(null);
581
+ }
582
+
583
+ console.log('\n── Loop guard: raised caps allow more repeated calls (#1198) ──');
584
+
585
+ {
586
+ configureToolCallLoopGuard({ repeated_tool: { default_cap: 10 } });
587
+ resetToolCallLoopGuard();
588
+ for (let i = 1; i <= 10; i++) {
589
+ const result = checkToolCallLoop('gsd_complete_milestone', { arg: `v${i}` });
590
+ assert.ok(result.block === false, `raised-cap call ${i} should be allowed`);
591
+ }
592
+ const blocked = checkToolCallLoop('gsd_complete_milestone', { arg: 'v11' });
593
+ assert.ok(blocked.block === true, '11th call should trip the raised cap of 10');
594
+ assert.ok(blocked.reason?.includes('cap 10'), 'block message should mention the active cap');
595
+ assert.ok(blocked.reason?.includes('tool_call_loop_guard'), 'block message should mention the config key');
596
+ configureToolCallLoopGuard(null);
597
+ }
598
+
599
+ console.log('\n── Loop guard: user-added exempt tools bypass the per-tool cap (#1198) ──');
600
+
601
+ {
602
+ configureToolCallLoopGuard({ repeated_tool: { exempt_tools: ['ctx_execute'] } });
603
+ resetToolCallLoopGuard();
604
+ for (let i = 1; i <= 30; i++) {
605
+ const result = checkToolCallLoop('ctx_execute', { arg: `v${i}` });
606
+ assert.ok(result.block === false, `exempt tool call ${i} should be allowed`);
607
+ }
608
+ // Built-in exempt defaults are preserved alongside the user-added tool.
609
+ resetToolCallLoopGuard();
610
+ for (let i = 1; i <= 30; i++) {
611
+ assert.ok(checkToolCallLoop('read', { path: `f${i}` }).block === false, 'built-in exempt read should remain exempt');
612
+ }
613
+ configureToolCallLoopGuard(null);
614
+ }
615
+
616
+ console.log('\n── Loop guard: identical-args max is configurable (#1198) ──');
617
+
618
+ {
619
+ configureToolCallLoopGuard({ identical_args: { max_consecutive_calls: 2 } });
620
+ resetToolCallLoopGuard();
621
+ assert.ok(checkToolCallLoop('web_search', { q: 'x' }).block === false, 'call 1 allowed');
622
+ assert.ok(checkToolCallLoop('web_search', { q: 'x' }).block === false, 'call 2 allowed');
623
+ const blocked = checkToolCallLoop('web_search', { q: 'x' });
624
+ assert.ok(blocked.block === true, '3rd identical call should trip lowered max of 2');
625
+ assert.ok(blocked.reason?.includes('max 2'), 'block message should mention active max');
626
+ configureToolCallLoopGuard(null);
627
+ }
628
+
629
+ console.log('\n── Loop guard: env overrides win over preferences (#1198) ──');
630
+
631
+ {
632
+ process.env.GSD_TOOL_LOOP_REPEATED_DEFAULT_CAP = '2';
633
+ configureToolCallLoopGuard({ repeated_tool: { default_cap: 6 } });
634
+ resetToolCallLoopGuard();
635
+ assert.ok(checkToolCallLoop('gsd_complete_milestone', { a: '1' }).block === false, 'call 1 allowed');
636
+ assert.ok(checkToolCallLoop('gsd_complete_milestone', { a: '2' }).block === false, 'call 2 allowed');
637
+ const blocked = checkToolCallLoop('gsd_complete_milestone', { a: '3' });
638
+ assert.ok(blocked.block === true, 'env override cap of 2 should win over preference cap of 6');
639
+ delete process.env.GSD_TOOL_LOOP_REPEATED_DEFAULT_CAP;
640
+ configureToolCallLoopGuard(null);
641
+ }
642
+
643
+ // ═══════════════════════════════════════════════════════════════════════════
644
+ // Reset restores default guard state after configuration tests
645
+ // ═══════════════════════════════════════════════════════════════════════════
646
+ resetToolCallLoopGuard();
@@ -30,7 +30,7 @@ import { join } from "node:path";
30
30
  import { tmpdir } from "node:os";
31
31
  import { execFileSync } from "node:child_process";
32
32
 
33
- import { syncProjectRootToWorktree } from "../auto-worktree.ts";
33
+ import { syncProjectRootToWorktree } from "../auto-worktree-sync.ts";
34
34
  import {
35
35
  createWorktree,
36
36
  removeWorktree,
@@ -268,7 +268,7 @@ test("#4934: every manifest declares a tools policy", () => {
268
268
  });
269
269
 
270
270
  test("#4934: tools.mode is one of the declared policies", () => {
271
- const validModes = new Set(["all", "read-only", "planning", "planning-dispatch", "docs", "verification"]);
271
+ const validModes = new Set(["all", "read-only", "planning", "planning-dispatch", "docs", "verification", "workflow-only"]);
272
272
  for (const [unitType, manifest] of Object.entries(UNIT_MANIFESTS)) {
273
273
  const mode = (manifest as { tools: { mode: string } }).tools.mode;
274
274
  assert.ok(
@@ -327,23 +327,71 @@ test("#5453: complete-milestone uses all tools so bash verification is not plann
327
327
  }
328
328
  });
329
329
 
330
- test("#5731: validate-milestone and complete-slice use all tools so closeout verification is not planning-dispatch blocked", () => {
331
- for (const unitType of ["validate-milestone", "complete-slice"] as const) {
332
- const manifest = UNIT_MANIFESTS[unitType];
333
- assert.strictEqual(manifest.tools.mode, "all");
334
- const result = shouldBlockPlanningUnit(
335
- "bash",
336
- "go test -short -count=1 ./...",
337
- process.cwd(),
338
- unitType,
339
- manifest.tools,
340
- );
341
- assert.strictEqual(
342
- result.block,
343
- false,
344
- `${unitType} must allow verification bash commands: ${result.reason}`,
345
- );
346
- }
330
+ test("#5731: complete-slice uses all tools so closeout verification is not planning-dispatch blocked", () => {
331
+ const manifest = UNIT_MANIFESTS["complete-slice"];
332
+ assert.strictEqual(manifest.tools.mode, "all");
333
+ const result = shouldBlockPlanningUnit(
334
+ "bash",
335
+ "go test -short -count=1 ./...",
336
+ process.cwd(),
337
+ "complete-slice",
338
+ manifest.tools,
339
+ );
340
+ assert.strictEqual(
341
+ result.block,
342
+ false,
343
+ `complete-slice must allow verification bash commands: ${result.reason}`,
344
+ );
345
+ });
346
+
347
+ test("#1157: validate-milestone uses workflow-only tools and blocks manual artifact writes", () => {
348
+ const manifest = UNIT_MANIFESTS["validate-milestone"];
349
+ assert.strictEqual(manifest.tools.mode, "workflow-only");
350
+ assert.deepEqual(resolveSubagentPermissionContract("validate-milestone"), {
351
+ allowed: true,
352
+ allowedSubagents: ["reviewer", "security", "tester"],
353
+ toolsMode: "workflow-only",
354
+ });
355
+
356
+ const validationWrite = shouldBlockPlanningUnit(
357
+ "write",
358
+ ".gsd/milestones/M001/M001-VALIDATION.md",
359
+ process.cwd(),
360
+ "validate-milestone",
361
+ manifest.tools,
362
+ );
363
+ assert.strictEqual(validationWrite.block, true);
364
+ assert.match(validationWrite.reason!, /workflow-only/);
365
+ assert.match(validationWrite.reason!, /direct artifact writes are disabled/);
366
+
367
+ const bash = shouldBlockPlanningUnit(
368
+ "bash",
369
+ "npm test",
370
+ process.cwd(),
371
+ "validate-milestone",
372
+ manifest.tools,
373
+ );
374
+ assert.strictEqual(bash.block, true);
375
+ assert.match(bash.reason!, /bash is not permitted/);
376
+
377
+ const validateTool = shouldBlockPlanningUnit(
378
+ "gsd_validate_milestone",
379
+ "",
380
+ process.cwd(),
381
+ "validate-milestone",
382
+ manifest.tools,
383
+ );
384
+ assert.strictEqual(validateTool.block, false);
385
+
386
+ const reviewer = shouldBlockPlanningUnit(
387
+ "subagent",
388
+ "",
389
+ process.cwd(),
390
+ "validate-milestone",
391
+ manifest.tools,
392
+ ["reviewer"],
393
+ );
394
+ assert.strictEqual(reviewer.block, false, reviewer.reason);
347
395
  });
348
396
 
349
397
  test("#5843: run-uat uses verification tools policy so build/test commands can run", () => {
@@ -7,6 +7,8 @@
7
7
 
8
8
  import test from "node:test";
9
9
  import assert from "node:assert/strict";
10
+ import { existsSync } from "node:fs";
11
+ import { join } from "node:path";
10
12
 
11
13
  import {
12
14
  KNOWN_UNIT_TYPES,
@@ -15,6 +17,8 @@ import {
15
17
  SECTION_CLOSE_GATE_UNIT_TYPES,
16
18
  getUnitDescriptor,
17
19
  getUnitPhaseChain,
20
+ getUnitPromptTemplate,
21
+ getUnitPromptTemplates,
18
22
  } from "../unit-registry.ts";
19
23
  import {
20
24
  AUTO_UNIT_SCOPED_TOOLS,
@@ -96,6 +100,40 @@ const EXPECTED_PHASE_CHAINS: Record<string, string[] | undefined> = {
96
100
  "no-such-unit": undefined,
97
101
  };
98
102
 
103
+ const EXPECTED_DIRECT_PROMPT_TEMPLATES: Record<string, string> = {
104
+ "research-milestone": "research-milestone",
105
+ "plan-milestone": "plan-milestone",
106
+ "validate-milestone": "validate-milestone",
107
+ "complete-milestone": "complete-milestone",
108
+ "research-slice": "research-slice",
109
+ "plan-slice": "plan-slice",
110
+ "refine-slice": "refine-slice",
111
+ "replan-slice": "replan-slice",
112
+ "complete-slice": "complete-slice",
113
+ "reassess-roadmap": "reassess-roadmap",
114
+ "execute-task": "execute-task",
115
+ "reactive-execute": "reactive-execute",
116
+ "run-uat": "run-uat",
117
+ "gate-evaluate": "gate-evaluate",
118
+ "rewrite-docs": "rewrite-docs",
119
+ "workflow-preferences": "guided-workflow-preferences",
120
+ "discuss-project": "guided-discuss-project",
121
+ "discuss-requirements": "guided-discuss-requirements",
122
+ "research-decision": "guided-research-decision",
123
+ "research-project": "guided-research-project",
124
+ };
125
+
126
+ const EXPECTED_UNDECLARED_PROMPT_TEMPLATE_TYPES = [
127
+ "discuss-slice",
128
+ "execute-task-simple",
129
+ "triage-captures",
130
+ "quick-task",
131
+ ];
132
+
133
+ const EXPECTED_CONDITIONAL_PROMPT_TEMPLATES: Record<string, string[]> = {
134
+ "discuss-milestone": ["discuss", "discuss-headless", "guided-discuss-milestone"],
135
+ };
136
+
99
137
  // ─── Derived-view parity ──────────────────────────────────────────────────
100
138
 
101
139
  test("KNOWN_UNIT_TYPES derives exactly the pre-registry list, in order", () => {
@@ -134,6 +172,49 @@ test("phaseChainForUnit matches the pre-registry switch for every known input",
134
172
  }
135
173
  });
136
174
 
175
+ test("direct prompt-template associations live on the Unit Registry", () => {
176
+ for (const [unitType, promptTemplate] of Object.entries(EXPECTED_DIRECT_PROMPT_TEMPLATES)) {
177
+ assert.equal(
178
+ getUnitPromptTemplate(unitType),
179
+ promptTemplate,
180
+ `prompt template for ${unitType}`,
181
+ );
182
+ assert.ok(
183
+ existsSync(join(process.cwd(), "src/resources/extensions/gsd/prompts", `${promptTemplate}.md`)),
184
+ `prompt template file must exist for ${unitType}: ${promptTemplate}`,
185
+ );
186
+ }
187
+
188
+ for (const unitType of EXPECTED_UNDECLARED_PROMPT_TEMPLATE_TYPES) {
189
+ assert.equal(
190
+ getUnitPromptTemplate(unitType),
191
+ undefined,
192
+ `${unitType} prompt association is conditional or not verified yet`,
193
+ );
194
+ }
195
+ });
196
+
197
+ test("conditional prompt-template associations live on the Unit Registry without pretending to be direct", () => {
198
+ for (const [unitType, promptTemplates] of Object.entries(EXPECTED_CONDITIONAL_PROMPT_TEMPLATES)) {
199
+ assert.equal(
200
+ getUnitPromptTemplate(unitType),
201
+ undefined,
202
+ `${unitType} must not expose a single direct prompt template`,
203
+ );
204
+ assert.deepEqual(
205
+ getUnitPromptTemplates(unitType),
206
+ promptTemplates,
207
+ `prompt templates for ${unitType}`,
208
+ );
209
+ for (const promptTemplate of promptTemplates) {
210
+ assert.ok(
211
+ existsSync(join(process.cwd(), "src/resources/extensions/gsd/prompts", `${promptTemplate}.md`)),
212
+ `prompt template file must exist for ${unitType}: ${promptTemplate}`,
213
+ );
214
+ }
215
+ }
216
+ });
217
+
137
218
  test("AUTO_UNIT_SCOPED_TOOLS mirrors each contract's allowed tools", () => {
138
219
  for (const [unitType, contract] of Object.entries(UNIT_TOOL_CONTRACTS)) {
139
220
  assert.deepEqual(AUTO_UNIT_SCOPED_TOOLS[unitType], contract.allowedGsdTools);
@@ -6,7 +6,9 @@ import {
6
6
  formatExecuteTaskRecoveryStatus,
7
7
  inspectExecuteTaskDurability,
8
8
  isInFlightRuntimePhase,
9
+ readUnitHarnessAbort,
9
10
  readUnitRuntimeRecord,
11
+ recordUnitHarnessAbort,
10
12
  writeUnitRuntimeRecord,
11
13
  } from "../unit-runtime.ts";
12
14
  import { closeDatabase, insertMilestone, insertSlice, insertTask, openDatabase } from "../gsd-db.ts";
@@ -41,6 +43,34 @@ console.log("\n=== runtime record write/read/update ===");
41
43
  assert.deepStrictEqual(loaded!.phase, "wrapup-warning-sent", "updated phase readable");
42
44
  }
43
45
 
46
+ console.log("\n=== runtime harness abort preservation and explicit clear ===");
47
+ {
48
+ const startedAt = 3000;
49
+ recordUnitHarnessAbort(base, "gate-evaluate", "M100/S02/gates+Q3", startedAt, {
50
+ kind: "tool-error",
51
+ reason: "Tool execution failed before the unit could complete its gate evaluation.",
52
+ toolName: "browser_click",
53
+ });
54
+
55
+ const preserved = writeUnitRuntimeRecord(base, "gate-evaluate", "M100/S02/gates+Q3", startedAt, {
56
+ phase: "wrapup-warning-sent",
57
+ });
58
+ assert.equal(preserved.harnessAbort?.kind, "tool-error", "ordinary same-run updates preserve harness abort");
59
+
60
+ const cleared = writeUnitRuntimeRecord(base, "gate-evaluate", "M100/S02/gates+Q3", startedAt, {
61
+ phase: "recovered",
62
+ harnessAbort: undefined,
63
+ });
64
+ assert.equal(cleared.harnessAbort, undefined, "explicit clear removes stale harness abort");
65
+ assert.equal(
66
+ readUnitHarnessAbort(base, "gate-evaluate", "M100/S02/gates+Q3", startedAt),
67
+ null,
68
+ "cleared harness abort no longer blocks result saves",
69
+ );
70
+
71
+ clearUnitRuntimeRecord(base, "gate-evaluate", "M100/S02/gates+Q3");
72
+ }
73
+
44
74
  console.log("\n=== execute-task durability inspection ===");
45
75
  {
46
76
  let status = await inspectExecuteTaskDurability(base, "M100/S02/T09");
@@ -186,6 +186,58 @@ test("uok gitops turn action commit creates commit with unit trailer", () => {
186
186
  }
187
187
  });
188
188
 
189
+ test("uok gitops turn action commit defaults to child repositories in parent mode", () => {
190
+ const root = mkdtempSync(join(tmpdir(), "gsd-uok-gitops-parent-commit-"));
191
+ try {
192
+ initRepo(root);
193
+ mkdirSync(join(root, ".gsd"), { recursive: true });
194
+ mkdirSync(join(root, "frontend"), { recursive: true });
195
+ mkdirSync(join(root, "backend"), { recursive: true });
196
+ initRepo(join(root, "frontend"));
197
+ initRepo(join(root, "backend"));
198
+ writeFileSync(join(root, ".gitignore"), "frontend/\nbackend/\n", "utf-8");
199
+ run("git add .gitignore", root);
200
+ run('git commit -m "chore: ignore nested repos"', root);
201
+ writeFileSync(join(root, ".gsd", "PREFERENCES.md"), `---
202
+ version: 1
203
+ workspace:
204
+ mode: parent
205
+ repositories:
206
+ frontend:
207
+ path: frontend
208
+ backend:
209
+ path: backend
210
+ ---
211
+ `, "utf-8");
212
+ run("git add .gsd/PREFERENCES.md", root);
213
+ run('git commit -m "chore: configure parent workspace repos"', root);
214
+
215
+ const rootHeadBefore = run("git rev-parse HEAD", root);
216
+ writeFileSync(join(root, "frontend", "README.md"), "# frontend dirty\n", "utf-8");
217
+ writeFileSync(join(root, "backend", "README.md"), "# backend dirty\n", "utf-8");
218
+
219
+ const result = runTurnGitAction({
220
+ basePath: root,
221
+ action: "commit",
222
+ unitType: "execute-task",
223
+ unitId: "M001/S01/T-parent",
224
+ });
225
+
226
+ assert.equal(result.status, "ok");
227
+ assert.equal(result.commitMessages?.project, undefined);
228
+ assert.equal(typeof result.commitMessages?.frontend, "string");
229
+ assert.equal(typeof result.commitMessages?.backend, "string");
230
+ assert.equal(result.commitMessage, result.commitMessages?.frontend);
231
+ assert.equal(run("git rev-parse HEAD", root), rootHeadBefore);
232
+ assert.equal(run("git status --porcelain", join(root, "frontend")), "");
233
+ assert.equal(run("git status --porcelain", join(root, "backend")), "");
234
+ assert.ok(run("git log -1 --pretty=%B", join(root, "frontend")).includes("GSD-Unit: M001/S01/T-parent"));
235
+ assert.ok(run("git log -1 --pretty=%B", join(root, "backend")).includes("GSD-Unit: M001/S01/T-parent"));
236
+ } finally {
237
+ rmSync(root, { recursive: true, force: true });
238
+ }
239
+ });
240
+
189
241
  test("uok gitops turn action commit reuses the collected dirty status", () => {
190
242
  const repo = makeRepo();
191
243
  const wrapperDir = mkdtempSync(join(tmpdir(), "gsd-uok-git-wrapper-"));
@@ -23,7 +23,7 @@ import {
23
23
 
24
24
  function makeProjectDir(label = "gsd-vsp-"): string {
25
25
  const dir = realpathSync(mkdtempSync(join(tmpdir(), label)));
26
- mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
26
+ mkdirSync(join(dir, ".gsd", "phases", "01-m001"), { recursive: true });
27
27
  return dir;
28
28
  }
29
29
 
@@ -236,4 +236,56 @@ describe("validator-scope-parity: scope uses canonical projectRoot not worktree
236
236
  "verifyExpectedArtifactForScope should return false when artifact is absent",
237
237
  );
238
238
  });
239
+
240
+ test("verifyExpectedArtifactForScope rejects zero-slice scoped plan-milestone roadmaps", () => {
241
+ const ws = createWorkspace(base);
242
+ const scope = scopeMilestone(ws, "M001");
243
+
244
+ writeFileSync(scope.roadmapFile(), [
245
+ "# M001: Placeholder",
246
+ "",
247
+ "## Slices",
248
+ "",
249
+ "_TBD_",
250
+ "",
251
+ ].join("\n"));
252
+
253
+ const ready = verifyExpectedArtifactForScope(scope, "plan-milestone", "M001");
254
+ assert.equal(
255
+ ready,
256
+ false,
257
+ "scoped plan-milestone verification must parse roadmap content, not only check existence",
258
+ );
259
+ });
260
+
261
+ test("verifyExpectedArtifactForScope verifies the scoped plan-milestone roadmap path", () => {
262
+ const ws = createWorkspace(base);
263
+ const realScope = scopeMilestone(ws, "M001");
264
+ const scopedRoadmap = join(base, "scoped-M001-ROADMAP.md");
265
+ const scope = {
266
+ ...realScope,
267
+ roadmapFile: () => scopedRoadmap,
268
+ };
269
+
270
+ writeFileSync(scopedRoadmap, [
271
+ "# M001: Scoped roadmap",
272
+ "",
273
+ "## Slices",
274
+ "",
275
+ "- [ ] **S01: First slice** `risk:low` `depends:[]`",
276
+ " > After this: a real slice exists.",
277
+ "",
278
+ ].join("\n"));
279
+
280
+ assert.equal(
281
+ resolveExpectedArtifactPathForScope(scope, "plan-milestone", "M001"),
282
+ scopedRoadmap,
283
+ "scoped plan-milestone artifact path must come from scope.roadmapFile()",
284
+ );
285
+ assert.equal(
286
+ verifyExpectedArtifactForScope(scope, "plan-milestone", "M001"),
287
+ true,
288
+ "scoped plan-milestone verification must read the roadmap from scope.roadmapFile()",
289
+ );
290
+ });
239
291
  });