gsd-pi 2.78.0 → 2.78.1-dev.82bcf6b71

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 (577) hide show
  1. package/README.md +60 -23
  2. package/dist/bundled-resource-path.d.ts +7 -0
  3. package/dist/bundled-resource-path.js +34 -2
  4. package/dist/claude-cli-check.js +104 -33
  5. package/dist/cli-policy.d.ts +13 -0
  6. package/dist/cli-policy.js +17 -0
  7. package/dist/cli.js +95 -55
  8. package/dist/headless-query.d.ts +22 -0
  9. package/dist/headless-query.js +43 -8
  10. package/dist/headless.d.ts +10 -0
  11. package/dist/headless.js +16 -1
  12. package/dist/loader.js +9 -13
  13. package/dist/onboarding.d.ts +10 -0
  14. package/dist/onboarding.js +2 -2
  15. package/dist/provider-migrations.d.ts +2 -2
  16. package/dist/provider-migrations.js +5 -2
  17. package/dist/resource-loader.d.ts +5 -2
  18. package/dist/resource-loader.js +30 -13
  19. package/dist/resources/.managed-resources-content-hash +1 -0
  20. package/dist/resources/extensions/claude-code-cli/readiness.js +128 -32
  21. package/dist/resources/extensions/google-search/index.js +2 -6
  22. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  23. package/dist/resources/extensions/gsd/auto/phases.js +5 -13
  24. package/dist/resources/extensions/gsd/auto/run-unit.js +26 -12
  25. package/dist/resources/extensions/gsd/auto/session.js +5 -6
  26. package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
  27. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +55 -21
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  29. package/dist/resources/extensions/gsd/auto-prompts.js +69 -2
  30. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  31. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  32. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  33. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  34. package/dist/resources/extensions/gsd/auto-worktree.js +75 -13
  35. package/dist/resources/extensions/gsd/auto.js +39 -14
  36. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  38. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  39. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  40. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +112 -31
  41. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  42. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +45 -8
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  45. package/dist/resources/extensions/gsd/commands/catalog.js +76 -5
  46. package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -1
  47. package/dist/resources/extensions/gsd/commands/handlers/ops.js +8 -0
  48. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  49. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  50. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  51. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  52. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  53. package/dist/resources/extensions/gsd/commands-worktree.js +309 -0
  54. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  55. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  56. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  57. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  58. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  59. package/dist/resources/extensions/gsd/forensics.js +10 -8
  60. package/dist/resources/extensions/gsd/git-service.js +12 -5
  61. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  62. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  63. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  64. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  65. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  66. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  67. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  68. package/dist/resources/extensions/gsd/model-router.js +114 -9
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  70. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  71. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  72. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  73. package/dist/resources/extensions/gsd/preferences.js +5 -3
  74. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  77. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  78. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  80. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  81. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  83. package/dist/resources/extensions/gsd/state.js +42 -0
  84. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  85. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  86. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  87. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  88. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  89. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  90. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  91. package/dist/resources/extensions/gsd/worktree-resolver.js +28 -13
  92. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  93. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  94. package/dist/resources/extensions/gsd/worktree.js +4 -115
  95. package/dist/resources/extensions/mcp-client/index.js +6 -9
  96. package/dist/resources/extensions/ollama/index.js +15 -2
  97. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  98. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  99. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  100. package/dist/resources/extensions/subagent/index.js +324 -178
  101. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  102. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  103. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  104. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  105. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  106. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  107. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  108. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  109. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  110. package/dist/resources/skills/lint/SKILL.md +4 -0
  111. package/dist/resources/skills/review/SKILL.md +4 -0
  112. package/dist/resources/skills/test/SKILL.md +3 -0
  113. package/dist/rtk-shared.d.ts +3 -0
  114. package/dist/rtk-shared.js +17 -0
  115. package/dist/rtk.d.ts +2 -5
  116. package/dist/rtk.js +3 -20
  117. package/dist/runtime-checks.d.ts +27 -0
  118. package/dist/runtime-checks.js +38 -0
  119. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  120. package/dist/web/standalone/.next/BUILD_ID +1 -1
  121. package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
  122. package/dist/web/standalone/.next/build-manifest.json +4 -4
  123. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  124. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  125. package/dist/web/standalone/.next/required-server-files.json +3 -3
  126. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  137. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  165. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  195. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  201. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  215. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  217. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  219. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  221. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/index.html +1 -1
  231. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  232. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  233. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  234. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  235. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  236. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  237. package/dist/web/standalone/.next/server/app/page.js +2 -2
  238. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app-paths-manifest.json +19 -19
  240. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  241. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  242. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  244. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  245. package/dist/web/standalone/.next/server/middleware.js +2 -2
  246. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  248. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  249. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  250. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  251. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  252. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  254. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  259. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  260. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  261. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  262. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  263. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  264. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  265. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  266. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  267. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  268. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  269. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  270. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  271. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  272. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  273. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  274. package/dist/web/standalone/package.json +2 -1
  275. package/dist/web/standalone/server.js +1 -1
  276. package/dist/welcome-screen.js +27 -1
  277. package/dist/worktree-cli.d.ts +1 -0
  278. package/dist/worktree-cli.js +9 -3
  279. package/dist/worktree-status-banner.d.ts +1 -0
  280. package/dist/worktree-status-banner.js +132 -0
  281. package/package.json +1 -3
  282. package/packages/daemon/package.json +2 -2
  283. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  284. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  285. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  286. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  287. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  288. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  289. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  290. package/packages/mcp-server/package.json +2 -2
  291. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  292. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  293. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  294. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  295. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  296. package/packages/native/package.json +1 -1
  297. package/packages/native/tsconfig.tsbuildinfo +1 -1
  298. package/packages/pi-agent-core/package.json +1 -1
  299. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  300. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  301. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  302. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  303. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  304. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  305. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  306. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  307. package/packages/pi-ai/dist/types.d.ts +13 -0
  308. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  309. package/packages/pi-ai/dist/types.js.map +1 -1
  310. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  311. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  312. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  313. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  314. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  315. package/packages/pi-ai/package.json +1 -1
  316. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  317. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  318. package/packages/pi-ai/src/types.ts +13 -0
  319. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  320. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  321. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  322. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  324. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  326. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  327. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  328. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  329. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  331. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  333. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  335. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  337. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  339. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  341. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  343. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  347. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  349. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  351. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  352. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  353. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  354. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  355. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  356. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  357. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  358. package/packages/pi-coding-agent/package.json +1 -1
  359. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  360. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  361. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  362. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  363. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  364. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  365. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  366. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  367. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  368. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  369. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  370. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  371. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  372. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  373. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  374. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  375. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  376. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  377. package/packages/pi-tui/package.json +1 -1
  378. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  379. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  380. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  381. package/packages/rpc-client/package.json +1 -1
  382. package/pkg/package.json +1 -1
  383. package/src/resources/extensions/claude-code-cli/readiness.ts +130 -30
  384. package/src/resources/extensions/google-search/index.ts +2 -9
  385. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  386. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  387. package/src/resources/extensions/gsd/auto/run-unit.ts +26 -12
  388. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  389. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  390. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  391. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +60 -24
  392. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  393. package/src/resources/extensions/gsd/auto-prompts.ts +66 -2
  394. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  395. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  396. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  397. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  398. package/src/resources/extensions/gsd/auto-worktree.ts +97 -12
  399. package/src/resources/extensions/gsd/auto.ts +37 -10
  400. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  401. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  402. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  403. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  404. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
  405. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  406. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  407. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
  408. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  409. package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
  410. package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
  411. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  412. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  413. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  414. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  415. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  416. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  417. package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
  418. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  419. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  420. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  421. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  422. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  423. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  424. package/src/resources/extensions/gsd/forensics.ts +12 -7
  425. package/src/resources/extensions/gsd/git-service.ts +13 -5
  426. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  427. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  428. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  429. package/src/resources/extensions/gsd/journal.ts +4 -1
  430. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  431. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  432. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  433. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  434. package/src/resources/extensions/gsd/model-router.ts +172 -9
  435. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  436. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  437. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  438. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  439. package/src/resources/extensions/gsd/preferences.ts +16 -2
  440. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  441. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  442. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  443. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  444. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  445. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  446. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  447. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  448. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  449. package/src/resources/extensions/gsd/state.ts +42 -0
  450. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  451. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +179 -1
  452. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  453. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  454. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  455. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  456. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  457. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
  458. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  459. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
  460. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  461. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  462. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  463. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  464. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  465. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  466. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  467. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  468. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  469. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  470. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  471. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  472. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  473. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  474. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  475. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  476. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  477. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  478. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
  479. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  480. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  481. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  482. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  483. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  484. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  485. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  486. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  487. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  488. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  489. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  490. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  491. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  492. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  493. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  494. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  495. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  496. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  497. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  498. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  499. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  500. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  501. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  502. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  503. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  504. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
  505. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  506. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  507. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  508. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +8 -2
  509. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +12 -6
  510. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  511. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  512. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  513. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  514. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  515. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  516. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  517. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  518. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +235 -0
  519. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +85 -0
  520. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  521. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  522. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  523. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  524. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  525. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  526. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  527. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  528. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  529. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  530. package/src/resources/extensions/gsd/worktree-resolver.ts +28 -14
  531. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  532. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  533. package/src/resources/extensions/gsd/worktree.ts +8 -119
  534. package/src/resources/extensions/mcp-client/index.ts +6 -10
  535. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  536. package/src/resources/extensions/ollama/index.ts +16 -2
  537. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  538. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  539. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  540. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  541. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  542. package/src/resources/extensions/subagent/index.ts +165 -7
  543. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  544. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  545. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  546. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  547. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  548. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  549. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  550. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  551. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  552. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  553. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  554. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  555. package/src/resources/skills/lint/SKILL.md +4 -0
  556. package/src/resources/skills/review/SKILL.md +4 -0
  557. package/src/resources/skills/test/SKILL.md +3 -0
  558. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  559. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  560. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  561. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  562. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  563. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  564. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  565. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  566. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  567. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  568. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  569. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  570. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  571. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  572. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  573. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  574. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  575. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  576. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → hcvW7f3yv1JHzlWe7tIc6}/_buildManifest.js +0 -0
  577. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → hcvW7f3yv1JHzlWe7tIc6}/_ssgManifest.js +0 -0
