gsd-pi 2.78.1-dev.84a383f51 → 2.78.1

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 (474) hide show
  1. package/README.md +7 -7
  2. package/dist/cli.js +55 -95
  3. package/dist/headless-query.d.ts +0 -22
  4. package/dist/headless-query.js +4 -24
  5. package/dist/headless.d.ts +0 -10
  6. package/dist/headless.js +1 -16
  7. package/dist/loader.js +10 -7
  8. package/dist/onboarding.d.ts +0 -10
  9. package/dist/onboarding.js +2 -2
  10. package/dist/provider-migrations.d.ts +2 -2
  11. package/dist/provider-migrations.js +2 -5
  12. package/dist/resource-loader.d.ts +2 -5
  13. package/dist/resource-loader.js +5 -28
  14. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +601 -0
  15. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +651 -0
  16. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +91 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +0 -23
  18. package/dist/resources/extensions/gsd/auto/phases.js +2 -2
  19. package/dist/resources/extensions/gsd/auto/run-unit.js +1 -3
  20. package/dist/resources/extensions/gsd/auto/session.js +0 -3
  21. package/dist/resources/extensions/gsd/auto-recovery.js +4 -43
  22. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  23. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  24. package/dist/resources/extensions/gsd/auto-worktree.js +0 -30
  25. package/dist/resources/extensions/gsd/auto.js +5 -14
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -14
  27. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +5 -7
  28. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  29. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +4 -5
  30. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -94
  31. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +6 -11
  32. package/dist/resources/extensions/gsd/bootstrap/system-context.js +8 -34
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +2 -38
  34. package/dist/resources/extensions/gsd/commands/catalog.js +5 -69
  35. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -22
  36. package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -3
  37. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -10
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -4
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +1 -39
  41. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  42. package/dist/resources/extensions/gsd/forensics.js +2 -2
  43. package/dist/resources/extensions/gsd/git-service.js +5 -12
  44. package/dist/resources/extensions/gsd/gsd-db.js +2 -11
  45. package/dist/resources/extensions/gsd/guided-flow.js +23 -23
  46. package/dist/resources/extensions/gsd/memory-store.js +31 -66
  47. package/dist/resources/extensions/gsd/model-router.js +9 -114
  48. package/dist/resources/extensions/gsd/native-git-bridge.js +1 -7
  49. package/dist/resources/extensions/gsd/preferences-models.js +15 -91
  50. package/dist/resources/extensions/gsd/preferences-types.js +0 -2
  51. package/dist/resources/extensions/gsd/preferences-validation.js +0 -32
  52. package/dist/resources/extensions/gsd/preferences.js +3 -5
  53. package/dist/resources/extensions/gsd/prompt-loader.js +12 -23
  54. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -9
  55. package/dist/resources/extensions/gsd/state.js +0 -42
  56. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
  57. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
  58. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +112 -0
  59. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +23 -0
  60. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +5 -0
  61. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -18
  62. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  63. package/dist/resources/extensions/gsd/watch/header-renderer.js +1 -3
  64. package/dist/resources/extensions/gsd/worktree-command.js +46 -26
  65. package/dist/resources/extensions/mcp-client/index.js +3 -6
  66. package/dist/resources/extensions/slash-commands/create-extension.js +22 -36
  67. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -9
  68. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  69. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  70. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  71. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  72. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  73. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  74. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  75. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
  76. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  77. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +608 -0
  78. package/dist/rtk-shared.d.ts +0 -3
  79. package/dist/rtk-shared.js +0 -17
  80. package/dist/rtk.d.ts +5 -2
  81. package/dist/rtk.js +20 -3
  82. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  85. package/dist/web/standalone/.next/build-manifest.json +4 -4
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/react-loadable-manifest.json +4 -44
  88. package/dist/web/standalone/.next/required-server-files.json +3 -3
  89. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  100. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  148. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  158. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -4
  164. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  178. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  180. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/index.html +1 -1
  194. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  195. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  196. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  197. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  198. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  199. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/page.js +2 -2
  201. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  203. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  204. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  205. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  207. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware.js +2 -2
  209. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  211. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  212. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  213. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  214. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  215. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  216. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +20 -0
  217. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  218. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +1 -0
  223. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  224. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  225. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  226. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  227. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  228. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  229. package/dist/web/standalone/package.json +1 -2
  230. package/dist/web/standalone/server.js +1 -1
  231. package/package.json +1 -1
  232. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  233. package/packages/mcp-server/dist/workflow-tools.js +46 -74
  234. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  235. package/packages/mcp-server/src/workflow-tools.test.ts +0 -26
  236. package/packages/mcp-server/src/workflow-tools.ts +58 -93
  237. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  238. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  239. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  240. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -48
  241. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  242. package/packages/pi-ai/dist/types.d.ts +0 -13
  243. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  244. package/packages/pi-ai/dist/types.js.map +1 -1
  245. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  246. package/packages/pi-ai/dist/utils/repair-tool-json.js +3 -24
  247. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  248. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +0 -26
  249. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  250. package/packages/pi-ai/src/providers/anthropic-shared.ts +20 -52
  251. package/packages/pi-ai/src/types.ts +0 -13
  252. package/packages/pi-ai/src/utils/repair-tool-json.ts +3 -24
  253. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +0 -32
  254. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  255. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/agent-session.js +0 -6
  257. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/messages.js +0 -4
  260. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -19
  262. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -10
  264. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/model-registry.js +0 -18
  266. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +0 -13
  268. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -20
  270. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -14
  274. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  275. package/packages/pi-coding-agent/src/core/agent-session.ts +0 -7
  276. package/packages/pi-coding-agent/src/core/messages.ts +0 -4
  277. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -32
  278. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -21
  279. package/packages/pi-coding-agent/src/core/system-prompt.ts +15 -33
  280. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -17
  281. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  282. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  283. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +3 -17
  284. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  285. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +3 -20
  286. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  287. package/src/resources/extensions/gsd/auto/loop.ts +2 -24
  288. package/src/resources/extensions/gsd/auto/phases.ts +3 -3
  289. package/src/resources/extensions/gsd/auto/run-unit.ts +1 -3
  290. package/src/resources/extensions/gsd/auto/session.ts +0 -3
  291. package/src/resources/extensions/gsd/auto/types.ts +0 -1
  292. package/src/resources/extensions/gsd/auto-recovery.ts +8 -46
  293. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  294. package/src/resources/extensions/gsd/auto-tool-tracking.ts +4 -2
  295. package/src/resources/extensions/gsd/auto-worktree.ts +0 -38
  296. package/src/resources/extensions/gsd/auto.ts +4 -14
  297. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -15
  298. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +7 -8
  299. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  300. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +9 -10
  301. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -102
  302. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +6 -12
  303. package/src/resources/extensions/gsd/bootstrap/system-context.ts +8 -39
  304. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +11 -39
  305. package/src/resources/extensions/gsd/commands/catalog.ts +5 -75
  306. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -22
  307. package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -3
  308. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -15
  309. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  310. package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -4
  311. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +1 -39
  312. package/src/resources/extensions/gsd/doctor-types.ts +1 -3
  313. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  314. package/src/resources/extensions/gsd/forensics.ts +2 -2
  315. package/src/resources/extensions/gsd/git-service.ts +5 -13
  316. package/src/resources/extensions/gsd/gsd-db.ts +2 -12
  317. package/src/resources/extensions/gsd/guided-flow.ts +25 -25
  318. package/src/resources/extensions/gsd/memory-store.ts +28 -81
  319. package/src/resources/extensions/gsd/model-router.ts +9 -172
  320. package/src/resources/extensions/gsd/native-git-bridge.ts +1 -7
  321. package/src/resources/extensions/gsd/preferences-models.ts +15 -101
  322. package/src/resources/extensions/gsd/preferences-types.ts +0 -6
  323. package/src/resources/extensions/gsd/preferences-validation.ts +0 -35
  324. package/src/resources/extensions/gsd/preferences.ts +2 -16
  325. package/src/resources/extensions/gsd/prompt-loader.ts +12 -26
  326. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -9
  327. package/src/resources/extensions/gsd/state.ts +0 -42
  328. package/src/resources/extensions/gsd/templates/PREFERENCES.md +0 -1
  329. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +1 -178
  330. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +0 -58
  331. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +5 -9
  332. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -21
  333. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  334. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +211 -138
  335. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +59 -142
  336. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +4 -7
  337. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +32 -89
  338. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +22 -0
  339. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +23 -41
  340. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +43 -3
  341. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +3 -5
  342. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +87 -22
  343. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +118 -7
  344. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +47 -0
  345. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +60 -18
  346. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +76 -14
  347. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +75 -0
  348. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +83 -22
  349. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +63 -1
  350. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +1 -26
  351. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +0 -30
  352. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +4 -14
  353. package/src/resources/extensions/gsd/tests/health-widget.test.ts +12 -22
  354. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +1 -64
  355. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +0 -22
  356. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +23 -0
  357. package/src/resources/extensions/gsd/tests/memory-store.test.ts +0 -128
  358. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +1 -33
  359. package/src/resources/extensions/gsd/tests/model-router.test.ts +8 -169
  360. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +0 -8
  361. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +43 -32
  362. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +10 -4
  363. package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -127
  364. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +0 -16
  365. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +0 -7
  366. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  367. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +19 -168
  368. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +1 -7
  369. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -23
  370. package/src/resources/extensions/gsd/tests/token-profile.test.ts +4 -51
  371. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +16 -7
  372. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +7 -5
  373. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +1 -15
  374. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  375. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +0 -15
  376. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -17
  377. package/src/resources/extensions/gsd/unit-context-manifest.ts +8 -8
  378. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  379. package/src/resources/extensions/gsd/watch/header-renderer.ts +1 -3
  380. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  381. package/src/resources/extensions/gsd/worktree-command.ts +44 -31
  382. package/src/resources/extensions/mcp-client/index.ts +3 -6
  383. package/src/resources/extensions/slash-commands/create-extension.ts +24 -38
  384. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -9
  385. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  386. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  387. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  388. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  389. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  390. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  391. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  392. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  393. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  394. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +12 -32
  395. package/dist/cli-policy.d.ts +0 -13
  396. package/dist/cli-policy.js +0 -17
  397. package/dist/resources/.managed-resources-content-hash +0 -1
  398. package/dist/resources/extensions/gsd/auto-runtime-state.js +0 -31
  399. package/dist/resources/extensions/gsd/milestone-id-reservation.js +0 -36
  400. package/dist/resources/extensions/gsd/worktree-session-state.js +0 -33
  401. package/dist/runtime-checks.d.ts +0 -27
  402. package/dist/runtime-checks.js +0 -38
  403. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  404. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +0 -1
  405. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +0 -1
  406. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +0 -1
  407. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +0 -1
  408. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +0 -1
  409. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +0 -10
  410. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +0 -2
  411. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +0 -20
  412. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  413. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +0 -1
  414. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  415. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  416. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +0 -1
  417. package/dist/worktree-status-banner.d.ts +0 -1
  418. package/dist/worktree-status-banner.js +0 -132
  419. package/packages/mcp-server/dist/alias-telemetry.d.ts +0 -8
  420. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +0 -1
  421. package/packages/mcp-server/dist/alias-telemetry.js +0 -30
  422. package/packages/mcp-server/dist/alias-telemetry.js.map +0 -1
  423. package/packages/mcp-server/src/alias-telemetry.test.ts +0 -78
  424. package/packages/mcp-server/src/alias-telemetry.ts +0 -30
  425. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +0 -2
  426. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +0 -1
  427. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +0 -231
  428. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +0 -1
  429. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +0 -289
  430. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +0 -37
  431. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +0 -1
  432. package/packages/pi-coding-agent/dist/core/token-telemetry.js +0 -49
  433. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +0 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +0 -2
  435. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +0 -1
  436. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +0 -133
  437. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +0 -1
  438. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +0 -2
  439. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +0 -1
  440. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +0 -78
  441. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +0 -1
  442. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +0 -2
  443. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +0 -1
  444. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +0 -181
  445. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +0 -1
  446. package/packages/pi-coding-agent/src/core/token-telemetry.ts +0 -77
  447. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +0 -212
  448. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +0 -102
  449. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +0 -200
  450. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +0 -2
  451. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +0 -1
  452. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +0 -161
  453. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +0 -1
  454. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +0 -219
  455. package/src/resources/extensions/gsd/auto-runtime-state.ts +0 -51
  456. package/src/resources/extensions/gsd/milestone-id-reservation.ts +0 -47
  457. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +0 -116
  458. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +0 -100
  459. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +0 -93
  460. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +0 -47
  461. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +0 -63
  462. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +0 -81
  463. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +0 -57
  464. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +0 -145
  465. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +0 -124
  466. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +0 -152
  467. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +0 -50
  468. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +0 -93
  469. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +0 -101
  470. package/src/resources/extensions/gsd/worktree-session-state.ts +0 -35
  471. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +0 -91
  472. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +0 -58
  473. /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_buildManifest.js +0 -0
  474. /package/dist/web/standalone/.next/static/{UF5VF4F1tB0miEtJS7LyX → 7afp7gq8-DVbxum83zRQ-}/_ssgManifest.js +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"leak-fixes-runtime.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/leak-fixes-runtime.test.ts"],"names":[],"mappings":"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","sourcesContent":["// Runtime regression tests for the long-running-session leak fixes.\n//\n// Replaces the source-grep file `src/tests/session-memory-leaks.test.ts`\n// (deleted in #4875, tracked as #4873). The previous tests asserted on\n// identifier presence (`_prevRender`, `_lastMessage`, `MAX_CHAT_COMPONENTS`)\n// in source — a regression that set `MAX_CHAT_COMPONENTS = Number.MAX_SAFE_INTEGER`\n// or replaced `setText` with an inline mutation would still pass.\n//\n// Each test below drives the actual component through a long-running scenario\n// and asserts on observable behaviour.\n\nimport { describe, it, mock, beforeEach, afterEach } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { Container } from \"../../tui.js\";\nimport { Loader } from \"../loader.js\";\nimport { Text } from \"../text.js\";\n\ninterface MockTui {\n\trequestRender: ReturnType<typeof mock.fn>;\n}\n\nfunction makeMockTUI(): MockTui {\n\treturn { requestRender: mock.fn() };\n}\n\n// ─── Container render-skip ──────────────────────────────────────────────\n\ndescribe(\"Container.render skips work when output is unchanged\", () => {\n\tit(\"returns the SAME array reference across two renders with no changes\", () => {\n\t\t// The container caches `_prevRender` so doRender() can short-circuit\n\t\t// the post-processing (image-line scan, applyLineResets, line diffs).\n\t\t// The contract for the optimization is reference equality of the\n\t\t// returned array — that's what the consumer in tui.ts checks.\n\t\tconst c = new Container();\n\t\tc.addChild(new Text(\"hello\", 0, 0));\n\n\t\tconst first = c.render(20);\n\t\tconst second = c.render(20);\n\t\tassert.strictEqual(\n\t\t\tsecond,\n\t\t\tfirst,\n\t\t\t\"Container must return the same array reference when content is unchanged \" +\n\t\t\t\t\"(reference equality is the consumer-visible contract for the skip)\",\n\t\t);\n\t});\n\n\tit(\"returns a DIFFERENT array reference after addChild invalidates the cache\", () => {\n\t\t// If a regression caused `_prevRender` to never reset, downstream\n\t\t// rendering would skip post-processing for new components — visible\n\t\t// as missing/stale UI. Behaviourally we observe that adding a child\n\t\t// breaks the reference-equality contract on the next render.\n\t\tconst c = new Container();\n\t\tc.addChild(new Text(\"a\", 0, 0));\n\t\tconst first = c.render(20);\n\t\tc.addChild(new Text(\"b\", 0, 0));\n\t\tconst second = c.render(20);\n\t\tassert.notStrictEqual(\n\t\t\tsecond,\n\t\t\tfirst,\n\t\t\t\"adding a child must invalidate the cached render reference\",\n\t\t);\n\t});\n\n\tit(\"returns a different reference after content changes\", () => {\n\t\tconst t = new Text(\"hello\", 0, 0);\n\t\tconst c = new Container();\n\t\tc.addChild(t);\n\n\t\tconst first = c.render(20);\n\t\tt.setText(\"world\");\n\t\tconst second = c.render(20);\n\t\tassert.notStrictEqual(\n\t\t\tsecond,\n\t\t\tfirst,\n\t\t\t\"changing a child's text must produce a fresh array (not the cached one)\",\n\t\t);\n\t});\n});\n\n// ─── Loader frame isolation ─────────────────────────────────────────────\n\ndescribe(\"Loader does not mutate Text cache on every spinner tick\", () => {\n\tlet tui: MockTui;\n\tlet loader: Loader;\n\n\tbeforeEach(() => {\n\t\ttui = makeMockTUI();\n\t\tmock.timers.enable({ apis: [\"setInterval\"] });\n\t});\n\n\tafterEach(() => {\n\t\ttry {\n\t\t\tloader?.stop();\n\t\t} catch {\n\t\t\t/* best-effort */\n\t\t}\n\t\tmock.timers.reset();\n\t});\n\n\tit(\"does not invalidate Text's render cache across N spinner ticks\", () => {\n\t\t// Loader extends Text. Text caches its rendered lines keyed by\n\t\t// (text, width). The leak was: the old Loader called setText()\n\t\t// on every 80ms tick, which always cleared the cache, forcing a\n\t\t// re-wrap of the message text.\n\t\t// Behavioural test: render the loader, capture the cached array\n\t\t// reference returned by Text.render, advance many ticks, and\n\t\t// assert the underlying Text cache was NOT invalidated (we observe\n\t\t// this via reference equality of the cached lines slice in the\n\t\t// returned array — the second `result[*]` segment from super.render\n\t\t// stays identity-stable when the cache survives).\n\t\tloader = new Loader(tui as never, (s) => s, (s) => s, \"the-message\");\n\n\t\tconst before = loader.render(40);\n\t\t// Run 50 frame intervals — the spinner should rotate, but the\n\t\t// underlying message text wrapping must not change.\n\t\tmock.timers.tick(80 * 50);\n\t\tconst after = loader.render(40);\n\n\t\t// The message portion (everything after the first `\"\"` padding line\n\t\t// and after the spinner glyph + space prefix on the first content\n\t\t// line) must be byte-identical across renders.\n\t\tassert.equal(before.length, after.length, \"render shape stable across ticks\");\n\t\t// Trailing message lines (index 2 onwards) come straight from Text's\n\t\t// cache without any spinner mutation. They must be reference-equal\n\t\t// substrings — same string contents byte-for-byte.\n\t\tfor (let i = 2; i < before.length; i++) {\n\t\t\tassert.equal(\n\t\t\t\tafter[i],\n\t\t\t\tbefore[i],\n\t\t\t\t`message line ${i} must remain byte-identical across spinner ticks ` +\n\t\t\t\t\t`(cache must not be invalidated by frame rotation)`,\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"setMessage invalidates Text cache and a new message is reflected\", () => {\n\t\t// Quiescence is conditional on the message being unchanged — we\n\t\t// must still see updates when it actually changes. This is the\n\t\t// counter-test that prevents a false-positive \"cache always stable\"\n\t\t// fix that would freeze the loader text.\n\t\tloader = new Loader(tui as never, (s) => s, (s) => s, \"first\");\n\t\tconst beforeFirstRender = loader.render(40).join(\"\\n\");\n\t\tloader.setMessage(\"second\");\n\t\tconst afterChange = loader.render(40).join(\"\\n\");\n\t\tassert.ok(afterChange.includes(\"second\"), \"new message must render\");\n\t\tassert.ok(!afterChange.includes(\"first\") || beforeFirstRender !== afterChange,\n\t\t\t\"render output must change when message changes\");\n\t});\n});\n\n// ─── Text.setText early-return guard ────────────────────────────────────\n\ndescribe(\"Text.setText returns early when value is unchanged\", () => {\n\tit(\"does not invalidate the cached render when setText receives the same value\", () => {\n\t\t// The setText early-return is the runtime guard that keeps the\n\t\t// Loader-and-Text cache stable. We observe it via reference equality\n\t\t// of the rendered output across a setText(SAME) call.\n\t\tconst t = new Text(\"identical\", 0, 0);\n\t\tconst first = t.render(30);\n\t\tt.setText(\"identical\"); // same value — must NOT clear the cache\n\t\tconst second = t.render(30);\n\t\tassert.strictEqual(\n\t\t\tsecond,\n\t\t\tfirst,\n\t\t\t\"setText with an unchanged value must leave the render cache intact\",\n\t\t);\n\t});\n\n\tit(\"invalidates cache when the value actually changes\", () => {\n\t\tconst t = new Text(\"one\", 0, 0);\n\t\tconst first = t.render(30);\n\t\tt.setText(\"two\");\n\t\tconst second = t.render(30);\n\t\tassert.notStrictEqual(\n\t\t\tsecond,\n\t\t\tfirst,\n\t\t\t\"setText with a new value must produce a fresh render result\",\n\t\t);\n\t});\n});\n\n// ─── Heap growth bound (gated on --expose-gc) ───────────────────────────\n\ndescribe(\"Long-running render loop does not leak heap (forced-GC bound)\", () => {\n\tconst hasGc = typeof (globalThis as any).gc === \"function\";\n\n\tit(\n\t\t\"renders a Container 5000 times with stable heapUsed (within 2x baseline)\",\n\t\t{ skip: !hasGc ? \"requires --expose-gc to drive deterministic GC between snapshots\" : false },\n\t\t() => {\n\t\t\t// This is the on-the-wire memory-soak test. The naive version\n\t\t\t// (no forced GC) is flaky because Node's GC is opportunistic;\n\t\t\t// any background allocation can shift heapUsed past an absolute\n\t\t\t// bound. We instead force GC between snapshots and assert a\n\t\t\t// RELATIVE bound: post-iteration heap must be within 2x of the\n\t\t\t// post-warmup baseline.\n\t\t\tconst gc = (globalThis as any).gc as () => void;\n\n\t\t\tconst c = new Container();\n\t\t\tconst t = new Text(\"steady-state\", 0, 0);\n\t\t\tc.addChild(t);\n\n\t\t\t// Warm up so the JIT and any lazy initial allocations settle.\n\t\t\tfor (let i = 0; i < 200; i++) c.render(40);\n\t\t\tgc();\n\t\t\tconst baseline = process.memoryUsage().heapUsed;\n\n\t\t\tfor (let i = 0; i < 5000; i++) c.render(40);\n\t\t\tgc();\n\t\t\tconst after = process.memoryUsage().heapUsed;\n\n\t\t\tassert.ok(\n\t\t\t\tafter < baseline * 2,\n\t\t\t\t`heapUsed must stay within 2x baseline after 5000 renders ` +\n\t\t\t\t\t`(baseline=${baseline}B, after=${after}B, ratio=${(after / baseline).toFixed(2)})`,\n\t\t\t);\n\t\t},\n\t);\n});\n"]}
