gsd-pi 2.80.0-dev.710c06e97 → 2.80.0-dev.7582bf37a

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 (685) hide show
  1. package/README.md +4 -2
  2. package/dist/claude-cli-check.d.ts +30 -0
  3. package/dist/claude-cli-check.js +18 -7
  4. package/dist/cli.js +0 -19
  5. package/dist/headless-query.d.ts +10 -0
  6. package/dist/headless-query.js +6 -4
  7. package/dist/loader-entrypoint.d.ts +8 -0
  8. package/dist/loader-entrypoint.js +27 -0
  9. package/dist/loader.js +2 -11
  10. package/dist/mcp-server.d.ts +1 -0
  11. package/dist/mcp-server.js +6 -3
  12. package/dist/resources/.managed-resources-content-hash +1 -1
  13. package/dist/resources/GSD-WORKFLOW.md +2 -2
  14. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +40 -3
  16. package/dist/resources/extensions/github-sync/sync.js +4 -1
  17. package/dist/resources/extensions/gsd/auto/loop.js +103 -9
  18. package/dist/resources/extensions/gsd/auto/phases.js +240 -139
  19. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  20. package/dist/resources/extensions/gsd/auto/run-unit.js +22 -30
  21. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  22. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  23. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  24. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  25. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  26. package/dist/resources/extensions/gsd/auto-post-unit.js +104 -86
  27. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  28. package/dist/resources/extensions/gsd/auto-recovery.js +174 -10
  29. package/dist/resources/extensions/gsd/auto-start.js +240 -15
  30. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  31. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +209 -81
  33. package/dist/resources/extensions/gsd/auto.js +168 -45
  34. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +99 -10
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
  36. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +30 -20
  38. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
  39. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
  40. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
  41. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  42. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +319 -54
  43. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
  44. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  45. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +19 -2
  46. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  47. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  48. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  49. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  50. package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
  51. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  52. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  53. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  54. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  55. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  56. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  57. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  58. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  59. package/dist/resources/extensions/gsd/detection.js +106 -0
  60. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  61. package/dist/resources/extensions/gsd/git-service.js +73 -5
  62. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  63. package/dist/resources/extensions/gsd/guided-flow.js +143 -48
  64. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  65. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  66. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  67. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  68. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  69. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  70. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  71. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  72. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  73. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  74. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +27 -23
  75. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  77. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  81. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  82. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  83. package/dist/resources/extensions/gsd/quick.js +34 -2
  84. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  85. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  86. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  87. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
  88. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  89. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  90. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  91. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  92. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  93. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  94. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  95. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  96. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  97. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  98. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  99. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  100. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  101. package/dist/resources/extensions/gsd/worktree-resolver.js +90 -22
  102. package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  103. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
  106. package/dist/web/standalone/.next/build-manifest.json +3 -3
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  109. package/dist/web/standalone/.next/required-server-files.json +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/index.html +1 -1
  129. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  130. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  131. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  132. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
  137. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/middleware.js +3 -3
  140. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  141. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  142. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  143. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  144. package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
  145. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  146. package/dist/web/standalone/server.js +1 -1
  147. package/dist/welcome-screen.d.ts +2 -0
  148. package/dist/welcome-screen.js +9 -7
  149. package/package.json +6 -4
  150. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  151. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  152. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  153. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  154. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  155. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  156. package/packages/native/tsconfig.tsbuildinfo +1 -1
  157. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  158. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  159. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  160. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  161. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  162. package/packages/pi-agent-core/dist/agent.js +2 -0
  163. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  164. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  165. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  166. package/packages/pi-agent-core/dist/index.js +2 -0
  167. package/packages/pi-agent-core/dist/index.js.map +1 -1
  168. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  169. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  170. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  171. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  172. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  173. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  174. package/packages/pi-agent-core/dist/types.js.map +1 -1
  175. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  176. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  177. package/packages/pi-agent-core/src/agent.ts +8 -0
  178. package/packages/pi-agent-core/src/index.ts +2 -0
  179. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  180. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  181. package/packages/pi-agent-core/src/types.ts +14 -0
  182. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  183. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  184. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  185. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  186. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  187. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  188. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  189. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  190. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  191. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  192. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  193. package/packages/pi-ai/dist/types.d.ts +2 -0
  194. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  195. package/packages/pi-ai/dist/types.js.map +1 -1
  196. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  197. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  198. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  199. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  200. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  201. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  202. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  203. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  204. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  205. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  206. package/packages/pi-ai/src/types.ts +3 -0
  207. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  208. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  209. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  210. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  211. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  212. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +30 -1
  214. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +17 -0
  216. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  217. package/packages/pi-coding-agent/dist/core/agent-session.js +52 -7
  218. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +78 -0
  220. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  222. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  224. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  226. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  227. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  228. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  229. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  230. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  231. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  232. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  233. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  234. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  235. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  236. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  237. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  239. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  241. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  243. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  245. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +41 -3
  247. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  250. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  252. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  253. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  254. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  255. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  256. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/sdk.js +81 -4
  258. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  260. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  262. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  264. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  266. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  268. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  270. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  272. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  274. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  276. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  278. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  280. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  282. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  284. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  286. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  288. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  290. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  292. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  294. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  296. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  298. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  299. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  300. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  302. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  304. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  306. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  307. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  308. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  309. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  310. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  311. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  312. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  313. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  314. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  316. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  319. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +137 -19
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +2 -2
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +2 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +32 -7
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +18 -0
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +225 -16
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  335. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +85 -2
  336. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
  338. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  340. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +22 -0
  342. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  343. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  345. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  346. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +21 -0
  347. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  349. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  350. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
  351. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  352. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  354. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  355. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  356. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +40 -1
  357. package/packages/pi-coding-agent/src/core/agent-session.ts +59 -7
  358. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +91 -0
  359. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  360. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  361. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  362. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  363. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  364. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  365. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  366. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -2
  367. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  368. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  369. package/packages/pi-coding-agent/src/core/sdk.ts +92 -4
  370. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  371. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  372. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  373. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  374. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  375. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  376. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  377. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  378. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  379. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  380. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  381. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  382. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  383. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  384. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  385. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  386. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  387. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +185 -19
  388. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +2 -2
  389. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  390. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +2 -1
  391. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +41 -10
  392. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +260 -16
  393. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
  394. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +107 -3
  395. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +24 -0
  396. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  397. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +25 -0
  398. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
  399. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  400. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  401. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/tui.js +18 -8
  403. package/packages/pi-tui/dist/tui.js.map +1 -1
  404. package/packages/pi-tui/src/tui.ts +20 -8
  405. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  406. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  407. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  408. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  409. package/src/resources/GSD-WORKFLOW.md +2 -2
  410. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  411. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +42 -3
  412. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +67 -0
  413. package/src/resources/extensions/github-sync/sync.ts +8 -1
  414. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  415. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  416. package/src/resources/extensions/gsd/auto/loop.ts +134 -16
  417. package/src/resources/extensions/gsd/auto/phases.ts +328 -200
  418. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  419. package/src/resources/extensions/gsd/auto/run-unit.ts +28 -30
  420. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  421. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  422. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  423. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  424. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  425. package/src/resources/extensions/gsd/auto-post-unit.ts +117 -88
  426. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  427. package/src/resources/extensions/gsd/auto-recovery.ts +185 -7
  428. package/src/resources/extensions/gsd/auto-start.ts +293 -21
  429. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  430. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  431. package/src/resources/extensions/gsd/auto-worktree.ts +241 -72
  432. package/src/resources/extensions/gsd/auto.ts +220 -40
  433. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -8
  434. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
  435. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
  436. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +32 -19
  437. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
  438. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
  439. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
  440. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  441. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +369 -54
  442. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
  443. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  444. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -2
  445. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  446. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  447. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  448. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  449. package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
  450. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  451. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  452. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  453. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  454. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  455. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  456. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  457. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  458. package/src/resources/extensions/gsd/detection.ts +128 -0
  459. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  460. package/src/resources/extensions/gsd/git-service.ts +87 -10
  461. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  462. package/src/resources/extensions/gsd/guided-flow.ts +169 -55
  463. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  464. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  465. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  466. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  467. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  468. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  469. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  470. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  471. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  472. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  473. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  474. package/src/resources/extensions/gsd/prompts/complete-milestone.md +27 -23
  475. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  476. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  477. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  478. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  479. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  480. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  481. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  482. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  483. package/src/resources/extensions/gsd/quick.ts +37 -2
  484. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  485. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  486. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  487. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  488. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  489. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  490. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  491. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +433 -11
  492. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  493. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  494. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  495. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +160 -11
  496. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  497. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  498. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +139 -2
  499. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  500. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  501. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  502. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  503. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  504. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
  505. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  506. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  507. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  508. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  509. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  510. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  511. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  512. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  513. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  514. package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
  515. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  516. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  517. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  518. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  519. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  520. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
  521. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  522. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  523. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  524. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  525. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  526. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
  527. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  528. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  529. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  530. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  531. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  532. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
  533. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  534. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  535. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  536. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  537. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  538. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  539. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  540. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  541. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  542. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  543. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  544. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  545. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  546. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  547. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  548. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  549. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  550. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  551. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  552. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
  553. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
  554. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  555. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +66 -0
  556. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  557. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  558. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  559. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  560. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  561. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  562. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  563. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  564. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  565. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  566. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  567. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  568. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  569. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
  570. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  571. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  572. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  573. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  574. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  575. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  576. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  577. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  578. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  579. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  580. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
  581. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  582. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  583. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  584. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  585. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  586. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
  587. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  588. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  589. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  590. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  591. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  592. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  593. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  594. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
  595. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  596. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  597. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  598. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  599. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  600. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  601. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  602. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  603. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  604. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  605. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  606. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  607. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  608. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  609. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  610. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  611. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  612. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  613. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  614. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  615. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  616. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  617. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  618. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  619. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  620. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  621. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  622. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -59
  623. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  624. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  625. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  626. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  627. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  628. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  629. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  630. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  631. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
  632. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
  633. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  634. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  635. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  636. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  637. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  638. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  639. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  640. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  641. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  642. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  643. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  644. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  645. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  646. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  647. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  648. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  649. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  650. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  651. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  652. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  653. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  654. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  655. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  656. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +38 -6
  657. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  658. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  659. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  660. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  661. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  662. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  663. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +203 -4
  664. package/src/resources/extensions/gsd/tests/write-gate.test.ts +40 -1
  665. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  666. package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
  667. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  668. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  669. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  670. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  671. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  672. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  673. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  674. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  675. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  676. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  677. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  678. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  679. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  680. package/src/resources/extensions/gsd/worktree-resolver.ts +119 -20
  681. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  682. package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  683. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  684. /package/dist/web/standalone/.next/static/{CaMwumvGbBPZrJicfsCzV → Y9yOOsO4ZA5BPTOS8ixvP}/_buildManifest.js +0 -0
  685. /package/dist/web/standalone/.next/static/{CaMwumvGbBPZrJicfsCzV → Y9yOOsO4ZA5BPTOS8ixvP}/_ssgManifest.js +0 -0
