gsd-pi 2.52.0 → 2.53.0-dev.a67436f

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 (247) hide show
  1. package/README.md +55 -32
  2. package/dist/headless-query.js +1 -1
  3. package/dist/headless-ui.d.ts +2 -2
  4. package/dist/headless-ui.js +18 -15
  5. package/dist/headless.d.ts +11 -0
  6. package/dist/headless.js +178 -38
  7. package/dist/resources/extensions/get-secrets-from-user.js +7 -0
  8. package/dist/resources/extensions/gsd/auto/phases.js +28 -8
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +5 -1
  10. package/dist/resources/extensions/gsd/auto-worktree.js +70 -14
  11. package/dist/resources/extensions/gsd/auto.js +22 -0
  12. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -10
  13. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -3
  14. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  15. package/dist/resources/extensions/gsd/git-service.js +4 -3
  16. package/dist/resources/extensions/gsd/guided-flow.js +4 -3
  17. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -4
  18. package/dist/resources/extensions/gsd/parallel-orchestrator.js +18 -2
  19. package/dist/resources/extensions/gsd/preferences-types.js +1 -1
  20. package/dist/resources/extensions/gsd/state.js +18 -29
  21. package/dist/resources/extensions/gsd/status-guards.js +12 -0
  22. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -3
  23. package/dist/resources/extensions/gsd/tools/complete-slice.js +4 -3
  24. package/dist/resources/extensions/gsd/tools/complete-task.js +4 -3
  25. package/dist/resources/extensions/gsd/tools/plan-milestone.js +4 -14
  26. package/dist/resources/extensions/gsd/tools/plan-slice.js +4 -14
  27. package/dist/resources/extensions/gsd/tools/plan-task.js +4 -14
  28. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +6 -7
  29. package/dist/resources/extensions/gsd/tools/reopen-slice.js +4 -3
  30. package/dist/resources/extensions/gsd/tools/reopen-task.js +5 -4
  31. package/dist/resources/extensions/gsd/tools/replan-slice.js +5 -6
  32. package/dist/resources/extensions/gsd/validation.js +21 -0
  33. package/dist/resources/extensions/shared/rtk.js +14 -4
  34. package/dist/rtk.js +3 -1
  35. package/dist/web/standalone/.next/BUILD_ID +1 -1
  36. package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -20
  37. package/dist/web/standalone/.next/build-manifest.json +4 -4
  38. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  39. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  40. package/dist/web/standalone/.next/required-server-files.json +3 -3
  41. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  42. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  44. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  52. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  53. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  54. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  55. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  56. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  58. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  68. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  80. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  108. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  114. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  130. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  134. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/index.html +1 -1
  144. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  145. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  146. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  147. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  149. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/page.js +2 -2
  151. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -20
  153. package/dist/web/standalone/.next/server/chunks/2229.js +1 -1
  154. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  155. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/middleware.js +2 -2
  158. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  160. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  161. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  162. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  163. package/dist/web/standalone/.next/static/chunks/4024.87fd909ae0110f50.js +9 -0
  164. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  165. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  166. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  167. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  168. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  169. package/dist/web/standalone/.next/static/chunks/{webpack-024d82be84800e52.js → webpack-bca0e732db0dcec3.js} +1 -1
  170. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  171. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  172. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  173. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  174. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  175. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  176. package/dist/web/standalone/server.js +1 -1
  177. package/package.json +1 -1
  178. package/packages/mcp-server/README.md +6 -6
  179. package/packages/mcp-server/package.json +14 -4
  180. package/packages/mcp-server/src/cli.ts +1 -1
  181. package/packages/mcp-server/src/index.ts +1 -1
  182. package/packages/mcp-server/src/mcp-server.test.ts +2 -2
  183. package/packages/mcp-server/src/session-manager.ts +2 -2
  184. package/packages/mcp-server/src/types.ts +1 -1
  185. package/packages/pi-coding-agent/package.json +1 -1
  186. package/packages/rpc-client/README.md +125 -0
  187. package/packages/rpc-client/examples/basic-usage.ts +13 -0
  188. package/packages/rpc-client/package.json +17 -3
  189. package/packages/rpc-client/src/index.ts +10 -0
  190. package/packages/rpc-client/src/jsonl.ts +64 -0
  191. package/packages/rpc-client/src/rpc-client.test.ts +568 -0
  192. package/packages/rpc-client/src/rpc-client.ts +666 -0
  193. package/packages/rpc-client/src/rpc-types.ts +399 -0
  194. package/packages/rpc-client/tsconfig.examples.json +17 -0
  195. package/packages/rpc-client/tsconfig.json +24 -0
  196. package/pkg/package.json +1 -1
  197. package/scripts/ensure-workspace-builds.cjs +36 -8
  198. package/src/resources/extensions/get-secrets-from-user.ts +8 -0
  199. package/src/resources/extensions/gsd/auto/phases.ts +38 -7
  200. package/src/resources/extensions/gsd/auto-dispatch.ts +6 -1
  201. package/src/resources/extensions/gsd/auto-worktree.ts +73 -14
  202. package/src/resources/extensions/gsd/auto.ts +21 -0
  203. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +4 -11
  204. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +3 -3
  205. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  206. package/src/resources/extensions/gsd/git-service.ts +4 -3
  207. package/src/resources/extensions/gsd/guided-flow.ts +4 -3
  208. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -4
  209. package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -1
  210. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  211. package/src/resources/extensions/gsd/state.ts +18 -29
  212. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  213. package/src/resources/extensions/gsd/tests/active-milestone-id-guard.test.ts +91 -0
  214. package/src/resources/extensions/gsd/tests/auto-stale-lock-self-kill.test.ts +87 -0
  215. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +80 -0
  216. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +1 -1
  217. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +39 -0
  218. package/src/resources/extensions/gsd/tests/git-service.test.ts +64 -30
  219. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +51 -0
  220. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +277 -0
  221. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +103 -0
  222. package/src/resources/extensions/gsd/tests/preferences.test.ts +1 -1
  223. package/src/resources/extensions/gsd/tests/rate-limit-model-fallback.test.ts +90 -0
  224. package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +9 -8
  225. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +125 -0
  226. package/src/resources/extensions/gsd/tests/status-guards.test.ts +30 -0
  227. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -2
  228. package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +124 -0
  229. package/src/resources/extensions/gsd/tests/validation.test.ts +72 -0
  230. package/src/resources/extensions/gsd/tools/complete-milestone.ts +4 -3
  231. package/src/resources/extensions/gsd/tools/complete-slice.ts +4 -3
  232. package/src/resources/extensions/gsd/tools/complete-task.ts +4 -3
  233. package/src/resources/extensions/gsd/tools/plan-milestone.ts +4 -16
  234. package/src/resources/extensions/gsd/tools/plan-slice.ts +4 -16
  235. package/src/resources/extensions/gsd/tools/plan-task.ts +4 -16
  236. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +6 -7
  237. package/src/resources/extensions/gsd/tools/reopen-slice.ts +4 -3
  238. package/src/resources/extensions/gsd/tools/reopen-task.ts +5 -4
  239. package/src/resources/extensions/gsd/tools/replan-slice.ts +5 -7
  240. package/src/resources/extensions/gsd/validation.ts +23 -0
  241. package/src/resources/extensions/shared/rtk.ts +22 -4
  242. package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +0 -9
  243. package/dist/web/standalone/.next/static/chunks/app/page-fbecd1237e2d6d1f.js +0 -1
  244. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  245. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  246. /package/dist/web/standalone/.next/static/{vlgS2rkXjxeKhgXhdp4lh → YO-PWFRitlHM-L-dotlmm}/_buildManifest.js +0 -0
  247. /package/dist/web/standalone/.next/static/{vlgS2rkXjxeKhgXhdp4lh → YO-PWFRitlHM-L-dotlmm}/_ssgManifest.js +0 -0
