gsd-pi 2.64.0 → 2.65.0-dev.16e10d7

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 (585) hide show
  1. package/dist/headless.js +3 -1
  2. package/dist/mcp-server.js +6 -2
  3. package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +22 -7
  4. package/dist/resources/extensions/bg-shell/process-manager.js +6 -1
  5. package/dist/resources/extensions/browser-tools/capture.js +20 -1
  6. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
  7. package/dist/resources/extensions/gsd/auto/run-unit.js +13 -2
  8. package/dist/resources/extensions/gsd/auto-dashboard.js +5 -5
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +94 -8
  10. package/dist/resources/extensions/gsd/auto-model-selection.js +7 -5
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +115 -7
  12. package/dist/resources/extensions/gsd/auto-prompts.js +24 -0
  13. package/dist/resources/extensions/gsd/auto-recovery.js +12 -8
  14. package/dist/resources/extensions/gsd/auto-start.js +35 -1
  15. package/dist/resources/extensions/gsd/auto-tool-tracking.js +10 -0
  16. package/dist/resources/extensions/gsd/auto-verification.js +138 -1
  17. package/dist/resources/extensions/gsd/auto-worktree.js +29 -7
  18. package/dist/resources/extensions/gsd/auto.js +7 -2
  19. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +17 -4
  20. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +34 -13
  21. package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
  22. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +6 -4
  23. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -1
  24. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +12 -1
  25. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +16 -0
  26. package/dist/resources/extensions/gsd/bootstrap/system-context.js +20 -0
  27. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  28. package/dist/resources/extensions/gsd/commands/context.js +8 -1
  29. package/dist/resources/extensions/gsd/commands/handlers/core.js +21 -0
  30. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +104 -0
  31. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  32. package/dist/resources/extensions/gsd/commands-extensions.js +1 -1
  33. package/dist/resources/extensions/gsd/config-overlay.js +312 -0
  34. package/dist/resources/extensions/gsd/detection.js +1 -1
  35. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  36. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -0
  37. package/dist/resources/extensions/gsd/doctor.js +2 -1
  38. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  39. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  40. package/dist/resources/extensions/gsd/guided-flow.js +220 -29
  41. package/dist/resources/extensions/gsd/md-importer.js +14 -7
  42. package/dist/resources/extensions/gsd/notification-overlay.js +256 -0
  43. package/dist/resources/extensions/gsd/notification-store.js +273 -0
  44. package/dist/resources/extensions/gsd/notification-widget.js +56 -0
  45. package/dist/resources/extensions/gsd/parallel-orchestrator.js +17 -11
  46. package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
  47. package/dist/resources/extensions/gsd/pre-execution-checks.js +471 -0
  48. package/dist/resources/extensions/gsd/preferences-types.js +7 -0
  49. package/dist/resources/extensions/gsd/preferences-validation.js +78 -1
  50. package/dist/resources/extensions/gsd/preferences.js +13 -2
  51. package/dist/resources/extensions/gsd/preparation.js +1092 -0
  52. package/dist/resources/extensions/gsd/prompt-validation.js +67 -0
  53. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
  54. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  55. package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
  56. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
  57. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
  58. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
  59. package/dist/resources/extensions/gsd/prompts/rethink.md +2 -1
  60. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
  61. package/dist/resources/extensions/gsd/quick.js +19 -15
  62. package/dist/resources/extensions/gsd/reactive-graph.js +12 -0
  63. package/dist/resources/extensions/gsd/roadmap-slices.js +24 -5
  64. package/dist/resources/extensions/gsd/safety/content-validator.js +3 -3
  65. package/dist/resources/extensions/gsd/session-lock.js +23 -1
  66. package/dist/resources/extensions/gsd/state.js +100 -12
  67. package/dist/resources/extensions/gsd/templates/context-enhanced.md +138 -0
  68. package/dist/resources/extensions/gsd/tools/complete-slice.js +12 -3
  69. package/dist/resources/extensions/gsd/tools/complete-task.js +16 -4
  70. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -5
  71. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +5 -2
  72. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +119 -0
  73. package/dist/resources/extensions/gsd/tools/reopen-slice.js +30 -0
  74. package/dist/resources/extensions/gsd/tools/reopen-task.js +18 -0
  75. package/dist/resources/extensions/gsd/triage-resolution.js +25 -9
  76. package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
  77. package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
  78. package/dist/resources/extensions/gsd/workflow-projections.js +4 -7
  79. package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -4
  80. package/dist/resources/extensions/gsd/workflow-templates.js +11 -2
  81. package/dist/resources/extensions/gsd/worktree-manager.js +5 -2
  82. package/dist/resources/extensions/gsd/worktree.js +9 -0
  83. package/dist/resources/extensions/shared/interview-ui.js +1 -1
  84. package/dist/web/standalone/.next/BUILD_ID +1 -1
  85. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -14
  86. package/dist/web/standalone/.next/build-manifest.json +4 -4
  87. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  88. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  89. package/dist/web/standalone/.next/required-server-files.json +4 -4
  90. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  91. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  92. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  94. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  102. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  118. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  130. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/notifications/route.js +3 -0
  150. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
  151. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
  152. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  161. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  167. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  181. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  183. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  187. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/index.html +1 -1
  197. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  198. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  199. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  200. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  202. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/page.js +2 -2
  204. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -14
  206. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  207. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  208. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/middleware.js +2 -2
  212. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  214. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  215. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  216. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  217. package/dist/web/standalone/.next/static/Z3TgDP0c7kG9j8CVQVGcl/_buildManifest.js +1 -0
  218. package/dist/web/standalone/.next/static/chunks/6502.8874bcae249c02e1.js +9 -0
  219. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  221. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
  224. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
  228. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
  230. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
  231. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
  232. package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
  233. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
  234. package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
  235. package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
  236. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
  238. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
  239. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
  240. package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
  241. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
  242. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
  244. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
  245. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
  249. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
  250. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
  252. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
  254. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
  259. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
  260. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
  261. package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
  262. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
  263. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  264. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  265. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  266. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
  267. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
  268. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  269. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
  270. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
  271. package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-9fed74684e1c5bb1.js} +1 -1
  272. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  273. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  274. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  275. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  276. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  277. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  278. package/dist/web/standalone/server.js +1 -1
  279. package/package.json +1 -1
  280. package/packages/pi-agent-core/dist/agent-loop.js +26 -9
  281. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  282. package/packages/pi-agent-core/src/agent-loop.test.ts +100 -4
  283. package/packages/pi-agent-core/src/agent-loop.ts +43 -12
  284. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts +2 -0
  285. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts.map +1 -0
  286. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +38 -0
  287. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -0
  288. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/agent-session.js +11 -0
  290. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts +2 -0
  292. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts.map +1 -0
  293. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +24 -0
  294. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -0
  295. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/core/resource-loader.js +4 -1
  297. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/core/retry-handler.js +30 -19
  300. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +51 -0
  302. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/sdk.js +9 -9
  304. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +2 -1
  306. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +10 -1
  308. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  311. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +28 -5
  312. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +15 -1
  314. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +18 -0
  316. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -0
  318. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  319. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +40 -0
  320. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  321. package/packages/pi-coding-agent/package.json +1 -1
  322. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +64 -0
  323. package/packages/pi-coding-agent/src/core/agent-session.ts +10 -0
  324. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +42 -0
  325. package/packages/pi-coding-agent/src/core/resource-loader.ts +5 -1
  326. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +80 -0
  327. package/packages/pi-coding-agent/src/core/retry-handler.ts +37 -25
  328. package/packages/pi-coding-agent/src/core/sdk.ts +9 -9
  329. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +10 -0
  330. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +29 -4
  331. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +27 -0
  332. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +16 -1
  333. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +38 -0
  334. package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts +2 -0
  335. package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts.map +1 -0
  336. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +66 -0
  337. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -0
  338. package/packages/pi-tui/dist/components/image.d.ts +2 -0
  339. package/packages/pi-tui/dist/components/image.d.ts.map +1 -1
  340. package/packages/pi-tui/dist/components/image.js +4 -0
  341. package/packages/pi-tui/dist/components/image.js.map +1 -1
  342. package/packages/pi-tui/dist/components/image.test.d.ts +6 -0
  343. package/packages/pi-tui/dist/components/image.test.d.ts.map +1 -0
  344. package/packages/pi-tui/dist/components/image.test.js +32 -0
  345. package/packages/pi-tui/dist/components/image.test.js.map +1 -0
  346. package/packages/pi-tui/dist/components/loader.d.ts +4 -2
  347. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  348. package/packages/pi-tui/dist/components/loader.js +27 -9
  349. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  350. package/packages/pi-tui/dist/components/text.d.ts.map +1 -1
  351. package/packages/pi-tui/dist/components/text.js +2 -0
  352. package/packages/pi-tui/dist/components/text.js.map +1 -1
  353. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
  354. package/packages/pi-tui/dist/overlay-layout.js +12 -1
  355. package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
  356. package/packages/pi-tui/dist/tui.d.ts +4 -0
  357. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  358. package/packages/pi-tui/dist/tui.js +35 -0
  359. package/packages/pi-tui/dist/tui.js.map +1 -1
  360. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +82 -0
  361. package/packages/pi-tui/src/components/image.test.ts +36 -0
  362. package/packages/pi-tui/src/components/image.ts +5 -0
  363. package/packages/pi-tui/src/components/loader.ts +27 -10
  364. package/packages/pi-tui/src/components/text.ts +1 -0
  365. package/packages/pi-tui/src/overlay-layout.ts +13 -1
  366. package/packages/pi-tui/src/tui.ts +34 -0
  367. package/pkg/package.json +1 -1
  368. package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +19 -7
  369. package/src/resources/extensions/bg-shell/process-manager.ts +8 -2
  370. package/src/resources/extensions/browser-tools/capture.ts +19 -1
  371. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
  372. package/src/resources/extensions/gsd/auto/run-unit.ts +12 -2
  373. package/src/resources/extensions/gsd/auto-dashboard.ts +5 -4
  374. package/src/resources/extensions/gsd/auto-dispatch.ts +105 -8
  375. package/src/resources/extensions/gsd/auto-model-selection.ts +7 -5
  376. package/src/resources/extensions/gsd/auto-post-unit.ts +138 -6
  377. package/src/resources/extensions/gsd/auto-prompts.ts +31 -0
  378. package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
  379. package/src/resources/extensions/gsd/auto-start.ts +38 -0
  380. package/src/resources/extensions/gsd/auto-tool-tracking.ts +10 -0
  381. package/src/resources/extensions/gsd/auto-verification.ts +190 -2
  382. package/src/resources/extensions/gsd/auto-worktree.ts +28 -7
  383. package/src/resources/extensions/gsd/auto.ts +6 -1
  384. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -4
  385. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +35 -13
  386. package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
  387. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -4
  388. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -1
  389. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -1
  390. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +20 -0
  391. package/src/resources/extensions/gsd/bootstrap/system-context.ts +28 -0
  392. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  393. package/src/resources/extensions/gsd/commands/context.ts +7 -1
  394. package/src/resources/extensions/gsd/commands/handlers/core.ts +24 -0
  395. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +140 -0
  396. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  397. package/src/resources/extensions/gsd/commands-extensions.ts +1 -1
  398. package/src/resources/extensions/gsd/config-overlay.ts +331 -0
  399. package/src/resources/extensions/gsd/detection.ts +1 -1
  400. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  401. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -0
  402. package/src/resources/extensions/gsd/doctor.ts +2 -1
  403. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  404. package/src/resources/extensions/gsd/gsd-db.ts +13 -2
  405. package/src/resources/extensions/gsd/guided-flow.ts +254 -30
  406. package/src/resources/extensions/gsd/md-importer.ts +13 -6
  407. package/src/resources/extensions/gsd/notification-overlay.ts +295 -0
  408. package/src/resources/extensions/gsd/notification-store.ts +293 -0
  409. package/src/resources/extensions/gsd/notification-widget.ts +68 -0
  410. package/src/resources/extensions/gsd/parallel-orchestrator.ts +19 -11
  411. package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
  412. package/src/resources/extensions/gsd/pre-execution-checks.ts +581 -0
  413. package/src/resources/extensions/gsd/preferences-types.ts +53 -0
  414. package/src/resources/extensions/gsd/preferences-validation.ts +78 -1
  415. package/src/resources/extensions/gsd/preferences.ts +13 -2
  416. package/src/resources/extensions/gsd/preparation.ts +1419 -0
  417. package/src/resources/extensions/gsd/prompt-validation.ts +88 -0
  418. package/src/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
  419. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  420. package/src/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
  421. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +4 -1
  422. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
  423. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
  424. package/src/resources/extensions/gsd/prompts/rethink.md +2 -1
  425. package/src/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
  426. package/src/resources/extensions/gsd/quick.ts +20 -15
  427. package/src/resources/extensions/gsd/reactive-graph.ts +18 -0
  428. package/src/resources/extensions/gsd/roadmap-slices.ts +21 -5
  429. package/src/resources/extensions/gsd/safety/content-validator.ts +3 -3
  430. package/src/resources/extensions/gsd/session-lock.ts +17 -1
  431. package/src/resources/extensions/gsd/state.ts +101 -11
  432. package/src/resources/extensions/gsd/templates/context-enhanced.md +138 -0
  433. package/src/resources/extensions/gsd/tests/adversarial-review-fixes.test.ts +223 -0
  434. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +33 -2
  435. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +56 -0
  436. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +50 -0
  437. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +41 -0
  438. package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +36 -0
  439. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +72 -0
  440. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +54 -0
  441. package/src/resources/extensions/gsd/tests/defer-milestone-stamp.test.ts +30 -0
  442. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
  443. package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +36 -0
  444. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +46 -0
  445. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
  446. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +33 -0
  447. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +37 -0
  448. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
  449. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +37 -0
  450. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +48 -0
  451. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +42 -0
  452. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +38 -0
  453. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +103 -0
  454. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +42 -0
  455. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +5 -3
  456. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  457. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +28 -30
  458. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  459. package/src/resources/extensions/gsd/tests/integration-prepared-discussion.test.ts +525 -0
  460. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +62 -0
  461. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +48 -0
  462. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +46 -0
  463. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +73 -0
  464. package/src/resources/extensions/gsd/tests/notification-store.test.ts +282 -0
  465. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +77 -0
  466. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +55 -0
  467. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +39 -0
  468. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
  469. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
  470. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +68 -0
  471. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +1197 -0
  472. package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
  473. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
  474. package/src/resources/extensions/gsd/tests/preparation.test.ts +1211 -0
  475. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +53 -0
  476. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +83 -0
  477. package/src/resources/extensions/gsd/tests/prompt-builder.test.ts +669 -0
  478. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +7 -4
  479. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +85 -0
  480. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -1
  481. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +47 -0
  482. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +107 -0
  483. package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +45 -0
  484. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +63 -0
  485. package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +4 -5
  486. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +51 -0
  487. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +56 -0
  488. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +31 -0
  489. package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +39 -0
  490. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +51 -0
  491. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -1
  492. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +36 -0
  493. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +147 -0
  494. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +13 -0
  495. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +21 -0
  496. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +21 -0
  497. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +6 -7
  498. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +47 -0
  499. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +1 -0
  500. package/src/resources/extensions/gsd/tests/symlink-extension-discovery.test.ts +125 -0
  501. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +65 -0
  502. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +29 -1
  503. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
  505. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +3 -4
  506. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +15 -0
  507. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +89 -0
  508. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +48 -0
  509. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +38 -0
  510. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +16 -0
  511. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -0
  512. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +16 -17
  513. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +13 -9
  514. package/src/resources/extensions/gsd/tests/worktree.test.ts +26 -9
  515. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -0
  516. package/src/resources/extensions/gsd/tools/complete-slice.ts +13 -3
  517. package/src/resources/extensions/gsd/tools/complete-task.ts +16 -4
  518. package/src/resources/extensions/gsd/tools/plan-milestone.ts +11 -9
  519. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +5 -2
  520. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +152 -0
  521. package/src/resources/extensions/gsd/tools/reopen-slice.ts +27 -0
  522. package/src/resources/extensions/gsd/tools/reopen-task.ts +17 -0
  523. package/src/resources/extensions/gsd/triage-resolution.ts +29 -10
  524. package/src/resources/extensions/gsd/types.ts +4 -0
  525. package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
  526. package/src/resources/extensions/gsd/workflow-logger.ts +13 -0
  527. package/src/resources/extensions/gsd/workflow-projections.ts +4 -6
  528. package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -3
  529. package/src/resources/extensions/gsd/workflow-templates.ts +11 -2
  530. package/src/resources/extensions/gsd/worktree-manager.ts +4 -2
  531. package/src/resources/extensions/gsd/worktree.ts +10 -0
  532. package/src/resources/extensions/shared/interview-ui.ts +1 -1
  533. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +8 -10
  534. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
  535. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
  536. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
  537. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
  538. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  539. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  540. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
  541. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
  542. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
  543. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
  544. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
  545. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
  546. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
  547. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
  548. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
  549. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
  550. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
  551. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
  552. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
  553. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
  554. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
  555. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
  556. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
  557. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
  558. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
  559. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
  560. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
  561. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
  562. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
  563. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
  564. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
  565. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
  566. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
  567. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
  568. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
  569. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
  570. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  571. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
  572. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  573. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
  574. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
  575. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
  576. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
  577. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  578. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  579. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
  580. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
  581. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  582. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
  583. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
  584. package/dist/web/standalone/.next/static/eebXKteM9EaWyseHKTjqp/_buildManifest.js +0 -1
  585. /package/dist/web/standalone/.next/static/{eebXKteM9EaWyseHKTjqp → Z3TgDP0c7kG9j8CVQVGcl}/_ssgManifest.js +0 -0
