gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.d4fc28e6b

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 (580) hide show
  1. package/README.md +4 -2
  2. package/dist/cli.js +0 -19
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/GSD-WORKFLOW.md +2 -2
  5. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  6. package/dist/resources/extensions/github-sync/templates.js +39 -8
  7. package/dist/resources/extensions/gsd/auto/loop.js +119 -18
  8. package/dist/resources/extensions/gsd/auto/phases.js +212 -135
  9. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  10. package/dist/resources/extensions/gsd/auto/run-unit.js +41 -45
  11. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  12. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  13. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
  15. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  17. package/dist/resources/extensions/gsd/auto-post-unit.js +27 -14
  18. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  19. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  20. package/dist/resources/extensions/gsd/auto-start.js +199 -9
  21. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  22. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  23. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  24. package/dist/resources/extensions/gsd/auto.js +95 -27
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -3
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  27. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  28. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
  29. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  30. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -55
  33. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  34. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  35. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  36. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  37. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  38. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  39. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  40. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  41. package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
  42. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  43. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  44. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  45. package/dist/resources/extensions/gsd/detection.js +106 -0
  46. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  47. package/dist/resources/extensions/gsd/git-service.js +36 -4
  48. package/dist/resources/extensions/gsd/graph.js +9 -3
  49. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  50. package/dist/resources/extensions/gsd/guided-flow.js +129 -44
  51. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  52. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  53. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  54. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  55. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  56. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  57. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  58. package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
  59. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  60. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  61. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  62. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  63. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  64. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  65. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  66. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  68. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  70. package/dist/resources/extensions/gsd/quick.js +34 -2
  71. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  72. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  73. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  74. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  75. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  76. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  77. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  78. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  79. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  80. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  81. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  82. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  83. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  84. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  85. package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
  86. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  87. package/dist/web/standalone/.next/BUILD_ID +1 -1
  88. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  89. package/dist/web/standalone/.next/build-manifest.json +3 -3
  90. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  91. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/index.html +1 -1
  110. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  117. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  118. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  121. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  122. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  123. package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
  124. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
  125. package/dist/welcome-screen.d.ts +2 -0
  126. package/dist/welcome-screen.js +9 -7
  127. package/package.json +12 -8
  128. package/packages/contracts/package.json +1 -1
  129. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  130. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  131. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  132. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  133. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  134. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  135. package/packages/native/tsconfig.tsbuildinfo +1 -1
  136. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  137. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  138. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  139. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  140. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  141. package/packages/pi-agent-core/dist/agent.js +2 -0
  142. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  143. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  144. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  145. package/packages/pi-agent-core/dist/index.js +2 -0
  146. package/packages/pi-agent-core/dist/index.js.map +1 -1
  147. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  148. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  149. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  150. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  151. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  152. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  153. package/packages/pi-agent-core/dist/types.js.map +1 -1
  154. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  155. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  156. package/packages/pi-agent-core/src/agent.ts +8 -0
  157. package/packages/pi-agent-core/src/index.ts +2 -0
  158. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  159. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  160. package/packages/pi-agent-core/src/types.ts +14 -0
  161. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  162. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  163. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  164. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  165. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  166. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  167. package/packages/pi-ai/dist/models/index.js +8 -0
  168. package/packages/pi-ai/dist/models/index.js.map +1 -1
  169. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  170. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/providers/fake.js +319 -0
  172. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  173. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  174. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  175. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  176. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  177. package/packages/pi-ai/src/models/index.ts +9 -0
  178. package/packages/pi-ai/src/providers/fake.ts +376 -0
  179. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  180. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  181. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  182. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  184. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  186. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  188. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +76 -0
  190. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  192. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  194. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  196. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  197. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  198. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  199. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  200. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  201. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  202. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  203. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  204. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  205. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  206. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  207. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  209. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  211. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  213. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  215. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
  217. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  220. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  223. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  225. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  226. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  227. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  228. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  229. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  231. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -0
  233. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/settings-manager.js +33 -0
  235. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  237. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  240. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  242. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  244. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  253. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  257. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  265. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  267. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +17 -0
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +109 -17
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +69 -2
  274. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +93 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  278. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  283. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +26 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  296. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  303. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  307. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  308. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
  311. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  312. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  313. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  315. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  317. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  318. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  319. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  320. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  321. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  322. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
  323. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  324. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  325. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  326. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  327. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  328. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  329. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  330. package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
  331. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  332. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  333. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  334. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  335. package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
  336. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  337. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  338. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  339. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  340. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
  341. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
  342. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
  343. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  344. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  345. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  346. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  347. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
  348. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
  349. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
  350. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  351. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  352. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
  353. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  354. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  355. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  356. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
  357. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  358. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
  359. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  360. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  361. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  362. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  363. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  364. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  365. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  366. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  367. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  368. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  369. package/packages/pi-tui/dist/index.d.ts +1 -0
  370. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/index.js +2 -0
  372. package/packages/pi-tui/dist/index.js.map +1 -1
  373. package/packages/pi-tui/dist/style.d.ts +41 -0
  374. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  375. package/packages/pi-tui/dist/style.js +158 -0
  376. package/packages/pi-tui/dist/style.js.map +1 -0
  377. package/packages/pi-tui/dist/tui.d.ts +0 -1
  378. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  379. package/packages/pi-tui/dist/tui.js +21 -16
  380. package/packages/pi-tui/dist/tui.js.map +1 -1
  381. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  382. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  383. package/packages/pi-tui/src/index.ts +9 -0
  384. package/packages/pi-tui/src/style.ts +225 -0
  385. package/packages/pi-tui/src/tui.ts +23 -16
  386. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  387. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  388. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  389. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  390. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  391. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  392. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  393. package/pkg/dist/modes/interactive/theme/theme.js +18 -1
  394. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  395. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  396. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  397. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  398. package/src/resources/GSD-WORKFLOW.md +2 -2
  399. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  400. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  401. package/src/resources/extensions/github-sync/templates.ts +38 -8
  402. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  403. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  404. package/src/resources/extensions/gsd/auto/loop.ts +151 -26
  405. package/src/resources/extensions/gsd/auto/phases.ts +289 -196
  406. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  407. package/src/resources/extensions/gsd/auto/run-unit.ts +52 -44
  408. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  409. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  410. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  411. package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
  412. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  413. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  414. package/src/resources/extensions/gsd/auto-post-unit.ts +28 -14
  415. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  416. package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
  417. package/src/resources/extensions/gsd/auto-start.ts +237 -15
  418. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  419. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  420. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  421. package/src/resources/extensions/gsd/auto.ts +110 -22
  422. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +119 -2
  423. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  424. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  425. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
  426. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  427. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  428. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  429. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +386 -55
  430. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  431. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  432. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  433. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  434. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  435. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  436. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  437. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  438. package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
  439. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  440. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  441. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  442. package/src/resources/extensions/gsd/detection.ts +128 -0
  443. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  444. package/src/resources/extensions/gsd/git-service.ts +46 -8
  445. package/src/resources/extensions/gsd/graph.ts +12 -5
  446. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  447. package/src/resources/extensions/gsd/guided-flow.ts +150 -51
  448. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  449. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  450. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  451. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  452. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  453. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  454. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  455. package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
  456. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  457. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  458. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  459. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  460. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  461. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  462. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  463. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  464. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  466. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  467. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  468. package/src/resources/extensions/gsd/quick.ts +37 -2
  469. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  470. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  471. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  472. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
  473. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +516 -15
  474. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  475. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  476. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  477. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  478. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  479. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  480. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  481. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  482. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  483. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  484. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  485. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  486. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +117 -7
  487. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
  488. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  489. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  490. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  491. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  492. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  493. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  494. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  495. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  496. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  497. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  498. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  499. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  500. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  501. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  502. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  503. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  504. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  505. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  506. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  507. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  508. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  509. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  510. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  511. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  512. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  513. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  514. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  515. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  516. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  517. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  518. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  519. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  520. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  521. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  522. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  523. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  524. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  525. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  526. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  527. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  528. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  529. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  530. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  531. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  532. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  533. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  534. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  535. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  536. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  537. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
  538. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  539. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  540. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  541. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  542. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  543. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  544. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  545. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  546. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  547. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  548. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  549. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  550. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  551. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  552. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  553. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  554. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  555. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
  556. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  557. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  558. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  559. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  560. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  561. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
  562. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  563. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  564. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  565. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  566. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  567. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  568. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  569. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  570. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  571. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  572. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  573. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  574. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  575. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  576. package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
  577. package/packages/contracts/tsconfig.tsbuildinfo +0 -1
  578. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  579. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_buildManifest.js +0 -0
  580. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_ssgManifest.js +0 -0
