@opengsd/gsd-pi 1.8.0 → 1.8.1-dev.897b3c90

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 (463) hide show
  1. package/README.md +8 -3
  2. package/dist/cli.js +5 -1
  3. package/dist/headless-events.d.ts +2 -1
  4. package/dist/headless-events.js +11 -3
  5. package/dist/headless-milestone-readiness.d.ts +29 -0
  6. package/dist/headless-milestone-readiness.js +161 -0
  7. package/dist/headless.js +25 -2
  8. package/dist/print-mode-exit.d.ts +12 -0
  9. package/dist/print-mode-exit.js +14 -0
  10. package/dist/resources/.managed-resources-content-hash +1 -1
  11. package/dist/resources/GSD-WORKFLOW.md +16 -47
  12. package/dist/resources/extensions/browser-tools/capture.js +2 -77
  13. package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
  15. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
  16. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  17. package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
  19. package/dist/resources/extensions/gsd/auto-prompts.js +35 -1
  20. package/dist/resources/extensions/gsd/auto.js +5 -1
  21. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +78 -4
  22. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +84 -26
  23. package/dist/resources/extensions/gsd/command-feedback.js +16 -12
  24. package/dist/resources/extensions/gsd/compat/compat-marker.js +19 -2
  25. package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
  26. package/dist/resources/extensions/gsd/db/engine.js +51 -16
  27. package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
  28. package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
  29. package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
  30. package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
  31. package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
  32. package/dist/resources/extensions/gsd/docs/preferences-reference.md +4 -4
  33. package/dist/resources/extensions/gsd/doctor-history.js +65 -0
  34. package/dist/resources/extensions/gsd/doctor-state-checks.js +509 -0
  35. package/dist/resources/extensions/gsd/doctor-workspace-checks.js +91 -0
  36. package/dist/resources/extensions/gsd/doctor.js +14 -653
  37. package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
  38. package/dist/resources/extensions/gsd/gsd-db.js +187 -45
  39. package/dist/resources/extensions/gsd/guided-flow.js +29 -10
  40. package/dist/resources/extensions/gsd/markdown-renderer.js +16 -2
  41. package/dist/resources/extensions/gsd/md-importer.js +109 -16
  42. package/dist/resources/extensions/gsd/migrate/command.js +19 -162
  43. package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
  44. package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
  45. package/dist/resources/extensions/gsd/migrate/planning-writer.js +20 -19
  46. package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
  47. package/dist/resources/extensions/gsd/migration-auto-check.js +4 -0
  48. package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
  49. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
  50. package/dist/resources/extensions/gsd/paths.js +4 -1
  51. package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
  52. package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
  53. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  54. package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
  55. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
  56. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +27 -13
  57. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
  58. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +54 -14
  59. package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +48 -5
  60. package/dist/resources/extensions/gsd/stop-notice.js +15 -1
  61. package/dist/resources/extensions/gsd/sync-lock.js +13 -7
  62. package/dist/resources/extensions/gsd/tools/complete-task.js +82 -1
  63. package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
  64. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
  65. package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
  66. package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
  67. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
  68. package/dist/resources/extensions/gsd/unit-registry.js +4 -0
  69. package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
  70. package/dist/resources/extensions/gsd/worktree-state-projection.js +6 -0
  71. package/dist/resources/extensions/mac-tools/index.js +31 -9
  72. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  73. package/dist/web/standalone/.next/BUILD_ID +1 -1
  74. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  75. package/dist/web/standalone/.next/build-manifest.json +3 -3
  76. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  77. package/dist/web/standalone/.next/required-server-files.json +3 -3
  78. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  79. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  89. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  98. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  105. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  117. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  139. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  149. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  155. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  171. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  175. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/index.html +1 -1
  185. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  186. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  187. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  188. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  190. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  191. package/dist/web/standalone/.next/server/app/page.js +2 -2
  192. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  194. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  195. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  196. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/middleware.js +3 -3
  198. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  199. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  200. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  201. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  202. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  203. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  204. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  205. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  206. package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
  207. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  208. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  209. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  210. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  211. package/dist/web/standalone/package.json +0 -1
  212. package/dist/web/standalone/server.js +1 -1
  213. package/dist/web-mode.js +31 -3
  214. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  215. package/integrations/hermes/pyproject.toml +1 -1
  216. package/package.json +12 -10
  217. package/packages/cloud-mcp-gateway/package.json +2 -2
  218. package/packages/contracts/dist/workflow.d.ts +14 -0
  219. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  220. package/packages/contracts/dist/workflow.js +16 -0
  221. package/packages/contracts/dist/workflow.js.map +1 -1
  222. package/packages/contracts/package.json +1 -1
  223. package/packages/daemon/dist/cloud-config.d.ts +1 -1
  224. package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
  225. package/packages/daemon/dist/cloud-config.js +5 -1
  226. package/packages/daemon/dist/cloud-config.js.map +1 -1
  227. package/packages/daemon/dist/cloud-config.test.js +51 -1
  228. package/packages/daemon/dist/cloud-config.test.js.map +1 -1
  229. package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
  230. package/packages/daemon/dist/local-tool-executor.js +2 -0
  231. package/packages/daemon/dist/local-tool-executor.js.map +1 -1
  232. package/packages/daemon/package.json +6 -6
  233. package/packages/gsd-agent-core/package.json +5 -5
  234. package/packages/gsd-agent-modes/package.json +7 -7
  235. package/packages/gsd-cloud/dist/cli.d.ts +5 -0
  236. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
  237. package/packages/gsd-cloud/dist/cli.js +160 -0
  238. package/packages/gsd-cloud/dist/cli.js.map +1 -0
  239. package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
  240. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
  241. package/packages/gsd-cloud/dist/cloud-config.js +231 -0
  242. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
  243. package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
  244. package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
  245. package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
  246. package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
  247. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
  248. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
  249. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
  250. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
  251. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +35 -0
  252. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
  253. package/packages/gsd-cloud/dist/cloud-runtime.js +258 -0
  254. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
  255. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
  256. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
  257. package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
  258. package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
  259. package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
  260. package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
  261. package/packages/gsd-cloud/dist/cloud-token.js +37 -0
  262. package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
  263. package/packages/gsd-cloud/dist/config.d.ts +17 -0
  264. package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
  265. package/packages/gsd-cloud/dist/config.js +146 -0
  266. package/packages/gsd-cloud/dist/config.js.map +1 -0
  267. package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
  268. package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
  269. package/packages/gsd-cloud/dist/device-flow.js +128 -0
  270. package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
  271. package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
  272. package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
  273. package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
  274. package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
  275. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
  276. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
  277. package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
  278. package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
  279. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
  280. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
  281. package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
  282. package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
  283. package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
  284. package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
  285. package/packages/gsd-cloud/dist/executors/executor.js +11 -0
  286. package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
  287. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
  288. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
  289. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
  290. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
  291. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
  292. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
  293. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
  294. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
  295. package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
  296. package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
  297. package/packages/gsd-cloud/dist/executors/index.js +29 -0
  298. package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
  299. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
  300. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
  301. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
  302. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
  303. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
  304. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
  305. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
  306. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
  307. package/packages/gsd-cloud/dist/index.d.ts +7 -0
  308. package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
  309. package/packages/gsd-cloud/dist/index.js +8 -0
  310. package/packages/gsd-cloud/dist/index.js.map +1 -0
  311. package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
  312. package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
  313. package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
  314. package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
  315. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
  316. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
  317. package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
  318. package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
  319. package/packages/gsd-cloud/dist/logger.d.ts +25 -0
  320. package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
  321. package/packages/gsd-cloud/dist/logger.js +72 -0
  322. package/packages/gsd-cloud/dist/logger.js.map +1 -0
  323. package/packages/gsd-cloud/dist/types.d.ts +51 -0
  324. package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
  325. package/packages/gsd-cloud/dist/types.js +9 -0
  326. package/packages/gsd-cloud/dist/types.js.map +1 -0
  327. package/packages/gsd-cloud/package.json +3 -3
  328. package/packages/mcp-server/README.md +8 -0
  329. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  330. package/packages/mcp-server/dist/workflow-tools.js +64 -2
  331. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  332. package/packages/mcp-server/package.json +4 -4
  333. package/packages/native/package.json +1 -1
  334. package/packages/pi-agent-core/package.json +1 -1
  335. package/packages/pi-ai/dist/models.generated.d.ts +60 -0
  336. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  337. package/packages/pi-ai/dist/models.generated.js +54 -0
  338. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  339. package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
  340. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  341. package/packages/pi-ai/dist/providers/anthropic.js +19 -0
  342. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  343. package/packages/pi-ai/package.json +1 -1
  344. package/packages/pi-coding-agent/package.json +7 -7
  345. package/packages/pi-tui/package.json +2 -2
  346. package/packages/rpc-client/package.json +2 -2
  347. package/pkg/package.json +1 -1
  348. package/src/resources/GSD-WORKFLOW.md +16 -47
  349. package/src/resources/extensions/browser-tools/capture.ts +2 -86
  350. package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
  351. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
  352. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
  353. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
  354. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  355. package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
  356. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
  357. package/src/resources/extensions/gsd/auto-prompts.ts +38 -1
  358. package/src/resources/extensions/gsd/auto.ts +5 -1
  359. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +91 -4
  360. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -24
  361. package/src/resources/extensions/gsd/command-feedback.ts +19 -12
  362. package/src/resources/extensions/gsd/compat/compat-marker.ts +21 -4
  363. package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
  364. package/src/resources/extensions/gsd/db/engine.ts +53 -17
  365. package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
  366. package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
  367. package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
  368. package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
  369. package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
  370. package/src/resources/extensions/gsd/docs/preferences-reference.md +4 -4
  371. package/src/resources/extensions/gsd/doctor-history.ts +81 -0
  372. package/src/resources/extensions/gsd/doctor-state-checks.ts +527 -0
  373. package/src/resources/extensions/gsd/doctor-workspace-checks.ts +97 -0
  374. package/src/resources/extensions/gsd/doctor.ts +14 -673
  375. package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
  376. package/src/resources/extensions/gsd/gsd-db.ts +255 -52
  377. package/src/resources/extensions/gsd/guided-flow.ts +39 -10
  378. package/src/resources/extensions/gsd/markdown-renderer.ts +23 -7
  379. package/src/resources/extensions/gsd/md-importer.ts +116 -13
  380. package/src/resources/extensions/gsd/migrate/command.ts +21 -227
  381. package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
  382. package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
  383. package/src/resources/extensions/gsd/migrate/planning-writer.ts +21 -23
  384. package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
  385. package/src/resources/extensions/gsd/migration-auto-check.ts +3 -0
  386. package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
  387. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
  388. package/src/resources/extensions/gsd/paths.ts +4 -1
  389. package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
  390. package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
  391. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  392. package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
  393. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
  394. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +30 -13
  395. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
  396. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +67 -20
  397. package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +47 -5
  398. package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
  399. package/src/resources/extensions/gsd/stop-notice.ts +18 -1
  400. package/src/resources/extensions/gsd/sync-lock.ts +14 -6
  401. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
  402. package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
  403. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +104 -0
  404. package/src/resources/extensions/gsd/tests/complete-task.test.ts +286 -0
  405. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +76 -1
  406. package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
  407. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
  408. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
  409. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
  410. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
  411. package/src/resources/extensions/gsd/tests/doctor-history-public-api.test.ts +25 -0
  412. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
  413. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
  414. package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
  415. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
  416. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
  417. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
  418. package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
  419. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +53 -0
  420. package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
  421. package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
  422. package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
  423. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +53 -0
  424. package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
  425. package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
  426. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
  427. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -0
  428. package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
  429. package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
  430. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +47 -1
  431. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
  432. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +18 -3
  433. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
  434. package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
  435. package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
  436. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
  437. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +177 -25
  438. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +17 -0
  439. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
  440. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +34 -0
  441. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
  442. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
  443. package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
  444. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
  445. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
  446. package/src/resources/extensions/gsd/tools/complete-task.ts +120 -0
  447. package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
  448. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
  449. package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
  450. package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
  451. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
  452. package/src/resources/extensions/gsd/types.ts +11 -0
  453. package/src/resources/extensions/gsd/unit-registry.ts +4 -0
  454. package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
  455. package/src/resources/extensions/gsd/worktree-state-projection.ts +12 -0
  456. package/src/resources/extensions/mac-tools/index.ts +52 -9
  457. package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
  458. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  459. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  460. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  461. package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
  462. /package/dist/web/standalone/.next/static/{seHIUVbR1mm7LfG83nWJO → TezjdjSHBVRRr54XjAvte}/_buildManifest.js +0 -0
  463. /package/dist/web/standalone/.next/static/{seHIUVbR1mm7LfG83nWJO → TezjdjSHBVRRr54XjAvte}/_ssgManifest.js +0 -0