@@ -9,6 +9,7 @@ import { join } from "node:path";
9
9
  import { mkdirSync } from "node:fs";
10
10
  import { transaction, getMilestone, getMilestoneSlices, getSliceTasks, updateMilestoneStatus, } from "../gsd-db.js";
11
11
  import { resolveMilestonePath, clearPathCache } from "../paths.js";
12
+ import { isClosedStatus } from "../status-guards.js";
12
13
  import { saveFile, clearParseCache } from "../files.js";
13
14
  import { invalidateStateCache } from "../state.js";
14
15
  import { renderAllProjections } from "../workflow-projections.js";
@@ -89,7 +90,7 @@ export async function handleCompleteMilestone(params, basePath) {
89
90
  guardError = `milestone not found: ${params.milestoneId}`;
90
91
  return;
91
92
  }
92
- if (milestone.status === "complete" || milestone.status === "done") {
93
+ if (isClosedStatus(milestone.status)) {
93
94
  guardError = `milestone ${params.milestoneId} is already complete`;
94
95
  return;
95
96
  }
@@ -99,7 +100,7 @@ export async function handleCompleteMilestone(params, basePath) {
99
100
  guardError = `no slices found for milestone ${params.milestoneId}`;
100
101
  return;
101
102
  }
102
- const incompleteSlices = slices.filter(s => s.status !== "complete" && s.status !== "done");
103
+ const incompleteSlices = slices.filter(s => !isClosedStatus(s.status));
103
104
  if (incompleteSlices.length > 0) {
104
105
  const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
105
106
  guardError = `incomplete slices: ${incompleteIds}`;
@@ -108,7 +109,7 @@ export async function handleCompleteMilestone(params, basePath) {
108
109
  // Deep check: verify all tasks in all slices are complete
109
110
  for (const slice of slices) {
110
111
  const tasks = getSliceTasks(params.milestoneId, slice.id);
111
- const incompleteTasks = tasks.filter(t => t.status !== "complete" && t.status !== "done");
112
+ const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
112
113
  if (incompleteTasks.length > 0) {
113
114
  const ids = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
114
115
  guardError = `slice ${slice.id} has incomplete tasks: ${ids}`;
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { join } from "node:path";
10
10
  import { mkdirSync } from "node:fs";
11
+ import { isClosedStatus } from "../status-guards.js";
11
12
  import { transaction, insertMilestone, insertSlice, getSlice, getSliceTasks, getMilestone, updateSliceStatus, setSliceSummaryMd, } from "../gsd-db.js";
12
13
  import { resolveSlicePath, clearPathCache } from "../paths.js";
13
14
  import { checkOwnership, sliceUnitKey } from "../unit-ownership.js";
@@ -179,12 +180,12 @@ export async function handleCompleteSlice(params, basePath) {
179
180
  // Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
180
181
  // Only block if they exist and are closed.
181
182
  const milestone = getMilestone(params.milestoneId);
182
- if (milestone && (milestone.status === "complete" || milestone.status === "done")) {
183
+ if (milestone && isClosedStatus(milestone.status)) {
183
184
  guardError = `cannot complete slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
184
185
  return;
185
186
  }
186
187
  const slice = getSlice(params.milestoneId, params.sliceId);
187
- if (slice && (slice.status === "complete" || slice.status === "done")) {
188
+ if (slice && isClosedStatus(slice.status)) {
188
189
  guardError = `slice ${params.sliceId} is already complete — use gsd_slice_reopen first if you need to redo it`;
189
190
  return;
190
191
  }
@@ -194,7 +195,7 @@ export async function handleCompleteSlice(params, basePath) {
194
195
  guardError = `no tasks found for slice ${params.sliceId} in milestone ${params.milestoneId}`;
195
196
  return;
196
197
  }
197
- const incompleteTasks = tasks.filter(t => t.status !== "complete" && t.status !== "done");
198
+ const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
198
199
  if (incompleteTasks.length > 0) {
199
200
  const incompleteIds = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
200
201
  guardError = `incomplete tasks: ${incompleteIds}`;
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { join } from "node:path";
10
10
  import { mkdirSync } from "node:fs";
11
+ import { isClosedStatus } from "../status-guards.js";
11
12
  import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, setTaskSummaryMd, deleteVerificationEvidence, } from "../gsd-db.js";
12
13
  import { resolveSliceFile, resolveTasksDir, clearPathCache } from "../paths.js";
13
14
  import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
@@ -122,17 +123,17 @@ export async function handleCompleteTask(params, basePath) {
122
123
  // Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
123
124
  // Only block if they exist and are closed.
124
125
  const milestone = getMilestone(params.milestoneId);
125
- if (milestone && (milestone.status === "complete" || milestone.status === "done")) {
126
+ if (milestone && isClosedStatus(milestone.status)) {
126
127
  guardError = `cannot complete task in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
127
128
  return;
128
129
  }
129
130
  const slice = getSlice(params.milestoneId, params.sliceId);
130
- if (slice && (slice.status === "complete" || slice.status === "done")) {
131
+ if (slice && isClosedStatus(slice.status)) {
131
132
  guardError = `cannot complete task in a closed slice: ${params.sliceId} (status: ${slice.status})`;
132
133
  return;
133
134
  }
134
135
  const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
135
- if (existingTask && (existingTask.status === "complete" || existingTask.status === "done")) {
136
+ if (existingTask && isClosedStatus(existingTask.status)) {
136
137
  guardError = `task ${params.taskId} is already complete — use gsd_task_reopen first if you need to redo it`;
137
138
  return;
138
139
  }
@@ -1,22 +1,12 @@
1
1
  import { clearParseCache } from "../files.js";
2
+ import { isClosedStatus } from "../status-guards.js";
3
+ import { isNonEmptyString, validateStringArray } from "../validation.js";
2
4
  import { transaction, getMilestone, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
3
5
  import { invalidateStateCache } from "../state.js";
4
6
  import { renderRoadmapFromDb } from "../markdown-renderer.js";
5
7
  import { renderAllProjections } from "../workflow-projections.js";
6
8
  import { writeManifest } from "../workflow-manifest.js";
7
9
  import { appendEvent } from "../workflow-events.js";
8
- function isNonEmptyString(value) {
9
- return typeof value === "string" && value.trim().length > 0;
10
- }
11
- function validateStringArray(value, field) {
12
- if (!Array.isArray(value)) {
13
- throw new Error(`${field} must be an array`);
14
- }
15
- if (value.some((item) => !isNonEmptyString(item))) {
16
- throw new Error(`${field} must contain only non-empty strings`);
17
- }
18
- return value;
19
- }
20
10
  function validateRiskEntries(value) {
21
11
  if (!Array.isArray(value)) {
22
12
  throw new Error("keyRisks must be an array");
@@ -152,7 +142,7 @@ export async function handlePlanMilestone(rawParams, basePath) {
152
142
  try {
153
143
  transaction(() => {
154
144
  const existingMilestone = getMilestone(params.milestoneId);
155
- if (existingMilestone && (existingMilestone.status === "complete" || existingMilestone.status === "done")) {
145
+ if (existingMilestone && isClosedStatus(existingMilestone.status)) {
156
146
  guardError = `cannot re-plan milestone ${params.milestoneId}: it is already complete`;
157
147
  return;
158
148
  }
@@ -164,7 +154,7 @@ export async function handlePlanMilestone(rawParams, basePath) {
164
154
  guardError = `depends_on references unknown milestone: ${depId}`;
165
155
  return;
166
156
  }
167
- if (dep.status !== "complete" && dep.status !== "done") {
157
+ if (!isClosedStatus(dep.status)) {
168
158
  guardError = `depends_on milestone ${depId} is not yet complete (status: ${dep.status})`;
169
159
  return;
170
160
  }
@@ -1,22 +1,12 @@
1
1
  import { clearParseCache } from "../files.js";
2
+ import { isClosedStatus } from "../status-guards.js";
3
+ import { isNonEmptyString } from "../validation.js";
2
4
  import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, } from "../gsd-db.js";
3
5
  import { invalidateStateCache } from "../state.js";
4
6
  import { renderPlanFromDb } from "../markdown-renderer.js";
5
7
  import { renderAllProjections } from "../workflow-projections.js";
6
8
  import { writeManifest } from "../workflow-manifest.js";
7
9
  import { appendEvent } from "../workflow-events.js";
8
- function isNonEmptyString(value) {
9
- return typeof value === "string" && value.trim().length > 0;
10
- }
11
- function validateStringArray(value, field) {
12
- if (!Array.isArray(value)) {
13
- throw new Error(`${field} must be an array`);
14
- }
15
- if (value.some((item) => !isNonEmptyString(item))) {
16
- throw new Error(`${field} must contain only non-empty strings`);
17
- }
18
- return value;
19
- }
20
10
  function validateTasks(value) {
21
11
  if (!Array.isArray(value) || value.length === 0) {
22
12
  throw new Error("tasks must be a non-empty array");
@@ -113,7 +103,7 @@ export async function handlePlanSlice(rawParams, basePath) {
113
103
  guardError = `milestone not found: ${params.milestoneId}`;
114
104
  return;
115
105
  }
116
- if (parentMilestone.status === "complete" || parentMilestone.status === "done") {
106
+ if (isClosedStatus(parentMilestone.status)) {
117
107
  guardError = `cannot plan slice in a closed milestone: ${params.milestoneId} (status: ${parentMilestone.status})`;
118
108
  return;
119
109
  }
@@ -122,7 +112,7 @@ export async function handlePlanSlice(rawParams, basePath) {
122
112
  guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
123
113
  return;
124
114
  }
125
- if (parentSlice.status === "complete" || parentSlice.status === "done") {
115
+ if (isClosedStatus(parentSlice.status)) {
126
116
  guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
127
117
  return;
128
118
  }
@@ -1,22 +1,12 @@
1
1
  import { clearParseCache } from "../files.js";
2
+ import { isClosedStatus } from "../status-guards.js";
3
+ import { isNonEmptyString, validateStringArray } from "../validation.js";
2
4
  import { transaction, getSlice, getTask, insertTask, upsertTaskPlanning } from "../gsd-db.js";
3
5
  import { invalidateStateCache } from "../state.js";
4
6
  import { renderTaskPlanFromDb } from "../markdown-renderer.js";
5
7
  import { renderAllProjections } from "../workflow-projections.js";
6
8
  import { writeManifest } from "../workflow-manifest.js";
7
9
  import { appendEvent } from "../workflow-events.js";
8
- function isNonEmptyString(value) {
9
- return typeof value === "string" && value.trim().length > 0;
10
- }
11
- function validateStringArray(value, field) {
12
- if (!Array.isArray(value)) {
13
- throw new Error(`${field} must be an array`);
14
- }
15
- if (value.some((item) => !isNonEmptyString(item))) {
16
- throw new Error(`${field} must contain only non-empty strings`);
17
- }
18
- return value;
19
- }
20
10
  function validateParams(params) {
21
11
  if (!isNonEmptyString(params?.milestoneId))
22
12
  throw new Error("milestoneId is required");
@@ -61,12 +51,12 @@ export async function handlePlanTask(rawParams, basePath) {
61
51
  guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
62
52
  return;
63
53
  }
64
- if (parentSlice.status === "complete" || parentSlice.status === "done") {
54
+ if (isClosedStatus(parentSlice.status)) {
65
55
  guardError = `cannot plan task in a closed slice: ${params.sliceId} (status: ${parentSlice.status})`;
66
56
  return;
67
57
  }
68
58
  const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
69
- if (existingTask && (existingTask.status === "complete" || existingTask.status === "done")) {
59
+ if (existingTask && isClosedStatus(existingTask.status)) {
70
60
  guardError = `cannot re-plan task ${params.taskId}: it is already complete — use gsd_task_reopen first`;
71
61
  return;
72
62
  }
@@ -1,14 +1,13 @@
1
+ import { join } from "node:path";
1
2
  import { clearParseCache } from "../files.js";
3
+ import { isClosedStatus } from "../status-guards.js";
4
+ import { isNonEmptyString } from "../validation.js";
2
5
  import { transaction, getMilestone, getMilestoneSlices, getSlice, insertSlice, updateSliceFields, insertAssessment, deleteSlice, } from "../gsd-db.js";
3
6
  import { invalidateStateCache } from "../state.js";
4
7
  import { renderRoadmapFromDb, renderAssessmentFromDb } from "../markdown-renderer.js";
5
8
  import { renderAllProjections } from "../workflow-projections.js";
6
9
  import { writeManifest } from "../workflow-manifest.js";
7
10
  import { appendEvent } from "../workflow-events.js";
8
- import { join } from "node:path";
9
- function isNonEmptyString(value) {
10
- return typeof value === "string" && value.trim().length > 0;
11
- }
12
11
  function validateParams(params) {
13
12
  if (!isNonEmptyString(params?.milestoneId))
14
13
  throw new Error("milestoneId is required");
@@ -76,7 +75,7 @@ export async function handleReassessRoadmap(rawParams, basePath) {
76
75
  guardError = `milestone not found: ${params.milestoneId}`;
77
76
  return;
78
77
  }
79
- if (milestone.status === "complete" || milestone.status === "done") {
78
+ if (isClosedStatus(milestone.status)) {
80
79
  guardError = `cannot reassess a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
81
80
  return;
82
81
  }
@@ -86,7 +85,7 @@ export async function handleReassessRoadmap(rawParams, basePath) {
86
85
  guardError = `completedSliceId not found: ${params.milestoneId}/${params.completedSliceId}`;
87
86
  return;
88
87
  }
89
- if (completedSlice.status !== "complete" && completedSlice.status !== "done") {
88
+ if (!isClosedStatus(completedSlice.status)) {
90
89
  guardError = `completedSliceId ${params.completedSliceId} is not complete (status: ${completedSlice.status}) — reassess can only be called after a slice finishes`;
91
90
  return;
92
91
  }
@@ -94,7 +93,7 @@ export async function handleReassessRoadmap(rawParams, basePath) {
94
93
  const existingSlices = getMilestoneSlices(params.milestoneId);
95
94
  const completedSliceIds = new Set();
96
95
  for (const slice of existingSlices) {
97
- if (slice.status === "complete" || slice.status === "done") {
96
+ if (isClosedStatus(slice.status)) {
98
97
  completedSliceIds.add(slice.id);
99
98
  }
100
99
  }
@@ -11,6 +11,7 @@
11
11
  // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
12
12
  import { getMilestone, getSlice, getSliceTasks, updateSliceStatus, updateTaskStatus, transaction, } from "../gsd-db.js";
13
13
  import { invalidateStateCache } from "../state.js";
14
+ import { isClosedStatus } from "../status-guards.js";
14
15
  import { renderAllProjections } from "../workflow-projections.js";
15
16
  import { writeManifest } from "../workflow-manifest.js";
16
17
  import { appendEvent } from "../workflow-events.js";
@@ -31,8 +32,8 @@ export async function handleReopenSlice(params, basePath) {
31
32
  guardError = `milestone not found: ${params.milestoneId}`;
32
33
  return;
33
34
  }
34
- if (milestone.status === "complete" || milestone.status === "done") {
35
- guardError = `cannot reopen slice inside a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
35
+ if (isClosedStatus(milestone.status)) {
36
+ guardError = `cannot reopen slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
36
37
  return;
37
38
  }
38
39
  const slice = getSlice(params.milestoneId, params.sliceId);
@@ -40,7 +41,7 @@ export async function handleReopenSlice(params, basePath) {
40
41
  guardError = `slice not found: ${params.milestoneId}/${params.sliceId}`;
41
42
  return;
42
43
  }
43
- if (slice.status !== "complete" && slice.status !== "done") {
44
+ if (!isClosedStatus(slice.status)) {
44
45
  guardError = `slice ${params.sliceId} is not complete (status: ${slice.status}) — nothing to reopen`;
45
46
  return;
46
47
  }
@@ -10,6 +10,7 @@
10
10
  // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
11
11
  import { getMilestone, getSlice, getTask, updateTaskStatus, transaction, } from "../gsd-db.js";
12
12
  import { invalidateStateCache } from "../state.js";
13
+ import { isClosedStatus } from "../status-guards.js";
13
14
  import { renderAllProjections } from "../workflow-projections.js";
14
15
  import { writeManifest } from "../workflow-manifest.js";
15
16
  import { appendEvent } from "../workflow-events.js";
@@ -32,7 +33,7 @@ export async function handleReopenTask(params, basePath) {
32
33
  guardError = `milestone not found: ${params.milestoneId}`;
33
34
  return;
34
35
  }
35
- if (milestone.status === "complete" || milestone.status === "done") {
36
+ if (isClosedStatus(milestone.status)) {
36
37
  guardError = `cannot reopen task in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
37
38
  return;
38
39
  }
@@ -41,8 +42,8 @@ export async function handleReopenTask(params, basePath) {
41
42
  guardError = `slice not found: ${params.milestoneId}/${params.sliceId}`;
42
43
  return;
43
44
  }
44
- if (slice.status === "complete" || slice.status === "done") {
45
- guardError = `cannot reopen task inside a closed slice: ${params.sliceId} (status: ${slice.status}) — use gsd_slice_reopen first`;
45
+ if (isClosedStatus(slice.status)) {
46
+ guardError = `cannot reopen task in a closed slice: ${params.sliceId} (status: ${slice.status}) — use gsd_slice_reopen first`;
46
47
  return;
47
48
  }
48
49
  const task = getTask(params.milestoneId, params.sliceId, params.taskId);
@@ -50,7 +51,7 @@ export async function handleReopenTask(params, basePath) {
50
51
  guardError = `task not found: ${params.milestoneId}/${params.sliceId}/${params.taskId}`;
51
52
  return;
52
53
  }
53
- if (task.status !== "complete" && task.status !== "done") {
54
+ if (!isClosedStatus(task.status)) {
54
55
  guardError = `task ${params.taskId} is not complete (status: ${task.status}) — nothing to reopen`;
55
56
  return;
56
57
  }
@@ -1,13 +1,12 @@
1
1
  import { clearParseCache } from "../files.js";
2
2
  import { transaction, getSlice, getSliceTasks, getTask, insertTask, upsertTaskPlanning, insertReplanHistory, deleteTask, } from "../gsd-db.js";
3
3
  import { invalidateStateCache } from "../state.js";
4
+ import { isClosedStatus } from "../status-guards.js";
5
+ import { isNonEmptyString } from "../validation.js";
4
6
  import { renderPlanFromDb, renderReplanFromDb } from "../markdown-renderer.js";
5
7
  import { renderAllProjections } from "../workflow-projections.js";
6
8
  import { writeManifest } from "../workflow-manifest.js";
7
9
  import { appendEvent } from "../workflow-events.js";
8
- function isNonEmptyString(value) {
9
- return typeof value === "string" && value.trim().length > 0;
10
- }
11
10
  function validateParams(params) {
12
11
  if (!isNonEmptyString(params?.milestoneId))
13
12
  throw new Error("milestoneId is required");
@@ -59,7 +58,7 @@ export async function handleReplanSlice(rawParams, basePath) {
59
58
  guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
60
59
  return;
61
60
  }
62
- if (parentSlice.status === "complete" || parentSlice.status === "done") {
61
+ if (isClosedStatus(parentSlice.status)) {
63
62
  guardError = `cannot replan a closed slice: ${params.sliceId} (status: ${parentSlice.status})`;
64
63
  return;
65
64
  }
@@ -69,7 +68,7 @@ export async function handleReplanSlice(rawParams, basePath) {
69
68
  guardError = `blockerTaskId not found: ${params.milestoneId}/${params.sliceId}/${params.blockerTaskId}`;
70
69
  return;
71
70
  }
72
- if (blockerTask.status !== "complete" && blockerTask.status !== "done") {
71
+ if (!isClosedStatus(blockerTask.status)) {
73
72
  guardError = `blockerTaskId ${params.blockerTaskId} is not complete (status: ${blockerTask.status}) — the blocker task must be finished before a replan is triggered`;
74
73
  return;
75
74
  }
@@ -77,7 +76,7 @@ export async function handleReplanSlice(rawParams, basePath) {
77
76
  const existingTasks = getSliceTasks(params.milestoneId, params.sliceId);
78
77
  const completedTaskIds = new Set();
79
78
  for (const task of existingTasks) {
80
- if (task.status === "complete" || task.status === "done") {
79
+ if (isClosedStatus(task.status)) {
81
80
  completedTaskIds.add(task.id);
82
81
  }
83
82
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Shared input-validation primitives for GSD tool handlers.
3
+ */
4
+ /** Type guard: value is a string with at least one non-whitespace character. */
5
+ export function isNonEmptyString(value) {
6
+ return typeof value === "string" && value.trim().length > 0;
7
+ }
8
+ /**
9
+ * Validate that `value` is an array of non-empty strings.
10
+ * Throws with a message referencing `field` on failure.
11
+ * Returns the validated array (narrowed to string[]).
12
+ */
13
+ export function validateStringArray(value, field) {
14
+ if (!Array.isArray(value)) {
15
+ throw new Error(`${field} must be an array`);
16
+ }
17
+ if (value.some((item) => !isNonEmptyString(item))) {
18
+ throw new Error(`${field} must contain only non-empty strings`);
19
+ }
20
+ return value;
21
+ }
@@ -4,6 +4,7 @@ import { homedir } from "node:os";
4
4
  import { delimiter, join } from "node:path";
5
5
  const GSD_RTK_PATH_ENV = "GSD_RTK_PATH";
6
6
  const GSD_RTK_DISABLED_ENV = "GSD_RTK_DISABLED";
7
+ const GSD_RTK_REWRITE_TIMEOUT_MS_ENV = "GSD_RTK_REWRITE_TIMEOUT_MS";
7
8
  const RTK_TELEMETRY_DISABLED_ENV = "RTK_TELEMETRY_DISABLED";
8
9
  const RTK_REWRITE_TIMEOUT_MS = 5_000;
9
10
  function isTruthy(value) {
@@ -12,6 +13,13 @@ function isTruthy(value) {
12
13
  const normalized = value.trim().toLowerCase();
13
14
  return normalized === "1" || normalized === "true" || normalized === "yes";
14
15
  }
16
+ function getRewriteTimeoutMs(env = process.env) {
17
+ const configured = Number.parseInt(env[GSD_RTK_REWRITE_TIMEOUT_MS_ENV] ?? "", 10);
18
+ if (Number.isFinite(configured) && configured > 0) {
19
+ return configured;
20
+ }
21
+ return RTK_REWRITE_TIMEOUT_MS;
22
+ }
15
23
  export function isRtkEnabled(env = process.env) {
16
24
  return !isTruthy(env[GSD_RTK_DISABLED_ENV]);
17
25
  }
@@ -75,19 +83,21 @@ export function resolveRtkBinaryPath(options = {}) {
75
83
  }
76
84
  return resolveSystemRtkPath(options.pathValue ?? getPathValue(env), platform);
77
85
  }
78
- export function rewriteCommandWithRtk(command, env = process.env) {
86
+ export function rewriteCommandWithRtk(command, options = {}) {
87
+ const env = options.env ?? process.env;
79
88
  if (!command.trim())
80
89
  return command;
81
90
  if (!isRtkEnabled(env))
82
91
  return command;
83
- const binaryPath = resolveRtkBinaryPath({ env });
92
+ const binaryPath = options.binaryPath ?? resolveRtkBinaryPath({ env });
84
93
  if (!binaryPath)
85
94
  return command;
86
- const result = spawnSync(binaryPath, ["rewrite", command], {
95
+ const run = options.spawnSyncImpl ?? spawnSync;
96
+ const result = run(binaryPath, ["rewrite", command], {
87
97
  encoding: "utf-8",
88
98
  env: buildRtkEnv(env),
89
99
  stdio: ["ignore", "pipe", "ignore"],
90
- timeout: RTK_REWRITE_TIMEOUT_MS,
100
+ timeout: getRewriteTimeoutMs(env),
91
101
  // .cmd/.bat wrappers (used by fake-rtk in tests) require shell:true on Windows
92
102
  shell: /\.(cmd|bat)$/i.test(binaryPath),
93
103
  });
package/dist/rtk.js CHANGED
@@ -175,7 +175,9 @@ function resolveSystemRtkPath(pathValue, platform = process.platform) {
175
175
  export function resolveRtkBinaryPath(options = {}) {
176
176
  const env = options.env ?? process.env;
177
177
  const platform = options.platform ?? process.platform;
178
- const explicitPath = options.binaryPath ?? env[GSD_RTK_PATH_ENV];
178
+ if (options.binaryPath)
179
+ return options.binaryPath;
180
+ const explicitPath = env[GSD_RTK_PATH_ENV];
179
181
  if (explicitPath && existsSync(explicitPath)) {
180
182
  return explicitPath;
181
183
  }
@@ -1 +1 @@
1
- vlgS2rkXjxeKhgXhdp4lh
1
+ YO-PWFRitlHM-L-dotlmm
@@ -1,46 +1,46 @@
1
1
  {
2
2
  "/_global-error/page": "/_global-error",
3
3
  "/_not-found/page": "/_not-found",
4
- "/api/boot/route": "/api/boot",
5
4
  "/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
5
+ "/api/boot/route": "/api/boot",
6
6
  "/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
7
7
  "/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
8
- "/api/dev-mode/route": "/api/dev-mode",
9
8
  "/api/cleanup/route": "/api/cleanup",
10
- "/api/browse-directories/route": "/api/browse-directories",
11
9
  "/api/export-data/route": "/api/export-data",
12
- "/api/forensics/route": "/api/forensics",
13
10
  "/api/doctor/route": "/api/doctor",
14
- "/api/git/route": "/api/git",
11
+ "/api/browse-directories/route": "/api/browse-directories",
12
+ "/api/dev-mode/route": "/api/dev-mode",
15
13
  "/api/captures/route": "/api/captures",
16
- "/api/experimental/route": "/api/experimental",
17
- "/api/inspect/route": "/api/inspect",
18
- "/api/hooks/route": "/api/hooks",
19
14
  "/api/history/route": "/api/history",
15
+ "/api/forensics/route": "/api/forensics",
16
+ "/api/git/route": "/api/git",
17
+ "/api/hooks/route": "/api/hooks",
18
+ "/api/inspect/route": "/api/inspect",
19
+ "/api/live-state/route": "/api/live-state",
20
20
  "/api/knowledge/route": "/api/knowledge",
21
+ "/api/experimental/route": "/api/experimental",
21
22
  "/api/preferences/route": "/api/preferences",
22
- "/api/live-state/route": "/api/live-state",
23
23
  "/api/recovery/route": "/api/recovery",
24
- "/api/projects/route": "/api/projects",
25
- "/api/session/browser/route": "/api/session/browser",
26
24
  "/api/onboarding/route": "/api/onboarding",
27
- "/api/files/route": "/api/files",
25
+ "/api/session/browser/route": "/api/session/browser",
26
+ "/api/projects/route": "/api/projects",
27
+ "/api/session/manage/route": "/api/session/manage",
28
28
  "/api/session/command/route": "/api/session/command",
29
- "/api/settings-data/route": "/api/settings-data",
29
+ "/api/skill-health/route": "/api/skill-health",
30
30
  "/api/session/events/route": "/api/session/events",
31
+ "/api/settings-data/route": "/api/settings-data",
31
32
  "/api/shutdown/route": "/api/shutdown",
32
- "/api/session/manage/route": "/api/session/manage",
33
- "/api/skill-health/route": "/api/skill-health",
34
33
  "/api/steer/route": "/api/steer",
34
+ "/api/terminal/resize/route": "/api/terminal/resize",
35
35
  "/api/switch-root/route": "/api/switch-root",
36
+ "/api/files/route": "/api/files",
36
37
  "/api/terminal/input/route": "/api/terminal/input",
37
- "/api/terminal/resize/route": "/api/terminal/resize",
38
- "/api/terminal/sessions/route": "/api/terminal/sessions",
39
- "/api/undo/route": "/api/undo",
40
- "/api/remote-questions/route": "/api/remote-questions",
41
- "/api/update/route": "/api/update",
42
38
  "/api/visualizer/route": "/api/visualizer",
43
39
  "/api/terminal/stream/route": "/api/terminal/stream",
40
+ "/api/undo/route": "/api/undo",
41
+ "/api/terminal/sessions/route": "/api/terminal/sessions",
42
+ "/api/update/route": "/api/update",
43
+ "/api/remote-questions/route": "/api/remote-questions",
44
44
  "/api/terminal/upload/route": "/api/terminal/upload",
45
45
  "/page": "/"
46
46
  }
@@ -4,14 +4,14 @@
4
4
  ],
5
5
  "devFiles": [],
6
6
  "lowPriorityFiles": [
7
- "static/vlgS2rkXjxeKhgXhdp4lh/_buildManifest.js",
8
- "static/vlgS2rkXjxeKhgXhdp4lh/_ssgManifest.js"
7
+ "static/YO-PWFRitlHM-L-dotlmm/_buildManifest.js",
8
+ "static/YO-PWFRitlHM-L-dotlmm/_ssgManifest.js"
9
9
  ],
10
10
  "rootMainFiles": [
11
- "static/chunks/webpack-024d82be84800e52.js",
11
+ "static/chunks/webpack-bca0e732db0dcec3.js",
12
12
  "static/chunks/4bd1b696-e5d7c65570c947b7.js",
13
13
  "static/chunks/3794-337d1ca25ad99a89.js",
14
- "static/chunks/main-app-d3d4c336195465f9.js"
14
+ "static/chunks/main-app-fdab67f7802d7832.js"
15
15
  ],
16
16
  "rootMainFilesTree": {},
17
17
  "pages": {
@@ -78,8 +78,8 @@
78
78
  "dynamicRoutes": {},
79
79
  "notFoundRoutes": [],
80
80
  "preview": {
81
- "previewModeId": "a771cbd7151fe8792440248f74a9eee9",
82
- "previewModeSigningKey": "06c08aa13e30bbf98adc75382278314fd126424a2c85de220467482119ad407e",
83
- "previewModeEncryptionKey": "44023b0b0e864966518a457214e9fc1cead59218ead80a8e34e0d5758d8a9d9d"
81
+ "previewModeId": "01331f5d86acc7be1d3ecc8d5855e334",
82
+ "previewModeSigningKey": "8b6653cdd01c63bde017b6a42df870bc138ec94025546cdb71ac3548cfea7fa6",
83
+ "previewModeEncryptionKey": "2d7b20c003d03450d2f327b36c6e5db81437c825c1417b0299956d4083d83ea7"
84
84
  }
85
85
  }
@@ -6,7 +6,7 @@
6
6
  "static/chunks/363642f4.f9053a63f1b97508.js",
7
7
  "static/chunks/4986-c2fc8845ce785303.js",
8
8
  "static/chunks/2008.817d0885545aaea9.js",
9
- "static/chunks/4024.21054f459af5cc78.js"
9
+ "static/chunks/4024.87fd909ae0110f50.js"
10
10
  ]
11
11
  },
12
12
  "components/gsd/chat-mode.tsx -> react-markdown": {
@@ -100,7 +100,7 @@
100
100
  "transform": "lodash/{{member}}"
101
101
  }
102
102
  },
103
- "outputFileTracingRoot": "/home/runner/_work/gsd-2/gsd-2",
103
+ "outputFileTracingRoot": "/__w/gsd-2/gsd-2",
104
104
  "cacheComponents": false,
105
105
  "cacheLife": {
106
106
  "default": {
@@ -297,11 +297,11 @@
297
297
  "node-pty"
298
298
  ],
299
299
  "turbopack": {
300
- "root": "/home/runner/_work/gsd-2/gsd-2"
300
+ "root": "/__w/gsd-2/gsd-2"
301
301
  },
302
302
  "distDirRoot": ".next"
303
303
  },
304
- "appDir": "/home/runner/_work/gsd-2/gsd-2/web",
304
+ "appDir": "/__w/gsd-2/gsd-2/web",
305
305
  "relativeAppDir": "web",
306
306
  "files": [
307
307
  ".next/routes-manifest.json",