gsd-pi 2.41.0 → 2.42.0-dev.eedc83f

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 (483) 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 +15 -1
  5. package/dist/onboarding.js +2 -1
  6. package/dist/resource-loader.js +39 -6
  7. package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
  8. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  9. package/dist/resources/extensions/gsd/auto/phases.js +28 -10
  10. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  11. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  14. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  15. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  16. package/dist/resources/extensions/gsd/auto-start.js +8 -3
  17. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  18. package/dist/resources/extensions/gsd/auto.js +64 -2
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  20. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  21. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  22. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
  23. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  24. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  25. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  26. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  27. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  28. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  29. package/dist/resources/extensions/gsd/context-store.js +4 -3
  30. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  31. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  32. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  33. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  34. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  35. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  36. package/dist/resources/extensions/gsd/detection.js +20 -1
  37. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  38. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  39. package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
  40. package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
  41. package/dist/resources/extensions/gsd/doctor.js +11 -1
  42. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  43. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  44. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  45. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  46. package/dist/resources/extensions/gsd/export.js +9 -13
  47. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  48. package/dist/resources/extensions/gsd/files.js +28 -11
  49. package/dist/resources/extensions/gsd/forensics.js +94 -3
  50. package/dist/resources/extensions/gsd/git-constants.js +1 -0
  51. package/dist/resources/extensions/gsd/git-service.js +73 -3
  52. package/dist/resources/extensions/gsd/graph.js +225 -0
  53. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  54. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  55. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  56. package/dist/resources/extensions/gsd/journal.js +85 -0
  57. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  58. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  59. package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
  60. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  61. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  62. package/dist/resources/extensions/gsd/preferences.js +60 -8
  63. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  64. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  65. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  66. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
  68. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  69. package/dist/resources/extensions/gsd/repo-identity.js +92 -7
  70. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  71. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  72. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  73. package/dist/resources/extensions/gsd/service-tier.js +147 -0
  74. package/dist/resources/extensions/gsd/session-lock.js +2 -2
  75. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  76. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  77. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  78. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  79. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  80. package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
  81. package/dist/resources/extensions/mcp-client/index.js +2 -1
  82. package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
  83. package/dist/resources/extensions/subagent/index.js +7 -3
  84. package/dist/resources/extensions/voice/index.js +4 -4
  85. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  86. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  87. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  88. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  89. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  90. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  91. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  92. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  93. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  94. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  95. package/dist/web/standalone/.next/BUILD_ID +1 -1
  96. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  97. package/dist/web/standalone/.next/build-manifest.json +4 -4
  98. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  99. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  100. package/dist/web/standalone/.next/required-server-files.json +3 -3
  101. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  102. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  104. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  112. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  166. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  186. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  190. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app/page.js +2 -2
  207. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  209. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  210. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  211. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/middleware.js +2 -2
  214. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  216. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  217. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  218. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  219. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  220. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  224. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  226. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  227. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  228. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  229. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  230. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  231. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  232. package/dist/web/standalone/server.js +1 -1
  233. package/dist/web-mode.d.ts +4 -0
  234. package/dist/web-mode.js +69 -11
  235. package/package.json +1 -1
  236. package/packages/native/src/__tests__/text.test.mjs +33 -0
  237. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  238. package/packages/pi-agent-core/dist/agent.js +2 -0
  239. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  240. package/packages/pi-agent-core/dist/types.d.ts +6 -0
  241. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  242. package/packages/pi-agent-core/dist/types.js.map +1 -1
  243. package/packages/pi-agent-core/src/agent.test.ts +53 -0
  244. package/packages/pi-agent-core/src/agent.ts +3 -0
  245. package/packages/pi-agent-core/src/types.ts +6 -0
  246. package/packages/pi-agent-core/tsconfig.json +1 -1
  247. package/packages/pi-ai/dist/models.d.ts +5 -3
  248. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  249. package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
  250. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/models.generated.js +1135 -1588
  252. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  253. package/packages/pi-ai/dist/models.js.map +1 -1
  254. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
  256. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  257. package/packages/pi-ai/scripts/generate-models.ts +1543 -0
  258. package/packages/pi-ai/src/models.generated.ts +1140 -1593
  259. package/packages/pi-ai/src/models.ts +7 -4
  260. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
  261. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
  263. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  264. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  265. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
  267. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
  269. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  271. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  274. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
  277. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  278. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -0
  280. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
  282. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
  284. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
  286. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
  288. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
  291. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  293. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -10
  303. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  304. package/packages/pi-coding-agent/package.json +1 -1
  305. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -1
  306. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
  307. package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
  308. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  309. package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
  310. package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
  311. package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
  312. package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
  313. package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
  314. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
  315. package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
  316. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
  317. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  318. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
  319. package/pkg/package.json +1 -1
  320. package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
  321. package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
  322. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
  323. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  324. package/src/resources/extensions/gsd/auto/phases.ts +30 -10
  325. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  326. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  327. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  328. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  329. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  330. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  331. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  332. package/src/resources/extensions/gsd/auto-start.ts +8 -3
  333. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  334. package/src/resources/extensions/gsd/auto.ts +71 -2
  335. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  336. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  337. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  338. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
  339. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  340. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  341. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  342. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  343. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  344. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  345. package/src/resources/extensions/gsd/context-store.ts +4 -3
  346. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  347. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  348. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  349. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  350. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  351. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  352. package/src/resources/extensions/gsd/detection.ts +20 -1
  353. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  354. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  355. package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
  356. package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
  357. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  358. package/src/resources/extensions/gsd/doctor.ts +12 -1
  359. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  360. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  361. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  362. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  363. package/src/resources/extensions/gsd/export.ts +8 -15
  364. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  365. package/src/resources/extensions/gsd/files.ts +29 -12
  366. package/src/resources/extensions/gsd/forensics.ts +101 -3
  367. package/src/resources/extensions/gsd/git-constants.ts +1 -0
  368. package/src/resources/extensions/gsd/git-service.ts +76 -6
  369. package/src/resources/extensions/gsd/graph.ts +312 -0
  370. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  371. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  372. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  373. package/src/resources/extensions/gsd/journal.ts +134 -0
  374. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  375. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  376. package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
  377. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  378. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  379. package/src/resources/extensions/gsd/preferences.ts +63 -6
  380. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  381. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  382. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  383. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  384. package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
  385. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  386. package/src/resources/extensions/gsd/repo-identity.ts +95 -7
  387. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  388. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  389. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  390. package/src/resources/extensions/gsd/service-tier.ts +184 -0
  391. package/src/resources/extensions/gsd/session-lock.ts +2 -2
  392. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  393. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  394. package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
  395. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  396. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  397. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  398. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  399. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  400. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  401. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  402. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  403. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  404. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  405. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  406. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  407. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  408. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  409. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  410. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  411. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  412. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  413. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  414. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  415. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  416. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  417. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  418. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  419. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
  420. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
  421. package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
  422. package/src/resources/extensions/gsd/tests/git-service.test.ts +49 -0
  423. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  424. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  425. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  426. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  427. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  428. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  429. package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
  430. package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
  431. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  432. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  433. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  434. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  435. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  436. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  437. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  438. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  439. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  440. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  441. package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
  442. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  443. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  444. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  445. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
  446. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  447. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  448. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  449. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
  450. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  451. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  452. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  453. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
  454. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
  455. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
  456. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  457. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  458. package/src/resources/extensions/gsd/types.ts +3 -0
  459. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  460. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  461. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  462. package/src/resources/extensions/gsd/worktree-resolver.ts +32 -11
  463. package/src/resources/extensions/mcp-client/index.ts +5 -1
  464. package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
  465. package/src/resources/extensions/subagent/index.ts +7 -3
  466. package/src/resources/extensions/voice/index.ts +4 -4
  467. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  468. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  469. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  470. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  471. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  472. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  473. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  474. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  475. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  476. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  477. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  478. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  479. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  480. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  481. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  482. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_buildManifest.js +0 -0
  483. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_ssgManifest.js +0 -0
