gsd-pi 2.49.0 → 2.50.0-dev.d210a87

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 (679) hide show
  1. package/README.md +2 -0
  2. package/dist/cli.js +26 -0
  3. package/dist/headless-ui.js +12 -2
  4. package/dist/headless.js +29 -13
  5. package/dist/loader.js +4 -0
  6. package/dist/resource-loader.d.ts +4 -1
  7. package/dist/resource-loader.js +138 -3
  8. package/dist/resources/extensions/async-jobs/async-bash-tool.js +3 -1
  9. package/dist/resources/extensions/bg-shell/interaction.js +3 -1
  10. package/dist/resources/extensions/bg-shell/process-manager.js +4 -1
  11. package/dist/resources/extensions/claude-code-cli/partial-builder.js +5 -0
  12. package/dist/resources/extensions/gsd/auto/infra-errors.js +1 -0
  13. package/dist/resources/extensions/gsd/auto/phases.js +27 -12
  14. package/dist/resources/extensions/gsd/auto/resolve.js +2 -2
  15. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -2
  16. package/dist/resources/extensions/gsd/auto/session.js +9 -0
  17. package/dist/resources/extensions/gsd/auto-artifact-paths.js +8 -10
  18. package/dist/resources/extensions/gsd/auto-dashboard.js +28 -6
  19. package/dist/resources/extensions/gsd/auto-dispatch.js +113 -74
  20. package/dist/resources/extensions/gsd/auto-observability.js +54 -0
  21. package/dist/resources/extensions/gsd/auto-post-unit.js +53 -99
  22. package/dist/resources/extensions/gsd/auto-prompts.js +155 -17
  23. package/dist/resources/extensions/gsd/auto-recovery.js +79 -205
  24. package/dist/resources/extensions/gsd/auto-start.js +4 -31
  25. package/dist/resources/extensions/gsd/auto-timers.js +2 -2
  26. package/dist/resources/extensions/gsd/auto-utils.js +20 -0
  27. package/dist/resources/extensions/gsd/auto-verification.js +4 -7
  28. package/dist/resources/extensions/gsd/auto-worktree.js +257 -113
  29. package/dist/resources/extensions/gsd/auto.js +22 -10
  30. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -0
  31. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +24 -1
  32. package/dist/resources/extensions/gsd/branch-patterns.js +13 -0
  33. package/dist/resources/extensions/gsd/crash-recovery.js +6 -2
  34. package/dist/resources/extensions/gsd/custom-execution-policy.js +3 -2
  35. package/dist/resources/extensions/gsd/custom-verification.js +3 -1
  36. package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -2
  37. package/dist/resources/extensions/gsd/dashboard-overlay.js +4 -0
  38. package/dist/resources/extensions/gsd/detection.js +589 -3
  39. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  40. package/dist/resources/extensions/gsd/docs/preferences-reference.md +15 -0
  41. package/dist/resources/extensions/gsd/doctor-checks.js +5 -1234
  42. package/dist/resources/extensions/gsd/doctor-engine-checks.js +168 -0
  43. package/dist/resources/extensions/gsd/doctor-environment.js +28 -7
  44. package/dist/resources/extensions/gsd/doctor-git-checks.js +405 -0
  45. package/dist/resources/extensions/gsd/doctor-global-checks.js +74 -0
  46. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +600 -0
  47. package/dist/resources/extensions/gsd/doctor.js +9 -1
  48. package/dist/resources/extensions/gsd/extension-manifest.json +1 -1
  49. package/dist/resources/extensions/gsd/files.js +5 -1
  50. package/dist/resources/extensions/gsd/git-service.js +9 -10
  51. package/dist/resources/extensions/gsd/gsd-db.js +124 -1
  52. package/dist/resources/extensions/gsd/guided-flow-queue.js +10 -11
  53. package/dist/resources/extensions/gsd/guided-flow.js +10 -0
  54. package/dist/resources/extensions/gsd/init-wizard.js +9 -1
  55. package/dist/resources/extensions/gsd/markdown-renderer.js +33 -5
  56. package/dist/resources/extensions/gsd/model-router.js +25 -0
  57. package/dist/resources/extensions/gsd/notifications.js +23 -0
  58. package/dist/resources/extensions/gsd/observability-validator.js +422 -0
  59. package/dist/resources/extensions/gsd/preferences-skills.js +11 -5
  60. package/dist/resources/extensions/gsd/preferences-types.js +3 -1
  61. package/dist/resources/extensions/gsd/preferences-validation.js +64 -0
  62. package/dist/resources/extensions/gsd/preferences.js +3 -0
  63. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
  64. package/dist/resources/extensions/gsd/prompts/complete-slice.md +9 -8
  65. package/dist/resources/extensions/gsd/prompts/execute-task.md +16 -13
  66. package/dist/resources/extensions/gsd/prompts/forensics.md +19 -8
  67. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
  68. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  71. package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  73. package/dist/resources/extensions/gsd/prompts/plan-slice.md +8 -3
  74. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
  75. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  77. package/dist/resources/extensions/gsd/provider-error-pause.js +8 -0
  78. package/dist/resources/extensions/gsd/repo-identity.js +29 -0
  79. package/dist/resources/extensions/gsd/roadmap-mutations.js +110 -0
  80. package/dist/resources/extensions/gsd/roadmap-slices.js +2 -2
  81. package/dist/resources/extensions/gsd/rtk-status.js +43 -0
  82. package/dist/resources/extensions/gsd/rule-registry.js +10 -11
  83. package/dist/resources/extensions/gsd/session-forensics.js +13 -14
  84. package/dist/resources/extensions/gsd/session-lock.js +67 -56
  85. package/dist/resources/extensions/gsd/skill-catalog.js +1026 -0
  86. package/dist/resources/extensions/gsd/skill-discovery.js +3 -2
  87. package/dist/resources/extensions/gsd/skill-health.js +2 -2
  88. package/dist/resources/extensions/gsd/skill-telemetry.js +15 -5
  89. package/dist/resources/extensions/gsd/state.js +51 -12
  90. package/dist/resources/extensions/gsd/templates/milestone-summary.md +8 -0
  91. package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  92. package/dist/resources/extensions/gsd/templates/plan.md +16 -0
  93. package/dist/resources/extensions/gsd/templates/preferences.md +2 -0
  94. package/dist/resources/extensions/gsd/templates/roadmap.md +13 -0
  95. package/dist/resources/extensions/gsd/templates/slice-summary.md +9 -0
  96. package/dist/resources/extensions/gsd/templates/task-plan.md +24 -0
  97. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  98. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -1
  99. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -3
  100. package/dist/resources/extensions/gsd/undo.js +8 -7
  101. package/dist/resources/extensions/gsd/unit-runtime.js +2 -1
  102. package/dist/resources/extensions/gsd/verdict-parser.js +84 -0
  103. package/dist/resources/extensions/gsd/verification-gate.js +3 -1
  104. package/dist/resources/extensions/gsd/worktree-resolver.js +24 -0
  105. package/dist/resources/extensions/gsd/worktree.js +3 -2
  106. package/dist/resources/extensions/remote-questions/config.js +3 -5
  107. package/dist/resources/extensions/search-the-web/native-search.js +8 -3
  108. package/dist/resources/extensions/search-the-web/tool-search.js +19 -2
  109. package/dist/resources/extensions/shared/rtk-session-stats.js +189 -0
  110. package/dist/resources/extensions/shared/rtk.js +100 -0
  111. package/dist/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
  112. package/dist/rtk.d.ts +52 -0
  113. package/dist/rtk.js +332 -0
  114. package/dist/web/standalone/.next/BUILD_ID +1 -1
  115. package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -19
  116. package/dist/web/standalone/.next/build-manifest.json +4 -4
  117. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  118. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  119. package/dist/web/standalone/.next/required-server-files.json +3 -3
  120. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  121. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  122. package/dist/web/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  125. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  133. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/experimental/route.js +3 -0
  171. package/dist/web/standalone/.next/server/app/api/experimental/route.js.nft.json +1 -0
  172. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -0
  173. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/preferences/route.js.nft.json +1 -1
  205. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  211. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -26
  213. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js.nft.json +1 -1
  214. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  217. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  220. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  222. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  223. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  226. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  229. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  232. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  235. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  238. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  240. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  241. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  242. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  243. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js.nft.json +1 -1
  244. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  246. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js.nft.json +1 -1
  247. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  249. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  250. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  252. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  253. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  255. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js.nft.json +1 -1
  256. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  257. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  259. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  260. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  261. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  262. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  263. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  264. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  265. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app/index.html +1 -1
  267. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  268. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  269. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  270. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  271. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  272. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  273. package/dist/web/standalone/.next/server/app/page.js +2 -2
  274. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  275. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  276. package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -19
  277. package/dist/web/standalone/.next/server/chunks/2229.js +12 -0
  278. package/dist/web/standalone/.next/server/chunks/2331.js +25 -0
  279. package/dist/web/standalone/.next/server/chunks/{741.js → 4741.js} +1 -1
  280. package/dist/web/standalone/.next/server/chunks/5822.js +2 -0
  281. package/dist/web/standalone/.next/server/chunks/7471.js +13 -0
  282. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  283. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  284. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  285. package/dist/web/standalone/.next/server/middleware.js +3 -3
  286. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  287. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  288. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  289. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  290. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  291. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  292. package/dist/web/standalone/.next/static/chunks/{485.243af25f0cdf50d6.js → 2008.817d0885545aaea9.js} +6 -6
  293. package/dist/web/standalone/.next/static/chunks/4024.9ad5def014d90ce4.js +9 -0
  294. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +1 -0
  295. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  296. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +1 -0
  297. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +1 -0
  298. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  299. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  300. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +1 -0
  301. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +1 -0
  302. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +1 -0
  303. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +1 -0
  304. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +1 -0
  305. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +1 -0
  306. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +1 -0
  307. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +1 -0
  308. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +1 -0
  309. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +1 -0
  310. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +1 -0
  311. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +1 -0
  312. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +1 -0
  313. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +1 -0
  314. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +1 -0
  315. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +1 -0
  316. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +1 -0
  317. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +1 -0
  318. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +1 -0
  319. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +1 -0
  320. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +1 -0
  321. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +1 -0
  322. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +1 -0
  323. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +1 -0
  324. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +1 -0
  325. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +1 -0
  326. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +1 -0
  327. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +1 -0
  328. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +1 -0
  329. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +1 -0
  330. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  331. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +1 -0
  332. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  333. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +1 -0
  334. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +1 -0
  335. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +1 -0
  336. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +1 -0
  337. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  338. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  339. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  340. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +1 -0
  341. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +1 -0
  342. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  343. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +1 -0
  344. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +1 -0
  345. package/dist/web/standalone/.next/static/chunks/webpack-cfc9a116e6450a6b.js +1 -0
  346. package/dist/web/standalone/.next/static/css/de141508b083f922.css +1 -0
  347. package/dist/web/standalone/.next/static/yJIyd5cXPNpmXTv18ZlyC/_buildManifest.js +1 -0
  348. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  349. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  350. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  351. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  352. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  353. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  354. package/dist/web/standalone/server.js +1 -1
  355. package/package.json +1 -1
  356. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  357. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  358. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  359. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  360. package/packages/pi-ai/dist/providers/openai-codex-responses.js +39 -10
  361. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  362. package/packages/pi-ai/dist/types.d.ts +1 -0
  363. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  364. package/packages/pi-ai/dist/types.js.map +1 -1
  365. package/packages/pi-ai/src/providers/openai-codex-responses.ts +39 -8
  366. package/packages/pi-ai/src/types.ts +1 -1
  367. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
  368. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
  370. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts +3 -1
  372. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/bash-executor.js +10 -1
  374. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/blob-store.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/blob-store.js +8 -3
  377. package/packages/pi-coding-agent/dist/core/blob-store.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/discovery-cache.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/discovery-cache.js +9 -2
  380. package/packages/pi-coding-agent/dist/core/discovery-cache.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  382. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
  385. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/extensions/runner.js +13 -0
  387. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +19 -1
  389. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  391. package/packages/pi-coding-agent/dist/core/extensions/wrapper.d.ts.map +1 -1
  392. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js +8 -0
  393. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/package-manager.js +8 -1
  396. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/core/retry-handler.js +1 -1
  398. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  399. package/packages/pi-coding-agent/dist/core/skills.d.ts +11 -1
  400. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  401. package/packages/pi-coding-agent/dist/core/skills.js +30 -8
  402. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  403. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  404. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  405. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  406. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  407. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  408. package/packages/pi-coding-agent/dist/index.js +1 -1
  409. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  410. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  411. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +3 -2
  412. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  413. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -36
  415. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  416. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +5 -0
  417. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  418. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +12 -0
  419. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +2 -1
  422. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.d.ts.map +1 -1
  424. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js +5 -0
  425. package/packages/pi-coding-agent/dist/modes/rpc/jsonl.js.map +1 -1
  426. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +0 -1
  428. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  429. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  430. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  431. package/packages/pi-coding-agent/package.json +1 -1
  432. package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
  433. package/packages/pi-coding-agent/src/core/bash-executor.ts +10 -2
  434. package/packages/pi-coding-agent/src/core/blob-store.ts +6 -3
  435. package/packages/pi-coding-agent/src/core/discovery-cache.ts +9 -2
  436. package/packages/pi-coding-agent/src/core/extensions/index.ts +2 -0
  437. package/packages/pi-coding-agent/src/core/extensions/runner.ts +18 -0
  438. package/packages/pi-coding-agent/src/core/extensions/types.ts +21 -0
  439. package/packages/pi-coding-agent/src/core/extensions/wrapper.ts +9 -0
  440. package/packages/pi-coding-agent/src/core/package-manager.ts +10 -1
  441. package/packages/pi-coding-agent/src/core/retry-handler.ts +1 -1
  442. package/packages/pi-coding-agent/src/core/skills.ts +35 -10
  443. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  444. package/packages/pi-coding-agent/src/index.ts +4 -0
  445. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +3 -2
  446. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -36
  447. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +15 -0
  448. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +2 -1
  449. package/packages/pi-coding-agent/src/modes/rpc/jsonl.ts +6 -0
  450. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +0 -2
  451. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
  452. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  453. package/pkg/dist/modes/interactive/theme/themes.js +2 -1
  454. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  455. package/pkg/package.json +1 -1
  456. package/scripts/postinstall.js +163 -6
  457. package/src/resources/extensions/async-jobs/async-bash-tool.ts +3 -1
  458. package/src/resources/extensions/bg-shell/interaction.ts +3 -1
  459. package/src/resources/extensions/bg-shell/process-manager.ts +4 -1
  460. package/src/resources/extensions/claude-code-cli/partial-builder.ts +5 -0
  461. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +105 -0
  462. package/src/resources/extensions/gsd/auto/infra-errors.ts +1 -0
  463. package/src/resources/extensions/gsd/auto/phases.ts +25 -12
  464. package/src/resources/extensions/gsd/auto/resolve.ts +3 -3
  465. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -2
  466. package/src/resources/extensions/gsd/auto/session.ts +11 -0
  467. package/src/resources/extensions/gsd/auto/types.ts +13 -0
  468. package/src/resources/extensions/gsd/auto-artifact-paths.ts +19 -21
  469. package/src/resources/extensions/gsd/auto-dashboard.ts +36 -5
  470. package/src/resources/extensions/gsd/auto-dispatch.ts +122 -71
  471. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  472. package/src/resources/extensions/gsd/auto-observability.ts +72 -0
  473. package/src/resources/extensions/gsd/auto-post-unit.ts +73 -110
  474. package/src/resources/extensions/gsd/auto-prompts.ts +159 -17
  475. package/src/resources/extensions/gsd/auto-recovery.ts +80 -221
  476. package/src/resources/extensions/gsd/auto-start.ts +7 -27
  477. package/src/resources/extensions/gsd/auto-timers.ts +2 -2
  478. package/src/resources/extensions/gsd/auto-utils.ts +25 -0
  479. package/src/resources/extensions/gsd/auto-verification.ts +4 -7
  480. package/src/resources/extensions/gsd/auto-worktree.ts +305 -108
  481. package/src/resources/extensions/gsd/auto.ts +26 -15
  482. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +93 -0
  483. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -0
  484. package/src/resources/extensions/gsd/branch-patterns.ts +16 -0
  485. package/src/resources/extensions/gsd/crash-recovery.ts +6 -2
  486. package/src/resources/extensions/gsd/custom-execution-policy.ts +3 -2
  487. package/src/resources/extensions/gsd/custom-verification.ts +3 -1
  488. package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -2
  489. package/src/resources/extensions/gsd/dashboard-overlay.ts +7 -0
  490. package/src/resources/extensions/gsd/detection.ts +662 -3
  491. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  492. package/src/resources/extensions/gsd/docs/preferences-reference.md +15 -0
  493. package/src/resources/extensions/gsd/doctor-checks.ts +5 -1291
  494. package/src/resources/extensions/gsd/doctor-engine-checks.ts +182 -0
  495. package/src/resources/extensions/gsd/doctor-environment.ts +30 -7
  496. package/src/resources/extensions/gsd/doctor-git-checks.ts +415 -0
  497. package/src/resources/extensions/gsd/doctor-global-checks.ts +84 -0
  498. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +626 -0
  499. package/src/resources/extensions/gsd/doctor.ts +9 -1
  500. package/src/resources/extensions/gsd/extension-manifest.json +1 -1
  501. package/src/resources/extensions/gsd/files.ts +6 -1
  502. package/src/resources/extensions/gsd/git-service.ts +7 -15
  503. package/src/resources/extensions/gsd/gsd-db.ts +150 -2
  504. package/src/resources/extensions/gsd/guided-flow-queue.ts +11 -12
  505. package/src/resources/extensions/gsd/guided-flow.ts +11 -0
  506. package/src/resources/extensions/gsd/init-wizard.ts +9 -1
  507. package/src/resources/extensions/gsd/markdown-renderer.ts +37 -4
  508. package/src/resources/extensions/gsd/model-router.ts +25 -0
  509. package/src/resources/extensions/gsd/notifications.ts +23 -0
  510. package/src/resources/extensions/gsd/observability-validator.ts +456 -0
  511. package/src/resources/extensions/gsd/preferences-skills.ts +11 -5
  512. package/src/resources/extensions/gsd/preferences-types.ts +25 -1
  513. package/src/resources/extensions/gsd/preferences-validation.ts +63 -0
  514. package/src/resources/extensions/gsd/preferences.ts +3 -0
  515. package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -8
  516. package/src/resources/extensions/gsd/prompts/complete-slice.md +9 -8
  517. package/src/resources/extensions/gsd/prompts/execute-task.md +16 -13
  518. package/src/resources/extensions/gsd/prompts/forensics.md +19 -8
  519. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +32 -0
  520. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  521. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  522. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  523. package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  524. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  525. package/src/resources/extensions/gsd/prompts/plan-slice.md +8 -3
  526. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +3 -0
  527. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  528. package/src/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  529. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  530. package/src/resources/extensions/gsd/repo-identity.ts +28 -0
  531. package/src/resources/extensions/gsd/roadmap-mutations.ts +134 -0
  532. package/src/resources/extensions/gsd/roadmap-slices.ts +2 -2
  533. package/src/resources/extensions/gsd/rtk-status.ts +53 -0
  534. package/src/resources/extensions/gsd/rule-registry.ts +10 -11
  535. package/src/resources/extensions/gsd/session-forensics.ts +13 -14
  536. package/src/resources/extensions/gsd/session-lock.ts +92 -64
  537. package/src/resources/extensions/gsd/skill-catalog.ts +1085 -0
  538. package/src/resources/extensions/gsd/skill-discovery.ts +3 -2
  539. package/src/resources/extensions/gsd/skill-health.ts +2 -2
  540. package/src/resources/extensions/gsd/skill-telemetry.ts +15 -5
  541. package/src/resources/extensions/gsd/state.ts +54 -10
  542. package/src/resources/extensions/gsd/templates/milestone-summary.md +8 -0
  543. package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  544. package/src/resources/extensions/gsd/templates/plan.md +16 -0
  545. package/src/resources/extensions/gsd/templates/preferences.md +2 -0
  546. package/src/resources/extensions/gsd/templates/roadmap.md +13 -0
  547. package/src/resources/extensions/gsd/templates/slice-summary.md +9 -0
  548. package/src/resources/extensions/gsd/templates/task-plan.md +24 -0
  549. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +2 -2
  550. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +16 -0
  551. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +2 -2
  552. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -0
  553. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +1 -81
  554. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +2 -2
  555. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  556. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  557. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +9 -12
  558. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +5 -3
  559. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +33 -0
  560. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
  561. package/src/resources/extensions/gsd/tests/detection.test.ts +838 -0
  562. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  563. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +115 -1
  564. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +65 -1
  565. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +50 -0
  566. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
  567. package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +189 -0
  568. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +156 -0
  569. package/src/resources/extensions/gsd/tests/git-service.test.ts +49 -0
  570. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +63 -0
  572. package/src/resources/extensions/gsd/tests/infra-error.test.ts +12 -2
  573. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +39 -0
  574. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  575. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  576. package/src/resources/extensions/gsd/tests/model-router.test.ts +40 -0
  577. package/src/resources/extensions/gsd/tests/notifications.test.ts +28 -6
  578. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +474 -0
  579. package/src/resources/extensions/gsd/tests/preferences.test.ts +50 -0
  580. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +347 -0
  581. package/src/resources/extensions/gsd/tests/queue-completed-milestone-perf.test.ts +155 -0
  582. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +40 -0
  583. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +6 -6
  584. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +2 -1
  585. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +32 -0
  586. package/src/resources/extensions/gsd/tests/retry-diagnostic-reasoning.test.ts +161 -0
  587. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +4 -5
  588. package/src/resources/extensions/gsd/tests/rewrite-count-persist.test.ts +82 -0
  589. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +26 -0
  590. package/src/resources/extensions/gsd/tests/run-uat.test.ts +166 -16
  591. package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +223 -0
  592. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +12 -12
  593. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +44 -4
  594. package/src/resources/extensions/gsd/tests/skill-catalog.test.ts +193 -0
  595. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +24 -0
  596. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -1
  597. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
  598. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -1
  599. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +0 -16
  600. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +67 -0
  601. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +1 -1
  602. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +204 -0
  603. package/src/resources/extensions/gsd/tools/plan-slice.ts +16 -0
  604. package/src/resources/extensions/gsd/tools/validate-milestone.ts +3 -3
  605. package/src/resources/extensions/gsd/types.ts +32 -0
  606. package/src/resources/extensions/gsd/undo.ts +8 -7
  607. package/src/resources/extensions/gsd/unit-runtime.ts +2 -1
  608. package/src/resources/extensions/gsd/verdict-parser.ts +95 -0
  609. package/src/resources/extensions/gsd/verification-gate.ts +3 -3
  610. package/src/resources/extensions/gsd/worktree-resolver.ts +31 -0
  611. package/src/resources/extensions/gsd/worktree.ts +3 -2
  612. package/src/resources/extensions/remote-questions/config.ts +3 -5
  613. package/src/resources/extensions/search-the-web/native-search.ts +8 -3
  614. package/src/resources/extensions/search-the-web/tool-search.ts +22 -2
  615. package/src/resources/extensions/shared/rtk-session-stats.ts +249 -0
  616. package/src/resources/extensions/shared/rtk.ts +120 -0
  617. package/src/resources/skills/github-workflows/references/gh/SKILL.md +22 -1
  618. package/dist/resources/extensions/gsd/auto-worktree-sync.js +0 -191
  619. package/dist/resources/extensions/gsd/resource-version.js +0 -97
  620. package/dist/web/standalone/.next/server/chunks/229.js +0 -12
  621. package/dist/web/standalone/.next/server/chunks/441.js +0 -2
  622. package/dist/web/standalone/.next/server/chunks/471.js +0 -13
  623. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +0 -9
  624. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-d83ba70a25a85472.js +0 -1
  625. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-d83ba70a25a85472.js +0 -1
  626. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-d83ba70a25a85472.js +0 -1
  627. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-d83ba70a25a85472.js +0 -1
  628. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +0 -1
  629. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +0 -1
  630. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +0 -1
  631. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +0 -1
  632. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +0 -1
  633. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +0 -1
  634. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +0 -1
  635. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +0 -1
  636. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +0 -1
  637. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +0 -1
  638. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +0 -1
  639. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +0 -1
  640. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +0 -1
  641. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +0 -1
  642. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +0 -1
  673. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +0 -1
  674. package/dist/web/standalone/.next/static/gj-y5hikmhS--NT8Web6M/_buildManifest.js +0 -1
  675. package/packages/pi-ai/pnpm-lock.yaml +0 -2022
  676. package/packages/pi-coding-agent/pnpm-lock.yaml +0 -454
  677. package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -234
  678. package/src/resources/extensions/gsd/resource-version.ts +0 -101
  679. /package/dist/web/standalone/.next/static/{gj-y5hikmhS--NT8Web6M → yJIyd5cXPNpmXTv18ZlyC}/_ssgManifest.js +0 -0
