gsd-pi 2.75.0-dev.063e5a3 → 2.75.0-next.9c0ec0ba1

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 (449) hide show
  1. package/README.md +88 -51
  2. package/dist/headless-events.d.ts +1 -1
  3. package/dist/headless-events.js +5 -2
  4. package/dist/headless.js +5 -6
  5. package/dist/loader.js +0 -0
  6. package/dist/onboarding.js +39 -14
  7. package/dist/resources/extensions/ask-user-questions.js +11 -2
  8. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -4
  10. package/dist/resources/extensions/gsd/auto/detect-stuck.js +9 -0
  11. package/dist/resources/extensions/gsd/auto/loop.js +67 -4
  12. package/dist/resources/extensions/gsd/auto/phases.js +70 -47
  13. package/dist/resources/extensions/gsd/auto/resolve.js +1 -1
  14. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -1
  15. package/dist/resources/extensions/gsd/auto/session.js +5 -0
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +33 -5
  17. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +3 -3
  19. package/dist/resources/extensions/gsd/auto-prompts.js +2 -2
  20. package/dist/resources/extensions/gsd/auto-recovery.js +9 -0
  21. package/dist/resources/extensions/gsd/auto-verification.js +3 -3
  22. package/dist/resources/extensions/gsd/auto.js +32 -22
  23. package/dist/resources/extensions/gsd/commands/catalog.js +67 -3
  24. package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -0
  25. package/dist/resources/extensions/gsd/commands/handlers/ops.js +11 -0
  26. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +228 -29
  27. package/dist/resources/extensions/gsd/commands-cmux.js +5 -2
  28. package/dist/resources/extensions/gsd/commands-debug.js +388 -0
  29. package/dist/resources/extensions/gsd/commands-do.js +1 -0
  30. package/dist/resources/extensions/gsd/commands-handlers.js +21 -2
  31. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  32. package/dist/resources/extensions/gsd/commands-scan.js +94 -0
  33. package/dist/resources/extensions/gsd/commands-workflow-templates.js +101 -2
  34. package/dist/resources/extensions/gsd/debug-session-store.js +238 -0
  35. package/dist/resources/extensions/gsd/definition-loader.js +7 -0
  36. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -8
  37. package/dist/resources/extensions/gsd/doctor-providers.js +48 -20
  38. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +1 -3
  39. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  40. package/dist/resources/extensions/gsd/forensics.js +26 -29
  41. package/dist/resources/extensions/gsd/git-service.js +0 -1
  42. package/dist/resources/extensions/gsd/graph.js +0 -2
  43. package/dist/resources/extensions/gsd/model-cost-table.js +2 -1
  44. package/dist/resources/extensions/gsd/model-router.js +4 -1
  45. package/dist/resources/extensions/gsd/native-git-bridge.js +21 -5
  46. package/dist/resources/extensions/gsd/notifications.js +4 -0
  47. package/dist/resources/extensions/gsd/pre-execution-checks.js +7 -0
  48. package/dist/resources/extensions/gsd/preferences.js +10 -10
  49. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  50. package/dist/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  51. package/dist/resources/extensions/gsd/prompts/scan.md +79 -0
  52. package/dist/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  53. package/dist/resources/extensions/gsd/run-manager.js +37 -17
  54. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +6 -6
  55. package/dist/resources/extensions/gsd/uok/flags.js +6 -6
  56. package/dist/resources/extensions/gsd/uok/kernel.js +8 -3
  57. package/dist/resources/extensions/gsd/workflow-dispatch.js +64 -0
  58. package/dist/resources/extensions/gsd/workflow-install.js +327 -0
  59. package/dist/resources/extensions/gsd/workflow-mcp.js +0 -6
  60. package/dist/resources/extensions/gsd/workflow-plugins.js +346 -0
  61. package/dist/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  62. package/dist/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  63. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  64. package/dist/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  65. package/dist/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  66. package/dist/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  67. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  68. package/dist/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  69. package/dist/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  70. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  71. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  72. package/dist/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  73. package/dist/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  74. package/dist/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  75. package/dist/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  76. package/dist/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  77. package/dist/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  78. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  79. package/dist/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  80. package/dist/resources/extensions/gsd/workflow-templates/release.md +118 -0
  81. package/dist/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  82. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  83. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  84. package/dist/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  85. package/dist/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  86. package/dist/resources/extensions/remote-questions/commands.js +380 -0
  87. package/dist/resources/extensions/remote-questions/manager.js +28 -4
  88. package/dist/resources/extensions/remote-questions/telegram-adapter.js +79 -4
  89. package/dist/resources/extensions/shared/interview-ui.js +189 -1
  90. package/dist/resources/extensions/shared/layout-utils.js +17 -0
  91. package/dist/resources/extensions/shared/rtk-shared.js +47 -0
  92. package/dist/resources/extensions/shared/rtk.js +3 -46
  93. package/dist/resources/skills/create-workflow/SKILL.md +33 -6
  94. package/dist/rtk-shared.d.ts +10 -0
  95. package/dist/rtk-shared.js +47 -0
  96. package/dist/rtk.d.ts +2 -6
  97. package/dist/rtk.js +3 -48
  98. package/dist/shared/workspace-types.d.ts +52 -0
  99. package/dist/shared/workspace-types.js +1 -0
  100. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  101. package/dist/update-check.d.ts +10 -0
  102. package/dist/update-check.js +24 -3
  103. package/dist/web/standalone/.next/BUILD_ID +1 -1
  104. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  105. package/dist/web/standalone/.next/build-manifest.json +3 -3
  106. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  107. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  126. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/index.html +1 -1
  128. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  129. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  131. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  134. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  136. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  137. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  139. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  141. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  142. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  143. package/dist/web/standalone/.next/static/chunks/2826.02df9631042cc18e.js +9 -0
  144. package/dist/web/standalone/.next/static/chunks/{webpack-b868033a5834586d.js → webpack-6c7cda3e318eedb6.js} +1 -1
  145. package/dist/web/standalone/.next/static/css/3e9cdadb4d23b8a4.css +1 -0
  146. package/dist/wizard.js +2 -2
  147. package/dist/worktree-cli.d.ts +6 -5
  148. package/dist/worktree-cli.js +23 -7
  149. package/package.json +3 -3
  150. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  151. package/packages/native/tsconfig.tsbuildinfo +1 -1
  152. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  153. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  154. package/packages/pi-ai/dist/models/capability-patches.js +3 -2
  155. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  156. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +68 -0
  157. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -1
  158. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +68 -0
  159. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -1
  160. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +17 -0
  161. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -1
  162. package/packages/pi-ai/dist/models/generated/anthropic.js +17 -0
  163. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -1
  164. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +17 -0
  165. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -1
  166. package/packages/pi-ai/dist/models/generated/google-antigravity.js +17 -0
  167. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -1
  168. package/packages/pi-ai/dist/models/generated/groq.d.ts +0 -153
  169. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -1
  170. package/packages/pi-ai/dist/models/generated/groq.js +0 -153
  171. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -1
  172. package/packages/pi-ai/dist/models/generated/index.d.ts +119 -153
  173. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  174. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +17 -0
  175. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -1
  176. package/packages/pi-ai/dist/models/generated/openrouter.js +17 -0
  177. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -1
  178. package/packages/pi-ai/dist/models.generated.test.js +16 -0
  179. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  180. package/packages/pi-ai/dist/providers/amazon-bedrock.js +2 -1
  181. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  182. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +1 -1
  183. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  184. package/packages/pi-ai/dist/providers/anthropic-shared.js +7 -1
  185. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  186. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +12 -1
  187. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
  188. package/packages/pi-ai/package.json +1 -1
  189. package/packages/pi-ai/scripts/generate-models.ts +38 -0
  190. package/packages/pi-ai/src/models/capability-patches.ts +5 -2
  191. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +68 -0
  192. package/packages/pi-ai/src/models/generated/anthropic.ts +17 -0
  193. package/packages/pi-ai/src/models/generated/google-antigravity.ts +17 -0
  194. package/packages/pi-ai/src/models/generated/groq.ts +0 -153
  195. package/packages/pi-ai/src/models/generated/openrouter.ts +17 -0
  196. package/packages/pi-ai/src/models.generated.test.ts +16 -0
  197. package/packages/pi-ai/src/providers/amazon-bedrock.ts +2 -1
  198. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +15 -1
  199. package/packages/pi-ai/src/providers/anthropic-shared.ts +6 -2
  200. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  201. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts +2 -0
  202. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts.map +1 -0
  203. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +38 -0
  204. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -0
  205. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  206. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/auth-storage.js +9 -0
  208. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +36 -0
  210. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/sdk.js +10 -0
  213. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +2 -2
  215. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  216. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +69 -0
  217. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  218. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +76 -0
  219. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  220. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +0 -65
  221. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +1 -75
  223. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +1 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  226. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +185 -21
  227. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  228. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +56 -0
  229. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +41 -0
  230. package/packages/pi-coding-agent/src/core/auth-storage.ts +10 -0
  231. package/packages/pi-coding-agent/src/core/sdk.ts +14 -0
  232. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +2 -2
  233. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +82 -0
  234. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +1 -83
  235. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +201 -24
  236. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  237. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  238. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  239. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +69 -0
  240. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  241. package/pkg/dist/modes/interactive/theme/theme-schema.js +76 -0
  242. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  243. package/pkg/dist/modes/interactive/theme/theme.d.ts +0 -65
  244. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  245. package/pkg/dist/modes/interactive/theme/theme.js +1 -75
  246. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  247. package/pkg/dist/modes/interactive/theme/themes.d.ts +1 -1
  248. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  249. package/pkg/dist/modes/interactive/theme/themes.js +185 -21
  250. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  251. package/src/resources/extensions/ask-user-questions.ts +17 -2
  252. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  253. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -4
  254. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +18 -0
  255. package/src/resources/extensions/gsd/auto/detect-stuck.ts +10 -0
  256. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  257. package/src/resources/extensions/gsd/auto/loop.ts +109 -3
  258. package/src/resources/extensions/gsd/auto/phases.ts +94 -60
  259. package/src/resources/extensions/gsd/auto/resolve.ts +1 -1
  260. package/src/resources/extensions/gsd/auto/run-unit.ts +11 -1
  261. package/src/resources/extensions/gsd/auto/session.ts +7 -0
  262. package/src/resources/extensions/gsd/auto-dispatch.ts +45 -5
  263. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  264. package/src/resources/extensions/gsd/auto-post-unit.ts +3 -3
  265. package/src/resources/extensions/gsd/auto-prompts.ts +7 -2
  266. package/src/resources/extensions/gsd/auto-recovery.ts +16 -1
  267. package/src/resources/extensions/gsd/auto-verification.ts +3 -3
  268. package/src/resources/extensions/gsd/auto.ts +34 -26
  269. package/src/resources/extensions/gsd/commands/catalog.ts +60 -3
  270. package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -0
  271. package/src/resources/extensions/gsd/commands/handlers/ops.ts +11 -0
  272. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +279 -29
  273. package/src/resources/extensions/gsd/commands-cmux.ts +6 -2
  274. package/src/resources/extensions/gsd/commands-debug.ts +484 -0
  275. package/src/resources/extensions/gsd/commands-do.ts +1 -0
  276. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  277. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  278. package/src/resources/extensions/gsd/commands-scan.ts +125 -0
  279. package/src/resources/extensions/gsd/commands-workflow-templates.ts +129 -2
  280. package/src/resources/extensions/gsd/debug-session-store.ts +377 -0
  281. package/src/resources/extensions/gsd/definition-loader.ts +7 -0
  282. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -8
  283. package/src/resources/extensions/gsd/doctor-providers.ts +52 -22
  284. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +1 -3
  285. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  286. package/src/resources/extensions/gsd/forensics.ts +25 -29
  287. package/src/resources/extensions/gsd/git-service.ts +0 -1
  288. package/src/resources/extensions/gsd/graph.ts +0 -3
  289. package/src/resources/extensions/gsd/model-cost-table.ts +2 -1
  290. package/src/resources/extensions/gsd/model-router.ts +4 -1
  291. package/src/resources/extensions/gsd/native-git-bridge.ts +21 -5
  292. package/src/resources/extensions/gsd/notifications.ts +6 -0
  293. package/src/resources/extensions/gsd/pre-execution-checks.ts +6 -0
  294. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  295. package/src/resources/extensions/gsd/preferences.ts +10 -10
  296. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  297. package/src/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  298. package/src/resources/extensions/gsd/prompts/scan.md +79 -0
  299. package/src/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  300. package/src/resources/extensions/gsd/run-manager.ts +53 -19
  301. package/src/resources/extensions/gsd/templates/PREFERENCES.md +6 -6
  302. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -34
  303. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +45 -31
  304. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +39 -0
  305. package/src/resources/extensions/gsd/tests/commands-do.test.ts +48 -0
  306. package/src/resources/extensions/gsd/tests/commands-scan.test.ts +351 -0
  307. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +8 -6
  308. package/src/resources/extensions/gsd/tests/debug-command-handler.test.ts +905 -0
  309. package/src/resources/extensions/gsd/tests/debug-command-lifecycle.integration.test.ts +1229 -0
  310. package/src/resources/extensions/gsd/tests/debug-session-store.test.ts +565 -0
  311. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +64 -0
  312. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +67 -0
  313. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +62 -18
  314. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +29 -12
  315. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +74 -0
  316. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +0 -4
  317. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +36 -0
  318. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +41 -10
  319. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +51 -0
  320. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +171 -1
  321. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +24 -5
  322. package/src/resources/extensions/gsd/tests/preferences.test.ts +69 -1
  323. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +1 -1
  324. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +4 -0
  325. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +107 -0
  326. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +15 -0
  327. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +31 -1
  328. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +166 -0
  329. package/src/resources/extensions/gsd/tests/workflow-install.test.ts +113 -0
  330. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +15 -6
  331. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  332. package/src/resources/extensions/gsd/tests/workflow-plugins.test.ts +310 -0
  333. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +8 -2
  334. package/src/resources/extensions/gsd/unit-runtime.ts +1 -0
  335. package/src/resources/extensions/gsd/uok/flags.ts +6 -6
  336. package/src/resources/extensions/gsd/uok/kernel.ts +16 -4
  337. package/src/resources/extensions/gsd/workflow-dispatch.ts +106 -0
  338. package/src/resources/extensions/gsd/workflow-install.ts +423 -0
  339. package/src/resources/extensions/gsd/workflow-mcp.ts +0 -6
  340. package/src/resources/extensions/gsd/workflow-plugins.ts +403 -0
  341. package/src/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  342. package/src/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  343. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  344. package/src/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  345. package/src/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  346. package/src/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  347. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  348. package/src/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  349. package/src/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  350. package/src/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  351. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  352. package/src/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  353. package/src/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  354. package/src/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  355. package/src/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  356. package/src/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  357. package/src/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  358. package/src/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  359. package/src/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  360. package/src/resources/extensions/gsd/workflow-templates/release.md +118 -0
  361. package/src/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  362. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  363. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  364. package/src/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  365. package/src/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  366. package/src/resources/extensions/gsd/workflow-templates.ts +7 -0
  367. package/src/resources/extensions/gsd/workspace-index.ts +9 -4
  368. package/src/resources/extensions/remote-questions/commands.ts +480 -0
  369. package/src/resources/extensions/remote-questions/manager.ts +36 -3
  370. package/src/resources/extensions/remote-questions/telegram-adapter.ts +86 -4
  371. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +246 -0
  372. package/src/resources/extensions/remote-questions/tests/telegram-commands.test.ts +267 -0
  373. package/src/resources/extensions/shared/interview-ui.ts +195 -1
  374. package/src/resources/extensions/shared/layout-utils.ts +26 -0
  375. package/src/resources/extensions/shared/rtk-shared.ts +58 -0
  376. package/src/resources/extensions/shared/rtk.ts +12 -52
  377. package/src/resources/extensions/shared/tests/interview-preview.test.ts +177 -0
  378. package/src/resources/extensions/shared/tests/preview-layout.test.ts +120 -0
  379. package/src/resources/skills/create-workflow/SKILL.md +33 -6
  380. package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +0 -9
  381. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
  382. package/packages/native/dist/ps/types.d.ts +0 -5
  383. package/packages/native/dist/ps/types.js +0 -2
  384. package/packages/native/src/ps/types.ts +0 -5
  385. package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +0 -201
  386. package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +0 -9
  387. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +0 -762
  388. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +0 -19
  389. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +0 -1
  390. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +0 -9
  391. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +0 -3
  392. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +0 -230
  393. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +0 -87
  394. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +0 -32
  395. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +0 -169
  396. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +0 -21
  397. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +0 -88
  398. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +0 -36
  399. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +0 -21
  400. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +0 -22
  401. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +0 -23
  402. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +0 -8
  403. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +0 -41
  404. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +0 -21
  405. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +0 -4
  406. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +0 -63
  407. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +0 -10
  408. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +0 -5
  409. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +0 -4
  410. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +0 -3
  411. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +0 -46
  412. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +0 -24
  413. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +0 -12
  414. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +0 -63
  415. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +0 -13
  416. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +0 -12
  417. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +0 -2
  418. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +0 -6
  419. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +0 -6
  420. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +0 -2
  421. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +0 -5
  422. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +0 -6
  423. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +0 -13
  424. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +0 -8
  425. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +0 -10
  426. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +0 -5
  427. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +0 -4
  428. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +0 -3
  429. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +0 -46
  430. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +0 -24
  431. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +0 -12
  432. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +0 -63
  433. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +0 -13
  434. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +0 -12
  435. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +0 -2
  436. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +0 -6
  437. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +0 -6
  438. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +0 -2
  439. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +0 -5
  440. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +0 -6
  441. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +0 -13
  442. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +0 -8
  443. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +0 -12
  444. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +0 -12
  445. package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +0 -68
  446. package/packages/pi-ai/oauth.d.ts +0 -1
  447. package/packages/pi-ai/oauth.js +0 -1
  448. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → JncJywFxCugMuXGs56m-b}/_buildManifest.js +0 -0
  449. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → JncJywFxCugMuXGs56m-b}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -27,85 +27,120 @@ One command. Walk away. Come back to a built project with clean git history.
