@opengsd/gsd-pi 1.0.2-dev.e70300c → 1.0.2-dev.fb7ddf1

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 (480) hide show
  1. package/README.md +63 -12
  2. package/dist/headless-answers.js +2 -1
  3. package/dist/headless-events.d.ts +1 -0
  4. package/dist/headless-events.js +8 -1
  5. package/dist/onboarding.js +22 -3
  6. package/dist/resource-loader.d.ts +7 -0
  7. package/dist/resource-loader.js +44 -9
  8. package/dist/resources/.managed-resources-content-hash +1 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -11
  10. package/dist/resources/extensions/context7/index.js +12 -2
  11. package/dist/resources/extensions/get-secrets-from-user.js +16 -16
  12. package/dist/resources/extensions/google-cli/index.js +30 -0
  13. package/dist/resources/extensions/google-cli/models.js +55 -0
  14. package/dist/resources/extensions/google-cli/package.json +11 -0
  15. package/dist/resources/extensions/google-cli/readiness.js +12 -0
  16. package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +81 -1
  18. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
  19. package/dist/resources/extensions/gsd/auto/phases.js +38 -1
  20. package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
  21. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
  23. package/dist/resources/extensions/gsd/auto-post-unit.js +65 -16
  24. package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
  25. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  26. package/dist/resources/extensions/gsd/auto-start.js +232 -49
  27. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -1
  28. package/dist/resources/extensions/gsd/auto-verification.js +14 -2
  29. package/dist/resources/extensions/gsd/auto-worktree.js +34 -1
  30. package/dist/resources/extensions/gsd/auto.js +40 -2
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
  32. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
  33. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +107 -27
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
  36. package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +4 -4
  37. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  38. package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
  40. package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
  41. package/dist/resources/extensions/gsd/commands-usage.js +105 -1
  42. package/dist/resources/extensions/gsd/config-overlay.js +20 -14
  43. package/dist/resources/extensions/gsd/context-overlay.js +22 -16
  44. package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
  45. package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
  46. package/dist/resources/extensions/gsd/doctor-git-checks.js +70 -5
  47. package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
  48. package/dist/resources/extensions/gsd/doctor.js +7 -2
  49. package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
  50. package/dist/resources/extensions/gsd/guided-flow.js +5 -6
  51. package/dist/resources/extensions/gsd/key-manager.js +45 -13
  52. package/dist/resources/extensions/gsd/mcp-filter.js +57 -18
  53. package/dist/resources/extensions/gsd/mcp-project-config.js +15 -9
  54. package/dist/resources/extensions/gsd/migration-auto-check.js +5 -1
  55. package/dist/resources/extensions/gsd/milestone-actions.js +3 -0
  56. package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
  57. package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
  58. package/dist/resources/extensions/gsd/parallel-merge.js +6 -4
  59. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
  60. package/dist/resources/extensions/gsd/post-execution-checks.js +5 -4
  61. package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
  62. package/dist/resources/extensions/gsd/preferences.js +14 -2
  63. package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
  64. package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
  65. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  66. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  67. package/dist/resources/extensions/gsd/prompts/system.md +3 -20
  68. package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
  69. package/dist/resources/extensions/gsd/repo-identity.js +36 -6
  70. package/dist/resources/extensions/gsd/repository-registry.js +3 -1
  71. package/dist/resources/extensions/gsd/safety/evidence-collector.js +13 -6
  72. package/dist/resources/extensions/gsd/skill-activation.js +233 -0
  73. package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
  74. package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
  75. package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
  76. package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
  77. package/dist/resources/extensions/gsd/skill-scope.js +52 -0
  78. package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
  79. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
  80. package/dist/resources/extensions/gsd/skills.js +60 -0
  81. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
  82. package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
  83. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
  84. package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
  85. package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
  86. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
  87. package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
  88. package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
  89. package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
  90. package/dist/resources/extensions/gsd/vision-ask.js +22 -0
  91. package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
  92. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
  93. package/dist/resources/extensions/gsd/worktree-state-projection.js +29 -0
  94. package/dist/resources/extensions/search-the-web/native-search.js +57 -8
  95. package/dist/resources/extensions/shared/confirm-ui.js +9 -6
  96. package/dist/resources/extensions/shared/dialog-frame.js +42 -0
  97. package/dist/resources/extensions/shared/interview-ui.js +42 -30
  98. package/dist/resources/extensions/shared/next-action-ui.js +6 -6
  99. package/dist/resources/extensions/subagent/index.js +8 -15
  100. package/dist/resources/shared/package-manager-detection.js +36 -0
  101. package/dist/resources/skills/agent-browser/SKILL.md +1 -1
  102. package/dist/resources/skills/api-design/SKILL.md +1 -1
  103. package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
  104. package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
  105. package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
  106. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  107. package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  108. package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  109. package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
  110. package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
  111. package/dist/resources/skills/forensics/SKILL.md +2 -2
  112. package/dist/resources/skills/grill-me/SKILL.md +1 -1
  113. package/dist/resources/skills/handoff/SKILL.md +1 -1
  114. package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  115. package/dist/resources/skills/observability/SKILL.md +1 -1
  116. package/dist/resources/skills/security-review/SKILL.md +1 -1
  117. package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
  118. package/dist/resources/skills/tdd/SKILL.md +1 -1
  119. package/dist/resources/skills/write-docs/SKILL.md +1 -1
  120. package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
  121. package/dist/update-check.d.ts +6 -2
  122. package/dist/update-check.js +7 -3
  123. package/dist/web/standalone/.next/BUILD_ID +1 -1
  124. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  125. package/dist/web/standalone/.next/build-manifest.json +2 -2
  126. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/index.html +1 -1
  145. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  152. package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
  153. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  155. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  156. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  157. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  158. package/package.json +5 -2
  159. package/packages/cloud-mcp-gateway/package.json +2 -2
  160. package/packages/contracts/dist/rpc.test.js +5 -0
  161. package/packages/contracts/dist/rpc.test.js.map +1 -1
  162. package/packages/contracts/dist/workflow.d.ts +15 -0
  163. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  164. package/packages/contracts/dist/workflow.js +16 -0
  165. package/packages/contracts/dist/workflow.js.map +1 -1
  166. package/packages/contracts/dist/workflow.test.js +1 -0
  167. package/packages/contracts/dist/workflow.test.js.map +1 -1
  168. package/packages/contracts/package.json +1 -1
  169. package/packages/daemon/package.json +4 -4
  170. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
  171. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  172. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
  173. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  174. package/packages/gsd-agent-core/package.json +5 -5
  175. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
  176. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
  177. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
  178. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
  179. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
  180. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
  182. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
  184. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
  186. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
  187. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  196. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
  198. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
  202. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  204. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
  205. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  206. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
  208. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  209. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
  210. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  211. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
  212. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  213. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  214. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
  215. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  216. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
  217. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  218. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
  219. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  220. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
  221. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
  222. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
  223. package/packages/gsd-agent-modes/package.json +7 -7
  224. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  225. package/packages/mcp-server/dist/server.js +7 -1
  226. package/packages/mcp-server/dist/server.js.map +1 -1
  227. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +47 -8
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/package.json +3 -3
  232. package/packages/native/package.json +1 -1
  233. package/packages/pi-agent-core/dist/agent-loop.js +16 -14
  234. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  235. package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
  236. package/packages/pi-agent-core/dist/harness/skills.js +6 -0
  237. package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
  238. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
  239. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
  240. package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
  241. package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
  242. package/packages/pi-agent-core/package.json +1 -1
  243. package/packages/pi-ai/dist/models.generated.d.ts +48 -206
  244. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  245. package/packages/pi-ai/dist/models.generated.js +67 -220
  246. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  247. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  248. package/packages/pi-ai/dist/providers/anthropic.js +50 -0
  249. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  250. package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
  252. package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/types.d.ts +2 -0
  254. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/types.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js +29 -1
  257. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
  258. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
  259. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
  261. package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
  262. package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
  263. package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
  264. package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
  265. package/packages/pi-ai/package.json +1 -1
  266. package/packages/pi-coding-agent/README.md +1 -1
  267. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
  268. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
  271. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
  274. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
  276. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/skills.js +3 -0
  278. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
  281. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
  283. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
  285. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
  288. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  289. package/packages/pi-coding-agent/package.json +8 -8
  290. package/packages/pi-tui/package.json +1 -1
  291. package/packages/rpc-client/package.json +2 -2
  292. package/pkg/package.json +1 -1
  293. package/scripts/install/detect-existing.js +17 -3
  294. package/scripts/install/npm-global.js +103 -33
  295. package/scripts/install.js +1 -0
  296. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
  297. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
  298. package/src/resources/extensions/context7/index.ts +15 -2
  299. package/src/resources/extensions/get-secrets-from-user.ts +17 -16
  300. package/src/resources/extensions/google-cli/index.ts +34 -0
  301. package/src/resources/extensions/google-cli/models.ts +57 -0
  302. package/src/resources/extensions/google-cli/package.json +11 -0
  303. package/src/resources/extensions/google-cli/readiness.ts +15 -0
  304. package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
  305. package/src/resources/extensions/gsd/auto/loop.ts +96 -1
  306. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
  307. package/src/resources/extensions/gsd/auto/phases.ts +47 -1
  308. package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
  309. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  310. package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
  311. package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
  312. package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
  313. package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
  314. package/src/resources/extensions/gsd/auto-start.ts +307 -56
  315. package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
  316. package/src/resources/extensions/gsd/auto-verification.ts +18 -2
  317. package/src/resources/extensions/gsd/auto-worktree.ts +45 -1
  318. package/src/resources/extensions/gsd/auto.ts +50 -2
  319. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
  320. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
  321. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
  322. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
  323. package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
  324. package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
  325. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  326. package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
  327. package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
  328. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  329. package/src/resources/extensions/gsd/commands-usage.ts +110 -5
  330. package/src/resources/extensions/gsd/config-overlay.ts +19 -16
  331. package/src/resources/extensions/gsd/context-overlay.ts +24 -19
  332. package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
  333. package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
  334. package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
  335. package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
  336. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  337. package/src/resources/extensions/gsd/doctor.ts +7 -2
  338. package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
  339. package/src/resources/extensions/gsd/guided-flow.ts +5 -6
  340. package/src/resources/extensions/gsd/key-manager.ts +57 -14
  341. package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
  342. package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
  343. package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
  344. package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
  345. package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
  346. package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
  347. package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
  348. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
  349. package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
  350. package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
  351. package/src/resources/extensions/gsd/preferences.ts +17 -2
  352. package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
  353. package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
  354. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  355. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  356. package/src/resources/extensions/gsd/prompts/system.md +3 -20
  357. package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
  358. package/src/resources/extensions/gsd/repo-identity.ts +35 -7
  359. package/src/resources/extensions/gsd/repository-registry.ts +3 -1
  360. package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
  361. package/src/resources/extensions/gsd/skill-activation.ts +292 -0
  362. package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
  363. package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
  364. package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
  365. package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
  366. package/src/resources/extensions/gsd/skill-scope.ts +63 -0
  367. package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
  368. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
  369. package/src/resources/extensions/gsd/skills.ts +75 -0
  370. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
  371. package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
  372. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
  373. package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
  374. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
  375. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
  376. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
  377. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
  378. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
  379. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
  380. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
  381. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
  382. package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
  383. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
  384. package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
  385. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
  386. package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
  387. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
  388. package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
  389. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
  390. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
  391. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
  392. package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
  393. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
  394. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
  395. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
  396. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
  397. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
  398. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
  399. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
  400. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
  401. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
  402. package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
  403. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
  404. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
  405. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
  406. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
  407. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
  408. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
  409. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
  410. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
  411. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
  412. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
  413. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
  414. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
  415. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
  416. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
  417. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
  418. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
  419. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
  420. package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
  421. package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
  422. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
  423. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
  424. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
  425. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
  426. package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
  427. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
  428. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
  429. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
  430. package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
  431. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
  432. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
  433. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
  434. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
  435. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
  436. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
  437. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
  438. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
  439. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
  440. package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
  441. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
  442. package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
  443. package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
  444. package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
  445. package/src/resources/extensions/gsd/vision-ask.ts +28 -0
  446. package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
  447. package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
  448. package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
  449. package/src/resources/extensions/search-the-web/native-search.ts +60 -8
  450. package/src/resources/extensions/shared/confirm-ui.ts +8 -12
  451. package/src/resources/extensions/shared/dialog-frame.ts +71 -0
  452. package/src/resources/extensions/shared/interview-ui.ts +43 -42
  453. package/src/resources/extensions/shared/next-action-ui.ts +6 -6
  454. package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
  455. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
  456. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
  457. package/src/resources/extensions/subagent/index.ts +8 -15
  458. package/src/resources/shared/package-manager-detection.ts +39 -0
  459. package/src/resources/skills/agent-browser/SKILL.md +1 -1
  460. package/src/resources/skills/api-design/SKILL.md +1 -1
  461. package/src/resources/skills/code-optimizer/SKILL.md +6 -11
  462. package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
  463. package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
  464. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  465. package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  466. package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  467. package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
  468. package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
  469. package/src/resources/skills/forensics/SKILL.md +2 -2
  470. package/src/resources/skills/grill-me/SKILL.md +1 -1
  471. package/src/resources/skills/handoff/SKILL.md +1 -1
  472. package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  473. package/src/resources/skills/observability/SKILL.md +1 -1
  474. package/src/resources/skills/security-review/SKILL.md +1 -1
  475. package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
  476. package/src/resources/skills/tdd/SKILL.md +1 -1
  477. package/src/resources/skills/write-docs/SKILL.md +1 -1
  478. package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
  479. /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
  480. /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
