gsd-pi 2.78.0 → 2.78.1-dev.8a893322c

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 (559) hide show
  1. package/README.md +60 -23
  2. package/dist/bundled-resource-path.d.ts +7 -0
  3. package/dist/bundled-resource-path.js +34 -2
  4. package/dist/claude-cli-check.js +104 -33
  5. package/dist/cli-policy.d.ts +13 -0
  6. package/dist/cli-policy.js +17 -0
  7. package/dist/cli.js +95 -55
  8. package/dist/headless-query.d.ts +22 -0
  9. package/dist/headless-query.js +43 -8
  10. package/dist/headless.d.ts +10 -0
  11. package/dist/headless.js +16 -1
  12. package/dist/loader.js +9 -13
  13. package/dist/onboarding.d.ts +10 -0
  14. package/dist/onboarding.js +2 -2
  15. package/dist/provider-migrations.d.ts +2 -2
  16. package/dist/provider-migrations.js +5 -2
  17. package/dist/resource-loader.d.ts +5 -2
  18. package/dist/resource-loader.js +30 -13
  19. package/dist/resources/.managed-resources-content-hash +1 -0
  20. package/dist/resources/extensions/claude-code-cli/readiness.js +128 -32
  21. package/dist/resources/extensions/google-search/index.js +2 -6
  22. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  23. package/dist/resources/extensions/gsd/auto/phases.js +5 -13
  24. package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
  25. package/dist/resources/extensions/gsd/auto/session.js +5 -6
  26. package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
  27. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  28. package/dist/resources/extensions/gsd/auto-prompts.js +63 -2
  29. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  30. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  31. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  32. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  33. package/dist/resources/extensions/gsd/auto-worktree.js +60 -13
  34. package/dist/resources/extensions/gsd/auto.js +14 -5
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  36. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  37. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  38. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  39. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +112 -31
  40. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  41. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  42. package/dist/resources/extensions/gsd/bootstrap/system-context.js +45 -8
  43. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  44. package/dist/resources/extensions/gsd/commands/catalog.js +76 -5
  45. package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -1
  46. package/dist/resources/extensions/gsd/commands/handlers/ops.js +8 -0
  47. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  48. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  49. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  50. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  51. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  52. package/dist/resources/extensions/gsd/commands-worktree.js +309 -0
  53. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  54. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  55. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  56. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  57. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  58. package/dist/resources/extensions/gsd/forensics.js +10 -8
  59. package/dist/resources/extensions/gsd/git-service.js +12 -5
  60. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  61. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  62. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  63. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  64. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  65. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  66. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  67. package/dist/resources/extensions/gsd/model-router.js +114 -9
  68. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  69. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  70. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  71. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  72. package/dist/resources/extensions/gsd/preferences.js +5 -3
  73. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  74. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  75. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  76. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  77. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  78. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  79. package/dist/resources/extensions/gsd/state.js +42 -0
  80. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  81. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  82. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  83. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  84. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  85. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  86. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  87. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -13
  88. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  89. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  90. package/dist/resources/extensions/gsd/worktree.js +4 -115
  91. package/dist/resources/extensions/mcp-client/index.js +6 -9
  92. package/dist/resources/extensions/ollama/index.js +15 -2
  93. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  94. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  95. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  96. package/dist/resources/extensions/subagent/index.js +324 -178
  97. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  98. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  99. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  100. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  101. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  102. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  103. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  104. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  105. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  106. package/dist/rtk-shared.d.ts +3 -0
  107. package/dist/rtk-shared.js +17 -0
  108. package/dist/rtk.d.ts +2 -5
  109. package/dist/rtk.js +3 -20
  110. package/dist/runtime-checks.d.ts +27 -0
  111. package/dist/runtime-checks.js +38 -0
  112. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  113. package/dist/web/standalone/.next/BUILD_ID +1 -1
  114. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  115. package/dist/web/standalone/.next/build-manifest.json +4 -4
  116. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  117. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  118. package/dist/web/standalone/.next/required-server-files.json +3 -3
  119. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  120. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  130. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  146. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  158. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  178. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  194. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  208. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  210. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  214. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/index.html +1 -1
  224. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  225. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  226. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  227. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  228. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  229. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  230. package/dist/web/standalone/.next/server/app/page.js +2 -2
  231. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  233. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  234. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  235. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  237. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/middleware.js +2 -2
  239. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  241. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  242. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  243. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  244. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  245. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  249. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  250. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  252. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  253. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  254. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  256. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  257. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  259. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  260. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  261. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  262. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  263. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  264. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  265. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  266. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  267. package/dist/web/standalone/package.json +2 -1
  268. package/dist/web/standalone/server.js +1 -1
  269. package/dist/welcome-screen.js +27 -1
  270. package/dist/worktree-cli.d.ts +1 -0
  271. package/dist/worktree-cli.js +9 -3
  272. package/dist/worktree-status-banner.d.ts +1 -0
  273. package/dist/worktree-status-banner.js +132 -0
  274. package/package.json +1 -3
  275. package/packages/daemon/package.json +2 -2
  276. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  277. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  278. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  279. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  280. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  281. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  282. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  283. package/packages/mcp-server/package.json +2 -2
  284. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  285. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  286. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  287. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  288. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  289. package/packages/native/package.json +1 -1
  290. package/packages/native/tsconfig.tsbuildinfo +1 -1
  291. package/packages/pi-agent-core/package.json +1 -1
  292. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  293. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  294. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  295. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  296. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  297. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  298. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  299. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  300. package/packages/pi-ai/dist/types.d.ts +13 -0
  301. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/types.js.map +1 -1
  303. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  304. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  305. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  306. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  307. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  308. package/packages/pi-ai/package.json +1 -1
  309. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  310. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  311. package/packages/pi-ai/src/types.ts +13 -0
  312. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  313. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  314. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  315. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  316. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  317. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  320. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  321. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  322. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  324. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  326. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  328. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  329. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  330. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  331. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  332. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  333. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  334. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  336. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  337. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  338. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  339. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  340. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  342. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  343. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  344. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  345. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  346. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  347. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  348. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  349. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  350. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  351. package/packages/pi-coding-agent/package.json +1 -1
  352. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  353. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  354. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  355. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  356. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  357. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  358. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  359. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  360. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  361. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  362. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  363. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  364. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  365. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  366. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  367. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  368. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  369. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  370. package/packages/pi-tui/package.json +1 -1
  371. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  372. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  373. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  374. package/packages/rpc-client/package.json +1 -1
  375. package/pkg/package.json +1 -1
  376. package/src/resources/extensions/claude-code-cli/readiness.ts +130 -30
  377. package/src/resources/extensions/google-search/index.ts +2 -9
  378. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  379. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  380. package/src/resources/extensions/gsd/auto/run-unit.ts +3 -1
  381. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  382. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  383. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  384. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  385. package/src/resources/extensions/gsd/auto-prompts.ts +60 -2
  386. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  387. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  388. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  389. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  390. package/src/resources/extensions/gsd/auto-worktree.ts +82 -12
  391. package/src/resources/extensions/gsd/auto.ts +14 -4
  392. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  393. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  394. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  395. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  396. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
  397. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  398. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  399. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
  400. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  401. package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
  402. package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
  403. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  404. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  405. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  406. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  407. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  408. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  409. package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
  410. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  411. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  412. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  413. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  414. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  415. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  416. package/src/resources/extensions/gsd/forensics.ts +12 -7
  417. package/src/resources/extensions/gsd/git-service.ts +13 -5
  418. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  419. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  420. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  421. package/src/resources/extensions/gsd/journal.ts +4 -1
  422. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  423. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  424. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  425. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  426. package/src/resources/extensions/gsd/model-router.ts +172 -9
  427. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  428. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  429. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  430. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  431. package/src/resources/extensions/gsd/preferences.ts +16 -2
  432. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  433. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  434. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  435. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  436. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  437. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  438. package/src/resources/extensions/gsd/state.ts +42 -0
  439. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  440. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +178 -1
  441. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  442. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  443. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  444. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  445. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  446. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
  447. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  448. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
  449. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  450. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  451. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  452. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  453. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  454. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  455. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  456. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  457. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  458. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  459. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  460. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  461. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  462. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  463. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  464. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  465. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  466. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  467. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
  468. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  469. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  470. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  471. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  472. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  473. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  474. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  475. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  476. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  477. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  478. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  479. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  480. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  481. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  482. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  483. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  484. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  485. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  486. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  487. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  488. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  489. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  490. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  491. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  492. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  493. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
  494. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  495. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  496. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  497. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  498. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  499. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  500. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  501. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  502. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  503. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  504. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  505. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  506. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  507. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  508. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  509. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  510. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  511. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  512. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  513. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  514. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  515. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -14
  516. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  517. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  518. package/src/resources/extensions/gsd/worktree.ts +8 -119
  519. package/src/resources/extensions/mcp-client/index.ts +6 -10
  520. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  521. package/src/resources/extensions/ollama/index.ts +16 -2
  522. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  523. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  524. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  525. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  526. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  527. package/src/resources/extensions/subagent/index.ts +165 -7
  528. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  529. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  530. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  531. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  532. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  533. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  534. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  535. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  536. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  537. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  538. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  539. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  540. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  541. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  542. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  543. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  544. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  545. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  546. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  547. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  548. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  549. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  550. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  551. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  552. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  553. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  554. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  555. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  556. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  557. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  558. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → QK8fABiGPmonfTgboN0Y9}/_buildManifest.js +0 -0
  559. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → QK8fABiGPmonfTgboN0Y9}/_ssgManifest.js +0 -0