27
27
 
28
28
  ---
29
29
 
30
- ## What's New in v2.71
30
+ ## What's New in v2.75
31
31
 
32
- ### MCP Secure Env Collect
32
+ ### Knowledge Graph & Learning Extraction
33
33
 
34
- - **Secure credential collection over MCP** — the new `secure_env_collect` tool uses MCP form elicitation to collect secrets (API keys, tokens) from external clients without exposing values in tool output. Masks input in interactive mode.
35
- - **Hardened elicitation schema** MCP elicitation schema handling is stricter, with proper validation and fallback for providers that don't support forms.
34
+ - **Knowledge graph system** — GSD now builds a structured knowledge graph from project artifacts. Learnings, decisions, and patterns are parsed into queryable graph nodes.
35
+ - **`/gsd extract-learnings`**new command extracts decisions, lessons, patterns, and surprises from completed phase artifacts into `LEARNINGS.md`, which feeds the knowledge graph automatically.
36
36
 
37
- ### MCP Reliability
37
+ ### Unified Orchestration Kernel (UOK)
38
38
 
39
- - **Stream ordering preserved** — MCP tool output now renders in the correct order, fixing interleaved output in Claude Code and other MCP clients.
40
- - **isError flag propagation** — workflow tool execution failures now correctly return `isError: true`, so MCP clients can distinguish success from failure.
41
- - **Multi-round discuss questions** — new-project discuss phase supports multi-round questioning with structured question gates.
39
+ - **UOK is now the default** — the unified orchestration kernel replaces the legacy execution path. Plan-v2 compile gates, unified audit envelopes, turn-level git transaction modes, reactive/parallel scheduling via execution graph, and model policy filtering are all enforced by default. Legacy fallback remains as an emergency escape.
42
40
 
