gsd-pi 2.50.0 → 2.51.0-dev.7d435fe

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 (681) hide show
  1. package/README.md +6 -4
  2. package/dist/cli.js +26 -0
  3. package/dist/headless-events.d.ts +18 -0
  4. package/dist/headless-events.js +36 -0
  5. package/dist/headless-types.d.ts +28 -0
  6. package/dist/headless-types.js +7 -0
  7. package/dist/headless.d.ts +8 -3
  8. package/dist/headless.js +47 -16
  9. package/dist/help-text.js +16 -5
  10. package/dist/loader.js +4 -0
  11. package/dist/onboarding.js +5 -4
  12. package/dist/remote-questions-config.js +1 -1
  13. package/dist/resource-loader.d.ts +4 -1
  14. package/dist/resource-loader.js +138 -3
  15. package/dist/resources/extensions/async-jobs/async-bash-tool.js +32 -18
  16. package/dist/resources/extensions/bg-shell/interaction.js +3 -1
  17. package/dist/resources/extensions/bg-shell/process-manager.js +4 -1
  18. package/dist/resources/extensions/claude-code-cli/partial-builder.js +5 -0
  19. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
  20. package/dist/resources/extensions/gsd/auto/phases.js +16 -1
  21. package/dist/resources/extensions/gsd/auto/session.js +5 -0
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +22 -3
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +98 -53
  24. package/dist/resources/extensions/gsd/auto-observability.js +54 -0
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +37 -76
  26. package/dist/resources/extensions/gsd/auto-prompts.js +57 -0
  27. package/dist/resources/extensions/gsd/auto-recovery.js +21 -25
  28. package/dist/resources/extensions/gsd/auto-start.js +2 -0
  29. package/dist/resources/extensions/gsd/auto-timers.js +24 -2
  30. package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
  31. package/dist/resources/extensions/gsd/auto-utils.js +20 -0
  32. package/dist/resources/extensions/gsd/auto-worktree.js +21 -0
  33. package/dist/resources/extensions/gsd/auto.js +19 -7
  34. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +95 -69
  35. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
  36. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -1
  37. package/dist/resources/extensions/gsd/claude-import.js +60 -9
  38. package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
  39. package/dist/resources/extensions/gsd/commands-config.js +10 -5
  40. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  41. package/dist/resources/extensions/gsd/crash-recovery.js +6 -2
  42. package/dist/resources/extensions/gsd/custom-execution-policy.js +3 -2
  43. package/dist/resources/extensions/gsd/custom-verification.js +3 -1
  44. package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -2
  45. package/dist/resources/extensions/gsd/dashboard-overlay.js +4 -0
  46. package/dist/resources/extensions/gsd/detection.js +595 -9
  47. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +18 -3
  49. package/dist/resources/extensions/gsd/error-classifier.js +105 -0
  50. package/dist/resources/extensions/gsd/files.js +5 -1
  51. package/dist/resources/extensions/gsd/gitignore.js +7 -7
  52. package/dist/resources/extensions/gsd/gsd-db.js +298 -45
  53. package/dist/resources/extensions/gsd/guided-flow.js +10 -0
  54. package/dist/resources/extensions/gsd/init-wizard.js +11 -3
  55. package/dist/resources/extensions/gsd/key-manager.js +7 -16
  56. package/dist/resources/extensions/gsd/memory-store.js +28 -13
  57. package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
  58. package/dist/resources/extensions/gsd/model-router.js +25 -0
  59. package/dist/resources/extensions/gsd/notifications.js +23 -0
  60. package/dist/resources/extensions/gsd/observability-validator.js +422 -0
  61. package/dist/resources/extensions/gsd/preferences-models.js +1 -13
  62. package/dist/resources/extensions/gsd/preferences-skills.js +11 -5
  63. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  64. package/dist/resources/extensions/gsd/preferences-validation.js +25 -0
  65. package/dist/resources/extensions/gsd/preferences.js +16 -13
  66. package/dist/resources/extensions/gsd/prompts/forensics.md +11 -7
  67. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  68. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  69. package/dist/resources/extensions/gsd/provider-error-pause.js +0 -36
  70. package/dist/resources/extensions/gsd/roadmap-mutations.js +110 -0
  71. package/dist/resources/extensions/gsd/rtk-status.js +43 -0
  72. package/dist/resources/extensions/gsd/rule-registry.js +11 -12
  73. package/dist/resources/extensions/gsd/service-tier.js +13 -2
  74. package/dist/resources/extensions/gsd/session-forensics.js +7 -3
  75. package/dist/resources/extensions/gsd/skill-catalog.js +1026 -0
  76. package/dist/resources/extensions/gsd/skill-discovery.js +3 -2
  77. package/dist/resources/extensions/gsd/skill-health.js +2 -2
  78. package/dist/resources/extensions/gsd/skill-telemetry.js +15 -5
  79. package/dist/resources/extensions/gsd/state.js +38 -7
  80. package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
  81. package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  82. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  83. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -10
  84. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -17
  85. package/dist/resources/extensions/gsd/tools/complete-task.js +7 -18
  86. package/dist/resources/extensions/gsd/tools/plan-milestone.js +26 -17
  87. package/dist/resources/extensions/gsd/tools/plan-slice.js +25 -14
  88. package/dist/resources/extensions/gsd/tools/plan-task.js +21 -11
  89. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +47 -37
  90. package/dist/resources/extensions/gsd/tools/replan-slice.js +49 -38
  91. package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
  92. package/dist/resources/extensions/gsd/undo.js +8 -7
  93. package/dist/resources/extensions/gsd/unit-runtime.js +2 -1
  94. package/dist/resources/extensions/gsd/verification-gate.js +3 -1
  95. package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
  96. package/dist/resources/extensions/remote-questions/config.js +1 -1
  97. package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
  98. package/dist/resources/extensions/search-the-web/native-search.js +1 -1
  99. package/dist/resources/extensions/search-the-web/provider.js +1 -1
  100. package/dist/resources/extensions/shared/rtk-session-stats.js +189 -0
  101. package/dist/resources/extensions/shared/rtk.js +100 -0
  102. package/dist/rtk.d.ts +52 -0
  103. package/dist/rtk.js +332 -0
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
  106. package/dist/web/standalone/.next/build-manifest.json +4 -4
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  109. package/dist/web/standalone/.next/required-server-files.json +3 -3
  110. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  111. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  112. package/dist/web/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  115. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  123. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  143. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/experimental/route.js +3 -0
  161. package/dist/web/standalone/.next/server/app/api/experimental/route.js.nft.json +1 -0
  162. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -0
  163. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/preferences/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  201. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -26
  203. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  207. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  213. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  216. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  219. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  222. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  225. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  228. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  231. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  233. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js.nft.json +1 -1
  234. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  236. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js.nft.json +1 -1
  237. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  239. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  242. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  243. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  244. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  249. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  250. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  253. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  255. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  256. package/dist/web/standalone/.next/server/app/index.html +1 -1
  257. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  258. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  259. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  260. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  261. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  262. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  263. package/dist/web/standalone/.next/server/app/page.js +2 -2
  264. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  265. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
  267. package/dist/web/standalone/.next/server/chunks/2229.js +12 -0
  268. package/dist/web/standalone/.next/server/chunks/2331.js +25 -0
  269. package/dist/web/standalone/.next/server/chunks/{741.js → 4741.js} +1 -1
  270. package/dist/web/standalone/.next/server/chunks/5822.js +2 -0
  271. package/dist/web/standalone/.next/server/chunks/7471.js +13 -0
  272. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  273. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  274. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  275. package/dist/web/standalone/.next/server/middleware.js +3 -3
  276. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  277. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  278. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  279. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  280. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  281. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  282. package/dist/web/standalone/.next/static/RqOU-jOv9uZ1Q03P6L6nn/_buildManifest.js +1 -0
  283. package/dist/web/standalone/.next/static/chunks/{485.243af25f0cdf50d6.js → 2008.817d0885545aaea9.js} +6 -6
  284. package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +9 -0
  285. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +1 -0
  286. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  287. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +1 -0
  288. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +1 -0
  289. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  290. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  291. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +1 -0
  292. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +1 -0
  293. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +1 -0
  294. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +1 -0
  295. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +1 -0
  296. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +1 -0
  297. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +1 -0
  298. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +1 -0
  299. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +1 -0
  300. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +1 -0
  301. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +1 -0
  302. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +1 -0
  303. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +1 -0
  304. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +1 -0
  305. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +1 -0
  306. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +1 -0
  307. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +1 -0
  308. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +1 -0
  309. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +1 -0
  310. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +1 -0
  311. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +1 -0
  312. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +1 -0
  313. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +1 -0
  314. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +1 -0
  315. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +1 -0
  316. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +1 -0
  317. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +1 -0
  318. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +1 -0
  319. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +1 -0
  320. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +1 -0
  321. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  322. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +1 -0
  323. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  324. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +1 -0
  325. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +1 -0
  326. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +1 -0
  327. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +1 -0
  328. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  329. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  330. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  331. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +1 -0
  332. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +1 -0
  333. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  334. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +1 -0
  335. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +1 -0
  336. package/dist/web/standalone/.next/static/chunks/webpack-024d82be84800e52.js +1 -0
  337. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  338. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  339. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  340. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  341. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  342. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  343. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  344. package/dist/web/standalone/server.js +1 -1
  345. package/dist/wizard.js +4 -1
  346. package/package.json +2 -2
  347. package/packages/pi-ai/dist/models.d.ts +14 -3
  348. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  349. package/packages/pi-ai/dist/models.js +53 -10
  350. package/packages/pi-ai/dist/models.js.map +1 -1
  351. package/packages/pi-ai/dist/models.test.js +102 -1
  352. package/packages/pi-ai/dist/models.test.js.map +1 -1
  353. package/packages/pi-ai/dist/types.d.ts +31 -0
  354. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  355. package/packages/pi-ai/dist/types.js.map +1 -1
  356. package/packages/pi-ai/src/models.test.ts +114 -1
  357. package/packages/pi-ai/src/models.ts +70 -13
  358. package/packages/pi-ai/src/types.ts +32 -1
  359. package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
  360. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  361. package/packages/pi-coding-agent/dist/cli/args.js +3 -0
  362. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
  364. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
  366. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts +3 -1
  368. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/bash-executor.js +15 -2
  370. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  372. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
  375. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/extensions/runner.js +13 -0
  377. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +19 -1
  379. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  380. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/extensions/wrapper.d.ts.map +1 -1
  382. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js +8 -0
  383. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/model-registry.js +9 -4
  386. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/package-manager.js +8 -1
  389. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/skills.d.ts +11 -1
  391. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  392. package/packages/pi-coding-agent/dist/core/skills.js +30 -8
  393. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  396. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
  398. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
  399. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
  400. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
  401. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
  403. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  404. package/packages/pi-coding-agent/dist/index.d.ts +3 -3
  405. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  406. package/packages/pi-coding-agent/dist/index.js +1 -1
  407. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  408. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  409. package/packages/pi-coding-agent/dist/main.js +5 -3
  410. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  411. package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
  412. package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
  413. package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  415. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +3 -2
  416. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  417. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  418. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
  419. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +6 -4
  422. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +5 -0
  424. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  425. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +12 -0
  426. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  428. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +2 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  430. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
  431. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  432. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
  433. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  434. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
  435. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  436. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
  437. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  438. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
  439. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
  440. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
  441. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
  442. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
  443. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  444. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  445. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  446. package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
  447. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  448. package/packages/pi-coding-agent/package.json +1 -1
  449. package/packages/pi-coding-agent/src/cli/args.ts +4 -0
  450. package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
  451. package/packages/pi-coding-agent/src/core/bash-executor.ts +15 -3
  452. package/packages/pi-coding-agent/src/core/extensions/index.ts +2 -0
  453. package/packages/pi-coding-agent/src/core/extensions/runner.ts +18 -0
  454. package/packages/pi-coding-agent/src/core/extensions/types.ts +21 -0
  455. package/packages/pi-coding-agent/src/core/extensions/wrapper.ts +9 -0
  456. package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
  457. package/packages/pi-coding-agent/src/core/package-manager.ts +10 -1
  458. package/packages/pi-coding-agent/src/core/skills.ts +35 -10
  459. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  460. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
  461. package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
  462. package/packages/pi-coding-agent/src/index.ts +7 -0
  463. package/packages/pi-coding-agent/src/main.ts +5 -3
  464. package/packages/pi-coding-agent/src/modes/index.ts +8 -1
  465. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +3 -2
  466. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
  467. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +6 -4
  468. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +15 -0
  469. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +2 -1
  470. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
  471. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
  472. package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
  473. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
  474. package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
  475. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  476. package/pkg/dist/modes/interactive/theme/themes.js +2 -1
  477. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  478. package/pkg/package.json +1 -1
  479. package/scripts/postinstall.js +163 -6
  480. package/src/resources/extensions/async-jobs/async-bash-tool.ts +25 -12
  481. package/src/resources/extensions/bg-shell/interaction.ts +3 -1
  482. package/src/resources/extensions/bg-shell/process-manager.ts +4 -1
  483. package/src/resources/extensions/claude-code-cli/partial-builder.ts +5 -0
  484. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
  485. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +105 -0
  486. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
  487. package/src/resources/extensions/gsd/auto/phases.ts +15 -1
  488. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  489. package/src/resources/extensions/gsd/auto-dashboard.ts +31 -3
  490. package/src/resources/extensions/gsd/auto-dispatch.ts +102 -50
  491. package/src/resources/extensions/gsd/auto-observability.ts +72 -0
  492. package/src/resources/extensions/gsd/auto-post-unit.ts +56 -83
  493. package/src/resources/extensions/gsd/auto-prompts.ts +48 -0
  494. package/src/resources/extensions/gsd/auto-recovery.ts +19 -26
  495. package/src/resources/extensions/gsd/auto-start.ts +2 -0
  496. package/src/resources/extensions/gsd/auto-timers.ts +25 -1
  497. package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
  498. package/src/resources/extensions/gsd/auto-utils.ts +25 -0
  499. package/src/resources/extensions/gsd/auto-worktree.ts +21 -0
  500. package/src/resources/extensions/gsd/auto.ts +20 -7
  501. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +115 -72
  502. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
  503. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -1
  504. package/src/resources/extensions/gsd/claude-import.ts +58 -9
  505. package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
  506. package/src/resources/extensions/gsd/commands-config.ts +11 -5
  507. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  508. package/src/resources/extensions/gsd/crash-recovery.ts +6 -2
  509. package/src/resources/extensions/gsd/custom-execution-policy.ts +3 -2
  510. package/src/resources/extensions/gsd/custom-verification.ts +3 -1
  511. package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -2
  512. package/src/resources/extensions/gsd/dashboard-overlay.ts +7 -0
  513. package/src/resources/extensions/gsd/detection.ts +668 -9
  514. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  515. package/src/resources/extensions/gsd/docs/preferences-reference.md +18 -3
  516. package/src/resources/extensions/gsd/error-classifier.ts +139 -0
  517. package/src/resources/extensions/gsd/files.ts +6 -1
  518. package/src/resources/extensions/gsd/gitignore.ts +7 -7
  519. package/src/resources/extensions/gsd/gsd-db.ts +355 -63
  520. package/src/resources/extensions/gsd/guided-flow.ts +11 -0
  521. package/src/resources/extensions/gsd/init-wizard.ts +11 -3
  522. package/src/resources/extensions/gsd/key-manager.ts +7 -16
  523. package/src/resources/extensions/gsd/memory-store.ts +29 -18
  524. package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
  525. package/src/resources/extensions/gsd/model-router.ts +25 -0
  526. package/src/resources/extensions/gsd/notifications.ts +23 -0
  527. package/src/resources/extensions/gsd/observability-validator.ts +456 -0
  528. package/src/resources/extensions/gsd/preferences-models.ts +1 -13
  529. package/src/resources/extensions/gsd/preferences-skills.ts +11 -5
  530. package/src/resources/extensions/gsd/preferences-types.ts +20 -0
  531. package/src/resources/extensions/gsd/preferences-validation.ts +26 -0
  532. package/src/resources/extensions/gsd/preferences.ts +15 -13
  533. package/src/resources/extensions/gsd/prompts/forensics.md +11 -7
  534. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  535. package/src/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  536. package/src/resources/extensions/gsd/provider-error-pause.ts +0 -48
  537. package/src/resources/extensions/gsd/roadmap-mutations.ts +134 -0
  538. package/src/resources/extensions/gsd/rtk-status.ts +53 -0
  539. package/src/resources/extensions/gsd/rule-registry.ts +11 -12
  540. package/src/resources/extensions/gsd/service-tier.ts +14 -2
  541. package/src/resources/extensions/gsd/session-forensics.ts +7 -3
  542. package/src/resources/extensions/gsd/skill-catalog.ts +1085 -0
  543. package/src/resources/extensions/gsd/skill-discovery.ts +3 -2
  544. package/src/resources/extensions/gsd/skill-health.ts +2 -2
  545. package/src/resources/extensions/gsd/skill-telemetry.ts +15 -5
  546. package/src/resources/extensions/gsd/state.ts +38 -7
  547. package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
  548. package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  549. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +16 -0
  550. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +2 -2
  551. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +68 -0
  552. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
  553. package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
  554. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
  555. package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
  556. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +2 -2
  557. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  558. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
  559. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  560. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +5 -3
  561. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +33 -0
  562. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +39 -10
  563. package/src/resources/extensions/gsd/tests/detection.test.ts +839 -1
  564. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  565. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
  566. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
  567. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
  568. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
  569. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  570. package/src/resources/extensions/gsd/tests/git-service.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  572. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +63 -0
  573. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
  574. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
  575. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
  576. package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
  577. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  578. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  579. package/src/resources/extensions/gsd/tests/model-router.test.ts +40 -0
  580. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
  581. package/src/resources/extensions/gsd/tests/notifications.test.ts +28 -6
  582. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
  583. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +474 -0
  584. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
  585. package/src/resources/extensions/gsd/tests/preferences.test.ts +51 -1
  586. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
  587. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +40 -0
  588. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +6 -6
  589. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
  590. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
  591. package/src/resources/extensions/gsd/tests/retry-diagnostic-reasoning.test.ts +161 -0
  592. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +4 -5
  593. package/src/resources/extensions/gsd/tests/rewrite-count-persist.test.ts +82 -0
  594. package/src/resources/extensions/gsd/tests/run-uat.test.ts +146 -0
  595. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +12 -12
  596. package/src/resources/extensions/gsd/tests/skill-catalog.test.ts +193 -0
  597. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +56 -21
  598. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
  599. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
  600. package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
  601. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
  602. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
  603. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
  604. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -14
  605. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -21
  606. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -22
  607. package/src/resources/extensions/gsd/tools/plan-milestone.ts +28 -18
  608. package/src/resources/extensions/gsd/tools/plan-slice.ts +28 -16
  609. package/src/resources/extensions/gsd/tools/plan-task.ts +24 -12
  610. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +54 -42
  611. package/src/resources/extensions/gsd/tools/replan-slice.ts +53 -40
  612. package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
  613. package/src/resources/extensions/gsd/types.ts +2 -0
  614. package/src/resources/extensions/gsd/undo.ts +8 -7
  615. package/src/resources/extensions/gsd/unit-runtime.ts +2 -1
  616. package/src/resources/extensions/gsd/verification-gate.ts +3 -1
  617. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  618. package/src/resources/extensions/remote-questions/config.ts +1 -1
  619. package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
  620. package/src/resources/extensions/search-the-web/native-search.ts +1 -1
  621. package/src/resources/extensions/search-the-web/provider.ts +1 -1
  622. package/src/resources/extensions/shared/rtk-session-stats.ts +249 -0
  623. package/src/resources/extensions/shared/rtk.ts +120 -0
  624. package/dist/web/standalone/.next/server/chunks/229.js +0 -12
  625. package/dist/web/standalone/.next/server/chunks/441.js +0 -2
  626. package/dist/web/standalone/.next/server/chunks/471.js +0 -13
  627. package/dist/web/standalone/.next/static/MQOhBnkC_TLtNn_JvZWDj/_buildManifest.js +0 -1
  628. package/dist/web/standalone/.next/static/chunks/4024.7c75ac378de0f2b5.js +0 -9
  629. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-d83ba70a25a85472.js +0 -1
  630. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-d83ba70a25a85472.js +0 -1
  631. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-d83ba70a25a85472.js +0 -1
  632. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-d83ba70a25a85472.js +0 -1
  633. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +0 -1
  634. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +0 -1
  635. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +0 -1
  636. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +0 -1
  637. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +0 -1
  638. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +0 -1
  639. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +0 -1
  640. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +0 -1
  641. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +0 -1
  642. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +0 -1
  673. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +0 -1
  674. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  675. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +0 -1
  676. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +0 -1
  677. package/dist/web/standalone/.next/static/chunks/webpack-2473ce2c3879fff4.js +0 -1
  678. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +0 -1
  679. package/packages/pi-ai/pnpm-lock.yaml +0 -2022
  680. package/packages/pi-coding-agent/pnpm-lock.yaml +0 -454
  681. /package/dist/web/standalone/.next/static/{MQOhBnkC_TLtNn_JvZWDj → RqOU-jOv9uZ1Q03P6L6nn}/_ssgManifest.js +0 -0
