gsd-pi 2.41.0 → 2.42.0-dev.1df898f

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 (494) hide show
  1. package/README.md +92 -29
  2. package/dist/cli-web-branch.d.ts +6 -0
  3. package/dist/cli-web-branch.js +17 -0
  4. package/dist/cli.js +18 -3
  5. package/dist/loader.js +3 -1
  6. package/dist/onboarding.js +2 -1
  7. package/dist/resource-loader.js +39 -6
  8. package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
  9. package/dist/resources/extensions/async-jobs/await-tool.js +5 -0
  10. package/dist/resources/extensions/async-jobs/index.js +2 -0
  11. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  12. package/dist/resources/extensions/gsd/auto/phases.js +29 -13
  13. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  17. package/dist/resources/extensions/gsd/auto-prompts.js +3 -16
  18. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  19. package/dist/resources/extensions/gsd/auto-start.js +16 -14
  20. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  21. package/dist/resources/extensions/gsd/auto.js +64 -2
  22. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  23. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  24. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
  26. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  27. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  29. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  30. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  31. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  32. package/dist/resources/extensions/gsd/context-store.js +4 -3
  33. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  34. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  35. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  36. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  37. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  38. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  39. package/dist/resources/extensions/gsd/detection.js +20 -1
  40. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  41. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  42. package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
  43. package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
  44. package/dist/resources/extensions/gsd/doctor.js +11 -1
  45. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  46. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  47. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  48. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  49. package/dist/resources/extensions/gsd/export.js +9 -13
  50. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  51. package/dist/resources/extensions/gsd/files.js +28 -11
  52. package/dist/resources/extensions/gsd/forensics.js +94 -3
  53. package/dist/resources/extensions/gsd/git-constants.js +1 -0
  54. package/dist/resources/extensions/gsd/git-service.js +6 -2
  55. package/dist/resources/extensions/gsd/graph.js +225 -0
  56. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  57. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  58. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  59. package/dist/resources/extensions/gsd/journal.js +85 -0
  60. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  61. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  62. package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
  63. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  64. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  65. package/dist/resources/extensions/gsd/preferences.js +60 -8
  66. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  67. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  68. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
  71. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  72. package/dist/resources/extensions/gsd/repo-identity.js +92 -7
  73. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  74. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  75. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  76. package/dist/resources/extensions/gsd/service-tier.js +147 -0
  77. package/dist/resources/extensions/gsd/session-lock.js +2 -2
  78. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  79. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  80. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  81. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  82. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  83. package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
  84. package/dist/resources/extensions/gsd/worktree.js +2 -2
  85. package/dist/resources/extensions/mcp-client/index.js +2 -1
  86. package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
  87. package/dist/resources/extensions/subagent/index.js +7 -3
  88. package/dist/resources/extensions/voice/index.js +4 -4
  89. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  90. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  91. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  92. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  93. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  94. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  95. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  96. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  97. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  98. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  101. package/dist/web/standalone/.next/build-manifest.json +4 -4
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  104. package/dist/web/standalone/.next/required-server-files.json +3 -3
  105. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  106. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  108. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  116. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  170. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  176. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  190. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/index.html +1 -1
  204. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  205. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  206. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  207. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  208. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  209. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  210. package/dist/web/standalone/.next/server/app/page.js +2 -2
  211. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  213. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  214. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  215. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/middleware.js +2 -2
  218. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  220. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  221. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  222. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  223. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  224. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  228. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  230. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  231. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  232. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  233. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  234. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  235. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  236. package/dist/web/standalone/server.js +1 -1
  237. package/dist/web-mode.d.ts +4 -0
  238. package/dist/web-mode.js +69 -11
  239. package/package.json +1 -1
  240. package/packages/native/src/__tests__/text.test.mjs +33 -0
  241. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  242. package/packages/pi-agent-core/dist/agent.js +2 -0
  243. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  244. package/packages/pi-agent-core/dist/types.d.ts +6 -0
  245. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  246. package/packages/pi-agent-core/dist/types.js.map +1 -1
  247. package/packages/pi-agent-core/src/agent.test.ts +53 -0
  248. package/packages/pi-agent-core/src/agent.ts +3 -0
  249. package/packages/pi-agent-core/src/types.ts +6 -0
  250. package/packages/pi-agent-core/tsconfig.json +1 -1
  251. package/packages/pi-ai/dist/models.d.ts +5 -3
  252. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  253. package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
  254. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/models.generated.js +1135 -1588
  256. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  257. package/packages/pi-ai/dist/models.js.map +1 -1
  258. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  259. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
  260. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  261. package/packages/pi-ai/scripts/generate-models.ts +1543 -0
  262. package/packages/pi-ai/src/models.generated.ts +1140 -1593
  263. package/packages/pi-ai/src/models.ts +7 -4
  264. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
  265. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
  267. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  269. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
  271. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
  273. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  275. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  278. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
  281. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -0
  284. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
  286. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
  288. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
  290. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
  292. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
  295. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -10
  307. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  308. package/packages/pi-coding-agent/package.json +1 -1
  309. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -1
  310. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
  311. package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
  312. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  313. package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
  314. package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
  315. package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
  316. package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
  317. package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
  318. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
  319. package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
  320. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
  321. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  322. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
  323. package/pkg/package.json +1 -1
  324. package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
  325. package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
  326. package/src/resources/extensions/async-jobs/await-tool.test.ts +47 -0
  327. package/src/resources/extensions/async-jobs/await-tool.ts +5 -0
  328. package/src/resources/extensions/async-jobs/index.ts +1 -0
  329. package/src/resources/extensions/async-jobs/job-manager.ts +2 -0
  330. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -2
  331. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  332. package/src/resources/extensions/gsd/auto/phases.ts +31 -13
  333. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  334. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  335. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  336. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  337. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  338. package/src/resources/extensions/gsd/auto-prompts.ts +2 -18
  339. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  340. package/src/resources/extensions/gsd/auto-start.ts +15 -13
  341. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  342. package/src/resources/extensions/gsd/auto.ts +71 -2
  343. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  344. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  345. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  346. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
  347. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  348. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  349. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  350. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  351. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  352. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  353. package/src/resources/extensions/gsd/context-store.ts +4 -3
  354. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  355. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  356. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  357. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  358. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  359. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  360. package/src/resources/extensions/gsd/detection.ts +20 -1
  361. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  362. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  363. package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
  364. package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
  365. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  366. package/src/resources/extensions/gsd/doctor.ts +12 -1
  367. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  368. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  369. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  370. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  371. package/src/resources/extensions/gsd/export.ts +8 -15
  372. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  373. package/src/resources/extensions/gsd/files.ts +29 -12
  374. package/src/resources/extensions/gsd/forensics.ts +101 -3
  375. package/src/resources/extensions/gsd/git-constants.ts +1 -0
  376. package/src/resources/extensions/gsd/git-service.ts +5 -5
  377. package/src/resources/extensions/gsd/gitignore.ts +1 -1
  378. package/src/resources/extensions/gsd/graph.ts +312 -0
  379. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  380. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  381. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  382. package/src/resources/extensions/gsd/journal.ts +134 -0
  383. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  384. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  385. package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
  386. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  387. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  388. package/src/resources/extensions/gsd/preferences.ts +63 -6
  389. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  390. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  391. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  392. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  393. package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
  394. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  395. package/src/resources/extensions/gsd/repo-identity.ts +95 -7
  396. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  397. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  398. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  399. package/src/resources/extensions/gsd/service-tier.ts +184 -0
  400. package/src/resources/extensions/gsd/session-lock.ts +2 -2
  401. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  402. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  403. package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
  404. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  405. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  406. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  407. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  408. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  409. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  410. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  411. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  412. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  413. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  414. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  415. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  416. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  417. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  418. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  419. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  420. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  421. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  422. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  423. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  424. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  425. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  426. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  427. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  428. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
  429. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
  430. package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
  431. package/src/resources/extensions/gsd/tests/git-service.test.ts +44 -0
  432. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  433. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  434. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  435. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  436. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  437. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  438. package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
  439. package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
  440. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  441. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  442. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  443. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  444. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  445. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  446. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  447. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  448. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  449. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  450. package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
  451. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +56 -3
  452. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  453. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  454. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  455. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
  456. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  457. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  458. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  459. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
  460. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  461. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  462. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  463. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
  464. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
  465. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +79 -5
  466. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  467. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  468. package/src/resources/extensions/gsd/types.ts +3 -0
  469. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  470. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  471. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  472. package/src/resources/extensions/gsd/worktree-resolver.ts +32 -12
  473. package/src/resources/extensions/gsd/worktree.ts +2 -2
  474. package/src/resources/extensions/mcp-client/index.ts +5 -1
  475. package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
  476. package/src/resources/extensions/subagent/index.ts +7 -3
  477. package/src/resources/extensions/voice/index.ts +4 -4
  478. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  479. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  480. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  481. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  482. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  483. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  484. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  485. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  486. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  487. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  488. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  489. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  490. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  491. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  492. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  493. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_buildManifest.js +0 -0
  494. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_ssgManifest.js +0 -0
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Service Tier — gating, status formatting, icon resolution, and
3
+ * the /gsd fast command handler.
4
+ *
5
+ * Service tiers (priority/flex) are an OpenAI feature that only applies
6
+ * to gpt-5.4 variants. This module centralizes the model-gating logic
7
+ * so that icons, preferences, and the before_provider_request hook all
8
+ * use a single source of truth.
9
+ */
10
+ import { existsSync, readFileSync } from "node:fs";
11
+ import { saveFile } from "./files.js";
12
+ import { getGlobalGSDPreferencesPath, loadEffectiveGSDPreferences, loadGlobalGSDPreferences, } from "./preferences.js";
13
+ import { ensurePreferencesFile, serializePreferencesToFrontmatter } from "./commands-prefs-wizard.js";
14
+ const SERVICE_TIER_SCOPE_NOTE = "Only affects gpt-5.4 models, regardless of provider.";
15
+ // ─── Gating ──────────────────────────────────────────────────────────────────
16
+ /**
17
+ * Returns true when the given model ID supports OpenAI service tiers.
18
+ * Currently only gpt-5.4 variants qualify.
19
+ */
20
+ export function supportsServiceTier(modelId) {
21
+ if (!modelId)
22
+ return false;
23
+ // Strip provider prefix if present (e.g. "openai/gpt-5.4" → "gpt-5.4")
24
+ const bare = modelId.includes("/") ? modelId.split("/").pop() : modelId;
25
+ return bare.startsWith("gpt-5.4");
26
+ }
27
+ // ─── Status Formatting ───────────────────────────────────────────────────────
28
+ /**
29
+ * Human-readable description of the current service tier setting.
30
+ */
31
+ export function formatServiceTierStatus(tier) {
32
+ if (!tier) {
33
+ return [
34
+ "Service tier: disabled",
35
+ "",
36
+ "Usage:",
37
+ " /gsd fast on Set to priority (2x cost, faster)",
38
+ " /gsd fast flex Set to flex (0.5x cost, slower)",
39
+ " /gsd fast off Disable service tier",
40
+ "",
41
+ SERVICE_TIER_SCOPE_NOTE,
42
+ ].join("\n");
43
+ }
44
+ const label = tier === "priority" ? "priority (2x cost, faster)" : "flex (0.5x cost, slower)";
45
+ return [
46
+ `Service tier: ${label}`,
47
+ "",
48
+ "Usage:",
49
+ " /gsd fast on Set to priority (2x cost, faster)",
50
+ " /gsd fast flex Set to flex (0.5x cost, slower)",
51
+ " /gsd fast off Disable service tier",
52
+ "",
53
+ SERVICE_TIER_SCOPE_NOTE,
54
+ ].join("\n");
55
+ }
56
+ export function formatServiceTierFooterStatus(tier, modelId) {
57
+ if (!tier || !modelId || !supportsServiceTier(modelId))
58
+ return undefined;
59
+ return tier === "priority" ? "fast: ⚡ priority" : "fast: 💰 flex";
60
+ }
61
+ // ─── Icon Resolution ─────────────────────────────────────────────────────────
62
+ /**
63
+ * Returns the appropriate icon for the active service tier and model.
64
+ * Returns empty string when the tier is inactive or the model doesn't
65
+ * support service tiers.
66
+ */
67
+ export function resolveServiceTierIcon(tier, modelId) {
68
+ if (!tier || !supportsServiceTier(modelId))
69
+ return "";
70
+ return tier === "priority" ? "⚡" : "💰";
71
+ }
72
+ // ─── Preference Read ─────────────────────────────────────────────────────────
73
+ /**
74
+ * Read the effective service_tier setting from preferences.
75
+ */
76
+ export function getEffectiveServiceTier() {
77
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
78
+ const raw = prefs?.service_tier;
79
+ if (raw === "priority" || raw === "flex")
80
+ return raw;
81
+ return undefined;
82
+ }
83
+ // ─── Preference Write ────────────────────────────────────────────────────────
84
+ function extractBodyAfterFrontmatter(content) {
85
+ const start = content.startsWith("---\n") ? 4 : content.startsWith("---\r\n") ? 5 : -1;
86
+ if (start === -1)
87
+ return null;
88
+ const closingIdx = content.indexOf("\n---", start);
89
+ if (closingIdx === -1)
90
+ return null;
91
+ const after = content.slice(closingIdx + 4);
92
+ return after.trim() ? after : null;
93
+ }
94
+ async function writeGlobalServiceTier(ctx, tier) {
95
+ const path = getGlobalGSDPreferencesPath();
96
+ await ensurePreferencesFile(path, ctx, "global");
97
+ const existing = loadGlobalGSDPreferences();
98
+ const prefs = existing?.preferences ? { ...existing.preferences } : {};
99
+ prefs.version = prefs.version || 1;
100
+ if (tier) {
101
+ prefs.service_tier = tier;
102
+ }
103
+ else {
104
+ delete prefs.service_tier;
105
+ }
106
+ const frontmatter = serializePreferencesToFrontmatter(prefs);
107
+ let body = "\n# GSD Skill Preferences\n\nSee `~/.gsd/agent/extensions/gsd/docs/preferences-reference.md` for full field documentation and examples.\n";
108
+ if (existsSync(path)) {
109
+ const preserved = extractBodyAfterFrontmatter(readFileSync(path, "utf-8"));
110
+ if (preserved)
111
+ body = preserved;
112
+ }
113
+ await saveFile(path, `---\n${frontmatter}---${body}`);
114
+ await ctx.waitForIdle();
115
+ await ctx.reload();
116
+ }
117
+ // ─── Command Handler ─────────────────────────────────────────────────────────
118
+ /**
119
+ * Handle `/gsd fast [on|off|flex|status]`.
120
+ */
121
+ export async function handleFast(args, ctx) {
122
+ const trimmed = args.trim().toLowerCase();
123
+ if (!trimmed || trimmed === "status") {
124
+ const tier = getEffectiveServiceTier();
125
+ ctx.ui.notify(formatServiceTierStatus(tier), "info");
126
+ return;
127
+ }
128
+ if (trimmed === "on") {
129
+ await writeGlobalServiceTier(ctx, "priority");
130
+ ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus("priority", ctx.model?.id));
131
+ ctx.ui.notify("Service tier set to priority (2x cost, faster responses). Only affects gpt-5.4 models, regardless of provider.", "info");
132
+ return;
133
+ }
134
+ if (trimmed === "off") {
135
+ await writeGlobalServiceTier(ctx, undefined);
136
+ ctx.ui.setStatus("gsd-fast", undefined);
137
+ ctx.ui.notify("Service tier disabled.", "info");
138
+ return;
139
+ }
140
+ if (trimmed === "flex") {
141
+ await writeGlobalServiceTier(ctx, "flex");
142
+ ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus("flex", ctx.model?.id));
143
+ ctx.ui.notify("Service tier set to flex (0.5x cost, slower responses). Only affects gpt-5.4 models, regardless of provider.", "info");
144
+ return;
145
+ }
146
+ ctx.ui.notify("Usage: /gsd fast [on|off|flex|status]\n\n on Priority tier (2x cost, faster)\n off Disable service tier\n flex Flex tier (0.5x cost, slower)\n status Show current setting", "warning");
147
+ }
@@ -199,7 +199,7 @@ export function acquireSessionLock(basePath) {
199
199
  // during a long LLM call — not a real takeover. Log and continue.
200
200
  const elapsed = Date.now() - _lockAcquiredAt;
201
201
  if (elapsed < 1_800_000) {
202
- process.stderr.write(`[gsd] Lock heartbeat mismatch after ${Math.round(elapsed / 1000)}s — event loop stall, continuing.\n`);
202
+ process.stderr.write(`[gsd] Lock heartbeat caught up after ${Math.round(elapsed / 1000)}s — long LLM call, no action needed.\n`);
203
203
  return; // Suppress false positive
204
204
  }
205
205
  // Past the stale window — check if the lock file still belongs to us before
@@ -252,7 +252,7 @@ export function acquireSessionLock(basePath) {
252
252
  // on benign mtime drift (laptop sleep, heavy LLM event loop stalls).
253
253
  const elapsed = Date.now() - _lockAcquiredAt;
254
254
  if (elapsed < 1_800_000) {
255
- process.stderr.write(`[gsd] Lock heartbeat mismatch after ${Math.round(elapsed / 1000)}s — event loop stall, continuing.\n`);
255
+ process.stderr.write(`[gsd] Lock heartbeat caught up after ${Math.round(elapsed / 1000)}s — long LLM call, no action needed.\n`);
256
256
  return;
257
257
  }
258
258
  // Check PID ownership before declaring compromise (#1578)
@@ -25,6 +25,7 @@ export function formatDecisionCompact(decision) {
25
25
  decision.choice,
26
26
  decision.rationale,
27
27
  decision.revisable,
28
+ decision.made_by ?? 'agent',
28
29
  ].join(" | ");
29
30
  }
30
31
  /** Format multiple decisions in compact notation with a Fields header. */
@@ -32,7 +33,7 @@ export function formatDecisionsCompact(decisions) {
32
33
  if (decisions.length === 0) {
33
34
  return "# Decisions (compact)\n(none)";
34
35
  }
35
- const header = "# Decisions (compact)\nFields: id | when | scope | decision | choice | rationale | revisable";
36
+ const header = "# Decisions (compact)\nFields: id | when | scope | decision | choice | rationale | revisable | made_by";
36
37
  const lines = decisions.map(formatDecisionCompact);
37
38
  return `${header}\n\n${lines.join("\n")}`;
38
39
  }
@@ -4,5 +4,5 @@
4
4
  To reverse a decision, add a new row that supersedes it.
5
5
  Read this file at the start of any planning or research phase. -->
6
6
 
7
- | # | When | Scope | Decision | Choice | Rationale | Revisable? |
8
- |---|------|-------|----------|--------|-----------|------------|
7
+ | # | When | Scope | Decision | Choice | Rationale | Revisable? | Made By |
8
+ |---|------|-------|----------|--------|-----------|------------|---------|
@@ -0,0 +1,7 @@
1
+ /**
2
+ * workflow-engine.ts — WorkflowEngine interface.
3
+ *
4
+ * Defines the contract every engine implementation must satisfy.
5
+ * Imports only from the leaf-node engine-types.
6
+ */
7
+ export {};
@@ -7,8 +7,20 @@
7
7
  import { readFileSync, existsSync } from "node:fs";
8
8
  import { join, dirname } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
- const __extensionDir = dirname(fileURLToPath(import.meta.url));
10
+ import { homedir } from "node:os";
11
+ const __extensionDir = resolveGsdExtensionDir();
11
12
  const registryPath = join(__extensionDir, "workflow-templates", "registry.json");
13
+ /** Resolve the GSD extension dir with fallback to ~/.gsd/agent/extensions/gsd/. */
14
+ function resolveGsdExtensionDir() {
15
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
16
+ if (existsSync(join(moduleDir, "workflow-templates")))
17
+ return moduleDir;
18
+ const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
19
+ const agentGsdDir = join(gsdHome, "agent", "extensions", "gsd");
20
+ if (existsSync(join(agentGsdDir, "workflow-templates")))
21
+ return agentGsdDir;
22
+ return moduleDir;
23
+ }
12
24
  // ─── Registry Cache ──────────────────────────────────────────────────────────
13
25
  let cachedRegistry = null;
14
26
  /**
@@ -206,10 +206,24 @@ export function listWorktrees(basePath) {
206
206
  * If the process is currently inside the worktree, chdir out first.
207
207
  */
208
208
  export function removeWorktree(basePath, name, opts = {}) {
209
- const wtPath = worktreePath(basePath, name);
210
- const resolvedWtPath = existsSync(wtPath) ? realpathSync(wtPath) : wtPath;
209
+ let wtPath = worktreePath(basePath, name);
211
210
  const branch = opts.branch ?? worktreeBranchName(name);
212
211
  const { deleteBranch = true, force = true } = opts;
212
+ // Resolve the ACTUAL worktree path from git's worktree list.
213
+ // The computed path may differ when .gsd/ is (or was) a symlink to an
214
+ // external state directory — git resolves symlinks at worktree creation
215
+ // time, so its registered path points to the resolved external location.
216
+ // If syncStateToProjectRoot later creates a real .gsd/ directory that
217
+ // shadows the symlink, the computed path diverges from git's record.
218
+ try {
219
+ const entries = nativeWorktreeList(basePath);
220
+ const entry = entries.find(e => e.branch === branch);
221
+ if (entry?.path) {
222
+ wtPath = entry.path;
223
+ }
224
+ }
225
+ catch { /* fall back to computed path */ }
226
+ const resolvedWtPath = existsSync(wtPath) ? realpathSync(wtPath) : wtPath;
213
227
  // If we're inside the worktree, move out first — git can't remove an in-use directory
214
228
  const cwd = process.cwd();
215
229
  const resolvedCwd = existsSync(cwd) ? realpathSync(cwd) : cwd;
@@ -226,15 +240,15 @@ export function removeWorktree(basePath, name, opts = {}) {
226
240
  }
227
241
  return;
228
242
  }
229
- // Remove worktree (force if requested, to handle dirty worktrees)
243
+ // Remove worktree using the resolved path (force if requested, to handle dirty worktrees)
230
244
  try {
231
- nativeWorktreeRemove(basePath, wtPath, force);
245
+ nativeWorktreeRemove(basePath, resolvedWtPath, force);
232
246
  }
233
247
  catch { /* may fail */ }
234
248
  // If the directory is still there (e.g. locked), try harder with force
235
- if (existsSync(wtPath)) {
249
+ if (existsSync(resolvedWtPath)) {
236
250
  try {
237
- nativeWorktreeRemove(basePath, wtPath, true);
251
+ nativeWorktreeRemove(basePath, resolvedWtPath, true);
238
252
  }
239
253
  catch { /* may fail */ }
240
254
  }
@@ -253,7 +253,18 @@ export class WorktreeResolver {
253
253
  if (roadmapPath) {
254
254
  const roadmapContent = this.deps.readFileSync(roadmapPath, "utf-8");
255
255
  const mergeResult = this.deps.mergeMilestoneToMain(originalBase, milestoneId, roadmapContent);
256
- ctx.notify(`Milestone ${milestoneId} merged to main.${mergeResult.pushed ? " Pushed to remote." : ""}`, "info");
256
+ if (mergeResult.codeFilesChanged) {
257
+ ctx.notify(`Milestone ${milestoneId} merged to main.${mergeResult.pushed ? " Pushed to remote." : ""}`, "info");
258
+ }
259
+ else {
260
+ // (#1906) Milestone produced only .gsd/ metadata — no actual code was
261
+ // merged. This typically means the LLM wrote planning artifacts
262
+ // (summaries, roadmaps) but never implemented the code. Surface this
263
+ // clearly so the user knows the milestone is not truly complete.
264
+ ctx.notify(`WARNING: Milestone ${milestoneId} merged to main but contained NO code changes — only .gsd/ metadata files. ` +
265
+ `The milestone summary may describe planned work that was never implemented. ` +
266
+ `Review the milestone output and re-run if code is missing.`, "warning");
267
+ }
257
268
  }
258
269
  else {
259
270
  // No roadmap at either location — teardown but PRESERVE the branch so
@@ -275,9 +286,9 @@ export class WorktreeResolver {
275
286
  });
276
287
  // Surface a clear, actionable error. The worktree and milestone branch are
277
288
  // intentionally preserved — nothing has been deleted. The user can retry
278
- // /complete-milestone or merge manually once the underlying issue is fixed
289
+ // /gsd dispatch complete-milestone or merge manually once the underlying issue is fixed
279
290
  // (e.g. checkout to wrong branch, unresolved conflicts). (#1668)
280
- ctx.notify(`Milestone merge failed: ${msg}. Your worktree and milestone branch are preserved — retry /complete-milestone or merge manually.`, "warning");
291
+ ctx.notify(`Milestone merge failed: ${msg}. Your worktree and milestone branch are preserved — retry /gsd dispatch complete-milestone or merge manually.`, "warning");
281
292
  // Clean up stale merge state left by failed squash-merge (#1389)
282
293
  try {
283
294
  const gitDir = join(originalBase || this.s.basePath, ".git");
@@ -339,7 +350,13 @@ export class WorktreeResolver {
339
350
  const mergeResult = this.deps.mergeMilestoneToMain(this.s.basePath, milestoneId, roadmapContent);
340
351
  // Rebuild GitService after merge (branch HEAD changed)
341
352
  this.rebuildGitService();
342
- ctx.notify(`Milestone ${milestoneId} merged (branch mode).${mergeResult.pushed ? " Pushed to remote." : ""}`, "info");
353
+ if (mergeResult.codeFilesChanged) {
354
+ ctx.notify(`Milestone ${milestoneId} merged (branch mode).${mergeResult.pushed ? " Pushed to remote." : ""}`, "info");
355
+ }
356
+ else {
357
+ ctx.notify(`WARNING: Milestone ${milestoneId} merged (branch mode) but contained NO code changes — only .gsd/ metadata. ` +
358
+ `Review the milestone output and re-run if code is missing.`, "warning");
359
+ }
343
360
  debugLog("WorktreeResolver", {
344
361
  action: "mergeAndExit",
345
362
  milestoneId,
@@ -48,14 +48,14 @@ export function setActiveMilestoneId(basePath, milestoneId) {
48
48
  * record when the user starts from a different branch (#300). Always a no-op
49
49
  * if on a GSD slice branch.
50
50
  */
51
- export function captureIntegrationBranch(basePath, milestoneId, options) {
51
+ export function captureIntegrationBranch(basePath, milestoneId) {
52
52
  // In a worktree, the base branch is implicit (worktree/<name>).
53
53
  // Writing it to META.json would leave stale metadata after merge back to main.
54
54
  if (detectWorktreeName(basePath))
55
55
  return;
56
56
  const svc = getService(basePath);
57
57
  const current = svc.getCurrentBranch();
58
- writeIntegrationBranch(basePath, milestoneId, current, options);
58
+ writeIntegrationBranch(basePath, milestoneId, current);
59
59
  }
60
60
  // ─── Pure Utility Functions (unchanged) ────────────────────────────────────
61
61
  /**
@@ -108,7 +108,8 @@ async function getOrConnect(name, signal) {
108
108
  });
109
109
  }
110
110
  else if (config.transport === "http" && config.url) {
111
- transport = new StreamableHTTPClientTransport(new URL(config.url));
111
+ const resolvedUrl = config.url.replace(/\$\{([^}]+)\}/g, (_, name) => process.env[name] ?? "");
112
+ transport = new StreamableHTTPClientTransport(new URL(resolvedUrl));
112
113
  }
113
114
  else {
114
115
  throw new Error(`Server "${name}" has unsupported transport: ${config.transport}`);
@@ -259,9 +259,9 @@ export function registerSearchTool(pi) {
259
259
  // with brief interruptions every MAX_CONSECUTIVE_DUPES+1 calls.
260
260
  if (cacheKey === lastSearchKey) {
261
261
  consecutiveDupeCount++;
262
- if (consecutiveDupeCount >= MAX_CONSECUTIVE_DUPES) {
262
+ if (consecutiveDupeCount > MAX_CONSECUTIVE_DUPES) {
263
263
  return {
264
- content: [{ type: "text", text: `⚠️ Search loop detected: the query "${params.query}" has been searched ${consecutiveDupeCount + 1} times consecutively with identical results. The information you need is already in the previous search results above. Stop searching and use those results to proceed with your task.` }],
264
+ content: [{ type: "text", text: `⚠️ Search loop detected: the query "${params.query}" has been searched ${consecutiveDupeCount} times consecutively with identical results. The information you need is already in the previous search results above. Stop searching and use those results to proceed with your task.` }],
265
265
  isError: true,
266
266
  details: { errorKind: "search_loop", error: "Consecutive duplicate search detected" },
267
267
  };
@@ -269,7 +269,7 @@ export function registerSearchTool(pi) {
269
269
  }
270
270
  else {
271
271
  lastSearchKey = cacheKey;
272
- consecutiveDupeCount = 0;
272
+ consecutiveDupeCount = 1;
273
273
  }
274
274
  const cached = searchCache.get(cacheKey);
275
275
  if (cached) {
@@ -409,12 +409,16 @@ async function runSingleAgentInCmuxSplit(cmuxClient, directionOrSurfaceId, defau
409
409
  const bundledPaths = (process.env.GSD_BUNDLED_EXTENSION_PATHS ?? "").split(path.delimiter).map((s) => s.trim()).filter(Boolean);
410
410
  const extensionArgs = bundledPaths.flatMap((p) => ["--extension", p]);
411
411
  const processArgs = [process.env.GSD_BIN_PATH, ...extensionArgs, ...buildSubagentProcessArgs(agent, task, tmpPromptPath)];
412
+ // Normalize all paths to forward slashes before embedding in bash strings.
413
+ // On Windows, backslashes are interpreted as escape characters by bash,
414
+ // mangling paths like C:\Users\user into C:Useruser (#1436).
415
+ const bashPath = (p) => shellEscape(p.replaceAll("\\", "/"));
412
416
  const innerScript = [
413
- `cd ${shellEscape(cwd ?? defaultCwd)}`,
417
+ `cd ${bashPath(cwd ?? defaultCwd)}`,
414
418
  "set -o pipefail",
415
- `${shellEscape(process.execPath)} ${processArgs.map(shellEscape).join(" ")} 2> >(tee ${shellEscape(stderrPath)} >&2) | tee ${shellEscape(stdoutPath)}`,
419
+ `${bashPath(process.execPath)} ${processArgs.map(a => bashPath(a)).join(" ")} 2> >(tee ${bashPath(stderrPath)} >&2) | tee ${bashPath(stdoutPath)}`,
416
420
  "status=${PIPESTATUS[0]}",
417
- `printf '%s' "$status" > ${shellEscape(exitPath)}`,
421
+ `printf '%s' "$status" > ${bashPath(exitPath)}`,
418
422
  ].join("; ");
419
423
  const sent = await cmuxClient.sendSurface(cmuxSurfaceId, `bash -lc ${shellEscape(innerScript)}`);
420
424
  if (!sent) {
@@ -1,6 +1,6 @@
1
1
  import { shortcutDesc } from "../shared/mod.js";
2
2
  import { isKeyRelease, Key, matchesKey, truncateToWidth, visibleWidth } from "@gsd/pi-tui";
3
- import { spawn, execSync } from "node:child_process";
3
+ import { spawn, execFileSync } from "node:child_process";
4
4
  import * as fs from "node:fs";
5
5
  import * as os from "node:os";
6
6
  import * as path from "node:path";
@@ -22,7 +22,7 @@ function ensureBinary() {
22
22
  if (fs.existsSync(RECOGNIZER_BIN))
23
23
  return true;
24
24
  try {
25
- execSync(`swiftc "${SWIFT_SRC}" -o "${RECOGNIZER_BIN}" -framework Speech -framework AVFoundation`, {
25
+ execFileSync("swiftc", [SWIFT_SRC, "-o", RECOGNIZER_BIN, "-framework", "Speech", "-framework", "AVFoundation"], {
26
26
  timeout: 60000,
27
27
  });
28
28
  return true;
@@ -42,7 +42,7 @@ function ensureLinuxReady(ctx) {
42
42
  }
43
43
  // Check python3 exists
44
44
  try {
45
- execSync("which python3", { stdio: "pipe" });
45
+ execFileSync("which", ["python3"], { stdio: "pipe" });
46
46
  }
47
47
  catch {
48
48
  ctx.ui.notify("Voice: python3 not found — install with: sudo apt install python3", "error");
@@ -51,7 +51,7 @@ function ensureLinuxReady(ctx) {
51
51
  // Check that sounddevice is importable
52
52
  const py = linuxPython();
53
53
  try {
54
- execSync(`${py} -c "import sounddevice"`, {
54
+ execFileSync(py, ["-c", "import sounddevice"], {
55
55
  stdio: "pipe",
56
56
  timeout: 10000,
57
57
  });
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: create-workflow
3
+ description: Conversational guide for creating valid YAML workflow definitions. Use when asked to "create a workflow", "new workflow definition", "build a workflow", "workflow YAML", "define workflow steps", or "workflow from template".
4
+ ---
5
+
6
+ <essential_principles>
7
+ You are a workflow definition author. You help users create valid V1 YAML workflow definitions that the GSD workflow engine can execute.
8
+
9
+ **V1 Schema Basics:**
10
+
11
+ - Every definition requires `version: 1`, a non-empty `name`, and at least one step in `steps[]`.
12
+ - Optional top-level fields: `description` (string), `params` (key-value defaults for `{{ key }}` substitution).
13
+ - Each step requires: `id` (unique string), `name` (non-empty string), `prompt` (non-empty string).
14
+ - Each step optionally has: `requires` or `depends_on` (array of step IDs), `produces` (array of artifact paths), `context_from` (array of step IDs), `verify` (verification policy object), `iterate` (fan-out config object).
15
+ - YAML uses **snake_case** keys: `depends_on`, `context_from`. The engine converts to camelCase internally.
16
+
17
+ **Validation Rules:**
18
+
19
+ - Step IDs must be unique across the workflow.
20
+ - Dependencies (`requires`/`depends_on`) must reference existing step IDs — no dangling refs.
21
+ - A step cannot depend on itself.
22
+ - The dependency graph must be acyclic (no circular dependencies).
23
+ - `produces` paths must not contain `..` (path traversal rejected).
24
+ - `iterate.source` must not contain `..` (path traversal rejected).
25
+ - `iterate.pattern` must be a valid regex with at least one capture group.
26
+
27
+ **Four Verification Policies:**
28
+
29
+ 1. `content-heuristic` — Checks artifact content. Optional: `minSize` (number), `pattern` (string).
30
+ 2. `shell-command` — Runs a shell command. Required: `command` (non-empty string).
31
+ 3. `prompt-verify` — Asks an LLM to verify. Required: `prompt` (non-empty string).
32
+ 4. `human-review` — Pauses for human approval. No extra fields required.
33
+
34
+ **Parameter Substitution:**
35
+
36
+ - Define defaults in top-level `params: { key: "default_value" }`.
37
+ - Use `{{ key }}` placeholders in step prompts — the engine replaces them at runtime.
38
+ - CLI overrides take precedence over definition defaults.
39
+ - Parameter values must not contain `..` (path traversal guard).
40
+ - Any unresolved `{{ key }}` after substitution causes an error.
41
+
42
+ **Path Traversal Guard:**
43
+
44
+ - The engine rejects any `produces` path or `iterate.source` containing `..`.
45
+ - Parameter values are also checked for `..` during substitution.
46
+
47
+ **Output Location:**
48
+
49
+ - Finished definitions go in `.gsd/workflow-defs/<name>.yaml`.
50
+ - After writing, tell the user to validate with `/gsd workflow validate <name>`.
51
+ </essential_principles>
52
+
53
+ <routing>
54
+ Determine the user's intent and route to the appropriate workflow:
55
+
56
+ **"I want to create a workflow from scratch" / "new workflow" / "build a workflow":**
57
+ → Read `workflows/create-from-scratch.md` and follow it.
58
+
59
+ **"I want to start from a template" / "from an example" / "customize a template":**
60
+ → Read `workflows/create-from-template.md` and follow it.
61
+
62
+ **"Help me understand the schema" / "what fields are available?":**
63
+ → Read `references/yaml-schema-v1.md` and explain the relevant parts.
64
+
65
+ **"How does verification work?" / "verify policies":**
66
+ → Read `references/verification-policies.md` and explain.
67
+
68
+ **"How do I use context_from / iterate / params?":**
69
+ → Read `references/feature-patterns.md` and explain the relevant feature.
70
+
71
+ **If intent is unclear, ask one clarifying question:**
72
+ - "Do you want to create a workflow from scratch, or start from an existing template?"
73
+ - Then route based on the answer.
74
+ </routing>
75
+
76
+ <reference_index>
77
+ Read these files when you need detailed schema knowledge during workflow authoring:
78
+
79
+ - `references/yaml-schema-v1.md` — Complete field-by-field V1 schema reference. Read when you need to explain any field's type, constraints, or defaults.
80
+ - `references/verification-policies.md` — All four verify policies with complete YAML examples. Read when helping the user choose or configure verification for a step.
81
+ - `references/feature-patterns.md` — Usage patterns for `context_from`, `iterate`, and `params` with complete YAML examples. Read when the user wants context chaining, fan-out iteration, or parameterized workflows.
82
+ </reference_index>
83
+
84
+ <templates_index>
85
+ Available templates in `templates/`:
86
+
87
+ - `workflow-definition.yaml` — Blank scaffold with all fields shown as comments. Copy and fill for a quick start.
88
+ - `blog-post-pipeline.yaml` — Linear chain with params and content-heuristic verification.
89
+ - `code-audit.yaml` — Iterate-based fan-out with shell-command verification.
90
+ - `release-checklist.yaml` — Diamond dependency graph with human-review verification.
91
+ </templates_index>
92
+
93
+ <output_conventions>
94
+ When assembling the final YAML:
95
+
96
+ 1. Use 2-space indentation consistently.
97
+ 2. Quote string values that contain special YAML characters (`:`, `{`, `}`, `[`, `]`, `#`).
98
+ 3. Always include `version: 1` as the first field.
99
+ 4. Order top-level fields: `version`, `name`, `description`, `params`, `steps`.
100
+ 5. Order step fields: `id`, `name`, `prompt`, `requires`, `produces`, `context_from`, `verify`, `iterate`.
101
+ 6. Write the file to `.gsd/workflow-defs/<name>.yaml`.
102
+ 7. After writing, tell the user: "Run `/gsd workflow validate <name>` to check the definition."
103
+ </output_conventions>