gsd-pi 2.78.1-dev.84a383f51 → 2.78.1

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 (474) hide show
  1. package/README.md +7 -7
  2. package/dist/cli.js +55 -95
  3. package/dist/headless-query.d.ts +0 -22
  4. package/dist/headless-query.js +4 -24
  5. package/dist/headless.d.ts +0 -10
  6. package/dist/headless.js +1 -16
  7. package/dist/loader.js +10 -7
  8. package/dist/onboarding.d.ts +0 -10
  9. package/dist/onboarding.js +2 -2
  10. package/dist/provider-migrations.d.ts +2 -2
  11. package/dist/provider-migrations.js +2 -5
  12. package/dist/resource-loader.d.ts +2 -5
  13. package/dist/resource-loader.js +5 -28
  14. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +601 -0
  15. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +651 -0
  16. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +91 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +0 -23
  18. package/dist/resources/extensions/gsd/auto/phases.js +2 -2
  19. package/dist/resources/extensions/gsd/auto/run-unit.js +1 -3
  20. package/dist/resources/extensions/gsd/auto/session.js +0 -3
  21. package/dist/resources/extensions/gsd/auto-recovery.js +4 -43
  22. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  23. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  24. package/dist/resources/extensions/gsd/auto-worktree.js +0 -30
  25. package/dist/resources/extensions/gsd/auto.js +5 -14
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -14
  27. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +5 -7
  28. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  29. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +4 -5
  30. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -94
  31. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +6 -11
  32. package/dist/resources/extensions/gsd/bootstrap/system-context.js +8 -34
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +2 -38
  34. package/dist/resources/extensions/gsd/commands/catalog.js +5 -69
  35. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -22
  36. package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -3
  37. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -10
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -4
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +1 -39
  41. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  42. package/dist/resources/extensions/gsd/forensics.js +2 -2
  43. package/dist/resources/extensions/gsd/git-service.js +5 -12
  44. package/dist/resources/extensions/gsd/gsd-db.js +2 -11
  45. package/dist/resources/extensions/gsd/guided-flow.js +23 -23
  46. package/dist/resources/extensions/gsd/memory-store.js +31 -66
  47. package/dist/resources/extensions/gsd/model-router.js +9 -114
  48. package/dist/resources/extensions/gsd/native-git-bridge.js +1 -7
  49. package/dist/resources/extensions/gsd/preferences-models.js +15 -91
  50. package/dist/resources/extensions/gsd/preferences-types.js +0 -2
  51. package/dist/resources/extensions/gsd/preferences-validation.js +0 -32
  52. package/dist/resources/extensions/gsd/preferences.js +3 -5
  53. package/dist/resources/extensions/gsd/prompt-loader.js +12 -23
  54. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -9
  55. package/dist/resources/extensions/gsd/state.js +0 -42
  56. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
  57. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
  58. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +112 -0
  59. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +23 -0
  60. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +5 -0
  61. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -18
  62. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  63. package/dist/resources/extensions/gsd/watch/header-renderer.js +1 -3
  64. package/dist/resources/extensions/gsd/worktree-command.js +46 -26
  65. package/dist/resources/extensions/mcp-client/index.js +3 -6
  66. package/dist/resources/extensions/slash-commands/create-extension.js +22 -36
  67. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -9
  68. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  69. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  70. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  71. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  72. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  73. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  74. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  75. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
  76. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  77. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +608 -0
  78. package/dist/rtk-shared.d.ts +0 -3
  79. package/dist/rtk-shared.js +0 -17
  80. package/dist/rtk.d.ts +5 -2
  81. package/dist/rtk.js +20 -3
  82. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  85. package/dist/web/standalone/.next/build-manifest.json +4 -4
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/react-loadable-manifest.json +4 -44
  88. package/dist/web/standalone/.next/required-server-files.json +3 -3
  89. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  100. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  148. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  158. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -4
  164. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  178. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  180. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/index.html +1 -1
  194. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  195. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  196. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  197. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  198. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  199. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/page.js +2 -2
  201. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  203. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  204. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  205. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  207. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware.js +2 -2
  209. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  211. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  212. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  213. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  214. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  215. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  216. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +20 -0
  217. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  218. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +1 -0
  223. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  224. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  225. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  226. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  227. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  228. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  229. package/dist/web/standalone/package.json +1 -2
  230. package/dist/web/standalone/server.js +1 -1
  231. package/package.json +1 -1
  232. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  233. package/packages/mcp-server/dist/workflow-tools.js +46 -74
  234. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  235. package/packages/mcp-server/src/workflow-tools.test.ts +0 -26
  236. package/packages/mcp-server/src/workflow-tools.ts +58 -93
  237. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  238. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  239. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  240. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -48
  241. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  242. package/packages/pi-ai/dist/types.d.ts +0 -13
  243. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  244. package/packages/pi-ai/dist/types.js.map +1 -1
  245. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  246. package/packages/pi-ai/dist/utils/repair-tool-json.js +3 -24
  247. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  248. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +0 -26
  249. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  250. package/packages/pi-ai/src/providers/anthropic-shared.ts +20 -52
  251. package/packages/pi-ai/src/types.ts +0 -13
  252. package/packages/pi-ai/src/utils/repair-tool-json.ts +3 -24
  253. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +0 -32
  254. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  255. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/agent-session.js +0 -6
  257. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/messages.js +0 -4
  260. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -19
  262. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -10
  264. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/model-registry.js +0 -18
  266. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +0 -13
  268. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -20
  270. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -14
  274. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  275. package/packages/pi-coding-agent/src/core/agent-session.ts +0 -7
  276. package/packages/pi-coding-agent/src/core/messages.ts +0 -4
  277. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -32
  278. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -21
  279. package/packages/pi-coding-agent/src/core/system-prompt.ts +15 -33
  280. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -17
  281. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  282. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  283. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +3 -17
  284. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  285. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +3 -20
  286. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  287. package/src/resources/extensions/gsd/auto/loop.ts +2 -24
  288. package/src/resources/extensions/gsd/auto/phases.ts +3 -3
  289. package/src/resources/extensions/gsd/auto/run-unit.ts +1 -3
  290. package/src/resources/extensions/gsd/auto/session.ts +0 -3
  291. package/src/resources/extensions/gsd/auto/types.ts +0 -1
  292. package/src/resources/extensions/gsd/auto-recovery.ts +8 -46
  293. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  294. package/src/resources/extensions/gsd/auto-tool-tracking.ts +4 -2
  295. package/src/resources/extensions/gsd/auto-worktree.ts +0 -38
  296. package/src/resources/extensions/gsd/auto.ts +4 -14
  297. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -15
  298. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +7 -8
  299. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  300. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +9 -10
  301. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -102
  302. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +6 -12
  303. package/src/resources/extensions/gsd/bootstrap/system-context.ts +8 -39
  304. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +11 -39
  305. package/src/resources/extensions/gsd/commands/catalog.ts +5 -75
  306. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -22
  307. package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -3
  308. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -15
  309. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  310. package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -4
  311. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +1 -39
  312. package/src/resources/extensions/gsd/doctor-types.ts +1 -3
  313. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  314. package/src/resources/extensions/gsd/forensics.ts +2 -2
  315. package/src/resources/extensions/gsd/git-service.ts +5 -13
  316. package/src/resources/extensions/gsd/gsd-db.ts +2 -12
  317. package/src/resources/extensions/gsd/guided-flow.ts +25 -25
  318. package/src/resources/extensions/gsd/memory-store.ts +28 -81
  319. package/src/resources/extensions/gsd/model-router.ts +9 -172
  320. package/src/resources/extensions/gsd/native-git-bridge.ts +1 -7
  321. package/src/resources/extensions/gsd/preferences-models.ts +15 -101
  322. package/src/resources/extensions/gsd/preferences-types.ts +0 -6
  323. package/src/resources/extensions/gsd/preferences-validation.ts +0 -35
  324. package/src/resources/extensions/gsd/preferences.ts +2 -16
  325. package/src/resources/extensions/gsd/prompt-loader.ts +12 -26
  326. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -9
  327. package/src/resources/extensions/gsd/state.ts +0 -42
  328. package/src/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
  329. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +1 -178
  330. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +0 -58
  331. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +5 -9
  332. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -21
  333. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  334. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +211 -138
  335. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +59 -142
  336. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +4 -7
  337. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +32 -89
  338. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +22 -0
  339. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +23 -41
  340. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +43 -3
  341. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +3 -5
  342. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +87 -22
  343. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +118 -7
  344. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +47 -0
  345. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +60 -18
  346. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +76 -14
  347. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +75 -0
  348. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +83 -22
  349. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +63 -1
  350. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +1 -26
  351. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +0 -30
  352. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +4 -14
  353. package/src/resources/extensions/gsd/tests/health-widget.test.ts +12 -22
  354. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +1 -64
  355. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +0 -22
  356. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +23 -0
  357. package/src/resources/extensions/gsd/tests/memory-store.test.ts +0 -128
  358. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +1 -33
  359. package/src/resources/extensions/gsd/tests/model-router.test.ts +8 -169
  360. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +0 -8
  361. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +43 -32
  362. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +10 -4
  363. package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -127
  364. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +0 -16
  365. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +0 -7
  366. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  367. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +19 -168
  368. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +1 -7
  369. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -23
  370. package/src/resources/extensions/gsd/tests/token-profile.test.ts +4 -51
  371. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +16 -7
  372. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +7 -5
  373. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +1 -15
  374. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  375. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +0 -15
  376. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -17
  377. package/src/resources/extensions/gsd/unit-context-manifest.ts +8 -8
  378. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  379. package/src/resources/extensions/gsd/watch/header-renderer.ts +1 -3
  380. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  381. package/src/resources/extensions/gsd/worktree-command.ts +44 -31
  382. package/src/resources/extensions/mcp-client/index.ts +3 -6
  383. package/src/resources/extensions/slash-commands/create-extension.ts +24 -38
  384. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -9
  385. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  386. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  387. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  388. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  389. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  390. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  391. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  392. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  393. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  394. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
  395. package/dist/cli-policy.d.ts +0 -13
  396. package/dist/cli-policy.js +0 -17
  397. package/dist/resources/.managed-resources-content-hash +0 -1
  398. package/dist/resources/extensions/gsd/auto-runtime-state.js +0 -31
  399. package/dist/resources/extensions/gsd/milestone-id-reservation.js +0 -36
  400. package/dist/resources/extensions/gsd/worktree-session-state.js +0 -33
  401. package/dist/runtime-checks.d.ts +0 -27
  402. package/dist/runtime-checks.js +0 -38
  403. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  404. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +0 -1
  405. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +0 -1
  406. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +0 -1
  407. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +0 -1
  408. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +0 -1
  409. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +0 -10
  410. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +0 -2
  411. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +0 -20
  412. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  413. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +0 -1
  414. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  415. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  416. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +0 -1
  417. package/dist/worktree-status-banner.d.ts +0 -1
  418. package/dist/worktree-status-banner.js +0 -132
  419. package/packages/mcp-server/dist/alias-telemetry.d.ts +0 -8
  420. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +0 -1
  421. package/packages/mcp-server/dist/alias-telemetry.js +0 -30
  422. package/packages/mcp-server/dist/alias-telemetry.js.map +0 -1
  423. package/packages/mcp-server/src/alias-telemetry.test.ts +0 -78
  424. package/packages/mcp-server/src/alias-telemetry.ts +0 -30
  425. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +0 -2
  426. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +0 -1
  427. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +0 -231
  428. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +0 -1
  429. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +0 -289
  430. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +0 -37
  431. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +0 -1
  432. package/packages/pi-coding-agent/dist/core/token-telemetry.js +0 -49
  433. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +0 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +0 -2
  435. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +0 -1
  436. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +0 -133
  437. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +0 -1
  438. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +0 -2
  439. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +0 -1
  440. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +0 -78
  441. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +0 -1
  442. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +0 -2
  443. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +0 -1
  444. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +0 -181
  445. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +0 -1
  446. package/packages/pi-coding-agent/src/core/token-telemetry.ts +0 -77
  447. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +0 -212
  448. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +0 -102
  449. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +0 -200
  450. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +0 -2
  451. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +0 -1
  452. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +0 -161
  453. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +0 -1
  454. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +0 -219
  455. package/src/resources/extensions/gsd/auto-runtime-state.ts +0 -51
  456. package/src/resources/extensions/gsd/milestone-id-reservation.ts +0 -47
  457. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +0 -116
  458. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +0 -100
  459. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +0 -93
  460. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +0 -47
  461. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +0 -63
  462. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +0 -81
  463. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +0 -57
  464. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +0 -145
  465. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +0 -124
  466. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +0 -152
  467. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +0 -50
  468. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +0 -93
  469. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +0 -101
  470. package/src/resources/extensions/gsd/worktree-session-state.ts +0 -35
  471. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +0 -91
  472. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +0 -58
  473. /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_buildManifest.js +0 -0
  474. /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_ssgManifest.js +0 -0