@@ -1,73 +1,156 @@
1
1
  /**
2
- * Regression test for #3580 — complete-slice verification gate
2
+ * Behavioural regression test for #3580 — complete-slice verification gate.
3
3
  *
4
- * Without the gate, a prompt regression could silently advance a blocked
5
- * or failed slice to "complete" status. The fix adds a BLOCKED_SIGNALS
6
- * regex that rejects completion when verification/UAT content clearly
7
- * indicates blocked or failed state.
4
+ * The gate must reject completion when the verification or UAT content
5
+ * indicates a blocked or failed slice. Drives the real handler with
6
+ * blocked-signal fixtures and asserts on the returned error. Replaces an
7
+ * earlier test file that only string-matched the BLOCKED_SIGNALS regex
8
+ * literal in the source (Refs #4826/#4831).
8
9
  */
9
10
 
10
- import { describe, it } from 'node:test'
11
- import assert from 'node:assert/strict'
12
- import { readFileSync } from 'node:fs'
13
- import { resolve } from 'node:path'
14
- import { extractSourceRegion } from "./test-helpers.ts";
11
+ import { describe, test, beforeEach, afterEach } from 'node:test';
12
+ import assert from 'node:assert/strict';
13
+ import * as fs from 'node:fs';
14
+ import * as path from 'node:path';
15
+ import * as os from 'node:os';
15
16
 
