gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.f55d16d13

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 (303) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/GSD-WORKFLOW.md +2 -2
  3. package/dist/resources/extensions/github-sync/templates.js +39 -8
  4. package/dist/resources/extensions/gsd/auto/loop.js +16 -9
  5. package/dist/resources/extensions/gsd/auto/phases.js +37 -30
  6. package/dist/resources/extensions/gsd/auto/run-unit.js +19 -15
  7. package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
  8. package/dist/resources/extensions/gsd/auto-dispatch.js +10 -0
  9. package/dist/resources/extensions/gsd/auto-post-unit.js +10 -10
  10. package/dist/resources/extensions/gsd/auto-prompts.js +111 -1
  11. package/dist/resources/extensions/gsd/auto-recovery.js +154 -8
  12. package/dist/resources/extensions/gsd/auto-start.js +2 -3
  13. package/dist/resources/extensions/gsd/auto.js +9 -1
  14. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +15 -1
  15. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -1
  16. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  17. package/dist/resources/extensions/gsd/clean-root-preflight.js +42 -4
  18. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  19. package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
  20. package/dist/resources/extensions/gsd/db-base-schema.js +14 -0
  21. package/dist/resources/extensions/gsd/db-migration-steps.js +16 -0
  22. package/dist/resources/extensions/gsd/detection.js +106 -0
  23. package/dist/resources/extensions/gsd/graph.js +9 -3
  24. package/dist/resources/extensions/gsd/gsd-db.js +102 -2
  25. package/dist/resources/extensions/gsd/guided-flow.js +2 -2
  26. package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
  27. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
  28. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  29. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  30. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  31. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  32. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  33. package/dist/web/standalone/.next/BUILD_ID +1 -1
  34. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  35. package/dist/web/standalone/.next/build-manifest.json +3 -3
  36. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  37. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  38. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  39. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  47. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  55. package/dist/web/standalone/.next/server/app/index.html +1 -1
  56. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  63. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  64. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  65. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  67. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  68. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  69. package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
  70. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
  71. package/package.json +10 -6
  72. package/packages/contracts/package.json +1 -1
  73. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  74. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  75. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  76. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  77. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  78. package/packages/pi-ai/dist/models/index.js +8 -0
  79. package/packages/pi-ai/dist/models/index.js.map +1 -1
  80. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  81. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  82. package/packages/pi-ai/dist/providers/fake.js +319 -0
  83. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  84. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  85. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  86. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  87. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  88. package/packages/pi-ai/src/models/index.ts +9 -0
  89. package/packages/pi-ai/src/providers/fake.ts +376 -0
  90. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  91. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  92. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +74 -0
  93. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
  95. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  96. package/packages/pi-coding-agent/dist/core/extensions/runner.js +14 -1
  97. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  98. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +97 -0
  99. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  100. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  101. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  102. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  103. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +4 -0
  104. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  105. package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
  106. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  107. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  108. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  109. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  110. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  111. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  112. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
  113. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  114. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
  115. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  116. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
  117. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  118. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  119. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  122. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  125. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  126. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  127. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  128. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  129. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  130. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  131. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  132. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  133. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +16 -0
  134. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  135. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +106 -17
  136. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  138. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +60 -1
  139. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  140. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +40 -1
  141. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  143. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  144. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  145. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  148. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  149. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +23 -0
  150. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  153. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  155. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  156. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  157. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  158. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  159. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  161. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  163. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  164. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
  165. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  167. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  168. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  169. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  170. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  171. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  172. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  173. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  174. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  175. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
  176. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  177. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +87 -0
  178. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +108 -0
  179. package/packages/pi-coding-agent/src/core/extensions/runner.ts +16 -1
  180. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  181. package/packages/pi-coding-agent/src/core/settings-manager.ts +12 -0
  182. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  183. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  184. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
  185. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
  186. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
  187. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  188. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  189. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  190. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  191. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +118 -17
  192. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +43 -1
  193. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -1
  194. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  195. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  196. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +25 -0
  197. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  198. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  199. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  200. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
  201. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  202. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
  203. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  204. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  205. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  206. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  207. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  208. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  209. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  210. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  211. package/packages/pi-tui/dist/index.d.ts +1 -0
  212. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  213. package/packages/pi-tui/dist/index.js +2 -0
  214. package/packages/pi-tui/dist/index.js.map +1 -1
  215. package/packages/pi-tui/dist/style.d.ts +41 -0
  216. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  217. package/packages/pi-tui/dist/style.js +158 -0
  218. package/packages/pi-tui/dist/style.js.map +1 -0
  219. package/packages/pi-tui/dist/tui.d.ts +0 -1
  220. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  221. package/packages/pi-tui/dist/tui.js +3 -8
  222. package/packages/pi-tui/dist/tui.js.map +1 -1
  223. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  224. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  225. package/packages/pi-tui/src/index.ts +9 -0
  226. package/packages/pi-tui/src/style.ts +225 -0
  227. package/packages/pi-tui/src/tui.ts +3 -8
  228. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  229. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  230. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  231. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  232. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  233. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  234. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  235. package/pkg/dist/modes/interactive/theme/theme.js +18 -1
  236. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  237. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  238. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  239. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  240. package/src/resources/GSD-WORKFLOW.md +2 -2
  241. package/src/resources/extensions/github-sync/templates.ts +38 -8
  242. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  243. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  244. package/src/resources/extensions/gsd/auto/loop.ts +17 -10
  245. package/src/resources/extensions/gsd/auto/phases.ts +42 -28
  246. package/src/resources/extensions/gsd/auto/run-unit.ts +24 -14
  247. package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
  248. package/src/resources/extensions/gsd/auto-dispatch.ts +17 -0
  249. package/src/resources/extensions/gsd/auto-post-unit.ts +10 -10
  250. package/src/resources/extensions/gsd/auto-prompts.ts +116 -1
  251. package/src/resources/extensions/gsd/auto-recovery.ts +153 -7
  252. package/src/resources/extensions/gsd/auto-start.ts +7 -6
  253. package/src/resources/extensions/gsd/auto.ts +12 -1
  254. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -1
  255. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -1
  256. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  257. package/src/resources/extensions/gsd/clean-root-preflight.ts +41 -3
  258. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  259. package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
  260. package/src/resources/extensions/gsd/db-base-schema.ts +15 -0
  261. package/src/resources/extensions/gsd/db-migration-steps.ts +17 -0
  262. package/src/resources/extensions/gsd/detection.ts +128 -0
  263. package/src/resources/extensions/gsd/graph.ts +12 -5
  264. package/src/resources/extensions/gsd/gsd-db.ts +119 -1
  265. package/src/resources/extensions/gsd/guided-flow.ts +2 -2
  266. package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
  267. package/src/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
  268. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  269. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  270. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  271. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
  272. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +84 -5
  273. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +170 -1
  274. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +88 -2
  275. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  276. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +112 -6
  277. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
  278. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  279. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  280. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  281. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  282. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  283. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  284. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  285. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  286. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  287. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  288. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  289. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  290. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  291. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  292. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +46 -2
  293. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  294. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  295. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
  296. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  297. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  298. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  299. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  300. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  301. package/packages/contracts/tsconfig.tsbuildinfo +0 -1
  302. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → mPZbi5BH9dwokaPZlrYuQ}/_buildManifest.js +0 -0
  303. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → mPZbi5BH9dwokaPZlrYuQ}/_ssgManifest.js +0 -0