@@ -5,7 +5,30 @@ import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
  import { test } from "node:test";
7
7
  import { loadConfig } from "./config.js";
8
- import { createGatewayLookup, exchangePairingCode, parseCloudGatewayUrl, redactedCloudStatus, saveCloudConfig } from "./cloud-config.js";
8
+ import { createGatewayLookup, exchangePairingCode, parseCloudGatewayUrl, postJsonToValidatedGateway, redactedCloudStatus, saveCloudConfig } from "./cloud-config.js";
9
+ // Start a loopback server, returning its base URL; skips the test under sandbox EPERM.
10
+ async function listenLoopback(t, handler) {
11
+ const server = createServer(handler);
12
+ try {
13
+ await new Promise((resolve, reject) => {
14
+ server.once("error", reject);
15
+ server.listen(0, "127.0.0.1", resolve);
16
+ });
17
+ }
18
+ catch (err) {
19
+ if (err.code === "EPERM") {
20
+ t.skip("loopback listen is blocked in this sandbox");
21
+ return null;
22
+ }
23
+ throw err;
24
+ }
25
+ const address = server.address();
26
+ assert.ok(address && typeof address === "object");
27
+ return {
28
+ baseUrl: `http://127.0.0.1:${address.port}`,
29
+ close: () => new Promise((resolve, reject) => server.close((err) => err ? reject(err) : resolve())),
30
+ };
31
+ }
9
32
  // Invoke a gateway lookup and capture (err, result) from its Node-style callback.
10
33
  function runGatewayLookup(url, options) {
11
34
  const lookup = createGatewayLookup(new URL(url));
@@ -100,6 +123,33 @@ test("pairing exchange rejects unsafe gateway URLs before making requests", asyn
100
123
  globalThis.fetch = originalFetch;
101
124
  }
102
125
  });