@@ -1,99 +1,42 @@
1
1
  /**
2
- * Behavioural regression test for #4129.
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.
3
4
  *
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.
5
+ * Root cause: reconcileSliceTasks called
6
+ * updateTaskStatus(milestoneId, sliceId, t.id, "complete")
7
+ * without a completedAt timestamp, so the column stays NULL.
8
8
  *
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).
9
+ * Fix: pass new Date().toISOString() as the 5th argument.
13
10
  */
14
11
 
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 { /* */ }
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
+ );
77
32
  });
78
33
 
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}`,
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)",
97
40
  );
98
41
  });
99
42
  });
@@ -0,0 +1,22 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { readFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { extractSourceRegion } from "./test-helpers.ts";
6
+
7
+ test("copyPlanningArtifacts skips when source and destination .gsd resolve to the same path", () => {
8
+ const srcPath = join(import.meta.dirname, "..", "auto-worktree.ts");
9
+ const src = readFileSync(srcPath, "utf-8");
10
+
11
+ const fnIdx = src.indexOf("function copyPlanningArtifacts");
12
+ assert.ok(fnIdx !== -1, "copyPlanningArtifacts function exists");
13
+
14
+ const fnBody = extractSourceRegion(src, "function copyPlanningArtifacts");
15
+
16
+ const guardIdx = fnBody.indexOf("if (isSamePath(srcGsd, dstGsd)) return;");
17
+ const copyIdx = fnBody.indexOf("safeCopyRecursive(join(srcGsd, \"milestones\")");
18
+
19
+ assert.ok(guardIdx !== -1, "copyPlanningArtifacts should guard same-path .gsd copies");
20
+ assert.ok(copyIdx !== -1, "copyPlanningArtifacts should still copy milestones when paths differ");
21
+ assert.ok(guardIdx < copyIdx, "same-path guard should run before any copy attempt");
22
+ });
@@ -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, _hasPendingResolveForTest, _resetPendingResolve } from "../auto-loop.js";
15
+ import { autoLoop, resolveAgentEnd, _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,17 +29,6 @@ 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
-
43
32
  afterEach(() => {
44
33
  _resetPendingResolve();
45
34
  for (const d of tmpDirs) {
@@ -287,16 +276,19 @@ describe("Custom engine loop integration", () => {
287
276
  // We need to resolve resolveAgentEnd for each step.
288
277
 
289
278
  // Step 1: step-a
279
+ await new Promise((r) => setTimeout(r, 80));
290
280
  unitCount++;
291
- await resolveNextAgentEnd();
281
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
292
282
 
293
283
  // Step 2: step-b
284
+ await new Promise((r) => setTimeout(r, 80));
294
285
  unitCount++;
295
- await resolveNextAgentEnd();
286
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
296
287
 
297
288
  // Step 3: step-c
289
+ await new Promise((r) => setTimeout(r, 80));
298
290
  unitCount++;
299
- await resolveNextAgentEnd();
291
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
300
292
 
301
293
  // After step-c completes, engine.reconcile marks it complete, then
302
294
  // next deriveState sees isComplete=true → stopAuto → loop exits
@@ -406,7 +398,8 @@ describe("Custom engine loop integration", () => {
406
398
 
407
399
  const loopPromise = autoLoop(ctx, pi, s, deps);
408
400
 
409
- await resolveNextAgentEnd();
401
+ await new Promise((r) => setTimeout(r, 80));
402
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
410
403
 
411
404
  await loopPromise;
412
405
 
@@ -467,10 +460,12 @@ describe("Custom engine loop integration", () => {
467
460
  const loopPromise = autoLoop(ctx, pi, s, deps);
468
461
 
469
462
  // Resolve step-a
470
- await resolveNextAgentEnd();
463
+ await new Promise((r) => setTimeout(r, 80));
464
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
471
465
 
472
466
  // Resolve step-b
473
- await resolveNextAgentEnd();
467
+ await new Promise((r) => setTimeout(r, 80));
468
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
474
469
 
475
470
  await loopPromise;
476
471
 
@@ -519,9 +514,7 @@ describe("Custom engine loop integration", () => {
519
514
  });
520
515
 
521
516
  const resolver = setInterval(() => {
522
- if (_hasPendingResolveForTest()) {
523
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
524
- }
517
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
525
518
  }, 25);
526
519
  let timeout: NodeJS.Timeout | undefined;
527
520
  try {
@@ -576,9 +569,7 @@ describe("Custom engine loop integration", () => {
576
569
  });
577
570
  const deps1 = makeMockDeps();
578
571
  const resolver1 = setInterval(() => {
579
- if (_hasPendingResolveForTest()) {
580
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
581
- }
572
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
582
573
  if (pi1.calls.length >= 2) {
583
574
  s1.active = false;
584
575
  }
@@ -623,9 +614,7 @@ describe("Custom engine loop integration", () => {
623
614
  },
624
615
  });
625
616
  const resolver2 = setInterval(() => {
626
- if (_hasPendingResolveForTest()) {
627
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
628
- }
617
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
629
618
  }, 25);
630
619
  let timeout2: NodeJS.Timeout | undefined;
631
620
  try {
@@ -651,12 +640,7 @@ describe("Custom engine loop integration", () => {
651
640
  assert.match(stopEntry ?? "", /requested retry 4 times without passing/);
652
641
  });
653
642
 
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.
643
+ it("GRAPH.yaml step stays pending when session deactivates before reconcile", async () => {
660
644
  _resetPendingResolve();
661
645
 
662
646
  // Two-step workflow: a → b. We will complete step-a, then force a break
@@ -688,30 +672,28 @@ describe("Custom engine loop integration", () => {
688
672
  const loopPromise = autoLoop(ctx, pi, s, deps);
689
673
 
690
674
  // Resolve step-a successfully
691
- await resolveNextAgentEnd();
675
+ await new Promise((r) => setTimeout(r, 80));
676
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
692
677
 
693
678
  // Step-b enters runUnit — deactivate the session before resolving.
694
679
  // runUnit checks s.active after newSession and returns cancelled if false.
695
680
  // But since newSession resolves synchronously in our mock (before the
696
681
  // active check), the unit still runs. Instead, let's just cancel it.
682
+ await new Promise((r) => setTimeout(r, 80));
697
683
  // Resolve as cancelled to simulate a failed session
698
- await resolveNextAgentEnd();
684
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
699
685
 
700
686
  // The reconcile will still run for step-b in this flow since
701
687
  // runUnitPhase returns "next" (not "break") for completed units.
702
688
  // After both steps complete, the engine detects isComplete and stops.
703
689
  await loopPromise;
704
690
 
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.
691
+ // Verify step-a is complete
708
692
  const finalGraph = readGraph(runDir);
709
693
  const stepA = finalGraph.steps.find(s => s.id === "step-a");
710
- const stepB = finalGraph.steps.find(s => s.id === "step-b");
711
694
  assert.equal(stepA?.status, "complete", "Step-a should be complete");
712
- assert.equal(stepB?.status, "complete", "Step-b should be complete");
713
695
 
714
- // The loop must stop once isComplete fires.
696
+ // Verify the loop stopped appropriately
715
697
  assert.ok(
716
698
  deps.callLog.some((e: string) => e.startsWith("stopAuto:")),
717
699
  "stopAuto should have been called",
@@ -16,6 +16,7 @@
16
16
  * retrying can never succeed and causes cost spikes.
17
17
  */
18
18
 
19
+ import { readFileSync } from "node:fs";
19
20
  import { join, sep } from "node:path";
20
21
  import { createTestContext } from "./test-helpers.ts";
21
22
 
@@ -88,8 +89,47 @@ assertEq(
88
89
  "Non-worktree path is unchanged",
89
90
  );
90
91
 
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.
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
+ );
94
134
 
95
135
  report();
@@ -167,11 +167,9 @@ 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
- // 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}`);
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}`);
175
173
 
176
174
  disableDebug();
177
175
  });
@@ -1,22 +1,28 @@
1
1
  /**
2
- * Behavioural regression tests for #2892.
2
+ * discuss-empty-db-fallback.test.ts Tests for #2892.
3
3
  *
4
- * When the DB is open but empty (e.g. after crash/truncation),
5
- * getMilestoneSlices() returns []. The fix in showDiscuss() falls back to
6
- * parsing slices from the on-disk ROADMAP file instead of declaring "all
7
- * slices are complete." These tests pin the parser contract that the
8
- * fallback depends on: incomplete checkboxes (`[ ]`) yield `done=false`
9
- * slices and completed checkboxes (`[x]`) yield `done=true`.
10
- *
11
- * The earlier source-grep / regex-on-showDiscuss-body tests (audit verdicts
12
- * SOURCE_GREP / POSITIONAL — see #4826/#4829) were dropped; they pinned a
13
- * specific surface form rather than behaviour.
4
+ * When the DB is open but empty (e.g., after crash/truncation),
5
+ * getMilestoneSlices() returns [] and showDiscuss() incorrectly declares
6
+ * "All slices are complete." The fix adds a roadmap fallback: when the DB
7
+ * returns zero slices but a ROADMAP file exists, parse slices from the
8
+ * roadmap instead of treating zero slices as "all complete."
14
9
  */
15
10
 
16
11
  import { describe, test } from "node:test";
17
12
  import assert from "node:assert/strict";
13
+ import { readFileSync } from "node:fs";
14
+ import { fileURLToPath } from "node:url";
15
+ import { dirname, join } from "node:path";
18
16
  import { parseRoadmapSlices } from "../roadmap-slices.ts";
19
17
 
18
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
19
+
20
+ function readGuidedFlowSource(): string {
21
+ const thisFile = fileURLToPath(import.meta.url);
22
+ const thisDir = dirname(thisFile);
23
+ return readFileSync(join(thisDir, "..", "guided-flow.ts"), "utf-8");
24
+ }
25
+
20
26
  const SAMPLE_ROADMAP = `# M012 Roadmap
