takt 0.44.0 → 0.46.0

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 (595) hide show
  1. package/README.md +1 -0
  2. package/builtins/en/config.yaml +9 -0
  3. package/builtins/en/facets/instructions/implement-maintenance.md +2 -0
  4. package/builtins/en/facets/instructions/implement.md +3 -2
  5. package/builtins/en/facets/instructions/review-arch.md +1 -1
  6. package/builtins/en/facets/instructions/review-coding.md +4 -3
  7. package/builtins/en/facets/instructions/review-cqrs-es.md +1 -1
  8. package/builtins/en/facets/instructions/review-pure.md +1 -0
  9. package/builtins/en/facets/instructions/review-qa.md +1 -0
  10. package/builtins/en/facets/instructions/review-terraform.md +1 -1
  11. package/builtins/en/facets/instructions/review-test.md +2 -0
  12. package/builtins/en/facets/instructions/supervise-maintenance.md +7 -5
  13. package/builtins/en/facets/instructions/supervise.md +11 -4
  14. package/builtins/en/facets/instructions/write-tests-maintenance.md +1 -0
  15. package/builtins/en/facets/knowledge/e2e-testing.md +11 -1
  16. package/builtins/en/facets/knowledge/unit-testing.md +11 -0
  17. package/builtins/en/facets/output-contracts/maintenance-scope.md +5 -0
  18. package/builtins/en/facets/output-contracts/pure-review.md +61 -0
  19. package/builtins/en/facets/output-contracts/qa-review.md +5 -0
  20. package/builtins/en/facets/output-contracts/supervisor-validation.md +1 -1
  21. package/builtins/en/facets/output-contracts/testing-review.md +6 -1
  22. package/builtins/en/facets/personas/ai-antipattern-reviewer.md +2 -2
  23. package/builtins/en/facets/personas/architecture-reviewer.md +1 -1
  24. package/builtins/en/facets/personas/pr-commenter.md +2 -2
  25. package/builtins/en/facets/personas/pure-reviewer.md +22 -0
  26. package/builtins/en/facets/personas/supervisor.md +1 -1
  27. package/builtins/en/facets/personas/terraform-reviewer.md +3 -3
  28. package/builtins/en/facets/policies/ai-antipattern.md +2 -0
  29. package/builtins/en/facets/policies/coding.md +36 -0
  30. package/builtins/en/facets/policies/review.md +26 -1
  31. package/builtins/en/facets/policies/testing.md +25 -0
  32. package/builtins/en/workflows/backend-cqrs.yaml +21 -0
  33. package/builtins/en/workflows/backend.yaml +21 -0
  34. package/builtins/en/workflows/default-high.yaml +1 -1
  35. package/builtins/en/workflows/default-peer-review.yaml +24 -3
  36. package/builtins/en/workflows/draft.yaml +4 -32
  37. package/builtins/en/workflows/dual-cqrs.yaml +21 -0
  38. package/builtins/en/workflows/dual.yaml +5 -5
  39. package/builtins/en/workflows/frontend-maintenance.yaml +21 -0
  40. package/builtins/en/workflows/frontend.yaml +21 -0
  41. package/builtins/en/workflows/peer-review.yaml +13 -70
  42. package/builtins/en/workflows/provider-options/edit.yaml +21 -0
  43. package/builtins/en/workflows/provider-options/review-files.yaml +10 -0
  44. package/builtins/en/workflows/provider-options/review-readonly.yaml +16 -0
  45. package/builtins/en/workflows/provider-options/review-web.yaml +14 -0
  46. package/builtins/en/workflows/review-backend-cqrs.yaml +21 -0
  47. package/builtins/en/workflows/review-backend.yaml +21 -0
  48. package/builtins/en/workflows/review-default.yaml +6 -6
  49. package/builtins/en/workflows/review-dual-cqrs.yaml +21 -0
  50. package/builtins/en/workflows/review-dual.yaml +21 -0
  51. package/builtins/en/workflows/review-fix-backend-cqrs.yaml +21 -0
  52. package/builtins/en/workflows/review-fix-backend.yaml +21 -0
  53. package/builtins/en/workflows/review-fix-default.yaml +6 -6
  54. package/builtins/en/workflows/review-fix-dual-cqrs.yaml +21 -0
  55. package/builtins/en/workflows/review-fix-dual.yaml +21 -0
  56. package/builtins/en/workflows/review-fix-frontend.yaml +21 -0
  57. package/builtins/en/workflows/review-fix-takt-default.yaml +5 -5
  58. package/builtins/en/workflows/review-frontend.yaml +21 -0
  59. package/builtins/en/workflows/review-takt-default.yaml +6 -6
  60. package/builtins/en/workflows/takt-default-refresh-all.yaml +6 -6
  61. package/builtins/en/workflows/takt-default-refresh-fast.yaml +5 -5
  62. package/builtins/en/workflows/takt-default.yaml +4 -27
  63. package/builtins/en/workflows/terraform.yaml +23 -2
  64. package/builtins/ja/config.yaml +9 -0
  65. package/builtins/ja/facets/instructions/implement-maintenance.md +2 -0
  66. package/builtins/ja/facets/instructions/implement.md +3 -2
  67. package/builtins/ja/facets/instructions/review-arch.md +1 -1
  68. package/builtins/ja/facets/instructions/review-coding.md +4 -3
  69. package/builtins/ja/facets/instructions/review-cqrs-es.md +1 -1
  70. package/builtins/ja/facets/instructions/review-pure.md +1 -0
  71. package/builtins/ja/facets/instructions/review-qa.md +1 -0
  72. package/builtins/ja/facets/instructions/review-terraform.md +1 -1
  73. package/builtins/ja/facets/instructions/review-test.md +2 -0
  74. package/builtins/ja/facets/instructions/supervise-maintenance.md +6 -4
  75. package/builtins/ja/facets/instructions/supervise.md +11 -4
  76. package/builtins/ja/facets/instructions/write-tests-maintenance.md +1 -0
  77. package/builtins/ja/facets/knowledge/e2e-testing.md +11 -1
  78. package/builtins/ja/facets/knowledge/unit-testing.md +11 -0
  79. package/builtins/ja/facets/output-contracts/maintenance-scope.md +5 -0
  80. package/builtins/ja/facets/output-contracts/pure-review.md +61 -0
  81. package/builtins/ja/facets/output-contracts/qa-review.md +5 -0
  82. package/builtins/ja/facets/output-contracts/supervisor-validation.md +1 -1
  83. package/builtins/ja/facets/output-contracts/testing-review.md +6 -1
  84. package/builtins/ja/facets/personas/ai-antipattern-reviewer.md +2 -2
  85. package/builtins/ja/facets/personas/architecture-reviewer.md +2 -2
  86. package/builtins/ja/facets/personas/pr-commenter.md +3 -3
  87. package/builtins/ja/facets/personas/pure-reviewer.md +22 -0
  88. package/builtins/ja/facets/personas/supervisor.md +1 -1
  89. package/builtins/ja/facets/personas/terraform-reviewer.md +3 -3
  90. package/builtins/ja/facets/policies/ai-antipattern.md +2 -0
  91. package/builtins/ja/facets/policies/coding.md +36 -0
  92. package/builtins/ja/facets/policies/review.md +26 -1
  93. package/builtins/ja/facets/policies/testing.md +25 -0
  94. package/builtins/ja/workflows/backend-cqrs.yaml +21 -0
  95. package/builtins/ja/workflows/backend.yaml +21 -0
  96. package/builtins/ja/workflows/default-high.yaml +1 -1
  97. package/builtins/ja/workflows/default-peer-review.yaml +24 -3
  98. package/builtins/ja/workflows/draft.yaml +4 -32
  99. package/builtins/ja/workflows/dual-cqrs.yaml +21 -0
  100. package/builtins/ja/workflows/dual.yaml +5 -5
  101. package/builtins/ja/workflows/frontend-maintenance.yaml +21 -0
  102. package/builtins/ja/workflows/frontend.yaml +21 -0
  103. package/builtins/ja/workflows/peer-review.yaml +13 -70
  104. package/builtins/ja/workflows/provider-options/edit.yaml +21 -0
  105. package/builtins/ja/workflows/provider-options/review-files.yaml +10 -0
  106. package/builtins/ja/workflows/provider-options/review-readonly.yaml +16 -0
  107. package/builtins/ja/workflows/provider-options/review-web.yaml +14 -0
  108. package/builtins/ja/workflows/review-backend-cqrs.yaml +21 -0
  109. package/builtins/ja/workflows/review-backend.yaml +21 -0
  110. package/builtins/ja/workflows/review-default.yaml +7 -7
  111. package/builtins/ja/workflows/review-dual-cqrs.yaml +21 -0
  112. package/builtins/ja/workflows/review-dual.yaml +21 -0
  113. package/builtins/ja/workflows/review-fix-backend-cqrs.yaml +21 -0
  114. package/builtins/ja/workflows/review-fix-backend.yaml +21 -0
  115. package/builtins/ja/workflows/review-fix-default.yaml +6 -6
  116. package/builtins/ja/workflows/review-fix-dual-cqrs.yaml +21 -0
  117. package/builtins/ja/workflows/review-fix-dual.yaml +21 -0
  118. package/builtins/ja/workflows/review-fix-frontend.yaml +21 -0
  119. package/builtins/ja/workflows/review-fix-takt-default.yaml +6 -6
  120. package/builtins/ja/workflows/review-frontend.yaml +21 -0
  121. package/builtins/ja/workflows/review-takt-default.yaml +7 -7
  122. package/builtins/ja/workflows/takt-default-refresh-all.yaml +6 -6
  123. package/builtins/ja/workflows/takt-default-refresh-fast.yaml +5 -5
  124. package/builtins/ja/workflows/takt-default.yaml +4 -27
  125. package/builtins/ja/workflows/terraform.yaml +22 -1
  126. package/dist/agents/decompose-task-usecase.d.ts +2 -1
  127. package/dist/agents/decompose-task-usecase.d.ts.map +1 -1
  128. package/dist/agents/decompose-task-usecase.js +7 -5
  129. package/dist/agents/decompose-task-usecase.js.map +1 -1
  130. package/dist/agents/judge-status-usecase.d.ts +21 -8
  131. package/dist/agents/judge-status-usecase.d.ts.map +1 -1
  132. package/dist/agents/judge-status-usecase.js +30 -13
  133. package/dist/agents/judge-status-usecase.js.map +1 -1
  134. package/dist/agents/runner-prompt.d.ts +3 -1
  135. package/dist/agents/runner-prompt.d.ts.map +1 -1
  136. package/dist/agents/runner-prompt.js +11 -4
  137. package/dist/agents/runner-prompt.js.map +1 -1
  138. package/dist/agents/runner.d.ts.map +1 -1
  139. package/dist/agents/runner.js +23 -5
  140. package/dist/agents/runner.js.map +1 -1
  141. package/dist/agents/structured-caller/capability-aware-structured-caller.d.ts +1 -1
  142. package/dist/agents/structured-caller/capability-aware-structured-caller.d.ts.map +1 -1
  143. package/dist/agents/structured-caller/capability-aware-structured-caller.js +3 -3
  144. package/dist/agents/structured-caller/capability-aware-structured-caller.js.map +1 -1
  145. package/dist/agents/structured-caller/contracts.d.ts +1 -1
  146. package/dist/agents/structured-caller/contracts.d.ts.map +1 -1
  147. package/dist/agents/structured-caller/default-structured-caller.d.ts +1 -1
  148. package/dist/agents/structured-caller/default-structured-caller.d.ts.map +1 -1
  149. package/dist/agents/structured-caller/default-structured-caller.js +2 -2
  150. package/dist/agents/structured-caller/default-structured-caller.js.map +1 -1
  151. package/dist/agents/structured-caller/prompt-based-structured-caller.d.ts +1 -1
  152. package/dist/agents/structured-caller/prompt-based-structured-caller.d.ts.map +1 -1
  153. package/dist/agents/structured-caller/prompt-based-structured-caller.js +16 -17
  154. package/dist/agents/structured-caller/prompt-based-structured-caller.js.map +1 -1
  155. package/dist/agents/team-leader-structured-output.d.ts +3 -3
  156. package/dist/agents/team-leader-structured-output.d.ts.map +1 -1
  157. package/dist/agents/team-leader-structured-output.js +14 -10
  158. package/dist/agents/team-leader-structured-output.js.map +1 -1
  159. package/dist/agents/types.d.ts +1 -0
  160. package/dist/agents/types.d.ts.map +1 -1
  161. package/dist/commands/analyze-usage.d.ts +26 -0
  162. package/dist/commands/analyze-usage.d.ts.map +1 -0
  163. package/dist/commands/analyze-usage.js +305 -0
  164. package/dist/commands/analyze-usage.js.map +1 -0
  165. package/dist/core/logging/contracts.d.ts +1 -0
  166. package/dist/core/logging/contracts.d.ts.map +1 -1
  167. package/dist/core/logging/contracts.js +1 -0
  168. package/dist/core/logging/contracts.js.map +1 -1
  169. package/dist/core/logging/phaseUsageEvent.d.ts +40 -0
  170. package/dist/core/logging/phaseUsageEvent.d.ts.map +1 -0
  171. package/dist/core/logging/phaseUsageEvent.js +195 -0
  172. package/dist/core/logging/phaseUsageEvent.js.map +1 -0
  173. package/dist/core/logging/providerEvent.d.ts +4 -0
  174. package/dist/core/logging/providerEvent.d.ts.map +1 -1
  175. package/dist/core/logging/providerEvent.js +31 -27
  176. package/dist/core/logging/providerEvent.js.map +1 -1
  177. package/dist/core/models/config-schemas.d.ts +16 -0
  178. package/dist/core/models/config-schemas.d.ts.map +1 -1
  179. package/dist/core/models/part.d.ts +2 -1
  180. package/dist/core/models/part.d.ts.map +1 -1
  181. package/dist/core/models/schema-base.d.ts +66 -0
  182. package/dist/core/models/schema-base.d.ts.map +1 -1
  183. package/dist/core/models/schema-base.js +7 -2
  184. package/dist/core/models/schema-base.js.map +1 -1
  185. package/dist/core/models/workflow-provider-options.d.ts +5 -0
  186. package/dist/core/models/workflow-provider-options.d.ts.map +1 -1
  187. package/dist/core/models/workflow-provider-options.js.map +1 -1
  188. package/dist/core/models/workflow-schemas.d.ts +165 -21
  189. package/dist/core/models/workflow-schemas.d.ts.map +1 -1
  190. package/dist/core/models/workflow-schemas.js +62 -18
  191. package/dist/core/models/workflow-schemas.js.map +1 -1
  192. package/dist/core/models/workflow-types.d.ts +1 -1
  193. package/dist/core/models/workflow-types.d.ts.map +1 -1
  194. package/dist/core/models/workflow-types.js.map +1 -1
  195. package/dist/core/workflow/arpeggio/types.d.ts +3 -0
  196. package/dist/core/workflow/arpeggio/types.d.ts.map +1 -1
  197. package/dist/core/workflow/engine/ArpeggioRunner.d.ts +2 -0
  198. package/dist/core/workflow/engine/ArpeggioRunner.d.ts.map +1 -1
  199. package/dist/core/workflow/engine/ArpeggioRunner.js +10 -0
  200. package/dist/core/workflow/engine/ArpeggioRunner.js.map +1 -1
  201. package/dist/core/workflow/engine/OptionsBuilder.d.ts.map +1 -1
  202. package/dist/core/workflow/engine/OptionsBuilder.js +2 -0
  203. package/dist/core/workflow/engine/OptionsBuilder.js.map +1 -1
  204. package/dist/core/workflow/engine/ParallelRunner.d.ts +1 -0
  205. package/dist/core/workflow/engine/ParallelRunner.d.ts.map +1 -1
  206. package/dist/core/workflow/engine/ParallelRunner.js +4 -0
  207. package/dist/core/workflow/engine/ParallelRunner.js.map +1 -1
  208. package/dist/core/workflow/engine/StepExecutor.d.ts.map +1 -1
  209. package/dist/core/workflow/engine/StepExecutor.js +2 -0
  210. package/dist/core/workflow/engine/StepExecutor.js.map +1 -1
  211. package/dist/core/workflow/engine/TeamLeaderRunner.d.ts.map +1 -1
  212. package/dist/core/workflow/engine/TeamLeaderRunner.js +9 -4
  213. package/dist/core/workflow/engine/TeamLeaderRunner.js.map +1 -1
  214. package/dist/core/workflow/engine/WorkflowEngineSetup.d.ts.map +1 -1
  215. package/dist/core/workflow/engine/WorkflowEngineSetup.js +2 -0
  216. package/dist/core/workflow/engine/WorkflowEngineSetup.js.map +1 -1
  217. package/dist/core/workflow/engine/WorkflowRunLoop.d.ts +1 -0
  218. package/dist/core/workflow/engine/WorkflowRunLoop.d.ts.map +1 -1
  219. package/dist/core/workflow/engine/WorkflowRunLoop.js +3 -0
  220. package/dist/core/workflow/engine/WorkflowRunLoop.js.map +1 -1
  221. package/dist/core/workflow/engine/engine-provider-options.d.ts.map +1 -1
  222. package/dist/core/workflow/engine/engine-provider-options.js +3 -3
  223. package/dist/core/workflow/engine/engine-provider-options.js.map +1 -1
  224. package/dist/core/workflow/engine/parallel-logger.d.ts +1 -1
  225. package/dist/core/workflow/engine/parallel-logger.d.ts.map +1 -1
  226. package/dist/core/workflow/engine/parallel-logger.js +3 -1
  227. package/dist/core/workflow/engine/parallel-logger.js.map +1 -1
  228. package/dist/core/workflow/engine/task-decomposer.d.ts +1 -1
  229. package/dist/core/workflow/engine/task-decomposer.d.ts.map +1 -1
  230. package/dist/core/workflow/engine/task-decomposer.js +3 -3
  231. package/dist/core/workflow/engine/task-decomposer.js.map +1 -1
  232. package/dist/core/workflow/engine/team-leader-budget-errors.d.ts +2 -0
  233. package/dist/core/workflow/engine/team-leader-budget-errors.d.ts.map +1 -0
  234. package/dist/core/workflow/engine/team-leader-budget-errors.js +12 -0
  235. package/dist/core/workflow/engine/team-leader-budget-errors.js.map +1 -0
  236. package/dist/core/workflow/engine/team-leader-execution.d.ts.map +1 -1
  237. package/dist/core/workflow/engine/team-leader-execution.js +16 -2
  238. package/dist/core/workflow/engine/team-leader-execution.js.map +1 -1
  239. package/dist/core/workflow/engine/team-leader-part-runner.d.ts.map +1 -1
  240. package/dist/core/workflow/engine/team-leader-part-runner.js +1 -0
  241. package/dist/core/workflow/engine/team-leader-part-runner.js.map +1 -1
  242. package/dist/core/workflow/evaluation/RuleEvaluator.d.ts +2 -0
  243. package/dist/core/workflow/evaluation/RuleEvaluator.d.ts.map +1 -1
  244. package/dist/core/workflow/evaluation/RuleEvaluator.js +1 -0
  245. package/dist/core/workflow/evaluation/RuleEvaluator.js.map +1 -1
  246. package/dist/core/workflow/observability/workflowSpans.d.ts +3 -0
  247. package/dist/core/workflow/observability/workflowSpans.d.ts.map +1 -1
  248. package/dist/core/workflow/observability/workflowSpans.js +61 -10
  249. package/dist/core/workflow/observability/workflowSpans.js.map +1 -1
  250. package/dist/core/workflow/phase-runner.d.ts +2 -0
  251. package/dist/core/workflow/phase-runner.d.ts.map +1 -1
  252. package/dist/core/workflow/phase-runner.js.map +1 -1
  253. package/dist/core/workflow/promotion/PromotionEvaluator.d.ts +2 -0
  254. package/dist/core/workflow/promotion/PromotionEvaluator.d.ts.map +1 -1
  255. package/dist/core/workflow/promotion/PromotionEvaluator.js +1 -0
  256. package/dist/core/workflow/promotion/PromotionEvaluator.js.map +1 -1
  257. package/dist/core/workflow/promotion/promotion-runtime.d.ts +2 -0
  258. package/dist/core/workflow/promotion/promotion-runtime.d.ts.map +1 -1
  259. package/dist/core/workflow/promotion/promotion-runtime.js +1 -0
  260. package/dist/core/workflow/promotion/promotion-runtime.js.map +1 -1
  261. package/dist/core/workflow/quality-gates/commandGateRunner.d.ts +1 -1
  262. package/dist/core/workflow/quality-gates/commandGateRunner.d.ts.map +1 -1
  263. package/dist/core/workflow/quality-gates/commandGateRunner.js +11 -6
  264. package/dist/core/workflow/quality-gates/commandGateRunner.js.map +1 -1
  265. package/dist/core/workflow/quality-gates/qualityGateRunner.d.ts +1 -1
  266. package/dist/core/workflow/quality-gates/qualityGateRunner.d.ts.map +1 -1
  267. package/dist/core/workflow/quality-gates/qualityGateRunner.js +2 -2
  268. package/dist/core/workflow/quality-gates/qualityGateRunner.js.map +1 -1
  269. package/dist/core/workflow/quality-gates/types.d.ts +2 -0
  270. package/dist/core/workflow/quality-gates/types.d.ts.map +1 -1
  271. package/dist/core/workflow/report-phase-runner.js +1 -0
  272. package/dist/core/workflow/report-phase-runner.js.map +1 -1
  273. package/dist/core/workflow/status-judgment-phase.d.ts.map +1 -1
  274. package/dist/core/workflow/status-judgment-phase.js +2 -0
  275. package/dist/core/workflow/status-judgment-phase.js.map +1 -1
  276. package/dist/core/workflow/types.d.ts +4 -0
  277. package/dist/core/workflow/types.d.ts.map +1 -1
  278. package/dist/features/interactive/aiCaller.d.ts +6 -1
  279. package/dist/features/interactive/aiCaller.d.ts.map +1 -1
  280. package/dist/features/interactive/aiCaller.js +14 -5
  281. package/dist/features/interactive/aiCaller.js.map +1 -1
  282. package/dist/features/interactive/clipboardImage.d.ts +3 -0
  283. package/dist/features/interactive/clipboardImage.d.ts.map +1 -0
  284. package/dist/features/interactive/clipboardImage.js +91 -0
  285. package/dist/features/interactive/clipboardImage.js.map +1 -0
  286. package/dist/features/interactive/clipboardImageFeedback.d.ts +2 -0
  287. package/dist/features/interactive/clipboardImageFeedback.d.ts.map +1 -0
  288. package/dist/features/interactive/clipboardImageFeedback.js +6 -0
  289. package/dist/features/interactive/clipboardImageFeedback.js.map +1 -0
  290. package/dist/features/interactive/conversationLoop.d.ts.map +1 -1
  291. package/dist/features/interactive/conversationLoop.js +8 -3
  292. package/dist/features/interactive/conversationLoop.js.map +1 -1
  293. package/dist/features/interactive/imageAttachments.d.ts +3 -0
  294. package/dist/features/interactive/imageAttachments.d.ts.map +1 -1
  295. package/dist/features/interactive/imageAttachments.js +18 -0
  296. package/dist/features/interactive/imageAttachments.js.map +1 -1
  297. package/dist/features/interactive/interactive.d.ts +1 -0
  298. package/dist/features/interactive/interactive.d.ts.map +1 -1
  299. package/dist/features/interactive/interactive.js.map +1 -1
  300. package/dist/features/interactive/interactiveInput.d.ts.map +1 -1
  301. package/dist/features/interactive/interactiveInput.js +4 -1
  302. package/dist/features/interactive/interactiveInput.js.map +1 -1
  303. package/dist/features/interactive/lineEditor.d.ts +18 -14
  304. package/dist/features/interactive/lineEditor.d.ts.map +1 -1
  305. package/dist/features/interactive/lineEditor.js +174 -80
  306. package/dist/features/interactive/lineEditor.js.map +1 -1
  307. package/dist/features/interactive/passthroughMode.d.ts.map +1 -1
  308. package/dist/features/interactive/passthroughMode.js +4 -1
  309. package/dist/features/interactive/passthroughMode.js.map +1 -1
  310. package/dist/features/interactive/quietMode.d.ts.map +1 -1
  311. package/dist/features/interactive/quietMode.js +5 -2
  312. package/dist/features/interactive/quietMode.js.map +1 -1
  313. package/dist/features/interactive/slashCommandRegistry.d.ts.map +1 -1
  314. package/dist/features/interactive/slashCommandRegistry.js +1 -0
  315. package/dist/features/interactive/slashCommandRegistry.js.map +1 -1
  316. package/dist/features/tasks/attachments.d.ts.map +1 -1
  317. package/dist/features/tasks/attachments.js +18 -1
  318. package/dist/features/tasks/attachments.js.map +1 -1
  319. package/dist/features/tasks/execute/runAllTasks.js +3 -3
  320. package/dist/features/tasks/execute/runAllTasks.js.map +1 -1
  321. package/dist/features/tasks/execute/selectAndExecute.d.ts.map +1 -1
  322. package/dist/features/tasks/execute/selectAndExecute.js +1 -2
  323. package/dist/features/tasks/execute/selectAndExecute.js.map +1 -1
  324. package/dist/features/tasks/execute/taskSpecContext.d.ts +1 -0
  325. package/dist/features/tasks/execute/taskSpecContext.d.ts.map +1 -1
  326. package/dist/features/tasks/execute/taskSpecContext.js +25 -1
  327. package/dist/features/tasks/execute/taskSpecContext.js.map +1 -1
  328. package/dist/features/tasks/execute/workflowExecution.d.ts.map +1 -1
  329. package/dist/features/tasks/execute/workflowExecution.js +30 -0
  330. package/dist/features/tasks/execute/workflowExecution.js.map +1 -1
  331. package/dist/features/tasks/execute/workflowExecutionBootstrap.d.ts.map +1 -1
  332. package/dist/features/tasks/execute/workflowExecutionBootstrap.js +13 -1
  333. package/dist/features/tasks/execute/workflowExecutionBootstrap.js.map +1 -1
  334. package/dist/features/tasks/execute/workflowExecutionEvents.d.ts.map +1 -1
  335. package/dist/features/tasks/execute/workflowExecutionEvents.js +6 -0
  336. package/dist/features/tasks/execute/workflowExecutionEvents.js.map +1 -1
  337. package/dist/features/tasks/watch/index.js +3 -3
  338. package/dist/features/tasks/watch/index.js.map +1 -1
  339. package/dist/infra/claude/client.d.ts.map +1 -1
  340. package/dist/infra/claude/client.js +2 -0
  341. package/dist/infra/claude/client.js.map +1 -1
  342. package/dist/infra/claude/executor.d.ts.map +1 -1
  343. package/dist/infra/claude/executor.js +5 -35
  344. package/dist/infra/claude/executor.js.map +1 -1
  345. package/dist/infra/claude/image-input.d.ts +4 -0
  346. package/dist/infra/claude/image-input.d.ts.map +1 -0
  347. package/dist/infra/claude/image-input.js +63 -0
  348. package/dist/infra/claude/image-input.js.map +1 -0
  349. package/dist/infra/claude/options-builder.d.ts.map +1 -1
  350. package/dist/infra/claude/options-builder.js +2 -3
  351. package/dist/infra/claude/options-builder.js.map +1 -1
  352. package/dist/infra/claude/types.d.ts +5 -0
  353. package/dist/infra/claude/types.d.ts.map +1 -1
  354. package/dist/infra/claude/usage.d.ts +3 -0
  355. package/dist/infra/claude/usage.d.ts.map +1 -0
  356. package/dist/infra/claude/usage.js +45 -0
  357. package/dist/infra/claude/usage.js.map +1 -0
  358. package/dist/infra/claude-headless/headless-spawn.d.ts.map +1 -1
  359. package/dist/infra/claude-headless/headless-spawn.js +2 -1
  360. package/dist/infra/claude-headless/headless-spawn.js.map +1 -1
  361. package/dist/infra/claude-headless/result-response.d.ts.map +1 -1
  362. package/dist/infra/claude-headless/result-response.js +1 -0
  363. package/dist/infra/claude-headless/result-response.js.map +1 -1
  364. package/dist/infra/claude-headless/stream-json-lines.d.ts +2 -0
  365. package/dist/infra/claude-headless/stream-json-lines.d.ts.map +1 -1
  366. package/dist/infra/claude-headless/stream-json-lines.js +4 -0
  367. package/dist/infra/claude-headless/stream-json-lines.js.map +1 -1
  368. package/dist/infra/claude-headless/types.d.ts +1 -0
  369. package/dist/infra/claude-headless/types.d.ts.map +1 -1
  370. package/dist/infra/claude-terminal/client.d.ts.map +1 -1
  371. package/dist/infra/claude-terminal/client.js +1 -0
  372. package/dist/infra/claude-terminal/client.js.map +1 -1
  373. package/dist/infra/claude-terminal/response-normalizer.js.map +1 -1
  374. package/dist/infra/claude-terminal/tmux-backend.d.ts.map +1 -1
  375. package/dist/infra/claude-terminal/tmux-backend.js +15 -1
  376. package/dist/infra/claude-terminal/tmux-backend.js.map +1 -1
  377. package/dist/infra/claude-terminal/types.d.ts +2 -0
  378. package/dist/infra/claude-terminal/types.d.ts.map +1 -1
  379. package/dist/infra/codex/client.d.ts.map +1 -1
  380. package/dist/infra/codex/client.js +14 -2
  381. package/dist/infra/codex/client.js.map +1 -1
  382. package/dist/infra/codex/types.d.ts +3 -0
  383. package/dist/infra/codex/types.d.ts.map +1 -1
  384. package/dist/infra/codex/types.js.map +1 -1
  385. package/dist/infra/config/configNormalizers.d.ts.map +1 -1
  386. package/dist/infra/config/configNormalizers.js +9 -1
  387. package/dist/infra/config/configNormalizers.js.map +1 -1
  388. package/dist/infra/config/loaders/workflowDiscovery.js +1 -1
  389. package/dist/infra/config/loaders/workflowDiscovery.js.map +1 -1
  390. package/dist/infra/config/loaders/workflowLoopMonitorNormalizer.d.ts.map +1 -1
  391. package/dist/infra/config/loaders/workflowLoopMonitorNormalizer.js +1 -1
  392. package/dist/infra/config/loaders/workflowLoopMonitorNormalizer.js.map +1 -1
  393. package/dist/infra/config/loaders/workflowParser.d.ts.map +1 -1
  394. package/dist/infra/config/loaders/workflowParser.js +1 -1
  395. package/dist/infra/config/loaders/workflowParser.js.map +1 -1
  396. package/dist/infra/config/loaders/workflowProviderOptionsResolver.d.ts +7 -0
  397. package/dist/infra/config/loaders/workflowProviderOptionsResolver.d.ts.map +1 -0
  398. package/dist/infra/config/loaders/workflowProviderOptionsResolver.js +68 -0
  399. package/dist/infra/config/loaders/workflowProviderOptionsResolver.js.map +1 -0
  400. package/dist/infra/config/loaders/workflowStepFeaturesNormalizer.d.ts.map +1 -1
  401. package/dist/infra/config/loaders/workflowStepFeaturesNormalizer.js +5 -3
  402. package/dist/infra/config/loaders/workflowStepFeaturesNormalizer.js.map +1 -1
  403. package/dist/infra/config/loaders/workflowStepNormalizer.d.ts +1 -1
  404. package/dist/infra/config/loaders/workflowStepNormalizer.d.ts.map +1 -1
  405. package/dist/infra/config/loaders/workflowStepNormalizer.js +41 -10
  406. package/dist/infra/config/loaders/workflowStepNormalizer.js.map +1 -1
  407. package/dist/infra/config/providerOptions.d.ts +6 -1
  408. package/dist/infra/config/providerOptions.d.ts.map +1 -1
  409. package/dist/infra/config/providerOptions.js +31 -3
  410. package/dist/infra/config/providerOptions.js.map +1 -1
  411. package/dist/infra/config/providerOptionsContract.d.ts +3 -3
  412. package/dist/infra/config/providerOptionsContract.d.ts.map +1 -1
  413. package/dist/infra/config/providerOptionsContract.js +8 -0
  414. package/dist/infra/config/providerOptionsContract.js.map +1 -1
  415. package/dist/infra/copilot/client.d.ts.map +1 -1
  416. package/dist/infra/copilot/client.js +7 -8
  417. package/dist/infra/copilot/client.js.map +1 -1
  418. package/dist/infra/copilot/types.d.ts +1 -0
  419. package/dist/infra/copilot/types.d.ts.map +1 -1
  420. package/dist/infra/cursor/client.d.ts.map +1 -1
  421. package/dist/infra/cursor/client.js +7 -8
  422. package/dist/infra/cursor/client.js.map +1 -1
  423. package/dist/infra/cursor/types.d.ts +1 -0
  424. package/dist/infra/cursor/types.d.ts.map +1 -1
  425. package/dist/infra/fs/index.d.ts +1 -0
  426. package/dist/infra/fs/index.d.ts.map +1 -1
  427. package/dist/infra/fs/index.js +1 -0
  428. package/dist/infra/fs/index.js.map +1 -1
  429. package/dist/infra/fs/jsonl.d.ts +2 -0
  430. package/dist/infra/fs/jsonl.d.ts.map +1 -0
  431. package/dist/infra/fs/jsonl.js +5 -0
  432. package/dist/infra/fs/jsonl.js.map +1 -0
  433. package/dist/infra/kiro/client.d.ts.map +1 -1
  434. package/dist/infra/kiro/client.js +10 -0
  435. package/dist/infra/kiro/client.js.map +1 -1
  436. package/dist/infra/kiro/process.d.ts.map +1 -1
  437. package/dist/infra/kiro/process.js +4 -2
  438. package/dist/infra/kiro/process.js.map +1 -1
  439. package/dist/infra/kiro/types.d.ts +2 -0
  440. package/dist/infra/kiro/types.d.ts.map +1 -1
  441. package/dist/infra/observability/otelFoundation.d.ts +2 -0
  442. package/dist/infra/observability/otelFoundation.d.ts.map +1 -1
  443. package/dist/infra/observability/otelFoundation.js +138 -25
  444. package/dist/infra/observability/otelFoundation.js.map +1 -1
  445. package/dist/infra/observability/usageEventsSpanProcessor.d.ts +19 -0
  446. package/dist/infra/observability/usageEventsSpanProcessor.d.ts.map +1 -0
  447. package/dist/infra/observability/usageEventsSpanProcessor.js +77 -0
  448. package/dist/infra/observability/usageEventsSpanProcessor.js.map +1 -0
  449. package/dist/infra/opencode/OpenCodeStreamHandler.d.ts +19 -0
  450. package/dist/infra/opencode/OpenCodeStreamHandler.d.ts.map +1 -1
  451. package/dist/infra/opencode/OpenCodeStreamHandler.js +10 -0
  452. package/dist/infra/opencode/OpenCodeStreamHandler.js.map +1 -1
  453. package/dist/infra/opencode/allowedTools.d.ts +2 -0
  454. package/dist/infra/opencode/allowedTools.d.ts.map +1 -0
  455. package/dist/infra/opencode/allowedTools.js +10 -0
  456. package/dist/infra/opencode/allowedTools.js.map +1 -0
  457. package/dist/infra/opencode/client.d.ts +4 -2
  458. package/dist/infra/opencode/client.d.ts.map +1 -1
  459. package/dist/infra/opencode/client.js +283 -124
  460. package/dist/infra/opencode/client.js.map +1 -1
  461. package/dist/infra/opencode/index.d.ts +1 -1
  462. package/dist/infra/opencode/index.d.ts.map +1 -1
  463. package/dist/infra/opencode/index.js +1 -1
  464. package/dist/infra/opencode/index.js.map +1 -1
  465. package/dist/infra/opencode/types.d.ts +12 -10
  466. package/dist/infra/opencode/types.d.ts.map +1 -1
  467. package/dist/infra/opencode/types.js +109 -40
  468. package/dist/infra/opencode/types.js.map +1 -1
  469. package/dist/infra/providers/allowed-tool-edit-policy.d.ts +3 -0
  470. package/dist/infra/providers/allowed-tool-edit-policy.d.ts.map +1 -0
  471. package/dist/infra/providers/allowed-tool-edit-policy.js +10 -0
  472. package/dist/infra/providers/allowed-tool-edit-policy.js.map +1 -0
  473. package/dist/infra/providers/claude-headless.d.ts +3 -0
  474. package/dist/infra/providers/claude-headless.d.ts.map +1 -1
  475. package/dist/infra/providers/claude-headless.js +9 -0
  476. package/dist/infra/providers/claude-headless.js.map +1 -1
  477. package/dist/infra/providers/claude-terminal.d.ts +3 -0
  478. package/dist/infra/providers/claude-terminal.d.ts.map +1 -1
  479. package/dist/infra/providers/claude-terminal.js +9 -0
  480. package/dist/infra/providers/claude-terminal.js.map +1 -1
  481. package/dist/infra/providers/claude.d.ts +3 -0
  482. package/dist/infra/providers/claude.d.ts.map +1 -1
  483. package/dist/infra/providers/claude.js +10 -0
  484. package/dist/infra/providers/claude.js.map +1 -1
  485. package/dist/infra/providers/codex.d.ts +3 -0
  486. package/dist/infra/providers/codex.d.ts.map +1 -1
  487. package/dist/infra/providers/codex.js +9 -0
  488. package/dist/infra/providers/codex.js.map +1 -1
  489. package/dist/infra/providers/copilot.d.ts +3 -0
  490. package/dist/infra/providers/copilot.d.ts.map +1 -1
  491. package/dist/infra/providers/copilot.js +8 -0
  492. package/dist/infra/providers/copilot.js.map +1 -1
  493. package/dist/infra/providers/cursor.d.ts +3 -0
  494. package/dist/infra/providers/cursor.d.ts.map +1 -1
  495. package/dist/infra/providers/cursor.js +8 -0
  496. package/dist/infra/providers/cursor.js.map +1 -1
  497. package/dist/infra/providers/imageAttachmentPrompt.d.ts +4 -0
  498. package/dist/infra/providers/imageAttachmentPrompt.d.ts.map +1 -0
  499. package/dist/infra/providers/imageAttachmentPrompt.js +10 -0
  500. package/dist/infra/providers/imageAttachmentPrompt.js.map +1 -0
  501. package/dist/infra/providers/kiro.d.ts +3 -0
  502. package/dist/infra/providers/kiro.d.ts.map +1 -1
  503. package/dist/infra/providers/kiro.js +12 -0
  504. package/dist/infra/providers/kiro.js.map +1 -1
  505. package/dist/infra/providers/mock.d.ts +3 -0
  506. package/dist/infra/providers/mock.d.ts.map +1 -1
  507. package/dist/infra/providers/mock.js +8 -0
  508. package/dist/infra/providers/mock.js.map +1 -1
  509. package/dist/infra/providers/opencode.d.ts +4 -1
  510. package/dist/infra/providers/opencode.d.ts.map +1 -1
  511. package/dist/infra/providers/opencode.js +17 -3
  512. package/dist/infra/providers/opencode.js.map +1 -1
  513. package/dist/infra/providers/provider-capabilities.d.ts +3 -0
  514. package/dist/infra/providers/provider-capabilities.d.ts.map +1 -1
  515. package/dist/infra/providers/provider-capabilities.js +19 -1
  516. package/dist/infra/providers/provider-capabilities.js.map +1 -1
  517. package/dist/infra/providers/runtimeSystemPrompt.d.ts +2 -0
  518. package/dist/infra/providers/runtimeSystemPrompt.d.ts.map +1 -0
  519. package/dist/infra/providers/runtimeSystemPrompt.js +11 -0
  520. package/dist/infra/providers/runtimeSystemPrompt.js.map +1 -0
  521. package/dist/infra/providers/types.d.ts +9 -0
  522. package/dist/infra/providers/types.d.ts.map +1 -1
  523. package/dist/infra/rate-limit/detection.d.ts +1 -1
  524. package/dist/infra/rate-limit/detection.d.ts.map +1 -1
  525. package/dist/infra/rate-limit/detection.js +6 -7
  526. package/dist/infra/rate-limit/detection.js.map +1 -1
  527. package/dist/infra/resources/schema-loader.d.ts +1 -1
  528. package/dist/infra/resources/schema-loader.d.ts.map +1 -1
  529. package/dist/infra/resources/schema-loader.js +8 -4
  530. package/dist/infra/resources/schema-loader.js.map +1 -1
  531. package/dist/infra/service/runSyncConflictResolver.d.ts.map +1 -1
  532. package/dist/infra/service/runSyncConflictResolver.js +3 -1
  533. package/dist/infra/service/runSyncConflictResolver.js.map +1 -1
  534. package/dist/infra/task/clone-exec.d.ts +2 -0
  535. package/dist/infra/task/clone-exec.d.ts.map +1 -1
  536. package/dist/infra/task/clone-exec.js +29 -0
  537. package/dist/infra/task/clone-exec.js.map +1 -1
  538. package/dist/infra/task/clone.d.ts.map +1 -1
  539. package/dist/infra/task/clone.js +3 -1
  540. package/dist/infra/task/clone.js.map +1 -1
  541. package/dist/infra/task/runner.d.ts +1 -1
  542. package/dist/infra/task/runner.d.ts.map +1 -1
  543. package/dist/infra/task/runner.js +2 -2
  544. package/dist/infra/task/runner.js.map +1 -1
  545. package/dist/infra/task/summarize.d.ts.map +1 -1
  546. package/dist/infra/task/summarize.js +3 -1
  547. package/dist/infra/task/summarize.js.map +1 -1
  548. package/dist/infra/task/taskLifecycleService.d.ts +1 -2
  549. package/dist/infra/task/taskLifecycleService.d.ts.map +1 -1
  550. package/dist/infra/task/taskLifecycleService.js +13 -19
  551. package/dist/infra/task/taskLifecycleService.js.map +1 -1
  552. package/dist/infra/task/taskRecordMutations.d.ts +0 -1
  553. package/dist/infra/task/taskRecordMutations.d.ts.map +1 -1
  554. package/dist/infra/task/taskRecordMutations.js +0 -12
  555. package/dist/infra/task/taskRecordMutations.js.map +1 -1
  556. package/dist/shared/constants.d.ts +3 -0
  557. package/dist/shared/constants.d.ts.map +1 -1
  558. package/dist/shared/constants.js +3 -0
  559. package/dist/shared/constants.js.map +1 -1
  560. package/dist/shared/i18n/labels_en.yaml +3 -1
  561. package/dist/shared/i18n/labels_ja.yaml +3 -1
  562. package/dist/shared/prompts/en/perform_agent_system_prompt.md +9 -1
  563. package/dist/shared/prompts/en/provider_runtime_system_prompt.md +18 -0
  564. package/dist/shared/prompts/index.d.ts +1 -1
  565. package/dist/shared/prompts/index.d.ts.map +1 -1
  566. package/dist/shared/prompts/index.js +7 -1
  567. package/dist/shared/prompts/index.js.map +1 -1
  568. package/dist/shared/prompts/ja/perform_agent_system_prompt.md +9 -1
  569. package/dist/shared/prompts/ja/provider_runtime_system_prompt.md +18 -0
  570. package/dist/shared/telemetry/childProcessEnv.d.ts +7 -0
  571. package/dist/shared/telemetry/childProcessEnv.d.ts.map +1 -0
  572. package/dist/shared/telemetry/childProcessEnv.js +176 -0
  573. package/dist/shared/telemetry/childProcessEnv.js.map +1 -0
  574. package/dist/shared/telemetry/index.d.ts +3 -0
  575. package/dist/shared/telemetry/index.d.ts.map +1 -0
  576. package/dist/shared/telemetry/index.js +3 -0
  577. package/dist/shared/telemetry/index.js.map +1 -0
  578. package/dist/shared/telemetry/otlp.d.ts +40 -0
  579. package/dist/shared/telemetry/otlp.d.ts.map +1 -0
  580. package/dist/shared/telemetry/otlp.js +72 -0
  581. package/dist/shared/telemetry/otlp.js.map +1 -0
  582. package/dist/shared/types/provider.d.ts +28 -1
  583. package/dist/shared/types/provider.d.ts.map +1 -1
  584. package/dist/shared/types/provider.js +15 -1
  585. package/dist/shared/types/provider.js.map +1 -1
  586. package/dist/shared/ui/StreamDisplay.d.ts.map +1 -1
  587. package/dist/shared/ui/StreamDisplay.js +1 -0
  588. package/dist/shared/ui/StreamDisplay.js.map +1 -1
  589. package/package.json +8 -4
  590. package/builtins/en/facets/instructions/review-requirements.md +0 -17
  591. package/builtins/en/facets/output-contracts/requirements-review.md +0 -56
  592. package/builtins/en/facets/personas/requirements-reviewer.md +0 -33
  593. package/builtins/ja/facets/instructions/review-requirements.md +0 -17
  594. package/builtins/ja/facets/output-contracts/requirements-review.md +0 -56
  595. package/builtins/ja/facets/personas/requirements-reviewer.md +0 -33