16
- const src = readFileSync(
17
- resolve(process.cwd(), 'src', 'resources', 'extensions', 'gsd', 'tools', 'complete-slice.ts'),
18
- 'utf-8',
19
- )
17
+ import {
18
+ openDatabase,
19
+ closeDatabase,
20
+ insertMilestone,
21
+ insertSlice,
22
+ insertTask,
23
+ } from '../gsd-db.ts';
24
+ import { handleCompleteSlice } from '../tools/complete-slice.ts';
25
+ import type { CompleteSliceParams } from '../types.ts';
26
+
27
+ function tempDbPath(): string {
28
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-blocked-gate-'));
29
+ return path.join(dir, 'test.db');
30
+ }
31
+
32
+ function cleanupDb(dbPath: string): void {
33
+ closeDatabase();
34
+ try { fs.rmSync(path.dirname(dbPath), { recursive: true, force: true }); } catch { /* */ }
35
+ }
36
+
37
+ function makeProject(): string {
38
+ const basePath = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-gate-proj-'));
39
+ fs.mkdirSync(path.join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks'), { recursive: true });
40
+ fs.writeFileSync(
41
+ path.join(basePath, '.gsd', 'milestones', 'M001', 'M001-ROADMAP.md'),
42
+ `# M001\n\n## Slices\n- [ ] **S01: Test** \`risk:low\` \`depends:[]\`\n - After this: works\n`,
43
+ );
44
+ return basePath;
45
+ }
46
+
47
+ function makeParams(overrides: Partial<CompleteSliceParams>): CompleteSliceParams {
48
+ return {
49
+ sliceId: 'S01',
50
+ milestoneId: 'M001',
51
+ sliceTitle: 'Test Slice',
52
+ oneLiner: 'one liner',
53
+ narrative: 'narrative',
54
+ verification: 'all green',
55
+ deviations: 'None.',
56
+ knownLimitations: 'None.',
57
+ followUps: 'None.',
58
+ keyFiles: [],
59
+ keyDecisions: [],
60
+ patternsEstablished: [],
61
+ observabilitySurfaces: [],
62
+ provides: [],
63
+ requirementsSurfaced: [],
64
+ drillDownPaths: [],
65
+ affects: [],
66
+ requirementsAdvanced: [],
67
+ requirementsValidated: [],
68
+ requirementsInvalidated: [],
69
+ filesModified: [],
70
+ requires: [],
71
+ uatContent: 'UAT body.',
72
+ ...overrides,
73
+ };
74
+ }
20
75
 
21
76
  describe('complete-slice verification gate (#3580)', () => {
22
- it('BLOCKED_SIGNALS regex is defined', () => {
23
- assert.ok(
24
- src.includes('BLOCKED_SIGNALS'),
25
- 'BLOCKED_SIGNALS constant must be defined in complete-slice.ts',
26
- )
27
- })
77
+ let dbPath: string;
78
+ let basePath: string;
79
+
80
+ beforeEach(() => {
81
+ dbPath = tempDbPath();
82
+ openDatabase(dbPath);
83
+ basePath = makeProject();
84
+ insertMilestone({ id: 'M001' });
85
+ insertSlice({ id: 'S01', milestoneId: 'M001' });
86
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'T1' });
87
+ });
28
88
 
29
- it('BLOCKED_SIGNALS is a regex that tests verification content', () => {
30
- // Extract the BLOCKED_SIGNALS definition line
31
- const idx = src.indexOf('BLOCKED_SIGNALS')
32
- assert.ok(idx !== -1)
33
- const lineEnd = src.indexOf(';', idx)
34
- const definition = src.slice(idx, lineEnd)
89
+ afterEach(() => {
90
+ cleanupDb(dbPath);
91
+ try { fs.rmSync(basePath, { recursive: true, force: true }); } catch { /* */ }
92
+ });
35
93
 
36
- // Must be a regex (starts with /)
37
- assert.ok(
38
- definition.includes('= /'),
39
- 'BLOCKED_SIGNALS must be assigned a regex literal',
40
- )
94
+ test('rejects when verification text contains "verification failed"', async () => {
95
+ const result = await handleCompleteSlice(
96
+ makeParams({ verification: 'verification failed: the regression came back' }),
97
+ basePath,
98
+ );
99
+ assert.ok('error' in result, 'expected handler to return an error');
100
+ assert.match((result as { error: string }).error, /blocked|failed|do not complete/i);
101
+ });
41
102
 
42
- // Must match key blocked/failed signals
43
- assert.ok(definition.includes('blocked'), 'regex must match "blocked" signals')
44
- assert.ok(definition.includes('failed'), 'regex must match "failed" signals')
45
- })
103
+ test('rejects when uatContent contains "verification_result: failed"', async () => {
104
+ const result = await handleCompleteSlice(
105
+ makeParams({ uatContent: '## Result\nverification_result: failed\n' }),
106
+ basePath,
107
+ );
108
+ assert.ok('error' in result, 'expected handler to return an error');
109
+ assert.match((result as { error: string }).error, /blocked|failed|do not complete/i);
110
+ });
46
111
 
47
- it('gate checks params.verification and params.uatContent', () => {
48
- // Find usage of BLOCKED_SIGNALS.test
49
- const testCalls = src.match(/BLOCKED_SIGNALS\.test\([^)]+\)/g)
50
- assert.ok(testCalls, 'BLOCKED_SIGNALS.test() must be called')
51
- assert.ok(testCalls.length >= 2, 'must check at least verification and uatContent')
112
+ test('rejects when verification declares "status: blocked"', async () => {
113
+ const result = await handleCompleteSlice(
114
+ makeParams({ verification: 'status: blocked — db unavailable' }),
115
+ basePath,
116
+ );
117
+ assert.ok('error' in result, 'expected handler to return an error');
118
+ assert.match((result as { error: string }).error, /blocked|failed|do not complete/i);
119
+ });
52
120
 
53
- const joined = testCalls.join(' ')
54
- assert.ok(joined.includes('verification'), 'must test params.verification')
55
- assert.ok(joined.includes('uatContent'), 'must test params.uatContent')
56
- })
121
+ test('rejects when uatContent says "slice is blocked"', async () => {
122
+ const result = await handleCompleteSlice(
123
+ makeParams({ uatContent: 'slice is blocked on upstream' }),
124
+ basePath,
125
+ );
126
+ assert.ok('error' in result, 'expected handler to return an error');
127
+ assert.match((result as { error: string }).error, /blocked|failed|do not complete/i);
128
+ });
57
129
 