@@ -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
 
@@ -173,6 +173,8 @@ export type ExtensionErrorListener = (error: ExtensionError) => void;
173
173
  export type NewSessionHandler = (options?: {
174
174
  parentSession?: string;
175
175
  setup?: (sessionManager: SessionManager) => Promise<void>;
176
+ /** Explicit workspace root for the new session/tool runtime. */
177
+ workspaceRoot?: string;
176
178
  /** See ExtensionCommandContext.newSession for docs (#3731). */
177
179
  abortSignal?: AbortSignal;
178
180
  }) => Promise<{ cancelled: boolean }>;
@@ -235,6 +237,7 @@ export class ExtensionRunner {
235
237
  private getContextUsageFn: () => ContextUsage | undefined = () => undefined;
236
238
  private compactFn: (options?: CompactOptions) => void = () => {};
237
239
  private getSystemPromptFn: () => string = () => "";
240
+ private setCompactionThresholdOverrideFn: (percent: number | undefined) => void = () => {};
238
241
  private newSessionHandler: NewSessionHandler = async () => {
239
242
  throw new Error("Command context not yet bound: newSession is unavailable during early lifecycle");
240
243
  };
@@ -274,11 +277,7 @@ export class ExtensionRunner {
274
277
  }
275
278
 
276
279
  private currentCwd(): string {
277
- try {
278
- return process.cwd();
279
- } catch {
280
- return this.cwd;
281
- }
280
+ return this.cwd;
282
281
  }
283
282
 
284
283
  /**
@@ -413,6 +412,8 @@ export class ExtensionRunner {
413
412
  this.runtime.getActiveTools = actions.getActiveTools;
414
413
  this.runtime.getAllTools = actions.getAllTools;
415
414
  this.runtime.setActiveTools = actions.setActiveTools;
415
+ this.runtime.getVisibleSkills = actions.getVisibleSkills;
416
+ this.runtime.setVisibleSkills = actions.setVisibleSkills;
416
417
  this.runtime.refreshTools = actions.refreshTools;
417
418
  this.runtime.getCommands = actions.getCommands;
418
419
  this.runtime.setModel = actions.setModel;
@@ -428,6 +429,7 @@ export class ExtensionRunner {
428
429
  this.getContextUsageFn = contextActions.getContextUsage;
429
430
  this.compactFn = contextActions.compact;
430
431
  this.getSystemPromptFn = contextActions.getSystemPrompt;
432
+ this.setCompactionThresholdOverrideFn = contextActions.setCompactionThresholdOverride;
431
433
 
432
434
  // Flush provider registrations queued during extension loading
433
435
  for (const { name, config } of this.runtime.pendingProviderRegistrations) {
@@ -714,9 +716,23 @@ export class ExtensionRunner {
714
716
  getContextUsage: () => this.getContextUsageFn(),
715
717
  compact: (options) => this.compactFn(options),
716
718
  getSystemPrompt: () => this.getSystemPromptFn(),
719
+ setCompactionThresholdOverride: (percent) => this.setCompactionThresholdOverrideFn(percent),
717
720
  };
718
721
  }
719
722
 
723
+ private createEventContext(eventType: string): ExtensionContext {
724
+ return {
725
+ ...this.createContext(),
726
+ shutdown: () => {
727
+ throw new Error(`Extension event '${eventType}' cannot request TUI shutdown`);
728
+ },
729
+ };
730
+ }
731
+
732
+ private isShutdownGuardedEvent(eventType: string): boolean {
733
+ return eventType === "agent_end" || eventType === "stop" || eventType === "session_end";
734
+ }
735
+
720
736
  createCommandContext(): ExtensionCommandContext {
721
737
  return {
722
738
  ...this.createContext(),
@@ -757,7 +773,9 @@ export class ExtensionRunner {
757
773
  getEvent: () => unknown,
758
774
  processResult: (handlerResult: unknown, extensionPath: string) => { done: boolean },
759
775
  ): Promise<void> {
760
- const ctx = this.createContext();
776
+ const ctx = this.isShutdownGuardedEvent(eventType)
777
+ ? this.createEventContext(eventType)
778
+ : this.createContext();
761
779
 
762
780
  for (const ext of this.extensions) {
763
781
  const handlers = ext.handlers.get(eventType);
@@ -289,6 +289,12 @@ export interface ExtensionContext {
289
289
  compact(options?: CompactOptions): void;
290
290
  /** Get the current effective system prompt. */
291
291
  getSystemPrompt(): string;
292
+ /**
293
+ * Set or clear an in-memory compaction threshold-percent override (0 < value < 1).
294
+ * Pass `undefined` to clear. The override is not persisted; host integrations
295
+ * are expected to re-apply on each session_start.
296
+ */
297
+ setCompactionThresholdOverride(percent: number | undefined): void;
292
298
  }