@@ -1,220 +1,147 @@
1
1
  /**
2
- * Budget Prediction — unit tests for M004/S04.
2
+ * budget-prediction.test.ts — unit tests for budget prediction math
3
+ * (`getAverageCostPerUnitType`, `predictRemainingCost`) exported from
4
+ * `metrics.ts`.
3
5
  *
4
- * Tests prediction math, auto-downgrade logic, and dashboard integration.
5
- * Uses extracted pure functions (avoiding module import chain) and
6
- * source-level structural checks for dashboard/auto.ts integration.
6
+ * The previous version (PR #582, `972dd05f4`) re-implemented both
7
+ * functions inline, citing a `paths.js @gsd/pi-coding-agent` import
8
+ * chain as the reason. That chain concern is no longer valid — the
9
+ * real exports import cleanly from `metrics.ts`. All 10 math tests
10
+ * were then exercising the test's own copy of the functions, not the
11
+ * product code. #4840 documented the false-coverage case.
12
+ *
13
+ * This rewrite imports the real functions, deletes the inline copies,
14
+ * drops the 3 source-grep tests (`metricsSrc.includes(...)`) and the
15
+ * 2 dashboard `includes` tests (dashboard integration should be a
16
+ * behaviour test against the dashboard builder, not a grep), and
17
+ * deletes the synthesized `downgrade:` test that exercised a local
18
+ * closure instead of product code. See #4784 / #4840.
7
19
  */