@@ -1,219 +0,0 @@
1
- // Runtime regression tests for the long-running-session leak fixes.
2
- //
3
- // Replaces the source-grep file `src/tests/session-memory-leaks.test.ts`
4
- // (deleted in #4875, tracked as #4873). The previous tests asserted on
5
- // identifier presence (`_prevRender`, `_lastMessage`, `MAX_CHAT_COMPONENTS`)
6
- // in source — a regression that set `MAX_CHAT_COMPONENTS = Number.MAX_SAFE_INTEGER`
7
- // or replaced `setText` with an inline mutation would still pass.
8
- //
9
- // Each test below drives the actual component through a long-running scenario
10
- // and asserts on observable behaviour.
11
-
12
- import { describe, it, mock, beforeEach, afterEach } from "node:test";
13
- import assert from "node:assert/strict";
14
- import { Container } from "../../tui.js";
15
- import { Loader } from "../loader.js";
16
- import { Text } from "../text.js";
17
-
18
- interface MockTui {
19
- requestRender: ReturnType<typeof mock.fn>;
20
- }
21
-
22
- function makeMockTUI(): MockTui {
23
- return { requestRender: mock.fn() };
24
- }
25
-
26
- // ─── Container render-skip ──────────────────────────────────────────────
27
-
28
- describe("Container.render skips work when output is unchanged", () => {
29
- it("returns the SAME array reference across two renders with no changes", () => {
30
- // The container caches `_prevRender` so doRender() can short-circuit
31
- // the post-processing (image-line scan, applyLineResets, line diffs).
32
- // The contract for the optimization is reference equality of the
33
- // returned array — that's what the consumer in tui.ts checks.
34
- const c = new Container();
35
- c.addChild(new Text("hello", 0, 0));
36
-
37
- const first = c.render(20);
38
- const second = c.render(20);
39
- assert.strictEqual(
40
- second,
41
- first,
42
- "Container must return the same array reference when content is unchanged " +
43
- "(reference equality is the consumer-visible contract for the skip)",
44
- );
45
- });
46
-
47
- it("returns a DIFFERENT array reference after addChild invalidates the cache", () => {
48
- // If a regression caused `_prevRender` to never reset, downstream
49
- // rendering would skip post-processing for new components — visible
50
- // as missing/stale UI. Behaviourally we observe that adding a child
51
- // breaks the reference-equality contract on the next render.
52
- const c = new Container();
53
- c.addChild(new Text("a", 0, 0));
54
- const first = c.render(20);
55
- c.addChild(new Text("b", 0, 0));
56
- const second = c.render(20);
57
- assert.notStrictEqual(
58
- second,
59
- first,
60
- "adding a child must invalidate the cached render reference",
61
- );
62
- });
63
-
64
- it("returns a different reference after content changes", () => {
65
- const t = new Text("hello", 0, 0);
66
- const c = new Container();
67
- c.addChild(t);
68
-
69
- const first = c.render(20);
70
- t.setText("world");
71
- const second = c.render(20);
72
- assert.notStrictEqual(
73
- second,
74
- first,
75
- "changing a child's text must produce a fresh array (not the cached one)",
76
- );
77
- });
78
- });
79
-
80
- // ─── Loader frame isolation ─────────────────────────────────────────────
81
-
82
- describe("Loader does not mutate Text cache on every spinner tick", () => {
83
- let tui: MockTui;
84
- let loader: Loader;
85
-
86
- beforeEach(() => {
87
- tui = makeMockTUI();
88
- mock.timers.enable({ apis: ["setInterval"] });
89
- });
90
-
91
- afterEach(() => {
92
- try {
93
- loader?.stop();
94
- } catch {
95
- /* best-effort */
96
- }
97
- mock.timers.reset();
98
- });
99
-
100
- it("does not invalidate Text's render cache across N spinner ticks", () => {
101
- // Loader extends Text. Text caches its rendered lines keyed by
102
- // (text, width). The leak was: the old Loader called setText()
103
- // on every 80ms tick, which always cleared the cache, forcing a
104
- // re-wrap of the message text.
105
- // Behavioural test: render the loader, capture the cached array
106
- // reference returned by Text.render, advance many ticks, and
107
- // assert the underlying Text cache was NOT invalidated (we observe
108
- // this via reference equality of the cached lines slice in the
109
- // returned array — the second `result[*]` segment from super.render
110
- // stays identity-stable when the cache survives).
111
- loader = new Loader(tui as never, (s) => s, (s) => s, "the-message");
112
-
113
- const before = loader.render(40);
114
- // Run 50 frame intervals — the spinner should rotate, but the
115
- // underlying message text wrapping must not change.
116
- mock.timers.tick(80 * 50);
117
- const after = loader.render(40);
118
-
119
- // The message portion (everything after the first `""` padding line
120
- // and after the spinner glyph + space prefix on the first content
121
- // line) must be byte-identical across renders.
122
- assert.equal(before.length, after.length, "render shape stable across ticks");
123
- // Trailing message lines (index 2 onwards) come straight from Text's
124
- // cache without any spinner mutation. They must be reference-equal
125
- // substrings — same string contents byte-for-byte.
126
- for (let i = 2; i < before.length; i++) {
127
- assert.equal(
128
- after[i],
129
- before[i],
130
- `message line ${i} must remain byte-identical across spinner ticks ` +
131
- `(cache must not be invalidated by frame rotation)`,
132
- );
133
- }
134
- });
135
-
136
- it("setMessage invalidates Text cache and a new message is reflected", () => {
137
- // Quiescence is conditional on the message being unchanged — we
138
- // must still see updates when it actually changes. This is the
139
- // counter-test that prevents a false-positive "cache always stable"
140
- // fix that would freeze the loader text.
141
- loader = new Loader(tui as never, (s) => s, (s) => s, "first");
142
- const beforeFirstRender = loader.render(40).join("\n");
143
- loader.setMessage("second");
144
- const afterChange = loader.render(40).join("\n");
145
- assert.ok(afterChange.includes("second"), "new message must render");
146
- assert.ok(!afterChange.includes("first") || beforeFirstRender !== afterChange,
147
- "render output must change when message changes");
148
- });
149
- });
150
-
151
- // ─── Text.setText early-return guard ────────────────────────────────────
152
-
153
- describe("Text.setText returns early when value is unchanged", () => {
154
- it("does not invalidate the cached render when setText receives the same value", () => {
155
- // The setText early-return is the runtime guard that keeps the
156
- // Loader-and-Text cache stable. We observe it via reference equality
157
- // of the rendered output across a setText(SAME) call.
158
- const t = new Text("identical", 0, 0);
159
- const first = t.render(30);
160
- t.setText("identical"); // same value — must NOT clear the cache
161
- const second = t.render(30);
162
- assert.strictEqual(
163
- second,
164
- first,
165
- "setText with an unchanged value must leave the render cache intact",
166
- );
167
- });
168
-
169
- it("invalidates cache when the value actually changes", () => {
170
- const t = new Text("one", 0, 0);
171
- const first = t.render(30);
172
- t.setText("two");
173
- const second = t.render(30);
174
- assert.notStrictEqual(
175
- second,
176
- first,
177
- "setText with a new value must produce a fresh render result",
178
- );
179
- });
180
- });
181
-
182
- // ─── Heap growth bound (gated on --expose-gc) ───────────────────────────
183
-
184
- describe("Long-running render loop does not leak heap (forced-GC bound)", () => {
185
- const hasGc = typeof (globalThis as any).gc === "function";
186
-
187
- it(
188
- "renders a Container 5000 times with stable heapUsed (within 2x baseline)",
189
- { skip: !hasGc ? "requires --expose-gc to drive deterministic GC between snapshots" : false },
190
- () => {
191
- // This is the on-the-wire memory-soak test. The naive version
192
- // (no forced GC) is flaky because Node's GC is opportunistic;
193
- // any background allocation can shift heapUsed past an absolute
194
- // bound. We instead force GC between snapshots and assert a
195
- // RELATIVE bound: post-iteration heap must be within 2x of the
196
- // post-warmup baseline.
197
- const gc = (globalThis as any).gc as () => void;
198
-
199
- const c = new Container();
200
- const t = new Text("steady-state", 0, 0);
201
- c.addChild(t);
202
-
203
- // Warm up so the JIT and any lazy initial allocations settle.
204
- for (let i = 0; i < 200; i++) c.render(40);
205
- gc();
206
- const baseline = process.memoryUsage().heapUsed;
207
-
208
- for (let i = 0; i < 5000; i++) c.render(40);
209
- gc();
210
- const after = process.memoryUsage().heapUsed;
211
-
212
- assert.ok(
213
- after < baseline * 2,
214
- `heapUsed must stay within 2x baseline after 5000 renders ` +
215
- `(baseline=${baseline}B, after=${after}B, ratio=${(after / baseline).toFixed(2)})`,
216
- );
217
- },
218
- );
219
- });
@@ -1,51 +0,0 @@
1
- // GSD auto-mode runtime state
2
- import { AutoSession } from "./auto/session.js";
3
- import type { CurrentUnit } from "./auto/session.js";
4
- import {
5
- isDeterministicPolicyError,
6
- isQueuedUserMessageSkip,
7
- isToolInvocationError,
8
- markToolEnd as markTrackedToolEnd,
9
- markToolStart as markTrackedToolStart,
10
- } from "./auto-tool-tracking.js";
11
-
12
- export const autoSession = new AutoSession();
13
-
14
- export type AutoRuntimeSnapshot = {
15
- active: boolean;
16
- paused: boolean;
17
- currentUnit: CurrentUnit | null;
18
- basePath: string;
19
- };
20
-
21
- export function getAutoRuntimeSnapshot(): AutoRuntimeSnapshot {
22
- return {
23
- active: autoSession.active,
24
- paused: autoSession.paused,
25
- currentUnit: autoSession.currentUnit ? { ...autoSession.currentUnit } : null,
26
- basePath: autoSession.basePath,
27
- };
28
- }
29
-
30
- export function isAutoActive(): boolean {
31
- return autoSession.active;
32
- }
33
-
34
- export function isAutoPaused(): boolean {
35
- return autoSession.paused;
36
- }
37
-
38
- export function markToolStart(toolCallId: string, toolName?: string): void {
39
- markTrackedToolStart(toolCallId, autoSession.active, toolName);
40
- }
41
-
42
- export function markToolEnd(toolCallId: string): void {
43
- markTrackedToolEnd(toolCallId);
44
- }
45
-
46
- export function recordToolInvocationError(toolName: string, errorMsg: string): void {
47
- if (!autoSession.active) return;
48
- if (isToolInvocationError(errorMsg) || isQueuedUserMessageSkip(errorMsg) || isDeterministicPolicyError(errorMsg)) {
49
- autoSession.lastToolInvocationError = `${toolName}: ${errorMsg}`;
50
- }
51
- }
@@ -1,47 +0,0 @@
1
- import { isDbAvailable, getAllMilestones } from "./gsd-db.js";
2
- import {
3
- getReservedMilestoneIds,
4
- milestoneIdSort,
5
- nextMilestoneId,
6
- reserveMilestoneId,
7
- } from "./milestone-ids.js";
8
- import { isReusableGhostMilestone } from "./state.js";
9
-
10
- function getDatabaseMilestoneIds(): string[] {
11
- if (!isDbAvailable()) return [];
12
- return getAllMilestones().map((milestone) => milestone.id);
13
- }
14
-
15
- /**
16
- * Generate the next milestone ID, accounting for DB rows and in-process
17
- * reservations, and reserve it.
18
- */
19
- export function nextMilestoneIdReserved(
20
- existingIds: string[],
21
- uniqueEnabled: boolean,
22
- basePath?: string,
23
- ): string {
24
- const reservedIds = getReservedMilestoneIds();
25
- const allIds = [
26
- ...new Set([
27
- ...existingIds,
28
- ...reservedIds,
29
- ...getDatabaseMilestoneIds(),
30
- ]),
31
- ];
32
-
33
- if (basePath) {
34
- const sorted = [...allIds].sort(milestoneIdSort);
35
- for (const candidate of sorted) {
36
- if (reservedIds.has(candidate)) continue;
37
- if (isReusableGhostMilestone(basePath, candidate)) {
38
- reserveMilestoneId(candidate);
39
- return candidate;
40
- }
41
- }
42
- }
43
-
44
- const id = nextMilestoneId(allIds, uniqueEnabled);
45
- reserveMilestoneId(id);
46
- return id;
47
- }
@@ -1,116 +0,0 @@
1
- // GSD Extension — Regression test for #4996: deferred milestone dir creation
2
- // Verifies that showHeadlessMilestoneCreation does not pre-create the milestone
3
- // directory before the discuss flow runs. The dir should only appear after a
4
- // writer (saveArtifactToDb / atomicWriteAsync) emits the first artifact.
5
-
6
- import { describe, it, beforeEach, afterEach } from "node:test";
7
- import assert from "node:assert/strict";
8
- import { mkdtempSync, mkdirSync, existsSync, rmSync, readFileSync } from "node:fs";
9
- import { dirname, join } from "node:path";
10
- import { tmpdir } from "node:os";
11
- import { fileURLToPath } from "node:url";
12
-
13
- import { isReusableGhostMilestone } from "../state.ts";
14
- import { nextMilestoneIdReserved } from "../milestone-id-reservation.ts";
15
- import { clearReservedMilestoneIds, findMilestoneIds } from "../milestone-ids.ts";
16
- import { invalidateAllCaches } from "../cache.ts";
17
- import { closeDatabase, openDatabase } from "../gsd-db.ts";
18
-
19
- const __dirname = dirname(fileURLToPath(import.meta.url));
20
- const GUIDED_FLOW_PATH = join(__dirname, "..", "guided-flow.ts");
21
-
22
- function getShowHeadlessBody(): string {
23
- const source = readFileSync(GUIDED_FLOW_PATH, "utf-8");
24
- const fnStart = source.indexOf("export async function showHeadlessMilestoneCreation");
25
- assert.ok(fnStart > -1, "showHeadlessMilestoneCreation must exist in guided-flow.ts");
26
- const nextExport = source.indexOf("\nexport ", fnStart + 1);
27
- return source.slice(fnStart, nextExport === -1 ? source.length : nextExport);
28
- }
29
-
30
- function makeBase(prefix = "gsd-deferred-dir-"): string {
31
- const base = mkdtempSync(join(tmpdir(), prefix));
32
- mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
33
- return base;
34
- }
35
-
36
- describe("showHeadlessMilestoneCreation source guard (#4996)", () => {
37
- it("does not call mkdirSync in the headless milestone creation path", () => {
38
- const body = getShowHeadlessBody();
39
- assert.doesNotMatch(
40
- body,
41
- /\bmkdirSync\s*\(/,
42
- "showHeadlessMilestoneCreation must not pre-create milestone directories",
43
- );
44
- });
45
-
46
- it("does not call mkdir or mkdirp before dispatchWorkflow", () => {
47
- const body = getShowHeadlessBody();
48
- const dispatchIdx = body.indexOf("dispatchWorkflow");
49
- assert.ok(dispatchIdx > -1, "dispatchWorkflow must be present");
50
-
51
- const beforeDispatch = body.slice(0, dispatchIdx);
52
- assert.doesNotMatch(
53
- beforeDispatch,
54
- /\b(?:mkdir|mkdirp)\s*\(/,
55
- "showHeadlessMilestoneCreation must defer directory creation until artifact write",
56
- );
57
- });
58
- });
59
-
60
- describe("deferred milestone dir creation (#4996)", () => {
61
- let base: string;
62
-
63
- beforeEach(() => {
64
- clearReservedMilestoneIds();
65
- });
66
-
67
- afterEach(() => {
68
- try { closeDatabase(); } catch { /* ignore */ }
69
- try { invalidateAllCaches(); } catch { /* ignore */ }
70
- try { clearReservedMilestoneIds(); } catch { /* ignore */ }
71
- try { rmSync(base, { recursive: true, force: true }); } catch { /* ignore */ }
72
- });
73
-
74
- it("(a) fresh project: milestones dir has no M001 entry before any discuss flow", () => {
75
- base = makeBase();
76
- const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
77
- assert.equal(nextId, "M001", "reservation should choose M001 for a fresh project");
78
-
79
- const ids = findMilestoneIds(base);
80
- assert.equal(ids.length, 0, "no milestone dirs should exist before any discuss flow");
81
-
82
- // And specifically M001 should not exist
83
- const m001Dir = join(base, ".gsd", "milestones", "M001");
84
- assert.ok(!existsSync(m001Dir), "M001 dir must not exist before the discuss flow runs");
85
- });
86
-
87
- it("(b) abandoned discuss flow leaves no orphan: isReusableGhostMilestone returns false for non-existent dir", () => {
88
- base = makeBase();
89
- const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
90
- assert.equal(nextId, "M001", "reservation should not require a pre-created directory");
91
-
92
- const m001Dir = join(base, ".gsd", "milestones", "M001");
93
- assert.ok(!existsSync(m001Dir), "no M001 dir should exist");
94
- assert.equal(isReusableGhostMilestone(base, "M001"), false, "non-existent milestone should not be reusable");
95
- // findMilestoneIds only returns dirs that exist
96
- const ids = findMilestoneIds(base);
97
- assert.ok(!ids.includes("M001"), "M001 should not appear in findMilestoneIds when no dir exists");
98
- });
99
-
100
- it("(c) a stub dir left from a previous bug IS reusable but a newly-generated ID with no dir is not in the ghost list", () => {
101
- base = makeBase();
102
- openDatabase(join(base, ".gsd", "gsd.db"));
103
- // Create a stub to represent a pre-existing phantom
104
- mkdirSync(join(base, ".gsd", "milestones", "M001", "slices"), { recursive: true });
105
-
106
- // isReusableGhostMilestone identifies the orphaned stub
107
- assert.ok(isReusableGhostMilestone(base, "M001"), "pre-existing stub should be identified as reusable ghost");
108
- const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
109
- assert.equal(nextId, "M001", "reservation should reuse the pre-existing ghost");
110
-
111
- // The new ID (M002, which would be max+1 in this scenario but ghost reuse returns M001)
112
- // should not have a dir
113
- const m002Dir = join(base, ".gsd", "milestones", "M002");
114
- assert.ok(!existsSync(m002Dir), "a freshly-requested ID should have no dir until first artifact write");
115
- });
116
- });
@@ -1,100 +0,0 @@
1
- // GSD Extension — Regression test for #4996: doctor orphan milestone dir check
2
- // Verifies that checkRuntimeHealth reports orphan_milestone_dir for empty stub
3
- // dirs with no DB row, does not report populated dirs, and does not report
4
- // legitimate in-flight worktree-only milestone dirs.
5
-
6
- import { describe, it, afterEach } from "node:test";
7
- import assert from "node:assert/strict";
8
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
9
- import { join } from "node:path";
10
- import { tmpdir } from "node:os";
11
-
12
- import { checkRuntimeHealth } from "../doctor-runtime-checks.ts";
13
- import {
14
- openDatabase,
15
- closeDatabase,
16
- insertMilestone,
17
- } from "../gsd-db.ts";
18
- import { invalidateAllCaches } from "../cache.ts";
19
- import type { DoctorIssue, DoctorIssueCode } from "../doctor-types.ts";
20
-
21
- function makeBase(prefix = "gsd-doctor-orphan-"): string {
22
- const base = mkdtempSync(join(tmpdir(), prefix));
23
- mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
24
- return base;
25
- }
26
-
27
- function stubDir(base: string, mid: string): void {
28
- mkdirSync(join(base, ".gsd", "milestones", mid, "slices"), { recursive: true });
29
- }
30
-
31
- function populateDir(base: string, mid: string): void {
32
- mkdirSync(join(base, ".gsd", "milestones", mid), { recursive: true });
33
- writeFileSync(join(base, ".gsd", "milestones", mid, `${mid}-CONTEXT.md`), `# ${mid}\n`);
34
- }
35
-
36
- describe("gsd_doctor orphan milestone directory check (#4996)", () => {
37
- let base: string;
38
-
39
- afterEach(() => {
40
- try { closeDatabase(); } catch { /* ignore */ }
41
- try { invalidateAllCaches(); } catch { /* ignore */ }
42
- try { rmSync(base, { recursive: true, force: true }); } catch { /* ignore */ }
43
- });
44
-
45
- it("(a) empty stub dir with no DB row is reported as orphan_milestone_dir", async () => {
46
- base = makeBase();
47
- stubDir(base, "M003");
48
-
49
- const issues: DoctorIssue[] = [];
50
- const fixes: string[] = [];
51
- await checkRuntimeHealth(base, issues, fixes, () => false);
52
-
53
- const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
54
- assert.ok(orphan, "should report orphan_milestone_dir for empty stub");
55
- assert.equal(orphan?.severity, "warning");
56
- assert.equal(orphan?.fixable, true);
57
- assert.ok(orphan?.message.includes("M003"), "message should name the milestone");
58
- });
59
-
60
- it("(b) populated milestone dir is NOT reported", async () => {
61
- base = makeBase();
62
- populateDir(base, "M001");
63
-
64
- const issues: DoctorIssue[] = [];
65
- const fixes: string[] = [];
66
- await checkRuntimeHealth(base, issues, fixes, () => false);
67
-
68
- const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M001");
69
- assert.ok(!orphan, "populated milestone dir must not be reported as orphan");
70
- });
71
-
72
- it("(c) worktree-only milestone (no content files, no DB row, but worktree exists) is NOT reported", async () => {
73
- base = makeBase();
74
- stubDir(base, "M003");
75
- // Simulate a legitimate in-flight worktree
76
- mkdirSync(join(base, ".gsd", "worktrees", "M003"), { recursive: true });
77
-
78
- const issues: DoctorIssue[] = [];
79
- const fixes: string[] = [];
80
- await checkRuntimeHealth(base, issues, fixes, () => false);
81
-
82
- const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
83
- assert.ok(!orphan, "milestone with a worktree must not be reported as orphan");
84
- });
85
-
86
- it("(d) queued DB row (in-flight ID) is NOT reported as orphan", async () => {
87
- base = makeBase();
88
- stubDir(base, "M003");
89
- const dbPath = join(base, ".gsd", "gsd.db");
90
- openDatabase(dbPath);
91
- insertMilestone({ id: "M003", status: "queued" });
92
-
93
- const issues: DoctorIssue[] = [];
94
- const fixes: string[] = [];
95
- await checkRuntimeHealth(base, issues, fixes, () => false);
96
-
97
- const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
98
- assert.ok(!orphan, "queued DB row must block orphan report (in-flight race protection)");
99
- });
100
- });
@@ -1,93 +0,0 @@
1
- // GSD Extension — Regression test for #4996: ensurePreconditions phantom dir guard
2
- // Verifies that ensurePreconditions does not create milestone directories for
3
- // forward-referenced slice unit IDs when the milestone has no DB row.
4
-
5
- import { describe, it, afterEach } from "node:test";
6
- import assert from "node:assert/strict";
7
- import { mkdtempSync, mkdirSync, writeFileSync, existsSync, rmSync } from "node:fs";
8
- import { join } from "node:path";
9
- import { tmpdir } from "node:os";
10
-
11
- import { ensurePreconditions } from "../auto.ts";
12
- import {
13
- openDatabase,
14
- closeDatabase,
15
- insertMilestone,
16
- } from "../gsd-db.ts";
17
-
18
- import type { GSDState } from "../types.ts";
19
-
20
- function makeBase(prefix = "gsd-precond-"): string {
21
- const base = mkdtempSync(join(tmpdir(), prefix));
22
- mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
23
- return base;
24
- }
25
-
26
- function makeMinimalState(): GSDState {
27
- return {
28
- activeMilestone: null,
29
- activeSlice: null,
30
- activeTask: null,
31
- phase: "planning",
32
- recentDecisions: [],
33
- blockers: [],
34
- nextAction: "",
35
- registry: [],
36
- };
37
- }
38
-
39
- describe("ensurePreconditions phantom-dir guard (#4996)", () => {
40
- let base: string;
41
-
42
- afterEach(() => {
43
- try { closeDatabase(); } catch { /* ignore */ }
44
- try { rmSync(base, { recursive: true, force: true }); } catch { /* ignore */ }
45
- });
46
-
47
- it("(a) slice unit ID for unknown milestone does NOT create dirs when no DB row exists", () => {
48
- base = makeBase();
49
- const state = makeMinimalState();
50
-
51
- ensurePreconditions("execute-task", "M003/S01", base, state);
52
-
53
- const milestoneDir = join(base, ".gsd", "milestones", "M003");
54
- assert.ok(!existsSync(milestoneDir), "M003 dir must not be created for phantom slice dispatch");
55
- });
56
-
57
- it("(b) slice unit ID for milestone with DB row DOES create dirs", () => {
58
- base = makeBase();
59
- const dbPath = join(base, ".gsd", "gsd.db");
60
- openDatabase(dbPath);
61
- insertMilestone({ id: "M003", status: "active" });
62
- const state = makeMinimalState();
63
-
64
- ensurePreconditions("execute-task", "M003/S01", base, state);
65
-
66
- const milestoneDir = join(base, ".gsd", "milestones", "M003");
67
- assert.ok(existsSync(milestoneDir), "M003 dir must be created when DB row exists");
68
- });
69
-
70
- it("(c) slice unit ID for existing milestone dir with CONTEXT.md content file uses normal scaffolding", () => {
71
- base = makeBase();
72
- const mid = "M003";
73
- const milestoneDir = join(base, ".gsd", "milestones", mid);
74
- mkdirSync(milestoneDir, { recursive: true });
75
- writeFileSync(join(milestoneDir, `${mid}-CONTEXT.md`), "# Context\n");
76
- const state = makeMinimalState();
77
-
78
- ensurePreconditions("execute-task", "M003/S01", base, state);
79
-
80
- const slicesDir = join(milestoneDir, "slices");
81
- assert.ok(existsSync(slicesDir), "existing milestone dir should allow slice scaffolding");
82
- });
83
-
84
- it("(d) milestone-only unit ID (no slice) still creates dir even with no DB row", () => {
85
- base = makeBase();
86
- const state = makeMinimalState();
87
-
88
- ensurePreconditions("discuss-milestone", "M003", base, state);
89
-
90
- const milestoneDir = join(base, ".gsd", "milestones", "M003");
91
- assert.ok(existsSync(milestoneDir), "M003 dir must be created for milestone-only dispatch");
92
- });
93
- });