@@ -8,6 +8,7 @@ import {
8
8
  scanSessionTokenTotals,
9
9
  handleUsage,
10
10
  } from "../commands-usage.ts";
11
+ import { assertFullOuterBorder } from "./tui-border-assertions.ts";
11
12
 
12
13
  const TS = 1;
13
14
 
@@ -108,3 +109,99 @@ test("handleUsage emits JSON when --json is passed", async () => {
108
109
  assert.equal(parsed.contextUsage.tokens, 10_000);
109
110
  assert.equal(parsed.sessionTotals.input, 0);
110
111
  });
112
+
113
+ test("handleUsage renders interactive usage output inside a full border", async () => {
114
+ let renderFn: ((width: number) => string[]) | undefined;
115
+ const messages: string[] = [];
116
+ const ctx = {
117
+ hasUI: true,
118
+ model: { provider: "claude-code", id: "claude-sonnet-4-6", contextWindow: 200_000 },
119
+ getContextUsage: () => ({ tokens: 10_000, contextWindow: 200_000, percent: 5 }),
120
+ sessionManager: { getEntries: () => [] },
121
+ ui: {
122
+ custom: async (factory: any) => {
123
+ const theme = {
124
+ fg: (_color: string, text: string) => text,
125
+ bold: (text: string) => text,
126
+ };
127
+ const component = factory({ requestRender: () => {} }, theme, {}, () => {});
128
+ renderFn = component.render;
129
+ return true;
130
+ },
131
+ notify(message: string) {
132
+ messages.push(message);
133
+ },
134
+ },
135
+ };
136
+
137
+ await handleUsage("", ctx as any);
138
+
139
+ assert.equal(messages.length, 0, "interactive usage should use the dialog instead of notify");
140
+ assert.ok(renderFn, "render function should have been captured");
141
+ const lines = renderFn!(80);
142
+ assertFullOuterBorder(lines, 80);
143
+ assert.match(lines.join("\n"), /claude-code\/claude-sonnet-4-6/);
144
+ });
145
+
146
+ test("handleUsage keeps short-terminal usage dialog scrollable", async () => {
147
+ const originalRowsDescriptor = Object.getOwnPropertyDescriptor(process.stdout, "rows");
148
+ Object.defineProperty(process.stdout, "rows", { value: 10, configurable: true });
149
+
150
+ try {
151
+ let component: { render(width: number): string[]; handleInput(data: string): void } | undefined;
152
+ let closed = false;
153
+ const ctx = {
154
+ hasUI: true,
155
+ model: { provider: "claude-code", id: "claude-sonnet-4-6", contextWindow: 200_000 },
156
+ getContextUsage: () => ({ tokens: 10_000, contextWindow: 200_000, percent: 5 }),
157
+ sessionManager: {
158
+ getEntries: () => sessionEntries({
159
+ role: "assistant",
160
+ usage: {
161
+ input: 1000,
162
+ output: 200,
163
+ cacheRead: 500,
164
+ cacheWrite: 100,
165
+ totalTokens: 1800,
166
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0.05 },
167
+ },
168
+ content: [{ type: "toolCall", id: "tc-1", name: "read", arguments: {} }],
169
+ timestamp: TS,
170
+ }),
171
+ },
172
+ ui: {
173
+ custom: async (factory: any) => {
174
+ const theme = {
175
+ fg: (_color: string, text: string) => text,
176
+ bold: (text: string) => text,
177
+ };
178
+ component = factory({ requestRender: () => {} }, theme, {}, () => {
179
+ closed = true;
180
+ });
181
+ return true;
182
+ },
183
+ notify() {},
184
+ },
185
+ };
186
+
187
+ await handleUsage("", ctx as any);
188
+
189
+ assert.ok(component, "usage dialog should render via custom UI");
190
+ const initialLines = component.render(80);
191
+ assert.ok(initialLines.length <= 8, `usage dialog should fit 80% terminal height, got ${initialLines.length}`);
192
+
193
+ for (let i = 0; i < 10; i++) component.handleInput("\u001b[B");
194
+
195
+ assert.equal(closed, false, "scroll keys should not close a scrollable usage dialog");
196
+ assert.match(component.render(80).join("\n"), /Tool calls: 1/);
197
+
198
+ component.handleInput("x");
199
+ assert.equal(closed, true, "non-scroll keys should close the usage dialog");
200
+ } finally {
201
+ if (originalRowsDescriptor) {
202
+ Object.defineProperty(process.stdout, "rows", originalRowsDescriptor);
203
+ } else {
204
+ delete (process.stdout as { rows?: number }).rows;
205
+ }
206
+ }
207
+ });
@@ -2,7 +2,7 @@
2
2
 