@@ -131,7 +131,7 @@ test("postflightPopStash — restores stashed changes and emits info notificatio
131
131
  run('git commit -m "simulate merge"', repo);
132
132
 
133
133
  const postNotifications: Array<{ msg: string; level: string }> = [];
134
- postflightPopStash(repo, "M004", (msg, level) => {
134
+ postflightPopStash(repo, "M004", preflight.stashMarker, (msg, level) => {
135
135
  postNotifications.push({ msg, level });
136
136
  });
137
137
 
@@ -171,7 +171,7 @@ test("preflight + merge + postflight round-trip preserves uncommitted changes",
171
171
  run('git commit -m "feat: add feature"', repo);
172
172
 
173
173
  // Postflight: pop stash
174
- postflightPopStash(repo, "M005", () => {});
174
+ postflightPopStash(repo, "M005", preflight.stashMarker, () => {});
175
175
 
176
176
  // README.md must still have our local content
177
177
  const restored = readFileSync(join(repo, "README.md"), "utf-8");
@@ -184,3 +184,89 @@ test("preflight + merge + postflight round-trip preserves uncommitted changes",
184
184
  try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
185
185
  }
186
186
  });
187
+
188
+ test("postflightPopStash conflict warning names the exact stash ref", () => {
189
+ const repo = createTempRepo();
190
+ try {
191
+ writeFileSync(join(repo, "README.md"), "# local work\n");
192
+ const preflight = preflightCleanRoot(repo, "M005C", () => {});
193
+ assert.equal(preflight.stashPushed, true, "must have stashed");
194
+
195
+ writeFileSync(join(repo, "README.md"), "# merged work\n");
196
+ run("git add README.md", repo);
197
+ run('git commit -m "simulate conflicting merge"', repo);
198
+
199
+ const notifications: Array<{ msg: string; level: string }> = [];
200
+ postflightPopStash(repo, "M005C", preflight.stashMarker, (msg, level) => {
201
+ notifications.push({ msg, level });
202
+ });
203
+
204
+ const warning = notifications.find((n) => n.level === "warning")?.msg ?? "";
205
+ assert.match(warning, /git stash pop stash@\{\d+\}/);
206
+ assert.match(warning, /git stash apply stash@\{\d+\}/);
207
+ } finally {
208
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
209
+ }
210
+ });
211
+
212
+ test("postflightPopStash restores the matching GSD stash, not stash@{0}", () => {
213
+ const repo = createTempRepo();
214
+ try {
215
+ writeFileSync(join(repo, "README.md"), "# target stash\n");
216
+ const preflight = preflightCleanRoot(repo, "M006", () => {});
217
+ assert.equal(preflight.stashPushed, true, "must have stashed target change");
218
+
219
+ writeFileSync(join(repo, "other.txt"), "other stash\n");
220
+ run('git stash push --include-untracked -m "unrelated newer stash"', repo);
221
+
222
+ postflightPopStash(repo, "M006", preflight.stashMarker, () => {});
223
+
224
+ const content = readFileSync(join(repo, "README.md"), "utf-8");
225
+ assert.equal(content.replace(/\r\n/g, "\n"), "# target stash\n");
226
+ const stashList = run("git stash list", repo);
227
+ assert.ok(stashList.includes("unrelated newer stash"), "unrelated newer stash must remain");
228
+ assert.ok(!stashList.includes("gsd-preflight-stash [gsd-preflight-stash:M006"), "target stash should be consumed");
229
+ } finally {
230
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
231
+ }
232
+ });
233
+
234
+ test("postflightPopStash restores the exact preflight marker when another same-milestone stash exists", () => {
235
+ const repo = createTempRepo();
236
+ try {
237
+ writeFileSync(join(repo, "README.md"), "# target stash\n");
238
+ const preflight = preflightCleanRoot(repo, "M007", () => {});
239
+ assert.equal(preflight.stashPushed, true, "must have stashed target change");
240
+ assert.ok(preflight.stashMarker, "preflight must expose exact stash marker");
241
+
242
+ writeFileSync(join(repo, "same-milestone.txt"), "newer same milestone stash\n");
243
+ run('git stash push --include-untracked -m "gsd-preflight-stash [gsd-preflight-stash:M007:other]"', repo);
244
+
245
+ postflightPopStash(repo, "M007", preflight.stashMarker, () => {});
246
+
247
+ const content = readFileSync(join(repo, "README.md"), "utf-8");
248
+ assert.equal(content.replace(/\r\n/g, "\n"), "# target stash\n");
249
+ const stashList = run("git stash list", repo);
250
+ assert.ok(stashList.includes("gsd-preflight-stash:M007:other"), "newer same-milestone stash must remain");
251
+ assert.ok(!stashList.includes(preflight.stashMarker), "exact target stash should be consumed");
252
+ } finally {
253
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
254
+ }
255
+ });
256
+
257
+ test("postflightPopStash falls back to milestone marker prefix when exact marker is unavailable", () => {
258
+ const repo = createTempRepo();
259
+ try {
260
+ writeFileSync(join(repo, "README.md"), "# fallback stash\n");
261
+ run('git stash push --include-untracked -m "gsd-preflight-stash [gsd-preflight-stash:M008:fallback]"', repo);
262
+
263
+ postflightPopStash(repo, "M008", undefined, () => {});
264
+
265
+ const content = readFileSync(join(repo, "README.md"), "utf-8");
266
+ assert.equal(content.replace(/\r\n/g, "\n"), "# fallback stash\n");
267
+ const stashList = run("git stash list", repo);
268
+ assert.ok(!stashList.includes("gsd-preflight-stash:M008:fallback"), "fallback stash should be consumed");
269
+ } finally {
270
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
271
+ }
272
+ });
@@ -1,3 +1,4 @@
1
+ // GSD2 commands-extract-learnings tests
1
2
  import { describe, it, beforeEach, afterEach } from "node:test";
2
3
  import assert from "node:assert/strict";
3
4
  import { mkdirSync, writeFileSync, rmSync, readFileSync } from "node:fs";
@@ -484,6 +485,14 @@ describe("buildExtractionStepsBlock", () => {
484
485
  assert.ok(/skip/i.test(block));
485
486
  });
486
487
 
488
+ it("limits duplicate checks to one milestone-scoped memory query", () => {
489
+ const block = buildExtractionStepsBlock(ctx);
490
+ const memoryQueryMatches = block.match(/memory_query/g) ?? [];
491
+ assert.equal(memoryQueryMatches.length, 1);
492
+ assert.ok(block.includes("Do not re-read milestone artefacts or repeat memory queries category-by-category"));
493
+ assert.ok(!block.includes("Before each `capture_thought` call, optionally call `memory_query`"));
494
+ });
495
+
487
496
  it("instructs capture_thought as the sole persistence path for Patterns, Lessons, and Decisions (ADR-013 step 6 cutover)", () => {
488
497
  const block = buildExtractionStepsBlock(ctx);
489
498
  // Each of the three persistence steps must call capture_thought.
@@ -372,7 +372,56 @@ describe("Custom engine loop integration", () => {
372
372
  assert.ok(stopEntry?.includes("Workflow complete"), "Should stop with 'Workflow complete'");
373
373
  });
374
374
 
375
- it("finishes custom-engine skip turns and clears current turn state", async () => {
375
+ it("finalizes custom-engine complete turns and clears current turn state", async () => {
376
+ _resetPendingResolve();
377
+
378
+ const runDir = makeTmpDir();
379
+ const graph = makeGraph([
380
+ makeStep({ id: "step-a", status: "complete" }),
381
+ ], "already-done");
382
+ writeGraph(runDir, graph);
383
+ writeDefinition(runDir, graph.steps, "already-done");
384
+
385
+ const ctx = makeMockCtx();
386
+ const pi = makeMockPi();
387
+ const s = makeLoopSession({
388
+ activeEngineId: "custom",
389
+ activeRunDir: runDir,
390
+ basePath: runDir,
391
+ });
392
+ const turnResults: Array<{ status: string; failureClass: string; error?: string }> = [];
393
+ const deps = makeMockDeps({
394
+ stopAuto: async (_ctx, _pi, reason) => {
395
+ deps.callLog.push(`stopAuto:${reason ?? "no-reason"}`);
396
+ s.active = false;
397
+ },
398
+ uokObserver: {
399
+ onTurnStart: () => {},
400
+ onTurnResult: (result) => {
401
+ deps.callLog.push(`turnResult:${result.status}`);
402
+ turnResults.push({
403
+ status: result.status,
404
+ failureClass: result.failureClass,
405
+ error: result.error,
406
+ });
407
+ },
408
+ onPhaseResult: () => {},
409
+ },
410
+ });
411
+
412
+ await autoLoop(ctx, pi, s, deps);
413
+
414
+ assert.deepEqual(turnResults, [{ status: "completed", failureClass: "none", error: undefined }]);
415
+ assert.ok(
416
+ deps.callLog.indexOf("turnResult:completed") < deps.callLog.indexOf("stopAuto:Workflow complete"),
417
+ `turn should finalize before stopAuto; log=${deps.callLog.join(",")}`,
418
+ );
419
+ assert.equal(s.currentTraceId, null);
420
+ assert.equal(s.currentTurnId, null);
421
+ assert.equal(pi.calls.length, 0, "complete workflow should not dispatch work");
422
+ });
423
+
424
+ it("stops blocked custom workflows and clears current turn state", async () => {
376
425
  _resetPendingResolve();
377
426
 
378
427
  const runDir = makeTmpDir();
@@ -390,13 +439,65 @@ describe("Custom engine loop integration", () => {
390
439
  activeRunDir: runDir,
391
440
  basePath: runDir,
392
441
  });
393
- const turnResults: Array<{ status: string }> = [];
442
+ const turnResults: Array<{ status: string; failureClass: string; error?: string }> = [];
394
443
  const deps = makeMockDeps({
444
+ stopAuto: async (_ctx, _pi, reason) => {
445
+ deps.callLog.push(`stopAuto:${reason ?? "no-reason"}`);
446
+ s.active = false;
447
+ },
448
+ uokObserver: {
449
+ onTurnStart: () => {},
450
+ onTurnResult: (result) => {
451
+ turnResults.push({
452
+ status: result.status,
453
+ failureClass: result.failureClass,
454
+ error: result.error,
455
+ });
456
+ },
457
+ onPhaseResult: () => {},
458
+ },
459
+ });
460
+
461
+ await autoLoop(ctx, pi, s, deps);
462
+
463
+ assert.equal(turnResults.length, 1);
464
+ assert.equal(turnResults[0].status, "stopped");
465
+ assert.equal(turnResults[0].failureClass, "manual-attention");
466
+ assert.match(turnResults[0].error ?? "", /custom-engine-dispatch-stop/);
467
+ assert.equal(s.currentTraceId, null);
468
+ assert.equal(s.currentTurnId, null);
469
+ assert.equal(pi.calls.length, 0, "blocked workflow should not dispatch a custom step");
470
+ assert.match(
471
+ deps.callLog.find((e: string) => e.startsWith("stopAuto:")) ?? "",
472
+ /Workflow blocked: no pending steps are ready/,
473
+ );
474
+ });
475
+
476
+ it("finalizes the active turn when the session lock is lost", async () => {
477
+ _resetPendingResolve();
478
+
479
+ const ctx = makeMockCtx();
480
+ const pi = makeMockPi();
481
+ const s = makeLoopSession();
482
+ const turnResults: Array<{ status: string; failureClass: string; error?: string }> = [];
483
+ const deps = makeMockDeps({
484
+ validateSessionLock: () => ({
485
+ valid: false,
486
+ failureReason: "pid-mismatch",
487
+ expectedPid: 111,
488
+ existingPid: 222,
489
+ } as SessionLockStatus),
490
+ handleLostSessionLock: () => {
491
+ deps.callLog.push("handleLostSessionLock");
492
+ },
395
493
  uokObserver: {
396
494
  onTurnStart: () => {},
397
495
  onTurnResult: (result) => {
398
- turnResults.push({ status: result.status });
399
- s.active = false;
496
+ turnResults.push({
497
+ status: result.status,
498
+ failureClass: result.failureClass,
499
+ error: result.error,
500
+ });
400
501
  },
401
502
  onPhaseResult: () => {},
402
503
  },
@@ -404,10 +505,15 @@ describe("Custom engine loop integration", () => {
404
505
 
405
506
  await autoLoop(ctx, pi, s, deps);
406
507
 
407
- assert.deepEqual(turnResults, [{ status: "skipped" }]);
508
+ assert.deepEqual(turnResults, [{
509
+ status: "stopped",
510
+ failureClass: "manual-attention",
511
+ error: "session-lock-lost",
512
+ }]);
408
513
  assert.equal(s.currentTraceId, null);
409
514
  assert.equal(s.currentTurnId, null);
410
- assert.equal(pi.calls.length, 0, "skip should not dispatch a custom step");
515
+ assert.equal(pi.calls.length, 0, "lost session lock must not dispatch work");
516
+ assert.ok(deps.callLog.includes("handleLostSessionLock"));
411
517
  });
412
518
 
413
519
  it("does not call runPreDispatch or runFinalize on the custom path", async () => {
@@ -193,7 +193,7 @@ describe("CustomWorkflowEngine.resolveDispatch", () => {
193
193
  }
194
194
  });
195
195
 
196
- it("returns skip when pending steps are blocked by incomplete dependencies", async () => {
196
+ it("returns stop with dependency details when pending steps are blocked", async () => {
197
197
  const { engine } = setupEngine([
198
198
  makeStep({ id: "a", dependsOn: ["b"] }),
199
199
  makeStep({ id: "b", dependsOn: ["a"] }),
@@ -202,7 +202,45 @@ describe("CustomWorkflowEngine.resolveDispatch", () => {
202
202
  const state = await engine.deriveState("/unused");
203
203
  const dispatch = await engine.resolveDispatch(state, { basePath: "/unused" });
204
204
 
205
- assert.deepEqual(dispatch, { action: "skip" });
205
+ assert.equal(dispatch.action, "stop");
206
+ if (dispatch.action === "stop") {
207
+ assert.equal(dispatch.level, "error");
208
+ assert.match(dispatch.reason, /Workflow blocked/);
209
+ assert.match(dispatch.reason, /a waiting on b \(pending\)/);
210
+ assert.match(dispatch.reason, /b waiting on a \(pending\)/);
211
+ }
212
+ });
213
+
214
+ it("reports missing dependencies when no pending step can run", async () => {
215
+ const { engine } = setupEngine([
216
+ makeStep({ id: "a", dependsOn: ["missing-step"] }),
217
+ ]);
218
+
219
+ const state = await engine.deriveState("/unused");
220
+ const dispatch = await engine.resolveDispatch(state, { basePath: "/unused" });
221
+
222
+ assert.equal(dispatch.action, "stop");
223
+ if (dispatch.action === "stop") {
224
+ assert.equal(dispatch.level, "error");
225
+ assert.match(dispatch.reason, /a waiting on missing-step \(missing\)/);
226
+ }
227
+ });
228
+
229
+ it("does not report expanded dependencies as blockers", async () => {
230
+ const { engine } = setupEngine([
231
+ makeStep({ id: "iter", status: "expanded" }),
232
+ makeStep({ id: "after", dependsOn: ["iter", "missing-step"] }),
233
+ ]);
234
+
235
+ const state = await engine.deriveState("/unused");
236
+ const dispatch = await engine.resolveDispatch(state, { basePath: "/unused" });
237
+
238
+ assert.equal(dispatch.action, "stop");
239
+ if (dispatch.action === "stop") {
240
+ assert.equal(dispatch.level, "error");
241
+ assert.match(dispatch.reason, /after waiting on missing-step \(missing\)/);
242
+ assert.doesNotMatch(dispatch.reason, /iter \(expanded\)/);
243
+ }
206
244
  });
207
245
 
208
246
  it("respects dependency ordering", async () => {