126
+ test("postJsonToValidatedGateway rejects when the gateway never responds", async (t) => {
127
+ // Handler that accepts the request but never sends a response — the hung-server case.
128
+ const server = await listenLoopback(t, () => { });
129
+ if (!server)
130
+ return;
131
+ try {
132
+ await assert.rejects(postJsonToValidatedGateway(new URL(`${server.baseUrl}/x`), {}, 200), /timed out after 200ms/);
133
+ }
134
+ finally {
135
+ await server.close();
136
+ }
137
+ });
138
+ test("postJsonToValidatedGateway resolves a fast healthy response before the timeout", async (t) => {
139
+ const server = await listenLoopback(t, (_req, res) => {
140
+ res.writeHead(200, { "content-type": "application/json" });
141
+ res.end("{}");
142
+ });
143
+ if (!server)
144
+ return;
145
+ try {
146
+ const body = await postJsonToValidatedGateway(new URL(`${server.baseUrl}/x`), {}, 200);
147
+ assert.deepEqual(body, {});
148
+ }
149
+ finally {
150
+ await server.close();
151
+ }
152
+ });
103
153
  test("pairing exchange posts to a validated gateway URL", async (t) => {
104
154
  let requestedUrl = "";
105
155
  let requestBody = "";
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-config.test.js","sourceRoot":"","sources":["../src/cloud-config.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\";\nimport { createServer } from \"node:http\";\nimport { mkdtempSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { test } from \"node:test\";\nimport { loadConfig } from \"./config.js\";\nimport { createGatewayLookup, exchangePairingCode, parseCloudGatewayUrl, redactedCloudStatus, saveCloudConfig } from \"./cloud-config.js\";\n\n// Invoke a gateway lookup and capture (err, result) from its Node-style callback.\nfunction runGatewayLookup(url: string, options: unknown): Promise<{ err: Error | null; result: unknown }> {\n const lookup = createGatewayLookup(new URL(url));\n return new Promise((resolve) => {\n (lookup as unknown as (h: string, o: unknown, cb: (...a: unknown[]) => void) => void)(\n \"localhost\",\n options,\n (...args: unknown[]) => resolve({ err: (args[0] as Error | null) ?? null, result: args[1] }),\n );\n });\n}\n\ntest(\"createGatewayLookup honors all:true with an array callback (regression: scalar form threw 'Invalid IP address' on Node >=20)\", async () => {\n const { err, result } = await runGatewayLookup(\"http://localhost\", { all: true, family: 0 });\n assert.equal(err, null, \"loopback allowed for http URL\");\n assert.ok(Array.isArray(result), \"all:true must call back with an array\");\n assert.ok((result as unknown[]).length > 0, \"expected at least one address\");\n});\n\ntest(\"createGatewayLookup all:true still enforces the SSRF guard on every address\", async () => {\n const { err } = await runGatewayLookup(\"https://localhost\", { all: true, family: 0 });\n assert.ok(err instanceof Error, \"https loopback must be rejected\");\n assert.match(err!.message, /private or loopback/);\n});\n\ntest(\"cloud config stores device token but redacts status output\", () => {\n const dir = mkdtempSync(join(tmpdir(), \"gsd-cloud-config-\"));\n const configPath = join(dir, \"daemon.yaml\");\n\n const config = saveCloudConfig(configPath, {\n gateway_url: \"https://gateway.example\",\n device_token: \"secret-device-token\",\n runtime_id: \"rt1\",\n runtime_name: \"Laptop\",\n enabled: true,\n });\n\n const rawConfig = readFileSync(configPath, \"utf8\");\n assert.doesNotMatch(rawConfig, /secret-device-token/);\n assert.match(rawConfig, /device_token_encrypted:/);\n assert.equal(statSync(configPath).mode & 0o777, 0o600);\n assert.equal(config.cloud?.device_token, \"secret-device-token\");\n assert.deepEqual(redactedCloudStatus(config), {\n configured: true,\n enabled: true,\n gateway_url: \"https://gateway.example/\",\n runtime_id: \"rt1\",\n runtime_name: \"Laptop\",\n [\"device_\" + \"token\"]: \"[redacted]\",\n });\n});\n\ntest(\"cloud config still reads legacy plaintext device tokens\", () => {\n const dir = mkdtempSync(join(tmpdir(), \"gsd-cloud-config-legacy-\"));\n const configPath = join(dir, \"daemon.yaml\");\n const legacyToken = \"legacy-secret-device-token\";\n writeFileSync(configPath, [\n \"cloud:\",\n \" gateway_url: https://gateway.example/\",\n ` device_token: ${legacyToken}`,\n \" runtime_id: rt1\",\n \"\",\n ].join(\"\\n\"));\n assert.equal(loadConfig(configPath).cloud?.device_token, legacyToken);\n\n const config = saveCloudConfig(configPath, {\n gateway_url: \"https://gateway.example\",\n device_token: legacyToken,\n runtime_id: \"rt1\",\n });\n\n const rawConfig = readFileSync(configPath, \"utf8\");\n assert.equal(config.cloud?.device_token, legacyToken);\n assert.doesNotMatch(rawConfig, new RegExp(legacyToken));\n assert.match(rawConfig, /device_token_encrypted:/);\n});\n\ntest(\"cloud gateway URL validation allows HTTPS and localhost HTTP\", () => {\n assert.equal(parseCloudGatewayUrl(\"https://gateway.example/base/\").toString(), \"https://gateway.example/base\");\n assert.equal(parseCloudGatewayUrl(\"http://localhost:8787\").toString(), \"http://localhost:8787/\");\n assert.equal(parseCloudGatewayUrl(\"http://127.0.0.1:8787\").toString(), \"http://127.0.0.1:8787/\");\n});\n\ntest(\"cloud gateway URL validation rejects unsafe destinations\", () => {\n assert.throws(() => parseCloudGatewayUrl(\"file:///tmp/socket\"), /must use http or https/);\n assert.throws(() => parseCloudGatewayUrl(\"http://gateway.example\"), /Plain HTTP/);\n assert.throws(() => parseCloudGatewayUrl(\"https://user:pass@gateway.example\"), /must not include credentials/);\n assert.throws(() => parseCloudGatewayUrl(\"https://gateway.example/#token\"), /must not include a fragment/);\n assert.throws(() => parseCloudGatewayUrl(\"https://127.0.0.1:8787\"), /must not target private/);\n assert.throws(() => parseCloudGatewayUrl(\"https://10.0.0.5\"), /must not target private/);\n assert.throws(() => parseCloudGatewayUrl(\"https://192.168.1.10\"), /must not target private/);\n assert.throws(() => parseCloudGatewayUrl(\"https://[::1]:8787\"), /must not target private/);\n});\n\ntest(\"pairing exchange rejects unsafe gateway URLs before making requests\", async () => {\n const originalFetch = globalThis.fetch;\n let called = false;\n globalThis.fetch = (async () => {\n called = true;\n throw new Error(\"fetch should not be called\");\n }) as typeof fetch;\n try {\n await assert.rejects(\n exchangePairingCode({ gatewayUrl: \"https://127.0.0.1:8787\", code: \"ABCD1234\" }),\n /must not target private/,\n );\n assert.equal(called, false);\n } finally {\n globalThis.fetch = originalFetch;\n }\n});\n\ntest(\"pairing exchange posts to a validated gateway URL\", async (t) => {\n let requestedUrl = \"\";\n let requestBody = \"\";\n const runtimeAuthValue = \"runtime-auth-fixture\";\n const server = createServer((req, res) => {\n requestedUrl = req.url ?? \"\";\n req.setEncoding(\"utf8\");\n req.on(\"data\", (chunk) => {\n requestBody += chunk;\n });\n req.on(\"end\", () => {\n res.writeHead(200, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify({\n runtimeId: \"rt1\",\n [\"device\" + \"Token\"]: runtimeAuthValue,\n }));\n });\n });\n try {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", resolve);\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"EPERM\") {\n t.skip(\"loopback listen is blocked in this sandbox\");\n return;\n }\n throw err;\n }\n try {\n const address = server.address();\n assert.ok(address && typeof address === \"object\");\n const result = await exchangePairingCode({\n gatewayUrl: `http://127.0.0.1:${address.port}/base?ignored=true`,\n code: \"ABCD1234\",\n });\n assert.equal(result.runtimeId, \"rt1\");\n assert.equal(result.deviceToken, runtimeAuthValue);\n assert.equal(requestedUrl, \"/pairing/exchange\");\n assert.deepEqual(JSON.parse(requestBody), { code: \"ABCD1234\" });\n } finally {\n await new Promise<void>((resolve, reject) => server.close((err) => err ? reject(err) : resolve()));\n }\n});\n"]}
1
+ {"version":3,"file":"cloud-config.test.js","sourceRoot":"","sources":["../src/cloud-config.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\";\nimport { createServer, type RequestListener } from \"node:http\";\nimport { mkdtempSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { test } from \"node:test\";\nimport { loadConfig } from \"./config.js\";\nimport { createGatewayLookup, exchangePairingCode, parseCloudGatewayUrl, postJsonToValidatedGateway, redactedCloudStatus, saveCloudConfig } from \"./cloud-config.js\";\n\n// Start a loopback server, returning its base URL; skips the test under sandbox EPERM.\nasync function listenLoopback(\n t: { skip: (msg: string) => void },\n handler: RequestListener,\n): Promise<{ baseUrl: string; close: () => Promise<void> } | null> {\n const server = createServer(handler);\n try {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", resolve);\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"EPERM\") {\n t.skip(\"loopback listen is blocked in this sandbox\");\n return null;\n }\n throw err;\n }\n const address = server.address();\n assert.ok(address && typeof address === \"object\");\n return {\n baseUrl: `http://127.0.0.1:${address.port}`,\n close: () => new Promise<void>((resolve, reject) => server.close((err) => err ? reject(err) : resolve())),\n };\n}\n\n// Invoke a gateway lookup and capture (err, result) from its Node-style callback.\nfunction runGatewayLookup(url: string, options: unknown): Promise<{ err: Error | null; result: unknown }> {\n const lookup = createGatewayLookup(new URL(url));\n return new Promise((resolve) => {\n (lookup as unknown as (h: string, o: unknown, cb: (...a: unknown[]) => void) => void)(\n \"localhost\",\n options,\n (...args: unknown[]) => resolve({ err: (args[0] as Error | null) ?? null, result: args[1] }),\n );\n });\n}\n\ntest(\"createGatewayLookup honors all:true with an array callback (regression: scalar form threw 'Invalid IP address' on Node >=20)\", async () => {\n const { err, result } = await runGatewayLookup(\"http://localhost\", { all: true, family: 0 });\n assert.equal(err, null, \"loopback allowed for http URL\");\n assert.ok(Array.isArray(result), \"all:true must call back with an array\");\n assert.ok((result as unknown[]).length > 0, \"expected at least one address\");\n});\n\ntest(\"createGatewayLookup all:true still enforces the SSRF guard on every address\", async () => {\n const { err } = await runGatewayLookup(\"https://localhost\", { all: true, family: 0 });\n assert.ok(err instanceof Error, \"https loopback must be rejected\");\n assert.match(err!.message, /private or loopback/);\n});\n\ntest(\"cloud config stores device token but redacts status output\", () => {\n const dir = mkdtempSync(join(tmpdir(), \"gsd-cloud-config-\"));\n const configPath = join(dir, \"daemon.yaml\");\n\n const config = saveCloudConfig(configPath, {\n gateway_url: \"https://gateway.example\",\n device_token: \"secret-device-token\",\n runtime_id: \"rt1\",\n runtime_name: \"Laptop\",\n enabled: true,\n });\n\n const rawConfig = readFileSync(configPath, \"utf8\");\n assert.doesNotMatch(rawConfig, /secret-device-token/);\n assert.match(rawConfig, /device_token_encrypted:/);\n assert.equal(statSync(configPath).mode & 0o777, 0o600);\n assert.equal(config.cloud?.device_token, \"secret-device-token\");\n assert.deepEqual(redactedCloudStatus(config), {\n configured: true,\n enabled: true,\n gateway_url: \"https://gateway.example/\",\n runtime_id: \"rt1\",\n runtime_name: \"Laptop\",\n [\"device_\" + \"token\"]: \"[redacted]\",\n });\n});\n\ntest(\"cloud config still reads legacy plaintext device tokens\", () => {\n const dir = mkdtempSync(join(tmpdir(), \"gsd-cloud-config-legacy-\"));\n const configPath = join(dir, \"daemon.yaml\");\n const legacyToken = \"legacy-secret-device-token\";\n writeFileSync(configPath, [\n \"cloud:\",\n \" gateway_url: https://gateway.example/\",\n ` device_token: ${legacyToken}`,\n \" runtime_id: rt1\",\n \"\",\n ].join(\"\\n\"));\n assert.equal(loadConfig(configPath).cloud?.device_token, legacyToken);\n\n const config = saveCloudConfig(configPath, {\n gateway_url: \"https://gateway.example\",\n device_token: legacyToken,\n runtime_id: \"rt1\",\n });\n\n const rawConfig = readFileSync(configPath, \"utf8\");\n assert.equal(config.cloud?.device_token, legacyToken);\n assert.doesNotMatch(rawConfig, new RegExp(legacyToken));\n assert.match(rawConfig, /device_token_encrypted:/);\n});\n\ntest(\"cloud gateway URL validation allows HTTPS and localhost HTTP\", () => {\n assert.equal(parseCloudGatewayUrl(\"https://gateway.example/base/\").toString(), \"https://gateway.example/base\");\n assert.equal(parseCloudGatewayUrl(\"http://localhost:8787\").toString(), \"http://localhost:8787/\");\n assert.equal(parseCloudGatewayUrl(\"http://127.0.0.1:8787\").toString(), \"http://127.0.0.1:8787/\");\n});\n\ntest(\"cloud gateway URL validation rejects unsafe destinations\", () => {\n assert.throws(() => parseCloudGatewayUrl(\"file:///tmp/socket\"), /must use http or https/);\n assert.throws(() => parseCloudGatewayUrl(\"http://gateway.example\"), /Plain HTTP/);\n assert.throws(() => parseCloudGatewayUrl(\"https://user:pass@gateway.example\"), /must not include credentials/);\n assert.throws(() => parseCloudGatewayUrl(\"https://gateway.example/#token\"), /must not include a fragment/);\n assert.throws(() => parseCloudGatewayUrl(\"https://127.0.0.1:8787\"), /must not target private/);\n assert.throws(() => parseCloudGatewayUrl(\"https://10.0.0.5\"), /must not target private/);\n assert.throws(() => parseCloudGatewayUrl(\"https://192.168.1.10\"), /must not target private/);\n assert.throws(() => parseCloudGatewayUrl(\"https://[::1]:8787\"), /must not target private/);\n});\n\ntest(\"pairing exchange rejects unsafe gateway URLs before making requests\", async () => {\n const originalFetch = globalThis.fetch;\n let called = false;\n globalThis.fetch = (async () => {\n called = true;\n throw new Error(\"fetch should not be called\");\n }) as typeof fetch;\n try {\n await assert.rejects(\n exchangePairingCode({ gatewayUrl: \"https://127.0.0.1:8787\", code: \"ABCD1234\" }),\n /must not target private/,\n );\n assert.equal(called, false);\n } finally {\n globalThis.fetch = originalFetch;\n }\n});\n\ntest(\"postJsonToValidatedGateway rejects when the gateway never responds\", async (t) => {\n // Handler that accepts the request but never sends a response — the hung-server case.\n const server = await listenLoopback(t, () => { /* never call res.end */ });\n if (!server) return;\n try {\n await assert.rejects(\n postJsonToValidatedGateway(new URL(`${server.baseUrl}/x`), {}, 200),\n /timed out after 200ms/,\n );\n } finally {\n await server.close();\n }\n});\n\ntest(\"postJsonToValidatedGateway resolves a fast healthy response before the timeout\", async (t) => {\n const server = await listenLoopback(t, (_req, res) => {\n res.writeHead(200, { \"content-type\": \"application/json\" });\n res.end(\"{}\");\n });\n if (!server) return;\n try {\n const body = await postJsonToValidatedGateway(new URL(`${server.baseUrl}/x`), {}, 200);\n assert.deepEqual(body, {});\n } finally {\n await server.close();\n }\n});\n\ntest(\"pairing exchange posts to a validated gateway URL\", async (t) => {\n let requestedUrl = \"\";\n let requestBody = \"\";\n const runtimeAuthValue = \"runtime-auth-fixture\";\n const server = createServer((req, res) => {\n requestedUrl = req.url ?? \"\";\n req.setEncoding(\"utf8\");\n req.on(\"data\", (chunk) => {\n requestBody += chunk;\n });\n req.on(\"end\", () => {\n res.writeHead(200, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify({\n runtimeId: \"rt1\",\n [\"device\" + \"Token\"]: runtimeAuthValue,\n }));\n });\n });\n try {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", resolve);\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"EPERM\") {\n t.skip(\"loopback listen is blocked in this sandbox\");\n return;\n }\n throw err;\n }\n try {\n const address = server.address();\n assert.ok(address && typeof address === \"object\");\n const result = await exchangePairingCode({\n gatewayUrl: `http://127.0.0.1:${address.port}/base?ignored=true`,\n code: \"ABCD1234\",\n });\n assert.equal(result.runtimeId, \"rt1\");\n assert.equal(result.deviceToken, runtimeAuthValue);\n assert.equal(requestedUrl, \"/pairing/exchange\");\n assert.deepEqual(JSON.parse(requestBody), { code: \"ABCD1234\" });\n } finally {\n await new Promise<void>((resolve, reject) => server.close((err) => err ? reject(err) : resolve()));\n }\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"local-tool-executor.d.ts","sourceRoot":"","sources":["../src/local-tool-executor.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAgB9C,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAJ/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;gBAGhD,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;IAUvD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiFpG,kBAAkB,IAAI,OAAO,CAAC,KAAK,CAAC;QACxC,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC,CAAC;YAcW,kBAAkB;YAMlB,kBAAkB;IAOhC,OAAO,CAAC,mBAAmB;IAmD3B,OAAO,CAAC,4BAA4B;YAMtB,YAAY;CAgC3B"}
1
+ {"version":3,"file":"local-tool-executor.d.ts","sourceRoot":"","sources":["../src/local-tool-executor.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAgB9C,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAJ/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;gBAGhD,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;IAUvD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiFpG,kBAAkB,IAAI,OAAO,CAAC,KAAK,CAAC;QACxC,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC,CAAC;YAcW,kBAAkB;YAMlB,kBAAkB;IAOhC,OAAO,CAAC,mBAAmB;IAqD3B,OAAO,CAAC,4BAA4B;YAMtB,YAAY;CAgC3B"}
@@ -151,6 +151,8 @@ export class LocalToolExecutor {
151
151
  case "gsd_task_plan": return this.invokeRegisteredWorkflowTool("gsd_task_plan", args);
152
152
  case "gsd_replan_slice": return this.invokeRegisteredWorkflowTool("gsd_replan_slice", args);
153
153
  case "gsd_slice_replan": return this.invokeRegisteredWorkflowTool("gsd_slice_replan", args);
154
+ case "gsd_replan_task": return this.invokeRegisteredWorkflowTool("gsd_replan_task", args);
155
+ case "gsd_rework_brief_save": return this.invokeRegisteredWorkflowTool("gsd_rework_brief_save", args);
154
156
  case "gsd_slice_complete": return this.invokeRegisteredWorkflowTool("gsd_slice_complete", args);
155
157
  case "gsd_complete_slice": return this.invokeRegisteredWorkflowTool("gsd_complete_slice", args);
156
158
  case "gsd_skip_slice": return this.invokeRegisteredWorkflowTool("gsd_skip_slice", args);
@@ -1 +1 @@
1
- {"version":3,"file":"local-tool-executor.js","sourceRoot":"","sources":["../src/local-tool-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { execFileSync } from \"node:child_process\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { basename, join, resolve } from \"node:path\";\nimport {\n readCaptures,\n readHistory,\n readKnowledge,\n readProgress,\n readRoadmap,\n buildGraph,\n graphDiff,\n graphQuery,\n graphStatus,\n registerWorkflowTools,\n resolveGsdRoot,\n runDoctorLite,\n writeGraph,\n writeSnapshot,\n WORKFLOW_TOOL_NAMES,\n} from \"@opengsd/mcp-server\";\nimport type { SessionManager } from \"./session-manager.js\";\nimport type { ProjectInfo } from \"./types.js\";\n\ntype ToolHandler = (args: Record<string, unknown>) => Promise<unknown>;\nconst WORKFLOW_TOOL_NAME_SET = new Set<string>(WORKFLOW_TOOL_NAMES);\nconst QUERY_FIELDS = {\n all: [\"state\", \"project\", \"requirements\", \"milestones\"],\n state: [\"state\"],\n status: [\"state\"],\n project: [\"project\"],\n requirements: [\"requirements\"],\n milestones: [\"milestones\"],\n} as const;\n\ntype QueryCategory = keyof typeof QUERY_FIELDS;\ntype ProjectStateField = (typeof QUERY_FIELDS)[QueryCategory][number];\n\nexport class LocalToolExecutor {\n private readonly workflowHandlers = new Map<string, ToolHandler>();\n\n constructor(\n private readonly sessionManager: SessionManager,\n private readonly scanProjects: () => Promise<ProjectInfo[]>,\n ) {\n registerWorkflowTools({\n tool: (name: string, _description: string, _params: Record<string, unknown>, handler: ToolHandler) => {\n if (!WORKFLOW_TOOL_NAME_SET.has(name)) return;\n this.workflowHandlers.set(name, handler);\n },\n });\n }\n\n async execute(toolName: string, rawArgs: Record<string, unknown>, projectAlias?: string): Promise<unknown> {\n const args = { ...rawArgs };\n if (projectAlias) {\n args.projectDir = await this.resolveProjectPath(projectAlias);\n }\n\n const workflowResult = this.executeWorkflowTool(toolName, args);\n if (workflowResult) return workflowResult;\n\n switch (toolName) {\n case \"gsd_execute\": {\n const projectDir = await this.requiredProjectDir(args);\n const sessionId = await this.sessionManager.startSession({\n projectDir,\n command: typeof args.command === \"string\" ? args.command : undefined,\n model: typeof args.model === \"string\" ? args.model : undefined,\n bare: typeof args.bare === \"boolean\" ? args.bare : undefined,\n });\n return { content: [{ type: \"text\", text: JSON.stringify({ sessionId, status: \"started\" }, null, 2) }] };\n }\n case \"gsd_status\": {\n const session = this.sessionManager.getSession(String(args.sessionId ?? \"\"));\n if (!session) throw new Error(`Session not found: ${String(args.sessionId ?? \"\")}`);\n const toolCallCount = session.events.filter((event) => {\n const type = (event as Record<string, unknown>).type;\n return type === \"tool_use\" || type === \"tool_execution_start\";\n }).length;\n return { content: [{ type: \"text\", text: JSON.stringify({\n status: session.status,\n progress: {\n eventCount: session.events.length,\n toolCalls: toolCallCount,\n },\n recentEvents: session.events.slice(-10),\n pendingBlocker: session.pendingBlocker\n ? {\n id: session.pendingBlocker.id,\n method: session.pendingBlocker.method,\n message: session.pendingBlocker.message,\n }\n : null,\n cost: session.cost,\n durationMs: Date.now() - session.startTime,\n }, null, 2) }] };\n }\n case \"gsd_result\":\n return { content: [{ type: \"text\", text: JSON.stringify(this.sessionManager.getResult(String(args.sessionId ?? \"\")), null, 2) }] };\n case \"gsd_cancel\":\n if (typeof args.sessionId === \"string\") await this.sessionManager.cancelSession(args.sessionId);\n else await this.sessionManager.cancelSessionByDir(await this.requiredProjectDir(args));\n return { content: [{ type: \"text\", text: JSON.stringify({ cancelled: true }, null, 2) }] };\n case \"gsd_resolve_blocker\": {\n const sessionId = String(args.sessionId ?? \"\");\n const response = String(args.response ?? \"\");\n await this.sessionManager.resolveBlocker(sessionId, response);\n return { content: [{ type: \"text\", text: JSON.stringify({ resolved: true }, null, 2) }] };\n }\n case \"gsd_query\": {\n const projectDir = await this.requiredProjectDir(args);\n const query = typeof args.query === \"string\" ? args.query : undefined;\n return { content: [{ type: \"text\", text: JSON.stringify(await readProjectState(projectDir, query), null, 2) }] };\n }\n case \"gsd_progress\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readProgress(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_roadmap\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readRoadmap(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_history\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readHistory(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_doctor\":\n return { content: [{ type: \"text\", text: JSON.stringify(await runDoctorLite(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_captures\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readCaptures(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_knowledge\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readKnowledge(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_graph\":\n return { content: [{ type: \"text\", text: JSON.stringify(await this.executeGraph(args), null, 2) }] };\n default:\n throw new Error(`Unsupported forwarded GSD MCP tool: ${toolName}`);\n }\n }\n\n async advertisedProjects(): Promise<Array<{\n alias: string;\n path: string;\n repoIdentity: string;\n remoteLabel?: string;\n markers: string[];\n }>> {\n const projects = await this.scanProjects();\n return projects.map((project) => {\n const remoteLabel = gitRemote(project.path);\n return {\n alias: project.name,\n path: project.path,\n repoIdentity: identityFor(project.path, remoteLabel),\n ...(remoteLabel ? { remoteLabel } : {}),\n markers: project.markers,\n };\n });\n }\n\n private async requiredProjectDir(args: Record<string, unknown>): Promise<string> {\n const value = args.projectDir;\n if (typeof value === \"string\" && value.trim()) return this.resolveProjectPath(value);\n throw new Error(\"projectDir or projectAlias is required\");\n }\n\n private async resolveProjectPath(aliasOrPath: string): Promise<string> {\n const projects = await this.scanProjects();\n const match = projects.find((project) => project.name === aliasOrPath || project.path === aliasOrPath);\n if (!match) throw new Error(`Project is not advertised by the Local GSD Runtime: ${aliasOrPath}`);\n return match.path;\n }\n\n private executeWorkflowTool(toolName: string, args: Record<string, unknown>): Promise<unknown> | undefined {\n switch (toolName) {\n case \"gsd_decision_save\": return this.invokeRegisteredWorkflowTool(\"gsd_decision_save\", args);\n case \"gsd_save_decision\": return this.invokeRegisteredWorkflowTool(\"gsd_save_decision\", args);\n case \"gsd_requirement_update\": return this.invokeRegisteredWorkflowTool(\"gsd_requirement_update\", args);\n case \"gsd_update_requirement\": return this.invokeRegisteredWorkflowTool(\"gsd_update_requirement\", args);\n case \"gsd_requirement_save\": return this.invokeRegisteredWorkflowTool(\"gsd_requirement_save\", args);\n case \"gsd_save_requirement\": return this.invokeRegisteredWorkflowTool(\"gsd_save_requirement\", args);\n case \"gsd_milestone_generate_id\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_generate_id\", args);\n case \"gsd_generate_milestone_id\": return this.invokeRegisteredWorkflowTool(\"gsd_generate_milestone_id\", args);\n case \"gsd_plan_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_plan_milestone\", args);\n case \"gsd_plan_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_plan_slice\", args);\n case \"gsd_plan_task\": return this.invokeRegisteredWorkflowTool(\"gsd_plan_task\", args);\n case \"gsd_task_plan\": return this.invokeRegisteredWorkflowTool(\"gsd_task_plan\", args);\n case \"gsd_replan_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_replan_slice\", args);\n case \"gsd_slice_replan\": return this.invokeRegisteredWorkflowTool(\"gsd_slice_replan\", args);\n case \"gsd_slice_complete\": return this.invokeRegisteredWorkflowTool(\"gsd_slice_complete\", args);\n case \"gsd_complete_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_complete_slice\", args);\n case \"gsd_skip_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_skip_slice\", args);\n case \"gsd_complete_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_complete_milestone\", args);\n case \"gsd_milestone_complete\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_complete\", args);\n case \"gsd_validate_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_validate_milestone\", args);\n case \"gsd_milestone_validate\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_validate\", args);\n case \"gsd_reassess_roadmap\": return this.invokeRegisteredWorkflowTool(\"gsd_reassess_roadmap\", args);\n case \"gsd_roadmap_reassess\": return this.invokeRegisteredWorkflowTool(\"gsd_roadmap_reassess\", args);\n case \"gsd_save_gate_result\": return this.invokeRegisteredWorkflowTool(\"gsd_save_gate_result\", args);\n case \"gsd_summary_save\": return this.invokeRegisteredWorkflowTool(\"gsd_summary_save\", args);\n case \"gsd_task_complete\": return this.invokeRegisteredWorkflowTool(\"gsd_task_complete\", args);\n case \"gsd_complete_task\": return this.invokeRegisteredWorkflowTool(\"gsd_complete_task\", args);\n case \"gsd_task_reopen\": return this.invokeRegisteredWorkflowTool(\"gsd_task_reopen\", args);\n case \"gsd_reopen_task\": return this.invokeRegisteredWorkflowTool(\"gsd_reopen_task\", args);\n case \"gsd_slice_reopen\": return this.invokeRegisteredWorkflowTool(\"gsd_slice_reopen\", args);\n case \"gsd_reopen_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_reopen_slice\", args);\n case \"gsd_milestone_reopen\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_reopen\", args);\n case \"gsd_reopen_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_reopen_milestone\", args);\n case \"gsd_milestone_status\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_status\", args);\n case \"gsd_journal_query\": return this.invokeRegisteredWorkflowTool(\"gsd_journal_query\", args);\n case \"gsd_exec\": return this.invokeRegisteredWorkflowTool(\"gsd_exec\", args);\n case \"gsd_exec_search\": return this.invokeRegisteredWorkflowTool(\"gsd_exec_search\", args);\n case \"gsd_resume\": return this.invokeRegisteredWorkflowTool(\"gsd_resume\", args);\n case \"gsd_capture_thought\": return this.invokeRegisteredWorkflowTool(\"gsd_capture_thought\", args);\n case \"gsd_memory_query\": return this.invokeRegisteredWorkflowTool(\"gsd_memory_query\", args);\n case \"gsd_memory_graph\": return this.invokeRegisteredWorkflowTool(\"gsd_memory_graph\", args);\n default:\n if (WORKFLOW_TOOL_NAME_SET.has(toolName)) {\n throw new Error(`Unsupported forwarded GSD MCP tool: ${toolName}`);\n }\n return undefined;\n }\n }\n\n private invokeRegisteredWorkflowTool(toolName: string, args: Record<string, unknown>): Promise<unknown> {\n const workflow = this.workflowHandlers.get(toolName);\n if (!workflow) throw new Error(`Unsupported forwarded GSD MCP tool: ${toolName}`);\n return workflow(args);\n }\n\n private async executeGraph(args: Record<string, unknown>): Promise<unknown> {\n const projectDir = await this.requiredProjectDir(args);\n const mode = args.mode;\n switch (mode) {\n case \"build\": {\n const gsdRoot = resolveGsdRoot(projectDir);\n if (args.snapshot === true) {\n await writeSnapshot(gsdRoot).catch(() => { /* best-effort */ });\n }\n const graph = await buildGraph(projectDir);\n await writeGraph(gsdRoot, graph);\n return {\n built: true,\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n builtAt: graph.builtAt,\n };\n }\n case \"query\":\n return graphQuery(\n projectDir,\n typeof args.term === \"string\" ? args.term : \"\",\n typeof args.budget === \"number\" ? args.budget : undefined,\n );\n case \"status\":\n return graphStatus(projectDir);\n case \"diff\":\n return graphDiff(projectDir);\n default:\n throw new Error(\"gsd_graph mode must be one of: build, query, status, diff\");\n }\n }\n}\n\nasync function readProjectState(projectDir: string, query: string | undefined): Promise<Record<string, unknown>> {\n const resolvedProjectDir = resolve(projectDir);\n const gsdDir = join(resolvedProjectDir, \".gsd\");\n const category = normalizeQuery(query);\n const wanted = new Set<ProjectStateField>(QUERY_FIELDS[category]);\n\n const result: Record<string, unknown> = {\n projectDir: resolvedProjectDir,\n query: category,\n };\n\n if (wanted.has(\"state\")) {\n result.state = await readTextOrNull(join(gsdDir, \"STATE.md\"));\n }\n if (wanted.has(\"project\")) {\n result.project = await readTextOrNull(join(gsdDir, \"PROJECT.md\"));\n }\n if (wanted.has(\"requirements\")) {\n result.requirements = await readTextOrNull(join(gsdDir, \"REQUIREMENTS.md\"));\n }\n if (wanted.has(\"milestones\")) {\n result.milestones = await readMilestones(gsdDir);\n }\n\n return result;\n}\n\nfunction normalizeQuery(query: string | undefined): QueryCategory {\n const key = (query ?? \"all\").trim().toLowerCase();\n return Object.hasOwn(QUERY_FIELDS, key) ? key as QueryCategory : \"all\";\n}\n\nasync function readTextOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function readMilestones(gsdDir: string): Promise<Array<{ id: string; hasRoadmap: boolean; hasSummary: boolean }>> {\n try {\n const entries = await readdir(join(gsdDir, \"milestones\"), { withFileTypes: true });\n const milestones: Array<{ id: string; hasRoadmap: boolean; hasSummary: boolean }> = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n milestones.push({\n id: entry.name,\n hasRoadmap: await milestoneFileExists(gsdDir, entry.name, \"ROADMAP\"),\n hasSummary: await milestoneFileExists(gsdDir, entry.name, \"SUMMARY\"),\n });\n }\n return milestones;\n } catch {\n return [];\n }\n}\n\nasync function milestoneFileExists(gsdDir: string, milestoneId: string, suffix: string): Promise<boolean> {\n const milestoneDir = join(gsdDir, \"milestones\", milestoneId);\n return fileExists(join(milestoneDir, `${milestoneId}-${suffix}.md`))\n || fileExists(join(milestoneDir, `${basename(milestoneDir)}-${suffix}.md`))\n || fileExists(join(milestoneDir, `${suffix}.md`));\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction gitRemote(projectPath: string): string | undefined {\n try {\n return execFileSync(\"git\", [\"remote\", \"get-url\", \"origin\"], {\n cwd: projectPath,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim() || undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction identityFor(projectPath: string, remote?: string): string {\n return createHash(\"sha256\").update(remote || `${basename(projectPath)}:${projectPath}`).digest(\"hex\").slice(0, 12);\n}\n"]}
1
+ {"version":3,"file":"local-tool-executor.js","sourceRoot":"","sources":["../src/local-tool-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { execFileSync } from \"node:child_process\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { basename, join, resolve } from \"node:path\";\nimport {\n readCaptures,\n readHistory,\n readKnowledge,\n readProgress,\n readRoadmap,\n buildGraph,\n graphDiff,\n graphQuery,\n graphStatus,\n registerWorkflowTools,\n resolveGsdRoot,\n runDoctorLite,\n writeGraph,\n writeSnapshot,\n WORKFLOW_TOOL_NAMES,\n} from \"@opengsd/mcp-server\";\nimport type { SessionManager } from \"./session-manager.js\";\nimport type { ProjectInfo } from \"./types.js\";\n\ntype ToolHandler = (args: Record<string, unknown>) => Promise<unknown>;\nconst WORKFLOW_TOOL_NAME_SET = new Set<string>(WORKFLOW_TOOL_NAMES);\nconst QUERY_FIELDS = {\n all: [\"state\", \"project\", \"requirements\", \"milestones\"],\n state: [\"state\"],\n status: [\"state\"],\n project: [\"project\"],\n requirements: [\"requirements\"],\n milestones: [\"milestones\"],\n} as const;\n\ntype QueryCategory = keyof typeof QUERY_FIELDS;\ntype ProjectStateField = (typeof QUERY_FIELDS)[QueryCategory][number];\n\nexport class LocalToolExecutor {\n private readonly workflowHandlers = new Map<string, ToolHandler>();\n\n constructor(\n private readonly sessionManager: SessionManager,\n private readonly scanProjects: () => Promise<ProjectInfo[]>,\n ) {\n registerWorkflowTools({\n tool: (name: string, _description: string, _params: Record<string, unknown>, handler: ToolHandler) => {\n if (!WORKFLOW_TOOL_NAME_SET.has(name)) return;\n this.workflowHandlers.set(name, handler);\n },\n });\n }\n\n async execute(toolName: string, rawArgs: Record<string, unknown>, projectAlias?: string): Promise<unknown> {\n const args = { ...rawArgs };\n if (projectAlias) {\n args.projectDir = await this.resolveProjectPath(projectAlias);\n }\n\n const workflowResult = this.executeWorkflowTool(toolName, args);\n if (workflowResult) return workflowResult;\n\n switch (toolName) {\n case \"gsd_execute\": {\n const projectDir = await this.requiredProjectDir(args);\n const sessionId = await this.sessionManager.startSession({\n projectDir,\n command: typeof args.command === \"string\" ? args.command : undefined,\n model: typeof args.model === \"string\" ? args.model : undefined,\n bare: typeof args.bare === \"boolean\" ? args.bare : undefined,\n });\n return { content: [{ type: \"text\", text: JSON.stringify({ sessionId, status: \"started\" }, null, 2) }] };\n }\n case \"gsd_status\": {\n const session = this.sessionManager.getSession(String(args.sessionId ?? \"\"));\n if (!session) throw new Error(`Session not found: ${String(args.sessionId ?? \"\")}`);\n const toolCallCount = session.events.filter((event) => {\n const type = (event as Record<string, unknown>).type;\n return type === \"tool_use\" || type === \"tool_execution_start\";\n }).length;\n return { content: [{ type: \"text\", text: JSON.stringify({\n status: session.status,\n progress: {\n eventCount: session.events.length,\n toolCalls: toolCallCount,\n },\n recentEvents: session.events.slice(-10),\n pendingBlocker: session.pendingBlocker\n ? {\n id: session.pendingBlocker.id,\n method: session.pendingBlocker.method,\n message: session.pendingBlocker.message,\n }\n : null,\n cost: session.cost,\n durationMs: Date.now() - session.startTime,\n }, null, 2) }] };\n }\n case \"gsd_result\":\n return { content: [{ type: \"text\", text: JSON.stringify(this.sessionManager.getResult(String(args.sessionId ?? \"\")), null, 2) }] };\n case \"gsd_cancel\":\n if (typeof args.sessionId === \"string\") await this.sessionManager.cancelSession(args.sessionId);\n else await this.sessionManager.cancelSessionByDir(await this.requiredProjectDir(args));\n return { content: [{ type: \"text\", text: JSON.stringify({ cancelled: true }, null, 2) }] };\n case \"gsd_resolve_blocker\": {\n const sessionId = String(args.sessionId ?? \"\");\n const response = String(args.response ?? \"\");\n await this.sessionManager.resolveBlocker(sessionId, response);\n return { content: [{ type: \"text\", text: JSON.stringify({ resolved: true }, null, 2) }] };\n }\n case \"gsd_query\": {\n const projectDir = await this.requiredProjectDir(args);\n const query = typeof args.query === \"string\" ? args.query : undefined;\n return { content: [{ type: \"text\", text: JSON.stringify(await readProjectState(projectDir, query), null, 2) }] };\n }\n case \"gsd_progress\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readProgress(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_roadmap\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readRoadmap(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_history\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readHistory(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_doctor\":\n return { content: [{ type: \"text\", text: JSON.stringify(await runDoctorLite(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_captures\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readCaptures(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_knowledge\":\n return { content: [{ type: \"text\", text: JSON.stringify(await readKnowledge(await this.requiredProjectDir(args)), null, 2) }] };\n case \"gsd_graph\":\n return { content: [{ type: \"text\", text: JSON.stringify(await this.executeGraph(args), null, 2) }] };\n default:\n throw new Error(`Unsupported forwarded GSD MCP tool: ${toolName}`);\n }\n }\n\n async advertisedProjects(): Promise<Array<{\n alias: string;\n path: string;\n repoIdentity: string;\n remoteLabel?: string;\n markers: string[];\n }>> {\n const projects = await this.scanProjects();\n return projects.map((project) => {\n const remoteLabel = gitRemote(project.path);\n return {\n alias: project.name,\n path: project.path,\n repoIdentity: identityFor(project.path, remoteLabel),\n ...(remoteLabel ? { remoteLabel } : {}),\n markers: project.markers,\n };\n });\n }\n\n private async requiredProjectDir(args: Record<string, unknown>): Promise<string> {\n const value = args.projectDir;\n if (typeof value === \"string\" && value.trim()) return this.resolveProjectPath(value);\n throw new Error(\"projectDir or projectAlias is required\");\n }\n\n private async resolveProjectPath(aliasOrPath: string): Promise<string> {\n const projects = await this.scanProjects();\n const match = projects.find((project) => project.name === aliasOrPath || project.path === aliasOrPath);\n if (!match) throw new Error(`Project is not advertised by the Local GSD Runtime: ${aliasOrPath}`);\n return match.path;\n }\n\n private executeWorkflowTool(toolName: string, args: Record<string, unknown>): Promise<unknown> | undefined {\n switch (toolName) {\n case \"gsd_decision_save\": return this.invokeRegisteredWorkflowTool(\"gsd_decision_save\", args);\n case \"gsd_save_decision\": return this.invokeRegisteredWorkflowTool(\"gsd_save_decision\", args);\n case \"gsd_requirement_update\": return this.invokeRegisteredWorkflowTool(\"gsd_requirement_update\", args);\n case \"gsd_update_requirement\": return this.invokeRegisteredWorkflowTool(\"gsd_update_requirement\", args);\n case \"gsd_requirement_save\": return this.invokeRegisteredWorkflowTool(\"gsd_requirement_save\", args);\n case \"gsd_save_requirement\": return this.invokeRegisteredWorkflowTool(\"gsd_save_requirement\", args);\n case \"gsd_milestone_generate_id\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_generate_id\", args);\n case \"gsd_generate_milestone_id\": return this.invokeRegisteredWorkflowTool(\"gsd_generate_milestone_id\", args);\n case \"gsd_plan_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_plan_milestone\", args);\n case \"gsd_plan_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_plan_slice\", args);\n case \"gsd_plan_task\": return this.invokeRegisteredWorkflowTool(\"gsd_plan_task\", args);\n case \"gsd_task_plan\": return this.invokeRegisteredWorkflowTool(\"gsd_task_plan\", args);\n case \"gsd_replan_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_replan_slice\", args);\n case \"gsd_slice_replan\": return this.invokeRegisteredWorkflowTool(\"gsd_slice_replan\", args);\n case \"gsd_replan_task\": return this.invokeRegisteredWorkflowTool(\"gsd_replan_task\", args);\n case \"gsd_rework_brief_save\": return this.invokeRegisteredWorkflowTool(\"gsd_rework_brief_save\", args);\n case \"gsd_slice_complete\": return this.invokeRegisteredWorkflowTool(\"gsd_slice_complete\", args);\n case \"gsd_complete_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_complete_slice\", args);\n case \"gsd_skip_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_skip_slice\", args);\n case \"gsd_complete_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_complete_milestone\", args);\n case \"gsd_milestone_complete\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_complete\", args);\n case \"gsd_validate_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_validate_milestone\", args);\n case \"gsd_milestone_validate\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_validate\", args);\n case \"gsd_reassess_roadmap\": return this.invokeRegisteredWorkflowTool(\"gsd_reassess_roadmap\", args);\n case \"gsd_roadmap_reassess\": return this.invokeRegisteredWorkflowTool(\"gsd_roadmap_reassess\", args);\n case \"gsd_save_gate_result\": return this.invokeRegisteredWorkflowTool(\"gsd_save_gate_result\", args);\n case \"gsd_summary_save\": return this.invokeRegisteredWorkflowTool(\"gsd_summary_save\", args);\n case \"gsd_task_complete\": return this.invokeRegisteredWorkflowTool(\"gsd_task_complete\", args);\n case \"gsd_complete_task\": return this.invokeRegisteredWorkflowTool(\"gsd_complete_task\", args);\n case \"gsd_task_reopen\": return this.invokeRegisteredWorkflowTool(\"gsd_task_reopen\", args);\n case \"gsd_reopen_task\": return this.invokeRegisteredWorkflowTool(\"gsd_reopen_task\", args);\n case \"gsd_slice_reopen\": return this.invokeRegisteredWorkflowTool(\"gsd_slice_reopen\", args);\n case \"gsd_reopen_slice\": return this.invokeRegisteredWorkflowTool(\"gsd_reopen_slice\", args);\n case \"gsd_milestone_reopen\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_reopen\", args);\n case \"gsd_reopen_milestone\": return this.invokeRegisteredWorkflowTool(\"gsd_reopen_milestone\", args);\n case \"gsd_milestone_status\": return this.invokeRegisteredWorkflowTool(\"gsd_milestone_status\", args);\n case \"gsd_journal_query\": return this.invokeRegisteredWorkflowTool(\"gsd_journal_query\", args);\n case \"gsd_exec\": return this.invokeRegisteredWorkflowTool(\"gsd_exec\", args);\n case \"gsd_exec_search\": return this.invokeRegisteredWorkflowTool(\"gsd_exec_search\", args);\n case \"gsd_resume\": return this.invokeRegisteredWorkflowTool(\"gsd_resume\", args);\n case \"gsd_capture_thought\": return this.invokeRegisteredWorkflowTool(\"gsd_capture_thought\", args);\n case \"gsd_memory_query\": return this.invokeRegisteredWorkflowTool(\"gsd_memory_query\", args);\n case \"gsd_memory_graph\": return this.invokeRegisteredWorkflowTool(\"gsd_memory_graph\", args);\n default:\n if (WORKFLOW_TOOL_NAME_SET.has(toolName)) {\n throw new Error(`Unsupported forwarded GSD MCP tool: ${toolName}`);\n }\n return undefined;\n }\n }\n\n private invokeRegisteredWorkflowTool(toolName: string, args: Record<string, unknown>): Promise<unknown> {\n const workflow = this.workflowHandlers.get(toolName);\n if (!workflow) throw new Error(`Unsupported forwarded GSD MCP tool: ${toolName}`);\n return workflow(args);\n }\n\n private async executeGraph(args: Record<string, unknown>): Promise<unknown> {\n const projectDir = await this.requiredProjectDir(args);\n const mode = args.mode;\n switch (mode) {\n case \"build\": {\n const gsdRoot = resolveGsdRoot(projectDir);\n if (args.snapshot === true) {\n await writeSnapshot(gsdRoot).catch(() => { /* best-effort */ });\n }\n const graph = await buildGraph(projectDir);\n await writeGraph(gsdRoot, graph);\n return {\n built: true,\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n builtAt: graph.builtAt,\n };\n }\n case \"query\":\n return graphQuery(\n projectDir,\n typeof args.term === \"string\" ? args.term : \"\",\n typeof args.budget === \"number\" ? args.budget : undefined,\n );\n case \"status\":\n return graphStatus(projectDir);\n case \"diff\":\n return graphDiff(projectDir);\n default:\n throw new Error(\"gsd_graph mode must be one of: build, query, status, diff\");\n }\n }\n}\n\nasync function readProjectState(projectDir: string, query: string | undefined): Promise<Record<string, unknown>> {\n const resolvedProjectDir = resolve(projectDir);\n const gsdDir = join(resolvedProjectDir, \".gsd\");\n const category = normalizeQuery(query);\n const wanted = new Set<ProjectStateField>(QUERY_FIELDS[category]);\n\n const result: Record<string, unknown> = {\n projectDir: resolvedProjectDir,\n query: category,\n };\n\n if (wanted.has(\"state\")) {\n result.state = await readTextOrNull(join(gsdDir, \"STATE.md\"));\n }\n if (wanted.has(\"project\")) {\n result.project = await readTextOrNull(join(gsdDir, \"PROJECT.md\"));\n }\n if (wanted.has(\"requirements\")) {\n result.requirements = await readTextOrNull(join(gsdDir, \"REQUIREMENTS.md\"));\n }\n if (wanted.has(\"milestones\")) {\n result.milestones = await readMilestones(gsdDir);\n }\n\n return result;\n}\n\nfunction normalizeQuery(query: string | undefined): QueryCategory {\n const key = (query ?? \"all\").trim().toLowerCase();\n return Object.hasOwn(QUERY_FIELDS, key) ? key as QueryCategory : \"all\";\n}\n\nasync function readTextOrNull(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function readMilestones(gsdDir: string): Promise<Array<{ id: string; hasRoadmap: boolean; hasSummary: boolean }>> {\n try {\n const entries = await readdir(join(gsdDir, \"milestones\"), { withFileTypes: true });\n const milestones: Array<{ id: string; hasRoadmap: boolean; hasSummary: boolean }> = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n milestones.push({\n id: entry.name,\n hasRoadmap: await milestoneFileExists(gsdDir, entry.name, \"ROADMAP\"),\n hasSummary: await milestoneFileExists(gsdDir, entry.name, \"SUMMARY\"),\n });\n }\n return milestones;\n } catch {\n return [];\n }\n}\n\nasync function milestoneFileExists(gsdDir: string, milestoneId: string, suffix: string): Promise<boolean> {\n const milestoneDir = join(gsdDir, \"milestones\", milestoneId);\n return fileExists(join(milestoneDir, `${milestoneId}-${suffix}.md`))\n || fileExists(join(milestoneDir, `${basename(milestoneDir)}-${suffix}.md`))\n || fileExists(join(milestoneDir, `${suffix}.md`));\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction gitRemote(projectPath: string): string | undefined {\n try {\n return execFileSync(\"git\", [\"remote\", \"get-url\", \"origin\"], {\n cwd: projectPath,\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim() || undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction identityFor(projectPath: string, remote?: string): string {\n return createHash(\"sha256\").update(remote || `${basename(projectPath)}:${projectPath}`).digest(\"hex\").slice(0, 12);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengsd/daemon",
3
- "version": "1.8.0",
3
+ "version": "1.8.1-dev.897b3c90",
4
4
  "description": "GSD daemon — background process for project monitoring and Discord integration",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,13 +27,13 @@
27
27
  },
28
28
  "scripts": {
29
29
  "build": "node ../../scripts/clean-package-dist.cjs && tsc",
30
- "test": "node --test dist/daemon.test.js dist/cloud-config.test.js dist/cloud-runtime.test.js dist/device-flow.test.js dist/local-tool-executor.test.js dist/mcp-cli.test.js dist/message-batcher.test.js"
30
+ "test": "pnpm run build && node --test dist/daemon.test.js dist/cloud-config.test.js dist/cloud-runtime.test.js dist/device-flow.test.js dist/local-tool-executor.test.js dist/mcp-cli.test.js dist/message-batcher.test.js"
31
31
  },
32
32
  "dependencies": {
33
- "@anthropic-ai/sdk": "^0.52.0",
34
- "@opengsd/contracts": "^1.8.0",
35
- "@opengsd/mcp-server": "^1.8.0",
36
- "@opengsd/rpc-client": "^1.8.0",
33
+ "@anthropic-ai/sdk": "^0.91.1",
34
+ "@opengsd/contracts": "^1.8.1-dev.897b3c90",
35
+ "@opengsd/mcp-server": "^1.8.1-dev.897b3c90",
36
+ "@opengsd/rpc-client": "^1.8.1-dev.897b3c90",
37
37
  "discord.js": "^14.25.1",
38
38
  "ws": "^8.20.0",
39
39
  "yaml": "^2.8.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gsd/agent-core",
3
- "version": "1.8.0",
3
+ "version": "1.8.1-dev.897b3c90",
4
4
  "description": "GSD session orchestration layer on top of @gsd/pi-coding-agent",
5
5
  "type": "module",
6
6
  "gsd": {
@@ -25,9 +25,9 @@
25
25
  "test": "node --import ../../src/resources/extensions/gsd/tests/resolve-ts.mjs --experimental-strip-types --test src/*.test.ts src/**/*.test.ts"
26
26
  },
27
27
  "dependencies": {
28
- "@gsd/native": "^1.8.0",
29
- "@gsd/pi-agent-core": "^1.8.0",
30
- "@gsd/pi-ai": "^1.8.0",
31
- "@gsd/pi-coding-agent": "^1.8.0"
28
+ "@gsd/native": "^1.8.1-dev.897b3c90",
29
+ "@gsd/pi-agent-core": "^1.8.1-dev.897b3c90",
30
+ "@gsd/pi-ai": "^1.8.1-dev.897b3c90",
31
+ "@gsd/pi-coding-agent": "^1.8.1-dev.897b3c90"
32
32
  }
33
33
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gsd/agent-modes",
3
- "version": "1.8.0",
3
+ "version": "1.8.1-dev.897b3c90",
4
4
  "description": "GSD run modes and CLI layer",
5
5
  "type": "module",
6
6
  "gsd": {
@@ -25,12 +25,12 @@
25
25
  "test": "node --import ../../src/resources/extensions/gsd/tests/resolve-ts.mjs --experimental-strip-types --test src/**/*.test.ts"
26
26
  },
27
27
  "dependencies": {
28
- "@gsd/agent-core": "^1.8.0",
29
- "@gsd/pi-agent-core": "^1.8.0",
30
- "@gsd/pi-ai": "^1.8.0",
31
- "@gsd/pi-coding-agent": "^1.8.0",
32
- "@gsd/pi-tui": "^1.8.0",
33
- "@opengsd/contracts": "^1.8.0",
28
+ "@gsd/agent-core": "^1.8.1-dev.897b3c90",
29
+ "@gsd/pi-agent-core": "^1.8.1-dev.897b3c90",
30
+ "@gsd/pi-ai": "^1.8.1-dev.897b3c90",
31
+ "@gsd/pi-coding-agent": "^1.8.1-dev.897b3c90",
32
+ "@gsd/pi-tui": "^1.8.1-dev.897b3c90",
33
+ "@opengsd/contracts": "^1.8.1-dev.897b3c90",
34
34
  "chalk": "^5.5.0"
35
35
  }
36
36
  }
@@ -0,0 +1,5 @@
1
+ export declare function handleCloudCommand(argv: string[], opts: {
2
+ binaryName: string;
3
+ }): Promise<void>;
4
+ export declare function formatUsage(binaryName: string): string;
5
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAqBA,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAC7D,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4FhB;AAkCD,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA8BtD"}
@@ -0,0 +1,160 @@
1
+ // Project/App: Open GSD
2
+ // File Purpose: Standalone gsd-cloud CLI — login / status / connect / disconnect.
3
+ //
4
+ // Wires device-flow + CloudRuntime + a selected Executor adapter DIRECTLY. It has
5
+ // no dependency on any Daemon or Orchestrator class; the only cloud behaviour is
6
+ // the WS relay client driving the local GSD runtime through the Executor seam.
7
+ import { parseArgs } from "node:util";
8
+ import { resolveConfigPath, loadConfig } from "./config.js";
9
+ import { Logger } from "./logger.js";
10
+ import { clearCloudConfig, exchangePairingCode, redactedCloudStatus, saveCloudConfig, } from "./cloud-config.js";
11
+ import { runDeviceFlow } from "./device-flow.js";
12
+ import { CloudRuntime } from "./cloud-runtime.js";
13
+ import { selectExecutor } from "./executors/index.js";
14
+ export async function handleCloudCommand(argv, opts) {
15
+ if (argv[0] === "--help" || argv[0] === "-h") {
16
+ process.stdout.write(formatUsage(opts.binaryName));
17
+ process.exit(0);
18
+ }
19
+ const command = argv[0];
20
+ const { values } = parseArgs({
21
+ args: argv.slice(1),
22
+ options: {
23
+ config: { type: "string", short: "c" },
24
+ gateway: { type: "string" },
25
+ code: { type: "string" },
26
+ "runtime-name": { type: "string" },
27
+ verbose: { type: "boolean", short: "v", default: false },
28
+ help: { type: "boolean", short: "h", default: false },
29
+ },
30
+ strict: true,
31
+ });
32
+ if (values.help || !command) {
33
+ process.stdout.write(formatUsage(opts.binaryName));
34
+ process.exit(0);
35
+ }
36
+ const configPath = resolveConfigPath(values.config);
37
+ if (command === "status") {
38
+ process.stdout.write(`${JSON.stringify(redactedCloudStatus(loadConfig(configPath)), null, 2)}\n`);
39
+ return;
40
+ }
41
+ if (command === "disconnect") {
42
+ clearCloudConfig(configPath);
43
+ process.stdout.write(`${opts.binaryName}: cloud runtime disconnected locally.\n`);
44
+ return;
45
+ }
46
+ if (command === "login") {
47
+ if (!values.gateway) {
48
+ throw new Error("login requires --gateway");
49
+ }
50
+ const runtimeName = values["runtime-name"];
51
+ const { deviceToken, runtimeId, gatewayUrl } = await runDeviceFlow({
52
+ gatewayUrl: values.gateway,
53
+ configPath,
54
+ runtimeName,
55
+ binaryName: opts.binaryName,
56
+ });
57
+ const config = saveCloudConfig(configPath, {
58
+ gateway_url: gatewayUrl,
59
+ device_token: deviceToken,
60
+ runtime_id: runtimeId,
61
+ ...(runtimeName ? { runtime_name: runtimeName } : {}),
62
+ enabled: true,
63
+ });
64
+ process.stdout.write(`${opts.binaryName}: cloud runtime ${runtimeId} paired — connecting...\n`);
65
+ await runCloudRuntime(config, opts.binaryName, values.verbose);
66
+ return;
67
+ }
68
+ if (command === "pair") {
69
+ if (!values.gateway || !values.code) {
70
+ throw new Error("pair requires --gateway and --code");
71
+ }
72
+ const runtimeName = values["runtime-name"];
73
+ const result = await exchangePairingCode({
74
+ gatewayUrl: values.gateway,
75
+ code: values.code,
76
+ runtimeName,
77
+ });
78
+ saveCloudConfig(configPath, {
79
+ gateway_url: values.gateway,
80
+ device_token: result.deviceToken,
81
+ runtime_id: result.runtimeId,
82
+ ...(runtimeName ? { runtime_name: runtimeName } : {}),
83
+ enabled: true,
84
+ });
85
+ process.stdout.write(`${opts.binaryName}: paired cloud runtime ${result.runtimeId}.\n`);
86
+ return;
87
+ }
88
+ if (command === "connect") {
89
+ const config = loadConfig(configPath);
90
+ if (!config.cloud?.device_token || !config.cloud.runtime_id) {
91
+ throw new Error("cloud runtime is not paired; run `login` first");
92
+ }
93
+ await runCloudRuntime(config, opts.binaryName, values.verbose);
94
+ return;
95
+ }
96
+ throw new Error(`Unknown cloud runtime command: ${command}`);
97
+ }
98
+ /**
99
+ * Start the WS relay and block until the process is signalled. This is the whole
100
+ * "daemon" for the standalone agent: one CloudRuntime + one Executor, no Discord,
101
+ * no scanner, no session-manager class.
102
+ */
103
+ async function runCloudRuntime(config, binaryName, verbose) {
104
+ if (!config.cloud)
105
+ throw new Error("cloud runtime is not configured");
106
+ if (config.cloud.enabled === false) {
107
+ throw new Error("cloud runtime is disabled in config; set cloud.enabled to true to connect");
108
+ }
109
+ const logger = new Logger({
110
+ filePath: config.log.file,
111
+ level: config.log.level,
112
+ verbose,
113
+ });
114
+ const executor = selectExecutor(logger);
115
+ const runtime = new CloudRuntime(config.cloud, executor, logger);
116
+ await runtime.start();
117
+ process.stdout.write(`${binaryName}: connected to ${config.cloud.gateway_url}. Press Ctrl+C to stop.\n`);
118
+ await new Promise((resolve) => {
119
+ const shutdown = () => {
120
+ runtime.stop();
121
+ void Promise.resolve(executor.close?.()).finally(() => {
122
+ void logger.close().finally(() => resolve());
123
+ });
124
+ };
125
+ process.once("SIGINT", shutdown);
126
+ process.once("SIGTERM", shutdown);
127
+ });
128
+ }
129
+ export function formatUsage(binaryName) {
130
+ return `Usage: ${binaryName} login [--gateway <url>] [--runtime-name <name>] [--config <path>]
131
+ ${binaryName} status [--config <path>]
132
+ ${binaryName} pair --gateway <url> --code <code> [--runtime-name <name>] [--config <path>]
133
+ ${binaryName} connect [--config <path>] [--verbose]
134
+ ${binaryName} disconnect [--config <path>]
135
+
136
+ Commands:
137
+ login (Recommended) Browser-based pairing — opens an approval URL in the
138
+ terminal, polls for authorization, then auto-connects. Defaults to
139
+ the public GSD Cloud gateway.
140
+ status Show current cloud runtime configuration and connection status.
141
+ pair Exchange a pairing code for a device token (headless/CI environments).
142
+ connect Connect using a previously paired device token.
143
+ disconnect Remove cloud runtime configuration from the local config file.
144
+
145
+ Options:
146
+ --config <path> Path to YAML config file (default: ~/.gsd/daemon.yaml)
147
+ --gateway <url> Cloud gateway URL (login defaults to https://cloud.opengsd.net)
148
+ --code <code> Pairing code from the gateway (pair only)
149
+ --runtime-name <name> Friendly name for this local GSD runtime
150
+ --verbose Print log entries to stderr in addition to the log file
151
+ --help Show this help message and exit
152
+
153
+ Environment:
154
+ GSD_CLOUD_PROJECTS Path-delimiter separated project dirs to advertise
155
+ (default: current working directory)
156
+ GSD_CLI_PATH Path to the gsd binary (default: gsd on PATH)
157
+ GSD_CLOUD_EXECUTOR Backend adapter: gsd-pi (default), codex, claude
158
+ `;
159
+ }
160
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["// Project/App: Open GSD\n// File Purpose: Standalone gsd-cloud CLI — login / status / connect / disconnect.\n//\n// Wires device-flow + CloudRuntime + a selected Executor adapter DIRECTLY. It has\n// no dependency on any Daemon or Orchestrator class; the only cloud behaviour is\n// the WS relay client driving the local GSD runtime through the Executor seam.\n\nimport { parseArgs } from \"node:util\";\nimport { resolveConfigPath, loadConfig } from \"./config.js\";\nimport { Logger } from \"./logger.js\";\nimport {\n clearCloudConfig,\n exchangePairingCode,\n redactedCloudStatus,\n saveCloudConfig,\n} from \"./cloud-config.js\";\nimport { runDeviceFlow } from \"./device-flow.js\";\nimport { CloudRuntime } from \"./cloud-runtime.js\";\nimport { selectExecutor } from \"./executors/index.js\";\nimport type { DaemonConfig } from \"./types.js\";\n\nexport async function handleCloudCommand(argv: string[], opts: {\n binaryName: string;\n}): Promise<void> {\n if (argv[0] === \"--help\" || argv[0] === \"-h\") {\n process.stdout.write(formatUsage(opts.binaryName));\n process.exit(0);\n }\n\n const command = argv[0];\n const { values } = parseArgs({\n args: argv.slice(1),\n options: {\n config: { type: \"string\", short: \"c\" },\n gateway: { type: \"string\" },\n code: { type: \"string\" },\n \"runtime-name\": { type: \"string\" },\n verbose: { type: \"boolean\", short: \"v\", default: false },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n strict: true,\n });\n\n if (values.help || !command) {\n process.stdout.write(formatUsage(opts.binaryName));\n process.exit(0);\n }\n\n const configPath = resolveConfigPath(values.config);\n\n if (command === \"status\") {\n process.stdout.write(`${JSON.stringify(redactedCloudStatus(loadConfig(configPath)), null, 2)}\\n`);\n return;\n }\n\n if (command === \"disconnect\") {\n clearCloudConfig(configPath);\n process.stdout.write(`${opts.binaryName}: cloud runtime disconnected locally.\\n`);\n return;\n }\n\n if (command === \"login\") {\n if (!values.gateway) {\n throw new Error(\"login requires --gateway\");\n }\n const runtimeName = values[\"runtime-name\"];\n const { deviceToken, runtimeId, gatewayUrl } = await runDeviceFlow({\n gatewayUrl: values.gateway,\n configPath,\n runtimeName,\n binaryName: opts.binaryName,\n });\n const config = saveCloudConfig(configPath, {\n gateway_url: gatewayUrl,\n device_token: deviceToken,\n runtime_id: runtimeId,\n ...(runtimeName ? { runtime_name: runtimeName } : {}),\n enabled: true,\n });\n process.stdout.write(`${opts.binaryName}: cloud runtime ${runtimeId} paired — connecting...\\n`);\n await runCloudRuntime(config, opts.binaryName, values.verbose);\n return;\n }\n\n if (command === \"pair\") {\n if (!values.gateway || !values.code) {\n throw new Error(\"pair requires --gateway and --code\");\n }\n const runtimeName = values[\"runtime-name\"];\n const result = await exchangePairingCode({\n gatewayUrl: values.gateway,\n code: values.code,\n runtimeName,\n });\n saveCloudConfig(configPath, {\n gateway_url: values.gateway,\n device_token: result.deviceToken,\n runtime_id: result.runtimeId,\n ...(runtimeName ? { runtime_name: runtimeName } : {}),\n enabled: true,\n });\n process.stdout.write(`${opts.binaryName}: paired cloud runtime ${result.runtimeId}.\\n`);\n return;\n }\n\n if (command === \"connect\") {\n const config = loadConfig(configPath);\n if (!config.cloud?.device_token || !config.cloud.runtime_id) {\n throw new Error(\"cloud runtime is not paired; run `login` first\");\n }\n await runCloudRuntime(config, opts.binaryName, values.verbose);\n return;\n }\n\n throw new Error(`Unknown cloud runtime command: ${command}`);\n}\n\n/**\n * Start the WS relay and block until the process is signalled. This is the whole\n * \"daemon\" for the standalone agent: one CloudRuntime + one Executor, no Discord,\n * no scanner, no session-manager class.\n */\nasync function runCloudRuntime(config: DaemonConfig, binaryName: string, verbose: boolean): Promise<void> {\n if (!config.cloud) throw new Error(\"cloud runtime is not configured\");\n if (config.cloud.enabled === false) {\n throw new Error(\"cloud runtime is disabled in config; set cloud.enabled to true to connect\");\n }\n const logger = new Logger({\n filePath: config.log.file,\n level: config.log.level,\n verbose,\n });\n const executor = selectExecutor(logger);\n const runtime = new CloudRuntime(config.cloud, executor, logger);\n await runtime.start();\n process.stdout.write(`${binaryName}: connected to ${config.cloud.gateway_url}. Press Ctrl+C to stop.\\n`);\n\n await new Promise<void>((resolve) => {\n const shutdown = () => {\n runtime.stop();\n void Promise.resolve(executor.close?.()).finally(() => {\n void logger.close().finally(() => resolve());\n });\n };\n process.once(\"SIGINT\", shutdown);\n process.once(\"SIGTERM\", shutdown);\n });\n}\n\nexport function formatUsage(binaryName: string): string {\n return `Usage: ${binaryName} login [--gateway <url>] [--runtime-name <name>] [--config <path>]\n ${binaryName} status [--config <path>]\n ${binaryName} pair --gateway <url> --code <code> [--runtime-name <name>] [--config <path>]\n ${binaryName} connect [--config <path>] [--verbose]\n ${binaryName} disconnect [--config <path>]\n\nCommands:\n login (Recommended) Browser-based pairing — opens an approval URL in the\n terminal, polls for authorization, then auto-connects. Defaults to\n the public GSD Cloud gateway.\n status Show current cloud runtime configuration and connection status.\n pair Exchange a pairing code for a device token (headless/CI environments).\n connect Connect using a previously paired device token.\n disconnect Remove cloud runtime configuration from the local config file.\n\nOptions:\n --config <path> Path to YAML config file (default: ~/.gsd/daemon.yaml)\n --gateway <url> Cloud gateway URL (login defaults to https://cloud.opengsd.net)\n --code <code> Pairing code from the gateway (pair only)\n --runtime-name <name> Friendly name for this local GSD runtime\n --verbose Print log entries to stderr in addition to the log file\n --help Show this help message and exit\n\nEnvironment:\n GSD_CLOUD_PROJECTS Path-delimiter separated project dirs to advertise\n (default: current working directory)\n GSD_CLI_PATH Path to the gsd binary (default: gsd on PATH)\n GSD_CLOUD_EXECUTOR Backend adapter: gsd-pi (default), codex, claude\n`;\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type { LookupFunction } from "node:net";
2
+ import type { DaemonConfig } from "./types.js";
3
+ export interface PairingExchangeResult {
4
+ runtimeId: string;
5
+ deviceToken: string;
6
+ }
7
+ export declare function exchangePairingCode(params: {
8
+ gatewayUrl: string;
9
+ code: string;
10
+ runtimeName?: string;
11
+ }): Promise<PairingExchangeResult>;
12
+ export declare function parseCloudGatewayUrl(value: string): URL;
13
+ export declare function saveCloudConfig(configPath: string, nextCloud: NonNullable<DaemonConfig["cloud"]>): DaemonConfig;
14
+ export declare function clearCloudConfig(configPath: string): DaemonConfig;
15
+ export declare function redactedCloudStatus(config: DaemonConfig): Record<string, unknown>;
16
+ export declare function validateGatewayNetworkTarget(url: URL): void;
17
+ export declare function createGatewayLookup(url: URL): LookupFunction;
18
+ export declare function postJsonToValidatedGateway(url: URL, payload: Record<string, unknown>, timeoutMs?: number): Promise<Record<string, unknown>>;
19
+ //# sourceMappingURL=cloud-config.d.ts.map