@opengsd/gsd-pi 1.3.0-dev.65546769 → 1.3.0-dev.738160b9

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 (488) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +17 -4
  3. package/dist/headless-answers.js +1 -1
  4. package/dist/headless-ui.d.ts +1 -1
  5. package/dist/headless-ui.js +1 -1
  6. package/dist/headless.js +1 -1
  7. package/dist/resources/.managed-resources-content-hash +1 -1
  8. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +11 -2
  10. package/dist/resources/extensions/google-cli/stream-adapter.js +82 -15
  11. package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
  12. package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -3
  13. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  14. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  15. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  16. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  17. package/dist/resources/extensions/gsd/auto-dispatch.js +34 -20
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
  19. package/dist/resources/extensions/gsd/auto-prompts.js +29 -14
  20. package/dist/resources/extensions/gsd/auto-recovery.js +9 -510
  21. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  22. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
  23. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  24. package/dist/resources/extensions/gsd/auto.js +19 -10
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -13
  26. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  27. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +11 -5
  28. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -0
  29. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  30. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +41 -21
  31. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -19
  32. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +96 -10
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  34. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
  35. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  36. package/dist/resources/extensions/gsd/commands-context.js +19 -1
  37. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +17 -11
  38. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  39. package/dist/resources/extensions/gsd/commands-worktree.js +12 -10
  40. package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -3
  41. package/dist/resources/extensions/gsd/db/engine.js +4 -1
  42. package/dist/resources/extensions/gsd/db/queries.js +60 -0
  43. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  44. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  45. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  46. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  47. package/dist/resources/extensions/gsd/doctor-engine-checks.js +192 -4
  48. package/dist/resources/extensions/gsd/doctor-providers.js +92 -8
  49. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
  50. package/dist/resources/extensions/gsd/exec-sandbox.js +53 -11
  51. package/dist/resources/extensions/gsd/flat-phase-migration.js +45 -0
  52. package/dist/resources/extensions/gsd/forensics.js +2 -32
  53. package/dist/resources/extensions/gsd/git-service.js +61 -4
  54. package/dist/resources/extensions/gsd/gitignore.js +4 -1
  55. package/dist/resources/extensions/gsd/guided-flow-queue.js +66 -5
  56. package/dist/resources/extensions/gsd/health-widget.js +55 -29
  57. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  58. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  59. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  60. package/dist/resources/extensions/gsd/markdown-renderer.js +8 -9
  61. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  62. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +44 -21
  63. package/dist/resources/extensions/gsd/metrics.js +4 -4
  64. package/dist/resources/extensions/gsd/migrate-external.js +11 -2
  65. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  66. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  67. package/dist/resources/extensions/gsd/milestone-implementation-evidence.js +26 -20
  68. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  69. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  70. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  71. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  72. package/dist/resources/extensions/gsd/quick.js +45 -2
  73. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  74. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  75. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  76. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  77. package/dist/resources/extensions/gsd/session-forensics.js +11 -1
  78. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  79. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  80. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  81. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  82. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  83. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  84. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +45 -2
  85. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  86. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  87. package/dist/resources/extensions/gsd/state.js +12 -611
  88. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  89. package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -2
  90. package/dist/resources/extensions/gsd/tools/complete-task.js +43 -14
  91. package/dist/resources/extensions/gsd/tools/exec-tool.js +7 -2
  92. package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
  93. package/dist/resources/extensions/gsd/tools/plan-task.js +28 -5
  94. package/dist/resources/extensions/gsd/undo.js +43 -6
  95. package/dist/resources/extensions/gsd/unit-context-composer.js +23 -7
  96. package/dist/resources/extensions/gsd/unit-registry.js +36 -6
  97. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +33 -3
  98. package/dist/resources/extensions/gsd/validation-block-guard.js +9 -4
  99. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  100. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  101. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  102. package/dist/resources/extensions/gsd/workspace-git-preflight.js +30 -1
  103. package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
  104. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  105. package/dist/web/standalone/.next/BUILD_ID +1 -1
  106. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  107. package/dist/web/standalone/.next/build-manifest.json +3 -3
  108. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  109. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  110. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/index.html +1 -1
  130. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  131. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  132. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  138. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  139. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  142. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  143. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  144. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  145. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  146. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  147. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  148. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  149. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  150. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  151. package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
  152. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  153. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  154. package/package.json +1 -1
  155. package/packages/cloud-mcp-gateway/package.json +2 -2
  156. package/packages/contracts/dist/workflow.d.ts +1 -0
  157. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  158. package/packages/contracts/dist/workflow.js +2 -0
  159. package/packages/contracts/dist/workflow.js.map +1 -1
  160. package/packages/contracts/package.json +1 -1
  161. package/packages/daemon/package.json +4 -4
  162. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  163. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  164. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  165. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  166. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  167. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  168. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  169. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  170. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  171. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  172. package/packages/gsd-agent-core/dist/index.js +2 -0
  173. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  174. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  175. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  176. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  177. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  178. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  179. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  180. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  181. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  182. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  183. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  184. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  185. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  186. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  187. package/packages/gsd-agent-core/package.json +5 -5
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  193. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  195. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  197. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  198. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -829
  199. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  201. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  202. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  203. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  204. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  205. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  206. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  207. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  208. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  209. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  210. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
  211. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  212. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  213. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  214. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  215. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  216. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  217. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  218. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  219. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  220. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  221. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  222. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  223. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  224. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  225. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  226. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  227. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  228. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  229. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  230. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  233. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  234. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  235. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  236. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  237. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +23 -5
  239. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  240. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  242. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  243. package/packages/gsd-agent-modes/package.json +7 -7
  244. package/packages/mcp-server/README.md +1 -1
  245. package/packages/mcp-server/dist/server.d.ts +1 -1
  246. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  247. package/packages/mcp-server/dist/server.js +3 -3
  248. package/packages/mcp-server/dist/server.js.map +1 -1
  249. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  250. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  251. package/packages/mcp-server/dist/workflow-tools.js +35 -21
  252. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  253. package/packages/mcp-server/package.json +4 -4
  254. package/packages/native/package.json +1 -1
  255. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  256. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  257. package/packages/pi-agent-core/package.json +1 -1
  258. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  259. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/models.generated.js +38 -0
  261. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  262. package/packages/pi-ai/package.json +1 -1
  263. package/packages/pi-coding-agent/README.md +3 -2
  264. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  265. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  266. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  267. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  268. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  269. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  270. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  271. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  272. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  273. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  274. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  275. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  276. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  277. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  278. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  279. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  280. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  281. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  283. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  285. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  286. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  287. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  290. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  291. package/packages/pi-coding-agent/package.json +7 -7
  292. package/packages/pi-tui/package.json +2 -2
  293. package/packages/rpc-client/package.json +2 -2
  294. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  295. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  296. package/pkg/dist/theme/theme-schema.js +1 -1
  297. package/pkg/dist/theme/theme-schema.js.map +1 -1
  298. package/pkg/dist/theme/theme.d.ts.map +1 -1
  299. package/pkg/dist/theme/theme.js +11 -7
  300. package/pkg/dist/theme/theme.js.map +1 -1
  301. package/pkg/package.json +1 -1
  302. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  303. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +20 -2
  304. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
  305. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +80 -0
  306. package/src/resources/extensions/google-cli/stream-adapter.ts +106 -19
  307. package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
  308. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  309. package/src/resources/extensions/gsd/auto/orchestrator.ts +25 -11
  310. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  311. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  312. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  313. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  314. package/src/resources/extensions/gsd/auto-dispatch.ts +35 -24
  315. package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
  316. package/src/resources/extensions/gsd/auto-prompts.ts +41 -15
  317. package/src/resources/extensions/gsd/auto-recovery.ts +13 -511
  318. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  319. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
  320. package/src/resources/extensions/gsd/auto-verification.ts +5 -1
  321. package/src/resources/extensions/gsd/auto.ts +23 -8
  322. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -12
  323. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  324. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +11 -5
  325. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -0
  326. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  327. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +52 -21
  328. package/src/resources/extensions/gsd/bootstrap/system-context.ts +52 -18
  329. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +104 -10
  330. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  331. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
  332. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  333. package/src/resources/extensions/gsd/commands-context.ts +18 -1
  334. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -10
  335. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  336. package/src/resources/extensions/gsd/commands-worktree.ts +12 -10
  337. package/src/resources/extensions/gsd/dashboard-overlay.ts +32 -3
  338. package/src/resources/extensions/gsd/db/engine.ts +8 -1
  339. package/src/resources/extensions/gsd/db/queries.ts +79 -0
  340. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  341. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  342. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  343. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  344. package/src/resources/extensions/gsd/doctor-engine-checks.ts +233 -5
  345. package/src/resources/extensions/gsd/doctor-providers.ts +103 -9
  346. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
  347. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  348. package/src/resources/extensions/gsd/exec-sandbox.ts +56 -11
  349. package/src/resources/extensions/gsd/flat-phase-migration.ts +44 -0
  350. package/src/resources/extensions/gsd/forensics.ts +2 -33
  351. package/src/resources/extensions/gsd/git-service.ts +69 -5
  352. package/src/resources/extensions/gsd/gitignore.ts +4 -1
  353. package/src/resources/extensions/gsd/guided-flow-queue.ts +89 -4
  354. package/src/resources/extensions/gsd/health-widget.ts +69 -32
  355. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  356. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  357. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  358. package/src/resources/extensions/gsd/markdown-renderer.ts +8 -11
  359. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  360. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +51 -19
  361. package/src/resources/extensions/gsd/metrics.ts +4 -4
  362. package/src/resources/extensions/gsd/migrate-external.ts +8 -2
  363. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  364. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  365. package/src/resources/extensions/gsd/milestone-implementation-evidence.ts +35 -21
  366. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  367. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  368. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  369. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  370. package/src/resources/extensions/gsd/quick.ts +43 -2
  371. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  372. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  373. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  374. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  375. package/src/resources/extensions/gsd/session-forensics.ts +11 -1
  376. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  377. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  378. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  379. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  380. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  381. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  382. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +81 -7
  383. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  384. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  385. package/src/resources/extensions/gsd/state.ts +32 -732
  386. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  387. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  388. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  389. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  390. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  391. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +146 -1
  392. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  393. package/src/resources/extensions/gsd/tests/commands-context.test.ts +26 -0
  394. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  395. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +80 -0
  396. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  397. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
  398. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +11 -0
  399. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +48 -8
  400. package/src/resources/extensions/gsd/tests/complete-task.test.ts +75 -0
  401. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +55 -2
  402. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  403. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  404. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  405. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
  406. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +26 -1
  407. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +70 -2
  408. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +107 -0
  409. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
  410. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +38 -0
  411. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  412. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +45 -1
  413. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  414. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +37 -2
  415. package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +88 -0
  416. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  417. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +42 -0
  418. package/src/resources/extensions/gsd/tests/health-widget.test.ts +268 -3
  419. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +130 -3
  420. package/src/resources/extensions/gsd/tests/integration/queue-active-milestone-context-budget.test.ts +93 -0
  421. package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +56 -9
  422. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  423. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  424. package/src/resources/extensions/gsd/tests/knowledge-cold-start.test.ts +14 -0
  425. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +78 -0
  426. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  427. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  428. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  429. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  430. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  431. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  432. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +43 -1
  433. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  434. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +26 -0
  435. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  436. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +1 -1
  437. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +10 -0
  438. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
  439. package/src/resources/extensions/gsd/tests/plan-task.test.ts +44 -1
  440. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  441. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +54 -1
  442. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  443. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  444. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
  445. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +195 -1
  446. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +185 -0
  447. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +87 -0
  448. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +103 -0
  449. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  450. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  451. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
  452. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  453. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +208 -0
  454. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +32 -3
  455. package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
  456. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +193 -14
  457. package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +25 -0
  458. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +38 -0
  459. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +79 -0
  460. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  461. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +66 -0
  462. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  463. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
  464. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
  465. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +6 -5
  466. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +151 -2
  467. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  468. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  469. package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
  470. package/src/resources/extensions/gsd/tools/complete-task.ts +53 -15
  471. package/src/resources/extensions/gsd/tools/exec-tool.ts +7 -3
  472. package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
  473. package/src/resources/extensions/gsd/tools/plan-task.ts +30 -5
  474. package/src/resources/extensions/gsd/undo.ts +47 -6
  475. package/src/resources/extensions/gsd/unit-context-composer.ts +33 -7
  476. package/src/resources/extensions/gsd/unit-registry.ts +36 -6
  477. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +41 -5
  478. package/src/resources/extensions/gsd/validation-block-guard.ts +13 -7
  479. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  480. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  481. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  482. package/src/resources/extensions/gsd/workspace-git-preflight.ts +31 -0
  483. package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
  484. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  485. package/dist/web/standalone/.next/static/chunks/796.e0bdc932325d7e03.js +0 -10
  486. package/dist/web/standalone/.next/static/chunks/webpack-f46ea08200a0227e.js +0 -1
  487. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_buildManifest.js +0 -0
  488. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_ssgManifest.js +0 -0