@@ -0,0 +1,223 @@
1
+ /**
2
+ * session-lock-transient-read.test.ts — Tests for transient lock file unreadability (#2324).
3
+ *
4
+ * Regression coverage for:
5
+ * #2324 onCompromised declares lock lost when the lock file is temporarily
6
+ * unreadable (NFS/CIFS latency, macOS APFS snapshot, concurrent process
7
+ * briefly holding the file).
8
+ *
9
+ * Tests:
10
+ * - readExistingLockDataWithRetry retries on transient read failure
11
+ * - readExistingLockDataWithRetry returns data when file becomes readable after retries
12
+ * - readExistingLockDataWithRetry returns null only when ALL retries exhausted
13
+ * - onCompromised does not declare compromise when lock file is transiently unreadable
14
+ */
15
+
16
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, renameSync, unlinkSync, chmodSync } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import { tmpdir } from 'node:os';
19
+ import { execSync, spawn } from 'node:child_process';
20
+
21
+ import {
22
+ acquireSessionLock,
23
+ getSessionLockStatus,
24
+ releaseSessionLock,
25
+ readExistingLockDataWithRetry,
26
+ type SessionLockData,
27
+ } from '../session-lock.ts';
28
+ import { gsdRoot } from '../paths.ts';
29
+ import { createTestContext } from './test-helpers.ts';
30
+
31
+ const { assertEq, assertTrue, report } = createTestContext();
32
+
33
+ async function main(): Promise<void> {
34
+
35
+ // ─── 1. readExistingLockDataWithRetry succeeds on first read when file is fine ─
36
+ console.log('\n=== 1. readExistingLockDataWithRetry reads file normally ===');
37
+ {
38
+ const base = mkdtempSync(join(tmpdir(), 'gsd-transient-'));
39
+ mkdirSync(join(base, '.gsd'), { recursive: true });
40
+
41
+ try {
42
+ const lockFile = join(gsdRoot(base), 'auto.lock');
43
+ const lockData: SessionLockData = {
44
+ pid: process.pid,
45
+ startedAt: new Date().toISOString(),
46
+ unitType: 'execute-task',
47
+ unitId: 'M001/S01/T01',
48
+ unitStartedAt: new Date().toISOString(),
49
+ sessionFile: 'test-session.json',
50
+ };
51
+ writeFileSync(lockFile, JSON.stringify(lockData, null, 2));
52
+
53
+ const result = readExistingLockDataWithRetry(lockFile);
54
+ assertTrue(result !== null, 'data returned for readable file');
55
+ assertEq(result!.pid, process.pid, 'correct PID read');
56
+ assertEq(result!.sessionFile, 'test-session.json', 'correct sessionFile read');
57
+ } finally {
58
+ rmSync(base, { recursive: true, force: true });
59
+ }
60
+ }
61
+
62
+ // ─── 2. readExistingLockDataWithRetry returns null for truly missing file ──
63
+ console.log('\n=== 2. readExistingLockDataWithRetry returns null for missing file ===');
64
+ {
65
+ const base = mkdtempSync(join(tmpdir(), 'gsd-transient-'));
66
+ mkdirSync(join(base, '.gsd'), { recursive: true });
67
+
68
+ try {
69
+ const lockFile = join(gsdRoot(base), 'auto.lock');
70
+ // File doesn't exist
71
+ const result = readExistingLockDataWithRetry(lockFile, { maxAttempts: 2, delayMs: 10 });
72
+ assertEq(result, null, 'null for truly missing file after retries');
73
+ } finally {
74
+ rmSync(base, { recursive: true, force: true });
75
+ }
76
+ }
77
+
78
+ // ─── 3. readExistingLockDataWithRetry recovers after transient rename ──────
79
+ console.log('\n=== 3. readExistingLockDataWithRetry recovers after transient unavailability ===');
80
+ {
81
+ const base = mkdtempSync(join(tmpdir(), 'gsd-transient-'));
82
+ mkdirSync(join(base, '.gsd'), { recursive: true });
83
+
84
+ try {
85
+ const lockFile = join(gsdRoot(base), 'auto.lock');
86
+ const tmpFile = lockFile + '.hidden';
87
+ const lockData: SessionLockData = {
88
+ pid: process.pid,
89
+ startedAt: new Date().toISOString(),
90
+ unitType: 'execute-task',
91
+ unitId: 'M001/S01/T01',
92
+ unitStartedAt: new Date().toISOString(),
93
+ sessionFile: 'recovery-session.json',
94
+ };
95
+ writeFileSync(lockFile, JSON.stringify(lockData, null, 2));
96
+
97
+ // Simulate transient unavailability: move file away, spawn a child process
98
+ // to restore it after 100ms. The child runs outside our event loop so it
99
+ // fires even during busy-wait retries.
100
+ renameSync(lockFile, tmpFile);
101
+ spawn('bash', ['-c', `sleep 0.1 && mv "${tmpFile}" "${lockFile}"`], { stdio: 'ignore', detached: true }).unref();
102
+
103
+ // With retries (3 attempts, 200ms delay), it should recover on 2nd or 3rd attempt
104
+ const result = readExistingLockDataWithRetry(lockFile, { maxAttempts: 3, delayMs: 200 });
105
+ assertTrue(result !== null, 'data recovered after transient unavailability');
106
+ if (result) {
107
+ assertEq(result.pid, process.pid, 'correct PID after recovery');
108
+ assertEq(result.sessionFile, 'recovery-session.json', 'correct sessionFile after recovery');
109
+ }
110
+ } finally {
111
+ rmSync(base, { recursive: true, force: true });
112
+ }
113
+ }
114
+
115
+ // ─── 4. readExistingLockDataWithRetry recovers from transient permission error ─
116
+ console.log('\n=== 4. readExistingLockDataWithRetry recovers from transient permission error ===');
117
+ {
118
+ const base = mkdtempSync(join(tmpdir(), 'gsd-transient-'));
119
+ mkdirSync(join(base, '.gsd'), { recursive: true });
120
+
121
+ try {
122
+ const lockFile = join(gsdRoot(base), 'auto.lock');
123
+ const lockData: SessionLockData = {
124
+ pid: process.pid,
125
+ startedAt: new Date().toISOString(),
126
+ unitType: 'execute-task',
127
+ unitId: 'M001/S01/T01',
128
+ unitStartedAt: new Date().toISOString(),
129
+ sessionFile: 'perm-session.json',
130
+ };
131
+ writeFileSync(lockFile, JSON.stringify(lockData, null, 2));
132
+
133
+ // Remove read permission to simulate NFS/CIFS latency, then spawn a child
134
+ // to restore permissions after 100ms (runs outside our event loop).
135
+ chmodSync(lockFile, 0o000);
136
+ spawn('bash', ['-c', `sleep 0.1 && chmod 644 "${lockFile}"`], { stdio: 'ignore', detached: true }).unref();
137
+
138
+ const result = readExistingLockDataWithRetry(lockFile, { maxAttempts: 3, delayMs: 200 });
139
+ assertTrue(result !== null, 'data recovered after transient permission error');
140
+ if (result) {
141
+ assertEq(result.pid, process.pid, 'correct PID after permission recovery');
142
+ }
143
+
144
+ // Ensure permissions restored for cleanup
145
+ try { chmodSync(lockFile, 0o644); } catch { /* best-effort */ }
146
+ } finally {
147
+ rmSync(base, { recursive: true, force: true });
148
+ }
149
+ }
150
+
151
+ // ─── 5. getSessionLockStatus does not false-positive on transient read failure ─
152
+ console.log('\n=== 5. getSessionLockStatus tolerates transient lock file unavailability ===');
153
+ {
154
+ const base = mkdtempSync(join(tmpdir(), 'gsd-transient-'));
155
+ mkdirSync(join(base, '.gsd'), { recursive: true });
156
+
157
+ try {
158
+ const result = acquireSessionLock(base);
159
+ assertTrue(result.acquired, 'lock acquired');
160
+
161
+ // Validate works initially
162
+ const status1 = getSessionLockStatus(base);
163
+ assertTrue(status1.valid, 'lock valid before transient failure');
164
+
165
+ // Temporarily hide the lock file
166
+ const lockFile = join(gsdRoot(base), 'auto.lock');
167
+ const tmpFile = lockFile + '.hidden';
168
+ renameSync(lockFile, tmpFile);
169
+
170
+ // Schedule restoration
171
+ setTimeout(() => {
172
+ try { renameSync(tmpFile, lockFile); } catch { /* best-effort */ }
173
+ }, 30);
174
+
175
+ // Small delay to ensure restoration runs, then check — with the OS lock
176
+ // still held, getSessionLockStatus should return valid=true even if the
177
+ // lock file was briefly missing (it checks _releaseFunction first).
178
+ await new Promise(r => setTimeout(r, 60));
179
+ const status2 = getSessionLockStatus(base);
180
+ assertTrue(status2.valid, 'lock still valid after transient file disappearance (OS lock held)');
181
+
182
+ // Restore if not yet restored
183
+ try { renameSync(tmpFile, lockFile); } catch { /* already restored */ }
184
+
185
+ releaseSessionLock(base);
186
+ } finally {
187
+ rmSync(base, { recursive: true, force: true });
188
+ }
189
+ }
190
+
191
+ // ─── 6. Retry defaults: 3 attempts with 200ms delay ────────────────────────
192
+ console.log('\n=== 6. Default retry params: function works with defaults ===');
193
+ {
194
+ const base = mkdtempSync(join(tmpdir(), 'gsd-transient-'));
195
+ mkdirSync(join(base, '.gsd'), { recursive: true });
196
+
197
+ try {
198
+ const lockFile = join(gsdRoot(base), 'auto.lock');
199
+ const lockData: SessionLockData = {
200
+ pid: process.pid,
201
+ startedAt: new Date().toISOString(),
202
+ unitType: 'execute-task',
203
+ unitId: 'M001/S01/T01',
204
+ unitStartedAt: new Date().toISOString(),
205
+ sessionFile: 'status-session.json',
206
+ };
207
+ writeFileSync(lockFile, JSON.stringify(lockData, null, 2));
208
+
209
+ // Call with no options — uses defaults (3 attempts, 200ms)
210
+ const result = readExistingLockDataWithRetry(lockFile);
211
+ assertTrue(result !== null, 'default params work for readable file');
212
+ } finally {
213
+ rmSync(base, { recursive: true, force: true });
214
+ }
215
+ }
216
+
217
+ report();
218
+ }
219
+
220
+ main().catch((error) => {
221
+ console.error(error);
222
+ process.exit(1);
223
+ });
@@ -113,12 +113,12 @@ test("postUnitPostVerification pushes to sidecarQueue for hooks", () => {
113
113
  assert.ok(triageSectionStart > -1, "auto-post-unit.ts must have a triage check section");
114
114
  const hookSection = source.slice(hookSectionStart, triageSectionStart);
115
115
  assert.ok(
116
- hookSection.includes("s.sidecarQueue.push("),
117
- "hook section must push to s.sidecarQueue",
116
+ hookSection.includes("enqueueSidecar(") || hookSection.includes("s.sidecarQueue.push("),
117
+ "hook section must enqueue to sidecarQueue (via enqueueSidecar or direct push)",
118
118
  );
119
119
  assert.ok(
120
- hookSection.includes('kind: "hook"'),
121
- "hook sidecar item must have kind: 'hook'",
120
+ hookSection.includes('"hook"'),
121
+ "hook sidecar item must reference kind 'hook'",
122
122
  );
123
123
  });
