gsd-pi 2.74.0 → 2.75.0-dev.063e5a3

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 (627) hide show
  1. package/dist/cli.js +85 -0
  2. package/dist/headless-query.js +4 -1
  3. package/dist/help-text.js +23 -0
  4. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  5. package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
  6. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  7. package/dist/resources/extensions/gsd/auto/phases.js +209 -10
  8. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +11 -1
  10. package/dist/resources/extensions/gsd/auto-model-selection.js +54 -8
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +220 -17
  12. package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
  13. package/dist/resources/extensions/gsd/auto-recovery.js +24 -10
  14. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  15. package/dist/resources/extensions/gsd/auto-verification.js +100 -2
  16. package/dist/resources/extensions/gsd/auto-worktree.js +2 -0
  17. package/dist/resources/extensions/gsd/auto.js +36 -4
  18. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -3
  19. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
  20. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +61 -9
  21. package/dist/resources/extensions/gsd/cache.js +16 -5
  22. package/dist/resources/extensions/gsd/commands/catalog.js +31 -1
  23. package/dist/resources/extensions/gsd/commands/handlers/core.js +5 -1
  24. package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
  25. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
  26. package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
  27. package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
  28. package/dist/resources/extensions/gsd/commands-do.js +79 -0
  29. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  30. package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
  31. package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
  32. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +51 -4
  33. package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
  34. package/dist/resources/extensions/gsd/commands-ship.js +187 -0
  35. package/dist/resources/extensions/gsd/db-writer.js +3 -5
  36. package/dist/resources/extensions/gsd/docs/preferences-reference.md +16 -1
  37. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  38. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  39. package/dist/resources/extensions/gsd/git-service.js +49 -1
  40. package/dist/resources/extensions/gsd/graph-context.js +157 -0
  41. package/dist/resources/extensions/gsd/gsd-db.js +581 -2
  42. package/dist/resources/extensions/gsd/guided-flow.js +31 -6
  43. package/dist/resources/extensions/gsd/index.js +15 -2
  44. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  45. package/dist/resources/extensions/gsd/journal.js +27 -0
  46. package/dist/resources/extensions/gsd/md-importer.js +3 -4
  47. package/dist/resources/extensions/gsd/memory-store.js +19 -51
  48. package/dist/resources/extensions/gsd/metrics.js +19 -0
  49. package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
  50. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
  51. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  52. package/dist/resources/extensions/gsd/preferences-models.js +20 -3
  53. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  54. package/dist/resources/extensions/gsd/preferences-validation.js +118 -2
  55. package/dist/resources/extensions/gsd/preferences.js +31 -0
  56. package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
  57. package/dist/resources/extensions/gsd/safety/evidence-collector.js +15 -30
  58. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  59. package/dist/resources/extensions/gsd/state.js +5 -1
  60. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
  61. package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
  62. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  63. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
  64. package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
  65. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  66. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  67. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  68. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  69. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  70. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  71. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  72. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  73. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  74. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  75. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  76. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  77. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  78. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
  79. package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
  80. package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
  81. package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
  82. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  83. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  84. package/dist/web/standalone/.next/BUILD_ID +1 -1
  85. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  86. package/dist/web/standalone/.next/build-manifest.json +3 -3
  87. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  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 -2
  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 +3 -3
  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.js +2 -2
  208. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  210. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  211. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  212. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  213. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  214. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  215. package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
  216. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  217. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  218. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  219. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  220. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  221. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  222. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  223. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  224. package/dist/web/standalone/server.js +1 -1
  225. package/package.json +3 -2
  226. package/packages/daemon/package.json +2 -2
  227. package/packages/mcp-server/dist/index.d.ts +3 -0
  228. package/packages/mcp-server/dist/index.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/index.js +3 -0
  230. package/packages/mcp-server/dist/index.js.map +1 -1
  231. package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
  232. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
  233. package/packages/mcp-server/dist/readers/graph.js +655 -0
  234. package/packages/mcp-server/dist/readers/graph.js.map +1 -0
  235. package/packages/mcp-server/dist/readers/index.d.ts +2 -0
  236. package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
  237. package/packages/mcp-server/dist/readers/index.js +1 -0
  238. package/packages/mcp-server/dist/readers/index.js.map +1 -1
  239. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  240. package/packages/mcp-server/dist/server.js +65 -0
  241. package/packages/mcp-server/dist/server.js.map +1 -1
  242. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  243. package/packages/mcp-server/dist/workflow-tools.js +88 -6
  244. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  245. package/packages/mcp-server/package.json +2 -2
  246. package/packages/mcp-server/src/index.ts +15 -0
  247. package/packages/mcp-server/src/readers/graph.test.ts +604 -0
  248. package/packages/mcp-server/src/readers/graph.ts +855 -0
  249. package/packages/mcp-server/src/readers/index.ts +12 -0
  250. package/packages/mcp-server/src/server.ts +83 -0
  251. package/packages/mcp-server/src/workflow-tools.ts +95 -10
  252. package/packages/mcp-server/tsconfig.json +1 -0
  253. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
  254. package/packages/native/package.json +2 -2
  255. package/packages/native/tsconfig.tsbuildinfo +1 -0
  256. package/packages/pi-agent-core/package.json +1 -1
  257. package/packages/pi-agent-core/tsconfig.json +1 -0
  258. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
  259. package/packages/pi-ai/dist/index.d.ts +1 -9
  260. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  261. package/packages/pi-ai/dist/index.js +1 -9
  262. package/packages/pi-ai/dist/index.js.map +1 -1
  263. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  264. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  265. package/packages/pi-ai/dist/models/capability-patches.js +36 -0
  266. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  267. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  268. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  269. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  270. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  271. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
  272. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  273. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
  274. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  275. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
  276. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  277. package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
  278. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  279. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  280. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  281. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  282. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  283. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  284. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  285. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  286. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  287. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  288. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  289. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  290. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  291. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
  292. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  293. package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
  294. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  295. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  296. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  297. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  298. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  299. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  300. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  301. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  302. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  303. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  304. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  305. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  306. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  307. package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
  308. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  309. package/packages/pi-ai/dist/models/generated/groq.js +311 -0
  310. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  311. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  312. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  313. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  314. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  315. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
  316. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  317. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  318. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  319. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  320. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  321. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  322. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  323. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  324. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  325. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  326. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  327. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  328. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  329. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  330. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  331. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  332. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  333. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  334. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  335. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
  336. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  337. package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
  338. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  339. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  340. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  341. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  342. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  343. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  344. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  345. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  346. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  347. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  348. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  349. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  350. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  351. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
  352. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  353. package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
  354. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  355. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  356. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  357. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  358. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  359. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  360. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  361. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  362. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  363. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  364. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  365. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  366. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  367. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  368. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  369. package/packages/pi-ai/dist/models/index.js +80 -0
  370. package/packages/pi-ai/dist/models/index.js.map +1 -0
  371. package/packages/pi-ai/dist/models.d.ts +1 -36
  372. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  373. package/packages/pi-ai/dist/models.generated.test.js +1 -2
  374. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  375. package/packages/pi-ai/dist/models.js +3 -112
  376. package/packages/pi-ai/dist/models.js.map +1 -1
  377. package/packages/pi-ai/dist/models.test.js +6 -5
  378. package/packages/pi-ai/dist/models.test.js.map +1 -1
  379. package/packages/pi-ai/package.json +1 -1
  380. package/packages/pi-ai/scripts/generate-models.ts +74 -40
  381. package/packages/pi-ai/src/index.ts +1 -9
  382. package/packages/pi-ai/src/models/capability-patches.ts +40 -0
  383. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  384. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
  385. package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
  386. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  387. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  388. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  389. package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
  390. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  391. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  392. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  393. package/packages/pi-ai/src/models/generated/groq.ts +313 -0
  394. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  395. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  396. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  397. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  398. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  399. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  400. package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
  401. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  402. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  403. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  404. package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
  405. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  406. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  407. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  408. package/packages/pi-ai/src/models/index.ts +106 -0
  409. package/packages/pi-ai/src/models.generated.test.ts +1 -2
  410. package/packages/pi-ai/src/models.test.ts +6 -5
  411. package/packages/pi-ai/src/models.ts +3 -153
  412. package/packages/pi-ai/tsconfig.json +1 -0
  413. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
  414. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  415. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
  416. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  417. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +472 -0
  418. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  419. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  420. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  421. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  422. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  423. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  424. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  425. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  426. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.d.ts +2 -0
  427. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.d.ts.map +1 -0
  428. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +61 -0
  429. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -0
  430. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
  431. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  432. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  433. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
  435. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  436. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  437. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  438. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +53 -0
  439. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
  440. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.d.ts +8 -5
  441. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  442. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +27 -13
  443. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  444. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  445. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  446. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +68 -8
  447. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  448. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  449. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
  450. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  451. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  452. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +232 -18
  453. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  454. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  455. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  456. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  457. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  458. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -0
  459. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  460. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +70 -6
  461. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  462. package/packages/pi-coding-agent/package.json +1 -1
  463. package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
  464. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +612 -0
  465. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  466. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  467. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +92 -0
  468. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
  469. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
  470. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +75 -0
  471. package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +36 -15
  472. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +83 -7
  473. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
  474. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +298 -41
  475. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  476. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +92 -6
  477. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  478. package/packages/pi-coding-agent/tsconfig.json +3 -2
  479. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
  480. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  481. package/packages/pi-tui/dist/tui.js +9 -2
  482. package/packages/pi-tui/dist/tui.js.map +1 -1
  483. package/packages/pi-tui/package.json +1 -1
  484. package/packages/pi-tui/src/tui.ts +9 -1
  485. package/packages/pi-tui/tsconfig.json +1 -0
  486. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
  487. package/packages/rpc-client/package.json +1 -1
  488. package/packages/rpc-client/tsconfig.json +1 -0
  489. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
  490. package/pkg/package.json +1 -1
  491. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  492. package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
  493. package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
  494. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  495. package/src/resources/extensions/gsd/auto/phases.ts +261 -10
  496. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  497. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -6
  498. package/src/resources/extensions/gsd/auto-model-selection.ts +69 -8
  499. package/src/resources/extensions/gsd/auto-post-unit.ts +238 -18
  500. package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
  501. package/src/resources/extensions/gsd/auto-recovery.ts +29 -9
  502. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  503. package/src/resources/extensions/gsd/auto-verification.ts +129 -2
  504. package/src/resources/extensions/gsd/auto-worktree.ts +1 -0
  505. package/src/resources/extensions/gsd/auto.ts +41 -2
  506. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +5 -3
  507. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
  508. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +72 -8
  509. package/src/resources/extensions/gsd/cache.ts +16 -5
  510. package/src/resources/extensions/gsd/commands/catalog.ts +31 -1
  511. package/src/resources/extensions/gsd/commands/handlers/core.ts +5 -1
  512. package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
  513. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
  514. package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
  515. package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
  516. package/src/resources/extensions/gsd/commands-do.ts +109 -0
  517. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  518. package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
  519. package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
  520. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +58 -4
  521. package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
  522. package/src/resources/extensions/gsd/commands-ship.ts +219 -0
  523. package/src/resources/extensions/gsd/db-writer.ts +3 -5
  524. package/src/resources/extensions/gsd/docs/preferences-reference.md +16 -1
  525. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  526. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  527. package/src/resources/extensions/gsd/git-service.ts +68 -0
  528. package/src/resources/extensions/gsd/graph-context.ts +212 -0
  529. package/src/resources/extensions/gsd/gsd-db.ts +788 -3
  530. package/src/resources/extensions/gsd/guided-flow.ts +36 -2
  531. package/src/resources/extensions/gsd/index.ts +18 -2
  532. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  533. package/src/resources/extensions/gsd/journal.ts +30 -0
  534. package/src/resources/extensions/gsd/md-importer.ts +3 -5
  535. package/src/resources/extensions/gsd/memory-store.ts +31 -62
  536. package/src/resources/extensions/gsd/metrics.ts +26 -0
  537. package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
  538. package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
  539. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  540. package/src/resources/extensions/gsd/preferences-models.ts +20 -3
  541. package/src/resources/extensions/gsd/preferences-types.ts +38 -0
  542. package/src/resources/extensions/gsd/preferences-validation.ts +117 -2
  543. package/src/resources/extensions/gsd/preferences.ts +34 -0
  544. package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
  545. package/src/resources/extensions/gsd/safety/evidence-collector.ts +15 -31
  546. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  547. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  548. package/src/resources/extensions/gsd/state.ts +9 -2
  549. package/src/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
  550. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +177 -0
  551. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +7 -3
  552. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  553. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  554. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +272 -0
  555. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +117 -0
  556. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  557. package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
  558. package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
  559. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  560. package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
  561. package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
  562. package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
  563. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
  564. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  565. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  566. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
  567. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  568. package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
  569. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  570. package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +71 -4
  572. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  573. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  574. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
  575. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  576. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  577. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  578. package/src/resources/extensions/gsd/tests/preferences.test.ts +145 -0
  579. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +57 -2
  580. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
  581. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
  582. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -5
  583. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  584. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  585. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  586. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  587. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  588. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  589. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  590. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  591. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  592. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  593. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  594. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
  595. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
  596. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  597. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
  598. package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
  599. package/src/resources/extensions/gsd/types.ts +14 -1
  600. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  601. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  602. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  603. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  604. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  605. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  606. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  607. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  608. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  609. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  610. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  611. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  612. package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
  613. package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
  614. package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
  615. package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
  616. package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
  617. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  618. package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
  619. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  620. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  621. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  622. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  623. package/packages/pi-ai/dist/models.generated.js +0 -14343
  624. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  625. package/packages/pi-ai/src/models.generated.ts +0 -14345
  626. /package/dist/web/standalone/.next/static/{JpjdI2QtmIkQr4xz6gbhM → j7IBD35UgrL2b298GLK3V}/_buildManifest.js +0 -0
  627. /package/dist/web/standalone/.next/static/{JpjdI2QtmIkQr4xz6gbhM → j7IBD35UgrL2b298GLK3V}/_ssgManifest.js +0 -0