@@ -1,3 +1,4 @@
1
+ // GSD2 - Agent session lifecycle and workspace runtime coordination
1
2
  /**
2
3
  * AgentSession - Core abstraction for agent lifecycle and session management.
3
4
  *
@@ -167,6 +168,8 @@ export interface AgentSessionConfig {
167
168
  baseToolsOverride?: Record<string, AgentTool>;
168
169
  /** Mutable ref used by Agent to access the current ExtensionRunner */
169
170
  extensionRunnerRef?: { current?: ExtensionRunner };
171
+ /** Mutable ref used by providers to access the current workspace root. */
172
+ workspaceRootRef?: { current: string };
170
173
  /** Optional: check if the claude-code CLI provider is ready (installed + authed).
171
174
  * Passed through to RetryHandler for third-party block recovery (#3772). */
172
175
  isClaudeCodeReady?: () => boolean;
@@ -284,6 +287,7 @@ export class AgentSession {
284
287
  private _baseToolRegistry: Map<string, AgentTool> = new Map();
285
288
  private _cwd: string;
286
289
  private _extensionRunnerRef?: { current?: ExtensionRunner };
290
+ private _workspaceRootRef?: { current: string };
287
291
  private _initialActiveToolNames?: string[];
288
292
  private _baseToolsOverride?: Record<string, AgentTool>;
289
293
  private _extensionUIContext?: ExtensionUIContext;
@@ -305,6 +309,8 @@ export class AgentSession {
305
309
 
306
310
  // Base system prompt (without extension appends) - used to apply fresh appends each turn
307
311
  private _baseSystemPrompt = "";
312
+ // Optional prompt-only skill catalog filter. Skills remain loaded and invocable by name.
313
+ private _visibleSkillNames: Set<string> | undefined = undefined;
308
314
 
309
315
  constructor(config: AgentSessionConfig) {
310
316
  this.agent = config.agent;
@@ -321,6 +327,10 @@ export class AgentSession {
321
327
  this._modelRegistry,
322
328
  );
323
329
  this._extensionRunnerRef = config.extensionRunnerRef;
330
+ this._workspaceRootRef = config.workspaceRootRef;
331
+ if (this._workspaceRootRef) {
332
+ this._workspaceRootRef.current = this._cwd;
333
+ }
324
334
  this._initialActiveToolNames = config.initialActiveToolNames;
325
335
  this._baseToolsOverride = config.baseToolsOverride;
326
336
 
@@ -867,6 +877,25 @@ export class AgentSession {
867
877
  this.agent.setSystemPrompt(this._baseSystemPrompt);
868
878
  }
869
879
 
880
+ /**
881
+ * Set or clear a prompt-only filter for the <available_skills> catalog.
882
+ *
883
+ * This does not unload skills or disable the Skill tool. It only controls
884
+ * which loaded skills are advertised in the system prompt on rebuild.
885
+ */
886
+ setVisibleSkillsByName(skillNames: string[] | undefined): void {
887
+ this._visibleSkillNames = skillNames === undefined
888
+ ? undefined
889
+ : new Set(skillNames.map((name) => name.trim().toLowerCase()).filter(Boolean));
890
+ this._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());
891
+ this.agent.setSystemPrompt(this._baseSystemPrompt);
892
+ }
893
+
894
+ /** Get the current prompt-only skill catalog filter, if one is active. */
895
+ getVisibleSkillNames(): string[] | undefined {
896
+ return this._visibleSkillNames ? [...this._visibleSkillNames] : undefined;
897
+ }
898
+
870
899
  /** Whether compaction or branch summarization is currently running */
871
900
  get isCompacting(): boolean {
872
901
  return this._compactionOrchestrator.isCompacting;
@@ -1045,6 +1074,9 @@ export class AgentSession {
1045
1074
  return buildSystemPrompt({
1046
1075
  cwd: this._cwd,
1047
1076
  skills: loadedSkills,
1077
+ skillFilter: this._visibleSkillNames
1078
+ ? (skill) => this._visibleSkillNames!.has(skill.name.trim().toLowerCase())
1079
+ : undefined,
1048
1080
  contextFiles: loadedContextFiles,
1049
1081
  customPrompt: loaderSystemPrompt,
1050
1082
  appendSystemPrompt,
@@ -1626,6 +1658,11 @@ export class AgentSession {
1626
1658
  // message_end/agent_end events fire while listeners are still connected.
1627
1659
  // During agent_end handling the turn is already ending; aborting there can
1628
1660
  // convert a successful auto-mode handoff into an aborted provider message.
1661
+ if (!this.agent.state.isStreaming) {
1662
+ this._retryHandler.abortRetry();
1663
+ await this.agent.waitForIdle();
1664
+ return;
1665
+ }
1629
1666
  await this.abort();
1630
1667
  }
1631
1668
 
@@ -1640,6 +1677,8 @@ export class AgentSession {
1640
1677
  async newSession(options?: {
1641
1678
  parentSession?: string;
1642
1679
  setup?: (sessionManager: SessionManager) => Promise<void>;
1680
+ /** Explicit workspace root for the new session/tool runtime. */
1681
+ workspaceRoot?: string;
1643
1682
  /** See ExtensionCommandContext.newSession for docs (#3731). */
1644
1683
  abortSignal?: AbortSignal;
1645
1684
  }): Promise<boolean> {
@@ -1661,10 +1700,10 @@ export class AgentSession {
1661
1700
  try {
1662
1701
  await this._settleCurrentTurnForSessionTransition();
1663
1702
 
1664
- // #3731: If the caller aborted (e.g. runUnit() timed out and restored cwd to
1665
- // project root), discard this session before capturing process.cwd() and
1666
- // rebuilding the tool runtime. Without this check, the late newSession()
1667
- // would rebuild tools with root cwd, breaking worktree isolation.
1703
+ // #3731: If the caller aborted (e.g. runUnit() timed out while the
1704
+ // worktree was being torn down), discard this session before rebuilding
1705
+ // the tool runtime. Without this check, the late newSession() could
1706
+ // rebuild tools with a stale workspace root.
1668
1707
  if (options?.abortSignal?.aborted) {
1669
1708
  return false;
1670
1709
  }
@@ -1674,15 +1713,21 @@ export class AgentSession {
1674
1713
  } finally {
1675
1714
  this._sessionSwitchPending = false;
1676
1715
  }
1677
- // Update cwd to current process directory auto-mode may have chdir'd
1678
- // into a worktree since the original session was created.
1716
+ // Update the workspace root for the new tool runtime. Auto-mode passes
1717
+ // this explicitly so session routing does not depend on global
1718
+ // process.cwd() after worktree merge/teardown. Other callers keep the
1719
+ // historical default.
1679
1720
  const previousCwd = this._cwd;
1680
- this._cwd = process.cwd();
1721
+ this._cwd = options?.workspaceRoot ?? process.cwd();
1722
+ if (this._workspaceRootRef) {
1723
+ this._workspaceRootRef.current = this._cwd;
1724
+ }
1681
1725
  this.sessionManager.newSession({ parentSession: options?.parentSession });
1682
1726
  this.agent.sessionId = this.sessionManager.getSessionId();
1683
1727
  this._steeringMessages = [];
1684
1728
  this._followUpMessages = [];
1685
1729
  this._pendingNextTurnMessages = [];
1730
+ this._visibleSkillNames = undefined;
1686
1731
 
1687
1732
  this.sessionManager.appendThinkingLevelChange(this.thinkingLevel);
1688
1733
 
@@ -2180,6 +2225,8 @@ export class AgentSession {
2180
2225
  getActiveTools: () => this.getActiveToolNames(),
2181
2226
  getAllTools: () => this.getAllTools(),
2182
2227
  setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
2228
+ getVisibleSkills: () => this.getVisibleSkillNames(),
2229
+ setVisibleSkills: (skillNames) => this.setVisibleSkillsByName(skillNames),
2183
2230
  refreshTools: () => this._refreshToolRegistry(),
2184
2231
  getCommands,
2185
2232
  setModel: async (model, options) => {
@@ -2211,6 +2258,9 @@ export class AgentSession {
2211
2258
  })();
2212
2259
  },
2213
2260
  getSystemPrompt: () => this.systemPrompt,
2261
+ setCompactionThresholdOverride: (percent) => {
2262
+ this.settingsManager.setCompactionThresholdOverride(percent);
2263
+ },
2214
2264
  },
2215
2265
  );
2216
2266
  }
@@ -2345,6 +2395,7 @@ export class AgentSession {
2345
2395
  this.settingsManager.reload();
2346
2396
  resetApiProviders();
2347
2397
  await this._resourceLoader.reload();
2398
+ this._visibleSkillNames = undefined;
2348
2399
  this._buildRuntime({
2349
2400
  activeToolNames: this.getActiveToolNames(),
2350
2401
  flagValues: previousFlagValues,
@@ -2534,6 +2585,7 @@ export class AgentSession {
2534
2585
  this._steeringMessages = [];
2535
2586
  this._followUpMessages = [];
2536
2587
  this._pendingNextTurnMessages = [];
2588
+ this._visibleSkillNames = undefined;
2537
2589
 
2538
2590
  // Set new session
2539
2591
  this.sessionManager.setSessionFile(sessionPath);
@@ -1002,6 +1002,97 @@ test("chat-controller does not pin when there are no tool calls", async () => {
1002
1002
  assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should stay empty without tool calls");
1003
1003
  });
1004
1004
 
1005
+ test("chat-controller rolls up only contiguous low-signal tool runs on message_end", async () => {
1006
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
1007
+ fg: (_key: string, text: string) => text,
1008
+ bg: (_key: string, text: string) => text,
1009
+ bold: (text: string) => text,
1010
+ italic: (text: string) => text,
1011
+ truncate: (text: string) => text,
1012
+ };
1013
+
1014
+ const host = createHost();
1015
+ host.getMarkdownThemeWithSettings = () => ({});
1016
+
1017
+ const t1 = { type: "toolCall", id: "t1", name: "bash", arguments: { command: "true" } };
1018
+ const t2 = { type: "toolCall", id: "t2", name: "bash", arguments: { command: "true" } };
1019
+ const text = { type: "text", text: "middle output" };
1020
+ const t3 = { type: "toolCall", id: "t3", name: "read", arguments: { path: "/tmp/a" } };
1021
+ const t4 = { type: "toolCall", id: "t4", name: "read", arguments: { path: "/tmp/b" } };
1022
+ const content = [t1, t2, text, t3, t4];
1023
+
1024
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
1025
+ await handleAgentEvent(host, {
1026
+ type: "message_update",
1027
+ message: makeAssistant(content),
1028
+ assistantMessageEvent: {
1029
+ type: "text_delta",
1030
+ contentIndex: 2,
1031
+ delta: text.text,
1032
+ partial: makeAssistant(content),
1033
+ },
1034
+ } as any);
1035
+
1036
+ for (const tool of [t1, t2, t3, t4]) {
1037
+ await handleAgentEvent(host, {
1038
+ type: "tool_execution_end",
1039
+ toolCallId: tool.id,
1040
+ isError: false,
1041
+ result: { content: [], details: {} },
1042
+ } as any);
1043
+ }
1044
+
1045
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(content) } as any);
1046
+
1047
+ assert.equal(host.chatContainer.children.length, 3, "two separated tool runs should become two summaries around text");
1048
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolPhaseSummaryComponent");
1049
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
1050
+ assert.equal(host.chatContainer.children[2]?.constructor?.name, "ToolPhaseSummaryComponent");
1051
+ assert.match(host.chatContainer.children[0].render(120).join("\n"), /Setup \/ shell 2 actions/);
1052
+ const readSummary = host.chatContainer.children[2].render(120).join("\n");
1053
+ assert.match(readSummary, /Context reads · 2 files/);
1054
+ assert.match(readSummary, /\/tmp\/a · \/tmp\/b/);
1055
+ assert.equal(host.chatContainer._prevRender, null, "summary reposition must invalidate the chat container render cache");
1056
+ });
1057
+
1058
+ test("chat-controller rolls up low-signal direct tool execution events on agent_end", async () => {
1059
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
1060
+ fg: (_key: string, text: string) => text,
1061
+ bg: (_key: string, text: string) => text,
1062
+ bold: (text: string) => text,
1063
+ italic: (text: string) => text,
1064
+ truncate: (text: string) => text,
1065
+ };
1066
+
1067
+ const host = createHost();
1068
+ host.getMarkdownThemeWithSettings = () => ({});
1069
+
1070
+ for (const toolCallId of ["bash-1", "bash-2", "bash-3"]) {
1071
+ await handleAgentEvent(host, {
1072
+ type: "tool_execution_start",
1073
+ toolCallId,
1074
+ toolName: "bash",
1075
+ args: { command: "true" },
1076
+ } as any);
1077
+ await handleAgentEvent(host, {
1078
+ type: "tool_execution_end",
1079
+ toolCallId,
1080
+ isError: false,
1081
+ result: { content: [], details: {} },
1082
+ } as any);
1083
+ }
1084
+
1085
+ assert.equal(host.chatContainer.children.length, 1, "direct tool events roll up as they finish");
1086
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolPhaseSummaryComponent");
1087
+ assert.match(host.chatContainer.children[0].render(120).join("\n"), /Setup \/ shell 3 actions/);
1088
+
1089
+ await handleAgentEvent(host, { type: "agent_end" } as any);
1090
+
1091
+ assert.equal(host.chatContainer.children.length, 1, "direct low-signal tool rows should roll up on agent_end");
1092
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolPhaseSummaryComponent");
1093
+ assert.match(host.chatContainer.children[0].render(120).join("\n"), /Setup \/ shell 3 actions/);
1094
+ });
1095
+
1005
1096
  // Regression test for issue #4144: interleaved text/tool content must render in content[] index order.
1006
1097
  // Stream: [text "A", toolCall T1, text "B", toolCall T2, text "C"]
1007
1098
  // Expected chatContainer order: textRun(A), toolExec(T1), textRun(B), toolExec(T2), textRun(C)
@@ -86,6 +86,13 @@ export interface CompactionSettings {
86
86
  enabled: boolean;
87
87
  reserveTokens: number;
88
88
  keepRecentTokens: number;
89
+ /**
90
+ * Optional percent-of-context-window threshold (0 < value < 1). When set,
91
+ * `shouldCompact()` fires once `contextTokens > contextWindow * thresholdPercent`,
92
+ * overriding the absolute `reserveTokens` calculation. Lets host integrations
93
+ * (e.g. GSD) express compaction policy as a fraction independent of model size.
94
+ */
95
+ thresholdPercent?: number;
89
96
  }
90
97
 
91
98
  export const DEFAULT_COMPACTION_SETTINGS: CompactionSettings = {
@@ -185,9 +192,20 @@ export function estimateContextTokens(messages: AgentMessage[]): ContextUsageEst
185
192
 
186
193
  /**
187
194
  * Check if compaction should trigger based on context usage.
195
+ *
196
+ * When `thresholdPercent` is set (and within (0, 1)), it overrides the absolute
197
+ * `reserveTokens` calculation: compaction fires at `contextWindow * thresholdPercent`.
198
+ * Otherwise the legacy `contextWindow - reserveTokens` headroom is used.
188
199
  */
189
200
  export function shouldCompact(contextTokens: number, contextWindow: number, settings: CompactionSettings): boolean {
190
201
  if (!settings.enabled) return false;
202
+ if (
203
+ settings.thresholdPercent !== undefined &&
204
+ settings.thresholdPercent > 0 &&
205
+ settings.thresholdPercent < 1
206
+ ) {
207
+ return contextTokens > contextWindow * settings.thresholdPercent;
208
+ }
191
209
  return contextTokens > contextWindow - settings.reserveTokens;
192
210
  }
193
211
 
@@ -0,0 +1,121 @@
1
+ // pi-coding-agent / Regression tests for compaction threshold percent (#5475)
2
+
3
+ import assert from "node:assert/strict";
4
+ import { describe, it } from "node:test";
5
+
6
+ import { shouldCompact, type CompactionSettings } from "./compaction/compaction.js";
7
+ import { SettingsManager } from "./settings-manager.js";
8
+
9
+ const REGISTRY_DEFAULTS: CompactionSettings = {
10
+ enabled: true,
11
+ reserveTokens: 16_384,
12
+ keepRecentTokens: 20_000,
13
+ };
14
+
15
+ describe("shouldCompact — thresholdPercent (#5475)", () => {
16
+ it("uses absolute reserveTokens when thresholdPercent is unset (legacy behavior)", () => {
17
+ // 200K window, 16384 reserve → fires at 183_617 tokens
18
+ assert.equal(shouldCompact(183_616, 200_000, REGISTRY_DEFAULTS), false);
19
+ assert.equal(shouldCompact(183_617, 200_000, REGISTRY_DEFAULTS), true);
20
+ });
21
+
22
+ it("uses thresholdPercent when set, ignoring reserveTokens", () => {
23
+ const settings: CompactionSettings = { ...REGISTRY_DEFAULTS, thresholdPercent: 0.7 };
24
+ // 200K * 0.7 = 140_000 → fires above that
25
+ assert.equal(shouldCompact(140_000, 200_000, settings), false);
26
+ assert.equal(shouldCompact(140_001, 200_000, settings), true);
27
+ // reserveTokens-based math would have said false at 183_616 — the percent override changes that
28
+ assert.equal(shouldCompact(150_000, 200_000, settings), true);
29
+ });
30
+
31
+ it("falls back to reserveTokens when thresholdPercent is out of range", () => {
32
+ // Defense in depth: reject 0, 1, negative, NaN, Infinity
33
+ for (const bad of [0, 1, -0.1, 1.5, Number.NaN, Number.POSITIVE_INFINITY]) {
34
+ const settings: CompactionSettings = { ...REGISTRY_DEFAULTS, thresholdPercent: bad };
35
+ assert.equal(
36
+ shouldCompact(183_616, 200_000, settings),
37
+ false,
38
+ `bad=${bad} should fall back to reserveTokens math`,
39
+ );
40
+ assert.equal(shouldCompact(183_617, 200_000, settings), true, `bad=${bad}`);
41
+ }
42
+ });
43
+
44
+ it("respects enabled=false regardless of thresholdPercent", () => {
45
+ const settings: CompactionSettings = {
46
+ ...REGISTRY_DEFAULTS,
47
+ enabled: false,
48
+ thresholdPercent: 0.5,
49
+ };
50
+ assert.equal(shouldCompact(199_999, 200_000, settings), false);
51
+ });
52
+
53
+ it("scales with contextWindow — same percent, different windows", () => {
54
+ const settings: CompactionSettings = { ...REGISTRY_DEFAULTS, thresholdPercent: 0.8 };
55
+ // 100K window: fires above 80_000
56
+ assert.equal(shouldCompact(80_000, 100_000, settings), false);
57
+ assert.equal(shouldCompact(80_001, 100_000, settings), true);
58
+ // 1M window: fires above 800_000
59
+ assert.equal(shouldCompact(800_000, 1_000_000, settings), false);
60
+ assert.equal(shouldCompact(800_001, 1_000_000, settings), true);
61
+ });
62
+ });
63
+
64
+ describe("SettingsManager — compaction threshold override (#5475)", () => {
65
+ it("getCompactionThresholdPercent returns undefined by default", () => {
66
+ const sm = SettingsManager.inMemory({});
67
+ assert.equal(sm.getCompactionThresholdPercent(), undefined);
68
+ assert.equal(sm.getCompactionSettings().thresholdPercent, undefined);
69
+ });
70
+
71
+ it("setCompactionThresholdOverride applies in-memory and is exposed via getCompactionSettings", () => {
72
+ const sm = SettingsManager.inMemory({});
73
+ sm.setCompactionThresholdOverride(0.7);
74
+ assert.equal(sm.getCompactionThresholdPercent(), 0.7);
75
+ assert.equal(sm.getCompactionSettings().thresholdPercent, 0.7);
76
+ });
77
+
78
+ it("setCompactionThresholdOverride(undefined) clears a prior override", () => {
79
+ const sm = SettingsManager.inMemory({});
80
+ sm.setCompactionThresholdOverride(0.7);
81
+ sm.setCompactionThresholdOverride(undefined);
82
+ assert.equal(sm.getCompactionThresholdPercent(), undefined);
83
+ assert.equal(sm.getCompactionSettings().thresholdPercent, undefined);
84
+ });
85
+
86
+ it("setCompactionThresholdOverride preserves other compaction fields (enabled, reserveTokens)", () => {
87
+ const sm = SettingsManager.inMemory({
88
+ compaction: { enabled: true, reserveTokens: 30_000, keepRecentTokens: 25_000 },
89
+ });
90
+ sm.setCompactionThresholdOverride(0.6);
91
+ const settings = sm.getCompactionSettings();
92
+ assert.equal(settings.enabled, true);
93
+ assert.equal(settings.reserveTokens, 30_000);
94
+ assert.equal(settings.keepRecentTokens, 25_000);
95
+ assert.equal(settings.thresholdPercent, 0.6);
96
+ });
97
+
98
+ it("setCompactionThresholdOverride works when no compaction config exists yet", () => {
99
+ const sm = SettingsManager.inMemory({});
100
+ sm.setCompactionThresholdOverride(0.85);
101
+ assert.equal(sm.getCompactionThresholdPercent(), 0.85);
102
+ // Other compaction fields fall back to their defaults
103
+ const settings = sm.getCompactionSettings();
104
+ assert.equal(settings.enabled, true);
105
+ assert.equal(typeof settings.reserveTokens, "number");
106
+ assert.equal(typeof settings.keepRecentTokens, "number");
107
+ });
108
+ });
109
+
110
+ describe("end-to-end — getCompactionSettings + shouldCompact (#5475)", () => {
111
+ it("70% threshold on a 200K window fires at the documented bug-report value (140_001 not 183_617)", () => {
112
+ const sm = SettingsManager.inMemory({});
113
+ sm.setCompactionThresholdOverride(0.7);
114
+ const settings = sm.getCompactionSettings();
115
+
116
+ assert.equal(shouldCompact(140_000, 200_000, settings), false);
117
+ assert.equal(shouldCompact(140_001, 200_000, settings), true);
118
+ // Pre-fix behavior would have required 183_617 — verify we no longer wait that long
119
+ assert.equal(shouldCompact(150_000, 200_000, settings), true);
120
+ });
121
+ });
@@ -0,0 +1,32 @@
1
+ import assert from "node:assert/strict";
2
+ import { describe, it, afterEach } from "node:test";
3
+ import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+
7
+ import { atomicWriteDbSnapshotSync } from "./db-snapshot.js";
8
+
9
+ describe("atomicWriteDbSnapshotSync", () => {
10
+ let dir: string;
11
+
12
+ afterEach(() => {
13
+ if (dir) {
14
+ rmSync(dir, { recursive: true, force: true });
15
+ }
16
+ });
17
+
18
+ it("writes the full snapshot and leaves no temp file after success", () => {
19
+ dir = mkdtempSync(join(tmpdir(), "gsd-db-snapshot-test-"));
20
+ const dbPath = join(dir, "agent.db");
21
+ const snapshot = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
22
+
23
+ atomicWriteDbSnapshotSync(dbPath, snapshot);
24
+
25
+ assert.deepEqual(readFileSync(dbPath), Buffer.from(snapshot));
26
+ assert.equal(existsSync(`${dbPath}.tmp`), false);
27
+ assert.deepEqual(
28
+ readdirSync(dir).filter((entry) => entry.includes("agent.db") && entry.includes(".tmp")),
29
+ [],
30
+ );
31
+ });
32
+ });
@@ -0,0 +1,66 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { closeSync, fsyncSync, openSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
3
+ import { basename, dirname, join } from "node:path";
4
+
5
+ export type DbSnapshot = Buffer | Uint8Array;
6
+
7
+ function closeBestEffort(fd: number | null): void {
8
+ if (fd === null) return;
9
+ try {
10
+ closeSync(fd);
11
+ } catch {
12
+ // Preserve the original write/rename failure when cleaning up.
13
+ }
14
+ }
15
+
16
+ function fsyncDirectoryBestEffort(dirPath: string): void {
17
+ let fd: number | null = null;
18
+ try {
19
+ fd = openSync(dirPath, "r");
20
+ fsyncSync(fd);
21
+ } catch {
22
+ // Directory fsync is unsupported on some platforms/filesystems.
23
+ } finally {
24
+ closeBestEffort(fd);
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Persist a sql.js database export without exposing callers to a torn live file.
30
+ *
31
+ * The snapshot is written to a unique temp file in the same directory, flushed,
32
+ * then renamed over the target. A hard kill during the temp write leaves the
33
+ * previous target intact; after rename, readers see the complete new snapshot.
34
+ *
35
+ * The rename replaces the target inode: existing file mode/ownership is not
36
+ * preserved, and a symlink at dbPath is replaced rather than written through.
37
+ * Agent DB snapshots are owned runtime files, so this trade-off favors a
38
+ * private 0600 replacement over retaining prior target metadata.
39
+ */
40
+ export function atomicWriteDbSnapshotSync(dbPath: string, snapshot: DbSnapshot): void {
41
+ const dirPath = dirname(dbPath);
42
+ const tmpPath = join(dirPath, `.${basename(dbPath)}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`);
43
+ let fd: number | null = null;
44
+ let renamed = false;
45
+
46
+ try {
47
+ fd = openSync(tmpPath, "wx", 0o600);
48
+ writeFileSync(fd, Buffer.from(snapshot));
49
+ fsyncSync(fd);
50
+ closeSync(fd);
51
+ fd = null;
52
+
53
+ renameSync(tmpPath, dbPath);
54
+ renamed = true;
55
+ fsyncDirectoryBestEffort(dirPath);
56
+ } finally {
57
+ closeBestEffort(fd);
58
+ if (!renamed) {
59
+ try {
60
+ unlinkSync(tmpPath);
61
+ } catch {
62
+ // The temp file may not have been created yet.
63
+ }
64
+ }
65
+ }
66
+ }
@@ -415,6 +415,8 @@ export function createExtensionRuntime(): ExtensionRuntime {
415
415
  getActiveTools: notInitialized,
416
416
  getAllTools: notInitialized,
417
417
  setActiveTools: notInitialized,
418
+ getVisibleSkills: notInitialized,
419
+ setVisibleSkills: notInitialized,
418
420
  // registerTool() is valid during extension load; refresh is only needed post-bind.
419
421
  refreshTools: () => {},
420
422
  getCommands: notInitialized,
@@ -566,6 +568,14 @@ function createExtensionAPI(
566
568
  runtime.setActiveTools(toolNames);
567
569
  },
568
570
 
571
+ getVisibleSkills(): string[] | undefined {
572
+ return runtime.getVisibleSkills();
573
+ },
574
+
575
+ setVisibleSkills(skillNames: string[] | undefined): void {
576
+ runtime.setVisibleSkills(skillNames);
577
+ },
578
+
569
579
  getCommands() {
570
580
  return runtime.getCommands();
571
581
  },
@@ -102,10 +102,65 @@ describe("ExtensionRunner.emitToolCall", () => {
102
102
  assert.equal(errors[0].event, "tool_call");
103
103
  assert.equal(errors[0].extensionPath, "/test/throwing-ext");
104
104
  });
105
+
106
+ it("preserves shutdown in tool_call handler context", async (t) => {
107
+ const dir = mkdtempSync(join(tmpdir(), "runner-test-"));
108
+ t.after(() => {
109
+ rmSync(dir, { recursive: true, force: true });
110
+ });
111
+
112
+ const sessionManager = SessionManager.create(dir, dir);
113
+ const authStorage = AuthStorage.create();
114
+ const modelRegistry = new ModelRegistry(authStorage, join(dir, "models.json"));
115
+ const runtime = makeMinimalRuntime();
116
+ let shutdownCount = 0;
117
+ const handlers = new Map();
118
+ handlers.set("tool_call", [
119
+ async (_event: unknown, ctx: { shutdown: () => void }) => {
120
+ ctx.shutdown();
121
+ },
122
+ ]);
123
+ const extension = {
124
+ path: "/test/shutdown-on-tool-call",
125
+ handlers,
126
+ commands: new Map(),
127
+ shortcuts: new Map(),
128
+ tools: new Map(),
129
+ flags: new Map(),
130
+ diagnostics: [],
131
+ } as unknown as Extension;
132
+ const runner = new ExtensionRunner([extension], runtime, dir, sessionManager, modelRegistry);
133
+ runner.bindCore({} as any, {
134
+ getModel: () => undefined,
135
+ isIdle: () => true,
136
+ abort: () => {},
137
+ hasPendingMessages: () => false,
138
+ shutdown: () => {
139
+ shutdownCount += 1;
140
+ },
141
+ getContextUsage: () => undefined,
142
+ compact: () => {},
143
+ getSystemPrompt: () => "",
144
+ setCompactionThresholdOverride: () => {},
145
+ });
146
+
147
+ const errors: any[] = [];
148
+ runner.onError((err) => errors.push(err));
149
+
150
+ await runner.emitToolCall({
151
+ type: "tool_call",
152
+ toolCallId: "test-123",
153
+ toolName: "test_tool",
154
+ input: {},
155
+ } as ToolCallEvent);
156
+
157
+ assert.equal(shutdownCount, 1);
158
+ assert.equal(errors.length, 0);
159
+ });
105
160
  });
106
161
 
107
162
  describe("ExtensionRunner.createContext", () => {
108
- it("uses the live process cwd instead of the constructor cwd", (t) => {
163
+ it("uses the constructor workspace root instead of ambient process cwd", (t) => {
109
164
  const originalCwd = process.cwd();
110
165
  const dir = mkdtempSync(join(tmpdir(), "runner-test-"));
111
166
  const projectDir = join(dir, "project");
@@ -124,8 +179,63 @@ describe("ExtensionRunner.createContext", () => {
124
179
  const realProjectDir = realpathSync(projectDir);
125
180
  process.chdir(realProjectDir);
126
181
 
127
- assert.equal(runner.createContext().cwd, realProjectDir);
128
- assert.equal(runner.createCommandContext().cwd, realProjectDir);
182
+ assert.equal(runner.createContext().cwd, originalCwd);
183
+ assert.equal(runner.createCommandContext().cwd, originalCwd);
184
+ });
185
+
186
+ it("does not let lifecycle event handlers close the TUI", async (t) => {
187
+ const dir = mkdtempSync(join(tmpdir(), "runner-test-"));
188
+ t.after(() => {
189
+ rmSync(dir, { recursive: true, force: true });
190
+ });
191
+
192
+ const sessionManager = SessionManager.create(dir, dir);
193
+ const authStorage = AuthStorage.create();
194
+ const modelRegistry = new ModelRegistry(authStorage, join(dir, "models.json"));
195
+ const runtime = makeMinimalRuntime();
196
+ let shutdownCount = 0;
197
+ const handlers = new Map();
198
+ handlers.set("agent_end", [
199
+ async (_event: unknown, ctx: { shutdown: () => void }) => {
200
+ ctx.shutdown();
201
+ },
202
+ ]);
203
+ const extension = {
204
+ path: "/test/shutdown-on-agent-end",
205
+ handlers,
206
+ commands: new Map(),
207
+ shortcuts: new Map(),
208
+ tools: new Map(),
209
+ flags: new Map(),
210
+ diagnostics: [],
211
+ } as unknown as Extension;
212
+ const runner = new ExtensionRunner([extension], runtime, dir, sessionManager, modelRegistry);
213
+ runner.bindCore({} as any, {
214
+ getModel: () => undefined,
215
+ isIdle: () => true,
216
+ abort: () => {},
217
+ hasPendingMessages: () => false,
218
+ shutdown: () => {
219
+ shutdownCount += 1;
220
+ },
221
+ getContextUsage: () => undefined,
222
+ compact: () => {},
223
+ getSystemPrompt: () => "",
224
+ setCompactionThresholdOverride: () => {},
225
+ });
226
+
227
+ const errors: any[] = [];
228
+ runner.onError((err) => errors.push(err));
229
+
230
+ await runner.emit({ type: "agent_end", messages: [] } as any);
231
+
232
+ assert.equal(shutdownCount, 0);
233
+ assert.equal(errors.length, 1);
234
+ assert.equal(errors[0].event, "agent_end");
235
+ assert.match(errors[0].error, /cannot request TUI shutdown/);
236
+
237
+ runner.createCommandContext().shutdown();
238
+ assert.equal(shutdownCount, 1);
129
239
  });
130
240
  });
131
241