124
124
 
@@ -132,12 +132,12 @@ test("postUnitPostVerification pushes to sidecarQueue for triage", () => {
132
132
  assert.ok(quickTaskSectionStart > -1, "auto-post-unit.ts must have a quick-task dispatch section");
133
133
  const triageSection = source.slice(triageSectionStart, quickTaskSectionStart);
134
134
  assert.ok(
135
- triageSection.includes("s.sidecarQueue.push("),
136
- "triage section must push to s.sidecarQueue",
135
+ triageSection.includes("enqueueSidecar(") || triageSection.includes("s.sidecarQueue.push("),
136
+ "triage section must enqueue to sidecarQueue (via enqueueSidecar or direct push)",
137
137
  );
138
138
  assert.ok(
139
- triageSection.includes('kind: "triage"'),
140
- "triage sidecar item must have kind: 'triage'",
139
+ triageSection.includes('"triage"'),
140
+ "triage sidecar item must reference kind 'triage'",
141
141
  );
142
142
  });
143
143
 
@@ -149,12 +149,12 @@ test("postUnitPostVerification pushes to sidecarQueue for quick-tasks", () => {
149
149
  assert.ok(quickTaskSectionStart > -1, "auto-post-unit.ts must have a quick-task dispatch section");
150
150
  const quickTaskSection = source.slice(quickTaskSectionStart);
151
151
  assert.ok(
152
- quickTaskSection.includes("s.sidecarQueue.push("),
153
- "quick-task section must push to s.sidecarQueue",
152
+ quickTaskSection.includes("enqueueSidecar(") || quickTaskSection.includes("s.sidecarQueue.push("),
153
+ "quick-task section must enqueue to sidecarQueue (via enqueueSidecar or direct push)",
154
154
  );
155
155
  assert.ok(
156
- quickTaskSection.includes('kind: "quick-task"'),
157
- "quick-task sidecar item must have kind: 'quick-task'",
156
+ quickTaskSection.includes('"quick-task"'),
157
+ "quick-task sidecar item must reference kind 'quick-task'",
158
158
  );
159
159
  });