58
- it('gate returns an error message when blocked signals detected', () => {
59
- // Find the return statement after BLOCKED_SIGNALS check
60
- const gateIdx = src.indexOf('BLOCKED_SIGNALS.test(')
61
- assert.ok(gateIdx !== -1)
130
+ test('rejects when verification says "cannot complete"', async () => {
131
+ const result = await handleCompleteSlice(
132
+ makeParams({ verification: 'cannot complete: requirements unmet' }),
133
+ basePath,
134
+ );
135
+ assert.ok('error' in result, 'expected handler to return an error');
136
+ assert.match((result as { error: string }).error, /blocked|failed|do not complete/i);
137
+ });
62
138
 
63
- const afterGate = extractSourceRegion(src, 'BLOCKED_SIGNALS.test(')
64
- assert.ok(
65
- afterGate.includes('return { error:'),
66
- 'blocked signal detection must return an error',
67
- )
68
- assert.ok(
69
- afterGate.includes('do not complete'),
70
- 'error message must explain why completion is rejected',
71
- )
72
- })
73
- })
139
+ test('passes the gate when verification + uatContent are clean', async () => {
140
+ // Sanity: the gate is not over-eager. Clean inputs reach the rest of
141
+ // the handler. (This call may still fail downstream because we provide
142
+ // a thin fixture; the only guarantee here is that the error — if any —
143
+ // is NOT the blocked-signals error.)
144
+ const result = await handleCompleteSlice(
145
+ makeParams({ verification: 'all 8 sections pass', uatContent: 'green across the board' }),
146
+ basePath,
147
+ );
148
+ if ('error' in result) {
149
+ assert.doesNotMatch(
150
+ result.error,
151
+ /blocked\/failed state — do not complete/,
152
+ `clean inputs should not be rejected by the BLOCKED_SIGNALS gate, got: ${result.error}`,
153
+ );
154
+ }
155
+ });
156
+ });
@@ -13,6 +13,7 @@ import {
13
13
  getSlice,
14
14
  updateSliceStatus,
15
15
  getSliceTasks,
16
+ SCHEMA_VERSION,
16
17
  } from '../gsd-db.ts';