43
- ### Model Selection Hardening
41
+ ### Extension API
44
42
 
45
- - **Unconfigured models blocked** — models without a configured provider are filtered from selection surfaces, preventing dispatch failures.
46
- - **Provider readiness required** — saved default model selection now verifies the provider is ready before accepting it.
47
- - **Session override honored** — `/gsd model` selection persists as a session override across all dispatch phases.
48
- - **Minimal context guard** — model override logic is skipped in minimal command contexts where it doesn't apply.
43
+ - **GSD Extension API** — third-party extensions can now be loaded from `.gsd/extensions/`, with a formal API surface for hooking into the GSD lifecycle (#3338).
49
44
 
50
- ### Auto-Mode Resilience
45
+ ### v1 Command Parity
51
46
 
52
- - **Credential cooldown recovery** — auto-mode survives transient 429 rate-limit responses with structured cooldown errors and a bounded retry budget.
53
- - **Fire-and-forget auto start** — auto start is detached from active turns to prevent blocking.
54
- - **Scoped forensics** — stuck-loop forensics are now scoped to auto sessions only, preventing false positives in interactive use.
47
+ - **12 missing commands added** — GSD v2 now covers all v1 commands, closing the migration gap.
55
48
 
56
49
  ### TUI Improvements
57
50
 
58
- - **Overlay subscription fix** — resolved overlay subscription lifecycle and `Ctrl+Shift+P` shortcut conflict.
59
- - **Improved overlays and shortcuts** — GSD overlays, keyboard shortcuts, and notification flows redesigned for consistency.
60
- - **Pinned output restored** — pinned output bar displays above the editor during tool execution again.
61
- - **Turn completion cleanup** — pinned latest output is cleared on turn completion, preventing stale output from persisting.
62
- - **Secure input masking** — extension input values are masked in interactive mode when collecting secrets.
51
+ - **Chat frame redesign** — compaction notices, tool execution cards, and the chat frame now share a unified styling with timestamps and model headers.
52
+ - **Inline tool calls** — assistant tool calls render inline with text instead of grouped at the end.
53
+ - **Compaction and success fixes** — tool cards no longer stick after compaction; success notifications are properly promoted.
63
54
 
64
- ### Provider Fixes
55
+ ### Auto-Mode & Reliability
65
56
 
66
- - **Full OAuth login URLs** — OAuth login URLs are now displayed in full instead of being truncated.
67
- - **MiniMax bearer auth** — MiniMax Anthropic API requests use proper bearer authentication.
68
- - **Case-insensitive tool rendering** — renderable tool matching is now case-insensitive, fixing missed tool output.
69
- - **Headless idle timeout** — idle timeout is kept off during interactive tool execution in headless mode.
57
+ - **Session timeout recovery** — auto-resume timer handles session creation timeouts; timeout counter resets on resume.
58
+ - **Compaction checkpoint fix** — all session phases are checkpointed during compaction, not just the executing phase.
59
+ - **MCP worktree routing** — tool writes are routed to the active worktree when a milestone has one; worktree paths are accepted in the project root guard.
60
+ - **Single-writer DB invariant** — the engine database now enforces a single-writer invariant, preventing corruption from concurrent access.
70
61
 
71
- ### Reliability & Internals
62
+ ### Providers & CI
72
63
 
73
- - **TOCTOU file locking** — race conditions in event log and custom workflow graph file locking are fixed with proper atomic lock acquisition.
74
- - **State derive refactor** — `deriveStateFromDb` god function extracted into composable, testable helpers.
75
- - **Windows portability** — hardened cross-platform portability across runtime, tooling, and CI.
76
- - **Model routing transparency** — dynamic routing is skipped for interactive dispatches; model changes are always shown in the banner.
77
- - **Capability-aware routing (ADR-004)** — full implementation of capability scoring, `before_model_select` hook, and task metadata extraction.
78
- - **Multi-model provider strategy (ADR-005)** — infrastructure for multi-provider model selection wired into live paths.
79
- - **Anti-fabrication guardrails** — discuss prompts enforce turn-taking to prevent fabricated user responses.
80
- - **Milestone worktree cleanup** — merged worktree cleanup uses the milestone branch instead of generic lookups.
81
- - **Tool cache control** — `cache_control` breakpoints added to tool definitions for improved prompt caching.
64
+ - **Alibaba DashScope** — added as a standalone provider (#3891).
65
+ - **Persistent language preference** — `/gsd language` sets a persistent language preference.
66
+ - **Flat-rate provider detection** — extended to custom and externalCli providers.
67
+ - **Thinking level as effort** — Claude Code now passes thinking level as an effort parameter.
68
+ - **Hardened release pipeline** — workspace versions synced in release commits, package-lock.json regenerated during bumps, incremental build cache issues resolved.
82
69
 
83
70
  See the full [Changelog](./CHANGELOG.md) for details on every release.
84
71
 
85
72
  <details>
86
- <summary>Previous highlights (v2.70 and earlier)</summary>
73
+ <summary>v2.74 highlights</summary>
74
+
75
+ - **DB-authoritative milestone completeness** — milestone completion state is derived from the database, not file markers (#4179)
76
+ - **Flat-rate provider detection** — extended to custom and externalCli providers
77
+ - **Thinking level as effort** — Claude Code passes thinking level as an effort parameter
78
+ - **False milestone merge prevention** — auto-mode no longer falsely merges after a `complete-milestone` failure (#4175)
79
+ - **Premature auto-stop fix** — prevents auto-mode from stopping early on blocked phase + missing reassessment
80
+ - **Inline tool call rendering** — assistant tool calls render inline with text instead of grouped at the end
81
+ - **Custom model preservation** — custom model selection preserved on `/gsd auto` bootstrap (#4122)
82
+
83
+ </details>
84
+
85
+ <details>
86
+ <summary>v2.73 highlights</summary>
87
+
88
+ - **Alibaba DashScope provider** — added as a standalone provider (#3891)
89
+ - **Layered depth enforcement** — discuss phase enforces depth gates for thorough requirements gathering (#4079)
90
+ - **Memory pressure watchdog** — stuck detection state persisted across sessions (#3708)
91
+ - **Ollama cloud auth** — cloud auth support and real context window resolution via `/api/show` (#4017)
92
+ - **DB corruption prevention** — direct writes to `gsd.db` blocked via hooks (#3674)
93
+ - **Circular dependency cleanup** — 3 circular dependencies broken in extension modules (#3730)
94
+ - **Subagent permissions** — GSD subagents default to `bypassPermissions` with safe built-ins pre-authorized
95
+ - **Security hardening** — auth middleware activated, shutdown/update routes hardened (#4023)
96
+ - **Stale slice reconciliation** — stale slice rows reconciled and STATE.md rebuilt before DB close (#3658)
97
+ - **Subagent model preference** — `subagent_model` preference wired through to dispatch prompt builders
98
+ - **Pipeline integrity** — 5 pipeline issues addressed from release audit, package-lock.json regenerated during bumps
99
+
100
+ </details>
101
+
102
+ <details>
103
+ <summary>v2.72 highlights</summary>
104
+
105
+ - **8 specialist subagents** — new specialist subagents and slim pro agents with GSD phase guard to prevent conflicts
106
+ - **Model selection hardening** — unconfigured models blocked from selection, provider readiness required, session override honored
107
+ - **Auto-mode resilience** — credential cooldown recovery with bounded retry budget, fire-and-forget auto start, scoped forensics
108
+ - **TUI overhaul** — overlays, keyboard shortcuts, and notification flows redesigned for consistency
109
+ - **Capability-aware routing (ADR-004)** — full implementation of capability scoring, `before_model_select` hook, and task metadata extraction
110
+ - **Multi-model provider strategy (ADR-005)** — infrastructure for multi-provider model selection wired into live paths
111
+ - **Anti-fabrication guardrails** — discuss prompts enforce turn-taking to prevent fabricated user responses
112
+ - **Windows portability** — hardened cross-platform portability across runtime, tooling, and CI
113
+ - **MCP reliability** — every registered tool exposed, SDK subpath resolution fixed, abort signals threaded through
114
+ - **Tool cache control** — `cache_control` breakpoints added to tool definitions for improved prompt caching
115
+
116
+ </details>
117
+
118
+ <details>
119
+ <summary>v2.71 highlights</summary>
120
+
121
+ - **Secure credential collection over MCP** — `secure_env_collect` tool uses MCP form elicitation to collect secrets without exposing values in tool output
122
+ - **MCP stream ordering** — tool output renders in correct order, fixing interleaved output in Claude Code and other MCP clients
123
+ - **isError flag propagation** — workflow tool execution failures correctly return `isError: true`
124
+ - **Multi-round discuss questions** — new-project discuss phase supports multi-round questioning with structured question gates
125
+ - **TOCTOU file locking** — race conditions in event log and custom workflow graph file locking fixed with atomic lock acquisition
126
+ - **State derive refactor** — `deriveStateFromDb` god function extracted into composable, testable helpers
127
+ - **Pinned output fixes** — restored above editor during tool execution, cleared on turn completion
128
+
129
+ </details>
130
+
131
+ <details>
132
+ <summary>v2.70 and earlier</summary>
87
133
 
88
134
  - **Full workflow over MCP (v2.68)** — slice replanning, milestone management, slice completion, task completion, and core planning tools exposed over MCP
89
135
  - **Transport-gated MCP (v2.68)** — workflow tool availability adapts to provider transport capabilities automatically
90
136
  - **Contextual tips system (v2.68)** — TUI and web terminal surface contextual tips based on workflow state
91
137
  - **Ask user questions over MCP (v2.70)** — interactive questions exposed via elicitation for external integrations
92
138
  - **Tiered Context Injection (M005)** — relevance-scoped context with 65%+ token reduction
93
- - **Resilient transient error recovery** — defers to Core RetryHandler and fixes cmdCtx race conditions
94
- - **Anthropic subscription routing** — auto-routed through Claude Code CLI provider with proper display names
95
139
  - **5-wave state machine hardening** — critical data integrity fixes across atomic writes, event log reconciliation, session recovery
96
- - **Discussion gate enforcement** — mechanical enforcement with fail-closed behavior
97
140
  - **Slice-level parallelism** — dependency-aware parallel dispatch within a milestone
98
- - **Persistent notification panel** — TUI overlay, widget, and web API for real-time notifications
99
141
  - **MCP server** — 6 read-only project state tools for external integrations, auto-wrapup guard, and question dedup
100
142
  - **Ollama extension** — first-class local LLM support via Ollama, with dynamic routing enabled by default
101
- - **Discord bot & daemon** — dedicated daemon package, Discord bot, and headless text mode with tool calls
102
- - **Capability-aware model routing (ADR-004)** — capability scoring, `before_model_select` hook, and task metadata extraction
103
143
  - **VS Code sidebar redesign** — SCM provider, checkpoints, diagnostics panel, activity feed, workflow controls, session forking
104
- - **`/gsd parallel watch`** — native TUI overlay for real-time worker monitoring
105
- - **Codebase map** — automatic codebase map injection for fresh agent contexts
106
- - **`--resume` flag** — resume previous sessions from the CLI
107
- - **Concurrent invocation guard** — prevents overlapping auto-mode runs
108
- - **VS Code integration** — status bar, file decorations, bash terminal, session tree, conversation history, and code lens
109
144
  - **Skills overhaul** — 30+ skill packs covering major frameworks, databases, and cloud platforms
110
145
  - **Single-writer state engine** — disciplined state transitions with machine guards and TOCTOU hardening
111
146
  - **DB-backed planning tools** — atomic SQLite tool calls for state transitions
@@ -389,6 +424,8 @@ On first run, GSD launches a branded setup wizard that walks you through LLM pro
389
424
  | `/gsd migrate` | Migrate a v1 `.planning` directory to `.gsd` format |
390
425
  | `/gsd help` | Categorized command reference for all GSD subcommands |
391
426
  | `/gsd mode` | Switch workflow mode (solo/team) with coordinated defaults |
427
+ | `/gsd workflow` | Unified workflow plugins — list, run `<name>`, install, info, validate |
428
+ | `/gsd start <template>` | Launch a bundled or custom workflow template (bugfix, release, etc.) |
392
429
  | `/gsd forensics` | Full-access GSD debugger for auto-mode failure investigation |
393
430
  | `/gsd cleanup` | Archive phase directories from completed milestones |
394
431
  | `/gsd doctor` | Runtime health checks — issues surface across widget, visualizer, and reports |
@@ -497,7 +534,7 @@ version: 1
497
534
  models:
498
535
  research: claude-sonnet-4-6
499
536
  planning:
500
- model: claude-opus-4-6
537
+ model: claude-opus-4-7
501
538
  fallbacks:
502
539
  - openrouter/z-ai/glm-5
503
540
  - openrouter/minimax/minimax-m2.5
@@ -756,7 +793,7 @@ In your preferences (`/gsd prefs`), assign different models to different phases:
756
793
  models:
757
794
  research: openrouter/deepseek/deepseek-r1
758
795
  planning:
759
- model: claude-opus-4-6
796
+ model: claude-opus-4-7
760
797
  fallbacks:
761
798
  - openrouter/z-ai/glm-5
762
799
  execution: claude-sonnet-4-6
@@ -47,4 +47,4 @@ export declare function isInteractiveHeadlessTool(toolName: string | undefined):
47
47
  export declare function shouldArmHeadlessIdleTimeout(toolCallCount: number, interactiveToolCount: number): boolean;
48
48
  export declare const FIRE_AND_FORGET_METHODS: Set<string>;
49
49
  export declare const QUICK_COMMANDS: Set<string>;
50
- export declare function isQuickCommand(command: string): boolean;
50
+ export declare function isQuickCommand(command: string, commandArgs?: readonly string[]): boolean;
@@ -100,6 +100,9 @@ export const QUICK_COMMANDS = new Set([
100
100
  'cleanup', 'migrate', 'doctor', 'remote', 'help', 'steer',
101
101
  'triage', 'visualize',
102
102
  ]);
103
- export function isQuickCommand(command) {
104
- return QUICK_COMMANDS.has(command);
103
+ const QUICK_WORKFLOW_SUBCOMMANDS = new Set(['list', 'validate']);
104
+ export function isQuickCommand(command, commandArgs = []) {
105
+ if (QUICK_COMMANDS.has(command))
106
+ return true;
107
+ return command === 'workflow' && QUICK_WORKFLOW_SUBCOMMANDS.has(commandArgs[0] ?? '');
105
108
  }
package/dist/headless.js CHANGED
@@ -606,7 +606,7 @@ async function runHeadlessOnce(options, restartCount) {
606
606
  }
607
607
  }
608
608
  // Quick commands: resolve on first agent_end
609
- if (eventObj.type === 'agent_end' && isQuickCommand(options.command) && !completed) {
609
+ if (eventObj.type === 'agent_end' && isQuickCommand(options.command, options.commandArgs) && !completed) {
610
610
  completed = true;
611
611
  resolveCompletion();
612
612
  return;
@@ -622,10 +622,9 @@ async function runHeadlessOnce(options, restartCount) {
622
622
  // Kill child process — don't await, just fire and exit.
623
623
  // The main flow may be awaiting a promise that resolves when the child dies,
624
624
  // which would race with this handler. Exit synchronously to ensure correct exit code.
625
- try {
626
- client.stop().catch(() => { });
627
- }
628
- catch { }
625
+ void client.stop().catch((error) => {
626
+ process.stderr.write(`[headless] Warning: failed to stop child process: ${error instanceof Error ? error.message : String(error)}\n`);
627
+ });
629
628
  if (timeoutTimer)
630
629
  clearTimeout(timeoutTimer);
631
630
  if (idleTimer)
@@ -707,7 +706,7 @@ async function runHeadlessOnce(options, restartCount) {
707
706
  process.stdin.resume();
708
707
  }
709
708
  // Detect child process crash (read-only exit event subscription — not stdin access)
710
- const internalProcess = client.process;
709
+ const internalProcess = Reflect.get(client, 'process');
711
710
  if (internalProcess) {
712
711
  internalProcess.on('exit', (code) => {
713
712
  if (!completed) {
package/dist/loader.js CHANGED
File without changes
@@ -118,6 +118,25 @@ function openBrowser(url) {
118
118
  execFile(cmd, [url], () => { });
119
119
  }
120
120
  }
121
+ /**
122
+ * Persist the selected default provider to settings.json.
123
+ *
124
+ * This ensures first startup after onboarding prefers the provider the user
125
+ * just configured, instead of falling back to the first "available" provider
126
+ * (which can be influenced by unrelated env auth like AWS_PROFILE).
127
+ */
128
+ function persistDefaultProvider(providerId) {
129
+ const settingsPath = join(agentDir, 'settings.json');
130
+ try {
131
+ const raw = existsSync(settingsPath) ? JSON.parse(readFileSync(settingsPath, 'utf-8')) : {};
132
+ raw.defaultProvider = providerId;
133
+ mkdirSync(dirname(settingsPath), { recursive: true });
134
+ writeFileSync(settingsPath, JSON.stringify(raw, null, 2), 'utf-8');
135
+ }
136
+ catch {
137
+ // Non-fatal: startup fallback logic will still run.
138
+ }
139
+ }
121
140
  /** Sentinel returned by runStep when the user cancels — tells the caller
122
141
  * to abort the entire wizard. */
123
142
  const STEP_CANCELLED = Symbol('step-cancelled');
@@ -283,16 +302,8 @@ async function runLlmStep(p, pc, authStorage) {
283
302
  p.log.info('Your Claude subscription will be used for inference. No API key needed.');
284
303
  // Store sentinel so hasAuth('claude-code') returns true on future boots
285
304
  authStorage.set('claude-code', { type: 'api_key', key: 'cli' });
286
- // Persist claude-code as the default provider so the startup migration in
287
- // cli.ts does not need to fire and the user is not left on "anthropic".
288
- const settingsPath = join(agentDir, 'settings.json');
289
- try {
290
- const raw = existsSync(settingsPath) ? JSON.parse(readFileSync(settingsPath, 'utf-8')) : {};
291
- raw.defaultProvider = 'claude-code';
292
- mkdirSync(dirname(settingsPath), { recursive: true });
293
- writeFileSync(settingsPath, JSON.stringify(raw, null, 2), 'utf-8');
294
- }
295
- catch { /* non-fatal — startup migration will catch it */ }
305
+ // Persist claude-code so startup does not keep users on anthropic direct API.
306
+ persistDefaultProvider('claude-code');
296
307
  return true;
297
308
  }
298
309
  // ── Step 2: Which provider? ──────────────────────────────────────────────
@@ -345,7 +356,7 @@ async function runOAuthFlow(p, pc, authStorage, providerId, oauthMap) {
345
356
  const s = p.spinner();
346
357
  s.start(`Authenticating with ${providerName}...`);
347
358
  try {
348
- await authStorage.login(providerId, {
359
+ const loginCallbacks = {
349
360
  onAuth: (info) => {
350
361
  s.stop(`Opening browser for ${providerName}`);
351
362
  openBrowser(info.url);
@@ -377,7 +388,9 @@ async function runOAuthFlow(p, pc, authStorage, providerId, oauthMap) {
377
388
  return result;
378
389
  }
379
390
  : undefined,
380
- });
391
+ };
392
+ await authStorage.login(providerId, loginCallbacks);
393
+ persistDefaultProvider(providerId);
381
394
  p.log.success(`Authenticated with ${pc.green(providerName)}`);
382
395
  return true;
383
396
  }
@@ -416,6 +429,7 @@ async function runApiKeyFlow(p, pc, authStorage, providerId, providerLabel) {
416
429
  p.log.warn(`Key doesn't start with expected prefix (${expectedPrefixes.join(' or ')}). Saving anyway.`);
417
430
  }
418
431
  authStorage.set(providerId, { type: 'api_key', key: trimmed });
432
+ persistDefaultProvider(providerId);
419
433
  p.log.success(`API key saved for ${pc.green(providerLabel)}`);
420
434
  // Provider-specific post-setup hints
421
435
  if (providerId === 'openrouter') {
@@ -438,6 +452,7 @@ async function runOllamaLocalFlow(p, pc, authStorage) {
438
452
  s.stop(`Ollama is running at ${pc.green(host)}`);
439
453
  // Store a placeholder so the provider is recognized as authenticated
440
454
  authStorage.set('ollama', { type: 'api_key', key: 'ollama' });
455
+ persistDefaultProvider('ollama');
441
456
  p.log.success(`${pc.green('Ollama (Local)')} configured — no API key needed`);
442
457
  p.log.info(pc.dim('Models are discovered automatically from your local Ollama instance.'));
443
458
  return true;
@@ -460,6 +475,7 @@ async function runOllamaLocalFlow(p, pc, authStorage) {
460
475
  if (p.isCancel(proceed) || !proceed)
461
476
  return false;
462
477
  authStorage.set('ollama', { type: 'api_key', key: 'ollama' });
478
+ persistDefaultProvider('ollama');
463
479
  p.log.success(`${pc.green('Ollama (Local)')} saved — models will appear when Ollama is running`);
464
480
  return true;
465
481
  }
@@ -509,6 +525,7 @@ async function runCustomOpenAIFlow(p, pc, authStorage) {
509
525
  const trimmedModelId = modelId.trim();
510
526
  // Save API key to auth storage
511
527
  authStorage.set('custom-openai', { type: 'api_key', key: trimmedKey });
528
+ persistDefaultProvider('custom-openai');
512
529
  // Write or merge into models.json
513
530
  const modelsJsonPath = join(agentDir, 'models.json');
514
531
  let config = { providers: {} };
@@ -653,7 +670,9 @@ async function runToolKeysStep(p, pc, authStorage) {
653
670
  // ─── Remote Questions Step ────────────────────────────────────────────────────
654
671
  async function runRemoteQuestionsStep(p, pc, authStorage) {
655
672
  // Check existing config — use getCredentialsForProvider to skip empty-key entries
656
- const hasValidKey = (provider) => authStorage.getCredentialsForProvider(provider).some((c) => c.type === 'api_key' && c.key);
673
+ const hasValidKey = (provider) => authStorage
674
+ .getCredentialsForProvider(provider)
675
+ .some((c) => c.type === 'api_key' && typeof c.key === 'string' && c.key.length > 0);
657
676
  const hasDiscord = hasValidKey('discord_bot');
658
677
  const hasSlack = hasValidKey('slack_bot');
659
678
  const hasTelegram = hasValidKey('telegram_bot');
@@ -858,7 +877,13 @@ async function runDiscordChannelStep(p, pc, token) {
858
877
  try {
859
878
  const res = await fetch(`https://discord.com/api/v10/guilds/${guildId}/channels`, { headers, signal: AbortSignal.timeout(15_000) });
860
879
  const data = await res.json();
861
- channels = Array.isArray(data) ? data.filter((ch) => ch.type === 0 || ch.type === 5) : [];
880
+ channels = Array.isArray(data)
881
+ ? data.filter((ch) => typeof ch === 'object' &&
882
+ ch !== null &&
883
+ typeof ch.id === 'string' &&
884
+ typeof ch.name === 'string' &&
885
+ (ch.type === 0 || ch.type === 5))
886
+ : [];
862
887
  }
863
888
  catch {
864
889
  p.log.warn('Could not fetch channels — configure later with /gsd remote discord');
@@ -16,13 +16,16 @@ import { showInterviewRound, } from "./shared/tui.js";
16
16
  const OptionSchema = Type.Object({
17
17
  label: Type.String({ description: "User-facing label (1-5 words)" }),
18
18
  description: Type.String({ description: "One short sentence explaining impact/tradeoff if selected" }),
19
+ preview: Type.Optional(Type.String({
20
+ description: "Optional markdown content shown in a side-by-side preview panel when this option is highlighted. Use for showing code samples, config snippets, or detailed explanations. Keep under ~20 lines — longer content is truncated.",
21
+ })),
19
22
  });
20
23
  const QuestionSchema = Type.Object({
21
24
  id: Type.String({ description: "Stable identifier for mapping answers (snake_case)" }),
22
25
  header: Type.String({ description: "Short header label shown in the UI (12 or fewer chars)" }),
23
26
  question: Type.String({ description: "Single-sentence prompt shown to the user" }),
24
27
  options: Type.Array(OptionSchema, {
25
- description: 'Provide 2-3 mutually exclusive choices for single-select, or any number for multi-select. Put the recommended option first and suffix its label with "(Recommended)". Do not include an "Other" option for single-select; the client adds a free-form "None of the above" option automatically.',
28
+ description: 'Provide 2-3 mutually exclusive choices for single-select, or any number for multi-select. Put the recommended option first and suffix its label with "(Recommended)". Each option can include an optional "preview" field with markdown content shown in a side panel. Do not include an "Other" option for single-select; the client adds a free-form "None of the above" option automatically.',
26
29
  }),
27
30
  allowMultiple: Type.Optional(Type.Boolean({
28
31
  description: "If true, the user can select multiple options using SPACE to toggle and ENTER to confirm. No 'None of the above' option is added. Default: false.",
@@ -134,12 +137,14 @@ export default function AskUserQuestions(pi) {
134
137
  pi.registerTool({
135
138
  name: "ask_user_questions",
136
139
  label: "Request User Input",
137
- description: "Request user input for one to three short questions and wait for the response. Single-select questions have 2-3 mutually exclusive options with a free-form 'None of the above' added automatically. Multi-select questions (allowMultiple: true) let the user toggle multiple options with SPACE and confirm with ENTER.",
140
+ description: "Request user input for one to three short questions and wait for the response. Single-select questions have 2-3 mutually exclusive options with a free-form 'None of the above' added automatically. Multi-select questions (allowMultiple: true) let the user toggle multiple options with SPACE and confirm with ENTER. Options can include an optional 'preview' field with markdown content shown in a side-by-side panel when highlighted.",
138
141
  promptGuidelines: [
139
142
  "Use ask_user_questions when you need the user to choose between concrete alternatives before proceeding.",
140
143
  "Keep questions to 1 when possible; never exceed 3.",
141
144
  "For single-select: each question must have 2-3 options. Put the recommended option first with '(Recommended)' suffix. Do not include an 'Other' or 'None of the above' option - the client adds one automatically.",
142
145
  "For multi-select: set allowMultiple: true. The user can pick any number of options. No 'None of the above' is added.",
146
+ "When options involve code patterns, config choices, or architecture decisions, add a 'preview' field with markdown content (code blocks, lists, headers, etc.). The preview renders in a side-by-side panel when the option is highlighted.",
147
+ "Preview content is rendered in a fixed-height panel (max ~20 lines visible). Keep previews concise — show the most relevant snippet, not exhaustive examples. Longer content is truncated with a '+N lines hidden' indicator.",
143
148
  ],
144
149
  parameters: AskUserQuestionsParams,
145
150
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
@@ -274,6 +279,10 @@ export default function AskUserQuestions(pi) {
274
279
  const headers = qs.map((q) => q.header).join(", ");
275
280
  text += theme.fg("dim", ` (${headers})`);
276
281
  }
282
+ const previewCount = qs.reduce((acc, q) => acc + (q.options || []).filter((o) => o.preview).length, 0);
283
+ if (previewCount > 0) {
284
+ text += theme.fg("accent", ` [${previewCount} preview${previewCount !== 1 ? "s" : ""}]`);
285
+ }
277
286
  for (const q of qs) {
278
287
  const multiSel = !!q.allowMultiple;
279
288
  text += `\n ${theme.fg("text", q.question)}`;
@@ -19,6 +19,15 @@ export const CLAUDE_CODE_MODELS = [
19
19
  contextWindow: 1_000_000,
20
20
  maxTokens: 128_000,
21
21
  },
22
+ {
23
+ id: "claude-opus-4-7",
24
+ name: "Claude Opus 4.7 (via Claude Code)",
25
+ reasoning: true,
26
+ input: ["text", "image"],
27
+ cost: ZERO_COST,
28
+ contextWindow: 1_000_000,
29
+ maxTokens: 128_000,
30
+ },
22
31
  {
23
32
  id: "claude-sonnet-4-6",
24
33
  name: "Claude Sonnet 4.6 (via Claude Code)",
@@ -6,7 +6,7 @@
6
6
  * AssistantMessageEvents for TUI rendering, then strips tool-call blocks from
7
7
  * the final AssistantMessage so GSD's agent loop doesn't try to dispatch them.
8
8
  */
9
- import { EventStream, mapThinkingLevelToEffort, supportsAdaptiveThinking } from "@gsd/pi-ai";
9
+ import { EventStream } from "@gsd/pi-ai";
10
10
  import { execSync } from "node:child_process";
11
11
  import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
12
12
  import { buildWorkflowMcpServers } from "../gsd/workflow-mcp.js";
@@ -482,6 +482,36 @@ export async function resolveClaudePermissionMode(env = process.env) {
482
482
  }
483
483
  return "bypassPermissions";
484
484
  }
485
+ // NOTE: These helpers intentionally mirror @gsd/pi-ai anthropic-shared
486
+ // behavior so this extension remains typecheck-stable even when the published
487
+ // @gsd/pi-ai barrel lags behind monorepo source exports.
488
+ function modelSupportsAdaptiveThinking(modelId) {
489
+ return (modelId.includes("opus-4-6")
490
+ || modelId.includes("opus-4.6")
491
+ || modelId.includes("opus-4-7")
492
+ || modelId.includes("opus-4.7")
493
+ || modelId.includes("sonnet-4-6")
494
+ || modelId.includes("sonnet-4.6"));
495
+ }
496
+ function mapThinkingLevelToAnthropicEffort(level, modelId) {
497
+ switch (level) {
498
+ case "minimal":
499
+ case "low":
500
+ return "low";
501
+ case "medium":
502
+ return "medium";
503
+ case "high":
504
+ return "high";
505
+ case "xhigh":
506
+ if (modelId.includes("opus-4-7") || modelId.includes("opus-4.7"))
507
+ return "xhigh";
508
+ if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6"))
509
+ return "max";
510
+ return "high";
511
+ default:
512
+ return "high";
513
+ }
514
+ }
485
515
  /**
486
516
  * Build the options object passed to the Claude Agent SDK's `query()` call.
487
517
  *
@@ -513,8 +543,8 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
513
543
  "Bash(pwd)",
514
544
  ...(mcpServers ? Object.keys(mcpServers).map((serverName) => `mcp__${serverName}__*`) : []),
515
545
  ];
516
- const effort = reasoning && supportsAdaptiveThinking(modelId)
517
- ? mapThinkingLevelToEffort(reasoning, modelId)
546
+ const effort = reasoning && modelSupportsAdaptiveThinking(modelId)
547
+ ? mapThinkingLevelToAnthropicEffort(reasoning, modelId)
518
548
  : undefined;
519
549
  return {
520
550
  pathToClaudeCodeExecutable: getClaudePath(),
@@ -529,7 +559,7 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
529
559
  disallowedTools,
530
560
  ...(allowedTools.length > 0 ? { allowedTools } : {}),
531
561
  ...(mcpServers ? { mcpServers } : {}),
532
- betas: modelId.includes("sonnet") ? ["context-1m-2025-08-07"] : [],
562
+ betas: (modelId.includes("sonnet") || modelId.includes("opus-4-7") || modelId.includes("opus-4.7")) ? ["context-1m-2025-08-07"] : [],
533
563
  ...(effort ? { effort } : {}),
534
564
  ...sdkExtraOptions,
535
565
  };
@@ -16,6 +16,7 @@ const ENOENT_PATH_RE = /ENOENT[^']*'([^']+)'/;
16
16
  *
17
17
  * Rule 1: Same error string twice in a row → stuck immediately.
18
18
  * Rule 2: Same unit key 3+ consecutive times → stuck (preserves prior behavior).
19
+ * Rule 2b: Same unit key appears 3+ times anywhere in the active window → stuck.
19
20
  * Rule 3: Oscillation A→B→A→B in last 4 entries → stuck.
20
21
  * Rule 4: Same ENOENT path in any 2 entries within the window → stuck (#3575).
21
22
  * Missing files don't self-heal between retries — retrying wastes budget.
@@ -48,6 +49,14 @@ export function detectStuck(window) {
48
49
  };
49
50
  }
50
51
  }
52
+ // Rule 2b: Same unit key 3+ times anywhere in the active window
53
+ const countInWindow = window.filter((entry) => entry.key === last.key).length;
54
+ if (countInWindow >= 3) {
55
+ return {
56
+ stuck: true,
57
+ reason: `${last.key} derived ${countInWindow} times in last ${window.length} attempts without progress${suffix}`,
58
+ };
59
+ }
51
60
  // Rule 3: Oscillation (A→B→A→B in last 4)
52
61
  if (window.length >= 4) {
53
62
  const w = window.slice(-4);