@@ -7,10 +7,11 @@
7
7
  import { createOpencode } from '@opencode-ai/sdk/v2';
8
8
  import { createServer } from 'node:net';
9
9
  import { AskUserQuestionDeniedError } from '../../core/workflow/ask-user-question-error.js';
10
- import { createLogger, getErrorMessage, createStreamDiagnostics, parseStructuredOutput } from '../../shared/utils/index.js';
10
+ import { createLogger, getErrorMessage, createStreamDiagnostics } from '../../shared/utils/index.js';
11
+ import { getNestedObservabilityEnvFingerprint, runWithNestedObservabilityProcessEnv, } from '../../shared/telemetry/index.js';
11
12
  import { parseProviderModel } from '../../shared/utils/providerModel.js';
12
- import { buildOpenCodePermissionRuleset, mapToOpenCodePermissionReply, mapToOpenCodeTools, } from './types.js';
13
- import { createStreamTrackingState, emitInit, emitText, emitResult, handlePartUpdated, } from './OpenCodeStreamHandler.js';
13
+ import { buildOpenCodePermissionRuleset, resolveOpenCodePermissionReply, } from './types.js';
14
+ import { createStreamTrackingState, emitInit, emitText, emitPermissionAsked, emitPermissionSummary, emitResult, handlePartUpdated, } from './OpenCodeStreamHandler.js';
14
15
  import { buildRateLimitedResponseFields, containsRateLimitError } from '../rate-limit/detection.js';