160
160
 
@@ -75,7 +75,7 @@ test("buildSkillActivationBlock activates skills via prefer_skills when context
75
75
  prefer_skills: ["react"],
76
76
  });
77
77
 
78
- assert.match(result, /Call Skill\('react'\)/);
78
+ assert.match(result, /Call Skill\(\{ skill: 'react' \}\)/);
79
79
  assert.doesNotMatch(result, /swiftui/);
80
80
  } finally {
81
81
  cleanup(base);
@@ -92,7 +92,7 @@ test("buildSkillActivationBlock includes always_use_skills from preferences usin
92
92
  always_use_skills: ["swift-testing"],
93
93
  });
94
94
 
95
- assert.equal(result, "<skill_activation>Call Skill('swift-testing').</skill_activation>");
95
+ assert.equal(result, "<skill_activation>Call Skill({ skill: 'swift-testing' }).</skill_activation>");
96
96
  } finally {
97
97
  cleanup(base);
98
98
  }
@@ -120,8 +120,8 @@ test("buildSkillActivationBlock includes skill_rules matches and task-plan skill
120
120
  skill_rules: [{ when: "prisma database schema", use: ["prisma"] }],
121
121
  });
122
122
 
123
- assert.match(result, /Call Skill\('accessibility'\)/);
124
- assert.match(result, /Call Skill\('prisma'\)/);
123
+ assert.match(result, /Call Skill\(\{ skill: 'accessibility' \}\)/);
124
+ assert.match(result, /Call Skill\(\{ skill: 'prisma' \}\)/);
125
125
  } finally {
126
126
  cleanup(base);
127
127
  }