@@ -26,16 +26,78 @@ function _isAlreadyRestoredApplyError(err) {
26
26
  return /already exists, no checkout/i.test(message);
27
27
  }
28
28
  export { _isAlreadyRestoredApplyError };
29
+ function gitOutput(basePath, args) {
30
+ return execFileSync("git", args, {
31
+ cwd: basePath,
32
+ stdio: ["ignore", "pipe", "pipe"],
33
+ encoding: "utf-8",
34
+ env: GIT_NO_PROMPT_ENV,
35
+ });
36
+ }
37
+ function listStashUntrackedPaths(basePath, stashRef) {
38
+ try {
39
+ return gitOutput(basePath, ["ls-tree", "-r", "-z", "--name-only", `${stashRef}^3`]).split("\0").filter(Boolean);
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ function listStashTrackedPaths(basePath, stashRef) {
46
+ try {
47
+ return gitOutput(basePath, ["diff", "--name-only", "-z", `${stashRef}^1`, stashRef]).split("\0").filter(Boolean);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ function readWorkingTreeStatus(basePath) {
54
+ try {
55
+ return gitOutput(basePath, ["status", "--porcelain", "-z", "--untracked-files=all"])
56
+ .split("\0")
57
+ .filter(Boolean)
58
+ .map((entry) => ({ code: entry.slice(0, 2), path: entry.slice(3) }));
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ function isAlreadyRestoredUntrackedStatus(basePath, stashRef, statusEntries) {
65
+ if (statusEntries.length === 0 || statusEntries.some((entry) => entry.code !== "??"))
66
+ return false;
67
+ const stashTrackedPaths = listStashTrackedPaths(basePath, stashRef);
68
+ if (!stashTrackedPaths || stashTrackedPaths.length > 0)
69
+ return false;
70
+ const stashUntrackedPaths = listStashUntrackedPaths(basePath, stashRef);
71
+ if (!stashUntrackedPaths || stashUntrackedPaths.length === 0)
72
+ return false;
73
+ const stashUntrackedPathSet = new Set(stashUntrackedPaths);
74
+ const workingTreeUntrackedPathSet = new Set(statusEntries.map((entry) => entry.path));
75
+ // "Already restored" requires the working tree's untracked paths to match the
76
+ // stash's untracked paths exactly, in BOTH directions:
77
+ // 1. every current untracked path comes from the stash (no unexplained user
78
+ // work that an apply would clobber), AND
79
+ // 2. every stash untracked path is already present in the working tree.
80
+ // Without (2), a partial restore (where only some stash files were recovered)
81
+ // would be misread as fully restored: the audit would no-op without applying
82
+ // or warning, leaving the remaining pre-merge files missing.
83
+ return (statusEntries.every((entry) => stashUntrackedPathSet.has(entry.path)) &&
84
+ stashUntrackedPaths.every((path) => workingTreeUntrackedPathSet.has(path)));
85
+ }
86
+ function manualApplyWarning(stashRef, milestoneId, reason) {
87
+ return (`Pre-merge stash ${stashRef} for milestone ${milestoneId} not auto-applied: ${reason}; ` +
88
+ `run \`git stash apply ${stashRef}\` manually to restore your pre-merge changes.`);
89
+ }
29
90
  /**
30
91
  * Audit `git stash list` for orphaned `gsd-preflight-stash:M00x:*` entries.
31
92
  *
32
93
  * The matching merge code in `phases.ts` previously skipped the postflight
33
94
  * pop whenever `mergeAndExit` threw, leaking the user's pre-merge working
34
- * tree into the stash list. For every preflight-stash entry whose milestone
35
- * is now complete (per the supplied callback), `git stash apply` is invoked
95
+ * tree into the stash list. Completed-milestone stashes are only auto-applied
96
+ * when the working tree is clean and the stash does not modify tracked files.
97
+ * Dirty trees and tracked-file stashes are left untouched with a manual
98
+ * recovery warning. When auto-apply is safe, `git stash apply` is invoked —
36
99
  * NOT `pop`. The stash entry stays in the list so the user retains a backup
37
- * if the apply produces unexpected merge results. Idempotent across repeated
38
- * startup runs.
100
+ * if the apply produces unexpected merge results.
39
101
  *
40
102
  * Failures are best-effort: a list error (no repo, git unavailable) returns
41
103
  * an empty result. An apply error becomes a warning the user sees alongside
@@ -45,12 +107,7 @@ export function auditOrphanedPreflightStashes(basePath, isMilestoneComplete) {
45
107
  const result = { applied: [], warnings: [] };
46
108
  let listOutput;
47
109
  try {
48
- listOutput = execFileSync("git", ["stash", "list", "--format=%gd%x00%s"], {
49
- cwd: basePath,
50
- stdio: ["ignore", "pipe", "pipe"],
51
- encoding: "utf-8",
52
- env: GIT_NO_PROMPT_ENV,
53
- });
110
+ listOutput = gitOutput(basePath, ["stash", "list", "--format=%gd%x00%s"]);
54
111
  }
55
112
  catch {
56
113
  return result;
@@ -78,13 +135,32 @@ export function auditOrphanedPreflightStashes(basePath, isMilestoneComplete) {
78
135
  }
79
136
  if (!complete)
80
137
  continue;
138
+ const statusEntries = readWorkingTreeStatus(basePath);
139
+ if (!statusEntries) {
140
+ result.warnings.push(manualApplyWarning(ref, milestoneId, "could not verify working tree status"));
141
+ continue;
142
+ }
143
+ if (statusEntries.length > 0) {
144
+ if (isAlreadyRestoredUntrackedStatus(basePath, ref, statusEntries))
145
+ continue;
146
+ result.warnings.push(manualApplyWarning(ref, milestoneId, "working tree not clean"));
147
+ continue;
148
+ }
149
+ const trackedPaths = listStashTrackedPaths(basePath, ref);
150
+ if (trackedPaths === null) {
151
+ result.warnings.push(manualApplyWarning(ref, milestoneId, "could not inspect tracked paths in stash"));
152
+ continue;
153
+ }
154
+ if (trackedPaths.length > 0) {
155
+ // A retained tracked-file stash has no durable marker showing whether a
156
+ // clean tree needs first recovery or would be re-mutated by an old backup.
157
+ const preview = trackedPaths.slice(0, 5).join(", ");
158
+ const suffix = trackedPaths.length > 5 ? `, and ${trackedPaths.length - 5} more` : "";
159
+ result.warnings.push(manualApplyWarning(ref, milestoneId, `stash modifies tracked files (${preview}${suffix})`));
160
+ continue;
161
+ }
81
162
  try {
82
- execFileSync("git", ["stash", "apply", "--quiet", ref], {
83
- cwd: basePath,
84
- stdio: ["ignore", "pipe", "pipe"],
85
- encoding: "utf-8",
86
- env: GIT_NO_PROMPT_ENV,
87
- });
163
+ gitOutput(basePath, ["stash", "apply", "--quiet", ref]);
88
164
  result.applied.push({ milestoneId, stashRef: ref });
89
165
  }
90
166
  catch (err) {
@@ -16,18 +16,20 @@ You are running the GSD **code-review** workflow — review source files changed
16
16
 
17
17
  1. **Determine the file set.** Use the explicit `--files` list if provided. Otherwise derive the changed source files from the active slice's recent commits / SUMMARY, or fall back to the git diff against the base branch. Exclude `.gsd/`, lockfiles, generated/vendored code, and docs unless `--files` names them.
18
18
 
19
- 2. **Review each file** at the requested depth:
19
+ 2. **Gather diff-first context.** Run `git diff` for the file set (or the relevant commit range) and use that as the primary review evidence. Use `read` only when the diff is insufficient — new/untracked files, truncated hunks, or missing surrounding context needed for a finding. Do **not** read every changed file when the diff already covers the edits. If the Tool Call Loop Guard blocks a tool, stop calling tools for the rest of this turn and continue in text.
20
+
21
+ 3. **Review at the requested depth:**
20
22
  - **quick** — bugs, security, and correctness only.
21
23
  - **standard** (default) — quick + maintainability, error handling, edge cases.
22
24
  - **deep** — standard + performance, concurrency, API design, test coverage gaps.
23
25
 
24
26
  Ground every finding in the actual code with file path + line reference. Categorize each by severity (critical / warning / nit) and type (bug, security, quality, performance).
25
27
 
26
- 3. **Write the review.** Produce `.gsd/reviews/{{reviewId}}-REVIEW.md` with the findings table and per-finding detail (location, issue, suggested fix).
28
+ 4. **Write the review.** Produce `.gsd/reviews/{{reviewId}}-REVIEW.md` with the findings table and per-finding detail (location, issue, suggested fix).
27
29
 
28
- 4. **Present results.** Summarize counts by severity and list the critical findings first.
30
+ 5. **Present results.** Summarize counts by severity and list the critical findings first.
29
31
 
30
- 5. **Fix mode** (only when `--fix` is set): for each finding that is safely auto-fixable (deterministic, no behavior change beyond the fix), apply it. After each fix batch, run the project's tests. Commit atomically with the finding IDs referenced in the message. Do not auto-apply findings that are ambiguous or that change public behavior — surface those for a human decision instead.
32
+ 6. **Fix mode** (only when `--fix` is set): for each finding that is safely auto-fixable (deterministic, no behavior change beyond the fix), apply it. After each fix batch, run the project's tests. Commit atomically with the finding IDs referenced in the message. Do not auto-apply findings that are ambiguous or that change public behavior — surface those for a human decision instead.
31
33
 
32
34
  ## Success criteria
33
35
 
@@ -104,8 +104,8 @@ If the preference is off, ignore this section and plan every slice fully.
104
104
 
105
105
  If the roadmap has one slice, also plan S01 and its tasks inline:
106
106
 
107
- 1. After `gsd_plan_milestone` returns, call `gsd_plan_slice` for S01 with full task breakdown.
108
- 2. Use inlined **Slice Plan** and **Task Plan** templates for tool parameters.
107
+ 1. After `gsd_plan_milestone` returns, call `gsd_plan_slice` for S01 with slice metadata only; omit `tasks`.
108
+ 2. Then call `gsd_plan_task` once per S01 task. Use inlined **Slice Plan** and **Task Plan** templates for tool parameters.
109
109
  3. Keep simple slices lean. Omit Proof Level, Integration Closure, and Observability if all would be "none"; executable verification commands are enough.
110
110
 
111
111
  Do **not** write plan files manually; use DB-backed tools so state stays consistent.
@@ -45,8 +45,8 @@ If slice research is inlined, trust its architectural findings, but verify every
45
45
  6. Include Threat Surface (Q3), Requirement Impact (Q4), proof level, observability, integration closure, Failure Modes (Q5), Load Profile (Q6), and Negative Tests (Q7) only where applicable.
46
46
  7. Right-size tasks. Simple slices can be one task; split only when context, ownership, or verification boundaries justify it.
47
47
  8. Task `verify` commands must be safe, simple commands. Do not use shell pipes, redirects, semicolons, backticks, command substitution, output trimming, or grep regex alternation with `|`. If multiple checks are needed, create a small test file and run it with `node --test` or a package test script, or use separate simple commands joined only with `&&`. For absence checks, verify a pattern does not exist with `! grep -q 'pattern' file` or `! rg -q 'pattern' file`; do not use `grep -c` or `rg -c` to assert zero matches because count commands exit 1 when they find zero matches, and the verification gate treats that as failure.
48
- 9. Each task needs the exact `gsd_plan_slice.tasks[]` shape: `taskId`, `title`, `description`, `estimate`, `files`, `verify`, `inputs`, `expectedOutput`, and optional `observabilityImpact`. `description` should contain the Why / Do / Done-when narrative. `files`, `inputs`, and `expectedOutput` must be JSON arrays of strings, even when there is only one path (for example, `"inputs": ["src/index.ts"]`, never `"inputs": "src/index.ts"`). Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands. **`expectedOutput` must only list files the task actually creates or overwrites on disk.** Do NOT include files the task merely reads, verifies, tests, or describes — those belong in `inputs`, `verify`, `description`, or slice success criteria. If a task is a pure verification or test task that produces no new files, `expectedOutput` must be `[]`; if it writes a test-result log or assertion output file, list only that concrete file path. A file that does not yet exist on disk and is needed as an `input` must be produced by an earlier task's `expectedOutput` — if no prior task creates it, add a task before this one that does. Never list GSD planning artifacts — anything under `.gsd/`, `.planning/`, or `.audits/`, or artifact names like `M001-CONTEXT.md` / `S01-PLAN.md` — in `inputs`, `files`, or `expectedOutput`: their content is preloaded as context, and they are written by workflow tools, not by tasks.
49
- 10. Persist with `gsd_plan_slice` using `milestoneId`, `sliceId`, `goal`, optional `successCriteria`/`proofLevel`/`integrationClosure`/`observabilityImpact`, and `tasks`. `gsd_plan_slice` handles task persistence transactionally and renders `{{outputPath}}` plus task plans; do not call `gsd_plan_task`. The DB-backed tool is the canonical write path. Do **not** rely on direct `PLAN.md` writes as the source of truth.
48
+ 9. Each task persisted with `gsd_plan_task` needs the exact shape: `milestoneId`, `sliceId`, `taskId`, `title`, `description`, `estimate`, `files`, `verify`, `inputs`, `expectedOutput`, and optional `observabilityImpact`. `description` should contain the Why / Do / Done-when narrative. Any npm package name in a task description's install/add instructions (`npm install`, `yarn add`, `pnpm add`) or in `require('...')` or `import ... from '...'` code examples is subject to pre-execution registry validation; reference only packages that exist on the public npm registry, and remove or correct any package name that is not real. `files`, `inputs`, and `expectedOutput` must be JSON arrays of strings, even when there is only one path (for example, `"inputs": ["src/index.ts"]`, never `"inputs": "src/index.ts"`). Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands. **`expectedOutput` must only list files the task actually creates or overwrites on disk.** Do NOT include files the task merely reads, verifies, tests, or describes — those belong in `inputs`, `verify`, `description`, or slice success criteria. If a task is a pure verification or test task that produces no new files, `expectedOutput` must be `[]`; if it writes a test-result log or assertion output file, list only that concrete file path. A file that does not yet exist on disk and is needed as an `input` must be produced by an earlier task's `expectedOutput` — if no prior task creates it, add a task before this one that does. Never list GSD planning artifacts — anything under `.gsd/`, `.planning/`, or `.audits/`, or artifact names like `M001-CONTEXT.md` / `S01-PLAN.md` — in `inputs`, `files`, or `expectedOutput`: their content is preloaded as context, and they are written by workflow tools, not by tasks.
49
+ 10. Persist incrementally through DB-backed tools. First call `gsd_plan_slice` with `milestoneId`, `sliceId`, `goal`, and optional `successCriteria`/`proofLevel`/`integrationClosure`/`observabilityImpact`; omit `tasks` for this metadata call. Then call `gsd_plan_task` once per task, using the task shape above. Each successful tool call saves progress and re-renders `{{outputPath}}` from DB. The DB-backed tools are the canonical write path. Do **not** rely on direct `PLAN.md` writes as the source of truth.
50
50
  11. Self-audit before finishing: goal/demo closure, requirement coverage, deliverable coverage audit (cross-check every file listed in CONTEXT.md `## Scope` / `### In Scope` against task `files` or `expectedOutput`), locked decisions, concrete paths, dependency order, wiring, scope size, proof truthfulness, feature completeness, and quality gates. Quality gates: non-trivial slices/tasks include specific Q3-Q7 coverage where applicable.
51
51
  12. If planning creates structural decisions, call `gsd_decision_save` for each; the tool persists the decision and regenerates `.gsd/DECISIONS.md`.
52
52
  13. {{commitInstruction}}
@@ -55,6 +55,6 @@ The slice directory already exists. Do not mkdir.
55
55
 
56
56
  **Autonomous execution:** no human is available. Do not call `ask_user_questions` or `secure_env_collect`; make reasonable assumptions and document them.
57
57
 
58
- **You MUST call `gsd_plan_slice` to persist planning state before finishing, unless the stale-path safety rule above stops the unit before safe planning can occur.**
58
+ **You MUST call `gsd_plan_slice` and then `gsd_plan_task` once for each planned task before finishing, unless the stale-path safety rule above stops the unit before safe planning can occur.**
59
59
 
60
60
  When done, say: "Slice {{sliceId}} planned." Say this exactly once — if you already said it in a prior message, do not repeat it.
@@ -8,8 +8,8 @@
8
8
  * Quick tasks live in `.gsd/quick/` and are tracked in STATE.md's
9
9
  * "Quick Tasks Completed" table.
10
10
  */
11
- import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
12
- import { isAbsolute, join, relative } from "node:path";
11
+ import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
12
+ import { isAbsolute, join, relative, resolve } from "node:path";
13
13
  import { QUICK_BRANCH_RE } from "./branch-patterns.js";
14
14
  import { loadPrompt } from "./prompt-loader.js";
15
15
  import { gsdRoot } from "./paths.js";
@@ -19,6 +19,7 @@ import { nativeBranchExists, nativeDetectMainBranch, nativeDiffNumstat } from ".
19
19
  import { nativeHasStagedChanges } from "./native-git-bridge.js";
20
20
  import { resolveUokFlags } from "./uok/flags.js";
21
21
  let pendingQuickReturn = null;
22
+ const pendingQuickReturnMisses = new Map();
22
23
  // ─── Quick Task Helpers ───────────────────────────────────────────────────────
23
24
  /**
24
25
  * Generate a URL-friendly slug from a description.
@@ -169,11 +170,36 @@ export function buildQuickCommitInstruction(basePath, root) {
169
170
  " - Quick tasks run outside the auto-mode lifecycle — there is no system auto-commit, so commit directly here.",
170
171
  ].join("\n");
171
172
  }
173
+ function readHeadBranchName(basePath) {
174
+ try {
175
+ const gitPath = join(basePath, ".git");
176
+ if (!existsSync(gitPath))
177
+ return null;
178
+ let headPath;
179
+ if (lstatSync(gitPath).isDirectory()) {
180
+ headPath = join(gitPath, "HEAD");
181
+ }
182
+ else {
183
+ const gitFile = readFileSync(gitPath, "utf-8").trim();
184
+ if (!gitFile.startsWith("gitdir: "))
185
+ return null;
186
+ headPath = join(resolve(basePath, gitFile.slice("gitdir: ".length)), "HEAD");
187
+ }
188
+ const head = readFileSync(headPath, "utf-8").trim();
189
+ if (!head.startsWith("ref: refs/heads/"))
190
+ return null;
191
+ return head.slice("ref: refs/heads/".length);
192
+ }
193
+ catch {
194
+ return null;
195
+ }
196
+ }
172
197
  function quickReturnStatePath(basePath) {
173
198
  return join(gsdRoot(basePath), "runtime", "quick-return.json");
174
199
  }
175
200
  function persistPendingReturn(state) {
176
201
  pendingQuickReturn = state;
202
+ pendingQuickReturnMisses.delete(state.basePath);
177
203
  mkdirSync(join(gsdRoot(state.basePath), "runtime"), { recursive: true });
178
204
  writeFileSync(quickReturnStatePath(state.basePath), JSON.stringify(state) + "\n", "utf-8");
179
205
  }
@@ -181,6 +207,13 @@ function readPendingReturn(basePath) {
181
207
  if (pendingQuickReturn && pendingQuickReturn.basePath === basePath) {
182
208
  return pendingQuickReturn;
183
209
  }
210
+ if (pendingQuickReturnMisses.has(basePath)) {
211
+ const statePath = quickReturnStatePath(basePath);
212
+ if (!existsSync(statePath) && readHeadBranchName(basePath) === pendingQuickReturnMisses.get(basePath)) {
213
+ return null;
214
+ }
215
+ pendingQuickReturnMisses.delete(basePath);
216
+ }
184
217
  try {
185
218
  const raw = readFileSync(quickReturnStatePath(basePath), "utf-8");
186
219
  const parsed = JSON.parse(raw);
@@ -191,6 +224,7 @@ function readPendingReturn(basePath) {
191
224
  && typeof parsed.slug === "string"
192
225
  && typeof parsed.description === "string") {
193
226
  pendingQuickReturn = parsed;
227
+ pendingQuickReturnMisses.delete(basePath);
194
228
  return pendingQuickReturn;
195
229
  }
196
230
  }
@@ -200,14 +234,23 @@ function readPendingReturn(basePath) {
200
234
  const inferred = inferQuickReturnFromBranch(basePath);
201
235
  if (inferred) {
202
236
  pendingQuickReturn = inferred;
237
+ pendingQuickReturnMisses.delete(basePath);
203
238
  return inferred;
204
239
  }
240
+ const branchAtMiss = readHeadBranchName(basePath);
241
+ if (branchAtMiss) {
242
+ pendingQuickReturnMisses.set(basePath, branchAtMiss);
243
+ }
205
244
  return null;
206
245
  }
207
246
  function clearPendingReturn(basePath) {
208
247
  if (pendingQuickReturn?.basePath === basePath) {
209
248
  pendingQuickReturn = null;
210
249
  }
250
+ const branchAtMiss = readHeadBranchName(basePath);
251
+ if (branchAtMiss) {
252
+ pendingQuickReturnMisses.set(basePath, branchAtMiss);
253
+ }
211
254
  rmSync(quickReturnStatePath(basePath), { force: true });
212
255
  }
213
256
  function hasStagedChanges(basePath) {
@@ -4,9 +4,15 @@ import { execFileSync } from "node:child_process";
4
4
  import { createHash } from "node:crypto";
5
5
  import { existsSync, readFileSync, statSync } from "node:fs";
6
6
  import { join } from "node:path";
7
+ import { GSD_RUNTIME_PATTERNS } from "./gitignore.js";
7
8
  const MAX_SYNC_FINGERPRINT_BYTES = 1_500_000_000;
9
+ const ROOT_RUNTIME_PATH_PREFIXES = Array.from(new Set(GSD_RUNTIME_PATTERNS.map((pattern) => {
10
+ const path = pattern.replace(/\/+$/, "");
11
+ const slash = path.indexOf("/");
12
+ return slash === -1 ? path : path.slice(0, slash);
13
+ })));
8
14
  function isRootRuntimePath(path) {
9
- return path === ".gsd" || path.startsWith(".gsd/");
15
+ return ROOT_RUNTIME_PATH_PREFIXES.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
10
16
  }
11
17
  function fileFingerprint(rootPath, relPath) {
12
18
  const absPath = join(rootPath, relPath);
@@ -20,14 +20,21 @@ const DESTRUCTIVE_PATTERNS = [
20
20
  { pattern: /\baws\s+\w+\s+(delete|create|put|remove|terminate)\b/i, label: "AWS mutation" },
21
21
  { pattern: /\bkubectl\s+(delete|apply)\b/i, label: "kubectl mutation" },
22
22
  ];
23
+ function stripQuotedAndComments(command) {
24
+ return command
25
+ .replace(/"(?:[^"\\]|\\.)*"/g, '""')
26
+ .replace(/'(?:[^'\\]|\\.)*'/g, "''")
27
+ .replace(/(^|\s)#.*$/g, "$1");
28
+ }
23
29
  /**
24
30
  * Classify a bash command for destructive operations.
25
31
  * Returns the list of matched destructive pattern labels.
26
32
  */
27
33
  export function classifyCommand(command) {
34
+ const commandToClassify = stripQuotedAndComments(command);
28
35
  const labels = [];
29
36
  for (const { pattern, label } of DESTRUCTIVE_PATTERNS) {
30
- if (pattern.test(command)) {
37
+ if (pattern.test(commandToClassify)) {
31
38
  // Deduplicate labels (e.g., two force-push patterns)
32
39
  if (!labels.includes(label))
33
40
  labels.push(label);
@@ -27,10 +27,14 @@ const EXECUTION_TOOL_NAMES = new Set([
27
27
  const MCP_EXECUTION_TOOL_RE = /^mcp__.+__gsd_(?:uat_)?exec(?:_search)?$/;
28
28
  // ─── Module State ───────────────────────────────────────────────────────────
29
29
  let unitEvidence = [];
30
+ let lastWritePath = null;
31
+ let lastWriteSig = null;
30
32
  // ─── Public API ─────────────────────────────────────────────────────────────
31
33
  /** Reset all evidence for a new unit. Call at unit start. */
32
34
  export function resetEvidence() {
33
35
  unitEvidence = [];
36
+ lastWritePath = null;
37
+ lastWriteSig = null;
34
38
  }
35
39
  /** Get a read-only view of all evidence collected for the current unit. */
36
40
  export function getEvidence() {
@@ -95,10 +99,15 @@ function isEvidenceArray(data) {
95
99
  export function saveEvidenceToDisk(basePath, milestoneId, sliceId, taskId) {
96
100
  try {
97
101
  const path = evidencePath(basePath, milestoneId, sliceId, taskId);
102
+ const body = JSON.stringify(unitEvidence, null, 2) + "\n";
103
+ if (path === lastWritePath && body === lastWriteSig)
104
+ return;
98
105
  mkdirSync(dirname(path), { recursive: true });
99
106
  const tmp = `${path}.tmp.${randomBytes(4).toString("hex")}`;
100
- writeFileSync(tmp, JSON.stringify(unitEvidence, null, 2) + "\n", "utf-8");
107
+ writeFileSync(tmp, body, "utf-8");
101
108
  renameSync(tmp, path);
109
+ lastWritePath = path;
110
+ lastWriteSig = body;
102
111
  }
103
112
  catch {
104
113
  // Non-fatal — don't let persistence failures break unit execution
@@ -112,6 +121,8 @@ export function saveEvidenceToDisk(basePath, milestoneId, sliceId, taskId) {
112
121
  */
113
122
  export function loadEvidenceFromDisk(basePath, milestoneId, sliceId, taskId) {
114
123
  try {
124
+ lastWritePath = null;
125
+ lastWriteSig = null;
115
126
  const path = evidencePath(basePath, milestoneId, sliceId, taskId);
116
127
  if (!existsSync(path))
117
128
  return;
@@ -136,6 +147,10 @@ export function clearEvidenceFromDisk(basePath, milestoneId, sliceId, taskId) {
136
147
  if (existsSync(path)) {
137
148
  unlinkSync(path);
138
149
  }
150
+ if (path === lastWritePath) {
151
+ lastWritePath = null;
152
+ lastWriteSig = null;
153
+ }
139
154
  }
140
155
  catch {
141
156
  // Non-fatal
@@ -44,8 +44,11 @@ export function validateFileChanges(basePath, expectedOutput, plannedFiles, file
44
44
  const actualFiles = getChangedFilesFromLastCommit(basePath);
45
45
  if (!actualFiles)
46
46
  return null;
47
- // Filter out .gsd/ internal files — only validate project source files
48
- const projectFiles = actualFiles.filter(f => !f.startsWith(".gsd/") && !f.startsWith(".gsd\\"));
47
+ // Filter out GSD-internal paths — only validate project source files.
48
+ const projectFiles = actualFiles.filter((f) => !f.startsWith(".gsd/") &&
49
+ !f.startsWith(".gsd\\") &&
50
+ !f.startsWith(".gsd-backups/") &&
51
+ !f.startsWith(".gsd-backups\\"));
49
52
  // Normalize expected paths (strip leading ./ or /)
50
53
  const normalizedExpected = new Set([...allExpected].map((f) => normalizePlannedFileReference(f).replace(/^\.\//, "").replace(/^\//, "")));
51
54
  // Build allowlist matchers once (dot: true so patterns like `**/.hidden` work).
@@ -176,11 +176,21 @@ export function extractTrace(entries) {
176
176
  }
177
177
  // Flush any pending tool calls that never got results (crash mid-tool)
178
178
  for (const [, pending] of pendingTools) {
179
+ const missingResultError = `Tool call ${pending.name} started but no toolResult was recorded`;
179
180
  toolCalls.push({
180
181
  name: pending.name,
181
182
  input: redactInput(pending.name, pending.input),
182
- isError: false,
183
+ result: "missing tool result (stream/tool-call abort before execution)",
184
+ isError: true,
183
185
  });
186
+ errors.push(missingResultError);
187
+ // Mark the matching commandsRun entry as failed so it is consistent with
188
+ // the isError: true on the tool call above (bash/bg_shell only).
189
+ if (pending.name === "bash" || pending.name === "bg_shell") {
190
+ const lastCmd = findLast(commandsRun, c => c.command === String(pending.input.command));
191
+ if (lastCmd)
192
+ lastCmd.failed = true;
193
+ }
184
194
  }
185
195
  return {
186
196
  toolCalls,
@@ -66,7 +66,7 @@ These commands dispatch native GSD prompts adapted to the milestone, slice, and
66
66
  | `progress` | Summarize recent work; can route `--next` or `--do "..."` |
67
67
  | `health` | Check `.gsd/` integrity (`--repair`, `--context`) |
68
68
  | `surface` | Manage surfaced skills and extensions |
69
- | `code-review` | Review changed source for bugs, security, and quality |
69
+ | `code-review` | Review changed source diff-first for bugs, security, and quality |
70
70
  | `review` | Peer-review recent work across reviewer perspectives |
71
71
  | `audit-milestone` | Verify a milestone met its definition of done |
72
72
  | `audit-uat` | Audit outstanding UAT/verification items |
@@ -0,0 +1,28 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: deriveState memoization cache and telemetry.
3
+ const CACHE_TTL_MS = 100;
4
+ let _stateCache = null;
5
+ let _telemetry = { dbDeriveCount: 0 };
6
+ export function getDeriveTelemetry() {
7
+ return { ..._telemetry };
8
+ }
9
+ export function resetDeriveTelemetry() {
10
+ _telemetry = { dbDeriveCount: 0 };
11
+ }
12
+ export function incrementDbDeriveCount() {
13
+ _telemetry.dbDeriveCount++;
14
+ }
15
+ export function invalidateStateCache() {
16
+ _stateCache = null;
17
+ }
18
+ export function readCachedDeriveState(cacheKey) {
19
+ if (_stateCache &&
20
+ _stateCache.basePath === cacheKey &&
21
+ Date.now() - _stateCache.timestamp < CACHE_TTL_MS) {
22
+ return _stateCache.result;
23
+ }
24
+ return null;
25
+ }
26
+ export function writeCachedDeriveState(cacheKey, result) {
27
+ _stateCache = { basePath: cacheKey, result, timestamp: Date.now() };
28
+ }
@@ -0,0 +1,39 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Workflow DB open helpers for state derivation.
3
+ import { getAllMilestones, isDbAvailable, setMilestoneQueueOrder } from '../../gsd-db.js';
4
+ import { openExistingWorkflowDatabase } from '../../db-workspace.js';
5
+ import { loadQueueOrder, sortByQueueOrder } from '../../queue-order.js';
6
+ export function syncQueueOrderProjectionToDb(basePath) {
7
+ const queueOrder = loadQueueOrder(basePath);
8
+ if (!queueOrder)
9
+ return;
10
+ const currentIds = getAllMilestones().map((m) => m.id);
11
+ const desiredIds = sortByQueueOrder(currentIds, queueOrder);
12
+ if (currentIds.length === desiredIds.length && currentIds.every((id, i) => id === desiredIds[i]))
13
+ return;
14
+ setMilestoneQueueOrder(desiredIds);
15
+ }
16
+ export function ensureExistingWorkflowDbOpen(basePath) {
17
+ const opened = isDbAvailable() || openExistingWorkflowDatabase(basePath).ok;
18
+ if (opened)
19
+ syncQueueOrderProjectionToDb(basePath);
20
+ return opened;
21
+ }
22
+ export function buildDbUnavailableState() {
23
+ return {
24
+ activeMilestone: null,
25
+ activeSlice: null,
26
+ activeTask: null,
27
+ phase: "pre-planning",
28
+ recentDecisions: [],
29
+ blockers: ["DB unavailable — runtime markdown state derivation is disabled"],
30
+ nextAction: "Open or create the canonical GSD database before deriving workflow state. If this project only has markdown state, run /gsd migrate explicitly.",
31
+ registry: [],
32
+ requirements: { active: 0, validated: 0, deferred: 0, outOfScope: 0, blocked: 0, total: 0 },
33
+ progress: { milestones: { done: 0, total: 0 } },
34
+ };
35
+ }
36
+ export function getRequestedMilestoneLock() {
37
+ const lock = process.env.GSD_MILESTONE_LOCK?.trim();
38
+ return lock || undefined;
39
+ }