8
20
 
9
- import test from "node:test";
21
+ import { describe, test } from "node:test";
10
22
  import assert from "node:assert/strict";
11
- import { readFileSync } from "node:fs";
12
- import { join, dirname } from "node:path";
13
- import { fileURLToPath } from "node:url";
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const metricsSrc = readFileSync(join(__dirname, "..", "metrics.ts"), "utf-8");
17
- const dashboardSrc = readFileSync(join(__dirname, "..", "auto-dashboard.ts"), "utf-8");
18
-
19
- // ─── Extract pure functions from metrics.ts source ────────────────────────
20
- // Can't import directly due to paths.js → @gsd/pi-coding-agent import chain.
21
- // Extract and evaluate the pure math functions.
22
-
23
- interface MockUnitMetrics {
24
- type: string;
25
- cost: number;
26
- }
27
-
28
- // Re-implement the functions under test (verified against source below)
29
- function getAverageCostPerUnitType(units: MockUnitMetrics[]): Map<string, number> {
30
- const sums = new Map<string, { total: number; count: number }>();
31
- for (const u of units) {
32
- const entry = sums.get(u.type) ?? { total: 0, count: 0 };
33
- entry.total += u.cost;
34
- entry.count += 1;
35
- sums.set(u.type, entry);
36
- }
37
- const avgs = new Map<string, number>();
38
- for (const [type, { total, count }] of sums) {
39
- avgs.set(type, total / count);
40
- }
41
- return avgs;
42
- }
43
23
 