293
299
 
294
300
  /**
@@ -303,10 +309,13 @@ export interface ExtensionCommandContext extends ExtensionContext {
303
309
  newSession(options?: {
304
310
  parentSession?: string;
305
311
  setup?: (sessionManager: SessionManager) => Promise<void>;
312
+ /** Explicit workspace root for the new session/tool runtime.
313
+ * When omitted, newSession() captures process.cwd() for backwards compatibility. */
314
+ workspaceRoot?: string;
306
315
  /** When aborted before the session is fully configured, newSession() returns
307
316
  * early without rebuilding the tool runtime. Used by runUnit() to discard
308
317
  * a late-resolving newSession() after the session-creation timeout fires,
309
- * preventing the tool runtime from being rebuilt with the wrong cwd (#3731). */
318
+ * preventing the tool runtime from being rebuilt with a stale workspace root (#3731). */
310
319
  abortSignal?: AbortSignal;
311
320
  }): Promise<{ cancelled: boolean }>;
312
321
 
@@ -842,6 +851,13 @@ export interface BeforeModelSelectResult {
842
851
  modelId: string;
843
852
  }
844
853
 
854
+ export interface AdjustToolSetRequestCustomMessage {
855
+ /** Index in the post-transform AgentMessage context. */
856
+ index: number;
857
+ /** Custom message type only; prompt/content text is intentionally omitted. */
858
+ customType: string;
859
+ }
860
+
845
861
  /**
846
862
  * Fired after model selection to allow extensions to adjust the active tool set (ADR-005 Phase 4).
847
863
  * Extensions can add, remove, or reorder tools based on the selected model's provider capabilities.
@@ -858,6 +874,12 @@ export interface AdjustToolSetEvent {
858
874
  activeToolNames: string[];
859
875
  /** Tools already filtered by provider compatibility */