@@ -191,3 +191,43 @@ test("buildSkillActivationBlock does not activate skills from extraContext or ta
191
191
  cleanup(base);
192
192
  }
193
193
  });
194
+
195
+ test("buildSkillActivationBlock rejects skill names with special characters", () => {
196
+ const base = makeTempBase();
197
+ try {
198
+ // Skill names with quotes, braces, or other non-alphanumeric characters are
199
+ // rejected by the SAFE_SKILL_NAME guard to prevent prompt injection.
200
+ writeSkill(base, "my-skill's", "Skill with apostrophe in name.");
201
+ loadOnlyTestSkills(base);
202
+
203
+ const result = buildBlock(base, {}, {
204
+ always_use_skills: ["my-skill's"],
205
+ });
206
+
207
+ // Unsafe skill name is filtered out — empty result
208
+ assert.equal(result, "");
209
+ } finally {
210
+ cleanup(base);
211
+ }
212
+ });
213
+
214
+ test("buildSkillActivationBlock allows valid skill names and rejects invalid ones", () => {
215
+ const base = makeTempBase();
216
+ try {
217
+ writeSkill(base, "react", "React skill.");
218
+ writeSkill(base, "bad'name", "Injection attempt.");
219
+ writeSkill(base, "good-skill-2", "Another valid skill.");
220
+ loadOnlyTestSkills(base);
221
+
222
+ const result = buildBlock(base, {}, {
223
+ always_use_skills: ["react", "bad'name", "good-skill-2"],
224
+ });
225
+
226
+ assert.match(result, /skill_activation/);
227
+ assert.match(result, /Call Skill\(\{ skill: 'react' \}\)/);
228
+ assert.match(result, /Call Skill\(\{ skill: 'good-skill-2' \}\)/);
229
+ assert.doesNotMatch(result, /bad'name/);
230
+ } finally {
231
+ cleanup(base);
232
+ }
233
+ });
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Unit tests for GSD Skill Catalog — pack matching logic.
3
+ *
4
+ * Exercises matchPacksForProject() to verify that project signals
5
+ * correctly map to skill packs.
6
+ */
7
+
8
+ import test from "node:test";
9
+ import assert from "node:assert/strict";
10
+ import { PROJECT_FILES } from "../detection.ts";
11
+ import { GREENFIELD_STACKS, SKILL_CATALOG, matchPacksForProject } from "../skill-catalog.ts";
12
+ import type { ProjectSignals } from "../detection.ts";
13
+
14
+ function makeSignals(overrides: Partial<ProjectSignals> = {}): ProjectSignals {
15
+ return {
16
+ detectedFiles: [],
17
+ isGitRepo: false,
18
+ isMonorepo: false,
19
+ xcodePlatforms: [],
20
+ hasCI: false,
21
+ hasTests: false,
22
+ verificationCommands: [],
23
+ ...overrides,
24
+ };
25
+ }
26
+
27
+ function packLabels(signals: ProjectSignals): string[] {
28
+ return matchPacksForProject(signals).map((p) => p.label);
29
+ }
30
+
31
+ // ── matchAlways packs are always included ────────────────────────────────────
32
+
33
+ test("matchPacksForProject: always includes matchAlways packs", () => {
34
+ const labels = packLabels(makeSignals());
35
+ assert.ok(labels.includes("Skill Discovery"), "should include Skill Discovery");
36
+ assert.ok(labels.includes("Skill Authoring"), "should include Skill Authoring");
37
+ assert.ok(labels.includes("Browser Automation"), "should include Browser Automation");
38
+ assert.ok(labels.includes("Document Handling"), "should include Document Handling");
39
+ assert.ok(labels.includes("Code Review & Quality"), "should include Code Review & Quality");
40
+ assert.ok(labels.includes("Git Advanced Workflows"), "should include Git Advanced Workflows");
41
+ });
42
+
43
+ // ── Language matching ────────────────────────────────────────────────────────
44
+
45
+ test("matchPacksForProject: Python language matches Python packs", () => {
46
+ const labels = packLabels(makeSignals({ primaryLanguage: "python", detectedFiles: ["pyproject.toml"] }));
47
+ assert.ok(labels.includes("Python"), "should include Python");
48
+ assert.ok(labels.includes("Python Advanced"), "should include Python Advanced");
49
+ });
50
+
51
+ test("matchPacksForProject: Rust language matches Rust packs", () => {
52
+ const labels = packLabels(makeSignals({ primaryLanguage: "rust", detectedFiles: ["Cargo.toml"] }));
53
+ assert.ok(labels.includes("Rust"), "should include Rust");
54
+ assert.ok(labels.includes("Rust Async Patterns"), "should include Rust Async Patterns");
55
+ });
56
+
57
+ test("matchPacksForProject: Go language matches Go packs", () => {
58
+ const labels = packLabels(makeSignals({ primaryLanguage: "go", detectedFiles: ["go.mod"] }));
59
+ assert.ok(labels.includes("Go"), "should include Go");
60
+ assert.ok(labels.includes("Go Concurrency Patterns"), "should include Go Concurrency Patterns");
61
+ });
62
+
63
+ test("matchPacksForProject: JS/TS matches web frontend packs", () => {
64
+ const labels = packLabels(makeSignals({ primaryLanguage: "javascript/typescript", detectedFiles: ["package.json"] }));
65
+ assert.ok(labels.includes("React & Web Frontend"), "should include React");
66
+ assert.ok(labels.includes("TypeScript & JS Development"), "should include TS/JS Dev");
67
+ assert.ok(labels.includes("React State & Patterns"), "should include React State");
68
+ assert.ok(labels.includes("shadcn/ui"), "should include shadcn");
69
+ assert.ok(labels.includes("Frontend Design & UX"), "should include Frontend Design");
70
+ });
71
+
72
+ // ── File matching ────────────────────────────────────────────────────────────
73
+
74
+ test("matchPacksForProject: angular.json triggers Angular packs", () => {
75
+ const labels = packLabels(makeSignals({ detectedFiles: ["angular.json"] }));
76
+ assert.ok(labels.includes("Angular"), "should include Angular");
77
+ assert.ok(labels.includes("Angular Migration"), "should include Angular Migration");
78
+ });
79
+
80
+ test("matchPacksForProject: next.config.ts triggers Next.js packs", () => {
81
+ const labels = packLabels(makeSignals({ detectedFiles: ["next.config.ts"] }));
82
+ assert.ok(labels.includes("Next.js"), "should include Next.js");
83
+ assert.ok(labels.includes("Next.js App Router Patterns"), "should include Next.js App Router");
84
+ });
85
+
86
+ test("matchPacksForProject: *.vue triggers Vue.js", () => {
87
+ const labels = packLabels(makeSignals({ detectedFiles: ["*.vue"] }));
88
+ assert.ok(labels.includes("Vue.js"), "should include Vue.js");
89
+ });
90
+
91
+ test("matchPacksForProject: Chart.yaml triggers Kubernetes", () => {
92
+ const labels = packLabels(makeSignals({ detectedFiles: ["Chart.yaml"] }));
93
+ assert.ok(labels.includes("Kubernetes"), "should include Kubernetes");
94
+ });
95
+
96
+ test("matchPacksForProject: hardhat.config.ts triggers Blockchain", () => {
97
+ const labels = packLabels(makeSignals({ detectedFiles: ["hardhat.config.ts"] }));
98
+ assert.ok(labels.includes("Blockchain & Web3"), "should include Blockchain & Web3");
99
+ });
100
+
101
+ test("matchPacksForProject: tailwind.config.ts triggers Tailwind CSS", () => {
102
+ const labels = packLabels(makeSignals({ detectedFiles: ["tailwind.config.ts"] }));
103
+ assert.ok(labels.includes("Tailwind CSS"), "should include Tailwind CSS");
104
+ });
105
+
106
+ // ── Xcode platform matching ─────────────────────────────────────────────────
107
+
108
+ test("matchPacksForProject: iphoneos triggers iOS packs", () => {
109
+ const labels = packLabels(makeSignals({ xcodePlatforms: ["iphoneos"] }));
110
+ assert.ok(labels.includes("iOS App Frameworks"), "should include iOS App Frameworks");
111
+ assert.ok(labels.includes("iOS Data Frameworks"), "should include iOS Data Frameworks");
112
+ assert.ok(labels.includes("iOS AI & ML"), "should include iOS AI & ML");
113
+ assert.ok(labels.includes("iOS Engineering"), "should include iOS Engineering");
114
+ assert.ok(labels.includes("iOS Hardware"), "should include iOS Hardware");
115
+ assert.ok(labels.includes("iOS Platform"), "should include iOS Platform");
116
+ });
117
+
118
+ // ── Isolation checks — packs that should NOT match ──────────────────────────
119
+
120
+ test("matchPacksForProject: FastAPI does not match generic Python", () => {
121
+ const labels = packLabels(makeSignals({ primaryLanguage: "python", detectedFiles: ["pyproject.toml"] }));
122
+ assert.ok(!labels.includes("FastAPI"), "FastAPI should NOT match generic Python projects");
123
+ });
124
+
125
+ test("matchPacksForProject: FastAPI matches when dep:fastapi detected", () => {
126
+ const labels = packLabels(makeSignals({ primaryLanguage: "python", detectedFiles: ["pyproject.toml", "dep:fastapi"] }));
127
+ assert.ok(labels.includes("FastAPI"), "FastAPI should match when dep:fastapi is in detectedFiles");
128
+ });
129
+
130
+ test("matchPacksForProject: Spring Boot does not match via language alone", () => {
131
+ // Simulate Android project: has java/kotlin language but no root pom.xml/build.gradle
132
+ const labels = packLabels(makeSignals({ primaryLanguage: "java/kotlin", detectedFiles: ["app/build.gradle"] }));
133
+ assert.ok(!labels.includes("Java & Spring Boot"), "Spring Boot should NOT match via language alone");
134
+ });
135
+
136
+ test("matchPacksForProject: Spring Boot matches only dep:spring-boot", () => {
137
+ const positive = packLabels(makeSignals({ detectedFiles: ["dep:spring-boot"] }));
138
+ assert.ok(positive.includes("Java & Spring Boot"), "should include Spring Boot pack when dependency marker exists");
139
+
140
+ const androidLike = packLabels(makeSignals({ detectedFiles: ["build.gradle", "app/build.gradle"], primaryLanguage: "java/kotlin" }));
141
+ assert.ok(!androidLike.includes("Java & Spring Boot"), "generic Gradle + Android markers should not imply Spring Boot");
142
+ });
143
+
144
+ test("matchPacksForProject: Unity does not include Godot", () => {
145
+ const labels = packLabels(makeSignals({ detectedFiles: ["ProjectSettings/ProjectVersion.txt"] }));
146
+ assert.ok(labels.includes("Unity"), "should include Unity");
147
+ assert.ok(!labels.includes("Godot"), "should NOT include Godot");
148
+ });
149
+
150
+ test("matchPacksForProject: Godot does not include Unity", () => {
151
+ const labels = packLabels(makeSignals({ detectedFiles: ["project.godot"] }));
152
+ assert.ok(labels.includes("Godot"), "should include Godot");
153
+ assert.ok(!labels.includes("Unity"), "should NOT include Unity");
154
+ });
155
+
156
+ test("matchPacksForProject: .NET backend patterns match F# and solution markers", () => {
157
+ const fsprojLabels = packLabels(makeSignals({ detectedFiles: ["*.fsproj"], primaryLanguage: "fsharp" }));
158
+ assert.ok(fsprojLabels.includes(".NET Backend Patterns"), "should include generic .NET backend patterns for F# projects");
159
+ assert.ok(!fsprojLabels.includes(".NET & C#"), "should not include C#-specific pack for F# projects");
160
+
161
+ const slnLabels = packLabels(makeSignals({ detectedFiles: ["*.sln"], primaryLanguage: "dotnet" }));
162
+ assert.ok(slnLabels.includes(".NET Backend Patterns"), "should include generic .NET backend patterns for solution files");
163
+ });
164
+
165
+ test("SKILL_CATALOG: every matchFiles entry is backed by detection", () => {
166
+ const knownMarkers = new Set<string>([
167
+ ...PROJECT_FILES,
168
+ "*.sqlite",
169
+ "*.sql",
170
+ "*.csproj",
171
+ "*.fsproj",
172
+ "*.sln",
173
+ "*.vue",
174
+ "dep:fastapi",
175
+ "dep:spring-boot",
176
+ ]);
177
+
178
+ for (const pack of SKILL_CATALOG) {
179
+ for (const marker of pack.matchFiles ?? []) {
180
+ assert.ok(knownMarkers.has(marker), `Unknown detection marker: ${marker} (pack: ${pack.label})`);
181
+ }
182
+ }
183
+ });
184
+
185
+ test("GREENFIELD_STACKS: every pack label resolves to SKILL_CATALOG", () => {
186
+ const labels = new Set(SKILL_CATALOG.map((pack) => pack.label));
187
+
188
+ for (const stack of GREENFIELD_STACKS) {
189
+ for (const packLabel of stack.packs) {
190
+ assert.ok(labels.has(packLabel), `Unknown pack label: ${packLabel} (stack: ${stack.id})`);
191
+ }
192
+ }
193
+ });
@@ -47,3 +47,27 @@ test("#2309: rate limits are still transient", () => {
47
47
  assert.equal(rlResult.isTransient, true, "rate limits are still transient");
48
48
  assert.equal(rlResult.isRateLimit, true, "rate limits are flagged as rate limits");
49
49
  });
50
+
51
+ // --- #2572: stream-truncation JSON parse errors should be transient ---
52
+
53
+ test("#2572: 'Expected double-quoted property name' (truncated stream) is transient", () => {
54
+ const result = classifyProviderError("Expected double-quoted property name in JSON at position 23 (line 1 column 24)");
55
+ assert.equal(result.isTransient, true, "truncated-stream JSON parse error should be transient");
56
+ assert.equal(result.isRateLimit, false, "not a rate limit");
57
+ assert.equal(result.suggestedDelayMs, 15_000, "should use 15s backoff like connection errors");
58
+ });
59
+
60
+ test("#2572: 'Unexpected end of JSON input' (truncated stream) is transient", () => {
61
+ const result = classifyProviderError("Unexpected end of JSON input");
62
+ assert.equal(result.isTransient, true, "'Unexpected end of JSON input' should be transient");
63
+ });
64
+
65
+ test("#2572: 'Unexpected token' in JSON (truncated stream) is transient", () => {
66
+ const result = classifyProviderError("Unexpected token < in JSON at position 0");
67
+ assert.equal(result.isTransient, true, "'Unexpected token in JSON' should be transient");
68
+ });
69
+
70
+ test("#2572: 'SyntaxError' with JSON context (truncated stream) is transient", () => {
71
+ const result = classifyProviderError("SyntaxError: JSON.parse: unexpected character at line 1 column 1");
72
+ assert.equal(result.isTransient, true, "'SyntaxError...JSON' should be transient");
73
+ });
@@ -44,7 +44,7 @@ console.log('\n── Tool naming: registration count ──');
44
44
  const pi = makeMockPi();
45
45
  registerDbTools(pi);
46
46
 
47
- assert.deepStrictEqual(pi.tools.length, 26, 'Should register exactly 26 tools (13 canonical + 13 aliases)');
47
+ assert.deepStrictEqual(pi.tools.length, 27, 'Should register exactly 27 tools (13 canonical + 13 aliases + 1 gate tool)');
48
48
 
49
49
  // ─── Both names exist for each pair ──────────────────────────────────────────
50
50
 
@@ -119,7 +119,7 @@ test("dispatch: triage dispatch keeps the loop in continue mode", () => {
119
119
  postUnitSrc.indexOf("// ── Quick-task dispatch"),
120
120
  );
121
121
  assert.ok(
122
- triageBlock.includes('return "continue"'),
122
+ triageBlock.includes('return "continue"') || triageBlock.includes("return enqueueSidecar("),
123
123
  "triage dispatch should return 'continue' after enqueuing sidecar work",
124
124
  );
125
125
  });