44
- function predictRemainingCost(
45
- avgCosts: Map<string, number>,
46
- remainingUnits: string[],
47
- fallbackAvg?: number,
48
- ): number {
49
- const allAvgs = [...avgCosts.values()];
50
- const overallAvg = fallbackAvg ?? (allAvgs.length > 0 ? allAvgs.reduce((a, b) => a + b, 0) / allAvgs.length : 0);
51
- let total = 0;
52
- for (const unitType of remainingUnits) {
53
- total += avgCosts.get(unitType) ?? overallAvg;
54
- }
55
- return total;
24
+ import {
25
+ getAverageCostPerUnitType,
26
+ predictRemainingCost,
27
+ } from "../metrics.ts";
28
+ import type { UnitMetrics } from "../metrics.ts";
29
+
30
+ // ─── Fixture helper ───────────────────────────────────────────────────────
31
+ // UnitMetrics has several required fields; this builder lets each test
32
+ // specify only the fields that matter for the cost math.
33
+
34
+ function makeUnit(partial: Partial<UnitMetrics> & { type: string; cost: number }): UnitMetrics {
35
+ return {
36
+ id: "M001/S01/T01",
37
+ model: "test-model",
38
+ startedAt: 0,
39
+ finishedAt: 0,
40
+ tokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
41
+ toolCalls: 0,
42
+ assistantMessages: 0,
43
+ userMessages: 0,
44
+ ...partial,
45
+ };
56
46
  }
57
47
 
58
- // ═══════════════════════════════════════════════════════════════════════════
59
- // Source Verification confirm our re-implementation matches
60
- // ═══════════════════════════════════════════════════════════════════════════
61
-
62
- test("source: metrics.ts exports getAverageCostPerUnitType", () => {
63
- assert.ok(metricsSrc.includes("export function getAverageCostPerUnitType"), "should be exported");
64
- });
65
-
66
- test("source: metrics.ts exports predictRemainingCost", () => {
67
- assert.ok(metricsSrc.includes("export function predictRemainingCost"), "should be exported");
68
- });
69
-
70
- test("source: getAverageCostPerUnitType uses Map<string, number>", () => {
71
- assert.ok(
72
- metricsSrc.includes("Map<string, number>") && metricsSrc.includes("getAverageCostPerUnitType"),
73
- "should return Map<string, number>",
74
- );
75
- });
76
-
77
- // ═══════════════════════════════════════════════════════════════════════════
78
- // Average Cost Per Unit Type
79
- // ═══════════════════════════════════════════════════════════════════════════
80
-
81
- test("avgCost: returns correct averages per unit type", () => {
82
- const units: MockUnitMetrics[] = [
83
- { type: "execute-task", cost: 0.10 },
84
- { type: "execute-task", cost: 0.20 },
85
- { type: "plan-slice", cost: 0.05 },
86
- { type: "plan-slice", cost: 0.15 },
87
- { type: "complete-slice", cost: 0.08 },
88
- ];
89
- const avgs = getAverageCostPerUnitType(units);
90
- assert.ok(Math.abs(avgs.get("execute-task")! - 0.15) < 0.001, "execute-task avg should be 0.15");
91
- assert.ok(Math.abs(avgs.get("plan-slice")! - 0.10) < 0.001, "plan-slice avg should be 0.10");
92
- assert.ok(Math.abs(avgs.get("complete-slice")! - 0.08) < 0.001, "complete-slice avg should be 0.08");
93
- });
94
-
95
- test("avgCost: returns empty map for empty input", () => {
96
- const avgs = getAverageCostPerUnitType([]);
97
- assert.equal(avgs.size, 0);
98
- });
99
-
100
- test("avgCost: single unit per type returns exact cost", () => {
101
- const avgs = getAverageCostPerUnitType([{ type: "execute-task", cost: 0.42 }]);
102
- assert.ok(Math.abs(avgs.get("execute-task")! - 0.42) < 0.001);
103
- });
104
-
105
- // ═══════════════════════════════════════════════════════════════════════════
106
- // Predict Remaining Cost
107
- // ═══════════════════════════════════════════════════════════════════════════
108
-
109
- test("predict: calculates remaining cost from averages", () => {
110
- const avgs = new Map([
111
- ["execute-task", 0.15],
112
- ["plan-slice", 0.10],
113
- ["complete-slice", 0.08],
114
- ]);
115
- const remaining = ["execute-task", "execute-task", "complete-slice"];
116
- const cost = predictRemainingCost(avgs, remaining);
117
- assert.ok(Math.abs(cost - 0.38) < 0.001);
118
- });
119
-
120
- test("predict: uses overall average for unknown unit types", () => {
121
- const avgs = new Map([
122
- ["execute-task", 0.10],
123
- ["plan-slice", 0.20],
124
- ]);
125
- const remaining = ["execute-task", "unknown-type"];
126
- const cost = predictRemainingCost(avgs, remaining);
127
- // unknown: (0.10 + 0.20) / 2 = 0.15 → total 0.10 + 0.15 = 0.25
128
- assert.ok(Math.abs(cost - 0.25) < 0.001);
129
- });
130
-
131
- test("predict: returns 0 for empty remaining", () => {
132
- const avgs = new Map([["execute-task", 0.15]]);
133
- assert.equal(predictRemainingCost(avgs, []), 0);
134
- });
135
-
136
- test("predict: handles no averages with fallback", () => {
137
- const avgs = new Map<string, number>();
138
- const cost = predictRemainingCost(avgs, ["execute-task", "plan-slice"], 0.10);
139
- assert.ok(Math.abs(cost - 0.20) < 0.001);
140
- });
141
-
142
- test("predict: handles no averages and no fallback", () => {
143
- const avgs = new Map<string, number>();
144
- const cost = predictRemainingCost(avgs, ["execute-task"]);
145
- assert.equal(cost, 0);
146
- });
147
-
148
- // ═══════════════════════════════════════════════════════════════════════════
149
- // Dashboard Integration
150
- // ═══════════════════════════════════════════════════════════════════════════
151
-
152
- test("dashboard: AutoDashboardData includes projectedRemainingCost field", () => {
153
- assert.ok(
154
- dashboardSrc.includes("projectedRemainingCost"),
155
- "AutoDashboardData should have projectedRemainingCost field",
156
- );
157
- });
158
-
159
- test("dashboard: AutoDashboardData includes profileDowngraded field", () => {
160
- assert.ok(
161
- dashboardSrc.includes("profileDowngraded"),
162
- "AutoDashboardData should have profileDowngraded field",
163
- );
164
- });
165
-
166
- // ═══════════════════════════════════════════════════════════════════════════
167
- // Budget Prediction — End-to-End Math
168
- // ═══════════════════════════════════════════════════════════════════════════
169
-
170
- test("e2e: budget ceiling exceeded triggers downgrade prediction", () => {
171
- const units: MockUnitMetrics[] = [
172
- { type: "execute-task", cost: 0.50 },
173
- { type: "execute-task", cost: 0.60 },
174
- { type: "plan-slice", cost: 0.30 },
175
- { type: "complete-slice", cost: 0.20 },
176
- ];
177
- const totalSpent = units.reduce((sum, u) => sum + u.cost, 0); // 1.60
178
- const avgs = getAverageCostPerUnitType(units);
179
- const remaining = ["execute-task", "execute-task", "execute-task"];
180
- const predictedRemaining = predictRemainingCost(avgs, remaining);
181
- const predictedTotal = totalSpent + predictedRemaining;
182
- const budgetCeiling = 2.50;
183
- assert.ok(predictedTotal > budgetCeiling, "should predict budget exhaustion");
184
- });
185
-
186
- test("e2e: budget ceiling not exceeded does not trigger", () => {
187
- const units: MockUnitMetrics[] = [
188
- { type: "execute-task", cost: 0.10 },
189
- { type: "plan-slice", cost: 0.05 },
190
- ];
191
- const totalSpent = units.reduce((sum, u) => sum + u.cost, 0); // 0.15
192
- const avgs = getAverageCostPerUnitType(units);
193
- const remaining = ["execute-task", "complete-slice"];
194
- const predictedRemaining = predictRemainingCost(avgs, remaining);
195
- const predictedTotal = totalSpent + predictedRemaining;
196
- const budgetCeiling = 5.00;
197
- assert.ok(predictedTotal <= budgetCeiling, "should not predict budget exhaustion");
198
- });
199
-
200
- // ═══════════════════════════════════════════════════════════════════════════
201
- // Downgrade Logic
202
- // ═══════════════════════════════════════════════════════════════════════════
203
-
204
- test("downgrade: one-way per D048 — downgrade should not be reversible", () => {
205
- // Simulate: first prediction triggers downgrade, second doesn't reverse it
206
- let downgraded = false;
207
-
208
- function checkDowngrade(predictedTotal: number, ceiling: number) {
209
- if (!downgraded && predictedTotal > ceiling) {
210
- downgraded = true;
211
- }
212
- // Never reverse — per D048
213
- }
214
-
215
- checkDowngrade(3.00, 2.50); // triggers
216
- assert.ok(downgraded, "should downgrade when prediction exceeds ceiling");
217
-
218
- checkDowngrade(1.50, 2.50); // doesn't reverse
219
- assert.ok(downgraded, "should stay downgraded (one-way per D048)");
48
+ describe("getAverageCostPerUnitType (metrics.ts)", () => {
49
+ test("returns correct averages per unit type", () => {
50
+ const units = [
51
+ makeUnit({ type: "execute-task", cost: 0.1 }),
52
+ makeUnit({ type: "execute-task", cost: 0.2 }),
53
+ makeUnit({ type: "plan-slice", cost: 0.05 }),
54
+ makeUnit({ type: "plan-slice", cost: 0.15 }),
55
+ makeUnit({ type: "complete-slice", cost: 0.08 }),
56
+ ];
57
+ const avgs = getAverageCostPerUnitType(units);
58
+ assert.ok(Math.abs(avgs.get("execute-task")! - 0.15) < 0.001, "execute-task avg");
59
+ assert.ok(Math.abs(avgs.get("plan-slice")! - 0.10) < 0.001, "plan-slice avg");
60
+ assert.ok(Math.abs(avgs.get("complete-slice")! - 0.08) < 0.001, "complete-slice avg");
61
+ });
62
+
63
+ test("returns empty map for empty input", () => {
64
+ assert.equal(getAverageCostPerUnitType([]).size, 0);
65
+ });
66
+
67
+ test("single unit per type returns exact cost", () => {
68
+ const avgs = getAverageCostPerUnitType([makeUnit({ type: "execute-task", cost: 0.42 })]);
69
+ assert.ok(Math.abs(avgs.get("execute-task")! - 0.42) < 0.001);
70
+ });
71
+ });
72
+
73
+ describe("predictRemainingCost (metrics.ts)", () => {
74
+ test("calculates remaining cost from known averages", () => {
75
+ const avgs = new Map([
76
+ ["execute-task", 0.15],
77
+ ["plan-slice", 0.10],
78
+ ["complete-slice", 0.08],
79
+ ]);
80
+ const remaining = ["execute-task", "execute-task", "complete-slice"];
81
+ const cost = predictRemainingCost(avgs, remaining);
82
+ // 2 × 0.15 + 0.08 = 0.38
83
+ assert.ok(Math.abs(cost - 0.38) < 0.001);
84
+ });
85
+
86
+ test("uses overall average for unknown unit types", () => {
87
+ const avgs = new Map([
88
+ ["execute-task", 0.10],
89
+ ["plan-slice", 0.20],
90
+ ]);
91
+ const remaining = ["execute-task", "unknown-type"];
92
+ // unknown: (0.10 + 0.20) / 2 = 0.15 total 0.10 + 0.15 = 0.25
93
+ assert.ok(Math.abs(predictRemainingCost(avgs, remaining) - 0.25) < 0.001);
94
+ });
95
+
96
+ test("returns 0 for empty remaining list", () => {
97
+ const avgs = new Map([["execute-task", 0.15]]);
98
+ assert.equal(predictRemainingCost(avgs, []), 0);
99
+ });
100
+
101
+ test("uses fallback when no averages are known", () => {
102
+ const cost = predictRemainingCost(new Map(), ["execute-task", "plan-slice"], 0.10);
103
+ assert.ok(Math.abs(cost - 0.20) < 0.001);
104
+ });
105
+
106
+ test("returns 0 when no averages and no fallback", () => {
107
+ assert.equal(predictRemainingCost(new Map(), ["execute-task"]), 0);
108
+ });
109
+ });
110
+
111
+ describe("end-to-end budget prediction (composes the real functions)", () => {
112
+ test("budget ceiling exceeded is detectable from real averages + projection", () => {
113
+ const units = [
114
+ makeUnit({ type: "execute-task", cost: 0.5 }),
115
+ makeUnit({ type: "execute-task", cost: 0.6 }),
116
+ makeUnit({ type: "plan-slice", cost: 0.3 }),
117
+ makeUnit({ type: "complete-slice", cost: 0.2 }),
118
+ ];
119
+ const totalSpent = units.reduce((sum, u) => sum + u.cost, 0); // 1.60
120
+ const avgs = getAverageCostPerUnitType(units);
121
+ const predicted = predictRemainingCost(avgs, [
122
+ "execute-task",
123
+ "execute-task",
124
+ "execute-task",
125
+ ]);
126
+ // avg execute-task = 0.55, predicted remaining = 3 × 0.55 = 1.65
127
+ // total = 1.60 + 1.65 = 3.25 > 2.50 ceiling
128
+ assert.ok(
129
+ totalSpent + predicted > 2.5,
130
+ "spent + predicted should exceed test ceiling",
131
+ );
132
+ });
133
+
134
+ test("budget ceiling not exceeded when averages stay low", () => {
135
+ const units = [
136
+ makeUnit({ type: "execute-task", cost: 0.1 }),
137
+ makeUnit({ type: "plan-slice", cost: 0.05 }),
138
+ ];
139
+ const totalSpent = units.reduce((sum, u) => sum + u.cost, 0); // 0.15
140
+ const avgs = getAverageCostPerUnitType(units);
141
+ const predicted = predictRemainingCost(avgs, ["execute-task", "complete-slice"]);
142
+ assert.ok(
143
+ totalSpent + predicted <= 5.0,
144
+ "spent + predicted should stay under test ceiling",
145
+ );
146
+ });
220
147
  });
@@ -2,12 +2,56 @@
2
2
  //
3
3
  // Guards the skill-trigger table in system-context.ts against accidental
4
4
  // regression. Every entry must have a non-empty trigger + skill, and the
5
- // skills added in PR #4505 must remain present.
5
+ // skills added in PR #4505 and PR #5060 must remain present.
6
6
  import { test } from 'node:test';
7
7
  import assert from 'node:assert/strict';
8
8
 
9
9
  import { BUNDLED_SKILL_TRIGGERS } from '../bootstrap/system-context.ts';
10
10
 
11
+ const PR_4505_BUNDLED_SKILLS = [
12
+ 'review',
13
+ 'test',
14
+ 'lint',
15
+ 'make-interfaces-feel-better',
16
+ 'accessibility',
17
+ 'grill-me',
18
+ 'design-an-interface',
19
+ 'tdd',
20
+ 'write-milestone-brief',
21
+ 'decompose-into-slices',
22
+ 'spike-wrap-up',
23
+ 'verify-before-complete',
24
+ 'create-mcp-server',
25
+ 'write-docs',
26
+ 'forensics',
27
+ 'handoff',
28
+ 'security-review',
29
+ 'api-design',
30
+ 'dependency-upgrade',
31
+ 'observability',
32
+ ] as const;
33
+
34
+ const PR_5060_BUNDLED_SKILLS = [
35
+ 'react-best-practices',
36
+ 'core-web-vitals',
37
+ 'github-workflows',
38
+ 'web-quality-audit',
39
+ 'agent-browser',
40
+ 'web-design-guidelines',
41
+ 'userinterface-wiki',
42
+ 'create-skill',
43
+ 'create-gsd-extension',
44
+ 'create-workflow',
45
+ 'code-optimizer',
46
+ ] as const;
47
+
48
+ function assertBundledSkillsRegistered(label: string, expectedSkills: readonly string[]): void {
49
+ const registered = new Set(BUNDLED_SKILL_TRIGGERS.map(e => e.skill));
50
+ for (const skill of expectedSkills) {
51
+ assert.ok(registered.has(skill), `${label}: expected bundled skill "${skill}" to be registered`);
52
+ }
53
+ }
54
+
11
55
  test('BUNDLED_SKILL_TRIGGERS: every entry has a non-empty trigger and skill', () => {
12
56
  assert.ok(BUNDLED_SKILL_TRIGGERS.length > 0, 'table should not be empty');
13
57
  for (const { trigger, skill } of BUNDLED_SKILL_TRIGGERS) {
@@ -17,32 +61,11 @@ test('BUNDLED_SKILL_TRIGGERS: every entry has a non-empty trigger and skill', ()
17
61
  });
18
62
 
19
63
  test('BUNDLED_SKILL_TRIGGERS: PR #4505 bundled skills are present', () => {
20
- const expected = [
21
- 'review',
22
- 'test',
23
- 'lint',
24
- 'make-interfaces-feel-better',
25
- 'accessibility',
26
- 'grill-me',
27
- 'design-an-interface',
28
- 'tdd',
29
- 'write-milestone-brief',
30
- 'decompose-into-slices',
31
- 'spike-wrap-up',
32
- 'verify-before-complete',
33
- 'create-mcp-server',
34
- 'write-docs',
35
- 'forensics',
36
- 'handoff',
37
- 'security-review',
38
- 'api-design',
39
- 'dependency-upgrade',
40
- 'observability',
41
- ];
42
- const registered = new Set(BUNDLED_SKILL_TRIGGERS.map(e => e.skill));
43
- for (const skill of expected) {
44
- assert.ok(registered.has(skill), `expected bundled skill "${skill}" to be registered`);
45
- }
64
+ assertBundledSkillsRegistered('PR #4505', PR_4505_BUNDLED_SKILLS);
65
+ });
66
+
67
+ test('BUNDLED_SKILL_TRIGGERS: PR #5060 previously-unexposed skills are present', () => {
68
+ assertBundledSkillsRegistered('PR #5060', PR_5060_BUNDLED_SKILLS);
46
69
  });
47
70
 
48
71
  test('BUNDLED_SKILL_TRIGGERS: skill ids are unique', () => {
@@ -0,0 +1,58 @@
1
+ // GSD2 — Regression test for Issue #4946 isVersionGreater (commands-extensions.ts)
2
+ //
3
+ // Covers the inline npm-version comparator that replaced the `semver` import in
4
+ // commands-extensions.ts. The original import broke `tsc -p tsconfig.json` whenever
5
+ // `@types/semver` failed to install — the file is type-checked transitively despite
6
+ // being under the `src/resources` exclude. The replacement keeps the same comparison
7
+ // semantics for the realistic input space (npm extension version strings) without
8
+ // pulling in the full semver type surface.
9
+
10
+ import test, { describe } from "node:test";
11
+ import assert from "node:assert/strict";
12
+ import { isVersionGreater } from "../commands-extensions.ts";
13
+
14
+ describe("isVersionGreater — npm extension version comparison (#4946)", () => {
15
+ test("strictly greater patch beats lesser patch", () => {
16
+ assert.equal(isVersionGreater("1.2.4", "1.2.3"), true);
17
+ assert.equal(isVersionGreater("1.2.3", "1.2.4"), false);
18
+ });
19
+
20
+ test("equal versions are not strictly greater", () => {
21
+ assert.equal(isVersionGreater("1.2.3", "1.2.3"), false);
22
+ });
23
+
24
+ test("numeric (not lexicographic) component comparison", () => {
25
+ // Lexicographic compare would say "1.10.0" < "1.9.0".
26
+ assert.equal(isVersionGreater("1.10.0", "1.9.0"), true);
27
+ assert.equal(isVersionGreater("1.9.0", "1.10.0"), false);
28
+ });
29
+
30
+ test("major bump beats minor and patch differences", () => {
31
+ assert.equal(isVersionGreater("2.0.0", "1.99.99"), true);
32
+ assert.equal(isVersionGreater("1.99.99", "2.0.0"), false);
33
+ });
34
+
35
+ test("missing trailing components default to zero", () => {
36
+ assert.equal(isVersionGreater("1.2", "1.1.9"), true);
37
+ assert.equal(isVersionGreater("1", "0.9.9"), true);
38
+ assert.equal(isVersionGreater("1.2", "1.2.0"), false);
39
+ });
40
+
41
+ test("release version beats prerelease at the same release number", () => {
42
+ assert.equal(isVersionGreater("1.0.0", "1.0.0-beta.1"), true);
43
+ assert.equal(isVersionGreater("1.0.0-beta.1", "1.0.0"), false);
44
+ });
45
+
46
+ test("prerelease ordering: beta.2 > beta.1, rc.1 > beta.9", () => {
47
+ assert.equal(isVersionGreater("1.0.0-beta.2", "1.0.0-beta.1"), true);
48
+ assert.equal(isVersionGreater("1.0.0-rc.1", "1.0.0-beta.9"), true);
49
+ });
50
+
51
+ test("non-numeric junk in components doesn't crash — coerces to 0", () => {
52
+ // Defensive: we don't throw on garbage input; we treat unparseable
53
+ // components as 0. This matches the behaviour the extension installer
54
+ // can rely on without surfacing an error to the user.
55
+ assert.equal(isVersionGreater("1.x.0", "1.0.0"), false);
56
+ assert.equal(isVersionGreater("abc", "0.0.1"), false);
57
+ });
58
+ });
@@ -0,0 +1,48 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+
4
+ import {
5
+ formatCleanKeepReason,
6
+ type WorktreeStatus,
7
+ } from "../commands-worktree.ts";
8
+
9
+ function mkStatus(over: Partial<WorktreeStatus>): WorktreeStatus {
10
+ const name = over.name ?? "feat-x";
11
+ return {
12
+ name,
13
+ path: `/repo/.gsd/worktrees/${name}`,
14
+ branch: `gsd/${name}`,
15
+ exists: true,
16
+ filesChanged: 0,
17
+ linesAdded: 0,
18
+ linesRemoved: 0,
19
+ uncommitted: false,
20
+ commits: 0,
21
+ ...over,
22
+ };
23
+ }
24
+
25
+ test("clean keep reason shows uncommitted-only worktrees clearly", () => {
26
+ const reason = formatCleanKeepReason(mkStatus({ uncommitted: true }));
27
+ assert.equal(reason, "uncommitted changes");
28
+ });
29
+
30
+ test("clean keep reason includes uncommitted context with changed files", () => {
31
+ const reason = formatCleanKeepReason(mkStatus({ filesChanged: 2, uncommitted: true }));
32
+ assert.equal(reason, "2 changed files, uncommitted");
33
+ });
34
+
35
+ test("clean keep reason flags missing directory with prune hint", () => {
36
+ const reason = formatCleanKeepReason(mkStatus({ exists: false }));
37
+ assert.equal(reason, "directory missing — run 'git worktree prune' to unregister");
38
+ });
39
+
40
+ test("clean keep reason reports changed files without uncommitted suffix", () => {
41
+ const reason = formatCleanKeepReason(mkStatus({ filesChanged: 2, uncommitted: false }));
42
+ assert.equal(reason, "2 changed files");
43
+ });
44
+
45
+ test("clean keep reason uses singular form for a single changed file", () => {
46
+ const reason = formatCleanKeepReason(mkStatus({ filesChanged: 1, uncommitted: false }));
47
+ assert.equal(reason, "1 changed file");
48
+ });