15
16
  const log = createLogger('opencode-sdk');
16
17
  const OPENCODE_STREAM_IDLE_TIMEOUT_MS = 10 * 60 * 1000;
@@ -31,60 +32,132 @@ const OPENCODE_RETRYABLE_ERROR_PATTERNS = [
31
32
  'failed to start server on port',
32
33
  'timeout waiting for server',
33
34
  ];
34
- let sharedServer = null;
35
- let initPromise = null;
36
- async function acquireClient(model, apiKey) {
37
- if (initPromise) {
38
- await initPromise;
35
+ const sharedServers = new Map();
36
+ async function acquireClient(model, apiKey, childProcessEnv, abortSignal) {
37
+ throwIfAborted(abortSignal);
38
+ const key = buildSharedServerKey(model, apiKey, childProcessEnv);
39
+ const entry = getSharedServerEntry(key);
40
+ if (entry.initPromise) {
41
+ const server = await entry.initPromise;
42
+ throwIfAborted(abortSignal);
43
+ return acquireSharedServer(server, abortSignal);
39
44
  }
40
- if (sharedServer?.model === model && sharedServer.apiKey === apiKey) {
41
- if (sharedServer.queue.length === 0) {
42
- return { client: sharedServer.client, release: () => releaseClient() };
45
+ if (entry.server) {
46
+ return acquireSharedServer(entry.server, abortSignal);
47
+ }
48
+ entry.initPromise = createSharedServer(model, apiKey, childProcessEnv)
49
+ .then((server) => {
50
+ entry.server = server;
51
+ return server;
52
+ })
53
+ .finally(() => {
54
+ entry.initPromise = undefined;
55
+ });
56
+ const server = await entry.initPromise;
57
+ throwIfAborted(abortSignal);
58
+ return acquireSharedServer(server, abortSignal);
59
+ }
60
+ function buildSharedServerKey(model, apiKey, childProcessEnv) {
61
+ return JSON.stringify([model, apiKey, getNestedObservabilityEnvFingerprint(childProcessEnv)]);
62
+ }
63
+ function getSharedServerEntry(key) {
64
+ const existing = sharedServers.get(key);
65
+ if (existing) {
66
+ return existing;
67
+ }
68
+ const entry = {};
69
+ sharedServers.set(key, entry);
70
+ return entry;
71
+ }
72
+ async function createSharedServer(model, apiKey, childProcessEnv) {
73
+ const port = await getFreePort();
74
+ const { client, server } = await runWithNestedObservabilityProcessEnv(childProcessEnv, () => createOpencode({
75
+ port,
76
+ config: {
77
+ model,
78
+ small_model: model,
79
+ ...(apiKey ? { provider: { opencode: { options: { apiKey } } } } : {}),
80
+ },
81
+ timeout: OPENCODE_SERVER_START_TIMEOUT_MS,
82
+ }));
83
+ const closeServer = () => {
84
+ try {
85
+ server.close();
43
86
  }
44
- return new Promise((resolve) => {
45
- sharedServer.queue.push((client) => resolve({ client, release: () => releaseClient() }));
46
- });
87
+ catch (error) {
88
+ log.debug(`Failed to close OpenCode server: ${getErrorMessage(error)}`, { model });
89
+ }
90
+ };
91
+ log.debug('OpenCode server started', { model, port });
92
+ return { client, close: closeServer, model, apiKey, busy: false, queue: [] };
93
+ }
94
+ function acquireSharedServer(server, abortSignal) {
95
+ throwIfAborted(abortSignal);
96
+ if (!server.busy) {
97
+ server.busy = true;
98
+ return { client: server.client, release: createReleaseHandle(server) };
47
99
  }
48
- sharedServer?.close();
49
- let resolveInit;
50
- initPromise = new Promise((resolve) => { resolveInit = resolve; });
100
+ return new Promise((resolve, reject) => {
101
+ const entry = { resolve, reject, signal: abortSignal };
102
+ if (abortSignal) {
103
+ entry.onAbort = () => {
104
+ removeQueuedClient(server, entry);
105
+ reject(new Error(OPENCODE_STREAM_ABORTED_MESSAGE));
106
+ };
107
+ abortSignal.addEventListener('abort', entry.onAbort, { once: true });
108
+ }
109
+ server.queue.push(entry);
110
+ });
111
+ }
112
+ export async function getOpenCodeSessionSnapshot(model, sessionID, directory, apiKey) {
113
+ const { client, release } = await acquireClient(model, apiKey, undefined);
51
114
  try {
52
- const port = await getFreePort();
53
- const { client, server } = await createOpencode({
54
- port,
55
- config: {
56
- model,
57
- small_model: model,
58
- ...(apiKey ? { provider: { opencode: { options: { apiKey } } } } : {}),
59
- },
60
- timeout: OPENCODE_SERVER_START_TIMEOUT_MS,
61
- });
62
- const closeServer = () => {
63
- try {
64
- server.close();
65
- }
66
- catch {
67
- // Ignore close errors
68
- }
69
- };
70
- sharedServer = { client, close: closeServer, model, apiKey, queue: [] };
71
- log.debug('OpenCode server started', { model, port });
72
- return { client, release: () => releaseClient() };
115
+ const result = await client.session.get({ sessionID, directory });
116
+ if (!result.data) {
117
+ throw new Error(`OpenCode session not found: ${sessionID}`);
118
+ }
119
+ return result.data;
73
120
  }
74
121
  finally {
75
- initPromise = null;
76
- resolveInit();
122
+ release();
77
123
  }
78
124
  }
79
- function releaseClient() {
80
- if (!sharedServer)
125
+ function releaseClient(server) {
126
+ const next = server.queue.shift();
127
+ if (next) {
128
+ if (next.signal && next.onAbort) {
129
+ next.signal.removeEventListener('abort', next.onAbort);
130
+ }
131
+ next.resolve({ client: server.client, release: createReleaseHandle(server) });
81
132
  return;
82
- const next = sharedServer.queue.shift();
83
- next?.(sharedServer.client);
133
+ }
134
+ server.busy = false;
135
+ }
136
+ function removeQueuedClient(server, entry) {
137
+ server.queue = server.queue.filter((queued) => queued !== entry);
138
+ if (entry.signal && entry.onAbort) {
139
+ entry.signal.removeEventListener('abort', entry.onAbort);
140
+ }
141
+ }
142
+ function throwIfAborted(signal) {
143
+ if (signal?.aborted) {
144
+ throw new Error(OPENCODE_STREAM_ABORTED_MESSAGE);
145
+ }
146
+ }
147
+ function createReleaseHandle(server) {
148
+ let released = false;
149
+ return () => {
150
+ if (released)
151
+ return;
152
+ released = true;
153
+ releaseClient(server);
154
+ };
84
155
  }
85
156
  export function resetSharedServer() {
86
- sharedServer?.close();
87
- sharedServer = null;
157
+ for (const entry of sharedServers.values()) {
158
+ entry.server?.close();
159
+ }
160
+ sharedServers.clear();
88
161
  }
89
162
  async function withTimeout(operation, timeoutMs, timeoutErrorMessage) {
90
163
  const controller = new AbortController();
@@ -123,25 +196,33 @@ function extractOpenCodeErrorMessage(error) {
123
196
  }
124
197
  return undefined;
125
198
  }
126
- function getCommonPrefixLength(a, b) {
127
- const max = Math.min(a.length, b.length);
128
- let i = 0;
129
- while (i < max && a[i] === b[i]) {
130
- i += 1;
131
- }
132
- return i;
133
- }
134
199
  function stripPromptEcho(chunk, echoState) {
135
200
  if (!chunk)
136
201
  return '';
137
- if (!echoState.remainingPrompt)
202
+ if (echoState.remainingPrompts.length === 0)
138
203
  return chunk;
139
- const consumeLength = getCommonPrefixLength(chunk, echoState.remainingPrompt);
140
- if (consumeLength > 0) {
141
- echoState.remainingPrompt = echoState.remainingPrompt.slice(consumeLength);
142
- return chunk.slice(consumeLength);
204
+ const matchingPrompts = echoState.remainingPrompts.filter((remainingPrompt) => (remainingPrompt.startsWith(chunk) || chunk.startsWith(remainingPrompt)));
205
+ if (matchingPrompts.length === 0) {
206
+ echoState.remainingPrompts = [];
207
+ return chunk;
208
+ }
209
+ const consumedPrompt = matchingPrompts
210
+ .filter((remainingPrompt) => chunk.startsWith(remainingPrompt))
211
+ .sort((a, b) => b.length - a.length)[0];
212
+ if (consumedPrompt !== undefined) {
213
+ const visible = chunk.slice(consumedPrompt.length);
214
+ echoState.remainingPrompts = [];
215
+ return visible;
216
+ }
217
+ echoState.remainingPrompts = matchingPrompts.map((remainingPrompt) => (remainingPrompt.slice(chunk.length)));
218
+ return '';
219
+ }
220
+ function buildPromptEchoCandidates(prompt, systemPrompt) {
221
+ const prompts = [prompt];
222
+ if (systemPrompt !== undefined && systemPrompt.length > 0) {
223
+ prompts.unshift(`${systemPrompt}\n\n${prompt}`);
143
224
  }
144
- return chunk;
225
+ return Array.from(new Set(prompts)).filter((candidate) => candidate.length > 0);
145
226
  }
146
227
  function toQuestionInput(props) {
147
228
  return {
@@ -165,6 +246,12 @@ function toQuestionAnswers(props, answers) {
165
246
  return [value];
166
247
  });
167
248
  }
249
+ function buildPermissionRejectedMessage(permission) {
250
+ if (permission && permission.length > 0) {
251
+ return `OpenCode permission rejected: ${permission}`;
252
+ }
253
+ return 'OpenCode permission rejected';
254
+ }
168
255
  async function getFreePort() {
169
256
  return new Promise((resolve, reject) => {
170
257
  const server = createServer();
@@ -198,6 +285,10 @@ export class OpenCodeClient {
198
285
  if (abortCause === 'timeout') {
199
286
  return true;
200
287
  }
288
+ if (abortCause === 'prompt') {
289
+ const lower = message.toLowerCase();
290
+ return OPENCODE_RETRYABLE_ERROR_PATTERNS.some((pattern) => lower.includes(pattern));
291
+ }
201
292
  if (aborted || abortCause) {
202
293
  return false;
203
294
  }
@@ -229,17 +320,6 @@ export class OpenCodeClient {
229
320
  }
230
321
  });
231
322
  }
232
- /** Build a prompt suffix that instructs the agent to return JSON matching the schema */
233
- buildStructuredOutputSuffix(schema) {
234
- return [
235
- '',
236
- '---',
237
- 'IMPORTANT: You MUST respond with ONLY a valid JSON object matching this schema. No other text, no markdown code blocks, no explanation.',
238
- '```',
239
- JSON.stringify(schema, null, 2),
240
- '```',
241
- ].join('\n');
242
- }
243
323
  buildRateLimitedResponse(agentType, sessionId, message) {
244
324
  return {
245
325
  persona: agentType,
@@ -250,14 +330,6 @@ export class OpenCodeClient {
250
330
  }
251
331
  /** Call OpenCode with an agent prompt */
252
332
  async call(agentType, prompt, options) {
253
- const basePrompt = options.systemPrompt
254
- ? `${options.systemPrompt}\n\n${prompt}`
255
- : prompt;
256
- // OpenCode SDK does not natively support structured output via outputFormat.
257
- // Inject JSON output instructions into the prompt to make the agent return JSON.
258
- const fullPrompt = options.outputSchema
259
- ? `${basePrompt}${this.buildStructuredOutputSuffix(options.outputSchema)}`
260
- : basePrompt;
261
333
  for (let attempt = 1; attempt <= OPENCODE_RETRY_MAX_ATTEMPTS; attempt++) {
262
334
  let idleTimeoutId;
263
335
  const streamAbortController = new AbortController();
@@ -267,7 +339,38 @@ export class OpenCodeClient {
267
339
  let release;
268
340
  let opencodeApiClient;
269
341
  let sessionId = options.sessionId;
342
+ let promptCompletion;
343
+ let promptCompletionWait;
344
+ let promptError;
270
345
  const interactionTimeoutMs = options.interactionTimeoutMs ?? OPENCODE_INTERACTION_TIMEOUT_MS;
346
+ const promptCompletionTimeoutMessage = 'OpenCode prompt completion timed out';
347
+ const awaitPromptCompletion = () => {
348
+ if (!promptCompletion) {
349
+ return Promise.resolve();
350
+ }
351
+ promptCompletionWait ??= (async () => {
352
+ let timeoutId;
353
+ try {
354
+ await Promise.race([
355
+ promptCompletion,
356
+ new Promise((_, reject) => {
357
+ timeoutId = setTimeout(() => {
358
+ reject(new Error(promptCompletionTimeoutMessage));
359
+ }, interactionTimeoutMs);
360
+ }),
361
+ ]);
362
+ }
363
+ catch (error) {
364
+ promptError ??= getErrorMessage(error);
365
+ }
366
+ finally {
367
+ if (timeoutId !== undefined) {
368
+ clearTimeout(timeoutId);
369
+ }
370
+ }
371
+ })();
372
+ return promptCompletionWait;
373
+ };
271
374
  const resetIdleTimeout = () => {
272
375
  if (idleTimeoutId !== undefined) {
273
376
  clearTimeout(idleTimeoutId);
@@ -284,6 +387,7 @@ export class OpenCodeClient {
284
387
  };
285
388
  if (options.abortSignal) {
286
389
  if (options.abortSignal.aborted) {
390
+ abortCause = 'external';
287
391
  streamAbortController.abort();
288
392
  }
289
393
  else {
@@ -301,48 +405,78 @@ export class OpenCodeClient {
301
405
  diagRef = diag;
302
406
  const parsedModel = parseProviderModel(options.model, 'OpenCode model');
303
407
  const fullModel = `${parsedModel.providerID}/${parsedModel.modelID}`;
304
- const acquired = await acquireClient(fullModel, options.opencodeApiKey);
408
+ const acquired = await acquireClient(fullModel, options.opencodeApiKey, options.childProcessEnv, options.abortSignal);
305
409
  opencodeApiClient = acquired.client;
306
410
  release = acquired.release;
307
- const sessionResult = sessionId
308
- ? { data: { id: sessionId } }
309
- : await opencodeApiClient.session.create({
411
+ if (streamAbortController.signal.aborted) {
412
+ release();
413
+ release = undefined;
414
+ throw new Error(OPENCODE_STREAM_ABORTED_MESSAGE);
415
+ }
416
+ const permissionRuleset = buildOpenCodePermissionRuleset(options.permissionMode, options.networkAccess, options.allowedTools);
417
+ const shouldCreateSession = sessionId === undefined || options.allowedTools !== undefined;
418
+ const appliedPermissionRuleset = shouldCreateSession;
419
+ if (sessionId === undefined) {
420
+ const sessionResult = await opencodeApiClient.session.create({
310
421
  directory: options.cwd,
311
- permission: buildOpenCodePermissionRuleset(options.permissionMode, options.networkAccess),
422
+ permission: permissionRuleset,
312
423
  });
313
- sessionId = sessionResult.data?.id;
314
- if (!sessionId) {
315
- release();
316
- throw new Error('Failed to create OpenCode session');
424
+ sessionId = sessionResult.data?.id;
425
+ if (!sessionId) {
426
+ throw new Error('Failed to create OpenCode session');
427
+ }
428
+ }
429
+ else if (options.allowedTools !== undefined) {
430
+ const sessionResult = await opencodeApiClient.session.create({
431
+ directory: options.cwd,
432
+ parentID: sessionId,
433
+ permission: permissionRuleset,
434
+ });
435
+ sessionId = sessionResult.data?.id;
436
+ if (!sessionId) {
437
+ throw new Error('Failed to create OpenCode session');
438
+ }
439
+ }
440
+ const activeSessionId = sessionId;
441
+ if (activeSessionId === undefined) {
442
+ throw new Error('OpenCode session ID is required');
317
443
  }
318
444
  const { stream } = await opencodeApiClient.event.subscribe({ directory: options.cwd }, { signal: streamAbortController.signal });
319
445
  resetIdleTimeout();
320
446
  diag.onConnected();
321
- const tools = mapToOpenCodeTools(options.allowedTools);
447
+ if (appliedPermissionRuleset) {
448
+ emitPermissionSummary(options.onStream, {
449
+ sessionId: activeSessionId,
450
+ ...(options.permissionMode !== undefined ? { permissionMode: options.permissionMode } : {}),
451
+ ...(options.allowedTools !== undefined ? { allowedTools: options.allowedTools } : {}),
452
+ ...(options.networkAccess !== undefined ? { networkAccess: options.networkAccess } : {}),
453
+ resolvedPermissions: permissionRuleset,
454
+ });
455
+ }
322
456
  const promptPayload = {
323
- sessionID: sessionId,
457
+ sessionID: activeSessionId,
324
458
  directory: options.cwd,
325
459
  model: parsedModel,
326
460
  ...(options.variant !== undefined ? { variant: options.variant } : {}),
327
- ...(tools ? { tools } : {}),
328
- parts: [{ type: 'text', text: fullPrompt }],
461
+ ...(options.systemPrompt !== undefined ? { system: options.systemPrompt } : {}),
462
+ parts: [{ type: 'text', text: prompt }],
329
463
  };
330
- if (options.outputSchema) {
331
- promptPayload.outputFormat = {
332
- type: 'json_schema',
333
- schema: options.outputSchema,
334
- };
335
- }
336
464
  const promptPayloadForSdk = promptPayload;
337
- await opencodeApiClient.session.promptAsync(promptPayloadForSdk, {
465
+ promptCompletion = opencodeApiClient.session.promptAsync(promptPayloadForSdk, {
338
466
  signal: streamAbortController.signal,
467
+ }).catch((error) => {
468
+ promptError = getErrorMessage(error);
469
+ if (!streamAbortController.signal.aborted) {
470
+ abortCause = 'prompt';
471
+ streamAbortController.abort();
472
+ }
339
473
  });
340
- emitInit(options.onStream, options.model, sessionId);
474
+ emitInit(options.onStream, options.model, activeSessionId);
341
475
  let content = '';
342
476
  let success = true;
343
477
  let failureMessage = '';
344
478
  const state = createStreamTrackingState();
345
- const echoState = { remainingPrompt: fullPrompt };
479
+ const echoState = { remainingPrompts: buildPromptEchoCandidates(prompt, options.systemPrompt) };
346
480
  const textOffsets = new Map();
347
481
  const textContentParts = new Map();
348
482
  // Consume a raw text delta for a part: strip the prompt echo, stream the
@@ -393,16 +527,27 @@ export class OpenCodeClient {
393
527
  }
394
528
  if (sseEvent.type === 'permission.asked') {
395
529
  const permProps = sseEvent.properties;
396
- if (permProps.sessionID === sessionId) {
530
+ if (permProps.sessionID === activeSessionId) {
397
531
  try {
398
- const reply = options.permissionMode
399
- ? mapToOpenCodePermissionReply(options.permissionMode)
400
- : 'once';
532
+ const reply = resolveOpenCodePermissionReply(options.permissionMode, permProps.permission, options.allowedTools !== undefined ? permissionRuleset : undefined);
533
+ emitPermissionAsked(options.onStream, {
534
+ requestId: permProps.id,
535
+ sessionId: permProps.sessionID,
536
+ permission: permProps.permission ?? '',
537
+ patterns: Array.isArray(permProps.patterns) ? permProps.patterns : [],
538
+ always: Array.isArray(permProps.always) ? permProps.always : [],
539
+ reply,
540
+ });
401
541
  await withTimeout((signal) => opencodeApiClient.permission.reply({
402
542
  requestID: permProps.id,
403
543
  directory: options.cwd,
404
544
  reply,
405
545
  }, { signal }), interactionTimeoutMs, 'OpenCode permission reply timed out');
546
+ if (reply === 'reject') {
547
+ success = false;
548
+ failureMessage = buildPermissionRejectedMessage(permProps.permission);
549
+ break;
550
+ }
406
551
  }
407
552
  catch (e) {
408
553
  success = false;
@@ -414,7 +559,7 @@ export class OpenCodeClient {
414
559
  }
415
560
  if (sseEvent.type === 'question.asked') {
416
561
  const questionProps = sseEvent.properties;
417
- if (questionProps.sessionID === sessionId) {
562
+ if (questionProps.sessionID === activeSessionId) {
418
563
  const rejectQuestion = () => withTimeout((signal) => opencodeApiClient.question.reject({
419
564
  requestID: questionProps.id,
420
565
  directory: options.cwd,
@@ -461,7 +606,7 @@ export class OpenCodeClient {
461
606
  if (sseEvent.type === 'message.updated') {
462
607
  const messageProps = sseEvent.properties;
463
608
  const info = messageProps.info;
464
- const isCurrentAssistantMessage = info?.sessionID === sessionId && info.role === 'assistant';
609
+ const isCurrentAssistantMessage = info?.sessionID === activeSessionId && info?.role === 'assistant';
465
610
  if (isCurrentAssistantMessage) {
466
611
  const streamError = extractOpenCodeErrorMessage(info?.error);
467
612
  if (streamError) {
@@ -476,7 +621,7 @@ export class OpenCodeClient {
476
621
  if (sseEvent.type === 'message.completed') {
477
622
  const completedProps = sseEvent.properties;
478
623
  const info = completedProps.info;
479
- const isCurrentAssistantMessage = info?.sessionID === sessionId && info.role === 'assistant';
624
+ const isCurrentAssistantMessage = info?.sessionID === activeSessionId && info?.role === 'assistant';
480
625
  if (isCurrentAssistantMessage) {
481
626
  const streamError = extractOpenCodeErrorMessage(info?.error);
482
627
  if (streamError) {
@@ -491,7 +636,7 @@ export class OpenCodeClient {
491
636
  if (sseEvent.type === 'message.failed') {
492
637
  const failedProps = sseEvent.properties;
493
638
  const info = failedProps.info;
494
- const isCurrentAssistantMessage = info?.sessionID === sessionId && info.role === 'assistant';
639
+ const isCurrentAssistantMessage = info?.sessionID === activeSessionId && info?.role === 'assistant';
495
640
  if (isCurrentAssistantMessage) {
496
641
  success = false;
497
642
  failureMessage = extractOpenCodeErrorMessage(info?.error) ?? 'OpenCode message failed';
@@ -502,23 +647,23 @@ export class OpenCodeClient {
502
647
  }
503
648
  if (sseEvent.type === 'session.status') {
504
649
  const statusProps = sseEvent.properties;
505
- if (statusProps.sessionID === sessionId && statusProps.status?.type === 'idle') {
650
+ if (statusProps.sessionID === activeSessionId && statusProps.status?.type === 'idle') {
506
651
  break;
507
652
  }
508
653
  continue;
509
654
  }
510
655
  if (sseEvent.type === 'session.idle') {
511
656
  const idleProps = sseEvent.properties;
512
- if (idleProps.sessionID === sessionId) {
657
+ if (idleProps.sessionID === activeSessionId) {
513
658
  break;
514
659
  }
515
660
  continue;
516
661
  }
517
662
  if (sseEvent.type === 'session.error') {
518
663
  const errorProps = sseEvent.properties;
519
- if (!errorProps.sessionID || errorProps.sessionID === sessionId) {
664
+ if (!errorProps.sessionID || errorProps.sessionID === activeSessionId) {
520
665
  success = false;
521
- failureMessage = errorProps.error?.data?.message ?? 'OpenCode session error';
666
+ failureMessage = extractOpenCodeErrorMessage(errorProps.error) ?? 'OpenCode session error';
522
667
  diag.onStreamError('session.error', failureMessage);
523
668
  break;
524
669
  }
@@ -526,12 +671,25 @@ export class OpenCodeClient {
526
671
  }
527
672
  }
528
673
  content = [...textContentParts.values()].join('\n');
674
+ if (!success && !streamAbortController.signal.aborted) {
675
+ streamAbortController.abort();
676
+ }
677
+ await awaitPromptCompletion();
678
+ if (promptError !== undefined) {
679
+ if (success) {
680
+ success = false;
681
+ failureMessage = promptError;
682
+ }
683
+ else if (!failureMessage) {
684
+ failureMessage = promptError;
685
+ }
686
+ }
529
687
  diag.onCompleted(success ? 'normal' : 'error', success ? undefined : failureMessage);
530
688
  if (!success) {
531
689
  const message = failureMessage || 'OpenCode execution failed';
532
690
  if (containsRateLimitError(message)) {
533
- const rateLimitedResponse = this.buildRateLimitedResponse(agentType, sessionId, message);
534
- emitResult(options.onStream, false, rateLimitedResponse.error ?? rateLimitedResponse.content, sessionId);
691
+ const rateLimitedResponse = this.buildRateLimitedResponse(agentType, activeSessionId, message);
692
+ emitResult(options.onStream, false, rateLimitedResponse.error ?? rateLimitedResponse.content, activeSessionId);
535
693
  return rateLimitedResponse;
536
694
  }
537
695
  const retriable = this.isRetriableError(message, streamAbortController.signal.aborted, abortCause);
@@ -540,25 +698,23 @@ export class OpenCodeClient {
540
698
  await this.waitForRetryDelay(attempt, options.abortSignal);
541
699
  continue;
542
700
  }
543
- emitResult(options.onStream, false, message, sessionId);
701
+ emitResult(options.onStream, false, message, activeSessionId);
544
702
  return {
545
703
  persona: agentType,
546
704
  status: 'error',
547
705
  content: message,
548
706
  timestamp: new Date(),
549
- sessionId,
707
+ sessionId: activeSessionId,
550
708
  };
551
709
  }
552
710
  const trimmed = content.trim();
553
- const structuredOutput = parseStructuredOutput(trimmed, !!options.outputSchema);
554
- emitResult(options.onStream, true, trimmed, sessionId);
711
+ emitResult(options.onStream, true, trimmed, activeSessionId);
555
712
  return {
556
713
  persona: agentType,
557
714
  status: 'done',
558
715
  content: trimmed,
559
716
  timestamp: new Date(),
560
- sessionId,
561
- structuredOutput,
717
+ sessionId: activeSessionId,
562
718
  };
563
719
  }
564
720
  catch (error) {
@@ -566,7 +722,9 @@ export class OpenCodeClient {
566
722
  const errorMessage = streamAbortController.signal.aborted
567
723
  ? abortCause === 'timeout'
568
724
  ? timeoutMessage
569
- : OPENCODE_STREAM_ABORTED_MESSAGE
725
+ : abortCause === 'prompt' && promptError !== undefined
726
+ ? promptError
727
+ : OPENCODE_STREAM_ABORTED_MESSAGE
570
728
  : message;
571
729
  if (containsRateLimitError(errorMessage)) {
572
730
  const rateLimitedResponse = this.buildRateLimitedResponse(agentType, sessionId, errorMessage);
@@ -575,7 +733,7 @@ export class OpenCodeClient {
575
733
  }
576
734
  return rateLimitedResponse;
577
735
  }
578
- diagRef?.onCompleted(abortCause === 'timeout' ? 'timeout' : streamAbortController.signal.aborted ? 'abort' : 'error', errorMessage);
736
+ diagRef?.onCompleted(abortCause === 'timeout' ? 'timeout' : streamAbortController.signal.aborted && abortCause !== 'prompt' ? 'abort' : 'error', errorMessage);
579
737
  const retriable = this.isRetriableError(errorMessage, streamAbortController.signal.aborted, abortCause);
580
738
  if (retriable && attempt < OPENCODE_RETRY_MAX_ATTEMPTS) {
581
739
  log.info('Retrying OpenCode call after transient exception', { agentType, attempt, errorMessage });
@@ -600,10 +758,11 @@ export class OpenCodeClient {
600
758
  if (options.abortSignal) {
601
759
  options.abortSignal.removeEventListener('abort', onExternalAbort);
602
760
  }
603
- release?.();
604
761
  if (!streamAbortController.signal.aborted) {
605
762
  streamAbortController.abort();
606
763
  }
764
+ await awaitPromptCompletion();
765
+ release?.();
607
766
  }
608
767
  }
609
768
  throw new Error('Unreachable: OpenCode retry loop exhausted without returning');