@@ -320,7 +320,7 @@ test("dispatch: quick-task dispatch keeps the loop in continue mode", () => {
320
320
  postUnitSrc.indexOf("if (s.stepMode)"),
321
321
  );
322
322
  assert.ok(
323
- quickTaskSection.includes('return "continue"'),
323
+ quickTaskSection.includes('return "continue"') || quickTaskSection.includes("return enqueueSidecar("),
324
324
  "quick-task dispatch should return 'continue' after enqueuing sidecar work",
325
325
  );
326
326
  });
@@ -6,7 +6,8 @@ import { tmpdir } from "node:os";
6
6
  import { randomUUID } from "node:crypto";
7
7
 
8
8
  import { deriveState, isValidationTerminal } from "../state.ts";
9
- import { resolveExpectedArtifactPath, verifyExpectedArtifact, diagnoseExpectedArtifact, buildLoopRemediationSteps } from "../auto-recovery.ts";
9
+ import { resolveExpectedArtifactPath, diagnoseExpectedArtifact } from "../auto-artifact-paths.ts";
10
+ import { verifyExpectedArtifact, buildLoopRemediationSteps } from "../auto-recovery.ts";
10
11
  import { resolveDispatch, type DispatchContext } from "../auto-dispatch.ts";
11
12
  import type { GSDState } from "../types.ts";
12
13
  import { clearPathCache } from "../paths.ts";