3
3
  import test from "node:test";
4
4
  import assert from "node:assert/strict";
5
- import { mkdirSync } from "node:fs";
5
+ import { mkdirSync, writeFileSync } from "node:fs";
6
6
  import { join } from "node:path";
7
7
 
8
8
  import { postUnitPreVerification } from "../auto-post-unit.ts";
@@ -70,7 +70,9 @@ test("complete-slice with gsd_task_reopen handoff continues instead of artifact-
70
70
  test("complete-slice with gsd_replan_slice tool result continues instead of artifact-retrying", async () => {
71
71
  const base = makeTempRepo("gsd-complete-slice-replan-");
72
72
  try {
73
- mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
73
+ const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
74
+ mkdirSync(sliceDir, { recursive: true });
75
+ writeFileSync(join(sliceDir, "S01-REPLAN.md"), "# Replan\n");
74
76
 
75
77
  const s = new AutoSession();
76
78
  s.active = true;
@@ -101,10 +103,45 @@ test("complete-slice with gsd_replan_slice tool result continues instead of arti
101
103
  assert.equal(s.pendingVerificationRetry, null);
102
104
  assert.equal(s.verificationRetryCount.has(retryKey), false);
103
105
  assert.ok(
104
- notifications.some((message) => message.includes("handed off via reopen/replan")),
106
+ notifications.some((message) => message.includes("valid replan outcome")),
105
107
  `expected handoff notification, got: ${notifications.join("\n")}`,
106
108
  );
107
109
  } finally {
108
110
  cleanup(base);
109
111
  }
110
112
  });
113
+
114
+ test("complete-slice with gsd_replan_slice but no REPLAN artifact retries", async () => {
115
+ const base = makeTempRepo("gsd-complete-slice-replan-missing-artifact-");
116
+ try {
117
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
118
+
119
+ const s = new AutoSession();
120
+ s.active = true;
121
+ s.basePath = base;
122
+ s.currentUnit = { type: "complete-slice", id: "M001/S01", startedAt: Date.now() };
123
+
124
+ const notifications: string[] = [];
125
+ const result = await postUnitPreVerification(
126
+ makePostUnitContext(base, s, notifications),
127
+ {
128
+ skipSettleDelay: true,
129
+ skipWorktreeSync: true,
130
+ agentEndMessages: [
131
+ {
132
+ role: "toolResult",
133
+ toolName: "gsd_replan_slice",
134
+ isError: false,
135
+ content: "Slice replanned with reopened task T02.",
136
+ },
137
+ ],
138
+ },
139
+ );
140
+
141
+ assert.equal(result, "retry");
142
+ assert.ok(s.pendingVerificationRetry);
143
+ assert.equal(s.pendingVerificationRetry?.unitId, "M001/S01");
144
+ } finally {
145
+ cleanup(base);
146
+ }
147
+ });
@@ -10,6 +10,7 @@ import type { ContextBreakdownReport } from "../commands-context.ts";
10
10
  import { buildContextChartHtml, writeContextChartHtml } from "../context-chart-html.ts";
11
11
  import { formatContextChartText, getContextChartTotals } from "../context-overlay.ts";
12
12
  import { buildContextBreakdown } from "../commands-context.ts";
13
+ import { assertFullOuterBorder } from "./tui-border-assertions.ts";
13
14
 
14
15
  const TS = 1;
15
16
 
@@ -103,3 +104,11 @@ test("formatContextChartText includes chart sections", () => {
103
104
  assert.match(text, /Conversation/);
104
105
  assert.match(text, /█/);
105
106
  });
107
+
108
+ test("formatContextChartText renders the context dialog inside a full border", () => {
109
+ const lines = formatContextChartText(SAMPLE_REPORT, 80).split("\n");
110
+ assertFullOuterBorder(lines, 80);
111
+ assert.match(lines[0] ?? "", /^╭─ Context Breakdown /);
112
+ assert.ok(lines.some((line) => line.startsWith("│")), "body rows should have side borders");
113
+ assert.match(lines.at(-1) ?? "", /^╰─+╯$/);
114
+ });
@@ -344,6 +344,70 @@ describe("Custom engine loop integration", () => {
344
344
  );
345
345
  });
346
346
 
347
+ it("step mode stops after one custom workflow step", async () => {
348
+ _resetPendingResolve();
349
+
350
+ const runDir = makeTmpDir();
351
+ const graph = makeGraph([
352
+ makeStep({ id: "step-a" }),
353
+ makeStep({ id: "step-b", dependsOn: ["step-a"] }),
354
+ makeStep({ id: "step-c", dependsOn: ["step-b"] }),
355
+ ], "step-mode-custom");
356
+ writeGraph(runDir, graph);
357
+ writeDefinition(runDir, graph.steps, "step-mode-custom");
358
+
359
+ const ctx = makeMockCtx();
360
+ const pi = makeMockPi();
361
+ const s = makeLoopSession({
362
+ activeEngineId: "custom",
363
+ activeRunDir: runDir,
364
+ basePath: runDir,
365
+ stepMode: true,
366
+ });
367
+
368
+ const deps = makeMockDeps({
369
+ stopAuto: async (_ctx, _pi, reason) => {
370
+ deps.callLog.push(`stopAuto:${reason ?? "no-reason"}`);
371
+ s.active = false;
372
+ },
373
+ });
374
+
375
+ const loopPromise = autoLoop(ctx, pi, s, deps);
376
+ await resolveNextAgentEnd();
377
+
378
+ let timeout: NodeJS.Timeout | undefined;
379
+ try {
380
+ await Promise.race([
381
+ loopPromise,
382
+ new Promise((_, reject) =>
383
+ timeout = setTimeout(() => {
384
+ s.active = false;
385
+ if (_hasPendingResolveForTest()) {
386
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
387
+ }
388
+ reject(new Error(
389
+ `step mode did not stop after one custom workflow step; calls=${pi.calls.length}; log=${deps.callLog.join(",")}`,
390
+ ));
391
+ }, 1_000),
392
+ ),
393
+ ]);
394
+ } finally {
395
+ if (timeout) clearTimeout(timeout);
396
+ }
397
+
398
+ const finalGraph = readGraph(runDir);
399
+ assert.equal(pi.calls.length, 1, "step mode should dispatch exactly one custom step");
400
+ assert.equal(finalGraph.steps[0]?.status, "complete", "first step should complete");
401
+ assert.equal(finalGraph.steps[1]?.status, "pending", "second step should wait for the next /gsd next");
402
+ assert.equal(finalGraph.steps[2]?.status, "pending", "third step should wait for a later step");
403
+ assert.equal(
404
+ deps.callLog.some((e: string) => e.startsWith("stopAuto:")),
405
+ false,
406
+ "step-mode pause should not complete or stop the whole workflow",
407
+ );
408
+ assert.equal(s.preserveStepSurfaceAfterLoopExit, true);
409
+ });
410
+
347
411
  it("stops when engine reports isComplete on first derive", async () => {
348
412
  _resetPendingResolve();
349
413
 
@@ -0,0 +1,25 @@
1
+ /**
2
+ * GSD dashboard overlay dialog chrome tests.
3
+ */
4
+
5
+ import test from "node:test";
6
+ import assert from "node:assert/strict";
7
+
8
+ import { GSDDashboardOverlay } from "../dashboard-overlay.ts";
9
+ import { assertFullOuterBorder } from "./tui-border-assertions.ts";
10
+
11
+ const fakeTheme = {
12
+ fg: (_color: string, text: string) => text,
13
+ bold: (text: string) => text,
14
+ };
15
+
16
+ test("GSDDashboardOverlay renders inside the shared full border", (t) => {
17
+ const overlay = new GSDDashboardOverlay({ requestRender() {} }, fakeTheme as any, () => {});
18
+ t.after(() => overlay.dispose());
19
+
20
+ const lines = overlay.render(100);
21
+ assertFullOuterBorder(lines, 100);
22
+ assert.match(lines[0] ?? "", /^╭─ GSD Dashboard /);
23
+ assert.ok(lines.some((line) => line.startsWith("│")), "body rows should have side borders");
24
+ assert.match(lines.at(-1) ?? "", /^╰─+╯$/);
25
+ });
@@ -19,6 +19,7 @@ const VALID_INVITE = "https://discord.gg/8NnkKuepmQ";
19
19
  const FILES_WITH_INVITE_LINKS: string[] = [
20
20
  "README.md",
21
21
  "docs/dev/what-is-pi/15-pi-packages-the-ecosystem.md",
22
+ "packages/pi-coding-agent/README.md",
22
23
  ];
23
24
 
24
25
  describe("Discord invite links (#2699)", () => {
@@ -9,7 +9,9 @@ const discussPrompt = readFileSync(promptPath, "utf-8");
9
9
  test("discuss prompt: resilient vision framing", () => {
10
10
  const hardenedPattern = /Say exactly:\s*"What's the vision\?"/;
11
11
  assert.ok(!hardenedPattern.test(discussPrompt), "prompt no longer uses exact-verbosity lock");
12
- assert.ok(discussPrompt.includes('Ask: "What\'s the vision?" once'), "prompt asks for vision exactly once");
12
+ assert.ok(discussPrompt.includes('Ask exactly this once: "{{visionAsk}}"'), "prompt asks the injected vision opener exactly once");
13
+ assert.ok(discussPrompt.includes("The opener is intentionally variable"), "prompt documents variable opener voice");
13
14
  assert.ok(discussPrompt.includes("Special handling"), "prompt documents special handling");
14
- assert.ok(discussPrompt.includes('instead of repeating "What\'s the vision?"'), "prompt forbids repeating");
15
+ assert.ok(discussPrompt.includes("instead of repeating the opener"), "prompt forbids repeating the opener");
16
+ assert.ok(!discussPrompt.includes('"What\'s the vision?"'), "prompt no longer freezes the old opener");
15
17
  });
@@ -111,7 +111,7 @@ describe("discuss tool scoping (#2949)", () => {
111
111
  setCalls.push([...tools]);
112
112
  activeTools = [...tools];
113
113
  },
114
- sendMessage: (message: unknown) => {
114
+ sendMessage: async (message: unknown) => {
115
115
  sent.push(message);
116
116
  sentTools = [...activeTools];
117
117
  },
@@ -4,7 +4,7 @@
4
4
  import test from "node:test";
5
5
  import assert from "node:assert/strict";
6
6
  import { execFileSync } from "node:child_process";
7
- import { existsSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
7
+ import { existsSync, mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
8
8
  import { tmpdir } from "node:os";
9
9
  import { join } from "node:path";
10
10
 
@@ -30,6 +30,17 @@ function makeRepo(): string {
30
30
  return base;
31
31
  }
32
32
 
33
+ function makeRepoWithOnlyGitignoreCommitted(): string {
34
+ const base = mkdtempSync(join(tmpdir(), "gsd-doctor-empty-worktree-"));
35
+ runGit(["init", "-b", "main"], base);
36
+ runGit(["config", "user.name", "Test User"], base);
37
+ runGit(["config", "user.email", "test@example.com"], base);
38
+ writeFileSync(join(base, ".gitignore"), "node_modules\n", "utf-8");
39
+ runGit(["add", "."], base);
40
+ runGit(["commit", "-m", "chore: init gitignore"], base);
41
+ return base;
42
+ }
43
+
33
44
  test("doctor fix recreates an empty registered milestone worktree", async (t) => {
34
45
  const base = makeRepo();
35
46
  t.after(() => rmSync(base, { recursive: true, force: true }));
@@ -63,3 +74,62 @@ test("doctor fix recreates an empty registered milestone worktree", async (t) =>
63
74
  assert.ok(existsSync(join(wtPath, "package.json")), "worktree content is restored");
64
75
  assert.ok(existsSync(join(wtPath, "milestone-note.txt")), "branch content is restored");
65
76
  });
77
+
78
+ test("doctor fix recreates an empty worktree when cwd is inside that worktree", async (t) => {
79
+ const base = makeRepo();
80
+ const originalCwd = process.cwd();
81
+ t.after(() => {
82
+ try {
83
+ process.chdir(originalCwd);
84
+ } catch { /* ignore deleted cwd during cleanup */ }
85
+ rmSync(base, { recursive: true, force: true });
86
+ });
87
+
88
+ createWorktree(base, "M001", { branch: "milestone/M001" });
89
+ const wtPath = worktreePath(base, "M001");
90
+ for (const entry of readdirSync(wtPath)) {
91
+ if (entry === ".git") continue;
92
+ rmSync(join(wtPath, entry), { recursive: true, force: true });
93
+ }
94
+ process.chdir(wtPath);
95
+
96
+ const report = await runGSDDoctor(base, {
97
+ fix: true,
98
+ fixLevel: "all",
99
+ isolationMode: "worktree",
100
+ });
101
+
102
+ assert.ok(
103
+ report.fixesApplied.some((fix) => fix.includes("recreated empty worktree")),
104
+ "doctor applies the repair while cwd is in the worktree",
105
+ );
106
+ assert.ok(existsSync(join(wtPath, "package.json")), "worktree content is restored");
107
+ });
108
+
109
+ test("doctor fix imports untracked project-root content when the worktree only has git metadata", async (t) => {
110
+ const base = makeRepoWithOnlyGitignoreCommitted();
111
+ t.after(() => rmSync(base, { recursive: true, force: true }));
112
+
113
+ mkdirSync(join(base, ".gsd"), { recursive: true });
114
+ writeFileSync(join(base, ".gsd", "PREFERENCES.md"), "---\ngit:\n isolation: worktree\n---\n", "utf-8");
115
+ writeFileSync(join(base, "package.json"), "{\"scripts\":{}}\n", "utf-8");
116
+ createWorktree(base, "M001", { branch: "milestone/M001" });
117
+ const wtPath = worktreePath(base, "M001");
118
+ assert.ok(existsSync(join(wtPath, ".gitignore")), "test setup keeps committed non-content metadata");
119
+ assert.equal(existsSync(join(wtPath, "package.json")), false, "test setup leaves project content only at the root");
120
+
121
+ const report = await runGSDDoctor(base, {
122
+ fix: true,
123
+ fixLevel: "all",
124
+ });
125
+
126
+ assert.ok(
127
+ report.issues.some((issue) => issue.code === "worktree_empty_with_project_content"),
128
+ "doctor reports the empty worktree even when .gitignore exists",
129
+ );
130
+ assert.ok(
131
+ report.fixesApplied.some((fix) => fix.includes("copied") && fix.includes("project file")),
132
+ "doctor copies the root project content into the recreated worktree",
133
+ );
134
+ assert.ok(existsSync(join(wtPath, "package.json")), "untracked project content is restored into the worktree");
135
+ });
@@ -702,6 +702,48 @@ test("runProviderChecks reports ok for claude-code without any API key", () => {
702
702
  rmSync(tmpHome, { recursive: true, force: true });
703
703
  });
704
704
 
705
+ test("runProviderChecks reports errors for required Google CLI providers missing from PATH", () => {
706
+ const scenarios = [
707
+ { provider: "google-gemini-cli", label: "Google Gemini CLI", model: "gemini-2.5-pro" },
708
+ { provider: "google-antigravity", label: "Antigravity", model: "default" },
709
+ ];
710
+
711
+ for (const { provider, label, model } of scenarios) {
712
+ const repo = realpathSync(mkdtempSync(join(tmpdir(), `gsd-providers-${provider}-repo-`)));
713
+ mkdirSync(join(repo, ".gsd"), { recursive: true });
714
+ writeFileSync(
715
+ join(repo, ".gsd", "PREFERENCES.md"),
716
+ [
717
+ "---",
718
+ "models:",
719
+ " execution:",
720
+ ` model: ${model}`,
721
+ ` provider: ${provider}`,
722
+ "---",
723
+ "",
724
+ ].join("\n"),
725
+ );
726
+
727
+ const tmpHome = realpathSync(mkdtempSync(join(tmpdir(), `gsd-providers-${provider}-home-`)));
728
+
729
+ withEnv({
730
+ HOME: tmpHome,
731
+ PATH: tmpHome,
732
+ }, () => {
733
+ withCwd(repo, () => {
734
+ const results = runProviderChecks();
735
+ const cli = results.find(r => r.name === provider);
736
+ assert.ok(cli, `${provider} result should exist`);
737
+ assert.equal(cli!.status, "error", `${provider} should error when the CLI binary is missing`);
738
+ assert.ok(cli!.detail?.includes(label), "should explain which CLI must be installed");
739
+ });
740
+ });
741
+
742
+ rmSync(repo, { recursive: true, force: true });
743
+ rmSync(tmpHome, { recursive: true, force: true });
744
+ }
745
+ });
746
+
705
747
  test("runProviderChecks reports ok for Anthropic via claude-code binary in PATH", () => {
706
748
  // Simulate a user who has no Anthropic API key but has the claude CLI installed.
707
749
  // Their PREFERENCES use a claude model without an explicit provider, so the doctor
@@ -736,6 +778,69 @@ test("runProviderChecks reports ok for Anthropic via claude-code binary in PATH"
736
778
  });
737
779
  });
738
780
 
781
+ test("runProviderChecks ignores external CLI auth sentinels when the CLI is missing", () => {
782
+ const scenarios = [
783
+ {
784
+ requiredProvider: "anthropic",
785
+ routeProvider: "claude-code",
786
+ model: "claude-sonnet-4-6",
787
+ env: {
788
+ ANTHROPIC_API_KEY: undefined,
789
+ ANTHROPIC_OAUTH_TOKEN: undefined,
790
+ COPILOT_GITHUB_TOKEN: undefined,
791
+ GH_TOKEN: undefined,
792
+ GITHUB_TOKEN: undefined,
793
+ },
794
+ },
795
+ {
796
+ requiredProvider: "google",
797
+ routeProvider: "google-gemini-cli",
798
+ model: "gemini-2.5-pro",
799
+ env: {
800
+ GEMINI_API_KEY: undefined,
801
+ GOOGLE_API_KEY: undefined,
802
+ },
803
+ },
804
+ ];
805
+
806
+ for (const { requiredProvider, routeProvider, model, env } of scenarios) {
807
+ const repo = realpathSync(mkdtempSync(join(tmpdir(), `gsd-providers-${routeProvider}-sentinel-repo-`)));
808
+ const tmpHome = realpathSync(mkdtempSync(join(tmpdir(), `gsd-providers-${routeProvider}-sentinel-home-`)));
809
+ const agentDir = join(tmpHome, ".gsd", "agent");
810
+ mkdirSync(join(repo, ".gsd"), { recursive: true });
811
+ mkdirSync(agentDir, { recursive: true });
812
+ writeFileSync(
813
+ join(repo, ".gsd", "PREFERENCES.md"),
814
+ [
815
+ "---",
816
+ "models:",
817
+ ` execution: ${model}`,
818
+ "---",
819
+ "",
820
+ ].join("\n"),
821
+ );
822
+ writeFileSync(join(agentDir, "auth.json"), JSON.stringify({
823
+ [routeProvider]: { type: "api_key", key: "cli" },
824
+ }));
825
+
826
+ withEnv({
827
+ ...env,
828
+ HOME: tmpHome,
829
+ PATH: tmpHome,
830
+ }, () => {
831
+ withCwd(repo, () => {
832
+ const results = runProviderChecks();
833
+ const provider = results.find(r => r.name === requiredProvider);
834
+ assert.ok(provider, `${requiredProvider} result should exist`);
835
+ assert.equal(provider!.status, "error", `${routeProvider} sentinel should not satisfy ${requiredProvider}`);
836
+ });
837
+ });
838
+
839
+ rmSync(repo, { recursive: true, force: true });
840
+ rmSync(tmpHome, { recursive: true, force: true });
841
+ }
842
+ });
843
+
739
844
  test("runProviderChecks detects claude.cmd in PATH on Windows (#4503)", { skip: process.platform !== "win32" }, () => {
740
845
  const tmpHome = realpathSync(mkdtempSync(join(tmpdir(), "gsd-providers-cc-win-route-home-")));
741
846
  const binDir = join(tmpHome, "bin");
@@ -1,11 +1,12 @@
1
1
  import { afterEach, test } from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { closeDatabase } from "../gsd-db.ts";
3
+ import { _getAdapter, closeDatabase, insertMilestone, openDatabase } from "../gsd-db.ts";
4
4
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { join } from "node:path";
6
6
  import { tmpdir } from "node:os";
7
7
  import { filterDoctorIssues } from "../doctor-format.ts";
8
8
  import { checkEngineHealth } from "../doctor-engine-checks.ts";
9
+ import { appendEvent } from "../workflow-events.ts";
9
10
 
10
11
  afterEach(() => {
11
12
  closeDatabase();
@@ -41,3 +42,102 @@ test("checkEngineHealth reports db_unavailable when gsd.db exists but the DB is
41
42
  assert.equal(dbIssue.unitId, "project");
42
43
  assert.equal(dbIssue.file, ".gsd/gsd.db");
43
44
  });
45
+
46
+ test("checkEngineHealth reads canonical reopen events from worktree bases", async (t) => {
47
+ const base = mkdtempSync(join(tmpdir(), "gsd-doctor-reopen-worktree-"));
48
+ t.after(() => rmSync(base, { recursive: true, force: true }));
49
+
50
+ const gsdDir = join(base, ".gsd");
51
+ const worktree = join(gsdDir, "worktrees", "M001");
52
+ mkdirSync(join(worktree, ".gsd"), { recursive: true });
53
+ writeFileSync(join(worktree, ".git"), "gitdir: ../../../../.git/worktrees/M001\n", "utf-8");
54
+
55
+ openDatabase(join(gsdDir, "gsd.db"));
56
+ insertMilestone({ id: "M001", title: "Reopened", status: "active" });
57
+ const db = _getAdapter()!;
58
+ db.prepare(
59
+ `INSERT INTO workers (
60
+ worker_id, host, pid, started_at, version, last_heartbeat_at, status, project_root_realpath
61
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
62
+ ).run("worker-1", "localhost", 1, "2026-01-01T00:00:00.000Z", "test", "2026-01-01T00:00:00.000Z", "stopped", base);
63
+ db.prepare(
64
+ `INSERT INTO unit_dispatches (
65
+ trace_id, worker_id, milestone_lease_token, milestone_id,
66
+ unit_type, unit_id, status, attempt_n, started_at, ended_at
67
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
68
+ ).run(
69
+ "trace-1",
70
+ "worker-1",
71
+ 1,
72
+ "M001",
73
+ "complete-milestone",
74
+ "M001",
75
+ "completed",
76
+ 1,
77
+ "2026-01-01T00:00:00.000Z",
78
+ "2026-01-01T00:00:01.000Z",
79
+ );
80
+ appendEvent(base, {
81
+ cmd: "reopen-milestone",
82
+ params: { milestoneId: "M001" },
83
+ ts: "2026-01-01T00:00:02.000Z",
84
+ actor: "agent",
85
+ });
86
+
87
+ const issues: any[] = [];
88
+ await checkEngineHealth(worktree, issues, []);
89
+
90
+ assert.equal(
91
+ issues.some((issue) => issue.code === "completed_milestone_reopened"),
92
+ false,
93
+ "canonical reopen event should exempt the reopened milestone from doctor drift errors",
94
+ );
95
+ });
96
+
97
+ test("checkEngineHealth treats explicit reopen as authoritative when dispatch timestamps are missing", async (t) => {
98
+ const base = mkdtempSync(join(tmpdir(), "gsd-doctor-reopen-no-dispatch-time-"));
99
+ t.after(() => rmSync(base, { recursive: true, force: true }));
100
+
101
+ const gsdDir = join(base, ".gsd");
102
+ mkdirSync(gsdDir, { recursive: true });
103
+
104
+ openDatabase(join(gsdDir, "gsd.db"));
105
+ insertMilestone({ id: "M001", title: "Reopened", status: "active" });
106
+ const db = _getAdapter()!;
107
+ db.prepare(
108
+ `INSERT INTO workers (
109
+ worker_id, host, pid, started_at, version, last_heartbeat_at, status, project_root_realpath
110
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
111
+ ).run("worker-1", "localhost", 1, "2026-01-01T00:00:00.000Z", "test", "2026-01-01T00:00:00.000Z", "stopped", base);
112
+ db.exec("PRAGMA writable_schema = ON");
113
+ db.prepare(
114
+ `UPDATE sqlite_schema
115
+ SET sql = replace(sql, 'started_at TEXT NOT NULL', 'started_at TEXT')
116
+ WHERE type = 'table' AND name = 'unit_dispatches'`,
117
+ ).run();
118
+ db.exec("PRAGMA writable_schema = OFF");
119
+ closeDatabase();
120
+ openDatabase(join(gsdDir, "gsd.db"));
121
+ const reopenedDb = _getAdapter()!;
122
+ reopenedDb.prepare(
123
+ `INSERT INTO unit_dispatches (
124
+ trace_id, worker_id, milestone_lease_token, milestone_id,
125
+ unit_type, unit_id, status, attempt_n, started_at, ended_at
126
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
127
+ ).run("trace-1", "worker-1", 1, "M001", "complete-milestone", "M001", "completed", 1, null, null);
128
+ appendEvent(base, {
129
+ cmd: "reopen-milestone",
130
+ params: { milestoneId: "M001" },
131
+ ts: "2026-01-01T00:00:02.000Z",
132
+ actor: "agent",
133
+ });
134
+
135
+ const issues: any[] = [];
136
+ await checkEngineHealth(base, issues, []);
137
+
138
+ assert.equal(
139
+ issues.some((issue) => issue.code === "completed_milestone_reopened"),
140
+ false,
141
+ "explicit reopen should exempt reopened milestone even when completion dispatch timestamps are absent",
142
+ );
143
+ });