17
18
  import { handleCompleteSlice } from '../tools/complete-slice.ts';
18
19
  import type { CompleteSliceParams } from '../types.ts';
@@ -115,19 +116,21 @@ Run the test suite and verify all assertions pass.
115
116
  }
116
117
 
117
118
  // ═══════════════════════════════════════════════════════════════════════════
118
- // complete-slice: Schema v6 migration
119
+ // complete-slice: fresh DB migrates to current schema version
119
120
  // ═══════════════════════════════════════════════════════════════════════════
120
121
 
121
- console.log('\n=== complete-slice: schema v6 migration ===');
122
+ console.log('\n=== complete-slice: fresh DB migrates to current schema version ===');
122
123
  {
123
124
  const dbPath = tempDbPath();
124
125
  openDatabase(dbPath);
125
126
 
126
127
  const adapter = _getAdapter()!;
127
128
 
128
- // Verify schema version is current (v22 quality_gates DDL fix)
129
+ // Pin schema version against the source-of-truth constant so this test
130
+ // survives migration bumps but still catches a "fresh DB was not migrated"
131
+ // regression.
129
132
  const versionRow = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
130
- assertEq(versionRow?.['v'], 22, 'schema version should be 22');
133
+ assertEq(versionRow?.['v'], SCHEMA_VERSION, 'fresh DB should be migrated to current SCHEMA_VERSION');
131
134
 
132
135
  // Verify slices table has full_summary_md and full_uat_md columns
133
136
  const cols = adapter.prepare("PRAGMA table_info(slices)").all();
@@ -1,42 +1,99 @@
1
1
  /**
2
- * Regression test for #4129: tasks.completed_at stays NULL when status is
3
- * reconciled to 'complete' via the file-existence path in state.ts.
2
+ * Behavioural regression test for #4129.
4
3
  *
5
- * Root cause: reconcileSliceTasks called
6
- * updateTaskStatus(milestoneId, sliceId, t.id, "complete")
7
- * without a completedAt timestamp, so the column stays NULL.
4
+ * When deriveStateFromDb's reconcileSliceTasks finds a SUMMARY.md on disk
5
+ * for a task whose DB row is still pending, it flips the row to "complete".
6
+ * Before #4129, the call to updateTaskStatus omitted the completedAt
7
+ * timestamp, leaving completed_at NULL forever.
8
8
  *
9
- * Fix: pass new Date().toISOString() as the 5th argument.
9
+ * The fix passes new Date().toISOString() as the 5th argument; this test
10
+ * exercises that path end-to-end and asserts the column is populated.
11
+ *
12
+ * Refs #4829 (rewrite from positional source-grep).
10
13
  */
11
14
 
12
- import { describe, test } from "node:test";
13
- import assert from "node:assert/strict";
14
- import { readFileSync } from "node:fs";
15
- import { join, dirname } from "node:path";
16
- import { fileURLToPath } from "node:url";
17
-
18
- const __dirname = dirname(fileURLToPath(import.meta.url));
19
- const stateSource = readFileSync(join(__dirname, "..", "state.ts"), "utf-8");
20
-
21
- describe("completed-at reconcile (#4129)", () => {
22
- test("reconcileSliceTasks passes a completedAt timestamp when setting status to complete", () => {
23
- // Before the fix, state.ts had:
24
- // updateTaskStatus(milestoneId, sliceId, t.id, "complete")
25
- // which leaves completed_at NULL in the DB.
26
- // After the fix, a timestamp must be passed as the 5th argument.
27
- assert.doesNotMatch(
28
- stateSource,
29
- /updateTaskStatus\(\s*milestoneId\s*,\s*sliceId\s*,\s*t\.id\s*,\s*["']complete["']\s*\)/,
30
- "updateTaskStatus must not be called without a completedAt timestamp when reconciling tasks to 'complete' (#4129)",
31
- );
15
+ import { describe, test, beforeEach, afterEach } from 'node:test';
16
+ import assert from 'node:assert/strict';
17
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
18
+ import { join } from 'node:path';
19
+ import { tmpdir } from 'node:os';
20
+
21
+ import { deriveStateFromDb, invalidateStateCache } from '../state.ts';
22
+ import {
23
+ openDatabase,
24
+ closeDatabase,
25
+ insertMilestone,
26
+ insertSlice,
27
+ insertTask,
28
+ getTask,
29
+ } from '../gsd-db.ts';
30
+
31
+ let basePath: string;
32
+
33
+ function setupProject(): void {
34
+ basePath = mkdtempSync(join(tmpdir(), 'gsd-completed-at-'));
35
+ // Project structure with active milestone, one slice, one task whose
36
+ // SUMMARY.md is already on disk — but the DB row is still "pending".
37
+ mkdirSync(join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks'), { recursive: true });
38
+
39
+ // CONTEXT + ROADMAP so deriveState identifies M001 as active and S01 as the active slice.
40
+ writeFileSync(
41
+ join(basePath, '.gsd', 'milestones', 'M001', 'M001-CONTEXT.md'),
42
+ '# M001\nActive milestone.\n',
43
+ );
44
+ writeFileSync(
45
+ join(basePath, '.gsd', 'milestones', 'M001', 'M001-ROADMAP.md'),
46
+ `# M001\n\n## Slices\n\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n - After this: works\n`,
47
+ );
48
+
49
+ // Plan file for the slice so reconcile can populate task list if DB is empty.
50
+ writeFileSync(
51
+ join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'S01-PLAN.md'),
52
+ `# S01: Slice\n\n## Tasks\n\n- [ ] **T01: Test task** \`est:30m\`\n - Do: x\n - Verify: y\n`,
53
+ );
54
+
55
+ // The summary file: this is the on-disk evidence that flips the task
56
+ // status to "complete" inside reconcileSliceTasks.
57
+ writeFileSync(
58
+ join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks', 'T01-SUMMARY.md'),
59
+ '---\nid: T01\nparent: S01\nmilestone: M001\nblocker_discovered: false\n---\n# T01\n',
60
+ );
61
+ }
62
+
63
+ describe('completed_at reconcile (#4129)', () => {
64
+ beforeEach(() => {
65
+ setupProject();
66
+ openDatabase(join(basePath, '.gsd', 'gsd.db'));
67
+ insertMilestone({ id: 'M001', title: 'M001', status: 'active' });
68
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Slice', status: 'active' });
69
+ // Task is "pending" in DB, but SUMMARY.md exists on disk → reconcile flips it.
70
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Test task', status: 'pending' });
71
+ invalidateStateCache();
72
+ });
73
+
74
+ afterEach(() => {
75
+ closeDatabase();
76
+ try { rmSync(basePath, { recursive: true, force: true }); } catch { /* */ }
32
77
  });
33
78
 
34
- test("reconcileSliceTasks passes new Date().toISOString() as the completedAt argument", () => {
35
- // Positive assertion: the fixed call must include a timestamp.
36
- assert.match(
37
- stateSource,
38
- /updateTaskStatus\(\s*milestoneId\s*,\s*sliceId\s*,\s*t\.id\s*,\s*["']complete["']\s*,\s*new Date\(\)\.toISOString\(\)\s*\)/,
39
- "reconcileSliceTasks must pass new Date().toISOString() as completedAt when setting task status to 'complete' (#4129)",
79
+ test('reconcileSliceTasks sets completed_at when flipping a pending task to complete via SUMMARY.md', async () => {
80
+ const before = getTask('M001', 'S01', 'T01');
81
+ assert.strictEqual(before?.status, 'pending', 'task starts pending');
82
+ assert.strictEqual(before?.completed_at, null, 'task starts with completed_at NULL');
83
+
84
+ // Trigger the reconcile path (state.ts reconcileSliceTasks).
85
+ await deriveStateFromDb(basePath);
86
+
87
+ const after = getTask('M001', 'S01', 'T01');
88
+ assert.strictEqual(after?.status, 'complete', 'task should be flipped to complete');
89
+ assert.ok(
90
+ typeof after?.completed_at === 'string' && after.completed_at.length > 0,
91
+ `completed_at must be populated by reconcileSliceTasks (#4129); got ${JSON.stringify(after?.completed_at)}`,
92
+ );
93
+ // Sanity: timestamp parses as a valid ISO date.
94
+ assert.ok(
95
+ !Number.isNaN(Date.parse(after!.completed_at!)),
96
+ `completed_at should be a valid ISO timestamp, got ${after!.completed_at}`,
40
97
  );
41
98
  });
42
99
  });
@@ -12,7 +12,7 @@ import { mkdtempSync, rmSync, existsSync } from "node:fs";
12
12
  import { join } from "node:path";
13
13
  import { tmpdir } from "node:os";
14
14
 
15
- import { autoLoop, resolveAgentEnd, _resetPendingResolve } from "../auto-loop.js";
15
+ import { autoLoop, resolveAgentEnd, _hasPendingResolveForTest, _resetPendingResolve } from "../auto-loop.js";
16
16
  import type { LoopDeps } from "../auto/loop-deps.js";
17
17
  import type { SessionLockStatus } from "../session-lock.js";
18
18
  import { writeGraph, readGraph, type WorkflowGraph, type GraphStep } from "../graph.ts";
@@ -29,6 +29,17 @@ function makeTmpDir(): string {
29
29
  return dir;
30
30
  }
31
31
 
32
+ async function resolveNextAgentEnd(timeoutMs = 3_000): Promise<void> {
33
+ const deadline = Date.now() + timeoutMs;
34
+ while (!_hasPendingResolveForTest()) {
35
+ if (Date.now() > deadline) {
36
+ throw new Error("Timed out waiting for pending agent_end resolver");
37
+ }
38
+ await new Promise((r) => setTimeout(r, 5));
39
+ }
40
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
41
+ }
42
+
32
43
  afterEach(() => {
33
44
  _resetPendingResolve();
34
45
  for (const d of tmpDirs) {
@@ -276,19 +287,16 @@ describe("Custom engine loop integration", () => {
276
287
  // We need to resolve resolveAgentEnd for each step.
277
288
 
278
289
  // Step 1: step-a
279
- await new Promise((r) => setTimeout(r, 80));
280
290
  unitCount++;
281
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
291
+ await resolveNextAgentEnd();
282
292
 
283
293
  // Step 2: step-b
284
- await new Promise((r) => setTimeout(r, 80));
285
294
  unitCount++;
286
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
295
+ await resolveNextAgentEnd();
287
296
 
288
297
  // Step 3: step-c
289
- await new Promise((r) => setTimeout(r, 80));
290
298
  unitCount++;
291
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
299
+ await resolveNextAgentEnd();
292
300
 
293
301
  // After step-c completes, engine.reconcile marks it complete, then
294
302
  // next deriveState sees isComplete=true → stopAuto → loop exits
@@ -398,8 +406,7 @@ describe("Custom engine loop integration", () => {
398
406
 
399
407
  const loopPromise = autoLoop(ctx, pi, s, deps);
400
408
 
401
- await new Promise((r) => setTimeout(r, 80));
402
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
409
+ await resolveNextAgentEnd();
403
410
 
404
411
  await loopPromise;
405
412
 
@@ -460,12 +467,10 @@ describe("Custom engine loop integration", () => {
460
467
  const loopPromise = autoLoop(ctx, pi, s, deps);
461
468
 
462
469
  // Resolve step-a
463
- await new Promise((r) => setTimeout(r, 80));
464
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
470
+ await resolveNextAgentEnd();
465
471
 
466
472
  // Resolve step-b
467
- await new Promise((r) => setTimeout(r, 80));
468
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
473
+ await resolveNextAgentEnd();
469
474
 
470
475
  await loopPromise;
471
476
 
@@ -514,7 +519,9 @@ describe("Custom engine loop integration", () => {
514
519
  });
515
520
 
516
521
  const resolver = setInterval(() => {
517
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
522
+ if (_hasPendingResolveForTest()) {
523
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
524
+ }
518
525
  }, 25);
519
526
  let timeout: NodeJS.Timeout | undefined;
520
527
  try {
@@ -569,7 +576,9 @@ describe("Custom engine loop integration", () => {
569
576
  });
570
577
  const deps1 = makeMockDeps();
571
578
  const resolver1 = setInterval(() => {
572
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
579
+ if (_hasPendingResolveForTest()) {
580
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
581
+ }
573
582
  if (pi1.calls.length >= 2) {
574
583
  s1.active = false;
575
584
  }
@@ -614,7 +623,9 @@ describe("Custom engine loop integration", () => {
614
623
  },
615
624
  });
616
625
  const resolver2 = setInterval(() => {
617
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
626
+ if (_hasPendingResolveForTest()) {
627
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
628
+ }
618
629
  }, 25);
619
630
  let timeout2: NodeJS.Timeout | undefined;
620
631
  try {
@@ -640,7 +651,12 @@ describe("Custom engine loop integration", () => {
640
651
  assert.match(stopEntry ?? "", /requested retry 4 times without passing/);
641
652
  });
642
653
 
643
- it("GRAPH.yaml step stays pending when session deactivates before reconcile", async () => {
654
+ it("two-step workflow drives both steps to complete and stops when isComplete fires", async () => {
655
+ // Note (#4831): renamed from "GRAPH.yaml step stays pending when session
656
+ // deactivates before reconcile" — the assertion body never proved the
657
+ // pending-on-deactivate claim and even comments that "the reconcile
658
+ // will still run for step-b". The behaviour this test actually pins is:
659
+ // both steps reconcile complete and stopAuto fires once isComplete.
644
660
  _resetPendingResolve();
645
661
 
646
662
  // Two-step workflow: a → b. We will complete step-a, then force a break
@@ -672,28 +688,30 @@ describe("Custom engine loop integration", () => {
672
688
  const loopPromise = autoLoop(ctx, pi, s, deps);
673
689
 
674
690
  // Resolve step-a successfully
675
- await new Promise((r) => setTimeout(r, 80));
676
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
691
+ await resolveNextAgentEnd();
677
692
 
678
693
  // Step-b enters runUnit — deactivate the session before resolving.
679
694
  // runUnit checks s.active after newSession and returns cancelled if false.
680
695
  // But since newSession resolves synchronously in our mock (before the
681
696
  // active check), the unit still runs. Instead, let's just cancel it.
682
- await new Promise((r) => setTimeout(r, 80));
683
697
  // Resolve as cancelled to simulate a failed session
684
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
698
+ await resolveNextAgentEnd();
685
699
 
686
700
  // The reconcile will still run for step-b in this flow since
687
701
  // runUnitPhase returns "next" (not "break") for completed units.
688
702
  // After both steps complete, the engine detects isComplete and stops.
689
703
  await loopPromise;
690
704
 
691
- // Verify step-a is complete
705
+ // Both steps reconcile complete; the renamed expectation pins that the
706
+ // engine drives the workflow through isComplete rather than leaving any
707
+ // step pending.
692
708
  const finalGraph = readGraph(runDir);
693
709
  const stepA = finalGraph.steps.find(s => s.id === "step-a");
710
+ const stepB = finalGraph.steps.find(s => s.id === "step-b");
694
711
  assert.equal(stepA?.status, "complete", "Step-a should be complete");
712
+ assert.equal(stepB?.status, "complete", "Step-b should be complete");
695
713
 
696
- // Verify the loop stopped appropriately
714
+ // The loop must stop once isComplete fires.
697
715
  assert.ok(
698
716
  deps.callLog.some((e: string) => e.startsWith("stopAuto:")),
699
717
  "stopAuto should have been called",
@@ -16,7 +16,6 @@
16
16
  * retrying can never succeed and causes cost spikes.
17
17
  */
18
18
 
19
- import { readFileSync } from "node:fs";
20
19
  import { join, sep } from "node:path";
21
20
  import { createTestContext } from "./test-helpers.ts";
22
21
 
@@ -89,47 +88,8 @@ assertEq(
89
88
  "Non-worktree path is unchanged",
90
89
  );
91
90
 
92
- // ── Part 2: ensureDbOpen returns structured failure context ──────────────
93
-
94
- console.log("\n=== #2517 Part 2: ensureDbOpen structured diagnostics ===");
95
-
96
- const dynamicToolsSrc = readFileSync(
97
- join(import.meta.dirname, "..", "bootstrap", "dynamic-tools.ts"),
98
- "utf-8",
99
- );
100
-
101
- // ensureDbOpen should surface diagnostic context, not just boolean false
102
- // Check that the catch block logs error details via workflow-logger
103
- assertTrue(
104
- dynamicToolsSrc.includes("ensureDbOpen failed") && dynamicToolsSrc.includes("logWarning"),
105
- "ensureDbOpen catch block surfaces diagnostic information via logWarning instead of bare false (#2517)",
106
- );
107
-
108
- // ── Part 3: post-unit does NOT artifact-retry on db_unavailable ──────────
109
-
110
- console.log("\n=== #2517 Part 3: post-unit db_unavailable is infra-fatal ===");
111
-
112
- const postUnitSrc = readFileSync(
113
- join(import.meta.dirname, "..", "auto-post-unit.ts"),
114
- "utf-8",
115
- );
116
-
117
- // The artifact retry block should check DB availability and skip retry
118
- // when the DB is unavailable (infra failure, not a missing artifact).
119
- assertTrue(
120
- postUnitSrc.includes("db_unavailable") || postUnitSrc.includes("isDbAvailable"),
121
- "post-unit artifact retry path checks DB availability to avoid retry loop (#2517)",
122
- );
123
-
124
- // Verify the retry block is guarded: when !isDbAvailable(), the code must
125
- // NOT return "retry". The pattern should be: if (!verified && !isDbAvailable()) { skip }
126
- // followed by else if (!verified) { ... return "retry" }
127
- const dbUnavailableGuard = postUnitSrc.match(
128
- /!triggerArtifactVerified\s*&&\s*!isDbAvailable\(\)/,
129
- );
130
- assertTrue(
131
- !!dbUnavailableGuard,
132
- "The retry block explicitly guards against !isDbAvailable() before returning 'retry' (#2517)",
133
- );
91
+ // Source-grep checks for ensureDbOpen diagnostics + post-unit retry guard
92
+ // were removed (#4826) — the behavioural retry-loop tests live in
93
+ // auto-post-unit.test.ts and exercise isDbAvailable() directly.
134
94
 
135
95
  report();
@@ -167,9 +167,11 @@ test('auto-prunes old debug logs', () => {
167
167
  enableDebug(tmp);
168
168
 
169
169
  const files = readdirSync(debugDir).filter(f => f.startsWith('debug-') && f.endsWith('.log'));
170
- // Should have at most MAX_DEBUG_LOGS (5) = 5 old + 1 new, but pruned to 5 total
171
- // Actually: prunes to < 5 old, then creates 1 new = at most 5
172
- assert.ok(files.length <= 6, `should have pruned old logs, got ${files.length}`);
170
+ // MAX_DEBUG_LOGS is 5 enableDebug prunes to < 5 old and then creates 1 new,
171
+ // so the directory must hold at most 5 files in total. The previous
172
+ // assertion (<= 6) would have passed even with one stale log left behind
173
+ // (Refs #4831).
174
+ assert.ok(files.length <= 5, `should have pruned old logs to <= 5, got ${files.length}`);
173
175
 
174
176
  disableDebug();
175
177
  });