860
876
  filteredTools: string[];
877
+ /**
878
+ * Custom message metadata in the current request tail, measured from the
879
+ * latest assistant message. This is metadata-only so extensions can scope
880
+ * queued custom-message turns without seeing raw prompt content.
881
+ */
882
+ requestCustomMessages?: AdjustToolSetRequestCustomMessage[];
861
883
  }
862
884
 
863
885
  /** Result from adjust_tool_set event handler. Return { toolNames } to override tool set. */
@@ -1480,6 +1502,20 @@ export interface ExtensionAPI {
1480
1502
  /** Set the active tools by name. */
1481
1503
  setActiveTools(toolNames: string[]): void;
1482
1504
 
1505
+ /**
1506
+ * Get the prompt-only skill catalog filter, if one is active.
1507
+ * Undefined means all loaded skills remain visible in <available_skills>.
1508
+ */
1509
+ getVisibleSkills(): string[] | undefined;
1510
+
1511
+ /**
1512
+ * Set or clear the prompt-only skill catalog filter.
1513
+ *
1514
+ * This changes which loaded skills are advertised in <available_skills>;
1515
+ * it does not unload skills or disable the Skill tool.
1516
+ */
1517
+ setVisibleSkills(skillNames: string[] | undefined): void;
1518
+
1483
1519
  /** Get available slash commands in the current session. */
1484
1520
  getCommands(): SlashCommandInfo[];
1485
1521
 
@@ -1721,6 +1757,8 @@ export interface ExtensionActions {
1721
1757
  getActiveTools: () => string[];
1722
1758
  getAllTools: () => ToolInfo[];
1723
1759
  setActiveTools: (toolNames: string[]) => void;
1760
+ getVisibleSkills: () => string[] | undefined;
1761
+ setVisibleSkills: (skillNames: string[] | undefined) => void;
1724
1762
  refreshTools: () => void;
1725
1763
  getCommands: () => SlashCommandInfo[];
1726
1764
  setModel: (model: Model<any>, options?: { persist?: boolean }) => Promise<boolean>;
@@ -1741,6 +1779,7 @@ export interface ExtensionContextActions {
1741
1779
  getContextUsage: () => ContextUsage | undefined;
1742
1780
  compact: (options?: CompactOptions) => void;
1743
1781
  getSystemPrompt: () => string;
1782
+ setCompactionThresholdOverride: (percent: number | undefined) => void;
1744
1783
  }
1745
1784
 
1746
1785
  /**
@@ -1752,6 +1791,8 @@ export interface ExtensionCommandContextActions {
1752
1791
  newSession: (options?: {
1753
1792
  parentSession?: string;
1754
1793
  setup?: (sessionManager: SessionManager) => Promise<void>;
1794
+ /** See ExtensionCommandContext.newSession for docs. */
1795
+ workspaceRoot?: string;
1755
1796
  /** See ExtensionCommandContext.newSession for docs (#3731). */
1756
1797
  abortSignal?: AbortSignal;
1757
1798
  }) => Promise<{ cancelled: boolean }>;