21
27
 
22
28
  ## Slices
@@ -28,23 +34,80 @@ const SAMPLE_ROADMAP = `# M012 Roadmap
28
34
  > After this: dashboard renders
29
35
  `;
30
36
 
31
- describe("discuss-empty-db-fallback parser contract (#2892)", () => {
32
- test("parseRoadmapSlices extracts slices from a valid ROADMAP", () => {
37
+ // ─── Tests ───────────────────────────────────────────────────────────────────
38
+
39
+ describe("discuss-empty-db-fallback (#2892)", () => {
40
+
41
+ test("1. parseRoadmapSlices extracts slices from a valid ROADMAP", () => {
33
42
  const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
34
43
  assert.strictEqual(slices.length, 3, "should parse 3 slices from sample roadmap");
35
- const ids = slices.map(s => s.id).sort();
36
- assert.deepStrictEqual(ids, ["S01", "S02", "S03"]);
44
+ assert.strictEqual(slices[0]!.id, "S01");
45
+ assert.strictEqual(slices[1]!.id, "S02");
46
+ assert.strictEqual(slices[2]!.id, "S03");
47
+ // All slices are incomplete ([ ] not [x])
48
+ assert.ok(slices.every(s => !s.done), "all slices should be incomplete");
37
49
  });
38
50
 
39
- test("incomplete checkboxes yield done=false (so fallback shows them as pending)", () => {
40
- const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
51
+ test("2. guided-flow imports parseRoadmapSlices for roadmap fallback", () => {
52
+ const source = readGuidedFlowSource();
53
+ assert.ok(
54
+ source.includes("parseRoadmapSlices"),
55
+ "guided-flow must import parseRoadmapSlices to support roadmap fallback when DB is empty",
56
+ );
57
+ });
58
+
59
+ test("3. guided-flow has roadmap fallback when normSlices is empty but roadmapContent exists", () => {
60
+ const source = readGuidedFlowSource();
61
+ // The fix must add a fallback that checks normSlices.length === 0 && roadmapContent
62
+ // and repopulates normSlices from the roadmap before the pendingSlices guard.
63
+ //
64
+ // Pattern: after DB query produces normSlices, if empty + roadmap exists,
65
+ // fall back to parseRoadmapSlices(roadmapContent).
66
+ const fallbackPattern = /normSlices\.length\s*===\s*0\s*&&\s*roadmapContent/;
41
67
  assert.ok(
42
- slices.every(s => s.done === false),
43
- "all 3 incomplete roadmap slices must be done=false otherwise the empty-DB fallback would falsely report them complete (#2892)",
68
+ fallbackPattern.test(source),
69
+ "guided-flow must check normSlices.length === 0 && roadmapContent to trigger roadmap fallback",
44
70
  );
45
71
  });
46
72
 
47
- test("completed checkboxes yield done=true; mixed roadmap surfaces only the open slices as pending", () => {
73
+ test("4. guided-flow no longer has unguarded pendingSlices === 0 exit after DB-only query", () => {
74
+ const source = readGuidedFlowSource();
75
+ // Extract the showDiscuss function body
76
+ const fnMatch = source.match(
77
+ /async function showDiscuss\s*\([^)]*\)[^{]*\{([\s\S]*?)\nfunction\s/,
78
+ );
79
+ assert.ok(!!fnMatch, "showDiscuss function body must be found");
80
+
81
+ if (fnMatch) {
82
+ const body = fnMatch[1]!;
83
+ // After the DB query block (isDbAvailable/getMilestoneSlices), there should
84
+ // be a roadmap fallback BEFORE the pendingSlices.length === 0 check.
85
+ // Find the getMilestoneSlices call and the pendingSlices === 0 check
86
+ const dbQueryIdx = body.indexOf("getMilestoneSlices");
87
+ const fallbackIdx = body.indexOf("parseRoadmapSlices");
88
+ const pendingGuardIdx = body.indexOf('pendingSlices.length === 0');
89
+
90
+ assert.ok(dbQueryIdx > 0, "getMilestoneSlices call must exist");
91
+ assert.ok(fallbackIdx > 0, "parseRoadmapSlices fallback must exist");
92
+ assert.ok(pendingGuardIdx > 0, "pendingSlices.length === 0 guard must exist");
93
+ assert.ok(
94
+ fallbackIdx > dbQueryIdx && fallbackIdx < pendingGuardIdx,
95
+ "parseRoadmapSlices fallback must appear BETWEEN DB query and pendingSlices === 0 guard",
96
+ );
97
+ }
98
+ });
99
+
100
+ test("5. roadmap-parsed slices map to NormSlice format with done=false by default", () => {
101
+ // When falling back to roadmap, incomplete slices ([ ]) should map to done:false,
102
+ // ensuring they appear as pending and are NOT falsely reported as complete.
103
+ const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
104
+ const normSlices = slices.map(s => ({ id: s.id, done: s.done, title: s.title }));
105
+ const pendingSlices = normSlices.filter(s => !s.done);
106
+ assert.strictEqual(pendingSlices.length, 3,
107
+ "all 3 incomplete roadmap slices should be pending — not falsely treated as complete");
108
+ });
109
+
110
+ test("6. roadmap with completed slices correctly reports them as done", () => {
48
111
  const completedRoadmap = `# M012 Roadmap
49
112
 
50
113
  ## Slices
@@ -56,7 +119,9 @@ describe("discuss-empty-db-fallback parser contract (#2892)", () => {
56
119
  > After this: dashboard renders
57
120
  `;
58
121
  const slices = parseRoadmapSlices(completedRoadmap);
59
- const pendingIds = slices.filter(s => !s.done).map(s => s.id);
60
- assert.deepStrictEqual(pendingIds, ["S02"], "only S02 should be reported as pending");
122
+ const normSlices = slices.map(s => ({ id: s.id, done: s.done, title: s.title }));
123
+ const pendingSlices = normSlices.filter(s => !s.done);
124
+ assert.strictEqual(pendingSlices.length, 1, "only S02 should be pending");
125
+ assert.strictEqual(pendingSlices[0]!.id, "S02");
61
126
  });
62
127
  });