@@ -167,7 +167,9 @@ import {
167
167
  buildLoopRemediationSteps,
168
168
  reconcileMergeState,
169
169
  } from "./auto-recovery.js";
170
- import { resolveDispatch } from "./auto-dispatch.js";
170
+ import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
171
+ import { initRegistry, convertDispatchRules } from "./rule-registry.js";
172
+ import { emitJournalEvent as _emitJournalEvent, type JournalEntry } from "./journal.js";
171
173
  import {
172
174
  type AutoDashboardData,
173
175
  updateProgressWidget as _updateProgressWidget,
@@ -356,6 +358,22 @@ export function isAutoPaused(): boolean {
356
358
  return s.paused;
357
359
  }
358
360
 
361
+ export function setActiveEngineId(id: string | null): void {
362
+ s.activeEngineId = id;
363
+ }
364
+
365
+ export function getActiveEngineId(): string | null {
366
+ return s.activeEngineId;
367
+ }
368
+
369
+ export function setActiveRunDir(runDir: string | null): void {
370
+ s.activeRunDir = runDir;
371
+ }
372
+
373
+ export function getActiveRunDir(): string | null {
374
+ return s.activeRunDir;
375
+ }
376
+
359
377
  /**
360
378
  * Return the model captured at auto-mode start for this session.
361
379
  * Used by error-recovery to fall back to the session's own model
@@ -535,6 +553,33 @@ function handleLostSessionLock(
535
553
  ctx?.ui.setFooter(undefined);
536
554
  }
537
555
 
556
+ /**
557
+ * Lightweight cleanup after autoLoop exits via step-wizard break.
558
+ *
559
+ * Unlike stopAuto (which tears down the entire session), this only clears
560
+ * the stale unit state, progress widget, status badge, and restores CWD so
561
+ * the dashboard does not show an orphaned timer and the shell is usable.
562
+ */
563
+ function cleanupAfterLoopExit(ctx: ExtensionContext): void {
564
+ s.currentUnit = null;
565
+ s.active = false;
566
+ clearUnitTimeout();
567
+
568
+ ctx.ui.setStatus("gsd-auto", undefined);
569
+ ctx.ui.setWidget("gsd-progress", undefined);
570
+ ctx.ui.setFooter(undefined);
571
+
572
+ // Restore CWD out of worktree back to original project root
573
+ if (s.originalBasePath) {
574
+ s.basePath = s.originalBasePath;
575
+ try {
576
+ process.chdir(s.basePath);
577
+ } catch {
578
+ /* best-effort */
579
+ }
580
+ }
581
+ }
582
+
538
583
  export async function stopAuto(
539
584
  ctx?: ExtensionContext,
540
585
  pi?: ExtensionAPI,
@@ -753,6 +798,8 @@ export async function pauseAuto(
753
798
  stepMode: s.stepMode,
754
799
  pausedAt: new Date().toISOString(),
755
800
  sessionFile: s.pausedSessionFile,
801
+ activeEngineId: s.activeEngineId,
802
+ activeRunDir: s.activeRunDir,
756
803
  };
757
804
  const runtimeDir = join(gsdRoot(s.originalBasePath || s.basePath), "runtime");
758
805
  mkdirSync(runtimeDir, { recursive: true });
@@ -849,6 +896,11 @@ function buildResolver(): WorktreeResolver {
849
896
  * This bundles all private functions that autoLoop needs without exporting them.
850
897
  */
851
898
  function buildLoopDeps(): LoopDeps {
899
+ // Initialize the unified rule registry with converted dispatch rules.
900
+ // Must happen before LoopDeps is assembled so facade functions
901
+ // (resolveDispatch, runPreDispatchHooks, etc.) delegate to the registry.
902
+ initRegistry(convertDispatchRules(DISPATCH_RULES));
903
+
852
904
  return {
853
905
  lockBase,
854
906
  buildSnapshotOpts,
@@ -959,6 +1011,9 @@ function buildLoopDeps(): LoopDeps {
959
1011
  return "";
960
1012
  }
961
1013
  },
1014
+
1015
+ // Journal
1016
+ emitJournalEvent: (entry: JournalEntry) => _emitJournalEvent(s.basePath, entry),
962
1017
  } as unknown as LoopDeps;
963
1018
  }
964
1019
 
@@ -981,7 +1036,19 @@ export async function startAuto(
981
1036
  const pausedPath = join(gsdRoot(base), "runtime", "paused-session.json");
982
1037
  if (existsSync(pausedPath)) {
983
1038
  const meta = JSON.parse(readFileSync(pausedPath, "utf-8"));
984
- if (meta.milestoneId) {
1039
+ if (meta.activeEngineId && meta.activeEngineId !== "dev") {
1040
+ // Custom workflow resume — restore engine state
1041
+ s.activeEngineId = meta.activeEngineId;
1042
+ s.activeRunDir = meta.activeRunDir ?? null;
1043
+ s.originalBasePath = meta.originalBasePath || base;
1044
+ s.stepMode = meta.stepMode ?? requestedStepMode;
1045
+ s.paused = true;
1046
+ try { unlinkSync(pausedPath); } catch { /* non-fatal */ }
1047
+ ctx.ui.notify(
1048
+ `Resuming paused custom workflow${meta.activeRunDir ? ` (${meta.activeRunDir})` : ""}.`,
1049
+ "info",
1050
+ );
1051
+ } else if (meta.milestoneId) {
985
1052
  // Validate the milestone still exists and isn't already complete (#1664).
986
1053
  const mDir = resolveMilestonePath(base, meta.milestoneId);
987
1054
  const summaryFile = resolveMilestoneFile(base, meta.milestoneId, "SUMMARY");
@@ -1121,6 +1188,7 @@ export async function startAuto(
1121
1188
  await selfHealRuntimeRecords(s.basePath, ctx);
1122
1189
 
1123
1190
  await autoLoop(ctx, pi, s, buildLoopDeps());
1191
+ cleanupAfterLoopExit(ctx);
1124
1192
  return;
1125
1193
  }
1126
1194
 
@@ -1155,6 +1223,7 @@ export async function startAuto(
1155
1223
 
1156
1224
  // Dispatch the first unit
1157
1225
  await autoLoop(ctx, pi, s, buildLoopDeps());
1226
+ cleanupAfterLoopExit(ctx);
1158
1227
  }
1159
1228
 
1160
1229
  // ─── Agent End Handler ────────────────────────────────────────────────────────
@@ -5,19 +5,71 @@ import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMileston
5
5
  import { loadEffectiveGSDPreferences } from "../preferences.js";
6
6
  import { ensureDbOpen } from "./dynamic-tools.js";
7
7
 
8
- export function registerDbTools(pi: ExtensionAPI): void {
8
+ /**
9
+ * Register an alias tool that shares the same execute function as its canonical counterpart.
10
+ * The alias description and promptGuidelines direct the LLM to prefer the canonical name.
11
+ */
12
+ function registerAlias(pi: ExtensionAPI, toolDef: any, aliasName: string, canonicalName: string): void {
9
13
  pi.registerTool({
10
- name: "gsd_save_decision",
14
+ ...toolDef,
15
+ name: aliasName,
16
+ description: toolDef.description + ` (alias for ${canonicalName} — prefer the canonical name)`,
17
+ promptGuidelines: [`Alias for ${canonicalName} — prefer the canonical name.`],
18
+ });
19
+ }
20
+
21
+ export function registerDbTools(pi: ExtensionAPI): void {
22
+ // ─── gsd_decision_save (formerly gsd_save_decision) ─────────────────────
23
+
24
+ const decisionSaveExecute = async (_toolCallId: any, params: any, _signal: any, _onUpdate: any, _ctx: any) => {
25
+ const dbAvailable = await ensureDbOpen();
26
+ if (!dbAvailable) {
27
+ return {
28
+ content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save decision." }],
29
+ details: { operation: "save_decision", error: "db_unavailable" } as any,
30
+ };
31
+ }
32
+ try {
33
+ const { saveDecisionToDb } = await import("../db-writer.js");
34
+ const { id } = await saveDecisionToDb(
35
+ {
36
+ scope: params.scope,
37
+ decision: params.decision,
38
+ choice: params.choice,
39
+ rationale: params.rationale,
40
+ revisable: params.revisable,
41
+ when_context: params.when_context,
42
+ made_by: params.made_by,
43
+ },
44
+ process.cwd(),
45
+ );
46
+ return {
47
+ content: [{ type: "text" as const, text: `Saved decision ${id}` }],
48
+ details: { operation: "save_decision", id } as any,
49
+ };
50
+ } catch (err) {
51
+ const msg = err instanceof Error ? err.message : String(err);
52
+ process.stderr.write(`gsd-db: gsd_decision_save tool failed: ${msg}\n`);
53
+ return {
54
+ content: [{ type: "text" as const, text: `Error saving decision: ${msg}` }],
55
+ details: { operation: "save_decision", error: msg } as any,
56
+ };
57
+ }
58
+ };
59
+
60
+ const decisionSaveTool = {
61
+ name: "gsd_decision_save",
11
62
  label: "Save Decision",
12
63
  description:
13
64
  "Record a project decision to the GSD database and regenerate DECISIONS.md. " +
14
65
  "Decision IDs are auto-assigned — never provide an ID manually.",
15
66
  promptSnippet: "Record a project decision to the GSD database (auto-assigns ID, regenerates DECISIONS.md)",
16
67
  promptGuidelines: [
17
- "Use gsd_save_decision when recording an architectural, pattern, library, or observability decision.",
68
+ "Use gsd_decision_save when recording an architectural, pattern, library, or observability decision.",
18
69
  "Decision IDs are auto-assigned (D001, D002, ...) — never guess or provide an ID.",
19
- "All fields except revisable and when_context are required.",
70
+ "All fields except revisable, when_context, and made_by are required.",
20
71
  "The tool writes to the DB and regenerates .gsd/DECISIONS.md automatically.",
72
+ "Set made_by to 'human' when the user explicitly directed the decision, 'agent' when the LLM chose autonomously (default), or 'collaborative' when it was discussed and agreed together.",
21
73
  ],
22
74
  parameters: Type.Object({
23
75
  scope: Type.String({ description: "Scope of the decision (e.g. 'architecture', 'library', 'observability')" }),
@@ -26,52 +78,69 @@ export function registerDbTools(pi: ExtensionAPI): void {
26
78
  rationale: Type.String({ description: "Why this choice was made" }),
27
79
  revisable: Type.Optional(Type.String({ description: "Whether this can be revisited (default: 'Yes')" })),
28
80
  when_context: Type.Optional(Type.String({ description: "When/context for the decision (e.g. milestone ID)" })),
81
+ made_by: Type.Optional(Type.Union([
82
+ Type.Literal("human"),
83
+ Type.Literal("agent"),
84
+ Type.Literal("collaborative"),
85
+ ], { description: "Who made this decision: 'human' (user directed), 'agent' (LLM decided autonomously), or 'collaborative' (discussed and agreed). Default: 'agent'" })),
29
86
  }),
30
- async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
31
- const dbAvailable = await ensureDbOpen();
32
- if (!dbAvailable) {
33
- return {
34
- content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save decision." }],
35
- details: { operation: "save_decision", error: "db_unavailable" } as any,
36
- };
37
- }
38
- try {
39
- const { saveDecisionToDb } = await import("../db-writer.js");
40
- const { id } = await saveDecisionToDb(
41
- {
42
- scope: params.scope,
43
- decision: params.decision,
44
- choice: params.choice,
45
- rationale: params.rationale,
46
- revisable: params.revisable,
47
- when_context: params.when_context,
48
- },
49
- process.cwd(),
50
- );
51
- return {
52
- content: [{ type: "text" as const, text: `Saved decision ${id}` }],
53
- details: { operation: "save_decision", id } as any,
54
- };
55
- } catch (err) {
56
- const msg = err instanceof Error ? err.message : String(err);
57
- process.stderr.write(`gsd-db: gsd_save_decision tool failed: ${msg}\n`);
87
+ execute: decisionSaveExecute,
88
+ };
89
+
90
+ pi.registerTool(decisionSaveTool);
91
+ registerAlias(pi, decisionSaveTool, "gsd_save_decision", "gsd_decision_save");
92
+
93
+ // ─── gsd_requirement_update (formerly gsd_update_requirement) ───────────
94
+
95
+ const requirementUpdateExecute = async (_toolCallId: any, params: any, _signal: any, _onUpdate: any, _ctx: any) => {
96
+ const dbAvailable = await ensureDbOpen();
97
+ if (!dbAvailable) {
98
+ return {
99
+ content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot update requirement." }],
100
+ details: { operation: "update_requirement", id: params.id, error: "db_unavailable" } as any,
101
+ };
102
+ }
103
+ try {
104
+ const db = await import("../gsd-db.js");
105
+ const existing = db.getRequirementById(params.id);
106
+ if (!existing) {
58
107
  return {
59
- content: [{ type: "text" as const, text: `Error saving decision: ${msg}` }],
60
- details: { operation: "save_decision", error: msg } as any,
108
+ content: [{ type: "text" as const, text: `Error: Requirement ${params.id} not found.` }],
109
+ details: { operation: "update_requirement", id: params.id, error: "not_found" } as any,
61
110
  };
62
111
  }
63
- },
64
- });
112
+ const { updateRequirementInDb } = await import("../db-writer.js");
113
+ const updates: Record<string, string | undefined> = {};
114
+ if (params.status !== undefined) updates.status = params.status;
115
+ if (params.validation !== undefined) updates.validation = params.validation;
116
+ if (params.notes !== undefined) updates.notes = params.notes;
117
+ if (params.description !== undefined) updates.description = params.description;
118
+ if (params.primary_owner !== undefined) updates.primary_owner = params.primary_owner;
119
+ if (params.supporting_slices !== undefined) updates.supporting_slices = params.supporting_slices;
120
+ await updateRequirementInDb(params.id, updates, process.cwd());
121
+ return {
122
+ content: [{ type: "text" as const, text: `Updated requirement ${params.id}` }],
123
+ details: { operation: "update_requirement", id: params.id } as any,
124
+ };
125
+ } catch (err) {
126
+ const msg = err instanceof Error ? err.message : String(err);
127
+ process.stderr.write(`gsd-db: gsd_requirement_update tool failed: ${msg}\n`);
128
+ return {
129
+ content: [{ type: "text" as const, text: `Error updating requirement: ${msg}` }],
130
+ details: { operation: "update_requirement", id: params.id, error: msg } as any,
131
+ };
132
+ }
133
+ };
65
134
 
66
- pi.registerTool({
67
- name: "gsd_update_requirement",
135
+ const requirementUpdateTool = {
136
+ name: "gsd_requirement_update",
68
137
  label: "Update Requirement",
69
138
  description:
70
139
  "Update an existing requirement in the GSD database and regenerate REQUIREMENTS.md. " +
71
140
  "Provide the requirement ID (e.g. R001) and any fields to update.",
72
141
  promptSnippet: "Update an existing GSD requirement by ID (regenerates REQUIREMENTS.md)",
73
142
  promptGuidelines: [
74
- "Use gsd_update_requirement to change status, validation, notes, or other fields on an existing requirement.",
143
+ "Use gsd_requirement_update to change status, validation, notes, or other fields on an existing requirement.",
75
144
  "The id parameter is required — it must be an existing RXXX identifier.",
76
145
  "All other fields are optional — only provided fields are updated.",
77
146
  "The tool verifies the requirement exists before updating.",
@@ -85,56 +154,73 @@ export function registerDbTools(pi: ExtensionAPI): void {
85
154
  primary_owner: Type.Optional(Type.String({ description: "Primary owning slice" })),
86
155
  supporting_slices: Type.Optional(Type.String({ description: "Supporting slices" })),
87
156
  }),
88
- async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
89
- const dbAvailable = await ensureDbOpen();
90
- if (!dbAvailable) {
91
- return {
92
- content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot update requirement." }],
93
- details: { operation: "update_requirement", id: params.id, error: "db_unavailable" } as any,
94
- };
95
- }
96
- try {
97
- const db = await import("../gsd-db.js");
98
- const existing = db.getRequirementById(params.id);
99
- if (!existing) {
100
- return {
101
- content: [{ type: "text" as const, text: `Error: Requirement ${params.id} not found.` }],
102
- details: { operation: "update_requirement", id: params.id, error: "not_found" } as any,
103
- };
104
- }
105
- const { updateRequirementInDb } = await import("../db-writer.js");
106
- const updates: Record<string, string | undefined> = {};
107
- if (params.status !== undefined) updates.status = params.status;
108
- if (params.validation !== undefined) updates.validation = params.validation;
109
- if (params.notes !== undefined) updates.notes = params.notes;
110
- if (params.description !== undefined) updates.description = params.description;
111
- if (params.primary_owner !== undefined) updates.primary_owner = params.primary_owner;
112
- if (params.supporting_slices !== undefined) updates.supporting_slices = params.supporting_slices;
113
- await updateRequirementInDb(params.id, updates, process.cwd());
114
- return {
115
- content: [{ type: "text" as const, text: `Updated requirement ${params.id}` }],
116
- details: { operation: "update_requirement", id: params.id } as any,
117
- };
118
- } catch (err) {
119
- const msg = err instanceof Error ? err.message : String(err);
120
- process.stderr.write(`gsd-db: gsd_update_requirement tool failed: ${msg}\n`);
121
- return {
122
- content: [{ type: "text" as const, text: `Error updating requirement: ${msg}` }],
123
- details: { operation: "update_requirement", id: params.id, error: msg } as any,
124
- };
157
+ execute: requirementUpdateExecute,
158
+ };
159
+
160
+ pi.registerTool(requirementUpdateTool);
161
+ registerAlias(pi, requirementUpdateTool, "gsd_update_requirement", "gsd_requirement_update");
162
+
163
+ // ─── gsd_summary_save (formerly gsd_save_summary) ──────────────────────
164
+
165
+ const summarySaveExecute = async (_toolCallId: any, params: any, _signal: any, _onUpdate: any, _ctx: any) => {
166
+ const dbAvailable = await ensureDbOpen();
167
+ if (!dbAvailable) {
168
+ return {
169
+ content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save artifact." }],
170
+ details: { operation: "save_summary", error: "db_unavailable" } as any,
171
+ };
172
+ }
173
+ const validTypes = ["SUMMARY", "RESEARCH", "CONTEXT", "ASSESSMENT"];
174
+ if (!validTypes.includes(params.artifact_type)) {
175
+ return {
176
+ content: [{ type: "text" as const, text: `Error: Invalid artifact_type "${params.artifact_type}". Must be one of: ${validTypes.join(", ")}` }],
177
+ details: { operation: "save_summary", error: "invalid_artifact_type" } as any,
178
+ };
179
+ }
180
+ try {
181
+ let relativePath: string;
182
+ if (params.task_id && params.slice_id) {
183
+ relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/tasks/${params.task_id}-${params.artifact_type}.md`;
184
+ } else if (params.slice_id) {
185
+ relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/${params.slice_id}-${params.artifact_type}.md`;
186
+ } else {
187
+ relativePath = `milestones/${params.milestone_id}/${params.milestone_id}-${params.artifact_type}.md`;
125
188
  }
126
- },
127
- });
189
+ const { saveArtifactToDb } = await import("../db-writer.js");
190
+ await saveArtifactToDb(
191
+ {
192
+ path: relativePath,
193
+ artifact_type: params.artifact_type,
194
+ content: params.content,
195
+ milestone_id: params.milestone_id,
196
+ slice_id: params.slice_id,
197
+ task_id: params.task_id,
198
+ },
199
+ process.cwd(),
200
+ );
201
+ return {
202
+ content: [{ type: "text" as const, text: `Saved ${params.artifact_type} artifact to ${relativePath}` }],
203
+ details: { operation: "save_summary", path: relativePath, artifact_type: params.artifact_type } as any,
204
+ };
205
+ } catch (err) {
206
+ const msg = err instanceof Error ? err.message : String(err);
207
+ process.stderr.write(`gsd-db: gsd_summary_save tool failed: ${msg}\n`);
208
+ return {
209
+ content: [{ type: "text" as const, text: `Error saving artifact: ${msg}` }],
210
+ details: { operation: "save_summary", error: msg } as any,
211
+ };
212
+ }
213
+ };
128
214
 
129
- pi.registerTool({
130
- name: "gsd_save_summary",
215
+ const summarySaveTool = {
216
+ name: "gsd_summary_save",
131
217
  label: "Save Summary",
132
218
  description:
133
219
  "Save a summary, research, context, or assessment artifact to the GSD database and write it to disk. " +
134
220
  "Computes the file path from milestone/slice/task IDs automatically.",
135
221
  promptSnippet: "Save a GSD artifact (summary/research/context/assessment) to DB and disk",
136
222
  promptGuidelines: [
137
- "Use gsd_save_summary to persist structured artifacts (SUMMARY, RESEARCH, CONTEXT, ASSESSMENT).",
223
+ "Use gsd_summary_save to persist structured artifacts (SUMMARY, RESEARCH, CONTEXT, ASSESSMENT).",
138
224
  "milestone_id is required. slice_id and task_id are optional — they determine the file path.",
139
225
  "The tool computes the relative path automatically: milestones/M001/M001-SUMMARY.md, milestones/M001/slices/S01/S01-SUMMARY.md, etc.",
140
226
  "artifact_type must be one of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT.",
@@ -146,59 +232,46 @@ export function registerDbTools(pi: ExtensionAPI): void {
146
232
  artifact_type: Type.String({ description: "One of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT" }),
147
233
  content: Type.String({ description: "The full markdown content of the artifact" }),
148
234
  }),
149
- async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
150
- const dbAvailable = await ensureDbOpen();
151
- if (!dbAvailable) {
152
- return {
153
- content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save artifact." }],
154
- details: { operation: "save_summary", error: "db_unavailable" } as any,
155
- };
156
- }
157
- const validTypes = ["SUMMARY", "RESEARCH", "CONTEXT", "ASSESSMENT"];
158
- if (!validTypes.includes(params.artifact_type)) {
159
- return {
160
- content: [{ type: "text" as const, text: `Error: Invalid artifact_type "${params.artifact_type}". Must be one of: ${validTypes.join(", ")}` }],
161
- details: { operation: "save_summary", error: "invalid_artifact_type" } as any,
162
- };
163
- }
164
- try {
165
- let relativePath: string;
166
- if (params.task_id && params.slice_id) {
167
- relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/tasks/${params.task_id}-${params.artifact_type}.md`;
168
- } else if (params.slice_id) {
169
- relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/${params.slice_id}-${params.artifact_type}.md`;
170
- } else {
171
- relativePath = `milestones/${params.milestone_id}/${params.milestone_id}-${params.artifact_type}.md`;
172
- }
173
- const { saveArtifactToDb } = await import("../db-writer.js");
174
- await saveArtifactToDb(
175
- {
176
- path: relativePath,
177
- artifact_type: params.artifact_type,
178
- content: params.content,
179
- milestone_id: params.milestone_id,
180
- slice_id: params.slice_id,
181
- task_id: params.task_id,
182
- },
183
- process.cwd(),
184
- );
185
- return {
186
- content: [{ type: "text" as const, text: `Saved ${params.artifact_type} artifact to ${relativePath}` }],
187
- details: { operation: "save_summary", path: relativePath, artifact_type: params.artifact_type } as any,
188
- };
189
- } catch (err) {
190
- const msg = err instanceof Error ? err.message : String(err);
191
- process.stderr.write(`gsd-db: gsd_save_summary tool failed: ${msg}\n`);
235
+ execute: summarySaveExecute,
236
+ };
237
+
238
+ pi.registerTool(summarySaveTool);
239
+ registerAlias(pi, summarySaveTool, "gsd_save_summary", "gsd_summary_save");
240
+
241
+ // ─── gsd_milestone_generate_id (formerly gsd_generate_milestone_id) ────
242
+
243
+ const milestoneGenerateIdExecute = async (_toolCallId: any, _params: any, _signal: any, _onUpdate: any, _ctx: any) => {
244
+ try {
245
+ // Claim a reserved ID if the guided-flow already previewed one to the user.
246
+ // This guarantees the ID shown in the UI matches the one materialised on disk.
247
+ const reserved = claimReservedId();
248
+ if (reserved) {
192
249
  return {
193
- content: [{ type: "text" as const, text: `Error saving artifact: ${msg}` }],
194
- details: { operation: "save_summary", error: msg } as any,
250
+ content: [{ type: "text" as const, text: reserved }],
251
+ details: { operation: "generate_milestone_id", id: reserved, source: "reserved" } as any,
195
252
  };
196
253
  }
197
- },
198
- });
199
254
 
200
- pi.registerTool({
201
- name: "gsd_generate_milestone_id",
255
+ const basePath = process.cwd();
256
+ const existingIds = findMilestoneIds(basePath);
257
+ const uniqueEnabled = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
258
+ const allIds = [...new Set([...existingIds, ...getReservedMilestoneIds()])];
259
+ const newId = nextMilestoneId(allIds, uniqueEnabled);
260
+ return {
261
+ content: [{ type: "text" as const, text: newId }],
262
+ details: { operation: "generate_milestone_id", id: newId, existingCount: existingIds.length, uniqueEnabled } as any,
263
+ };
264
+ } catch (err) {
265
+ const msg = err instanceof Error ? err.message : String(err);
266
+ return {
267
+ content: [{ type: "text" as const, text: `Error generating milestone ID: ${msg}` }],
268
+ details: { operation: "generate_milestone_id", error: msg } as any,
269
+ };
270
+ }
271
+ };
272
+
273
+ const milestoneGenerateIdTool = {
274
+ name: "gsd_milestone_generate_id",
202
275
  label: "Generate Milestone ID",
203
276
  description:
204
277
  "Generate the next milestone ID for a new GSD milestone. " +
@@ -206,41 +279,15 @@ export function registerDbTools(pi: ExtensionAPI): void {
206
279
  "Always use this tool when creating a new milestone — never invent milestone IDs manually.",
207
280
  promptSnippet: "Generate a valid milestone ID (respects unique_milestone_ids preference)",
208
281
  promptGuidelines: [
209
- "ALWAYS call gsd_generate_milestone_id before creating a new milestone directory or writing milestone files.",
282
+ "ALWAYS call gsd_milestone_generate_id before creating a new milestone directory or writing milestone files.",
210
283
  "Never invent or hardcode milestone IDs like M001, M002 — always use this tool.",
211
284
  "Call it once per milestone you need to create. For multi-milestone projects, call it once for each milestone in sequence.",
212
285
  "The tool returns the correct format based on project preferences (e.g. M001 or M001-r5jzab).",
213
286
  ],
214
287
  parameters: Type.Object({}),
215
- async execute(_toolCallId, _params, _signal, _onUpdate, _ctx) {
216
- try {
217
- // Claim a reserved ID if the guided-flow already previewed one to the user.
218
- // This guarantees the ID shown in the UI matches the one materialised on disk.
219
- const reserved = claimReservedId();
220
- if (reserved) {
221
- return {
222
- content: [{ type: "text" as const, text: reserved }],
223
- details: { operation: "generate_milestone_id", id: reserved, source: "reserved" } as any,
224
- };
225
- }
226
-
227
- const basePath = process.cwd();
228
- const existingIds = findMilestoneIds(basePath);
229
- const uniqueEnabled = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
230
- const allIds = [...new Set([...existingIds, ...getReservedMilestoneIds()])];
231
- const newId = nextMilestoneId(allIds, uniqueEnabled);
232
- return {
233
- content: [{ type: "text" as const, text: newId }],
234
- details: { operation: "generate_milestone_id", id: newId, existingCount: existingIds.length, uniqueEnabled } as any,
235
- };
236
- } catch (err) {
237
- const msg = err instanceof Error ? err.message : String(err);
238
- return {
239
- content: [{ type: "text" as const, text: `Error generating milestone ID: ${msg}` }],
240
- details: { operation: "generate_milestone_id", error: msg } as any,
241
- };
242
- }
243
- },
244
- });
245
- }
288
+ execute: milestoneGenerateIdExecute,
289
+ };
246
290
 
291
+ pi.registerTool(milestoneGenerateIdTool);
292
+ registerAlias(pi, milestoneGenerateIdTool, "gsd_generate_milestone_id", "gsd_milestone_generate_id");
293
+ }
@@ -0,0 +1,62 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
3
+
4
+ import { queryJournal } from "../journal.js";
5
+
6
+ export function registerJournalTools(pi: ExtensionAPI): void {
7
+ pi.registerTool({
8
+ name: "gsd_journal_query",
9
+ label: "Query Journal",
10
+ description:
11
+ "Query the structured event journal for auto-mode iterations. " +
12
+ "Returns matching journal entries filtered by flow ID, unit ID, rule name, event type, or time range.",
13
+ promptSnippet: "Query the GSD event journal with filters (flowId, unitId, rule, eventType, time range, limit)",
14
+ promptGuidelines: [
15
+ "Filter by flowId to trace all events from a single auto-mode iteration.",
16
+ "Filter by unitId to reconstruct the causal chain for a specific milestone/slice/task.",
17
+ "Use limit to control context size — default is 100 entries.",
18
+ ],
19
+ parameters: Type.Object({
20
+ flowId: Type.Optional(Type.String({ description: "Filter by flow ID (UUID grouping one iteration)" })),
21
+ unitId: Type.Optional(Type.String({ description: "Filter by unit ID (e.g. M001/S01/T01) from event data" })),
22
+ rule: Type.Optional(Type.String({ description: "Filter by rule name from the unified registry" })),
23
+ eventType: Type.Optional(Type.String({ description: "Filter by event type (e.g. dispatch-match, unit-start)" })),
24
+ after: Type.Optional(Type.String({ description: "ISO-8601 lower bound (inclusive)" })),
25
+ before: Type.Optional(Type.String({ description: "ISO-8601 upper bound (inclusive)" })),
26
+ limit: Type.Optional(Type.Number({ description: "Maximum entries to return (default: 100)", default: 100 })),
27
+ }),
28
+ async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
29
+ try {
30
+ const filters: Record<string, string | undefined> = {};
31
+ if (params.flowId !== undefined) filters.flowId = params.flowId;
32
+ if (params.unitId !== undefined) filters.unitId = params.unitId;
33
+ if (params.rule !== undefined) filters.rule = params.rule;
34
+ if (params.eventType !== undefined) filters.eventType = params.eventType;
35
+ if (params.after !== undefined) filters.after = params.after;
36
+ if (params.before !== undefined) filters.before = params.before;
37
+
38
+ const entries = queryJournal(process.cwd(), filters);
39
+ const limited = entries.slice(0, params.limit ?? 100);
40
+
41
+ if (limited.length === 0) {
42
+ return {
43
+ content: [{ type: "text" as const, text: "No matching journal entries found." }],
44
+ details: { operation: "journal_query", count: 0 } as any,
45
+ };
46
+ }
47
+
48
+ return {
49
+ content: [{ type: "text" as const, text: JSON.stringify(limited, null, 2) }],
50
+ details: { operation: "journal_query", count: limited.length } as any,
51
+ };
52
+ } catch (err) {
53
+ const msg = err instanceof Error ? err.message : String(err);
54
+ process.stderr.write(`gsd-journal: gsd_journal_query tool failed: ${msg}\n`);
55
+ return {
56
+ content: [{ type: "text" as const, text: `Error querying journal: ${msg}` }],
57
+ details: { operation: "journal_query", error: msg } as any,
58
+ };
59
+ }
60
+ },
61
+ });
62
+ }
@@ -5,6 +5,7 @@ import { registerExitCommand } from "../exit-command.js";
5
5
  import { registerWorktreeCommand } from "../worktree-command.js";
6
6
  import { registerDbTools } from "./db-tools.js";
7
7
  import { registerDynamicTools } from "./dynamic-tools.js";
8
+ import { registerJournalTools } from "./journal-tools.js";
8
9
  import { registerHooks } from "./register-hooks.js";
9
10
  import { registerShortcuts } from "./register-shortcuts.js";
10
11
 
@@ -40,6 +41,7 @@ export function registerGsdExtension(pi: ExtensionAPI): void {
40
41
 
41
42
  registerDynamicTools(pi);
42
43
  registerDbTools(pi);
44
+ registerJournalTools(pi);
43
45
  registerShortcuts(pi);
44
46
  registerHooks(pi);
45
47
  }