@@ -0,0 +1,337 @@
1
+ /**
2
+ * graph-context.test.ts — Unit tests for inlineGraphSubgraph().
3
+ *
4
+ * Covers:
5
+ * Group 1: Null-return paths (empty term, zero nodes, missing graph.json)
6
+ * Group 2: Correct output formatting (nodes, edges, stale annotation)
7
+ * Group 3: Node formatting (description, confidence, no-description)
8
+ *
9
+ * Testing strategy:
10
+ * @gsd-build/mcp-server is dynamically imported inside inlineGraphSubgraph().
11
+ * Because node:test (v22) does not support mock.module() without the
12
+ * --experimental-test-module-mocks flag (not enabled in test:unit), we
13
+ * exercise the real graphQuery/graphStatus functions by controlling the
14
+ * on-disk graph.json that those functions read. This is a clean, deterministic
15
+ * approach that avoids all module-level mocking.
16
+ *
17
+ * Fixture layout per test:
18
+ * <tmpDir>/.gsd/graphs/graph.json
19
+ *
20
+ * builtAt controls staleness: old timestamp → stale, recent → fresh.
21
+ */
22
+
23
+ import { describe, it } from "node:test";
24
+ import assert from "node:assert/strict";
25
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
26
+ import { join } from "node:path";
27
+ import { tmpdir } from "node:os";
28
+
29
+ import { inlineGraphSubgraph } from "../graph-context.ts";
30
+
31
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
32
+
33
+ interface TestNode {
34
+ id: string;
35
+ label: string;
36
+ type: string;
37
+ confidence: string;
38
+ description?: string;
39
+ sourceFile?: string;
40
+ }
41
+
42
+ interface TestEdge {
43
+ from: string;
44
+ to: string;
45
+ type: string;
46
+ confidence: string;
47
+ }
48
+
49
+ interface GraphFixture {
50
+ nodes: TestNode[];
51
+ edges: TestEdge[];
52
+ /** ISO timestamp for graph.builtAt. Controls staleness. Default: recent (not stale). */
53
+ builtAt?: string;
54
+ }
55
+
56
+ /** Returns an ISO timestamp that is stale (> 24h ago). */
57
+ function staleTimestamp(hoursAgo = 26): string {
58
+ return new Date(Date.now() - hoursAgo * 60 * 60 * 1000).toISOString();
59
+ }
60
+
61
+ /** Returns an ISO timestamp that is fresh (< 24h ago). */
62
+ function freshTimestamp(): string {
63
+ return new Date(Date.now() - 30 * 60 * 1000).toISOString(); // 30 minutes ago
64
+ }
65
+
66
+ /**
67
+ * Creates a temp project directory with a .gsd/graphs/graph.json file.
68
+ * Returns the projectDir path. Caller is responsible for cleanup.
69
+ */
70
+ function makeProjectDir(fixture: GraphFixture): string {
71
+ const projectDir = mkdtempSync(join(tmpdir(), "graph-ctx-test-"));
72
+ const gsdDir = join(projectDir, ".gsd");
73
+ const graphsDir = join(gsdDir, "graphs");
74
+ mkdirSync(graphsDir, { recursive: true });
75
+
76
+ const graph = {
77
+ nodes: fixture.nodes,
78
+ edges: fixture.edges,
79
+ builtAt: fixture.builtAt ?? freshTimestamp(),
80
+ };
81
+
82
+ writeFileSync(join(graphsDir, "graph.json"), JSON.stringify(graph), "utf-8");
83
+ return projectDir;
84
+ }
85
+
86
+ /** Removes a temp directory, suppressing errors on Windows. */
87
+ function cleanup(dir: string): void {
88
+ try { rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ }
89
+ }
90
+
91
+ /** Minimal node factory. */
92
+ function makeNode(overrides: Partial<TestNode> & { id: string; label: string }): TestNode {
93
+ return {
94
+ type: "CLASS",
95
+ confidence: "INFERRED",
96
+ ...overrides,
97
+ };
98
+ }
99
+
100
+ /** Minimal edge factory. */
101
+ function makeEdge(overrides: Partial<TestEdge> & { from: string; to: string }): TestEdge {
102
+ return {
103
+ type: "CALLS",
104
+ confidence: "INFERRED",
105
+ ...overrides,
106
+ };
107
+ }
108
+
109
+ // ─── Group 1: Null returns ────────────────────────────────────────────────────
110
+
111
+ describe("inlineGraphSubgraph — null returns", () => {
112
+ it("returns null immediately for empty string term", async () => {
113
+ // No graph.json needed — exits before any file I/O
114
+ const result = await inlineGraphSubgraph("/tmp/nonexistent", "", { budget: 3000 });
115
+ assert.strictEqual(result, null);
116
+ });
117
+
118
+ it("returns null for whitespace-only term", async () => {
119
+ const result = await inlineGraphSubgraph("/tmp/nonexistent", " ", { budget: 3000 });
120
+ assert.strictEqual(result, null);
121
+ });
122
+
123
+ it("returns null when graphQuery returns zero nodes (no matching term in graph)", async () => {
124
+ const projectDir = makeProjectDir({
125
+ nodes: [makeNode({ id: "n1", label: "AuthService" })],
126
+ edges: [],
127
+ });
128
+ try {
129
+ // "zzznomatch999" is intentionally absent from the fixture
130
+ const result = await inlineGraphSubgraph(projectDir, "zzznomatch999", { budget: 3000 });
131
+ assert.strictEqual(result, null);
132
+ } finally {
133
+ cleanup(projectDir);
134
+ }
135
+ });
136
+
137
+ it("returns null (no throw) when graph.json is missing", async () => {
138
+ // A project dir with no .gsd directory at all — graphQuery returns zero nodes
139
+ const projectDir = mkdtempSync(join(tmpdir(), "graph-ctx-nofile-"));
140
+ try {
141
+ const result = await inlineGraphSubgraph(projectDir, "auth", { budget: 3000 });
142
+ assert.strictEqual(result, null);
143
+ } finally {
144
+ cleanup(projectDir);
145
+ }
146
+ });
147
+ });
148
+
149
+ // ─── Group 2: Correct output formatting ──────────────────────────────────────
150
+
151
+ describe("inlineGraphSubgraph — correct output", () => {
152
+ it("returns block with section header and node labels when term matches", async () => {
153
+ const projectDir = makeProjectDir({
154
+ nodes: [
155
+ makeNode({ id: "n1", label: "UserService" }),
156
+ makeNode({ id: "n2", label: "UserRepository" }),
157
+ ],
158
+ edges: [],
159
+ });
160
+ try {
161
+ const result = await inlineGraphSubgraph(projectDir, "User", { budget: 3000 });
162
+ assert.ok(result !== null, "result should not be null");
163
+ assert.ok(result!.includes("### Knowledge Graph Context"), "should include section header");
164
+ assert.ok(result!.includes("UserService"), "should include first node label");
165
+ assert.ok(result!.includes("UserRepository"), "should include second node label");
166
+ assert.ok(result!.includes("Nodes (2)"), "should show node count");
167
+ } finally {
168
+ cleanup(projectDir);
169
+ }
170
+ });
171
+
172
+ it("does not include Relations section when edges array is empty", async () => {
173
+ const projectDir = makeProjectDir({
174
+ nodes: [makeNode({ id: "n1", label: "AuthController" })],
175
+ edges: [],
176
+ });
177
+ try {
178
+ const result = await inlineGraphSubgraph(projectDir, "Auth", { budget: 3000 });
179
+ assert.ok(result !== null, "result should not be null");
180
+ assert.ok(!result!.includes("Relations"), "should not include Relations section for zero edges");
181
+ assert.ok(!result!.includes("⚠"), "should not include stale warning for fresh graph");
182
+ } finally {
183
+ cleanup(projectDir);
184
+ }
185
+ });
186
+
187
+ it("includes Relations section when edges are present", async () => {
188
+ const projectDir = makeProjectDir({
189
+ nodes: [
190
+ makeNode({ id: "n1", label: "AuthService" }),
191
+ makeNode({ id: "n2", label: "UserRepo" }),
192
+ ],
193
+ edges: [makeEdge({ from: "n1", to: "n2", type: "CALLS" })],
194
+ });
195
+ try {
196
+ const result = await inlineGraphSubgraph(projectDir, "Auth", { budget: 3000 });
197
+ assert.ok(result !== null, "result should not be null");
198
+ assert.ok(result!.includes("Relations (1)"), "should show edge count");
199
+ assert.ok(result!.includes("→[CALLS]→"), "should include edge type in arrow notation");
200
+ } finally {
201
+ cleanup(projectDir);
202
+ }
203
+ });
204
+
205
+ it("includes stale annotation when graph was built more than 24h ago", async () => {
206
+ const projectDir = makeProjectDir({
207
+ nodes: [makeNode({ id: "n1", label: "AuthService" })],
208
+ edges: [],
209
+ builtAt: staleTimestamp(26), // 26 hours ago → stale
210
+ });
211
+ try {
212
+ const result = await inlineGraphSubgraph(projectDir, "Auth", { budget: 3000 });
213
+ assert.ok(result !== null, "result should not be null");
214
+ assert.ok(result!.includes("⚠ Graph last built"), "should include stale annotation");
215
+ assert.ok(result!.includes("h ago"), "should include hours-ago text");
216
+ } finally {
217
+ cleanup(projectDir);
218
+ }
219
+ });
220
+
221
+ it("does not include stale annotation for a fresh graph", async () => {
222
+ const projectDir = makeProjectDir({
223
+ nodes: [makeNode({ id: "n1", label: "AuthService" })],
224
+ edges: [],
225
+ builtAt: freshTimestamp(), // 30 minutes ago → not stale
226
+ });
227
+ try {
228
+ const result = await inlineGraphSubgraph(projectDir, "Auth", { budget: 3000 });
229
+ assert.ok(result !== null, "result should not be null");
230
+ assert.ok(!result!.includes("⚠"), "should not include stale annotation for fresh graph");
231
+ } finally {
232
+ cleanup(projectDir);
233
+ }
234
+ });
235
+
236
+ it("returns valid block even when graph.json has corrupted builtAt (graphStatus throws internally)", async () => {
237
+ // Write a graph.json with an invalid builtAt — graphStatus will catch and return {exists: false}
238
+ // inlineGraphSubgraph should still return the node block without stale annotation
239
+ const projectDir = mkdtempSync(join(tmpdir(), "graph-ctx-corrupt-"));
240
+ const gsdDir = join(projectDir, ".gsd");
241
+ const graphsDir = join(gsdDir, "graphs");
242
+ mkdirSync(graphsDir, { recursive: true });
243
+
244
+ const graph = {
245
+ nodes: [{ id: "n1", label: "AuthController", type: "CLASS", confidence: "INFERRED" }],
246
+ edges: [],
247
+ builtAt: "NOT-A-DATE", // invalid ISO — will cause Date.now() - NaN to produce NaN
248
+ };
249
+ writeFileSync(join(graphsDir, "graph.json"), JSON.stringify(graph), "utf-8");
250
+
251
+ try {
252
+ const result = await inlineGraphSubgraph(projectDir, "Auth", { budget: 3000 });
253
+ // graphQuery reads the file and finds the node; graphStatus may return {exists: true, stale: false/true}
254
+ // Either way, function must not throw and must return a string with node content
255
+ assert.ok(result !== null, "result should not be null");
256
+ assert.ok(result!.includes("AuthController"), "should include node label");
257
+ } finally {
258
+ cleanup(projectDir);
259
+ }
260
+ });
261
+
262
+ it("passes the budget option to graphQuery (enforces node count limit)", async () => {
263
+ // Each node uses ~20 tokens. With budget=20, only ~1 node should be returned.
264
+ // Build a graph with many nodes all matching the same term.
265
+ const nodes: TestNode[] = Array.from({ length: 10 }, (_, i) =>
266
+ makeNode({ id: `n${i}`, label: `AuthModule${i}` })
267
+ );
268
+ const projectDir = makeProjectDir({ nodes, edges: [] });
269
+ try {
270
+ const resultSmall = await inlineGraphSubgraph(projectDir, "Auth", { budget: 20 });
271
+ const resultLarge = await inlineGraphSubgraph(projectDir, "Auth", { budget: 10000 });
272
+
273
+ // Both should return something (at least 1 node matches)
274
+ assert.ok(resultSmall !== null, "small-budget result should not be null");
275
+ assert.ok(resultLarge !== null, "large-budget result should not be null");
276
+
277
+ // With a very small budget (20 tokens ≈ 1 node), fewer nodes should appear
278
+ const smallNodeCount = (resultSmall!.match(/- \*\*/g) || []).length;
279
+ const largeNodeCount = (resultLarge!.match(/- \*\*/g) || []).length;
280
+ assert.ok(
281
+ smallNodeCount <= largeNodeCount,
282
+ `small-budget should return <= nodes than large-budget (got ${smallNodeCount} vs ${largeNodeCount})`,
283
+ );
284
+ } finally {
285
+ cleanup(projectDir);
286
+ }
287
+ });
288
+ });
289
+
290
+ // ─── Group 3: Node formatting ─────────────────────────────────────────────────
291
+
292
+ describe("inlineGraphSubgraph — node formatting", () => {
293
+ it("includes description after em-dash when node has description", async () => {
294
+ const projectDir = makeProjectDir({
295
+ nodes: [makeNode({ id: "n1", label: "JwtValidator", description: "JWT validation" })],
296
+ edges: [],
297
+ });
298
+ try {
299
+ const result = await inlineGraphSubgraph(projectDir, "Jwt", { budget: 3000 });
300
+ assert.ok(result !== null, "result should not be null");
301
+ assert.ok(result!.includes("— JWT validation"), "should include description after em-dash");
302
+ } finally {
303
+ cleanup(projectDir);
304
+ }
305
+ });
306
+
307
+ it("omits em-dash suffix when node has no description", async () => {
308
+ const projectDir = makeProjectDir({
309
+ nodes: [makeNode({ id: "n1", label: "TokenStore" })], // no description
310
+ edges: [],
311
+ });
312
+ try {
313
+ const result = await inlineGraphSubgraph(projectDir, "Token", { budget: 3000 });
314
+ assert.ok(result !== null, "result should not be null");
315
+ const lines = result!.split("\n");
316
+ const nodeLine = lines.find((l) => l.includes("TokenStore"));
317
+ assert.ok(nodeLine !== undefined, "node line should be present");
318
+ assert.ok(!nodeLine.includes("—"), "node line should not include em-dash when no description");
319
+ } finally {
320
+ cleanup(projectDir);
321
+ }
322
+ });
323
+
324
+ it("includes confidence tier in the node output line", async () => {
325
+ const projectDir = makeProjectDir({
326
+ nodes: [makeNode({ id: "n1", label: "AuthService", confidence: "EXTRACTED" })],
327
+ edges: [],
328
+ });
329
+ try {
330
+ const result = await inlineGraphSubgraph(projectDir, "Auth", { budget: 3000 });
331
+ assert.ok(result !== null, "result should not be null");
332
+ assert.ok(result!.includes("EXTRACTED"), "should include the confidence tier in node line");
333
+ } finally {
334
+ cleanup(projectDir);
335
+ }
336
+ });
337
+ });
@@ -80,7 +80,7 @@ describe('gsd-db', () => {
80
80
  // Check schema_version table
81
81
  const adapter = _getAdapter()!;
82
82
  const version = adapter.prepare('SELECT MAX(version) as version FROM schema_version').get();
83
- assert.deepStrictEqual(version?.['version'], 14, 'schema version should be 14');
83
+ assert.deepStrictEqual(version?.['version'], 15, 'schema version should be 15');
84
84
 
85
85
  // Check tables exist by querying them
86
86
  const dRows = adapter.prepare('SELECT count(*) as cnt FROM decisions').get();
@@ -198,7 +198,7 @@ test("session_start bootstraps the health widget alongside notifications", async
198
198
  },
199
199
  } as any;
200
200
 
201
- registerHooks(pi);
201
+ registerHooks(pi, []);
202
202
  const sessionStart = handlers.get("session_start");
203
203
  assert.ok(sessionStart, "session_start handler is registered");
204
204
 
@@ -92,6 +92,7 @@ function makeMockDeps(
92
92
  getPriorSliceCompletionBlocker: () => null,
93
93
  getMainBranch: () => "main",
94
94
  closeoutUnit: async () => {},
95
+ autoCommitUnit: async () => null,
95
96
  recordOutcome: () => {},
96
97
  writeLock: () => {},
97
98
  captureAvailableSkills: () => {},
@@ -567,7 +568,15 @@ test("unit-end event contains errorContext when unit is cancelled with structure
567
568
  const { resolveAgentEndCancelled, _resetPendingResolve } = await import("../auto-loop.js");
568
569
  _resetPendingResolve();
569
570
 
570
- const deps = makeMockDeps(capture);
571
+ let pauseCalls = 0;
572
+ let commitCalls = 0;
573
+ const deps = makeMockDeps(capture, {
574
+ pauseAuto: async () => { pauseCalls++; },
575
+ autoCommitUnit: async () => {
576
+ commitCalls++;
577
+ return "commit";
578
+ },
579
+ });
571
580
  const ic = makeIC(deps);
572
581
  const iterData: IterationData = {
573
582
  unitType: "execute-task",
@@ -586,17 +595,75 @@ test("unit-end event contains errorContext when unit is cancelled with structure
586
595
  const unitPromise = runUnitPhase(ic, iterData, loopState);
587
596
  await new Promise(r => setTimeout(r, 50));
588
597
 
589
- // Resolve with errorContext (simulates a timeout cancel)
598
+ // Resolve with errorContext (simulates a unit hard timeout — not session creation)
590
599
  resolveAgentEndCancelled({ message: "Hard timeout error: exceeded limit", category: "timeout", isTransient: true });
591
600
 
592
601
  const result = await unitPromise;
593
- // Transient timeout cancellations pause (recoverable) instead of hard-stopping
602
+ // Unit hard timeouts pause (recoverable) without auto-resume
594
603
  assert.equal(result.action, "break");
595
- assert.equal((result as any).reason, "session-timeout");
604
+ assert.equal((result as any).reason, "unit-hard-timeout");
605
+ assert.equal(pauseCalls, 1, "timeout cancellations should pause auto-mode exactly once");
606
+ assert.equal(commitCalls, 1, "timeout cancellations should flush a unit auto-commit once");
596
607
 
597
608
  // Verify error classification used structured errorContext on the window entry
598
609
  const entry = loopState.recentUnits[loopState.recentUnits.length - 1];
599
610
  assert.ok(entry.error, "window entry must have error set");
600
611
  assert.ok(entry.error!.startsWith("timeout:"), "error must start with category from errorContext");
601
612
  assert.ok(entry.error!.includes("Hard timeout error"), "error must include the errorContext message");
613
+
614
+ const endEvents = capture.events.filter(e => e.eventType === "unit-end");
615
+ assert.equal(endEvents.length, 1, "timeout cancellations should still emit unit-end");
616
+ assert.equal((endEvents[0].data as any).status, "cancelled");
617
+ assert.equal((endEvents[0].data as any).artifactVerified, false);
618
+ assert.equal((endEvents[0].data as any).errorContext.category, "timeout");
619
+ });
620
+
621
+ test("session-failed cancellations close out and emit unit-end before hard stop", async () => {
622
+ const capture = createEventCapture();
623
+ const { resolveAgentEndCancelled, _resetPendingResolve } = await import("../auto-loop.js");
624
+ _resetPendingResolve();
625
+
626
+ let closeoutCalls = 0;
627
+ let commitCalls = 0;
628
+ let stopCalls = 0;
629
+ const deps = makeMockDeps(capture, {
630
+ closeoutUnit: async () => { closeoutCalls++; },
631
+ autoCommitUnit: async () => {
632
+ commitCalls++;
633
+ return "commit";
634
+ },
635
+ stopAuto: async () => { stopCalls++; },
636
+ });
637
+ const ic = makeIC(deps);
638
+ const iterData: IterationData = {
639
+ unitType: "execute-task",
640
+ unitId: "M001/S01/T01",
641
+ prompt: "do stuff",
642
+ finalPrompt: "do stuff",
643
+ pauseAfterUatDispatch: false,
644
+ state: { phase: "executing", activeMilestone: { id: "M001" }, activeSlice: { id: "S01" }, registry: [], blockers: [] } as any,
645
+ mid: "M001",
646
+ midTitle: "Test",
647
+ isRetry: false,
648
+ previousTier: undefined,
649
+ };
650
+ const loopState: LoopState = { recentUnits: [{ key: "execute-task/M001/S01/T01" }], stuckRecoveryAttempts: 0, consecutiveFinalizeTimeouts: 0 };
651
+
652
+ const unitPromise = runUnitPhase(ic, iterData, loopState);
653
+ await new Promise(r => setTimeout(r, 50));
654
+
655
+ resolveAgentEndCancelled({ message: "session bootstrap exploded", category: "session-failed", isTransient: false });
656
+
657
+ const result = await unitPromise;
658
+ assert.equal(result.action, "break");
659
+ assert.equal((result as any).reason, "session-failed");
660
+ assert.equal(closeoutCalls, 1, "session-failed cancellations should close out the unit before stopping");
661
+ assert.equal(commitCalls, 1, "session-failed cancellations should try one auto-commit flush");
662
+ assert.equal(stopCalls, 1, "session-failed cancellations should hard-stop auto-mode");
663
+
664
+ const endEvents = capture.events.filter(e => e.eventType === "unit-end");
665
+ assert.equal(endEvents.length, 1, "session-failed cancellations should emit unit-end");
666
+ assert.equal((endEvents[0].data as any).status, "cancelled");
667
+ assert.equal((endEvents[0].data as any).artifactVerified, false);
668
+ assert.equal((endEvents[0].data as any).errorContext.category, "session-failed");
602
669
  });
@@ -363,7 +363,7 @@ test('md-importer: schema v1→v2 migration', () => {
363
363
  openDatabase(':memory:');
364
364
  const adapter = _getAdapter();
365
365
  const version = adapter?.prepare('SELECT MAX(version) as v FROM schema_version').get();
366
- assert.deepStrictEqual(version?.v, 14, 'new DB should be at schema version 14');
366
+ assert.deepStrictEqual(version?.v, 15, 'new DB should be at schema version 15');
367
367
 
368
368
  // Artifacts table should exist
369
369
  const tableCheck = adapter?.prepare("SELECT count(*) as c FROM sqlite_master WHERE type='table' AND name='artifacts'").get();
@@ -413,4 +413,3 @@ test('md-importer: round-trip fidelity', () => {
413
413
  });
414
414
 
415
415
  // ═══════════════════════════════════════════════════════════════════════════
416
-
@@ -323,10 +323,9 @@ test('memory-store: schema includes memories table', () => {
323
323
  const viewCount = adapter.prepare('SELECT count(*) as cnt FROM active_memories').get();
324
324
  assert.deepStrictEqual(viewCount?.['cnt'], 0, 'active_memories view should exist');
325
325
 
326
- // Verify schema version is 14 (after indexes + slice_dependencies)
326
+ // Verify schema version is 15 (UOK gate/git/audit projection tables included)
327
327
  const version = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
328
- assert.deepStrictEqual(version?.['v'], 14, 'schema version should be 14');
328
+ assert.deepStrictEqual(version?.['v'], 15, 'schema version should be 15');
329
329
 
330
330
  closeDatabase();
331
331
  });
332
-
@@ -0,0 +1,140 @@
1
+ // native-git-bridge-exec-fallback.test.ts — regression for #4180
2
+ //
3
+ // nativeCommit, nativeIsRepo, and nativeResetHard used execSync() (string
4
+ // command) in their fallback paths. On Windows, execSync spawns cmd.exe which
5
+ // cannot resolve git when Git for Windows is installed via MSYS2/bash but not
6
+ // in cmd.exe's PATH. All other fallback paths in this file use execFileSync()
7
+ // which invokes the binary directly — these three must do the same.
8
+ //
9
+ // Static-analysis tests fail before the fix (source still has execSync calls)
10
+ // and pass after (replaced with execFileSync). Integration tests verify the
11
+ // fallback functions behave correctly on all platforms.
12
+
13
+ import { describe, test, beforeEach, afterEach } from "node:test";
14
+ import assert from "node:assert/strict";
15
+ import { mkdtempSync, writeFileSync, readFileSync, rmSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import { tmpdir } from "node:os";
18
+ import { execFileSync } from "node:child_process";
19
+ import { nativeIsRepo, nativeCommit, nativeResetHard } from "../native-git-bridge.js";
20
+
21
+ // ─── Static analysis ──────────────────────────────────────────────────────
22
+ // Verify the fallback paths of the three affected functions do not call the
23
+ // raw execSync() string-command variant. Replacing all execFileSync( tokens
24
+ // first ensures we match only the bare execSync( form.
25
+
26
+ const SRC_PATH = join(import.meta.dirname, "..", "native-git-bridge.ts");
27
+
28
+ function extractFunctionBody(src: string, fnName: string): string {
29
+ const idx = src.indexOf(`export function ${fnName}`);
30
+ if (idx === -1) throw new Error(`${fnName} not found in source`);
31
+ return src.slice(idx, idx + 1500);
32
+ }
33
+
34
+ function hasRawExecSync(body: string): boolean {
35
+ const withoutFileSync = body.replace(/execFileSync\(/g, "__FILESYNC__");
36
+ return withoutFileSync.includes("execSync(");
37
+ }
38
+
39
+ describe("native-git-bridge #4180: fallback paths use execFileSync not execSync", () => {
40
+ const src = readFileSync(SRC_PATH, "utf-8");
41
+
42
+ test("nativeIsRepo fallback does not use raw execSync", () => {
43
+ const body = extractFunctionBody(src, "nativeIsRepo");
44
+ assert.equal(
45
+ hasRawExecSync(body),
46
+ false,
47
+ "nativeIsRepo fallback must use execFileSync to avoid cmd.exe PATH failures on Windows",
48
+ );
49
+ });
50
+
51
+ test("nativeCommit fallback does not use raw execSync", () => {
52
+ const body = extractFunctionBody(src, "nativeCommit");
53
+ assert.equal(
54
+ hasRawExecSync(body),
55
+ false,
56
+ "nativeCommit fallback must use execFileSync to avoid cmd.exe PATH failures on Windows",
57
+ );
58
+ });
59
+
60
+ test("nativeResetHard fallback does not use raw execSync", () => {
61
+ const body = extractFunctionBody(src, "nativeResetHard");
62
+ assert.equal(
63
+ hasRawExecSync(body),
64
+ false,
65
+ "nativeResetHard fallback must use execFileSync to avoid cmd.exe PATH failures on Windows",
66
+ );
67
+ });
68
+ });
69
+
70
+ // ─── Integration tests ────────────────────────────────────────────────────
71
+ // Verify correct runtime behaviour through the fallback path (native module
72
+ // is disabled by default in tests — GSD_ENABLE_NATIVE_GSD_GIT is not set).
73
+
74
+ function git(args: string[], cwd: string): string {
75
+ return execFileSync("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
76
+ }
77
+
78
+ describe("native-git-bridge #4180: fallback runtime behaviour", () => {
79
+ let repo: string;
80
+
81
+ beforeEach(() => {
82
+ repo = mkdtempSync(join(tmpdir(), "ngb4180-"));
83
+ git(["init"], repo);
84
+ git(["config", "user.email", "test@test.com"], repo);
85
+ git(["config", "user.name", "Test"], repo);
86
+ writeFileSync(join(repo, "file.txt"), "initial\n");
87
+ git(["add", "."], repo);
88
+ git(["commit", "-m", "init"], repo);
89
+ });
90
+
91
+ afterEach(() => {
92
+ rmSync(repo, { recursive: true, force: true });
93
+ });
94
+
95
+ test("nativeIsRepo returns true for a valid git repository", () => {
96
+ assert.equal(nativeIsRepo(repo), true);
97
+ });
98
+
99
+ test("nativeIsRepo returns false for a plain directory", (t) => {
100
+ const dir = mkdtempSync(join(tmpdir(), "ngb4180-notrepo-"));
101
+ t.after(() => rmSync(dir, { recursive: true, force: true }));
102
+ assert.equal(nativeIsRepo(dir), false);
103
+ });
104
+
105
+ test("nativeCommit commits staged changes and returns non-null output", () => {
106
+ writeFileSync(join(repo, "file.txt"), "modified\n");
107
+ git(["add", "."], repo);
108
+
109
+ const result = nativeCommit(repo, "test: regression commit #4180");
110
+ assert.ok(result !== null, "should return output string for a successful commit");
111
+
112
+ const subject = git(["log", "-1", "--format=%s"], repo);
113
+ assert.equal(subject, "test: regression commit #4180");
114
+ });
115
+
116
+ test("nativeCommit returns null when nothing is staged", () => {
117
+ const result = nativeCommit(repo, "test: nothing staged");
118
+ assert.equal(result, null);
119
+ });
120
+
121
+ test("nativeCommit respects the allowEmpty option", () => {
122
+ const result = nativeCommit(repo, "test: empty commit #4180", { allowEmpty: true });
123
+ assert.ok(result !== null, "allow-empty commit should return output");
124
+
125
+ const subject = git(["log", "-1", "--format=%s"], repo);
126
+ assert.equal(subject, "test: empty commit #4180");
127
+ });
128
+
129
+ test("nativeResetHard discards unstaged working tree changes", () => {
130
+ writeFileSync(join(repo, "file.txt"), "dirty content\n");
131
+
132
+ const statusBefore = git(["status", "--short"], repo);
133
+ assert.ok(statusBefore.length > 0, "repo should be dirty before reset");
134
+
135
+ nativeResetHard(repo);
136
+
137
+ const content = readFileSync(join(repo, "file.txt"), "utf-8");
138
+ assert.equal(content, "initial\n", "file should be restored to HEAD content after hard reset");
139
+ });
140
+ });