@@ -38,6 +38,8 @@ function stubRuntime(): ExtensionRuntime {
38
38
  getActiveTools: () => [],
39
39
  getAllTools: () => [],
40
40
  setActiveTools: () => {},
41
+ getVisibleSkills: () => undefined,
42
+ setVisibleSkills: () => {},
41
43
  refreshTools: () => {},
42
44
  getCommands: () => [],
43
45
  setModel: async () => false,
@@ -578,6 +578,10 @@ export class ModelRegistry {
578
578
  * Defaults to "apiKey" for built-ins and providers without explicit mode.
579
579
  */
580
580
  getProviderAuthMode(provider: string): ProviderAuthMode {
581
+ // E2E-test-only: the fake provider is keyless. Sentinel is project-
582
+ // internal ("gsd-fake") so it cannot collide with a real provider.
583
+ // See packages/pi-ai/src/providers/fake.ts.
584
+ if (provider === "gsd-fake") return "none";
581
585
  const config = this.registeredProviders.get(provider);
582
586
  if (!config) return "apiKey";
583
587
  if (config.authMode) return config.authMode;
@@ -0,0 +1,60 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Tests final provider request-time tool compatibility filtering.
3
+
4
+ import assert from "node:assert/strict";
5
+ import test from "node:test";
6
+ import { Type } from "@sinclair/typebox";
7
+ import type { AgentTool } from "@gsd/pi-agent-core";
8
+ import { filterToolsForProviderRequest, getAdjustToolSetRequestCustomMessages } from "./sdk.js";
9
+ import { registerToolCompatibility, resetToolCompatibilityRegistry } from "./tools/tool-compatibility-registry.js";
10
+
11
+ function tool(name: string): AgentTool {
12
+ return {
13
+ name,
14
+ label: name,
15
+ description: name,
16
+ parameters: Type.Object({}),
17
+ execute: async () => ({ content: [], details: undefined }),
18
+ };
19
+ }
20
+
21
+ test("filterToolsForProviderRequest removes provider-incompatible tools", () => {
22
+ resetToolCompatibilityRegistry();
23
+ try {
24
+ registerToolCompatibility("image_result_tool", { producesImages: true });
25
+ registerToolCompatibility("complex_schema_tool", { schemaFeatures: ["patternProperties"] });
26
+
27
+ const result = filterToolsForProviderRequest(
28
+ [tool("bash"), tool("image_result_tool"), tool("complex_schema_tool")],
29
+ { api: "google-generative-ai", provider: "google" },
30
+ );
31
+
32
+ assert.deepEqual(result.compatible.map((entry) => entry.name), ["bash", "image_result_tool"]);
33
+ assert.deepEqual(result.filtered.map((entry) => entry.name), ["complex_schema_tool"]);
34
+ } finally {
35
+ resetToolCompatibilityRegistry();
36
+ }
37
+ });
38
+
39
+ test("filterToolsForProviderRequest enforces provider-specific hard caps at send time", () => {
40
+ const result = filterToolsForProviderRequest(
41
+ Array.from({ length: 130 }, (_, index) => tool(`tool_${index}`)),
42
+ { api: "openai-completions", provider: "groq" },
43
+ );
44
+
45
+ assert.equal(result.compatible.length, 128);
46
+ assert.deepEqual(result.filtered.map((entry) => entry.name), ["tool_128", "tool_129"]);
47
+ });
48
+
49
+ test("getAdjustToolSetRequestCustomMessages only reports custom messages in the current request tail", () => {
50
+ const messages = [
51
+ { role: "custom", customType: "gsd-run", content: "old workflow", display: false, timestamp: 1 },
52
+ { role: "assistant", content: [{ type: "text", text: "done" }], timestamp: 2 },
53
+ { role: "user", content: [{ type: "text", text: "normal prompt" }], timestamp: 3 },
54
+ { role: "custom", customType: "gsd-doctor-heal", content: "current workflow", display: false, timestamp: 4 },
55
+ ] as any[];
56
+
57
+ assert.deepEqual(getAdjustToolSetRequestCustomMessages(messages), [
58
+ { index: 3, customType: "gsd-doctor-heal" },
59
+ ]);
60
+ });