@@ -0,0 +1,1197 @@
1
+ /**
2
+ * pre-execution-checks.test.ts — Unit tests for pre-execution validation checks.
3
+ *
4
+ * Tests all 4 check types:
5
+ * 1. Package existence — npm view mocking, timeout handling
6
+ * 2. File path consistency — files exist vs prior expected_output
7
+ * 3. Task ordering — detect impossible read-before-create
8
+ * 4. Interface contracts — contradictory function signatures
9
+ */
10
+
11
+ import { describe, test, mock } from "node:test";
12
+ import assert from "node:assert/strict";
13
+ import { tmpdir } from "node:os";
14
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
15
+ import { join } from "node:path";
16
+
17
+ import {
18
+ extractPackageReferences,
19
+ checkFilePathConsistency,
20
+ checkTaskOrdering,
21
+ checkInterfaceContracts,
22
+ runPreExecutionChecks,
23
+ normalizeFilePath,
24
+ type PreExecutionResult,
25
+ } from "../pre-execution-checks.ts";
26
+ import type { TaskRow } from "../gsd-db.ts";
27
+
28
+ // ─── Test Fixtures ───────────────────────────────────────────────────────────
29
+
30
+ /**
31
+ * Create a minimal TaskRow for testing.
32
+ */
33
+ function createTask(overrides: Partial<TaskRow> = {}): TaskRow {
34
+ return {
35
+ milestone_id: "M001",
36
+ slice_id: "S01",
37
+ id: overrides.id ?? "T01",
38
+ title: "Test Task",
39
+ status: "pending",
40
+ one_liner: "",
41
+ narrative: "",
42
+ verification_result: "",
43
+ duration: "",
44
+ completed_at: null,
45
+ blocker_discovered: false,
46
+ deviations: "",
47
+ known_issues: "",
48
+ key_files: [],
49
+ key_decisions: [],
50
+ full_summary_md: "",
51
+ description: overrides.description ?? "",
52
+ estimate: "",
53
+ files: overrides.files ?? [],
54
+ verify: "",
55
+ inputs: overrides.inputs ?? [],
56
+ expected_output: overrides.expected_output ?? [],
57
+ observability_impact: "",
58
+ full_plan_md: "",
59
+ sequence: overrides.sequence ?? 0,
60
+ ...overrides,
61
+ };
62
+ }
63
+
64
+ // ─── Package Reference Extraction Tests ──────────────────────────────────────
65
+
66
+ describe("extractPackageReferences", () => {
67
+ test("extracts npm install patterns", () => {
68
+ const desc = "Run npm install lodash then npm i axios";
69
+ const packages = extractPackageReferences(desc);
70
+ assert.deepEqual(packages.sort(), ["axios", "lodash"]);
71
+ });
72
+
73
+ test("extracts yarn add patterns", () => {
74
+ const desc = "yarn add react-dom";
75
+ const packages = extractPackageReferences(desc);
76
+ assert.deepEqual(packages, ["react-dom"]);
77
+ });
78
+
79
+ test("extracts scoped packages", () => {
80
+ const desc = "npm install @types/node @babel/core";
81
+ const packages = extractPackageReferences(desc);
82
+ assert.ok(packages.includes("@types/node"));
83
+ assert.ok(packages.includes("@babel/core"));
84
+ });
85
+
86
+ test("extracts require statements from code blocks", () => {
87
+ const desc = `
88
+ \`\`\`javascript
89
+ const fs = require('fs-extra');
90
+ const path = require('path');
91
+ \`\`\`
92
+ `;
93
+ const packages = extractPackageReferences(desc);
94
+ assert.ok(packages.includes("fs-extra"));
95
+ });
96
+
97
+ test("extracts import statements from code blocks", () => {
98
+ const desc = `
99
+ \`\`\`typescript
100
+ import express from 'express';
101
+ import { Router } from 'express';
102
+ import type { Request } from 'express';
103
+ \`\`\`
104
+ `;
105
+ const packages = extractPackageReferences(desc);
106
+ assert.ok(packages.includes("express"));
107
+ });
108
+
109
+ test("ignores relative imports", () => {
110
+ const desc = `import { foo } from './local-file';`;
111
+ const packages = extractPackageReferences(desc);
112
+ assert.deepEqual(packages, []);
113
+ });
114
+
115
+ test("ignores node builtins", () => {
116
+ const desc = `import fs from 'node:fs';`;
117
+ const packages = extractPackageReferences(desc);
118
+ assert.deepEqual(packages, []);
119
+ });
120
+
121
+ test("normalizes package subpaths", () => {
122
+ const desc = "npm install lodash/get";
123
+ const packages = extractPackageReferences(desc);
124
+ assert.deepEqual(packages, ["lodash"]);
125
+ });
126
+
127
+ test("handles empty description", () => {
128
+ const packages = extractPackageReferences("");
129
+ assert.deepEqual(packages, []);
130
+ });
131
+
132
+ test("ignores flags in npm install", () => {
133
+ const desc = "npm install -D typescript";
134
+ const packages = extractPackageReferences(desc);
135
+ assert.ok(packages.includes("typescript"));
136
+ assert.ok(!packages.includes("-D"));
137
+ });
138
+ });
139
+
140
+ // ─── File Path Consistency Tests ─────────────────────────────────────────────
141
+
142
+ describe("checkFilePathConsistency", () => {
143
+ let tempDir: string;
144
+
145
+ test("passes when files exist on disk", () => {
146
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
147
+ mkdirSync(tempDir, { recursive: true });
148
+ writeFileSync(join(tempDir, "existing.ts"), "// content");
149
+
150
+ try {
151
+ const tasks = [
152
+ createTask({
153
+ id: "T01",
154
+ files: ["existing.ts"],
155
+ inputs: [],
156
+ expected_output: [],
157
+ }),
158
+ ];
159
+
160
+ const results = checkFilePathConsistency(tasks, tempDir);
161
+ assert.deepEqual(results, []);
162
+ } finally {
163
+ rmSync(tempDir, { recursive: true, force: true });
164
+ }
165
+ });
166
+
167
+ test("passes when files are in prior expected_output", () => {
168
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
169
+ mkdirSync(tempDir, { recursive: true });
170
+
171
+ try {
172
+ const tasks = [
173
+ createTask({
174
+ id: "T01",
175
+ sequence: 0,
176
+ files: [],
177
+ inputs: [],
178
+ expected_output: ["generated.ts"],
179
+ }),
180
+ createTask({
181
+ id: "T02",
182
+ sequence: 1,
183
+ files: ["generated.ts"],
184
+ inputs: [],
185
+ expected_output: [],
186
+ }),
187
+ ];
188
+
189
+ const results = checkFilePathConsistency(tasks, tempDir);
190
+ assert.deepEqual(results, []);
191
+ } finally {
192
+ rmSync(tempDir, { recursive: true, force: true });
193
+ }
194
+ });
195
+
196
+ test("fails when inputs don't exist and not in prior outputs", () => {
197
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
198
+ mkdirSync(tempDir, { recursive: true });
199
+
200
+ try {
201
+ const tasks = [
202
+ createTask({
203
+ id: "T01",
204
+ files: [],
205
+ inputs: ["nonexistent.ts"],
206
+ expected_output: [],
207
+ }),
208
+ ];
209
+
210
+ const results = checkFilePathConsistency(tasks, tempDir);
211
+ assert.equal(results.length, 1);
212
+ assert.equal(results[0].category, "file");
213
+ assert.equal(results[0].passed, false);
214
+ assert.equal(results[0].blocking, true);
215
+ assert.ok(results[0].message.includes("nonexistent.ts"));
216
+ } finally {
217
+ rmSync(tempDir, { recursive: true, force: true });
218
+ }
219
+ });
220
+
221
+ test("checks only inputs array, not files array", () => {
222
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
223
+ mkdirSync(tempDir, { recursive: true });
224
+
225
+ try {
226
+ const tasks = [
227
+ createTask({
228
+ id: "T01",
229
+ files: ["missing-file.ts"],
230
+ inputs: ["missing-input.ts"],
231
+ expected_output: [],
232
+ }),
233
+ ];
234
+
235
+ // Only inputs are checked — files ("files likely touched") are excluded
236
+ // because they may include files the task will create (#3626)
237
+ const results = checkFilePathConsistency(tasks, tempDir);
238
+ assert.equal(results.length, 1);
239
+ assert.ok(results.some((r) => r.target === "missing-input.ts"));
240
+ // missing-file.ts should NOT produce a failure
241
+ assert.ok(!results.some((r) => r.target === "missing-file.ts"));
242
+ } finally {
243
+ rmSync(tempDir, { recursive: true, force: true });
244
+ }
245
+ });
246
+
247
+ test("skips empty file strings", () => {
248
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
249
+ mkdirSync(tempDir, { recursive: true });
250
+
251
+ try {
252
+ const tasks = [
253
+ createTask({
254
+ id: "T01",
255
+ files: ["", " "],
256
+ inputs: [],
257
+ expected_output: [],
258
+ }),
259
+ ];
260
+
261
+ const results = checkFilePathConsistency(tasks, tempDir);
262
+ assert.deepEqual(results, []);
263
+ } finally {
264
+ rmSync(tempDir, { recursive: true, force: true });
265
+ }
266
+ });
267
+ });
268
+
269
+ // ─── Path Normalization Tests ────────────────────────────────────────────────
270
+
271
+ describe("normalizeFilePath", () => {
272
+ test("strips leading ./", () => {
273
+ assert.equal(normalizeFilePath("./src/a.ts"), "src/a.ts");
274
+ assert.equal(normalizeFilePath("././foo.ts"), "foo.ts");
275
+ });
276
+
277
+ test("normalizes backslashes to forward slashes", () => {
278
+ assert.equal(normalizeFilePath("src\\a.ts"), "src/a.ts");
279
+ assert.equal(normalizeFilePath("src\\sub\\file.ts"), "src/sub/file.ts");
280
+ });
281
+
282
+ test("removes duplicate slashes", () => {
283
+ assert.equal(normalizeFilePath("src//a.ts"), "src/a.ts");
284
+ assert.equal(normalizeFilePath("src///sub//file.ts"), "src/sub/file.ts");
285
+ });
286
+
287
+ test("handles empty string", () => {
288
+ assert.equal(normalizeFilePath(""), "");
289
+ });
290
+
291
+ test("removes trailing slash", () => {
292
+ assert.equal(normalizeFilePath("src/"), "src");
293
+ assert.equal(normalizeFilePath("src/sub/"), "src/sub");
294
+ });
295
+
296
+ test("handles paths without any normalization needed", () => {
297
+ assert.equal(normalizeFilePath("src/a.ts"), "src/a.ts");
298
+ assert.equal(normalizeFilePath("index.ts"), "index.ts");
299
+ });
300
+ });
301
+
302
+ describe("checkFilePathConsistency with path normalization", () => {
303
+ let tempDir: string;
304
+
305
+ test("./path matches path in prior expected_output", () => {
306
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
307
+ mkdirSync(tempDir, { recursive: true });
308
+
309
+ try {
310
+ const tasks = [
311
+ createTask({
312
+ id: "T01",
313
+ sequence: 0,
314
+ files: [],
315
+ inputs: [],
316
+ expected_output: ["src/generated.ts"], // Output without ./
317
+ }),
318
+ createTask({
319
+ id: "T02",
320
+ sequence: 1,
321
+ files: ["./src/generated.ts"], // Input with ./
322
+ inputs: [],
323
+ expected_output: [],
324
+ }),
325
+ ];
326
+
327
+ const results = checkFilePathConsistency(tasks, tempDir);
328
+ assert.deepEqual(results, [], "Should pass because ./src/generated.ts matches src/generated.ts");
329
+ } finally {
330
+ rmSync(tempDir, { recursive: true, force: true });
331
+ }
332
+ });
333
+
334
+ test("path matches ./path in prior expected_output", () => {
335
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
336
+ mkdirSync(tempDir, { recursive: true });
337
+
338
+ try {
339
+ const tasks = [
340
+ createTask({
341
+ id: "T01",
342
+ sequence: 0,
343
+ files: [],
344
+ inputs: [],
345
+ expected_output: ["./src/generated.ts"], // Output with ./
346
+ }),
347
+ createTask({
348
+ id: "T02",
349
+ sequence: 1,
350
+ files: ["src/generated.ts"], // Input without ./
351
+ inputs: [],
352
+ expected_output: [],
353
+ }),
354
+ ];
355
+
356
+ const results = checkFilePathConsistency(tasks, tempDir);
357
+ assert.deepEqual(results, [], "Should pass because src/generated.ts matches ./src/generated.ts");
358
+ } finally {
359
+ rmSync(tempDir, { recursive: true, force: true });
360
+ }
361
+ });
362
+
363
+ test("paths with mixed separators match", () => {
364
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
365
+ mkdirSync(tempDir, { recursive: true });
366
+
367
+ try {
368
+ const tasks = [
369
+ createTask({
370
+ id: "T01",
371
+ sequence: 0,
372
+ files: [],
373
+ inputs: [],
374
+ expected_output: ["src/sub/file.ts"],
375
+ }),
376
+ createTask({
377
+ id: "T02",
378
+ sequence: 1,
379
+ files: ["src\\sub\\file.ts"], // Backslash separators
380
+ inputs: [],
381
+ expected_output: [],
382
+ }),
383
+ ];
384
+
385
+ const results = checkFilePathConsistency(tasks, tempDir);
386
+ assert.deepEqual(results, [], "Should pass because backslash paths normalize to forward slash");
387
+ } finally {
388
+ rmSync(tempDir, { recursive: true, force: true });
389
+ }
390
+ });
391
+ });
392
+
393
+ describe("checkTaskOrdering with path normalization", () => {
394
+ test("./path in inputs triggers ordering check for path in expected_output", () => {
395
+ const tasks = [
396
+ createTask({
397
+ id: "T01",
398
+ sequence: 0,
399
+ files: [],
400
+ inputs: ["./generated.ts"], // Reads with ./
401
+ expected_output: [],
402
+ }),
403
+ createTask({
404
+ id: "T02",
405
+ sequence: 1,
406
+ files: [],
407
+ inputs: [],
408
+ expected_output: ["generated.ts"], // Creates without ./
409
+ }),
410
+ ];
411
+
412
+ const results = checkTaskOrdering(tasks, "/tmp");
413
+ assert.equal(results.length, 1, "Should detect ordering violation despite ./");
414
+ assert.ok(results[0].message.includes("T01"));
415
+ assert.ok(results[0].message.includes("T02"));
416
+ });
417
+
418
+ test("path in inputs triggers ordering check for ./path in expected_output", () => {
419
+ const tasks = [
420
+ createTask({
421
+ id: "T01",
422
+ sequence: 0,
423
+ files: [],
424
+ inputs: ["generated.ts"], // Reads without ./
425
+ expected_output: [],
426
+ }),
427
+ createTask({
428
+ id: "T02",
429
+ sequence: 1,
430
+ files: [],
431
+ inputs: [],
432
+ expected_output: ["./generated.ts"], // Creates with ./
433
+ }),
434
+ ];
435
+
436
+ const results = checkTaskOrdering(tasks, "/tmp");
437
+ assert.equal(results.length, 1, "Should detect ordering violation despite ./ on creator");
438
+ assert.ok(results[0].message.includes("sequence violation"));
439
+ });
440
+
441
+ test("no false positive when correctly ordered with mixed paths", () => {
442
+ const tasks = [
443
+ createTask({
444
+ id: "T01",
445
+ sequence: 0,
446
+ files: [],
447
+ inputs: [],
448
+ expected_output: ["./src/api.ts"],
449
+ }),
450
+ createTask({
451
+ id: "T02",
452
+ sequence: 1,
453
+ files: ["src/api.ts"], // Same file, different notation
454
+ inputs: [],
455
+ expected_output: [],
456
+ }),
457
+ ];
458
+
459
+ const results = checkTaskOrdering(tasks, "/tmp");
460
+ assert.deepEqual(results, [], "Should pass - T02 reads file that T01 already created");
461
+ });
462
+ });
463
+
464
+ // ─── Task Ordering Tests ─────────────────────────────────────────────────────
465
+
466
+ describe("checkTaskOrdering", () => {
467
+ test("passes when tasks are correctly ordered", () => {
468
+ const tasks = [
469
+ createTask({
470
+ id: "T01",
471
+ sequence: 0,
472
+ files: [],
473
+ inputs: [],
474
+ expected_output: ["api.ts"],
475
+ }),
476
+ createTask({
477
+ id: "T02",
478
+ sequence: 1,
479
+ files: ["api.ts"],
480
+ inputs: [],
481
+ expected_output: [],
482
+ }),
483
+ ];
484
+
485
+ const results = checkTaskOrdering(tasks, "/tmp");
486
+ assert.deepEqual(results, []);
487
+ });
488
+
489
+ test("fails when task inputs reference file created by later task", () => {
490
+ const tasks = [
491
+ createTask({
492
+ id: "T01",
493
+ sequence: 0,
494
+ files: [],
495
+ inputs: ["generated.ts"], // Reads file that doesn't exist yet
496
+ expected_output: [],
497
+ }),
498
+ createTask({
499
+ id: "T02",
500
+ sequence: 1,
501
+ files: [],
502
+ inputs: [],
503
+ expected_output: ["generated.ts"], // Creates the file
504
+ }),
505
+ ];
506
+
507
+ const results = checkTaskOrdering(tasks, "/tmp");
508
+ assert.equal(results.length, 1);
509
+ assert.equal(results[0].category, "file");
510
+ assert.equal(results[0].passed, false);
511
+ assert.equal(results[0].blocking, true);
512
+ assert.ok(results[0].message.includes("T01"));
513
+ assert.ok(results[0].message.includes("T02"));
514
+ assert.ok(results[0].message.includes("sequence violation"));
515
+ });
516
+
517
+ test("detects ordering violation in inputs array", () => {
518
+ const tasks = [
519
+ createTask({
520
+ id: "T01",
521
+ sequence: 0,
522
+ files: [],
523
+ inputs: ["schema.json"],
524
+ expected_output: [],
525
+ }),
526
+ createTask({
527
+ id: "T02",
528
+ sequence: 1,
529
+ files: [],
530
+ inputs: [],
531
+ expected_output: ["schema.json"],
532
+ }),
533
+ ];
534
+
535
+ const results = checkTaskOrdering(tasks, "/tmp");
536
+ assert.equal(results.length, 1);
537
+ assert.ok(results[0].message.includes("schema.json"));
538
+ });
539
+
540
+ test("handles multiple ordering violations via inputs", () => {
541
+ const tasks = [
542
+ createTask({
543
+ id: "T01",
544
+ sequence: 0,
545
+ files: [],
546
+ inputs: ["a.ts", "b.ts"],
547
+ expected_output: [],
548
+ }),
549
+ createTask({
550
+ id: "T02",
551
+ sequence: 1,
552
+ files: [],
553
+ inputs: [],
554
+ expected_output: ["a.ts"],
555
+ }),
556
+ createTask({
557
+ id: "T03",
558
+ sequence: 2,
559
+ files: [],
560
+ inputs: [],
561
+ expected_output: ["b.ts"],
562
+ }),
563
+ ];
564
+
565
+ const results = checkTaskOrdering(tasks, "/tmp");
566
+ assert.equal(results.length, 2);
567
+ });
568
+
569
+ test("passes when no dependencies between tasks", () => {
570
+ const tasks = [
571
+ createTask({
572
+ id: "T01",
573
+ sequence: 0,
574
+ files: [],
575
+ inputs: [],
576
+ expected_output: ["a.ts"],
577
+ }),
578
+ createTask({
579
+ id: "T02",
580
+ sequence: 1,
581
+ files: [],
582
+ inputs: [],
583
+ expected_output: ["b.ts"],
584
+ }),
585
+ ];
586
+
587
+ const results = checkTaskOrdering(tasks, "/tmp");
588
+ assert.deepEqual(results, []);
589
+ });
590
+ });
591
+
592
+ // ─── Interface Contract Tests ────────────────────────────────────────────────
593
+
594
+ describe("checkInterfaceContracts", () => {
595
+ test("passes when function signatures match", () => {
596
+ const tasks = [
597
+ createTask({
598
+ id: "T01",
599
+ description: `
600
+ \`\`\`typescript
601
+ function processData(input: string): boolean
602
+ \`\`\`
603
+ `,
604
+ }),
605
+ createTask({
606
+ id: "T02",
607
+ description: `
608
+ \`\`\`typescript
609
+ function processData(input: string): boolean
610
+ \`\`\`
611
+ `,
612
+ }),
613
+ ];
614
+
615
+ const results = checkInterfaceContracts(tasks, "/tmp");
616
+ assert.deepEqual(results, []);
617
+ });
618
+
619
+ test("warns on parameter mismatch (non-blocking)", () => {
620
+ const tasks = [
621
+ createTask({
622
+ id: "T01",
623
+ description: `
624
+ \`\`\`typescript
625
+ function saveUser(name: string): void
626
+ \`\`\`
627
+ `,
628
+ }),
629
+ createTask({
630
+ id: "T02",
631
+ description: `
632
+ \`\`\`typescript
633
+ function saveUser(name: string, email: string): void
634
+ \`\`\`
635
+ `,
636
+ }),
637
+ ];
638
+
639
+ const results = checkInterfaceContracts(tasks, "/tmp");
640
+ assert.equal(results.length, 1);
641
+ assert.equal(results[0].category, "schema");
642
+ assert.equal(results[0].target, "saveUser");
643
+ assert.equal(results[0].passed, true); // Warning, not failure
644
+ assert.equal(results[0].blocking, false);
645
+ assert.ok(results[0].message.includes("different parameters"));
646
+ });
647
+
648
+ test("warns on return type mismatch (non-blocking)", () => {
649
+ const tasks = [
650
+ createTask({
651
+ id: "T01",
652
+ description: `
653
+ \`\`\`typescript
654
+ function getData(): string
655
+ \`\`\`
656
+ `,
657
+ }),
658
+ createTask({
659
+ id: "T02",
660
+ description: `
661
+ \`\`\`typescript
662
+ function getData(): number
663
+ \`\`\`
664
+ `,
665
+ }),
666
+ ];
667
+
668
+ const results = checkInterfaceContracts(tasks, "/tmp");
669
+ assert.equal(results.length, 1);
670
+ assert.ok(results[0].message.includes("different return types"));
671
+ });
672
+
673
+ test("handles export function syntax", () => {
674
+ const tasks = [
675
+ createTask({
676
+ id: "T01",
677
+ description: `
678
+ \`\`\`typescript
679
+ export function validate(data: object): boolean
680
+ \`\`\`
681
+ `,
682
+ }),
683
+ createTask({
684
+ id: "T02",
685
+ description: `
686
+ \`\`\`typescript
687
+ export function validate(data: string): boolean
688
+ \`\`\`
689
+ `,
690
+ }),
691
+ ];
692
+
693
+ const results = checkInterfaceContracts(tasks, "/tmp");
694
+ assert.equal(results.length, 1);
695
+ assert.ok(results[0].message.includes("validate"));
696
+ });
697
+
698
+ test("handles async function syntax", () => {
699
+ const tasks = [
700
+ createTask({
701
+ id: "T01",
702
+ description: `
703
+ \`\`\`typescript
704
+ export async function fetchData(): Promise<string>
705
+ \`\`\`
706
+ `,
707
+ }),
708
+ createTask({
709
+ id: "T02",
710
+ description: `
711
+ \`\`\`typescript
712
+ export async function fetchData(): Promise<number>
713
+ \`\`\`
714
+ `,
715
+ }),
716
+ ];
717
+
718
+ const results = checkInterfaceContracts(tasks, "/tmp");
719
+ assert.equal(results.length, 1);
720
+ });
721
+
722
+ test("handles const arrow function syntax", () => {
723
+ const tasks = [
724
+ createTask({
725
+ id: "T01",
726
+ description: `
727
+ \`\`\`typescript
728
+ const handler = (req: Request): Response =>
729
+ \`\`\`
730
+ `,
731
+ }),
732
+ createTask({
733
+ id: "T02",
734
+ description: `
735
+ \`\`\`typescript
736
+ const handler = (req: Request, res: Response): void =>
737
+ \`\`\`
738
+ `,
739
+ }),
740
+ ];
741
+
742
+ const results = checkInterfaceContracts(tasks, "/tmp");
743
+ // Should have 2 results: parameter mismatch AND return type mismatch
744
+ assert.equal(results.length, 2);
745
+ assert.ok(results.some((r) => r.message.includes("handler")));
746
+ assert.ok(results.some((r) => r.message.includes("parameters")));
747
+ assert.ok(results.some((r) => r.message.includes("return types")));
748
+ });
749
+
750
+ test("passes when no code blocks present", () => {
751
+ const tasks = [
752
+ createTask({
753
+ id: "T01",
754
+ description: "Just some text without code blocks",
755
+ }),
756
+ ];
757
+
758
+ const results = checkInterfaceContracts(tasks, "/tmp");
759
+ assert.deepEqual(results, []);
760
+ });
761
+
762
+ test("handles multiple mismatches for same function", () => {
763
+ const tasks = [
764
+ createTask({
765
+ id: "T01",
766
+ description: `
767
+ \`\`\`typescript
768
+ function process(a: string): string
769
+ \`\`\`
770
+ `,
771
+ }),
772
+ createTask({
773
+ id: "T02",
774
+ description: `
775
+ \`\`\`typescript
776
+ function process(a: number): number
777
+ \`\`\`
778
+ `,
779
+ }),
780
+ ];
781
+
782
+ const results = checkInterfaceContracts(tasks, "/tmp");
783
+ // Should have both parameter and return type mismatches
784
+ assert.equal(results.length, 2);
785
+ });
786
+ });
787
+
788
+ // ─── runPreExecutionChecks Integration Tests ─────────────────────────────────
789
+
790
+ describe("runPreExecutionChecks", () => {
791
+ let tempDir: string;
792
+
793
+ test("returns pass status when all checks pass", async () => {
794
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
795
+ mkdirSync(tempDir, { recursive: true });
796
+ writeFileSync(join(tempDir, "existing.ts"), "// content");
797
+
798
+ try {
799
+ const tasks = [
800
+ createTask({
801
+ id: "T01",
802
+ files: ["existing.ts"],
803
+ inputs: [],
804
+ expected_output: ["output.ts"],
805
+ }),
806
+ createTask({
807
+ id: "T02",
808
+ files: ["output.ts"],
809
+ inputs: [],
810
+ expected_output: [],
811
+ }),
812
+ ];
813
+
814
+ const result = await runPreExecutionChecks(tasks, tempDir);
815
+ assert.equal(result.status, "pass");
816
+ assert.equal(result.checks.length, 0);
817
+ assert.ok(result.durationMs >= 0);
818
+ } finally {
819
+ rmSync(tempDir, { recursive: true, force: true });
820
+ }
821
+ });
822
+
823
+ test("returns fail status when blocking failure exists", async () => {
824
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
825
+ mkdirSync(tempDir, { recursive: true });
826
+
827
+ try {
828
+ const tasks = [
829
+ createTask({
830
+ id: "T01",
831
+ files: [],
832
+ inputs: ["nonexistent.ts"],
833
+ expected_output: [],
834
+ }),
835
+ ];
836
+
837
+ const result = await runPreExecutionChecks(tasks, tempDir);
838
+ assert.equal(result.status, "fail");
839
+ assert.ok(result.checks.length > 0);
840
+ assert.ok(result.checks.some((c) => c.blocking === true));
841
+ } finally {
842
+ rmSync(tempDir, { recursive: true, force: true });
843
+ }
844
+ });
845
+
846
+ test("returns warn status for non-blocking issues", async () => {
847
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
848
+ mkdirSync(tempDir, { recursive: true });
849
+
850
+ try {
851
+ // Create tasks with only interface contract warnings
852
+ const tasks = [
853
+ createTask({
854
+ id: "T01",
855
+ files: [],
856
+ inputs: [],
857
+ expected_output: [],
858
+ description: `
859
+ \`\`\`typescript
860
+ function foo(a: string): void
861
+ \`\`\`
862
+ `,
863
+ }),
864
+ createTask({
865
+ id: "T02",
866
+ files: [],
867
+ inputs: [],
868
+ expected_output: [],
869
+ description: `
870
+ \`\`\`typescript
871
+ function foo(a: number): void
872
+ \`\`\`
873
+ `,
874
+ }),
875
+ ];
876
+
877
+ const result = await runPreExecutionChecks(tasks, tempDir);
878
+ assert.equal(result.status, "warn");
879
+ assert.ok(result.checks.some((c) => c.blocking === false));
880
+ } finally {
881
+ rmSync(tempDir, { recursive: true, force: true });
882
+ }
883
+ });
884
+
885
+ test("combines results from all check types", async () => {
886
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
887
+ mkdirSync(tempDir, { recursive: true });
888
+
889
+ try {
890
+ const tasks = [
891
+ createTask({
892
+ id: "T01",
893
+ sequence: 0,
894
+ files: ["will-be-created.ts"], // Ordering violation
895
+ inputs: ["missing.ts"], // Missing file
896
+ expected_output: [],
897
+ description: `
898
+ \`\`\`typescript
899
+ function check(a: string): void
900
+ \`\`\`
901
+ `,
902
+ }),
903
+ createTask({
904
+ id: "T02",
905
+ sequence: 1,
906
+ files: [],
907
+ inputs: [],
908
+ expected_output: ["will-be-created.ts"],
909
+ description: `
910
+ \`\`\`typescript
911
+ function check(a: number): void
912
+ \`\`\`
913
+ `,
914
+ }),
915
+ ];
916
+
917
+ const result = await runPreExecutionChecks(tasks, tempDir);
918
+ assert.equal(result.status, "fail");
919
+
920
+ // Should have multiple types of issues
921
+ const categories = new Set(result.checks.map((c) => c.category));
922
+ assert.ok(categories.has("file")); // From consistency and ordering
923
+ assert.ok(categories.has("schema")); // From interface check
924
+ } finally {
925
+ rmSync(tempDir, { recursive: true, force: true });
926
+ }
927
+ });
928
+
929
+ test("reports duration in milliseconds", async () => {
930
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
931
+ mkdirSync(tempDir, { recursive: true });
932
+
933
+ try {
934
+ const tasks = [createTask({ id: "T01" })];
935
+ const result = await runPreExecutionChecks(tasks, tempDir);
936
+
937
+ assert.ok(typeof result.durationMs === "number");
938
+ assert.ok(result.durationMs >= 0);
939
+ } finally {
940
+ rmSync(tempDir, { recursive: true, force: true });
941
+ }
942
+ });
943
+
944
+ test("handles empty task array", async () => {
945
+ tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
946
+ mkdirSync(tempDir, { recursive: true });
947
+
948
+ try {
949
+ const result = await runPreExecutionChecks([], tempDir);
950
+ assert.equal(result.status, "pass");
951
+ assert.deepEqual(result.checks, []);
952
+ } finally {
953
+ rmSync(tempDir, { recursive: true, force: true });
954
+ }
955
+ });
956
+ });
957
+
958
+ // ─── Regression Tests: checkTaskOrdering false positive (#3677) ──────────────
959
+
960
+ describe("checkTaskOrdering false positive regression (#3677)", () => {
961
+ test("task.files should not trigger ordering violation when file is in later expected_output", () => {
962
+ // T01 has files: ["component.tsx"] — this is a file the task will CREATE,
963
+ // not read. Including task.files in the ordering check causes a false positive.
964
+ // After fix (check only task.inputs), this should return 0 results.
965
+ const tasks = [
966
+ createTask({
967
+ id: "T01",
968
+ sequence: 0,
969
+ files: ["component.tsx"],
970
+ inputs: [],
971
+ expected_output: [],
972
+ }),
973
+ createTask({
974
+ id: "T02",
975
+ sequence: 1,
976
+ files: [],
977
+ inputs: [],
978
+ expected_output: ["component.tsx"],
979
+ }),
980
+ ];
981
+
982
+ const results = checkTaskOrdering(tasks, "/tmp");
983
+ assert.equal(results.length, 0, "task.files should not be checked for ordering violations");
984
+ });
985
+
986
+ test("task.files with multiple files should not trigger false positives", () => {
987
+ // T01 lists several files it will touch/create — none should trigger ordering
988
+ // violations just because T02 declares one of them as expected_output.
989
+ const tasks = [
990
+ createTask({
991
+ id: "T01",
992
+ sequence: 0,
993
+ files: ["a.ts", "b.ts", "c.ts"],
994
+ inputs: [],
995
+ expected_output: [],
996
+ }),
997
+ createTask({
998
+ id: "T02",
999
+ sequence: 1,
1000
+ files: [],
1001
+ inputs: [],
1002
+ expected_output: ["b.ts"],
1003
+ }),
1004
+ ];
1005
+
1006
+ const results = checkTaskOrdering(tasks, "/tmp");
1007
+ assert.equal(results.length, 0, "Multiple task.files should not generate false positive violations");
1008
+ });
1009
+
1010
+ test("task.inputs SHOULD still trigger ordering violation", () => {
1011
+ // task.inputs represents files a task genuinely needs to READ, so a sequence
1012
+ // violation here is a real error and must still be detected.
1013
+ const tasks = [
1014
+ createTask({
1015
+ id: "T01",
1016
+ sequence: 0,
1017
+ files: [],
1018
+ inputs: ["config.json"],
1019
+ expected_output: [],
1020
+ }),
1021
+ createTask({
1022
+ id: "T02",
1023
+ sequence: 1,
1024
+ files: [],
1025
+ inputs: [],
1026
+ expected_output: ["config.json"],
1027
+ }),
1028
+ ];
1029
+
1030
+ const results = checkTaskOrdering(tasks, "/tmp");
1031
+ assert.equal(results.length, 1, "task.inputs ordering violation must still be detected");
1032
+ assert.equal(results[0].blocking, true);
1033
+ assert.ok(results[0].message.includes("T01"));
1034
+ assert.ok(results[0].message.includes("T02"));
1035
+ assert.ok(results[0].message.includes("sequence violation"));
1036
+ });
1037
+
1038
+ test("mixed files and inputs — only inputs trigger ordering violation", () => {
1039
+ // T01 will create "created.ts" (files) and also needs to READ "needed.json" (inputs).
1040
+ // T02 creates both. Only the inputs dependency is a real violation.
1041
+ const tasks = [
1042
+ createTask({
1043
+ id: "T01",
1044
+ sequence: 0,
1045
+ files: ["created.ts"],
1046
+ inputs: ["needed.json"],
1047
+ expected_output: [],
1048
+ }),
1049
+ createTask({
1050
+ id: "T02",
1051
+ sequence: 1,
1052
+ files: [],
1053
+ inputs: [],
1054
+ expected_output: ["created.ts", "needed.json"],
1055
+ }),
1056
+ ];
1057
+
1058
+ const results = checkTaskOrdering(tasks, "/tmp");
1059
+ assert.equal(results.length, 1, "Only the inputs entry should produce a violation, not files");
1060
+ assert.ok(results[0].target === "needed.json", "Violation target should be the input, not the file");
1061
+ });
1062
+
1063
+ test("task.files with normalized paths should not false-positive", () => {
1064
+ // Path normalization (./src/new-file.ts → src/new-file.ts) should not cause
1065
+ // task.files to match against expected_output and produce a false positive.
1066
+ const tasks = [
1067
+ createTask({
1068
+ id: "T01",
1069
+ sequence: 0,
1070
+ files: ["./src/new-file.ts"],
1071
+ inputs: [],
1072
+ expected_output: [],
1073
+ }),
1074
+ createTask({
1075
+ id: "T02",
1076
+ sequence: 1,
1077
+ files: [],
1078
+ inputs: [],
1079
+ expected_output: ["src/new-file.ts"],
1080
+ }),
1081
+ ];
1082
+
1083
+ const results = checkTaskOrdering(tasks, "/tmp");
1084
+ assert.equal(results.length, 0, "Normalized task.files path should not trigger a false positive");
1085
+ });
1086
+ });
1087
+
1088
+ // ─── checkFilePathConsistency additional edge cases ──────────────────────────
1089
+
1090
+ describe("checkFilePathConsistency additional edge cases", () => {
1091
+ test("inputs referencing glob-like patterns should not crash", () => {
1092
+ // A glob pattern in inputs is unusual but should be handled gracefully.
1093
+ // The file won't exist on disk, so it should produce a blocking result.
1094
+ const tasks = [
1095
+ createTask({
1096
+ id: "T01",
1097
+ files: [],
1098
+ inputs: ["src/**/*.ts"],
1099
+ expected_output: [],
1100
+ }),
1101
+ ];
1102
+
1103
+ // Should not throw
1104
+ let results: ReturnType<typeof checkFilePathConsistency>;
1105
+ assert.doesNotThrow(() => {
1106
+ results = checkFilePathConsistency(tasks, "/tmp");
1107
+ });
1108
+ assert.equal(results!.length, 1, "Glob-pattern input that doesn't exist should produce a blocking result");
1109
+ assert.equal(results![0].blocking, true);
1110
+ });
1111
+
1112
+ test("empty inputs array produces no results", () => {
1113
+ // A task with no inputs and only files should produce zero results from
1114
+ // consistency check — files are not checked (#3626).
1115
+ const tasks = [
1116
+ createTask({
1117
+ id: "T01",
1118
+ files: ["anything.ts"],
1119
+ inputs: [],
1120
+ expected_output: [],
1121
+ }),
1122
+ ];
1123
+
1124
+ const results = checkFilePathConsistency(tasks, "/tmp");
1125
+ assert.equal(results.length, 0, "Empty inputs should produce no consistency check results");
1126
+ });
1127
+
1128
+ test("inputs with absolute paths are checked correctly", () => {
1129
+ // An absolute path in inputs should resolve to itself and pass when the file exists.
1130
+ const tempDir = join(tmpdir(), `pre-exec-test-abs-${Date.now()}`);
1131
+ mkdirSync(tempDir, { recursive: true });
1132
+ const absFilePath = join(tempDir, "real-file.ts");
1133
+ writeFileSync(absFilePath, "// content");
1134
+
1135
+ try {
1136
+ const tasks = [
1137
+ createTask({
1138
+ id: "T01",
1139
+ files: [],
1140
+ inputs: [absFilePath],
1141
+ expected_output: [],
1142
+ }),
1143
+ ];
1144
+
1145
+ const results = checkFilePathConsistency(tasks, tempDir);
1146
+ assert.equal(results.length, 0, "Absolute path to an existing file should pass consistency check");
1147
+ } finally {
1148
+ rmSync(tempDir, { recursive: true, force: true });
1149
+ }
1150
+ });
1151
+ });
1152
+
1153
+ // ─── PreExecutionResult Type Tests ───────────────────────────────────────────
1154
+
1155
+ describe("PreExecutionResult type", () => {
1156
+ test("status is one of pass, warn, fail", async () => {
1157
+ const tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
1158
+ mkdirSync(tempDir, { recursive: true });
1159
+
1160
+ try {
1161
+ const tasks = [createTask({ id: "T01" })];
1162
+ const result = await runPreExecutionChecks(tasks, tempDir);
1163
+
1164
+ assert.ok(["pass", "warn", "fail"].includes(result.status));
1165
+ } finally {
1166
+ rmSync(tempDir, { recursive: true, force: true });
1167
+ }
1168
+ });
1169
+
1170
+ test("checks array matches PreExecutionCheckJSON schema", async () => {
1171
+ const tempDir = join(tmpdir(), `pre-exec-test-${Date.now()}`);
1172
+ mkdirSync(tempDir, { recursive: true });
1173
+
1174
+ try {
1175
+ const tasks = [
1176
+ createTask({
1177
+ id: "T01",
1178
+ files: ["missing.ts"],
1179
+ }),
1180
+ ];
1181
+
1182
+ const result = await runPreExecutionChecks(tasks, tempDir);
1183
+
1184
+ for (const check of result.checks) {
1185
+ assert.ok(["package", "file", "tool", "endpoint", "schema"].includes(check.category));
1186
+ assert.ok(typeof check.target === "string");
1187
+ assert.ok(typeof check.passed === "boolean");
1188
+ assert.ok(typeof check.message === "string");
1189
+ if (check.blocking !== undefined) {
1190
+ assert.ok(typeof check.blocking === "boolean");
1191
+ }
1192
+ }
1193
+ } finally {
1194
+ rmSync(tempDir, { recursive: true, force: true });
1195
+ }
1196
+ });
1197
+ });