@@ -71,6 +71,9 @@ export function getActiveMemoriesRanked(limit = 30) {
71
71
  /**
72
72
  * Generate the next memory ID: MEM + zero-padded 3-digit from MAX(seq).
73
73
  * Returns MEM001 if no memories exist.
74
+ *
75
+ * NOTE: For race-safe creation, prefer createMemory() which inserts with a
76
+ * placeholder ID then updates to the seq-derived ID atomically.
74
77
  */
75
78
  export function nextMemoryId() {
76
79
  if (!isDbAvailable())
@@ -94,7 +97,9 @@ export function nextMemoryId() {
94
97
  }
95
98
  // ─── Mutation Functions ─────────────────────────────────────────────────────
96
99
  /**
97
- * Insert a new memory with auto-assigned ID.
100
+ * Insert a new memory with a race-safe auto-assigned ID.
101
+ * Uses AUTOINCREMENT seq to derive the ID after insert, avoiding
102
+ * the read-then-write race in concurrent scenarios (e.g. worktrees).
98
103
  * Returns the assigned ID, or null on failure.
99
104
  */
100
105
  export function createMemory(fields) {
@@ -104,11 +109,12 @@ export function createMemory(fields) {
104
109
  if (!adapter)
105
110
  return null;
106
111
  try {
107
- const id = nextMemoryId();
108
112
  const now = new Date().toISOString();
113
+ // Insert with a temporary placeholder ID — seq is auto-assigned
114
+ const placeholder = `_TMP_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
109
115
  adapter.prepare(`INSERT INTO memories (id, category, content, confidence, source_unit_type, source_unit_id, created_at, updated_at)
110
116
  VALUES (:id, :category, :content, :confidence, :source_unit_type, :source_unit_id, :created_at, :updated_at)`).run({
111
- ':id': id,
117
+ ':id': placeholder,
112
118
  ':category': fields.category,
113
119
  ':content': fields.content,
114
120
  ':confidence': fields.confidence ?? 0.8,
@@ -117,7 +123,17 @@ export function createMemory(fields) {
117
123
  ':created_at': now,
118
124
  ':updated_at': now,
119
125
  });
120
- return id;
126
+ // Derive the real ID from the assigned seq
127
+ const row = adapter.prepare('SELECT seq FROM memories WHERE id = :id').get({ ':id': placeholder });
128
+ if (!row)
129
+ return placeholder; // fallback — should not happen
130
+ const seq = row['seq'];
131
+ const realId = `MEM${String(seq).padStart(3, '0')}`;
132
+ adapter.prepare('UPDATE memories SET id = :real_id WHERE id = :placeholder').run({
133
+ ':real_id': realId,
134
+ ':placeholder': placeholder,
135
+ });
136
+ return realId;
121
137
  }
122
138
  catch {
123
139
  return null;
@@ -258,15 +274,14 @@ export function enforceMemoryCap(max = 50) {
258
274
  if (count <= max)
259
275
  return;
260
276
  const excess = count - max;
261
- // Find the IDs of the lowest-ranked active memories
262
- const rows = adapter.prepare(`SELECT id FROM memories
263
- WHERE superseded_by IS NULL
264
- ORDER BY (confidence * (1.0 + hit_count * 0.1)) ASC
265
- LIMIT :limit`).all({ ':limit': excess });
266
- const now = new Date().toISOString();
267
- for (const row of rows) {
268
- adapter.prepare('UPDATE memories SET superseded_by = :reason, updated_at = :now WHERE id = :id').run({ ':reason': 'CAP_EXCEEDED', ':now': now, ':id': row['id'] });
269
- }
277
+ // Batch update: supersede lowest-ranked active memories in a single statement
278
+ adapter.prepare(`UPDATE memories SET superseded_by = 'CAP_EXCEEDED', updated_at = :now
279
+ WHERE id IN (
280
+ SELECT id FROM memories
281
+ WHERE superseded_by IS NULL
282
+ ORDER BY (confidence * (1.0 + hit_count * 0.1)) ASC
283
+ LIMIT :limit
284
+ )`).run({ ':now': new Date().toISOString(), ':limit': excess });
270
285
  }
271
286
  catch {
272
287
  // non-fatal
@@ -15,6 +15,7 @@ import { join } from "node:path";
15
15
  import { resolveMilestonePath, resolveMilestoneFile, buildMilestoneFileName, } from "./paths.js";
16
16
  import { invalidateAllCaches } from "./cache.js";
17
17
  import { loadQueueOrder, saveQueueOrder } from "./queue-order.js";
18
+ import { isDbAvailable, updateMilestoneStatus } from "./gsd-db.js";
18
19
  // ─── Park ──────────────────────────────────────────────────────────────────
19
20
  /**
20
21
  * Park a milestone — creates a PARKED.md marker file with reason and timestamp.
@@ -44,6 +45,15 @@ export function parkMilestone(basePath, milestoneId, reason) {
44
45
  "",
45
46
  ].join("\n");
46
47
  writeFileSync(parkedPath, content, "utf-8");
48
+ // Sync DB status so deriveStateFromDb also skips this milestone (#2694)
49
+ if (isDbAvailable()) {
50
+ try {
51
+ updateMilestoneStatus(milestoneId, "parked");
52
+ }
53
+ catch (err) {
54
+ process.stderr.write(`gsd: parkMilestone DB sync failed for ${milestoneId}: ${err.message}\n`);
55
+ }
56
+ }
47
57
  invalidateAllCaches();
48
58
  return true;
49
59
  }
@@ -60,6 +70,15 @@ export function unparkMilestone(basePath, milestoneId) {
60
70
  if (!existsSync(parkedPath))
61
71
  return false; // not parked
62
72
  unlinkSync(parkedPath);
73
+ // Sync DB status so deriveStateFromDb picks up the unparked milestone (#2694)
74
+ if (isDbAvailable()) {
75
+ try {
76
+ updateMilestoneStatus(milestoneId, "active");
77
+ }
78
+ catch (err) {
79
+ process.stderr.write(`gsd: unparkMilestone DB sync failed for ${milestoneId}: ${err.message}\n`);
80
+ }
81
+ }
63
82
  invalidateAllCaches();
64
83
  return true;
65
84
  }
@@ -68,6 +68,20 @@ export function resolveModelForComplexity(classification, phaseConfig, routingCo
68
68
  const configuredPrimary = phaseConfig.primary;
69
69
  const configuredTier = getModelTier(configuredPrimary);
70
70
  const requestedTier = classification.tier;
71
+ // If the configured model is unknown (not in MODEL_CAPABILITY_TIER),
72
+ // honor the user's explicit choice — don't downgrade based on a guess.
73
+ // Unknown models default to "heavy" in getModelTier, which makes every
74
+ // standard/light unit get downgraded to tier_models, silently ignoring
75
+ // the user's configuration. (#2192)
76
+ if (!isKnownModel(configuredPrimary)) {
77
+ return {
78
+ modelId: configuredPrimary,
79
+ fallbacks: phaseConfig.fallbacks,
80
+ tier: requestedTier,
81
+ wasDowngraded: false,
82
+ reason: `configured model "${configuredPrimary}" is not in the known tier map — honoring explicit config`,
83
+ };
84
+ }
71
85
  // Downgrade-only: if requested tier >= configured tier, no change
72
86
  if (tierOrdinal(requestedTier) >= tierOrdinal(configuredTier)) {
73
87
  return {
@@ -141,6 +155,17 @@ function getModelTier(modelId) {
141
155
  // Unknown models are assumed heavy (safest assumption)
142
156
  return "heavy";
143
157
  }
158
+ /** Check if a model ID has a known capability tier mapping. (#2192) */
159
+ function isKnownModel(modelId) {
160
+ const bareId = modelId.includes("/") ? modelId.split("/").pop() : modelId;
161
+ if (MODEL_CAPABILITY_TIER[bareId])
162
+ return true;
163
+ for (const knownId of Object.keys(MODEL_CAPABILITY_TIER)) {
164
+ if (bareId.includes(knownId) || knownId.includes(bareId))
165
+ return true;
166
+ }
167
+ return false;
168
+ }
144
169
  function findModelForTier(tier, config, availableModelIds, crossProvider) {
145
170
  // 1. Check explicit tier_models config
146
171
  const explicitModel = config.tier_models?.[tier];
@@ -49,6 +49,17 @@ export function buildDesktopNotificationCommand(platform, title, message, level
49
49
  const normalizedTitle = normalizeNotificationText(title);
50
50
  const normalizedMessage = normalizeNotificationText(message);
51
51
  if (platform === "darwin") {
52
+ // Prefer terminal-notifier: registers as its own Notification Center app,
53
+ // so it gets a proper permission entry in System Settings → Notifications.
54
+ // osascript notifications are silently swallowed when the calling terminal
55
+ // (Ghostty, iTerm2, etc.) lacks notification permissions — exits 0, no error.
56
+ // See: https://github.com/gsd-build/gsd-2/issues/2632
57
+ const tnPath = findExecutable("terminal-notifier");
58
+ if (tnPath) {
59
+ const sound = level === "error" ? "Basso" : "Glass";
60
+ return { file: tnPath, args: ["-title", normalizedTitle, "-message", normalizedMessage, "-sound", sound] };
61
+ }
62
+ // Fallback: osascript (works if terminal app has notification permissions)
52
63
  const sound = level === "error" ? 'sound name "Basso"' : 'sound name "Glass"';
53
64
  const script = `display notification "${escapeAppleScript(normalizedMessage)}" with title "${escapeAppleScript(normalizedTitle)}" ${sound}`;
54
65
  return { file: "osascript", args: ["-e", script] };
@@ -65,3 +76,15 @@ function normalizeNotificationText(s) {
65
76
  function escapeAppleScript(s) {
66
77
  return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
67
78
  }
79
+ /**
80
+ * Locate an executable on PATH. Returns absolute path or null.
81
+ * Non-fatal — returns null on any error.
82
+ */
83
+ function findExecutable(name) {
84
+ try {
85
+ return execFileSync("which", [name], { timeout: 2000, stdio: ["ignore", "pipe", "ignore"] }).toString().trim() || null;
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ }
@@ -0,0 +1,422 @@
1
+ import { loadFile } from "./files.js";
2
+ import { resolveSliceFile, resolveTaskFile, resolveTasksDir, resolveTaskFiles } from "./paths.js";
3
+ function getSection(content, heading, level = 2) {
4
+ const prefix = "#".repeat(level) + " ";
5
+ const escaped = heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6
+ const regex = new RegExp(`^${prefix}${escaped}\\s*$`, "m");
7
+ const match = regex.exec(content);
8
+ if (!match)
9
+ return null;
10
+ const start = match.index + match[0].length;
11
+ const rest = content.slice(start);
12
+ const nextHeading = rest.match(new RegExp(`^#{1,${level}} `, "m"));
13
+ const end = nextHeading ? nextHeading.index : rest.length;
14
+ return rest.slice(0, end).trim();
15
+ }
16
+ function getFrontmatter(content) {
17
+ const trimmed = content.trimStart();
18
+ if (!trimmed.startsWith("---"))
19
+ return null;
20
+ const afterFirst = trimmed.indexOf("\n");
21
+ if (afterFirst === -1)
22
+ return null;
23
+ const rest = trimmed.slice(afterFirst + 1);
24
+ const endIdx = rest.indexOf("\n---");
25
+ if (endIdx === -1)
26
+ return null;
27
+ return rest.slice(0, endIdx);
28
+ }
29
+ function hasFrontmatterKey(content, key) {
30
+ const fm = getFrontmatter(content);
31
+ if (!fm)
32
+ return false;
33
+ return new RegExp(`^${key}:`, "m").test(fm);
34
+ }
35
+ function normalizeMeaningfulLines(text) {
36
+ return text
37
+ .split("\n")
38
+ .map(line => line.trim())
39
+ .filter(line => line.length > 0)
40
+ .filter(line => !line.startsWith("<!--"))
41
+ .filter(line => !line.endsWith("-->"))
42
+ .filter(line => !/^[-*]\s*\{\{.+\}\}$/.test(line))
43
+ .filter(line => !/^\{\{.+\}\}$/.test(line));
44
+ }
45
+ function sectionLooksPlaceholderOnly(text) {
46
+ if (!text)
47
+ return true;
48
+ const lines = normalizeMeaningfulLines(text)
49
+ .map(line => line.replace(/^[-*]\s+/, "").trim())
50
+ .filter(line => line.length > 0);
51
+ if (lines.length === 0)
52
+ return true;
53
+ return lines.every(line => {
54
+ const lower = line.toLowerCase();
55
+ return lower === "none" ||
56
+ lower.endsWith(": none") ||
57
+ lower.includes("{{") ||
58
+ lower.includes("}}") ||
59
+ lower.startsWith("required for non-trivial") ||
60
+ lower.startsWith("describe how a future agent") ||
61
+ lower.startsWith("prefer:") ||
62
+ lower.startsWith("keep this section concise");
63
+ });
64
+ }
65
+ function textSuggestsObservabilityRelevant(content) {
66
+ const lower = content.toLowerCase();
67
+ const needles = [
68
+ " api", "route", "server", "worker", "queue", "job", "sync", "import",
69
+ "webhook", "auth", "db", "database", "migration", "cache", "background",
70
+ "polling", "realtime", "socket", "stateful", "integration", "ui", "form",
71
+ "submit", "status", "service", "pipeline", "health endpoint", "error path"
72
+ ];
73
+ return needles.some(needle => lower.includes(needle));
74
+ }
75
+ function verificationMentionsDiagnostics(section) {
76
+ if (!section)
77
+ return false;
78
+ const lower = section.toLowerCase();
79
+ const needles = [
80
+ "error", "failure", "diagnostic", "status", "health", "inspect", "log",
81
+ "network", "console", "retry", "last error", "correlation", "readiness"
82
+ ];
83
+ return needles.some(needle => lower.includes(needle));
84
+ }
85
+ export function validateSlicePlanContent(file, content) {
86
+ const issues = [];
87
+ // ── Plan quality rules (always run, not gated by runtime relevance) ──
88
+ const tasksSection = getSection(content, "Tasks", 2);
89
+ if (tasksSection) {
90
+ const lines = tasksSection.split("\n");
91
+ const taskLinePattern = /^- \[[ x]\] \*\*T\d+:/;
92
+ const taskLineIndices = [];
93
+ for (let i = 0; i < lines.length; i++) {
94
+ if (taskLinePattern.test(lines[i]))
95
+ taskLineIndices.push(i);
96
+ }
97
+ for (let t = 0; t < taskLineIndices.length; t++) {
98
+ const start = taskLineIndices[t];
99
+ const end = t + 1 < taskLineIndices.length ? taskLineIndices[t + 1] : lines.length;
100
+ // Check lines between this task header and the next (or section end)
101
+ const bodyLines = lines.slice(start + 1, end);
102
+ const meaningful = bodyLines.filter(l => l.trim().length > 0);
103
+ if (meaningful.length === 0) {
104
+ issues.push({
105
+ severity: "warning",
106
+ scope: "slice-plan",
107
+ file,
108
+ ruleId: "empty_task_entry",
109
+ message: "Inline task entry has no description content beneath the checkbox line.",
110
+ suggestion: "Add at least a Why/Files/Do/Verify summary so the task is self-describing.",
111
+ });
112
+ }
113
+ }
114
+ }
115
+ // ── Observability rules (gated by runtime relevance) ──
116
+ const relevant = textSuggestsObservabilityRelevant(content);
117
+ if (!relevant)
118
+ return issues;
119
+ const obs = getSection(content, "Observability / Diagnostics", 2);
120
+ const verification = getSection(content, "Verification", 2);
121
+ if (!obs) {
122
+ issues.push({
123
+ severity: "warning",
124
+ scope: "slice-plan",
125
+ file,
126
+ ruleId: "missing_observability_section",
127
+ message: "Slice plan appears non-trivial but is missing `## Observability / Diagnostics`.",
128
+ suggestion: "Add runtime signals, inspection surfaces, failure visibility, and redaction constraints.",
129
+ });
130
+ }
131
+ else if (sectionLooksPlaceholderOnly(obs)) {
132
+ issues.push({
133
+ severity: "warning",
134
+ scope: "slice-plan",
135
+ file,
136
+ ruleId: "observability_section_placeholder_only",
137
+ message: "Slice plan has `## Observability / Diagnostics` but it still looks like placeholder text.",
138
+ suggestion: "Replace placeholders with concrete signals and inspection surfaces a future agent should trust.",
139
+ });
140
+ }
141
+ if (!verificationMentionsDiagnostics(verification)) {
142
+ issues.push({
143
+ severity: "warning",
144
+ scope: "slice-plan",
145
+ file,
146
+ ruleId: "verification_missing_diagnostic_check",
147
+ message: "Slice verification does not appear to include any diagnostic or failure-path check.",
148
+ suggestion: "Add at least one verification step for inspectable failure state, structured error output, status surface, or equivalent.",
149
+ });
150
+ }
151
+ return issues;
152
+ }
153
+ export function validateTaskPlanContent(file, content) {
154
+ const issues = [];
155
+ // ── Plan quality rules (always run, not gated by runtime relevance) ──
156
+ // Rule: empty or missing Steps section
157
+ const stepsSection = getSection(content, "Steps", 2);
158
+ if (stepsSection === null || sectionLooksPlaceholderOnly(stepsSection)) {
159
+ issues.push({
160
+ severity: "warning",
161
+ scope: "task-plan",
162
+ file,
163
+ ruleId: "empty_steps_section",
164
+ message: "Task plan has an empty or missing `## Steps` section.",
165
+ suggestion: "Add concrete numbered implementation steps so execution has a clear sequence.",
166
+ });
167
+ }
168
+ // Rule: placeholder-only Verification section
169
+ const verificationSection = getSection(content, "Verification", 2);
170
+ if (verificationSection !== null && sectionLooksPlaceholderOnly(verificationSection)) {
171
+ issues.push({
172
+ severity: "warning",
173
+ scope: "task-plan",
174
+ file,
175
+ ruleId: "placeholder_verification",
176
+ message: "Task plan has `## Verification` but it still looks like placeholder text.",
177
+ suggestion: "Replace placeholders with concrete verification commands, test runs, or observable checks.",
178
+ });
179
+ }
180
+ // Rule: scope estimate thresholds
181
+ const fm = getFrontmatter(content);
182
+ if (fm) {
183
+ const stepsMatch = fm.match(/^estimated_steps:\s*(\d+)/m);
184
+ const filesMatch = fm.match(/^estimated_files:\s*(\d+)/m);
185
+ if (stepsMatch) {
186
+ const estimatedSteps = parseInt(stepsMatch[1], 10);
187
+ if (estimatedSteps >= 10) {
188
+ issues.push({
189
+ severity: "warning",
190
+ scope: "task-plan",
191
+ file,
192
+ ruleId: "scope_estimate_steps_high",
193
+ message: `Task plan estimates ${estimatedSteps} steps (threshold: 10). Consider splitting into smaller tasks.`,
194
+ suggestion: "Break the task into sub-tasks or reduce scope so each task stays focused and completable in one pass.",
195
+ });
196
+ }
197
+ }
198
+ if (filesMatch) {
199
+ const estimatedFiles = parseInt(filesMatch[1], 10);
200
+ if (estimatedFiles >= 12) {
201
+ issues.push({
202
+ severity: "warning",
203
+ scope: "task-plan",
204
+ file,
205
+ ruleId: "scope_estimate_files_high",
206
+ message: `Task plan estimates ${estimatedFiles} files (threshold: 12). Consider splitting into smaller tasks.`,
207
+ suggestion: "Break the task into sub-tasks or reduce scope to keep the change footprint manageable.",
208
+ });
209
+ }
210
+ }
211
+ }
212
+ // Rule: Inputs and Expected Output should contain backtick-wrapped file paths
213
+ const inputsSection = getSection(content, "Inputs", 2);
214
+ const outputSection = getSection(content, "Expected Output", 2);
215
+ const backtickPathPattern = /`[^`]*[./][^`]*`/;
216
+ if (outputSection === null || !backtickPathPattern.test(outputSection)) {
217
+ issues.push({
218
+ severity: "warning",
219
+ scope: "task-plan",
220
+ file,
221
+ ruleId: "missing_output_file_paths",
222
+ message: "Task plan `## Expected Output` is missing or has no backtick-wrapped file paths.",
223
+ suggestion: "List concrete output file paths in backticks (e.g. `src/types.ts`). These are machine-parsed to derive task dependencies.",
224
+ });
225
+ }
226
+ if (inputsSection !== null && inputsSection.trim().length > 0 && !backtickPathPattern.test(inputsSection)) {
227
+ issues.push({
228
+ severity: "info",
229
+ scope: "task-plan",
230
+ file,
231
+ ruleId: "missing_input_file_paths",
232
+ message: "Task plan `## Inputs` has content but no backtick-wrapped file paths.",
233
+ suggestion: "List input file paths in backticks (e.g. `src/config.json`). These are machine-parsed to derive task dependencies.",
234
+ });
235
+ }
236
+ // ── Observability rules (gated by runtime relevance) ──
237
+ const relevant = textSuggestsObservabilityRelevant(content);
238
+ if (!relevant)
239
+ return issues;
240
+ const obs = getSection(content, "Observability Impact", 2);
241
+ if (!obs) {
242
+ issues.push({
243
+ severity: "warning",
244
+ scope: "task-plan",
245
+ file,
246
+ ruleId: "missing_observability_impact",
247
+ message: "Task plan appears runtime-relevant but is missing `## Observability Impact`.",
248
+ suggestion: "Explain what signals change, how a future agent inspects this task, and what failure state becomes visible.",
249
+ });
250
+ }
251
+ else if (sectionLooksPlaceholderOnly(obs)) {
252
+ issues.push({
253
+ severity: "warning",
254
+ scope: "task-plan",
255
+ file,
256
+ ruleId: "observability_impact_placeholder_only",
257
+ message: "Task plan has `## Observability Impact` but it still looks empty or placeholder-only.",
258
+ suggestion: "Fill in concrete inspection surfaces or explicitly justify why observability is not applicable.",
259
+ });
260
+ }
261
+ return issues;
262
+ }
263
+ export function validateTaskSummaryContent(file, content) {
264
+ const issues = [];
265
+ if (!hasFrontmatterKey(content, "observability_surfaces")) {
266
+ issues.push({
267
+ severity: "warning",
268
+ scope: "task-summary",
269
+ file,
270
+ ruleId: "missing_observability_frontmatter",
271
+ message: "Task summary is missing `observability_surfaces` in frontmatter.",
272
+ suggestion: "List the durable status/log/error surfaces a future agent should use.",
273
+ });
274
+ }
275
+ const diagnostics = getSection(content, "Diagnostics", 2);
276
+ if (!diagnostics) {
277
+ issues.push({
278
+ severity: "warning",
279
+ scope: "task-summary",
280
+ file,
281
+ ruleId: "missing_diagnostics_section",
282
+ message: "Task summary is missing `## Diagnostics`.",
283
+ suggestion: "Document how to inspect what this task built later.",
284
+ });
285
+ }
286
+ else if (sectionLooksPlaceholderOnly(diagnostics)) {
287
+ issues.push({
288
+ severity: "warning",
289
+ scope: "task-summary",
290
+ file,
291
+ ruleId: "diagnostics_placeholder_only",
292
+ message: "Task summary diagnostics section still looks like placeholder text.",
293
+ suggestion: "Replace placeholders with concrete commands, endpoints, logs, error shapes, or failure artifacts.",
294
+ });
295
+ }
296
+ const evidence = getSection(content, "Verification Evidence", 2);
297
+ if (!evidence) {
298
+ issues.push({
299
+ severity: "warning",
300
+ scope: "task-summary",
301
+ file,
302
+ ruleId: "evidence_block_missing",
303
+ message: "Task summary is missing `## Verification Evidence`.",
304
+ suggestion: "Add a verification evidence table showing gate check results (command, exit code, verdict, duration).",
305
+ });
306
+ }
307
+ else if (sectionLooksPlaceholderOnly(evidence)) {
308
+ issues.push({
309
+ severity: "warning",
310
+ scope: "task-summary",
311
+ file,
312
+ ruleId: "evidence_block_placeholder",
313
+ message: "Task summary verification evidence section still looks like placeholder text.",
314
+ suggestion: "Replace placeholders with actual gate results or note that no verification commands were discovered.",
315
+ });
316
+ }
317
+ return issues;
318
+ }
319
+ export function validateSliceSummaryContent(file, content) {
320
+ const issues = [];
321
+ if (!hasFrontmatterKey(content, "observability_surfaces")) {
322
+ issues.push({
323
+ severity: "warning",
324
+ scope: "slice-summary",
325
+ file,
326
+ ruleId: "missing_observability_frontmatter",
327
+ message: "Slice summary is missing `observability_surfaces` in frontmatter.",
328
+ suggestion: "List the authoritative diagnostics and durable inspection surfaces for this slice.",
329
+ });
330
+ }
331
+ const diagnostics = getSection(content, "Authoritative diagnostics", 3);
332
+ if (!diagnostics) {
333
+ issues.push({
334
+ severity: "warning",
335
+ scope: "slice-summary",
336
+ file,
337
+ ruleId: "missing_authoritative_diagnostics",
338
+ message: "Slice summary is missing `### Authoritative diagnostics` in Forward Intelligence.",
339
+ suggestion: "Tell future agents where to look first and why that signal is trustworthy.",
340
+ });
341
+ }
342
+ else if (sectionLooksPlaceholderOnly(diagnostics)) {
343
+ issues.push({
344
+ severity: "warning",
345
+ scope: "slice-summary",
346
+ file,
347
+ ruleId: "authoritative_diagnostics_placeholder_only",
348
+ message: "Slice summary includes authoritative diagnostics but it still looks like placeholder text.",
349
+ suggestion: "Replace placeholders with the real first-stop diagnostic surface for this slice.",
350
+ });
351
+ }
352
+ return issues;
353
+ }
354
+ export async function validatePlanBoundary(basePath, milestoneId, sliceId) {
355
+ const issues = [];
356
+ const slicePlan = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN");
357
+ if (slicePlan) {
358
+ const content = await loadFile(slicePlan);
359
+ if (content)
360
+ issues.push(...validateSlicePlanContent(slicePlan, content));
361
+ }
362
+ const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId);
363
+ const taskPlans = tasksDir ? resolveTaskFiles(tasksDir, "PLAN") : [];
364
+ for (const file of taskPlans) {
365
+ const taskId = file.split("-")[0];
366
+ const taskPlan = resolveTaskFile(basePath, milestoneId, sliceId, taskId, "PLAN");
367
+ if (!taskPlan)
368
+ continue;
369
+ const content = await loadFile(taskPlan);
370
+ if (content)
371
+ issues.push(...validateTaskPlanContent(taskPlan, content));
372
+ }
373
+ return issues;
374
+ }
375
+ export async function validateExecuteBoundary(basePath, milestoneId, sliceId, taskId) {
376
+ const issues = [];
377
+ const slicePlan = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN");
378
+ if (slicePlan) {
379
+ const content = await loadFile(slicePlan);
380
+ if (content)
381
+ issues.push(...validateSlicePlanContent(slicePlan, content));
382
+ }
383
+ const taskPlan = resolveTaskFile(basePath, milestoneId, sliceId, taskId, "PLAN");
384
+ if (taskPlan) {
385
+ const content = await loadFile(taskPlan);
386
+ if (content)
387
+ issues.push(...validateTaskPlanContent(taskPlan, content));
388
+ }
389
+ return issues;
390
+ }
391
+ export async function validateCompleteBoundary(basePath, milestoneId, sliceId) {
392
+ const issues = [];
393
+ const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId);
394
+ const taskSummaries = tasksDir ? resolveTaskFiles(tasksDir, "SUMMARY") : [];
395
+ for (const file of taskSummaries) {
396
+ const taskId = file.split("-")[0];
397
+ const taskSummary = resolveTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY");
398
+ if (!taskSummary)
399
+ continue;
400
+ const content = await loadFile(taskSummary);
401
+ if (content)
402
+ issues.push(...validateTaskSummaryContent(taskSummary, content));
403
+ }
404
+ const sliceSummary = resolveSliceFile(basePath, milestoneId, sliceId, "SUMMARY");
405
+ if (sliceSummary) {
406
+ const content = await loadFile(sliceSummary);
407
+ if (content)
408
+ issues.push(...validateSliceSummaryContent(sliceSummary, content));
409
+ }
410
+ return issues;
411
+ }
412
+ export function formatValidationIssues(issues, limit = 4) {
413
+ if (issues.length === 0)
414
+ return "";
415
+ const lines = issues.slice(0, limit).map(issue => {
416
+ const fileName = issue.file.split("/").pop() || issue.file;
417
+ return `- ${fileName}: ${issue.message}`;
418
+ });
419
+ if (issues.length > limit)
420
+ lines.push(`- ...and ${issues.length - limit} more`);
421
+ return lines.join("\n");
422
+ }
@@ -98,18 +98,6 @@ export function getNextFallbackModel(currentModelId, modelConfig) {
98
98
  return modelsToTry[0];
99
99
  }
100
100
  }
101
- /**
102
- * Detect whether an error message indicates a transient network error
103
- * (worth retrying the same model) vs a permanent provider error
104
- * (auth failure, quota exceeded, etc. -- should fall back immediately).
105
- */
106
- export function isTransientNetworkError(errorMsg) {
107
- if (!errorMsg)
108
- return false;
109
- const hasNetworkSignal = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fetch failed|connection.*reset|dns/i.test(errorMsg);
110
- const hasPermanentSignal = /auth|unauthorized|forbidden|invalid.*key|quota|billing/i.test(errorMsg);
111
- return hasNetworkSignal && !hasPermanentSignal;
112
- }
113
101
  /**
114
102
  * Validate a model ID string.
115
103
  * Returns true if the ID looks like a valid model identifier.
@@ -273,7 +261,7 @@ export function resolveContextSelection() {
273
261
  return profile === "budget" ? "smart" : "full";
274
262
  }
275
263
  /**
276
- * Resolve the search provider preference from preferences.md.
264
+ * Resolve the search provider preference from PREFERENCES.md.
277
265
  * Returns undefined if not configured (caller falls back to existing behavior).
278
266
  */
279
267
  export function resolveSearchProviderFromPreferences() {
@@ -7,19 +7,25 @@
7
7
  import { existsSync, readdirSync } from "node:fs";
8
8
  import { homedir } from "node:os";
9
9
  import { isAbsolute, join } from "node:path";
10
- import { getAgentDir } from "@gsd/pi-coding-agent";
11
10
  import { statSync } from "node:fs";
12
11
  import { validatePreferences } from "./preferences-validation.js";
13
12
  import { loadEffectiveGSDPreferences } from "./preferences.js";
14
13
  /**
15
14
  * Known skill directories, in priority order.
16
- * User skills (~/.gsd/agent/skills/) take precedence over project skills.
15
+ * Global skills (~/.agents/skills/) take precedence over project skills.
16
+ * Legacy ~/.gsd/agent/skills/ is included as a fallback for pre-migration installs.
17
17
  */
18
18
  export function getSkillSearchDirs(cwd) {
19
- return [
20
- { dir: join(getAgentDir(), "skills"), method: "user-skill" },
21
- { dir: join(cwd, ".pi", "agent", "skills"), method: "project-skill" },
19
+ const dirs = [
20
+ { dir: join(homedir(), ".agents", "skills"), method: "user-skill" },
21
+ { dir: join(cwd, ".agents", "skills"), method: "project-skill" },
22
22
  ];
23
+ // Legacy fallback — read skills from old GSD directory only if migration hasn't completed
24
+ const legacyDir = join(homedir(), ".gsd", "agent", "skills");
25
+ if (existsSync(legacyDir) && !existsSync(join(legacyDir, ".migrated-to-agents"))) {
26
+ dirs.push({ dir: legacyDir, method: "user-skill" });
27
+ }
28
+ return dirs;
23
29
  }
24
30
  /**
25
31
  * Resolve a single skill reference to an absolute path.