@nhtio/adk 1.20260924.0 → 1.20260928.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 (317) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/artifact_methods-Cg0go7Q4.mjs +1 -0
  3. package/artifact_methods-CxeKTocm.cjs +1 -0
  4. package/batteries/artifacts/ecmascript.cjs +1 -1
  5. package/batteries/artifacts/ecmascript.mjs +1 -1
  6. package/batteries/artifacts/toon.cjs +1 -1
  7. package/batteries/artifacts/toon.mjs +1 -1
  8. package/batteries/artifacts/xml.cjs +1 -1
  9. package/batteries/artifacts/xml.mjs +1 -1
  10. package/batteries/artifacts/yaml.cjs +1 -1
  11. package/batteries/artifacts/yaml.mjs +1 -1
  12. package/batteries/artifacts.cjs +4 -4
  13. package/batteries/artifacts.mjs +4 -4
  14. package/batteries/dev-tools/forge.cjs +3 -3
  15. package/batteries/dev-tools/forge.mjs +3 -3
  16. package/batteries/dev-tools.cjs +3 -3
  17. package/batteries/dev-tools.mjs +3 -3
  18. package/batteries/encoding.cjs +7 -7
  19. package/batteries/encoding.mjs +7 -7
  20. package/batteries/generation/gemini/adapter.cjs +1 -1
  21. package/batteries/generation/gemini/adapter.mjs +1 -1
  22. package/batteries/generation/local_diffusion/adapter.cjs +1 -1
  23. package/batteries/generation/local_diffusion/adapter.mjs +1 -1
  24. package/batteries/generation/openai/adapter.cjs +1 -1
  25. package/batteries/generation/openai/adapter.mjs +1 -1
  26. package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
  27. package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
  28. package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
  29. package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
  30. package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
  31. package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
  32. package/batteries/llm/anthropic_messages/validation.cjs +2 -2
  33. package/batteries/llm/anthropic_messages/validation.mjs +2 -2
  34. package/batteries/llm/anthropic_messages.cjs +2 -2
  35. package/batteries/llm/anthropic_messages.mjs +2 -2
  36. package/batteries/llm/bedrock_converse/adapter.cjs +162 -21
  37. package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
  38. package/batteries/llm/bedrock_converse/adapter.mjs +162 -21
  39. package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
  40. package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
  41. package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
  42. package/batteries/llm/bedrock_converse/validation.cjs +2 -2
  43. package/batteries/llm/bedrock_converse/validation.mjs +2 -2
  44. package/batteries/llm/bedrock_converse.cjs +2 -2
  45. package/batteries/llm/bedrock_converse.mjs +2 -2
  46. package/batteries/llm/claude_code_cli/adapter.cjs +66 -25
  47. package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
  48. package/batteries/llm/claude_code_cli/adapter.mjs +66 -25
  49. package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
  50. package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
  51. package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
  52. package/batteries/llm/claude_code_cli/line_queue.d.ts +39 -0
  53. package/batteries/llm/claude_code_cli/message_id_state.d.ts +48 -0
  54. package/batteries/llm/claude_code_cli/types.d.ts +76 -0
  55. package/batteries/llm/claude_code_cli/validation.cjs +5 -2
  56. package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
  57. package/batteries/llm/claude_code_cli/validation.mjs +5 -2
  58. package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
  59. package/batteries/llm/claude_code_cli/wire.cjs.map +1 -1
  60. package/batteries/llm/claude_code_cli/wire.d.ts +45 -1
  61. package/batteries/llm/claude_code_cli/wire.mjs.map +1 -1
  62. package/batteries/llm/claude_code_cli/wrapper.d.ts +5 -4
  63. package/batteries/llm/claude_code_cli.cjs +2 -2
  64. package/batteries/llm/claude_code_cli.mjs +2 -2
  65. package/batteries/llm/gemini_generate_content/adapter.cjs +160 -19
  66. package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
  67. package/batteries/llm/gemini_generate_content/adapter.mjs +160 -19
  68. package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
  69. package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
  70. package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
  71. package/batteries/llm/gemini_generate_content/validation.cjs +2 -2
  72. package/batteries/llm/gemini_generate_content/validation.mjs +2 -2
  73. package/batteries/llm/gemini_generate_content.cjs +1 -1
  74. package/batteries/llm/gemini_generate_content.mjs +1 -1
  75. package/batteries/llm/litert_lm/adapter.cjs +6 -6
  76. package/batteries/llm/litert_lm/adapter.mjs +6 -6
  77. package/batteries/llm/litert_lm/helpers.cjs +3 -3
  78. package/batteries/llm/litert_lm/helpers.mjs +3 -3
  79. package/batteries/llm/litert_lm/validation.cjs +2 -2
  80. package/batteries/llm/litert_lm/validation.mjs +2 -2
  81. package/batteries/llm/litert_lm.cjs +1 -1
  82. package/batteries/llm/litert_lm.mjs +1 -1
  83. package/batteries/llm/ollama/adapter.cjs +6 -6
  84. package/batteries/llm/ollama/adapter.mjs +6 -6
  85. package/batteries/llm/ollama/helpers.cjs +4 -4
  86. package/batteries/llm/ollama/helpers.mjs +4 -4
  87. package/batteries/llm/ollama/validation.cjs +2 -2
  88. package/batteries/llm/ollama/validation.mjs +2 -2
  89. package/batteries/llm/ollama.cjs +2 -2
  90. package/batteries/llm/ollama.mjs +2 -2
  91. package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
  92. package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
  93. package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
  94. package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
  95. package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
  96. package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
  97. package/batteries/llm/openai_chat_completions.cjs +2 -2
  98. package/batteries/llm/openai_chat_completions.mjs +2 -2
  99. package/batteries/llm/openai_responses/adapter.cjs +6 -6
  100. package/batteries/llm/openai_responses/adapter.mjs +6 -6
  101. package/batteries/llm/openai_responses/helpers.cjs +3 -3
  102. package/batteries/llm/openai_responses/helpers.mjs +3 -3
  103. package/batteries/llm/openai_responses/validation.cjs +2 -2
  104. package/batteries/llm/openai_responses/validation.mjs +2 -2
  105. package/batteries/llm/openai_responses.cjs +2 -2
  106. package/batteries/llm/openai_responses.mjs +2 -2
  107. package/batteries/llm/transformers_js/adapter.cjs +6 -6
  108. package/batteries/llm/transformers_js/adapter.mjs +6 -6
  109. package/batteries/llm/transformers_js/helpers.cjs +3 -3
  110. package/batteries/llm/transformers_js/helpers.mjs +3 -3
  111. package/batteries/llm/transformers_js/validation.cjs +2 -2
  112. package/batteries/llm/transformers_js/validation.mjs +2 -2
  113. package/batteries/llm/transformers_js.cjs +1 -1
  114. package/batteries/llm/transformers_js.mjs +1 -1
  115. package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
  116. package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
  117. package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
  118. package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
  119. package/batteries/llm/webllm_chat_completions/validation.cjs +2 -2
  120. package/batteries/llm/webllm_chat_completions/validation.mjs +2 -2
  121. package/batteries/llm/webllm_chat_completions.cjs +2 -2
  122. package/batteries/llm/webllm_chat_completions.mjs +2 -2
  123. package/batteries/llm.cjs +2 -2
  124. package/batteries/llm.mjs +2 -2
  125. package/batteries/media/forge.cjs +4 -4
  126. package/batteries/media/forge.mjs +4 -4
  127. package/batteries/media/lint.cjs +1 -1
  128. package/batteries/media/lint.mjs +1 -1
  129. package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
  130. package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
  131. package/batteries/orchestration/executor.cjs +2 -2
  132. package/batteries/orchestration/executor.mjs +2 -2
  133. package/batteries/orchestration/forge.cjs +4 -4
  134. package/batteries/orchestration/forge.mjs +4 -4
  135. package/batteries/orchestration/validation.cjs +2 -2
  136. package/batteries/orchestration/validation.mjs +2 -2
  137. package/batteries/orchestration.cjs +4 -4
  138. package/batteries/orchestration.mjs +4 -4
  139. package/batteries/sandbox/js.cjs +1 -1
  140. package/batteries/sandbox/js.mjs +1 -1
  141. package/batteries/sandbox/tools.cjs +1 -1
  142. package/batteries/sandbox/tools.mjs +1 -1
  143. package/batteries/sandbox.cjs +3 -3
  144. package/batteries/sandbox.mjs +3 -3
  145. package/batteries/skills.cjs +9 -9
  146. package/batteries/skills.mjs +9 -9
  147. package/batteries/tools/_shared.cjs +1 -1
  148. package/batteries/tools/_shared.mjs +1 -1
  149. package/batteries/tools/color.cjs +2 -2
  150. package/batteries/tools/color.mjs +2 -2
  151. package/batteries/tools/comparison.cjs +2 -2
  152. package/batteries/tools/comparison.mjs +2 -2
  153. package/batteries/tools/data_structure.cjs +2 -2
  154. package/batteries/tools/data_structure.mjs +2 -2
  155. package/batteries/tools/datetime_extended.cjs +3 -3
  156. package/batteries/tools/datetime_extended.mjs +3 -3
  157. package/batteries/tools/datetime_math.cjs +3 -3
  158. package/batteries/tools/datetime_math.mjs +3 -3
  159. package/batteries/tools/encoding.cjs +2 -2
  160. package/batteries/tools/encoding.mjs +2 -2
  161. package/batteries/tools/formatting.cjs +2 -2
  162. package/batteries/tools/formatting.mjs +2 -2
  163. package/batteries/tools/geo_basics.cjs +2 -2
  164. package/batteries/tools/geo_basics.mjs +2 -2
  165. package/batteries/tools/math.cjs +2 -2
  166. package/batteries/tools/math.mjs +2 -2
  167. package/batteries/tools/memory.cjs +5 -5
  168. package/batteries/tools/memory.mjs +5 -5
  169. package/batteries/tools/parsing.cjs +3 -3
  170. package/batteries/tools/parsing.mjs +3 -3
  171. package/batteries/tools/retrievables.cjs +5 -5
  172. package/batteries/tools/retrievables.mjs +5 -5
  173. package/batteries/tools/scrapper.cjs +1 -1
  174. package/batteries/tools/scrapper.mjs +1 -1
  175. package/batteries/tools/searxng.cjs +1 -1
  176. package/batteries/tools/searxng.mjs +1 -1
  177. package/batteries/tools/standing_instructions.cjs +3 -3
  178. package/batteries/tools/standing_instructions.mjs +3 -3
  179. package/batteries/tools/statistics.cjs +3 -3
  180. package/batteries/tools/statistics.mjs +3 -3
  181. package/batteries/tools/string_processing.cjs +2 -2
  182. package/batteries/tools/string_processing.mjs +2 -2
  183. package/batteries/tools/structured_data.cjs +2 -2
  184. package/batteries/tools/structured_data.mjs +2 -2
  185. package/batteries/tools/text_analysis.cjs +3 -3
  186. package/batteries/tools/text_analysis.mjs +3 -3
  187. package/batteries/tools/text_comparison.cjs +2 -2
  188. package/batteries/tools/text_comparison.mjs +2 -2
  189. package/batteries/tools/time.cjs +3 -3
  190. package/batteries/tools/time.mjs +3 -3
  191. package/batteries/tools/unit_conversion.cjs +2 -2
  192. package/batteries/tools/unit_conversion.mjs +2 -2
  193. package/batteries/tools.cjs +2 -2
  194. package/batteries/tools.mjs +2 -2
  195. package/batteries/validation.cjs +4 -4
  196. package/batteries/validation.mjs +4 -4
  197. package/batteries/vector/conformance.cjs +59 -0
  198. package/batteries/vector/conformance.cjs.map +1 -1
  199. package/batteries/vector/conformance.mjs +59 -0
  200. package/batteries/vector/conformance.mjs.map +1 -1
  201. package/batteries/vector/lancedb.cjs +1 -1
  202. package/batteries/vector/lancedb.cjs.map +1 -1
  203. package/batteries/vector/lancedb.mjs +1 -1
  204. package/batteries/vector/lancedb.mjs.map +1 -1
  205. package/batteries/vector/retrievable.cjs +1 -1
  206. package/batteries/vector/retrievable.mjs +1 -1
  207. package/batteries/vector/sqlite_vec/index.d.ts +1 -1
  208. package/batteries/vector/sqlite_vec.cjs +19 -30
  209. package/batteries/vector/sqlite_vec.cjs.map +1 -1
  210. package/batteries/vector/sqlite_vec.mjs +20 -31
  211. package/batteries/vector/sqlite_vec.mjs.map +1 -1
  212. package/batteries.cjs +4 -4
  213. package/batteries.mjs +4 -4
  214. package/{chat_common-B7fvGTKv.cjs → chat_common-CNayzS1V.cjs} +2 -2
  215. package/{chat_common-B7fvGTKv.cjs.map → chat_common-CNayzS1V.cjs.map} +1 -1
  216. package/{chat_common-CeoHwSsz.mjs → chat_common-DKw8FDol.mjs} +2 -2
  217. package/{chat_common-CeoHwSsz.mjs.map → chat_common-DKw8FDol.mjs.map} +1 -1
  218. package/claude-code-cli-wrapper.cjs +104 -22
  219. package/claude-code-cli-wrapper.cjs.map +1 -1
  220. package/claude-code-cli-wrapper.mjs +104 -22
  221. package/claude-code-cli-wrapper.mjs.map +1 -1
  222. package/{common-7gCR3zQu.cjs → common-CqetsItm.cjs} +7 -7
  223. package/{common-7gCR3zQu.cjs.map → common-CqetsItm.cjs.map} +1 -1
  224. package/{common-B5maOoF_.mjs → common-oI1niK9Z.mjs} +7 -7
  225. package/{common-B5maOoF_.mjs.map → common-oI1niK9Z.mjs.map} +1 -1
  226. package/common.cjs +7 -7
  227. package/common.mjs +7 -7
  228. package/{dispatch_runner-DO7jo_gl.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
  229. package/{dispatch_runner-DO7jo_gl.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
  230. package/{dispatch_runner-FlriTyoq.cjs → dispatch_runner-DDUxXJC3.cjs} +5 -5
  231. package/{dispatch_runner-FlriTyoq.cjs.map → dispatch_runner-DDUxXJC3.cjs.map} +1 -1
  232. package/dispatch_runner.cjs +1 -1
  233. package/dispatch_runner.mjs +1 -1
  234. package/{ecmascript-bgwVyZG1.mjs → ecmascript-B9Z2C24U.mjs} +3 -3
  235. package/{ecmascript-bgwVyZG1.mjs.map → ecmascript-B9Z2C24U.mjs.map} +1 -1
  236. package/{ecmascript-BydSB03Y.cjs → ecmascript-BYfmjg7y.cjs} +3 -3
  237. package/{ecmascript-BydSB03Y.cjs.map → ecmascript-BYfmjg7y.cjs.map} +1 -1
  238. package/eslint/rules.cjs +1 -1
  239. package/eslint/rules.mjs +1 -1
  240. package/eslint.cjs +2 -2
  241. package/eslint.mjs +2 -2
  242. package/exceptions.cjs +1 -1
  243. package/exceptions.mjs +1 -1
  244. package/forge.cjs +2 -2
  245. package/forge.mjs +2 -2
  246. package/guards.cjs +7 -7
  247. package/guards.mjs +7 -7
  248. package/{helpers-Dcp4CrOz.cjs → helpers-DPlh_7Bn.cjs} +3 -3
  249. package/{helpers-Dcp4CrOz.cjs.map → helpers-DPlh_7Bn.cjs.map} +1 -1
  250. package/{helpers-C1T0DV8Q.mjs → helpers-mbn_EsDV.mjs} +3 -3
  251. package/{helpers-C1T0DV8Q.mjs.map → helpers-mbn_EsDV.mjs.map} +1 -1
  252. package/index.cjs +11 -11
  253. package/index.mjs +11 -11
  254. package/mcp/adk-docs-corpus.json +2 -2
  255. package/package.json +425 -425
  256. package/{retrievable-BBwiACtw.cjs → retrievable-Bq-O3k6r.cjs} +3 -3
  257. package/{retrievable-BBwiACtw.cjs.map → retrievable-Bq-O3k6r.cjs.map} +1 -1
  258. package/{retrievable-CrGKx4sc.mjs → retrievable-CXTAUuuv.mjs} +3 -3
  259. package/{retrievable-CrGKx4sc.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
  260. package/{scrapper-BibKj8qE.cjs → scrapper-B8xG9lTD.cjs} +4 -4
  261. package/{scrapper-BibKj8qE.cjs.map → scrapper-B8xG9lTD.cjs.map} +1 -1
  262. package/{scrapper-_JzgbLG5.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
  263. package/{scrapper-_JzgbLG5.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
  264. package/{searxng-D-nA2gEI.mjs → searxng-BFTJ6rTE.mjs} +4 -4
  265. package/{searxng-D-nA2gEI.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
  266. package/{searxng-C6xrLW-v.cjs → searxng-EJhWRnIE.cjs} +4 -4
  267. package/{searxng-C6xrLW-v.cjs.map → searxng-EJhWRnIE.cjs.map} +1 -1
  268. package/server.json +2 -2
  269. package/skills/adk-assembly/SKILL.md +2 -2
  270. package/{spooled_artifact-BLgbGT8b.cjs → spooled_artifact---DmicFW.cjs} +384 -384
  271. package/spooled_artifact---DmicFW.cjs.map +1 -0
  272. package/{spooled_artifact-BkOe4-j-.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
  273. package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
  274. package/spooled_artifact.cjs +2 -2
  275. package/spooled_artifact.mjs +2 -2
  276. package/{spooled_markdown_artifact-8zdejfcJ.cjs → spooled_markdown_artifact-Rjzj-kyh.cjs} +3 -3
  277. package/{spooled_markdown_artifact-8zdejfcJ.cjs.map → spooled_markdown_artifact-Rjzj-kyh.cjs.map} +1 -1
  278. package/{spooled_markdown_artifact-Dnl-lCGv.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
  279. package/{spooled_markdown_artifact-Dnl-lCGv.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
  280. package/{thought-BrQt6HAb.mjs → thought-CxSaF6Xf.mjs} +3 -3
  281. package/{thought-BrQt6HAb.mjs.map → thought-CxSaF6Xf.mjs.map} +1 -1
  282. package/{thought-COeZTQ-B.cjs → thought-Dp3sMWW6.cjs} +3 -3
  283. package/{thought-COeZTQ-B.cjs.map → thought-Dp3sMWW6.cjs.map} +1 -1
  284. package/{tokenizable-DDIdXbJN.cjs → tokenizable-BcodRtoW.cjs} +29 -29
  285. package/{tokenizable-DDIdXbJN.cjs.map → tokenizable-BcodRtoW.cjs.map} +1 -1
  286. package/{tokenizable-xPXj1AQX.mjs → tokenizable-VB4Av8GF.mjs} +30 -30
  287. package/{tokenizable-xPXj1AQX.mjs.map → tokenizable-VB4Av8GF.mjs.map} +1 -1
  288. package/{tool_call-JbjeUpRK.cjs → tool_call-B9px4W9k.cjs} +4 -4
  289. package/{tool_call-JbjeUpRK.cjs.map → tool_call-B9px4W9k.cjs.map} +1 -1
  290. package/{tool_call-8crmZsO8.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
  291. package/{tool_call-8crmZsO8.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
  292. package/{tools-BC4NJqZD.mjs → tools-D0MBDh2R.mjs} +6 -6
  293. package/{tools-BC4NJqZD.mjs.map → tools-D0MBDh2R.mjs.map} +1 -1
  294. package/{tools-D4mdzi0a.cjs → tools-aNbi6JyA.cjs} +6 -6
  295. package/{tools-D4mdzi0a.cjs.map → tools-aNbi6JyA.cjs.map} +1 -1
  296. package/{toon-BA9Q7NHG.mjs → toon-BSTQnHed.mjs} +5 -5
  297. package/{toon-BA9Q7NHG.mjs.map → toon-BSTQnHed.mjs.map} +1 -1
  298. package/{toon-b-0pFKZ8.cjs → toon-DmLwZ6H1.cjs} +5 -5
  299. package/{toon-b-0pFKZ8.cjs.map → toon-DmLwZ6H1.cjs.map} +1 -1
  300. package/{turn_runner-BmVXcBZ2.mjs → turn_runner-BHHD6h77.mjs} +5 -5
  301. package/{turn_runner-BmVXcBZ2.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
  302. package/{turn_runner-DX-3s3ih.cjs → turn_runner-Dj7JsUTQ.cjs} +5 -5
  303. package/{turn_runner-DX-3s3ih.cjs.map → turn_runner-Dj7JsUTQ.cjs.map} +1 -1
  304. package/turn_runner.cjs +1 -1
  305. package/turn_runner.mjs +1 -1
  306. package/{xml-B1JIGLpU.mjs → xml-CYseDztH.mjs} +5 -5
  307. package/{xml-B1JIGLpU.mjs.map → xml-CYseDztH.mjs.map} +1 -1
  308. package/{xml-fvwTsoRv.cjs → xml-zJul8jMQ.cjs} +5 -5
  309. package/{xml-fvwTsoRv.cjs.map → xml-zJul8jMQ.cjs.map} +1 -1
  310. package/{yaml-1mP4uxdf.mjs → yaml-BPBoiOjx.mjs} +5 -5
  311. package/{yaml-1mP4uxdf.mjs.map → yaml-BPBoiOjx.mjs.map} +1 -1
  312. package/{yaml-DPUTumla.cjs → yaml-D0PzoRAr.cjs} +5 -5
  313. package/{yaml-DPUTumla.cjs.map → yaml-D0PzoRAr.cjs.map} +1 -1
  314. package/artifact_methods-7KatxCSd.cjs +0 -1
  315. package/artifact_methods-q52ETLwI.mjs +0 -1
  316. package/spooled_artifact-BLgbGT8b.cjs.map +0 -1
  317. package/spooled_artifact-BkOe4-j-.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.cjs","names":["#baseline"],"sources":["../../../../src/batteries/llm/claude_code_cli/adapter.ts"],"sourcesContent":["/**\n * Cross-environment executor adapter that wraps the Claude Code CLI as a `DispatchExecutorFn`\n * destination.\n *\n * @module @nhtio/adk/batteries/llm/claude_code_cli/adapter\n *\n * @remarks\n * The first battery in the \"CLI harness\" family: rather than a direct wire-format provider, this\n * adapter drives an external coding-agent CLI binary that is itself a complete agent loop. Since a\n * subprocess must be spawned anyway, ALL Claude-Code-specific complexity — spawning the real\n * `claude` binary, hosting an MCP bridge server, translating its stream-json — lives in a\n * dedicated wrapper process (`wrapper.ts`, shipped as a sibling dist asset); this adapter only\n * ever spawns and drives that wrapper over the small, harness-agnostic protocol in `./wire`.\n *\n * Every dispatch iteration is stateless and self-contained: the full accumulated history renders\n * into one `-p` prompt string (`buildClaudeCodeCliPrompt`), a fresh wrapper is spawned, and real\n * ADK tools are bridged into the CLI's own tool loop via MCP — but actual execution always happens\n * on the ADK side, through `tool.executor(ctx)(args)`, exactly like every other LLM battery.\n */\n\nimport { sha256 } from 'js-sha256'\nimport { validateOptions } from './validation'\nimport { deCollideToolCallIds } from '../chat_common'\nimport { isError, isObject, isInstanceOf } from '@nhtio/adk/guards'\nimport { createNdjsonLineReader, encodeWrapperCommand } from './wire'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport {\n Tokenizable,\n ToolCall,\n Memory,\n Message,\n Media,\n ArtifactTool,\n SpooledArtifact,\n} from '@nhtio/adk/common'\nimport {\n E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR,\n E_CLAUDE_CODE_CLI_WRAPPER_CRASHED,\n E_CLAUDE_CODE_CLI_PROCESS_EXITED_NONZERO,\n E_CLAUDE_CODE_CLI_STREAM_ERROR,\n E_CLAUDE_CODE_CLI_STREAM_STALLED,\n E_CLAUDE_CODE_CLI_STARTUP_TIMEOUT,\n E_CLAUDE_CODE_CLI_MCP_BRIDGE_STARTUP_FAILED,\n E_CLAUDE_CODE_CLI_TURN_FAILED,\n E_INVALID_CLAUDE_CODE_CLI_OPTIONS,\n E_CLAUDE_CODE_CLI_CONTEXT_OVERFLOW,\n E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND,\n} from './exceptions'\nimport {\n defaultDescriptionToChatCompletionsJsonSchema,\n defaultRenderUntrustedContent,\n defaultRenderTrustedContent,\n defaultRenderStandingInstructions,\n defaultRenderMemories,\n defaultRenderRetrievables,\n defaultRenderRetrievableHandleBody,\n defaultRenderRetrievableSafetyDirective,\n defaultRenderFirstPartyRetrievables,\n defaultRenderThirdPartyPublicRetrievables,\n defaultRenderThirdPartyPrivateRetrievables,\n defaultRenderThought,\n defaultFilterThoughts,\n defaultToolsToChatCompletionsTools,\n defaultRenderChatCompletionsSystemPrompt,\n defaultRenderClaudeCodeCliTimelineMessage,\n defaultRenderClaudeCodeCliToolCallResult,\n defaultBuildClaudeCodeCliPrompt,\n renderArtifactHandleBody,\n looksLikeSpooledArtifact,\n} from './helpers'\nimport type { Tool } from '@nhtio/adk/common'\nimport type { SpoolStore } from '@nhtio/adk/common'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { TokenEncoding, TokenEncodingId } from '@nhtio/adk/types'\nimport type { WrapperEvent, WrapperCommand, WrapperBridgedTool } from './wire'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/dispatch_runner'\nimport type {\n ClaudeCodeCliAdapterOptions,\n ClaudeCodeCliHelpers,\n ExecaLike,\n ExecaResolver,\n UnsupportedMediaPolicy,\n} from './types'\n\ntype OutboundContentBlock =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n\n// ─── wrapper path resolution (Decision C) ──────────────────────────────────────\n\n/**\n * Resolve the built wrapper asset's on-disk path relative to this module's own compiled location.\n * `adapter.ts` carries its own `@module` tag (per the per-file tagging convention every other\n * multi-file battery uses), so it compiles to `dist/batteries/llm/claude_code_cli/adapter.mjs` —\n * three directories below the package root, where the wrapper (an explicit, un-tagged\n * `vite.config.mts` entry key) compiles to `dist/claude-code-cli-wrapper.mjs`.\n */\nexport const resolveDefaultWrapperPath = (): string => {\n // `typeof require === 'function'` alone is not a safe CJS-vs-ESM discriminator: rolldown's ESM\n // output wraps `require` in a shim/Proxy (falling back to itself when the real `require` is\n // absent) that still reports `typeof === 'function'`, but whose `.resolve` is not itself a\n // function — calling it throws instead of falling through to the URL-based ESM branch below.\n if (typeof require === 'function' && typeof require.resolve === 'function') {\n return require.resolve('../../../claude-code-cli-wrapper.cjs')\n }\n // `URL.pathname` is percent-encoded — a real install path containing a space, unicode, or any\n // other URL-reserved character would produce a non-existent argv path (e.g. `%20` instead of a\n // literal space) once handed to `execaFn`/`spawn` below. `decodeURIComponent` undoes that percent\n // encoding to recover the native filesystem path — equivalent to `node:url`'s `fileURLToPath` for\n // a POSIX path (verified directly), which this module avoids importing at module scope: this\n // file is transitively pulled into the browser test project via `src/batteries`'s barrel (e.g.\n // `tests/unit/batteries/index.cross.spec.ts`), and Vite externalizes `node:url` there, throwing\n // on any access to `fileURLToPath` at import time. This battery is POSIX-only in v1 anyway\n // (validated at options-construction time), so a POSIX-only decode is exactly the right amount\n // of `node:url` behavior to reimplement without importing it.\n return decodeURIComponent(\n new URL('../../../claude-code-cli-wrapper.mjs', import.meta.url).pathname\n )\n}\n\n/**\n * Existence-check a candidate wrapper path, lazily acquiring `node:fs`'s `existsSync` — never\n * imported at module scope for the same reason `resolveDefaultWrapperPath` avoids `node:url`\n * above: this file is transitively pulled into the browser test project via `src/batteries`'s\n * barrel, and a module-scope Node-builtin import would throw at import time there. Any failure to\n * even acquire `node:fs` (e.g. a hostile/exotic runtime) is treated as \"does not exist\" rather\n * than propagating, since this is only ever used to pick between fallback candidates.\n */\nconst existsOnDisk = async (path: string): Promise<boolean> => {\n try {\n const fs = (await import('node:fs')) as { existsSync?: (p: string) => boolean }\n return typeof fs.existsSync === 'function' && fs.existsSync(path)\n } catch {\n return false\n }\n}\n\n/**\n * Result of a self-reference resolution attempt: the resolved, existence-checked sibling path when\n * found, plus a full log of every candidate/reason tried — reported to the caller so\n * {@link E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND} can name everything actually checked, not just the\n * relative resolver's own error.\n */\ninterface SelfReferenceResolution {\n path?: string\n tried: string[]\n}\n\n/**\n * Injectable seams for {@link resolveWrapperPathViaSelfReference}'s two internal self-reference\n * routes — internal, non-breaking test hooks (mirrors {@link WrapperPathResolutionSeams} below,\n * one layer deeper). A real ambient `require` is module-scoped per compiled file, so a test file\n * patching its OWN `require.resolve` has no effect on `adapter.ts`'s ambient `require` (verified\n * directly — each ES module/CJS wrapper gets its own `require` binding, even within the same\n * vitest worker/module graph), and this repo's own `@nhtio/adk` package genuinely self-resolves\n * successfully inside the test environment (this worktree's own `package.json` is itself named\n * `@nhtio/adk`), so route 1 can't be made to fail deterministically without a seam either. These\n * two knobs let a unit test drive both \"ambient require resolution failed\" and \"import.meta.url\n * unavailable\" without needing a real bundled/stripped module environment. Both default to the\n * real ambient behavior when omitted.\n */\ninterface SelfReferenceResolutionSeams {\n ambientRequireResolve?: (specifier: string) => string\n importMetaUrl?: string | undefined\n}\n\n/**\n * Resolve the wrapper asset's sibling path relative to THIS PACKAGE's own already-published main\n * entry, rather than relative to the (possibly relocated-by-bundling) adapter module. Node's\n * package self-reference feature — a package resolving its own name as a bare specifier — is\n * depth-independent within `@nhtio/adk`'s own tree, so this survives the adapter code being moved\n * around WITHIN the package by a bundler. It only breaks once the calling code has been physically\n * bundled OUTSIDE `@nhtio/adk`'s own directory tree (e.g. into a consumer's Electron main-process\n * bundle) — at that point self-reference falls back to ordinary node_modules bare-specifier\n * resolution, which succeeds exactly when `@nhtio/adk` is still installed as a resolvable\n * dependency from the bundled code's new location. That is the same \"normal case\" the published\n * `wrapperPath` override already exists for, so this fallback is a strict improvement with no new\n * failure mode: when it can't resolve, behavior degrades to the pre-existing \"throw a clear error\"\n * path below rather than a worse outcome.\n *\n * Deliberately resolves this package's `exports['.']` main entry (already published, no `exports`\n * map change needed) and derives the wrapper's path as a sibling of that entry's directory — every\n * `vite.config.mts` `build.lib.entry` key (including the un-tagged wrapper) emits to a flat\n * `dist/` directory, so `dirname(mainEntry) === dirname(wrapperAsset)`.\n *\n * Two independent ways to reach a `require`-like resolver are tried, in this order, because a\n * bundled consumer may land in either shape and each leaves the OTHER unusable:\n *\n * 1. A real ambient `require` — present when THIS MODULE has itself been bundled into a CJS\n * output (e.g. `esbuild --platform=node --format=cjs`, which is common for an Electron\n * main-process bundle, the issue's reported scenario). Reused verbatim is the exact same\n * discriminator `resolveDefaultWrapperPath` above already documents:\n * `typeof require === 'function' && typeof require.resolve === 'function'` — because a bundled\n * ESM output can ALSO leave a truthy `require` behind as a dynamic-require shim/Proxy (rolldown\n * and esbuild both do this) whose `.resolve` is not itself a function, and calling it would\n * throw rather than genuinely resolving anything. In a genuine CJS bundle this ambient\n * `require.resolve('@nhtio/adk')` works directly with no `createRequire` bridge needed.\n * 2. `createRequire(import.meta.url)` — the ESM path, used only when step 1 didn't yield a usable\n * resolver. Verified empirically that esbuild's `--format=cjs` output rewrites every\n * `import.meta` reference in bundled source to a plain `var import_meta = {}`, so\n * `import.meta.url` is `undefined` there — `createRequire(undefined)` throws\n * `ERR_INVALID_ARG_VALUE` outright, so this branch is skipped by checking\n * `typeof import.meta.url === 'string'` first rather than letting that throw surface as an\n * opaque, unrelated-looking error. `createRequire` (rather than `import.meta.resolve`) is used\n * here because — unlike `import.meta.resolve` — its `.resolve` performs a real filesystem\n * existence check (verified directly: `import.meta.resolve` happily returns a URL for a target\n * file that does not exist, since it only resolves the `exports` map syntactically;\n * `require.resolve`, including through `createRequire`, throws `MODULE_NOT_FOUND` for a missing\n * target), so a resolved path here is already known to exist and only the derived wrapper\n * sibling still needs its own explicit check below.\n *\n * `tried` always accounts for BOTH routes once step 1 has not already produced a `mainEntry`: step\n * 2 either resolves, records its own failure, or — when `import.meta.url` isn't even a string —\n * records an explicit \"skipped: import.meta.url unavailable\" entry, so the thrown error's \"Tried:\"\n * list never silently omits a route just because it was never attempted.\n *\n * A `process.cwd()`-anchored resolution attempt is deliberately NOT included as a further\n * fallback: resolution should stay anchored to the bundle's own module identity, not to a mutable,\n * launch-directory-dependent value that has no necessary relationship to where the bundle — or\n * `@nhtio/adk` — actually live. Failing clearly and pointing at `wrapperPath` is a better outcome\n * than a resolution that silently varies with the process's current working directory.\n */\nconst resolveWrapperPathViaSelfReference = async (\n wrapperBasename: string,\n seams: SelfReferenceResolutionSeams = {}\n): Promise<SelfReferenceResolution> => {\n const tried: string[] = []\n let mainEntry: string | undefined\n\n const hasAmbientRequire =\n seams.ambientRequireResolve !== undefined ||\n (typeof require === 'function' && typeof require.resolve === 'function')\n if (hasAmbientRequire) {\n try {\n mainEntry = (seams.ambientRequireResolve ?? require.resolve)('@nhtio/adk')\n } catch (err) {\n tried.push(\n `self-reference via ambient require('@nhtio/adk') failed: ${isError(err) ? err.message : String(err)}`\n )\n }\n }\n\n // Every branch below either resolves `mainEntry` or pushes a `tried` entry explaining why not —\n // so by the time we reach the `mainEntry === undefined` check further down, `tried` can no longer\n // be empty (a prior review round's \"no usable ambient require and no import.meta.url\" catch-all\n // for a silently-empty `tried` is gone because it is now unreachable: the branch below records\n // its OWN skip reason instead of leaving nothing behind).\n if (mainEntry === undefined) {\n const importMetaUrl = 'importMetaUrl' in seams ? seams.importMetaUrl : import.meta.url\n if (typeof importMetaUrl === 'string') {\n try {\n const { createRequire } = await import('node:module')\n mainEntry = createRequire(importMetaUrl).resolve('@nhtio/adk')\n } catch (err) {\n tried.push(\n `self-reference via createRequire(import.meta.url).resolve('@nhtio/adk') failed: ${isError(err) ? err.message : String(err)}`\n )\n }\n } else {\n // Regression for the AI-review finding: this route being unavailable used to leave no trace\n // at all whenever the ambient-`require` route above HAD recorded something (e.g. it existed\n // but failed) — the \"Tried:\" list would then name the ambient failure but silently omit that\n // the createRequire route was never even attempted. Recording the skip explicitly means every\n // self-reference route is always accounted for in the thrown error.\n tried.push(\n 'self-reference via createRequire(import.meta.url) skipped: import.meta.url unavailable in this module context'\n )\n }\n }\n\n if (mainEntry === undefined) {\n return { tried }\n }\n\n const lastSlash = mainEntry.lastIndexOf('/')\n if (lastSlash < 0) {\n tried.push(\n `self-reference resolved '@nhtio/adk' to an unexpected path with no directory separator: ${mainEntry}`\n )\n return { tried }\n }\n const candidate = `${mainEntry.slice(0, lastSlash + 1)}${wrapperBasename}`\n tried.push(candidate)\n return (await existsOnDisk(candidate)) ? { path: candidate, tried } : { tried }\n}\n\n/**\n * Injectable seams for {@link resolveWrapperPathWithFallback}'s three collaborators — internal,\n * non-breaking test hooks (never new `ClaudeCodeCliAdapterOptions` fields): swapping these lets\n * unit tests exercise the bundled-fallback and unresolvable branches deterministically, without a\n * real `dist/` build or filesystem mocking. Each defaults to the real implementation above.\n */\ninterface WrapperPathResolutionSeams {\n resolveRelative?: () => string\n resolveSelfRef?: (wrapperBasename: string) => Promise<SelfReferenceResolution>\n checkExists?: (path: string) => Promise<boolean>\n}\n\n/**\n * Internal, non-public resolver used by the executor call site (never `resolveDefaultWrapperPath`\n * itself, which stays synchronous and unchanged for backwards compatibility with any caller that\n * already imports it directly). Tries the existing relative-to-module resolution FIRST — zero\n * behavior change for the common unbundled case — and only falls back to the self-reference\n * lookup when that candidate does not exist on disk (bundling relocated the adapter). Throws\n * {@link E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND} naming every path tried — the relative candidate (or\n * its resolution error) AND every self-reference candidate/reason from\n * {@link resolveWrapperPathViaSelfReference} — when neither resolves, rather than letting a bundled\n * consumer hit an opaque `MODULE_NOT_FOUND`/ENOENT deep inside `execa`, or a truncated error that\n * hides what the self-reference fallback actually attempted.\n *\n * @remarks\n * Electron/asar note: an app packaged into an `asar` archive can still `readFileSync`/`existsSync`\n * transparently-unpacked paths through Electron's patched `fs`, so this existence-check strategy\n * keeps working there without special-casing — but a wrapper asset that ships unpacked (outside\n * `asar`) is still the consumer's responsibility to arrange, same as any other spawned-executable\n * asset; `wrapperPath` remains the escape hatch when that layout doesn't line up.\n *\n * @remarks\n * Coverage note — deployment shapes: this resolver (both branches) only ever finds the wrapper\n * asset when `@nhtio/adk` itself (with `dist/claude-code-cli-wrapper.{cjs,mjs}` inside it) remains\n * an ordinarily-resolvable dependency from wherever the bundle ends up running — the bundle never\n * carries the wrapper asset itself. A bundle relocated outside its original project (so\n * `node_modules/@nhtio/adk` is no longer reachable), or an Electron app that prunes/asar-packs\n * `@nhtio/adk` out of its final package, is NOT covered by either branch and needs the explicit\n * `wrapperPath` option — which is exactly what the thrown error's message directs the caller to.\n */\nconst resolveWrapperPathWithFallback = async (\n seams: WrapperPathResolutionSeams = {}\n): Promise<string> => {\n const resolveRelative = seams.resolveRelative ?? resolveDefaultWrapperPath\n const resolveSelfRef = seams.resolveSelfRef ?? resolveWrapperPathViaSelfReference\n const checkExists = seams.checkExists ?? existsOnDisk\n\n const tried: string[] = []\n\n let relative: string | undefined\n try {\n relative = resolveRelative()\n } catch (err) {\n tried.push(isError(err) ? err.message : String(err))\n }\n if (relative !== undefined) {\n tried.push(relative)\n if (await checkExists(relative)) return relative\n }\n\n // Bundled-CJS wrinkle, made explicit here: in a real esbuild `--format=cjs` bundle,\n // `resolveDefaultWrapperPath`'s ambient-`require.resolve` branch throws `MODULE_NOT_FOUND` for\n // the RELATIVE `../../../claude-code-cli-wrapper.cjs` specifier (that relative path no longer\n // exists once bundling has relocated this module outside `@nhtio/adk`'s own tree), so `relative`\n // stays `undefined` and `isCjsWrapper` defaults `false` — `wrapperBasename` picks the `.mjs`\n // variant even though the CALLING bundle is CJS. This is harmless: the wrapper asset is never\n // imported/required in-process, only spawned as a completely separate `node` child process (see\n // `execaFn(process.execPath, [wrapperPath, ...])` at the call site below), and Node runs a\n // `.mjs`-suffixed file as ESM regardless of the PARENT process's own module format. Picking `.cjs`\n // here would be no more correct — either extension resolves to a real, runnable file once\n // self-reference finds `@nhtio/adk`'s own `dist/` directory.\n const isCjsWrapper = relative !== undefined && relative.endsWith('.cjs')\n const wrapperBasename = isCjsWrapper\n ? 'claude-code-cli-wrapper.cjs'\n : 'claude-code-cli-wrapper.mjs'\n const selfRef = await resolveSelfRef(wrapperBasename)\n tried.push(...selfRef.tried)\n if (selfRef.path !== undefined) return selfRef.path\n\n throw new E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND([tried.join(', ') || '(no candidates)'])\n}\n\n// Test-only aliases, following `transformers_js/adapter.ts`'s `__extractGeneratedText` precedent.\n// They are NOT re-exported from `index.ts` or any barrel, but because this file carries its own\n// `@module` tag they ARE reachable at runtime through the published\n// `@nhtio/adk/batteries/llm/claude_code_cli/adapter` subpath — and that reachability is load-bearing:\n// `tests/unit/build/claude_code_cli_wrapper_resolves_bundled.node.spec.ts` imports\n// `__resolveWrapperPathWithFallback` from that subpath to prove resolution inside a real bundle.\n// They carry no stability guarantee and are not part of the supported API; do not depend on them.\n// They are deliberately NOT marked `@internal`: `tsconfig.build.json` sets `stripInternal`, which\n// would drop them from the published `.d.ts` and break that bundled test's typed import.\n// `__resolveWrapperPathViaSelfReference` is exported one layer deeper than\n// `__resolveWrapperPathWithFallback` so a unit test can drive its `SelfReferenceResolutionSeams`\n// directly — see that interface's doc comment for why the outer seam (`resolveSelfRef`) can't\n// itself deterministically exercise route 1 vs. route 2.\nexport { resolveWrapperPathWithFallback as __resolveWrapperPathWithFallback }\nexport { resolveWrapperPathViaSelfReference as __resolveWrapperPathViaSelfReference }\n\n// ─── execa resolution (mirrors execa_executor.ts's lazy-resolver pattern) ──────\n\nconst resolveExeca = async (supplied: ExecaResolver | undefined): Promise<ExecaLike> => {\n let value: unknown =\n supplied ?? (() => import('execa') as unknown as Promise<{ execa: ExecaLike }>)\n if (typeof value === 'function' && !('exec' in (value as object))) {\n try {\n value = await (value as () => unknown)()\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR([\n `execa resolver failed: ${detail} — install the optional peer dependency \"execa\" or supply your own`,\n ])\n }\n }\n if (isObject(value) && 'execa' in value) {\n value = (value as { execa: unknown }).execa\n }\n if (typeof value !== 'function') {\n throw new E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR([\n 'execa resolver did not resolve to a function',\n ])\n }\n return value as ExecaLike\n}\n\n// ─── option merging ─────────────────────────────────────────────────────────\n\nconst mergeRecord = <T extends Record<string, unknown>>(\n layers: ReadonlyArray<T | undefined>\n): T | undefined => {\n let merged: T | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? ({} as T)), ...layer }\n }\n return merged\n}\n\nconst mergeOptions = (\n baseline: ClaudeCodeCliAdapterOptions,\n exec: Partial<ClaudeCodeCliAdapterOptions> | undefined,\n stash: Partial<ClaudeCodeCliAdapterOptions> | undefined\n): Partial<ClaudeCodeCliAdapterOptions> => {\n const layers = [baseline as Partial<ClaudeCodeCliAdapterOptions>, exec ?? {}, stash ?? {}]\n const out: Record<string, unknown> = {}\n for (const layer of layers) {\n for (const [k, v] of Object.entries(layer)) {\n if (v === undefined) continue\n if (k === 'helpers') continue\n out[k] = v\n }\n }\n const helpers = mergeRecord(layers.map((l) => l.helpers as Record<string, unknown> | undefined))\n if (helpers !== undefined) out.helpers = helpers\n return out as Partial<ClaudeCodeCliAdapterOptions>\n}\n\nconst resolveHelpers = (\n overrides: Partial<ClaudeCodeCliHelpers> | undefined\n): ClaudeCodeCliHelpers => {\n const src = overrides ?? {}\n return {\n descriptionToChatCompletionsJsonSchema:\n src.descriptionToChatCompletionsJsonSchema ?? defaultDescriptionToChatCompletionsJsonSchema,\n renderUntrustedContent: src.renderUntrustedContent ?? defaultRenderUntrustedContent,\n renderTrustedContent: src.renderTrustedContent ?? defaultRenderTrustedContent,\n renderStandingInstructions: src.renderStandingInstructions ?? defaultRenderStandingInstructions,\n renderMemories: src.renderMemories ?? defaultRenderMemories,\n renderRetrievables: src.renderRetrievables ?? defaultRenderRetrievables,\n renderRetrievableHandleBody:\n src.renderRetrievableHandleBody ?? defaultRenderRetrievableHandleBody,\n renderRetrievableSafetyDirective:\n src.renderRetrievableSafetyDirective ?? defaultRenderRetrievableSafetyDirective,\n renderFirstPartyRetrievables:\n src.renderFirstPartyRetrievables ?? defaultRenderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables:\n src.renderThirdPartyPublicRetrievables ?? defaultRenderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables:\n src.renderThirdPartyPrivateRetrievables ?? defaultRenderThirdPartyPrivateRetrievables,\n renderThought: src.renderThought ?? defaultRenderThought,\n filterThoughts: src.filterThoughts ?? defaultFilterThoughts,\n toolsToChatCompletionsTools:\n src.toolsToChatCompletionsTools ?? defaultToolsToChatCompletionsTools,\n renderChatCompletionsSystemPrompt:\n src.renderChatCompletionsSystemPrompt ?? defaultRenderChatCompletionsSystemPrompt,\n renderClaudeCodeCliTimelineMessage:\n src.renderClaudeCodeCliTimelineMessage ?? defaultRenderClaudeCodeCliTimelineMessage,\n renderClaudeCodeCliToolCallResult:\n src.renderClaudeCodeCliToolCallResult ?? defaultRenderClaudeCodeCliToolCallResult,\n buildClaudeCodeCliPrompt: src.buildClaudeCodeCliPrompt ?? defaultBuildClaudeCodeCliPrompt,\n }\n}\n\nconst estimateTokensOf = async (\n value: { estimateTokens: (encoding: TokenEncoding) => number | Promise<number> },\n encoding: TokenEncodingId\n): Promise<number> => Promise.resolve(value.estimateTokens(encoding as TokenEncoding))\n\n// ─── time / checksum helpers ────────────────────────────────────────────────\n\nconst nowIso = (): string => new Date().toISOString()\n\n/**\n * Normalise a thrown/rejected value into a real `Error` suitable as an exception `.cause`. Mirrors\n * `dispatch_runner.ts`'s internal (non-exported) `toErrorCause` convention: a genuine `Error` (per\n * the cross-realm-safe {@link isError} guard) passes through unchanged; anything else — a string,\n * a plain object, a cross-realm error whose `instanceof Error` is false — is wrapped in a real\n * `Error` whose message is the value's best string form, with the original preserved on `.cause`.\n *\n * Never throws. It runs inside the adapter's last-line-of-defence catch handlers (the `onEvent`\n * rejection handler, the stdout `'data'` listener, the background-shutdown rejection handler), so a\n * throw here would recreate the exact unhandled-rejection / uncaught-exception class it exists to\n * prevent. A hostile thrown value can defeat BOTH `JSON.stringify` and `String` (a `Proxy` with a\n * throwing trap, or an object whose `toJSON` and `toString` both throw) and can even make the\n * `isError` guard itself throw, so each step is guarded and the last resort is a fixed string.\n */\nconst toErrorCause = (value: unknown): Error => {\n try {\n if (isError(value)) return value\n } catch {\n /* a hostile value can throw from the guard's own property reads; treat it as a non-Error */\n }\n let text: string\n try {\n text =\n typeof value === 'string'\n ? value\n : value === undefined\n ? 'undefined'\n : (JSON.stringify(value) ?? String(value))\n } catch {\n try {\n text = String(value)\n } catch {\n text = '[unserialisable thrown value]'\n }\n }\n return new Error(`non-Error thrown while handling a wrapper event: ${text}`, { cause: value })\n}\n\n/**\n * Integrity checksum over `tool`/`args` — matches every other LLM battery's convention\n * (`sha256(canonicalStringify({tool, args}))`, see `ollama/adapter.ts`'s `computeChecksum`), NOT\n * the per-call `requestId`. Identical repeat calls must share this checksum: it feeds\n * `DispatchContext`'s own `#toolCallChecksums` loop-detection counter and cross-bus correlation,\n * neither of which can see a repeat if every call gets a unique value.\n */\nconst computeChecksum = (tool: string, args: unknown): string =>\n sha256(canonicalStringify({ tool, args }))\n\n// ─── outbound tool-result rendering (decision 8) ───────────────────────────────\n\nconst renderMediaListAsOutbound = async (\n mediaList: Media[],\n unsupportedResultMediaPolicy: UnsupportedMediaPolicy\n): Promise<{ content: OutboundContentBlock[]; isError: boolean }> => {\n const content: OutboundContentBlock[] = []\n let anyUnsupported = false\n for (const media of mediaList) {\n if (media.kind === 'image') {\n content.push({ type: 'image', data: await media.asBase64(), mimeType: media.mimeType })\n continue\n }\n // Every non-image modality is unsupported on the outbound MCP wire (only text/image content\n // blocks exist there) — routed through the SAME policy family the inbound direction uses\n // (decision 8), rather than an unconditional hardcoded error.\n if (unsupportedResultMediaPolicy === 'throw') {\n anyUnsupported = true\n content.push({\n type: 'text',\n text: `Unsupported result media modality: ${media.kind} (${media.mimeType})`,\n })\n continue\n }\n const byteLen = await media.byteLength().catch(() => undefined)\n content.push({\n type: 'text',\n text: `[media: ${media.filename}, ${media.mimeType}, ${byteLen ?? 'unknown'} bytes]`,\n })\n }\n return { content, isError: anyUnsupported }\n}\n\nconst renderOutboundResult = async (input: {\n raw: string | Uint8Array | SpooledArtifact | Media | Media[]\n callId: string\n inline: boolean\n spoolStore: SpoolStore\n unsupportedResultMediaPolicy: UnsupportedMediaPolicy\n}): Promise<{ content: OutboundContentBlock[]; isError: boolean }> => {\n const { raw, callId, inline } = input\n\n if (Media.isMedia(raw)) {\n return renderMediaListAsOutbound([raw], input.unsupportedResultMediaPolicy)\n }\n if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n return renderMediaListAsOutbound(raw, input.unsupportedResultMediaPolicy)\n }\n if (looksLikeSpooledArtifact(raw)) {\n const artifact = raw as SpooledArtifact\n if (inline === false) {\n let byteLength = 0\n let lineCount = 0\n try {\n byteLength = await artifact.byteLength()\n } catch {\n byteLength = 0\n }\n try {\n lineCount = await artifact.lineCount()\n } catch {\n lineCount = 0\n }\n const body = renderArtifactHandleBody({ callId, artifact, byteLength, lineCount })\n return { content: [{ type: 'text', text: body }], isError: false }\n }\n const text = await artifact.asString()\n return { content: [{ type: 'text', text }], isError: false }\n }\n if (typeof raw === 'string') {\n return { content: [{ type: 'text', text: raw }], isError: false }\n }\n if (isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n await input.spoolStore.write(callId, raw)\n return {\n content: [{ type: 'text', text: '[binary tool result — see history for details]' }],\n isError: false,\n }\n }\n return { content: [{ type: 'text', text: String(raw) }], isError: false }\n}\n\n// ─── the adapter ────────────────────────────────────────────────────────────\n\n/**\n * Opinionated CLI-harness LLM adapter that drives the Claude Code CLI as a `DispatchExecutorFn`\n * destination.\n *\n * @remarks\n * Construction validates options eagerly via {@link validateOptions} and throws\n * {@link @nhtio/adk/batteries/llm/claude_code_cli!E_INVALID_CLAUDE_CODE_CLI_OPTIONS} on failure\n * (including the POSIX-only platform guard and the `apiKey`/`authToken` XOR check). The returned\n * instance is reusable: call {@link ClaudeCodeCliAdapter.executor} once per `DispatchRunner`\n * configuration.\n */\nexport class ClaudeCodeCliAdapter {\n /** Customary key for per-iteration overrides on `ctx.stash`. */\n public static readonly STASH_KEY = 'claudeCodeCli' as const\n\n readonly #baseline: ClaudeCodeCliAdapterOptions\n\n /**\n * @param options - Constructor-baseline options. Re-validated on every iteration after\n * per-dispatch and per-iteration overrides are layered in.\n * @throws {@link @nhtio/adk/batteries/llm/claude_code_cli!E_INVALID_CLAUDE_CODE_CLI_OPTIONS} when\n * `options` does not satisfy `claudeCodeCliOptionsSchema`.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n }\n\n /**\n * Returns a {@link @nhtio/adk!DispatchExecutorFn} bound to this adapter's baseline plus optional\n * executor-scope overrides.\n */\n executor(overrides?: Partial<ClaudeCodeCliAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = ClaudeCodeCliAdapter\n\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n const localWarn = (msg: string): void => {\n helpers.log.warn({ kind: 'helper-warning', message: msg })\n }\n\n // ── Step 1: merge & validate ──────────────────────────────────────────\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<ClaudeCodeCliAdapterOptions>)\n : {}\n const merged = validateOptions(mergeOptions(baseline, overrides, stashOverrides))\n\n if (merged.tokenEncoding !== null && merged.contextWindow === undefined) {\n throw new E_INVALID_CLAUDE_CODE_CLI_OPTIONS([\n 'tokenEncoding is non-null but contextWindow is undefined',\n ])\n }\n\n // ── Step 2: resolve helpers ───────────────────────────────────────────\n const resolvedHelpers = resolveHelpers(merged.helpers)\n\n // ── Step 3: resolve execa + wrapper path ──────────────────────────────\n let execaFn: ExecaLike\n try {\n execaFn = await resolveExeca(merged.execa)\n } catch (err) {\n ctx.nack(isError(err) ? err : new Error(String(err)))\n return\n }\n let wrapperPath: string\n try {\n wrapperPath = merged.wrapperPath ?? (await resolveWrapperPathWithFallback())\n } catch (err) {\n ctx.nack(isError(err) ? err : new Error(String(err)))\n return\n }\n const claudeBin = merged.claudeBin ?? 'claude'\n\n // ── Step 5: pre-render inbound tool-call results (for history) ────────\n // Key by primitive identity, not id: repeated vendor/request ids must not cross-wire results.\n const renderedToolCallResults = new Map<ToolCall, string>()\n for (const tc of ctx.turnToolCalls) {\n const rendered = await resolvedHelpers.renderClaudeCodeCliToolCallResult({\n toolCall: tc,\n results: tc.results as\n | Tokenizable\n | SpooledArtifact\n | SpooledArtifact[]\n | Media\n | Media[],\n tool: ctx.tools.get(tc.tool) as Tool | undefined,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn: localWarn,\n })\n renderedToolCallResults.set(tc, rendered)\n }\n\n // ── Step 6: build the -p prompt ────────────────────────────────────────\n const { prompt, reasoningPayloads } = await resolvedHelpers.buildClaudeCodeCliPrompt({\n systemPrompt: ctx.systemPrompt,\n renderCtx: ctx,\n standingInstructions: ctx.standingInstructions,\n memories: ctx.turnMemories,\n retrievables: ctx.turnRetrievables,\n messages: ctx.turnMessages,\n thoughts: ctx.turnThoughts,\n toolCalls: ctx.turnToolCalls,\n tools: ctx.tools,\n renderedToolCallResults,\n bucketOrder: merged.bucketOrder ?? [\n 'standingInstructions',\n 'memories',\n 'retrievables',\n 'timeline',\n ],\n selfIdentity: merged.selfIdentity ?? 'assistant',\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n renderChatCompletionsSystemPrompt: resolvedHelpers.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: resolvedHelpers.renderStandingInstructions,\n renderMemories: resolvedHelpers.renderMemories,\n renderRetrievables: resolvedHelpers.renderRetrievables,\n renderRetrievableSafetyDirective: resolvedHelpers.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: resolvedHelpers.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: resolvedHelpers.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: resolvedHelpers.renderThirdPartyPrivateRetrievables,\n renderRetrievableHandleBody: resolvedHelpers.renderRetrievableHandleBody,\n renderClaudeCodeCliTimelineMessage: resolvedHelpers.renderClaudeCodeCliTimelineMessage,\n renderClaudeCodeCliToolCallResult: resolvedHelpers.renderClaudeCodeCliToolCallResult,\n renderThought: resolvedHelpers.renderThought,\n filterThoughts: resolvedHelpers.filterThoughts,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n warn: localWarn,\n })\n\n // A `-p` prompt string has no side channel for an opaque, vendor-specific reasoning payload\n // the way Ollama/OpenAI's JSON request bodies do (`_adk_reasoning_payloads`) — there is\n // nowhere in this wire to forward one. Surface that loss as a diagnostic rather than\n // silently dropping it, matching the honesty standard applied to every other documented v1\n // limitation of this battery (text-only media, subagent text).\n if (reasoningPayloads.length > 0) {\n helpers.log.debug({\n kind: 'reasoning-payload-dropped',\n message: `${reasoningPayloads.length} opaque reasoning payload(s) matched replayCompatibility but have no destination on the Claude Code CLI wire (no side channel exists for a '-p' prompt) and were dropped.`,\n })\n }\n\n // ── Step 7: build the bridged-tools set (excluding disallowedTools) ───\n const disallowed = new Set(merged.disallowedTools ?? [])\n const visibleTools = ctx.tools.visible().filter((t) => !disallowed.has(t.name))\n const bridgedTools: WrapperBridgedTool[] = visibleTools.map((t) => {\n const described = t.describe()\n const inputSchema = resolvedHelpers.descriptionToChatCompletionsJsonSchema(\n described.inputSchema as never\n )\n return {\n name: described.name,\n description: described.description,\n inputSchema:\n inputSchema && Object.keys(inputSchema).length > 0\n ? (inputSchema as Record<string, unknown>)\n : { type: 'object', properties: {} },\n }\n })\n\n // ── Step 8: context window enforcement ────────────────────────────────\n if (merged.tokenEncoding !== null && merged.contextWindow !== undefined) {\n const encoding = merged.tokenEncoding as TokenEncodingId\n // The rendered prompt is the actual `-p` wire value. Measure it directly rather than\n // re-summing its source buckets: renderers add envelopes, provenance, and ordering.\n const promptTokens = await estimateTokensOf(new Tokenizable(prompt), encoding)\n const appendSystemPromptTokens = merged.appendSystemPrompt\n ? await estimateTokensOf(new Tokenizable(merged.appendSystemPrompt), encoding)\n : 0\n\n // Keep source-bucket diagnostics for middleware deciding what to shed. They are not part\n // of the authoritative total above, since their content is already represented by prompt.\n const rawSystemPrompt = await estimateTokensOf(ctx.systemPrompt, encoding)\n let rawStandingInstructions = 0\n for (const value of ctx.standingInstructions)\n rawStandingInstructions += await estimateTokensOf(value, encoding)\n let rawMemories = 0\n for (const value of ctx.turnMemories as Set<Memory>)\n rawMemories += await estimateTokensOf(value.content, encoding)\n let rawRetrievables = 0\n for (const r of ctx.turnRetrievables) {\n rawRetrievables +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(\n r.id,\n encoding as TokenEncoding,\n resolvedHelpers.renderRetrievableHandleBody\n )\n : await estimateTokensOf(r.content, encoding)\n }\n let rawTimeline = 0\n for (const msg of ctx.turnMessages)\n if (msg.content !== undefined)\n rawTimeline += await estimateTokensOf(msg.content, encoding)\n for (const thought of ctx.turnThoughts)\n rawTimeline += await estimateTokensOf(thought.content, encoding)\n for (const rendered of renderedToolCallResults.values())\n rawTimeline += await estimateTokensOf(new Tokenizable(rendered), encoding)\n // Claude Code receives declarations through MCP, not a wire `tools` array. This stable\n // serialization is an honest floor: JSON declarations plus the CLI-visible names.\n const toolSerialization = `${JSON.stringify(bridgedTools)}|${bridgedTools\n .map((t) => `mcp__adk_bridge__${t.name}`)\n .join(',')}`\n const tools = await estimateTokensOf(new Tokenizable(toolSerialization), encoding)\n const perBucket = {\n prompt: promptTokens,\n appendSystemPrompt: appendSystemPromptTokens,\n tools,\n raw: {\n systemPrompt: rawSystemPrompt,\n standingInstructions: rawStandingInstructions,\n memories: rawMemories,\n retrievables: rawRetrievables,\n timeline: rawTimeline,\n },\n }\n const total = promptTokens + appendSystemPromptTokens + tools\n helpers.log.debug({\n kind: 'context-window-usage',\n message: `Context window usage: ${total}/${merged.contextWindow} tokens`,\n payload: { total, limit: merged.contextWindow, encoding, perBucket },\n })\n if (total > merged.contextWindow)\n throw new E_CLAUDE_CODE_CLI_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n encoding,\n JSON.stringify(perBucket),\n ])\n }\n\n // ── Step 9: spawn the wrapper ──────────────────────────────────────────\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n let child: ReturnType<ExecaLike>\n try {\n child = execaFn(process.execPath, [wrapperPath], { cleanup: true })\n } catch (err) {\n ctx.nack(\n new E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n\n const startupTimeoutMs = merged.startupTimeoutMs ?? 45_000\n const streamIdleTimeoutMs = merged.streamIdleTimeoutMs ?? 60_000\n const disposeGraceMs = merged.disposeGraceMs ?? 2_000\n\n let sawReady = false\n let sawInit = false\n // Set SYNCHRONOUSLY the instant a terminal `result`/`error` event is observed — before any\n // `await` (e.g. `sealCurrentMessage()`) runs. The wrapper closing stdout immediately after\n // writing its terminal line is a real, observed race: without this flag, `stdout`'s `'end'`\n // handler can fire and call `settleOnce` (nacking the turn as an unexpected exit) while the\n // `result` handler is still awaiting `sealCurrentMessage()`, even though `settleOnce` itself\n // is idempotent-guarded — the guard only helps once one of the two paths has actually run.\n let sawTerminalEvent = false\n let startupTimer: ReturnType<typeof setTimeout> | undefined\n let idleTimer: ReturnType<typeof setTimeout> | undefined\n let settled = false\n // Set once the outer `await new Promise<void>(...)` below is constructed. The startup/idle\n // timers are armed BEFORE that promise exists, so their settleOnce() callbacks must resolve\n // it through this indirection rather than a `finish` closure defined only inside it — without\n // this, a startup or stream-idle timeout would settle ctx (nack) but never resolve the outer\n // promise, hanging the executor forever.\n let resolveIteration: (() => void) | undefined\n let currentMessageId: string | undefined\n let currentMessageBuffer = ''\n let sealedMessage = false\n // Count of `tool_call_request`s currently executing (accepted but not yet answered with a\n // `tool_call_response`). `streamIdleTimeoutMs` measures MODEL-stream idleness — the wrapper\n // waiting on Claude — not ADK tool-execution latency; a real tool (a web search, a sandboxed\n // run) can legitimately take longer than a short idle timeout with zero model-stream activity\n // in between, which would otherwise be falsely nacked as `STREAM_STALLED`. While this is\n // positive, the idle timer is suspended entirely; it re-arms only once EVERY in-flight call\n // has answered, using a counter (not a boolean) because the wrapper's MCP bridge hands out a\n // fresh id per JSON-RPC CallTool request and can in principle have more than one call in\n // flight before the first is answered. This intentionally does NOT add a separate\n // tool-execution timeout — that is a different feature, out of scope here.\n let inFlightToolCalls = 0\n\n const clearStartupTimer = (): void => {\n if (startupTimer) clearTimeout(startupTimer)\n startupTimer = undefined\n }\n const clearIdleTimer = (): void => {\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = undefined\n }\n const maybeClearStartupTimer = (): void => {\n if (sawReady && sawInit) clearStartupTimer()\n }\n\n const writeCommand = (command: WrapperCommand): void => {\n try {\n child.stdin?.write(encodeWrapperCommand(command))\n } catch {\n /* the wrapper's stdin may already be gone */\n }\n }\n\n const gracefulShutdown = async (): Promise<void> => {\n writeCommand({ type: 'shutdown' })\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, disposeGraceMs)\n // This inner chain is its own, independently-floating promise (the surrounding `new\n // Promise<void>` executor above never calls `reject`, so `gracefulShutdown()`'s own\n // returned promise cannot reject from this step) — `.finally()` runs its callback on\n // EITHER outcome but still re-raises the original rejection on its OWN returned promise\n // afterwards, and that returned promise is not otherwise referenced. If `child` rejects\n // (e.g. an execa spawn failure), this becomes an unhandled rejection entirely on its own,\n // regardless of whether callers of `gracefulShutdown()` attach a `.catch()` — the `.catch`\n // below is what actually closes that off.\n void Promise.resolve(child)\n .finally(() => {\n clearTimeout(timer)\n resolve()\n })\n .catch(() => {\n /* already handled above by resolving the outer promise; nothing else to do with a\n rejected child here */\n })\n })\n try {\n child.kill('SIGTERM')\n } catch {\n /* already exited */\n }\n }\n\n // Fire-and-forget `gracefulShutdown()` at every non-awaited call site below: it is async and\n // CAN reject (e.g. the `child` promise it awaits inside a `.finally` can itself reject, and\n // `child.kill('SIGTERM')`'s own try/catch only guards the synchronous call, not any of the\n // awaited steps before it) — a bare `void gracefulShutdown()` leaves that rejection with no\n // attached handler, becoming an unhandled promise rejection that crashes the host process by\n // default (Node >= 15). That is exactly the class of bug issue #39 is about; best-effort\n // teardown must never surface as one. `settleOnce`'s own resolution must also never wait on\n // this — shutdown is a courtesy to the wrapper process, not a precondition for the executor\n // settling.\n const shutdownInBackground = (): void => {\n gracefulShutdown().catch((err: unknown) => {\n const cause = toErrorCause(err)\n try {\n helpers.log.debug({\n kind: 'graceful-shutdown-rejected',\n message: `Best-effort wrapper shutdown failed; ignoring (the turn has already settled or is settling independently): ${cause.message}`,\n payload: { cause: cause.message },\n })\n } catch {\n /* logging itself must never escape a fire-and-forget cleanup path */\n }\n })\n }\n\n const abortListener = (): void => {\n shutdownInBackground()\n }\n ctx.abortSignal.addEventListener('abort', abortListener, { once: true })\n const detachAbortListener = (): void =>\n ctx.abortSignal.removeEventListener('abort', abortListener)\n\n // `fn` used to run with no try/catch: a throw inside a settlement callback (e.g.\n // `helpers.reportGenerationStats(...)` or `ctx.ack()`/`ctx.nack()` throwing\n // `E_LLM_EXECUTION_ALREADY_SIGNALLED` on a lost race) propagated out of `settleOnce` itself\n // AFTER `settled` had already flipped true. Every OTHER settlement call site resolves the\n // iteration promise from WITHIN its own `fn` (the startup/idle timers, the `error` branch, the\n // Fix-B `onEvent(...).catch(...)` handler, the stdout `'end'` handler, the wrapper-process\n // `.then/.catch`) — a throw meant that code never ran. The `result` branch is the one\n // exception: it deliberately calls `finish()` AFTER `settleOnce(...)` returns (to await the\n // wrapper's real exit first, see the comment at that call site) rather than inside `fn`, so a\n // throw there aborted the branch before `finish()` was ever reached. Either way, nothing else\n // in the file resolves the promise, and the executor hangs forever.\n //\n // The catch below guarantees resolution ONLY on that failure path — nacking (unless something\n // already signalled) and force-resolving the iteration promise — without changing the timing\n // of the NORMAL, non-throwing path for any caller (in particular, the `result` branch above\n // still resolves only after awaiting the wrapper's exit when `fn` does not throw).\n //\n // Every step inside the `catch` is individually try/catch-guarded, and `resolveIteration?.()`\n // runs in a `finally` gated on a local `threw` flag — NOT sequentially after the log/nack/\n // shutdown calls — because review round 2 found that the original version called\n // `helpers.log.error(...)` (itself capable of throwing, e.g. a caller-supplied logger) BEFORE\n // `resolveIteration?.()`: if the logger threw, resolution was skipped entirely even though\n // `settled` was already `true`, so every LATER `settleOnce` call anywhere in the file becomes\n // a silent no-op (its own `if (settled) return` guard fires first) — hanging the executor with\n // no remaining path to resolve it, and the throw itself would escape whichever caller invoked\n // `settleOnce` (e.g. the stdout `'data'` listener's own catch block, becoming an uncaught\n // exception). Guaranteeing `resolveIteration?.()` via `finally` makes `settleOnce` itself\n // incapable of throwing or skipping resolution, regardless of which best-effort step fails.\n const settleOnce = (fn: () => void): void => {\n if (settled) return\n settled = true\n clearStartupTimer()\n clearIdleTimer()\n detachAbortListener()\n let threw = false\n try {\n fn()\n } catch (err) {\n threw = true\n try {\n const cause = toErrorCause(err)\n try {\n helpers.log.error({\n kind: 'settlement-handler-threw',\n message: `A dispatch settlement handler threw while finalising the turn; nacking (if not already signalled) instead of leaving the executor hung: ${cause.message}`,\n payload: { cause: cause.message },\n })\n } catch {\n /* a throwing logger must not itself prevent nacking/resolving below */\n }\n // `ctx.ack()`/`ctx.nack()` are single-shot and throw `E_LLM_EXECUTION_ALREADY_SIGNALLED`\n // on a second call — `fn` may have already signalled successfully before a LATER\n // statement in the same callback threw (e.g. `reportGenerationStats` throwing before\n // `ctx.ack()` runs is safe to nack; `ctx.ack()` itself throwing means it was already\n // signalled by a race, and nacking again would itself throw). Only nack if nothing has\n // signalled yet, and never let a lost race here escape as a second thrown error.\n if (!ctx.isSignalled) {\n try {\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_ERROR([cause.message], { cause }))\n } catch {\n /* lost a race with a concurrent signal between the check above and this call */\n }\n }\n } catch {\n /* toErrorCause itself is not expected to throw, but this is the last line of defence */\n }\n } finally {\n if (threw) {\n // Best-effort teardown; never lets a rejection or a synchronous throw from starting it\n // stop resolution below.\n try {\n shutdownInBackground()\n } catch {\n /* starting shutdown must never prevent forced resolution */\n }\n // `fn` threw partway through, so whatever branch called `settleOnce` never reached its\n // own `resolveIteration?.()`/`finish()` call (whether that call lived inside `fn` or,\n // like the `result` branch, was deferred until after `settleOnce` returned) — force it\n // here, unconditionally, regardless of what failed above. Calling an already-resolved\n // `resolve()` again is a safe no-op. The NORMAL (non-throwing) path is untouched: this\n // branch only runs when `fn` threw, so the `result` branch's deliberate \"resolve only\n // after awaiting the wrapper's exit\" timing is unaffected when `fn` succeeds.\n try {\n resolveIteration?.()\n } catch {\n /* resolveIteration is a bare Promise executor's resolve(); it cannot throw, but this\n call must never be what makes settleOnce itself throw */\n }\n }\n }\n }\n\n startupTimer = setTimeout(() => {\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STARTUP_TIMEOUT([startupTimeoutMs]))\n })\n }, startupTimeoutMs)\n\n const armIdleTimer = (): void => {\n if (!sawReady || !sawInit) return\n // Suspended while any ADK tool call is executing — see `inFlightToolCalls`. Re-armed by\n // `handleToolCallRequest`'s own completion path once the counter returns to zero.\n if (inFlightToolCalls > 0) return\n clearIdleTimer()\n idleTimer = setTimeout(() => {\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_STALLED([streamIdleTimeoutMs]))\n })\n }, streamIdleTimeoutMs)\n }\n\n const sealCurrentMessage = async (): Promise<void> => {\n if (sealedMessage || currentMessageId === undefined) return\n sealedMessage = true\n await ctx.storeMessage(\n new Message({\n id: currentMessageId,\n role: 'assistant',\n content: currentMessageBuffer,\n identity: merged.selfIdentity ?? 'assistant',\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n const handleToolCallRequest = async (\n requestId: string,\n toolName: string,\n rawArgs: unknown\n ): Promise<void> => {\n const tool = ctx.tools.get(toolName)\n if (!tool) {\n writeCommand({\n type: 'tool_call_response',\n requestId,\n results: {\n content: [{ type: 'text', text: `Tool not found: ${toolName}` }],\n isError: true,\n },\n })\n return\n }\n // MCP's own JSON-RPC CallTool wire always sends `arguments` as an object; a non-object\n // here would indicate a malformed request from the bridge, not a legitimate call — defend\n // the same way the Ollama battery does for its own non-object case.\n const args: string | Record<string, unknown> = isObject(rawArgs) ? rawArgs : {}\n // Rename the wrapper's per-spawn `requestId` into a turn-unique ADK id BEFORE it touches\n // any internal bookkeeping (reportToolCall/ToolCall/spoolStore/renderOutboundResult) —\n // every wrapper spawn resets its own counter to \"0\" (see mcp_bridge.ts), so a\n // multi-iteration dispatch would otherwise hand the SAME id to `ctx.storeToolCall`/\n // `helpers.reportToolCall` twice and collide with the first (already-complete) call. The\n // literal wrapper `requestId` is preserved untouched for both `tool_call_response`\n // `writeCommand` calls below — the bridge correlates those by ITS OWN id, not this one.\n const callId = (merged.toolCallIdFilter ?? deCollideToolCallIds)(requestId, ctx)\n helpers.reportToolCall(callId, { tool: tool.name, args })\n const isArtifactTool = ArtifactTool.isArtifactTool(tool)\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let toolHadError = false\n try {\n const raw = await tool.executor(ctx)(args)\n if (isArtifactTool) {\n if (Tokenizable.isTokenizable(raw)) {\n results = raw\n } else if (typeof raw === 'string') {\n results = new Tokenizable(raw)\n } else {\n throw new Error(\n `ArtifactTool \"${tool.name}\" returned a non-string/non-Tokenizable value`\n )\n }\n } else if (Media.isMedia(raw)) {\n results = raw\n } else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n results = raw as Media[]\n } else if (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(callId, raw)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n const reader = await spoolStore.write(callId, String(raw))\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n }\n } catch (err) {\n toolHadError = true\n results = new Tokenizable(isError(err) ? err.message : String(err))\n }\n helpers.reportToolCall(callId, { results, isError: toolHadError, isComplete: true })\n const completedAt = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: tool.name,\n args,\n checksum: computeChecksum(tool.name, args),\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n inline: isArtifactTool,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n\n let rendered: { content: OutboundContentBlock[]; isError: boolean }\n try {\n rendered = await renderOutboundResult({\n raw: results as string | Uint8Array | SpooledArtifact | Media | Media[],\n callId,\n inline: isArtifactTool,\n spoolStore,\n unsupportedResultMediaPolicy:\n merged.unsupportedResultMediaPolicy ?? merged.unsupportedMediaPolicy ?? 'throw',\n })\n } catch (err) {\n rendered = {\n content: [{ type: 'text', text: isError(err) ? err.message : String(err) }],\n isError: true,\n }\n }\n writeCommand({\n type: 'tool_call_response',\n requestId,\n results: { content: rendered.content, isError: toolHadError || rendered.isError },\n })\n }\n\n await new Promise<void>((resolve) => {\n const finish = (): void => resolve()\n resolveIteration = finish\n\n const onEvent = async (event: WrapperEvent): Promise<void> => {\n if (event.type === 'ready') {\n sawReady = true\n maybeClearStartupTimer()\n const runCommand: WrapperCommand = {\n type: 'run',\n prompt,\n appendSystemPrompt: merged.appendSystemPrompt,\n model: merged.model,\n cwd: merged.cwd,\n addDir: merged.addDir,\n allowedTools: bridgedTools.map((t) => t.name),\n maxBudgetUsd: merged.maxBudgetUsd,\n fallbackModel: merged.fallbackModel,\n auth: {\n apiKey: merged.apiKey,\n authToken: merged.authToken,\n baseUrl: merged.baseURL,\n },\n disableTelemetry: merged.disableTelemetry,\n disableErrorReporting: merged.disableErrorReporting,\n disableNonessentialTraffic: merged.disableNonessentialTraffic,\n mcpToolIdleTimeoutMs: merged.mcpToolIdleTimeoutMs,\n claudeBin,\n forwardSubagentText: merged.forwardSubagentText,\n unsupportedResultMediaPolicy: String(\n merged.unsupportedResultMediaPolicy ?? merged.unsupportedMediaPolicy ?? 'throw'\n ),\n bridgedTools,\n extraArgs: merged.extraArgs,\n }\n writeCommand(runCommand)\n // No `armIdleTimer()` call here: its own `sawReady && sawInit` gate always returns\n // immediately at this point, since `init` (per the wrapper protocol) always arrives\n // strictly after `ready` — verified by the full existing test suite passing unchanged\n // with this call removed. The `init` branch below is what actually starts the clock.\n return\n }\n if (event.type === 'init') {\n sawInit = true\n maybeClearStartupTimer()\n helpers.log.info({\n kind: 'claude-init',\n message: 'Claude Code CLI initialized.',\n payload: event as unknown as Record<string, unknown>,\n })\n if (event.mcpServerErrors && event.mcpServerErrors.length > 0) {\n settleOnce(() => {\n finish()\n shutdownInBackground()\n ctx.nack(\n new E_CLAUDE_CODE_CLI_MCP_BRIDGE_STARTUP_FAILED([\n event.mcpServerErrors!.join(', '),\n ])\n )\n })\n return\n }\n // Genuine progress: the handshake completed cleanly, so this is what actually starts\n // the stream-idle clock (armIdleTimer's own `sawReady && sawInit` gate makes every\n // earlier call, e.g. the one in the `ready` branch above, a no-op) — NOT merely \"a\n // stdout chunk arrived\" (see the `'data'` listener below for why that distinction\n // matters).\n armIdleTimer()\n return\n }\n if (event.type === 'retry') {\n // Deliberately does NOT re-arm the idle timer. This is a diagnostic passthrough of\n // Claude's own `system/api_retry` line, not evidence that the model is making\n // progress — it fires precisely WHILE the model is stalled waiting on a retryable\n // upstream error. Under exponential backoff, retries commonly land well under\n // `streamIdleTimeoutMs` apart (e.g. 1s/2s/4s/8s/16s/32s), so treating them as\n // idle-resetting activity (as an unconditional per-chunk re-arm would) lets a\n // sustained retry storm suppress the stall timeout indefinitely. Issue #39 itself does\n // not establish what actually caused its \"dispatch hangs for 11+ minutes despite a 60s\n // streamIdleTimeoutMs\" report — this is a PLAUSIBLE mechanism, not a confirmed root\n // cause: `wrapper.ts` genuinely emits `retry` (api_retry passthrough, ~L369) and `log`\n // (e.g. `malformed-command` ~L275, `duplicate-run-command` ~L253,\n // malformed-stream-json inside `dispatchReader` ~L331) on the SAME stdout stream that\n // carries progress events, with no periodic heartbeat gating their cadence, so the\n // shape of the bug is real and reproducible (see the fix-C test below) — it is fixed\n // for THIS scenario regardless of whether it was the exact mechanism behind the\n // original report.\n helpers.log.warn({\n kind: 'claude-retry',\n message: `Claude API retry, attempt ${event.attempt}`,\n payload: event as unknown as Record<string, unknown>,\n })\n return\n }\n if (event.type === 'message_delta') {\n currentMessageId = event.id\n currentMessageBuffer += event.delta\n helpers.reportMessage(event.id, event.delta, { isComplete: event.isComplete })\n if (event.isComplete) {\n await sealCurrentMessage()\n }\n armIdleTimer()\n return\n }\n if (event.type === 'thought_delta') {\n helpers.reportThought(event.id, event.delta, { isComplete: event.isComplete })\n armIdleTimer()\n return\n }\n if (event.type === 'tool_call_request') {\n // Suspend the model-stream idle clock for the duration of ADK tool EXECUTION, not just\n // the round trip's arrival/departure: `streamIdleTimeoutMs` exists to catch the wrapper\n // going silent while waiting on Claude, and a slow-but-healthy tool (a web search, a\n // sandboxed run) produces no wrapper stdout of its own while it runs. Track with a\n // counter, not a boolean, since more than one `tool_call_request` can be in flight\n // before the first is answered (the MCP bridge assigns each JSON-RPC CallTool its own\n // id independently of completion order).\n inFlightToolCalls += 1\n clearIdleTimer()\n try {\n await handleToolCallRequest(event.requestId, event.tool, event.args)\n } finally {\n inFlightToolCalls = Math.max(0, inFlightToolCalls - 1)\n }\n // Re-arm on completion, not arrival — a genuine round trip (request handled, response\n // written back to the wrapper's stdin) is progress. `armIdleTimer`'s own\n // `inFlightToolCalls > 0` gate means this is a no-op while any OTHER concurrent call is\n // still executing; the timer resumes only once the last one has answered.\n armIdleTimer()\n return\n }\n if (event.type === 'result') {\n sawTerminalEvent = true\n await sealCurrentMessage()\n settleOnce(() => {\n if (event.isError && event.subtype !== 'error_max_turns') {\n ctx.nack(\n new E_CLAUDE_CODE_CLI_TURN_FAILED([\n event.stopReason ?? 'unknown',\n event.resultText ?? '',\n ])\n )\n return\n }\n if (event.isError && event.subtype === 'error_max_turns') {\n helpers.log.debug({\n kind: 'claude-max-turns-reached',\n message:\n 'Claude reached the fixed single-turn limit; treating it as normal completion.',\n payload: { subtype: event.subtype },\n })\n }\n helpers.reportGenerationStats({\n provider: 'claude_code_cli',\n model: merged.model,\n raw: event.raw as Record<string, unknown> | undefined,\n })\n if (merged.autoAck) ctx.ack()\n })\n // The wrapper, not the adapter, initiates its own shutdown on this path (Decision D\n // step 5) — a terminal NDJSON line proves the wrapper WROTE it, not that the OS\n // process has actually exited yet. Await the wrapper's real exit before resolving so\n // the executor doesn't return while the wrapper (and its `claude` grandchild) are\n // still tearing down.\n await Promise.resolve(child).catch(() => undefined)\n finish()\n return\n }\n if (event.type === 'error') {\n settleOnce(() => {\n finish()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_WRAPPER_CRASHED([event.message]))\n })\n return\n }\n if (event.type === 'log') {\n helpers.log[event.level]({\n kind: event.kind,\n message: event.message,\n payload: event.payload as Record<string, unknown> | undefined,\n })\n return\n }\n // 'shutdown_complete' — nothing further to do; the wrapper is exiting on its own.\n }\n\n const eventReader = createNdjsonLineReader<WrapperEvent>((raw) => {\n let event: WrapperEvent\n try {\n event = JSON.parse(raw) as WrapperEvent\n } catch {\n helpers.log.trace({\n kind: 'malformed-wrapper-event',\n message: 'Failed to parse wrapper event line; skipping.',\n payload: { linePreview: raw.slice(0, 256) },\n })\n return undefined\n }\n // `onEvent` is async and this callback is itself invoked synchronously from\n // `child.stdout.on('data', ...)` (below): a bare `void onEvent(event)` would leave any\n // rejection with no attached `.catch`, becoming an unhandled promise rejection that\n // crashes the host process by default (Node >= 15) — a single malformed/erroring\n // wrapper event or tool handler must fail only THIS candidate's dispatch, never the\n // host. `settleOnce`'s own idempotency guard makes this safe even when `onEvent` already\n // settled normally along another path before throwing/rejecting further down its body.\n onEvent(event).catch((err: unknown) => {\n const cause = toErrorCause(err)\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_ERROR([cause.message], { cause }))\n })\n })\n return event\n })\n\n child.stdout?.on('data', (chunk: Uint8Array) => {\n // Deliberately does NOT re-arm the idle timer unconditionally here (as an earlier\n // version of this listener did) — that treated ANY stdout chunk as \"progress\", but\n // `log`/`retry` `WrapperEvent`s (diagnostic passthroughs the wrapper emits on the same\n // stdout stream — see `wrapper.ts`'s `log()` helper and its `system/api_retry`\n // translation) carry no evidence the model is actually advancing, and a sustained\n // sequence of them (e.g. exponential-backoff API retries a few seconds apart) could\n // suppress the stall timeout indefinitely — this is a plausible mechanism for the\n // \"dispatch hangs for 11+ minutes despite a 60s streamIdleTimeoutMs\" report (see issue\n // #39), now fixed for that scenario. Each `onEvent` branch below now re-arms\n // individually, only for event types that constitute genuine progress (`init`,\n // `message_delta`, `thought_delta`, a completed `tool_call_request` round trip);\n // `ready`/`retry`/`log` do not. `init`'s own branch handles the \"very first chunk after\n // the handshake\" case that this comment used to describe, since `armIdleTimer()`'s\n // `sawReady && sawInit` gate means no earlier call in this turn could have armed it\n // anyway.\n //\n // `eventReader.push` calls `onLine` (below) SYNCHRONOUSLY, all the way down to the\n // `JSON.parse`-failure `helpers.log.trace(...)` call — a throw from either escapes this\n // listener directly, bypassing the Fix-B `onEvent(event).catch(...)` chain entirely\n // (that chain only guards `onEvent`'s own async rejection, not a synchronous throw that\n // happens before `onEvent` is even reached). An uncaught throw from inside a\n // `'data'` listener is exactly as fatal to the host process as the unhandled rejection\n // Fix B closed off, so route it through the same reliable settlement path.\n try {\n eventReader.push(chunk)\n } catch (err) {\n const cause = toErrorCause(err)\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_ERROR([cause.message], { cause }))\n })\n }\n })\n child.stdout?.on('end', () => {\n // A terminal `result`/`error` event was already observed and its own handler is (or will\n // shortly be) in the middle of its own `settleOnce` — defer to it rather than racing it\n // with a wrong \"stdout ended without a terminal event\" nack for what was actually a\n // successful turn. `sawTerminalEvent` is set synchronously by that handler before any\n // `await`, so it is already true here whenever this really is that race.\n if (sawTerminalEvent) return\n settleOnce(() => {\n finish()\n ctx.nack(\n new E_CLAUDE_CODE_CLI_PROCESS_EXITED_NONZERO([\n 0,\n 'stdout ended without a terminal event',\n ])\n )\n })\n })\n\n void Promise.resolve(child)\n .then((result: unknown) => {\n // Same race as the `stdout.on('end')` guard above: the `result` handler may still be\n // awaiting `sealCurrentMessage()`/the child's own exit when the wrapper process itself\n // settles — defer to the terminal-event path rather than nacking a successful turn.\n if (sawTerminalEvent) return\n const exitCode =\n isObject(result) && 'exitCode' in result\n ? ((result as { exitCode: number | null }).exitCode ?? -1)\n : -1\n settleOnce(() => {\n finish()\n ctx.nack(\n new E_CLAUDE_CODE_CLI_PROCESS_EXITED_NONZERO([\n exitCode,\n 'wrapper process exited with no terminal event observed',\n ])\n )\n })\n })\n .catch(() => {\n if (sawTerminalEvent) return\n settleOnce(() => {\n finish()\n ctx.nack(new E_CLAUDE_CODE_CLI_WRAPPER_CRASHED(['wrapper process rejected']))\n })\n })\n })\n }\n }\n\n /**\n * Returns `true` when `value` is a {@link ClaudeCodeCliAdapter} instance.\n */\n public static isClaudeCodeCliAdapter(value: unknown): value is ClaudeCodeCliAdapter {\n return isInstanceOf(value, 'ClaudeCodeCliAdapter', ClaudeCodeCliAdapter)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"adapter.cjs","names":["#baseline"],"sources":["../../../../src/batteries/llm/claude_code_cli/adapter.ts"],"sourcesContent":["/**\n * Cross-environment executor adapter that wraps the Claude Code CLI as a `DispatchExecutorFn`\n * destination.\n *\n * @module @nhtio/adk/batteries/llm/claude_code_cli/adapter\n *\n * @remarks\n * The first battery in the \"CLI harness\" family: rather than a direct wire-format provider, this\n * adapter drives an external coding-agent CLI binary that is itself a complete agent loop. Since a\n * subprocess must be spawned anyway, ALL Claude-Code-specific complexity — spawning the real\n * `claude` binary, hosting an MCP bridge server, translating its stream-json — lives in a\n * dedicated wrapper process (`wrapper.ts`, shipped as a sibling dist asset); this adapter only\n * ever spawns and drives that wrapper over the small, harness-agnostic protocol in `./wire`.\n *\n * Every dispatch iteration is stateless and self-contained: the full accumulated history renders\n * into one `-p` prompt string (`buildClaudeCodeCliPrompt`), a fresh wrapper is spawned, and real\n * ADK tools are bridged into the CLI's own tool loop via MCP — but actual execution always happens\n * on the ADK side, through `tool.executor(ctx)(args)`, exactly like every other LLM battery.\n */\n\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { deCollideToolCallIds } from '../chat_common'\nimport { isError, isObject, isInstanceOf } from '@nhtio/adk/guards'\nimport { createNdjsonLineReader, encodeWrapperCommand } from './wire'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { InMemorySpoolStore } from '@nhtio/adk/batteries/storage/in_memory'\nimport {\n Tokenizable,\n ToolCall,\n Memory,\n Message,\n Media,\n ArtifactTool,\n SpooledArtifact,\n} from '@nhtio/adk/common'\nimport {\n E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR,\n E_CLAUDE_CODE_CLI_WRAPPER_CRASHED,\n E_CLAUDE_CODE_CLI_PROCESS_EXITED_NONZERO,\n E_CLAUDE_CODE_CLI_STREAM_ERROR,\n E_CLAUDE_CODE_CLI_STREAM_STALLED,\n E_CLAUDE_CODE_CLI_STARTUP_TIMEOUT,\n E_CLAUDE_CODE_CLI_MCP_BRIDGE_STARTUP_FAILED,\n E_CLAUDE_CODE_CLI_TURN_FAILED,\n E_INVALID_CLAUDE_CODE_CLI_OPTIONS,\n E_CLAUDE_CODE_CLI_CONTEXT_OVERFLOW,\n E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND,\n} from './exceptions'\nimport {\n defaultDescriptionToChatCompletionsJsonSchema,\n defaultRenderUntrustedContent,\n defaultRenderTrustedContent,\n defaultRenderStandingInstructions,\n defaultRenderMemories,\n defaultRenderRetrievables,\n defaultRenderRetrievableHandleBody,\n defaultRenderRetrievableSafetyDirective,\n defaultRenderFirstPartyRetrievables,\n defaultRenderThirdPartyPublicRetrievables,\n defaultRenderThirdPartyPrivateRetrievables,\n defaultRenderThought,\n defaultFilterThoughts,\n defaultToolsToChatCompletionsTools,\n defaultRenderChatCompletionsSystemPrompt,\n defaultRenderClaudeCodeCliTimelineMessage,\n defaultRenderClaudeCodeCliToolCallResult,\n defaultBuildClaudeCodeCliPrompt,\n renderArtifactHandleBody,\n looksLikeSpooledArtifact,\n} from './helpers'\nimport type { Tool } from '@nhtio/adk/common'\nimport type { SpoolStore } from '@nhtio/adk/common'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { TokenEncoding, TokenEncodingId } from '@nhtio/adk/types'\nimport type { WrapperEvent, WrapperCommand, WrapperBridgedTool } from './wire'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/dispatch_runner'\nimport type {\n ClaudeCodeCliAdapterOptions,\n ClaudeCodeCliHelpers,\n ExecaLike,\n ExecaResolver,\n UnsupportedMediaPolicy,\n} from './types'\n\ntype OutboundContentBlock =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n\n// ─── wrapper path resolution (Decision C) ──────────────────────────────────────\n\n/**\n * Resolve the built wrapper asset's on-disk path relative to this module's own compiled location.\n * `adapter.ts` carries its own `@module` tag (per the per-file tagging convention every other\n * multi-file battery uses), so it compiles to `dist/batteries/llm/claude_code_cli/adapter.mjs` —\n * three directories below the package root, where the wrapper (an explicit, un-tagged\n * `vite.config.mts` entry key) compiles to `dist/claude-code-cli-wrapper.mjs`.\n */\nexport const resolveDefaultWrapperPath = (): string => {\n // `typeof require === 'function'` alone is not a safe CJS-vs-ESM discriminator: rolldown's ESM\n // output wraps `require` in a shim/Proxy (falling back to itself when the real `require` is\n // absent) that still reports `typeof === 'function'`, but whose `.resolve` is not itself a\n // function — calling it throws instead of falling through to the URL-based ESM branch below.\n if (typeof require === 'function' && typeof require.resolve === 'function') {\n return require.resolve('../../../claude-code-cli-wrapper.cjs')\n }\n // `URL.pathname` is percent-encoded — a real install path containing a space, unicode, or any\n // other URL-reserved character would produce a non-existent argv path (e.g. `%20` instead of a\n // literal space) once handed to `execaFn`/`spawn` below. `decodeURIComponent` undoes that percent\n // encoding to recover the native filesystem path — equivalent to `node:url`'s `fileURLToPath` for\n // a POSIX path (verified directly), which this module avoids importing at module scope: this\n // file is transitively pulled into the browser test project via `src/batteries`'s barrel (e.g.\n // `tests/unit/batteries/index.cross.spec.ts`), and Vite externalizes `node:url` there, throwing\n // on any access to `fileURLToPath` at import time. This battery is POSIX-only in v1 anyway\n // (validated at options-construction time), so a POSIX-only decode is exactly the right amount\n // of `node:url` behavior to reimplement without importing it.\n return decodeURIComponent(\n new URL('../../../claude-code-cli-wrapper.mjs', import.meta.url).pathname\n )\n}\n\n/**\n * Existence-check a candidate wrapper path, lazily acquiring `node:fs`'s `existsSync` — never\n * imported at module scope for the same reason `resolveDefaultWrapperPath` avoids `node:url`\n * above: this file is transitively pulled into the browser test project via `src/batteries`'s\n * barrel, and a module-scope Node-builtin import would throw at import time there. Any failure to\n * even acquire `node:fs` (e.g. a hostile/exotic runtime) is treated as \"does not exist\" rather\n * than propagating, since this is only ever used to pick between fallback candidates.\n */\nconst existsOnDisk = async (path: string): Promise<boolean> => {\n try {\n const fs = (await import('node:fs')) as { existsSync?: (p: string) => boolean }\n return typeof fs.existsSync === 'function' && fs.existsSync(path)\n } catch {\n return false\n }\n}\n\n/**\n * Result of a self-reference resolution attempt: the resolved, existence-checked sibling path when\n * found, plus a full log of every candidate/reason tried — reported to the caller so\n * {@link E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND} can name everything actually checked, not just the\n * relative resolver's own error.\n */\ninterface SelfReferenceResolution {\n path?: string\n tried: string[]\n}\n\n/**\n * Injectable seams for {@link resolveWrapperPathViaSelfReference}'s two internal self-reference\n * routes — internal, non-breaking test hooks (mirrors {@link WrapperPathResolutionSeams} below,\n * one layer deeper). A real ambient `require` is module-scoped per compiled file, so a test file\n * patching its OWN `require.resolve` has no effect on `adapter.ts`'s ambient `require` (verified\n * directly — each ES module/CJS wrapper gets its own `require` binding, even within the same\n * vitest worker/module graph), and this repo's own `@nhtio/adk` package genuinely self-resolves\n * successfully inside the test environment (this worktree's own `package.json` is itself named\n * `@nhtio/adk`), so route 1 can't be made to fail deterministically without a seam either. These\n * two knobs let a unit test drive both \"ambient require resolution failed\" and \"import.meta.url\n * unavailable\" without needing a real bundled/stripped module environment. Both default to the\n * real ambient behavior when omitted.\n */\ninterface SelfReferenceResolutionSeams {\n ambientRequireResolve?: (specifier: string) => string\n importMetaUrl?: string | undefined\n}\n\n/**\n * Resolve the wrapper asset's sibling path relative to THIS PACKAGE's own already-published main\n * entry, rather than relative to the (possibly relocated-by-bundling) adapter module. Node's\n * package self-reference feature — a package resolving its own name as a bare specifier — is\n * depth-independent within `@nhtio/adk`'s own tree, so this survives the adapter code being moved\n * around WITHIN the package by a bundler. It only breaks once the calling code has been physically\n * bundled OUTSIDE `@nhtio/adk`'s own directory tree (e.g. into a consumer's Electron main-process\n * bundle) — at that point self-reference falls back to ordinary node_modules bare-specifier\n * resolution, which succeeds exactly when `@nhtio/adk` is still installed as a resolvable\n * dependency from the bundled code's new location. That is the same \"normal case\" the published\n * `wrapperPath` override already exists for, so this fallback is a strict improvement with no new\n * failure mode: when it can't resolve, behavior degrades to the pre-existing \"throw a clear error\"\n * path below rather than a worse outcome.\n *\n * Deliberately resolves this package's `exports['.']` main entry (already published, no `exports`\n * map change needed) and derives the wrapper's path as a sibling of that entry's directory — every\n * `vite.config.mts` `build.lib.entry` key (including the un-tagged wrapper) emits to a flat\n * `dist/` directory, so `dirname(mainEntry) === dirname(wrapperAsset)`.\n *\n * Two independent ways to reach a `require`-like resolver are tried, in this order, because a\n * bundled consumer may land in either shape and each leaves the OTHER unusable:\n *\n * 1. A real ambient `require` — present when THIS MODULE has itself been bundled into a CJS\n * output (e.g. `esbuild --platform=node --format=cjs`, which is common for an Electron\n * main-process bundle, the issue's reported scenario). Reused verbatim is the exact same\n * discriminator `resolveDefaultWrapperPath` above already documents:\n * `typeof require === 'function' && typeof require.resolve === 'function'` — because a bundled\n * ESM output can ALSO leave a truthy `require` behind as a dynamic-require shim/Proxy (rolldown\n * and esbuild both do this) whose `.resolve` is not itself a function, and calling it would\n * throw rather than genuinely resolving anything. In a genuine CJS bundle this ambient\n * `require.resolve('@nhtio/adk')` works directly with no `createRequire` bridge needed.\n * 2. `createRequire(import.meta.url)` — the ESM path, used only when step 1 didn't yield a usable\n * resolver. Verified empirically that esbuild's `--format=cjs` output rewrites every\n * `import.meta` reference in bundled source to a plain `var import_meta = {}`, so\n * `import.meta.url` is `undefined` there — `createRequire(undefined)` throws\n * `ERR_INVALID_ARG_VALUE` outright, so this branch is skipped by checking\n * `typeof import.meta.url === 'string'` first rather than letting that throw surface as an\n * opaque, unrelated-looking error. `createRequire` (rather than `import.meta.resolve`) is used\n * here because — unlike `import.meta.resolve` — its `.resolve` performs a real filesystem\n * existence check (verified directly: `import.meta.resolve` happily returns a URL for a target\n * file that does not exist, since it only resolves the `exports` map syntactically;\n * `require.resolve`, including through `createRequire`, throws `MODULE_NOT_FOUND` for a missing\n * target), so a resolved path here is already known to exist and only the derived wrapper\n * sibling still needs its own explicit check below.\n *\n * `tried` always accounts for BOTH routes once step 1 has not already produced a `mainEntry`: step\n * 2 either resolves, records its own failure, or — when `import.meta.url` isn't even a string —\n * records an explicit \"skipped: import.meta.url unavailable\" entry, so the thrown error's \"Tried:\"\n * list never silently omits a route just because it was never attempted.\n *\n * A `process.cwd()`-anchored resolution attempt is deliberately NOT included as a further\n * fallback: resolution should stay anchored to the bundle's own module identity, not to a mutable,\n * launch-directory-dependent value that has no necessary relationship to where the bundle — or\n * `@nhtio/adk` — actually live. Failing clearly and pointing at `wrapperPath` is a better outcome\n * than a resolution that silently varies with the process's current working directory.\n */\nconst resolveWrapperPathViaSelfReference = async (\n wrapperBasename: string,\n seams: SelfReferenceResolutionSeams = {}\n): Promise<SelfReferenceResolution> => {\n const tried: string[] = []\n let mainEntry: string | undefined\n\n const hasAmbientRequire =\n seams.ambientRequireResolve !== undefined ||\n (typeof require === 'function' && typeof require.resolve === 'function')\n if (hasAmbientRequire) {\n try {\n mainEntry = (seams.ambientRequireResolve ?? require.resolve)('@nhtio/adk')\n } catch (err) {\n tried.push(\n `self-reference via ambient require('@nhtio/adk') failed: ${isError(err) ? err.message : String(err)}`\n )\n }\n }\n\n // Every branch below either resolves `mainEntry` or pushes a `tried` entry explaining why not —\n // so by the time we reach the `mainEntry === undefined` check further down, `tried` can no longer\n // be empty (a prior review round's \"no usable ambient require and no import.meta.url\" catch-all\n // for a silently-empty `tried` is gone because it is now unreachable: the branch below records\n // its OWN skip reason instead of leaving nothing behind).\n if (mainEntry === undefined) {\n const importMetaUrl = 'importMetaUrl' in seams ? seams.importMetaUrl : import.meta.url\n if (typeof importMetaUrl === 'string') {\n try {\n const { createRequire } = await import('node:module')\n mainEntry = createRequire(importMetaUrl).resolve('@nhtio/adk')\n } catch (err) {\n tried.push(\n `self-reference via createRequire(import.meta.url).resolve('@nhtio/adk') failed: ${isError(err) ? err.message : String(err)}`\n )\n }\n } else {\n // Regression for the AI-review finding: this route being unavailable used to leave no trace\n // at all whenever the ambient-`require` route above HAD recorded something (e.g. it existed\n // but failed) — the \"Tried:\" list would then name the ambient failure but silently omit that\n // the createRequire route was never even attempted. Recording the skip explicitly means every\n // self-reference route is always accounted for in the thrown error.\n tried.push(\n 'self-reference via createRequire(import.meta.url) skipped: import.meta.url unavailable in this module context'\n )\n }\n }\n\n if (mainEntry === undefined) {\n return { tried }\n }\n\n const lastSlash = mainEntry.lastIndexOf('/')\n if (lastSlash < 0) {\n tried.push(\n `self-reference resolved '@nhtio/adk' to an unexpected path with no directory separator: ${mainEntry}`\n )\n return { tried }\n }\n const candidate = `${mainEntry.slice(0, lastSlash + 1)}${wrapperBasename}`\n tried.push(candidate)\n return (await existsOnDisk(candidate)) ? { path: candidate, tried } : { tried }\n}\n\n/**\n * Injectable seams for {@link resolveWrapperPathWithFallback}'s three collaborators — internal,\n * non-breaking test hooks (never new `ClaudeCodeCliAdapterOptions` fields): swapping these lets\n * unit tests exercise the bundled-fallback and unresolvable branches deterministically, without a\n * real `dist/` build or filesystem mocking. Each defaults to the real implementation above.\n */\ninterface WrapperPathResolutionSeams {\n resolveRelative?: () => string\n resolveSelfRef?: (wrapperBasename: string) => Promise<SelfReferenceResolution>\n checkExists?: (path: string) => Promise<boolean>\n}\n\n/**\n * Internal, non-public resolver used by the executor call site (never `resolveDefaultWrapperPath`\n * itself, which stays synchronous and unchanged for backwards compatibility with any caller that\n * already imports it directly). Tries the existing relative-to-module resolution FIRST — zero\n * behavior change for the common unbundled case — and only falls back to the self-reference\n * lookup when that candidate does not exist on disk (bundling relocated the adapter). Throws\n * {@link E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND} naming every path tried — the relative candidate (or\n * its resolution error) AND every self-reference candidate/reason from\n * {@link resolveWrapperPathViaSelfReference} — when neither resolves, rather than letting a bundled\n * consumer hit an opaque `MODULE_NOT_FOUND`/ENOENT deep inside `execa`, or a truncated error that\n * hides what the self-reference fallback actually attempted.\n *\n * @remarks\n * Electron/asar note: an app packaged into an `asar` archive can still `readFileSync`/`existsSync`\n * transparently-unpacked paths through Electron's patched `fs`, so this existence-check strategy\n * keeps working there without special-casing — but a wrapper asset that ships unpacked (outside\n * `asar`) is still the consumer's responsibility to arrange, same as any other spawned-executable\n * asset; `wrapperPath` remains the escape hatch when that layout doesn't line up.\n *\n * @remarks\n * Coverage note — deployment shapes: this resolver (both branches) only ever finds the wrapper\n * asset when `@nhtio/adk` itself (with `dist/claude-code-cli-wrapper.{cjs,mjs}` inside it) remains\n * an ordinarily-resolvable dependency from wherever the bundle ends up running — the bundle never\n * carries the wrapper asset itself. A bundle relocated outside its original project (so\n * `node_modules/@nhtio/adk` is no longer reachable), or an Electron app that prunes/asar-packs\n * `@nhtio/adk` out of its final package, is NOT covered by either branch and needs the explicit\n * `wrapperPath` option — which is exactly what the thrown error's message directs the caller to.\n */\nconst resolveWrapperPathWithFallback = async (\n seams: WrapperPathResolutionSeams = {}\n): Promise<string> => {\n const resolveRelative = seams.resolveRelative ?? resolveDefaultWrapperPath\n const resolveSelfRef = seams.resolveSelfRef ?? resolveWrapperPathViaSelfReference\n const checkExists = seams.checkExists ?? existsOnDisk\n\n const tried: string[] = []\n\n let relative: string | undefined\n try {\n relative = resolveRelative()\n } catch (err) {\n tried.push(isError(err) ? err.message : String(err))\n }\n if (relative !== undefined) {\n tried.push(relative)\n if (await checkExists(relative)) return relative\n }\n\n // Bundled-CJS wrinkle, made explicit here: in a real esbuild `--format=cjs` bundle,\n // `resolveDefaultWrapperPath`'s ambient-`require.resolve` branch throws `MODULE_NOT_FOUND` for\n // the RELATIVE `../../../claude-code-cli-wrapper.cjs` specifier (that relative path no longer\n // exists once bundling has relocated this module outside `@nhtio/adk`'s own tree), so `relative`\n // stays `undefined` and `isCjsWrapper` defaults `false` — `wrapperBasename` picks the `.mjs`\n // variant even though the CALLING bundle is CJS. This is harmless: the wrapper asset is never\n // imported/required in-process, only spawned as a completely separate `node` child process (see\n // `execaFn(wrapperExecPath, [wrapperPath, ...])` at the call site below — `wrapperExecPath`\n // defaults to `process.execPath`, same as always, but is overridable per issue #42's part C),\n // and Node runs a `.mjs`-suffixed file as ESM regardless of the PARENT process's own module\n // format. Picking `.cjs`\n // here would be no more correct — either extension resolves to a real, runnable file once\n // self-reference finds `@nhtio/adk`'s own `dist/` directory.\n const isCjsWrapper = relative !== undefined && relative.endsWith('.cjs')\n const wrapperBasename = isCjsWrapper\n ? 'claude-code-cli-wrapper.cjs'\n : 'claude-code-cli-wrapper.mjs'\n const selfRef = await resolveSelfRef(wrapperBasename)\n tried.push(...selfRef.tried)\n if (selfRef.path !== undefined) return selfRef.path\n\n throw new E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND([tried.join(', ') || '(no candidates)'])\n}\n\n// Test-only aliases, following `transformers_js/adapter.ts`'s `__extractGeneratedText` precedent.\n// They are NOT re-exported from `index.ts` or any barrel, but because this file carries its own\n// `@module` tag they ARE reachable at runtime through the published\n// `@nhtio/adk/batteries/llm/claude_code_cli/adapter` subpath — and that reachability is load-bearing:\n// `tests/unit/build/claude_code_cli_wrapper_resolves_bundled.node.spec.ts` imports\n// `__resolveWrapperPathWithFallback` from that subpath to prove resolution inside a real bundle.\n// They carry no stability guarantee and are not part of the supported API; do not depend on them.\n// They are deliberately NOT marked `@internal`: `tsconfig.build.json` sets `stripInternal`, which\n// would drop them from the published `.d.ts` and break that bundled test's typed import.\n// `__resolveWrapperPathViaSelfReference` is exported one layer deeper than\n// `__resolveWrapperPathWithFallback` so a unit test can drive its `SelfReferenceResolutionSeams`\n// directly — see that interface's doc comment for why the outer seam (`resolveSelfRef`) can't\n// itself deterministically exercise route 1 vs. route 2.\nexport { resolveWrapperPathWithFallback as __resolveWrapperPathWithFallback }\nexport { resolveWrapperPathViaSelfReference as __resolveWrapperPathViaSelfReference }\n\n// ─── execa resolution (mirrors execa_executor.ts's lazy-resolver pattern) ──────\n\nconst resolveExeca = async (supplied: ExecaResolver | undefined): Promise<ExecaLike> => {\n let value: unknown =\n supplied ?? (() => import('execa') as unknown as Promise<{ execa: ExecaLike }>)\n if (typeof value === 'function' && !('exec' in (value as object))) {\n try {\n value = await (value as () => unknown)()\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR([\n `execa resolver failed: ${detail} — install the optional peer dependency \"execa\" or supply your own`,\n ])\n }\n }\n if (isObject(value) && 'execa' in value) {\n value = (value as { execa: unknown }).execa\n }\n if (typeof value !== 'function') {\n throw new E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR([\n 'execa resolver did not resolve to a function',\n ])\n }\n return value as ExecaLike\n}\n\n// ─── option merging ─────────────────────────────────────────────────────────\n\nconst mergeRecord = <T extends Record<string, unknown>>(\n layers: ReadonlyArray<T | undefined>\n): T | undefined => {\n let merged: T | undefined\n for (const layer of layers) {\n if (!layer) continue\n merged = { ...(merged ?? ({} as T)), ...layer }\n }\n return merged\n}\n\nconst mergeOptions = (\n baseline: ClaudeCodeCliAdapterOptions,\n exec: Partial<ClaudeCodeCliAdapterOptions> | undefined,\n stash: Partial<ClaudeCodeCliAdapterOptions> | undefined\n): Partial<ClaudeCodeCliAdapterOptions> => {\n const layers = [baseline as Partial<ClaudeCodeCliAdapterOptions>, exec ?? {}, stash ?? {}]\n const out: Record<string, unknown> = {}\n for (const layer of layers) {\n for (const [k, v] of Object.entries(layer)) {\n if (v === undefined) continue\n if (k === 'helpers') continue\n out[k] = v\n }\n }\n const helpers = mergeRecord(layers.map((l) => l.helpers as Record<string, unknown> | undefined))\n if (helpers !== undefined) out.helpers = helpers\n return out as Partial<ClaudeCodeCliAdapterOptions>\n}\n\nconst resolveHelpers = (\n overrides: Partial<ClaudeCodeCliHelpers> | undefined\n): ClaudeCodeCliHelpers => {\n const src = overrides ?? {}\n return {\n descriptionToChatCompletionsJsonSchema:\n src.descriptionToChatCompletionsJsonSchema ?? defaultDescriptionToChatCompletionsJsonSchema,\n renderUntrustedContent: src.renderUntrustedContent ?? defaultRenderUntrustedContent,\n renderTrustedContent: src.renderTrustedContent ?? defaultRenderTrustedContent,\n renderStandingInstructions: src.renderStandingInstructions ?? defaultRenderStandingInstructions,\n renderMemories: src.renderMemories ?? defaultRenderMemories,\n renderRetrievables: src.renderRetrievables ?? defaultRenderRetrievables,\n renderRetrievableHandleBody:\n src.renderRetrievableHandleBody ?? defaultRenderRetrievableHandleBody,\n renderRetrievableSafetyDirective:\n src.renderRetrievableSafetyDirective ?? defaultRenderRetrievableSafetyDirective,\n renderFirstPartyRetrievables:\n src.renderFirstPartyRetrievables ?? defaultRenderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables:\n src.renderThirdPartyPublicRetrievables ?? defaultRenderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables:\n src.renderThirdPartyPrivateRetrievables ?? defaultRenderThirdPartyPrivateRetrievables,\n renderThought: src.renderThought ?? defaultRenderThought,\n filterThoughts: src.filterThoughts ?? defaultFilterThoughts,\n toolsToChatCompletionsTools:\n src.toolsToChatCompletionsTools ?? defaultToolsToChatCompletionsTools,\n renderChatCompletionsSystemPrompt:\n src.renderChatCompletionsSystemPrompt ?? defaultRenderChatCompletionsSystemPrompt,\n renderClaudeCodeCliTimelineMessage:\n src.renderClaudeCodeCliTimelineMessage ?? defaultRenderClaudeCodeCliTimelineMessage,\n renderClaudeCodeCliToolCallResult:\n src.renderClaudeCodeCliToolCallResult ?? defaultRenderClaudeCodeCliToolCallResult,\n buildClaudeCodeCliPrompt: src.buildClaudeCodeCliPrompt ?? defaultBuildClaudeCodeCliPrompt,\n }\n}\n\nconst estimateTokensOf = async (\n value: { estimateTokens: (encoding: TokenEncoding) => number | Promise<number> },\n encoding: TokenEncodingId\n): Promise<number> => Promise.resolve(value.estimateTokens(encoding as TokenEncoding))\n\n// ─── time / checksum helpers ────────────────────────────────────────────────\n\nconst nowIso = (): string => new Date().toISOString()\n\n/**\n * Normalise a thrown/rejected value into a real `Error` suitable as an exception `.cause`. Mirrors\n * `dispatch_runner.ts`'s internal (non-exported) `toErrorCause` convention: a genuine `Error` (per\n * the cross-realm-safe {@link isError} guard) passes through unchanged; anything else — a string,\n * a plain object, a cross-realm error whose `instanceof Error` is false — is wrapped in a real\n * `Error` whose message is the value's best string form, with the original preserved on `.cause`.\n *\n * Never throws. It runs inside the adapter's last-line-of-defence catch handlers (the `onEvent`\n * rejection handler, the stdout `'data'` listener, the background-shutdown rejection handler), so a\n * throw here would recreate the exact unhandled-rejection / uncaught-exception class it exists to\n * prevent. A hostile thrown value can defeat BOTH `JSON.stringify` and `String` (a `Proxy` with a\n * throwing trap, or an object whose `toJSON` and `toString` both throw) and can even make the\n * `isError` guard itself throw, so each step is guarded and the last resort is a fixed string.\n */\nconst toErrorCause = (value: unknown): Error => {\n try {\n if (isError(value)) return value\n } catch {\n /* a hostile value can throw from the guard's own property reads; treat it as a non-Error */\n }\n let text: string\n try {\n text =\n typeof value === 'string'\n ? value\n : value === undefined\n ? 'undefined'\n : (JSON.stringify(value) ?? String(value))\n } catch {\n try {\n text = String(value)\n } catch {\n text = '[unserialisable thrown value]'\n }\n }\n return new Error(`non-Error thrown while handling a wrapper event: ${text}`, { cause: value })\n}\n\n/**\n * Integrity checksum over `tool`/`args` — matches every other LLM battery's convention\n * (`sha256(canonicalStringify({tool, args}))`, see `ollama/adapter.ts`'s `computeChecksum`), NOT\n * the per-call `requestId`. Identical repeat calls must share this checksum: it feeds\n * `DispatchContext`'s own `#toolCallChecksums` loop-detection counter and cross-bus correlation,\n * neither of which can see a repeat if every call gets a unique value.\n */\nconst computeChecksum = (tool: string, args: unknown): string =>\n sha256(canonicalStringify({ tool, args }))\n\n// ─── outbound tool-result rendering (decision 8) ───────────────────────────────\n\nconst renderMediaListAsOutbound = async (\n mediaList: Media[],\n unsupportedResultMediaPolicy: UnsupportedMediaPolicy\n): Promise<{ content: OutboundContentBlock[]; isError: boolean }> => {\n const content: OutboundContentBlock[] = []\n let anyUnsupported = false\n for (const media of mediaList) {\n if (media.kind === 'image') {\n content.push({ type: 'image', data: await media.asBase64(), mimeType: media.mimeType })\n continue\n }\n // Every non-image modality is unsupported on the outbound MCP wire (only text/image content\n // blocks exist there) — routed through the SAME policy family the inbound direction uses\n // (decision 8), rather than an unconditional hardcoded error.\n if (unsupportedResultMediaPolicy === 'throw') {\n anyUnsupported = true\n content.push({\n type: 'text',\n text: `Unsupported result media modality: ${media.kind} (${media.mimeType})`,\n })\n continue\n }\n const byteLen = await media.byteLength().catch(() => undefined)\n content.push({\n type: 'text',\n text: `[media: ${media.filename}, ${media.mimeType}, ${byteLen ?? 'unknown'} bytes]`,\n })\n }\n return { content, isError: anyUnsupported }\n}\n\nconst renderOutboundResult = async (input: {\n raw: string | Uint8Array | SpooledArtifact | Media | Media[]\n callId: string\n inline: boolean\n spoolStore: SpoolStore\n unsupportedResultMediaPolicy: UnsupportedMediaPolicy\n}): Promise<{ content: OutboundContentBlock[]; isError: boolean }> => {\n const { raw, callId, inline } = input\n\n if (Media.isMedia(raw)) {\n return renderMediaListAsOutbound([raw], input.unsupportedResultMediaPolicy)\n }\n if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n return renderMediaListAsOutbound(raw, input.unsupportedResultMediaPolicy)\n }\n if (looksLikeSpooledArtifact(raw)) {\n const artifact = raw as SpooledArtifact\n if (inline === false) {\n let byteLength = 0\n let lineCount = 0\n try {\n byteLength = await artifact.byteLength()\n } catch {\n byteLength = 0\n }\n try {\n lineCount = await artifact.lineCount()\n } catch {\n lineCount = 0\n }\n const body = renderArtifactHandleBody({ callId, artifact, byteLength, lineCount })\n return { content: [{ type: 'text', text: body }], isError: false }\n }\n const text = await artifact.asString()\n return { content: [{ type: 'text', text }], isError: false }\n }\n if (typeof raw === 'string') {\n return { content: [{ type: 'text', text: raw }], isError: false }\n }\n if (isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n await input.spoolStore.write(callId, raw)\n return {\n content: [{ type: 'text', text: '[binary tool result — see history for details]' }],\n isError: false,\n }\n }\n return { content: [{ type: 'text', text: String(raw) }], isError: false }\n}\n\n// ─── the adapter ────────────────────────────────────────────────────────────\n\n/**\n * Opinionated CLI-harness LLM adapter that drives the Claude Code CLI as a `DispatchExecutorFn`\n * destination.\n *\n * @remarks\n * Construction validates options eagerly via {@link validateOptions} and throws\n * {@link @nhtio/adk/batteries/llm/claude_code_cli!E_INVALID_CLAUDE_CODE_CLI_OPTIONS} on failure\n * (including the POSIX-only platform guard and the `apiKey`/`authToken` XOR check). The returned\n * instance is reusable: call {@link ClaudeCodeCliAdapter.executor} once per `DispatchRunner`\n * configuration.\n */\nexport class ClaudeCodeCliAdapter {\n /** Customary key for per-iteration overrides on `ctx.stash`. */\n public static readonly STASH_KEY = 'claudeCodeCli' as const\n\n readonly #baseline: ClaudeCodeCliAdapterOptions\n\n /**\n * @param options - Constructor-baseline options. Re-validated on every iteration after\n * per-dispatch and per-iteration overrides are layered in.\n * @throws {@link @nhtio/adk/batteries/llm/claude_code_cli!E_INVALID_CLAUDE_CODE_CLI_OPTIONS} when\n * `options` does not satisfy `claudeCodeCliOptionsSchema`.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n }\n\n /**\n * Returns a {@link @nhtio/adk!DispatchExecutorFn} bound to this adapter's baseline plus optional\n * executor-scope overrides.\n */\n executor(overrides?: Partial<ClaudeCodeCliAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = ClaudeCodeCliAdapter\n\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n const localWarn = (msg: string): void => {\n helpers.log.warn({ kind: 'helper-warning', message: msg })\n }\n\n // ── Step 1: merge & validate ──────────────────────────────────────────\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides =\n stashRaw && typeof stashRaw === 'object'\n ? (stashRaw as Partial<ClaudeCodeCliAdapterOptions>)\n : {}\n const merged = validateOptions(mergeOptions(baseline, overrides, stashOverrides))\n\n if (merged.tokenEncoding !== null && merged.contextWindow === undefined) {\n throw new E_INVALID_CLAUDE_CODE_CLI_OPTIONS([\n 'tokenEncoding is non-null but contextWindow is undefined',\n ])\n }\n\n // ── Step 2: resolve helpers ───────────────────────────────────────────\n const resolvedHelpers = resolveHelpers(merged.helpers)\n\n // ── Step 3: resolve execa + wrapper path ──────────────────────────────\n let execaFn: ExecaLike\n try {\n execaFn = await resolveExeca(merged.execa)\n } catch (err) {\n ctx.nack(isError(err) ? err : new Error(String(err)))\n return\n }\n let wrapperPath: string\n try {\n wrapperPath = merged.wrapperPath ?? (await resolveWrapperPathWithFallback())\n } catch (err) {\n ctx.nack(isError(err) ? err : new Error(String(err)))\n return\n }\n const claudeBin = merged.claudeBin ?? 'claude'\n\n // ── Step 5: pre-render inbound tool-call results (for history) ────────\n // Key by primitive identity, not id: repeated vendor/request ids must not cross-wire results.\n const renderedToolCallResults = new Map<ToolCall, string>()\n for (const tc of ctx.turnToolCalls) {\n const rendered = await resolvedHelpers.renderClaudeCodeCliToolCallResult({\n toolCall: tc,\n results: tc.results as\n | Tokenizable\n | SpooledArtifact\n | SpooledArtifact[]\n | Media\n | Media[],\n tool: ctx.tools.get(tc.tool) as Tool | undefined,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn: localWarn,\n })\n renderedToolCallResults.set(tc, rendered)\n }\n\n // ── Step 6: build the -p prompt ────────────────────────────────────────\n const { prompt, reasoningPayloads } = await resolvedHelpers.buildClaudeCodeCliPrompt({\n systemPrompt: ctx.systemPrompt,\n renderCtx: ctx,\n standingInstructions: ctx.standingInstructions,\n memories: ctx.turnMemories,\n retrievables: ctx.turnRetrievables,\n messages: ctx.turnMessages,\n thoughts: ctx.turnThoughts,\n toolCalls: ctx.turnToolCalls,\n tools: ctx.tools,\n renderedToolCallResults,\n bucketOrder: merged.bucketOrder ?? [\n 'standingInstructions',\n 'memories',\n 'retrievables',\n 'timeline',\n ],\n selfIdentity: merged.selfIdentity ?? 'assistant',\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: merged.replayCompatibility ?? [],\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n renderChatCompletionsSystemPrompt: resolvedHelpers.renderChatCompletionsSystemPrompt,\n renderStandingInstructions: resolvedHelpers.renderStandingInstructions,\n renderMemories: resolvedHelpers.renderMemories,\n renderRetrievables: resolvedHelpers.renderRetrievables,\n renderRetrievableSafetyDirective: resolvedHelpers.renderRetrievableSafetyDirective,\n renderFirstPartyRetrievables: resolvedHelpers.renderFirstPartyRetrievables,\n renderThirdPartyPublicRetrievables: resolvedHelpers.renderThirdPartyPublicRetrievables,\n renderThirdPartyPrivateRetrievables: resolvedHelpers.renderThirdPartyPrivateRetrievables,\n renderRetrievableHandleBody: resolvedHelpers.renderRetrievableHandleBody,\n renderClaudeCodeCliTimelineMessage: resolvedHelpers.renderClaudeCodeCliTimelineMessage,\n renderClaudeCodeCliToolCallResult: resolvedHelpers.renderClaudeCodeCliToolCallResult,\n renderThought: resolvedHelpers.renderThought,\n filterThoughts: resolvedHelpers.filterThoughts,\n renderUntrustedContent: resolvedHelpers.renderUntrustedContent,\n renderTrustedContent: resolvedHelpers.renderTrustedContent,\n warn: localWarn,\n })\n\n // A `-p` prompt string has no side channel for an opaque, vendor-specific reasoning payload\n // the way Ollama/OpenAI's JSON request bodies do (`_adk_reasoning_payloads`) — there is\n // nowhere in this wire to forward one. Surface that loss as a diagnostic rather than\n // silently dropping it, matching the honesty standard applied to every other documented v1\n // limitation of this battery (text-only media, subagent text).\n if (reasoningPayloads.length > 0) {\n helpers.log.debug({\n kind: 'reasoning-payload-dropped',\n message: `${reasoningPayloads.length} opaque reasoning payload(s) matched replayCompatibility but have no destination on the Claude Code CLI wire (no side channel exists for a '-p' prompt) and were dropped.`,\n })\n }\n\n // ── Step 7: build the bridged-tools set (excluding disallowedTools) ───\n const disallowed = new Set(merged.disallowedTools ?? [])\n const visibleTools = ctx.tools.visible().filter((t) => !disallowed.has(t.name))\n const bridgedTools: WrapperBridgedTool[] = visibleTools.map((t) => {\n const described = t.describe()\n const inputSchema = resolvedHelpers.descriptionToChatCompletionsJsonSchema(\n described.inputSchema as never\n )\n return {\n name: described.name,\n description: described.description,\n inputSchema:\n inputSchema && Object.keys(inputSchema).length > 0\n ? (inputSchema as Record<string, unknown>)\n : { type: 'object', properties: {} },\n }\n })\n\n // ── Step 8: context window enforcement ────────────────────────────────\n if (merged.tokenEncoding !== null && merged.contextWindow !== undefined) {\n const encoding = merged.tokenEncoding as TokenEncodingId\n // The rendered prompt is the actual `-p` wire value. Measure it directly rather than\n // re-summing its source buckets: renderers add envelopes, provenance, and ordering.\n const promptTokens = await estimateTokensOf(new Tokenizable(prompt), encoding)\n const appendSystemPromptTokens = merged.appendSystemPrompt\n ? await estimateTokensOf(new Tokenizable(merged.appendSystemPrompt), encoding)\n : 0\n\n // Keep source-bucket diagnostics for middleware deciding what to shed. They are not part\n // of the authoritative total above, since their content is already represented by prompt.\n const rawSystemPrompt = await estimateTokensOf(ctx.systemPrompt, encoding)\n let rawStandingInstructions = 0\n for (const value of ctx.standingInstructions)\n rawStandingInstructions += await estimateTokensOf(value, encoding)\n let rawMemories = 0\n for (const value of ctx.turnMemories as Set<Memory>)\n rawMemories += await estimateTokensOf(value.content, encoding)\n let rawRetrievables = 0\n for (const r of ctx.turnRetrievables) {\n rawRetrievables +=\n !r.inline && SpooledArtifact.isSpooledArtifact(r.content) && r.content.hasSizeHints()\n ? r.content.estimateHandleTokens(\n r.id,\n encoding as TokenEncoding,\n resolvedHelpers.renderRetrievableHandleBody\n )\n : await estimateTokensOf(r.content, encoding)\n }\n let rawTimeline = 0\n for (const msg of ctx.turnMessages)\n if (msg.content !== undefined)\n rawTimeline += await estimateTokensOf(msg.content, encoding)\n for (const thought of ctx.turnThoughts)\n rawTimeline += await estimateTokensOf(thought.content, encoding)\n for (const rendered of renderedToolCallResults.values())\n rawTimeline += await estimateTokensOf(new Tokenizable(rendered), encoding)\n // Claude Code receives declarations through MCP, not a wire `tools` array. This stable\n // serialization is an honest floor: JSON declarations plus the CLI-visible names.\n const toolSerialization = `${JSON.stringify(bridgedTools)}|${bridgedTools\n .map((t) => `mcp__adk_bridge__${t.name}`)\n .join(',')}`\n const tools = await estimateTokensOf(new Tokenizable(toolSerialization), encoding)\n const perBucket = {\n prompt: promptTokens,\n appendSystemPrompt: appendSystemPromptTokens,\n tools,\n raw: {\n systemPrompt: rawSystemPrompt,\n standingInstructions: rawStandingInstructions,\n memories: rawMemories,\n retrievables: rawRetrievables,\n timeline: rawTimeline,\n },\n }\n const total = promptTokens + appendSystemPromptTokens + tools\n helpers.log.debug({\n kind: 'context-window-usage',\n message: `Context window usage: ${total}/${merged.contextWindow} tokens`,\n payload: { total, limit: merged.contextWindow, encoding, perBucket },\n })\n if (total > merged.contextWindow)\n throw new E_CLAUDE_CODE_CLI_CONTEXT_OVERFLOW([\n total,\n merged.contextWindow,\n encoding,\n JSON.stringify(perBucket),\n ])\n }\n\n // ── Step 9: spawn the wrapper ──────────────────────────────────────────\n const spoolStore = merged.spoolStore ?? new InMemorySpoolStore()\n // `wrapperExecPath` lets a consumer override the executable entirely (e.g. a Node binary\n // they bundle alongside their Electron app specifically to run this wrapper, the only\n // evidence-backed mitigation for an Electron host with the `RunAsNode` Fuse disabled — see\n // `autoDetectElectronHost`'s own doc comment in types.ts for the measured matrix behind that\n // claim). Left unset, this defaults to `process.execPath`, today's plain-Node-host behavior,\n // completely unchanged.\n const wrapperExecPath = merged.wrapperExecPath ?? process.execPath\n // Issue #42's part C: `process.versions.electron` is set only inside an Electron process\n // (main OR renderer with Node integration) — never in a plain Node host, so this default is\n // inert everywhere else. When true, `ELECTRON_RUN_AS_NODE: '1'` is merged into the spawned\n // wrapper's env: this is Electron's own documented mechanism for making a spawned copy of\n // the Electron binary run as plain Node instead of booting a second full Electron app with\n // the wrapper script as its main script (the bug this env var is applied here specifically\n // to fix). `wrapperEnv` (applied AFTER this default, so it always wins on a key collision)\n // is the escape hatch for a consumer who wants to force it off (`{ ELECTRON_RUN_AS_NODE:\n // undefined }`) or who is spawning a `wrapperExecPath` that doesn't need it at all.\n const isElectronHost = process.versions.electron !== undefined\n const wantsElectronRunAsNode = (merged.autoDetectElectronHost ?? true) && isElectronHost\n // issue #42 round-2 defect #3: the marker below must reflect the env value the wrapper will\n // ACTUALLY observe once `merged.wrapperEnv` (spread last, so it always wins on a key\n // collision) is applied — not `wantsElectronRunAsNode` alone. Previously the marker was\n // decided purely from `wantsElectronRunAsNode` and lived under a *different* key than\n // `ELECTRON_RUN_AS_NODE` itself, so a consumer opting OUT via\n // `wrapperEnv: { ELECTRON_RUN_AS_NODE: undefined }` removed our injected value but never\n // touched the marker — the wrapper still stripped the grandchild's own ambient\n // `ELECTRON_RUN_AS_NODE` even though the adapter no longer injected anything. A consumer who\n // explicitly supplies their own `ELECTRON_RUN_AS_NODE` key in `wrapperEnv` — to turn it off,\n // to force it on for their own unrelated reason, or anything else — has taken ownership of\n // that variable, so the marker (which exists ONLY to let the wrapper distinguish \"the\n // adapter's own injection\" from \"the consumer's/host's ambient environment\") must never be\n // set in that case, regardless of what value they chose.\n const consumerOverridesElectronRunAsNode =\n merged.wrapperEnv !== undefined &&\n Object.prototype.hasOwnProperty.call(merged.wrapperEnv, 'ELECTRON_RUN_AS_NODE')\n const weInjectedElectronRunAsNode =\n wantsElectronRunAsNode && !consumerOverridesElectronRunAsNode\n const wrapperEnv: Record<string, string | undefined> | undefined =\n wantsElectronRunAsNode || merged.wrapperEnv !== undefined\n ? {\n ...(wantsElectronRunAsNode ? { ELECTRON_RUN_AS_NODE: '1' } : {}),\n ...(weInjectedElectronRunAsNode\n ? {\n // issue #42 defect #3: `buildClaudeEnv()` in the wrapper starts from a full\n // copy of ITS OWN `process.env` — which now includes the line above — and\n // forwards nearly all of it, unmodified, to the `claude` grandchild. `claude`\n // itself could be a Node/Electron-based binary, and this stray var could\n // unexpectedly change ITS behavior too, which this auto-detect option was\n // never meant to affect. This private marker (stripped by the wrapper itself,\n // see `buildClaudeEnv`, and never forwarded any further) tells the wrapper\n // \"I am the one who injected ELECTRON_RUN_AS_NODE, not the consumer's own\n // ambient environment\" — so the wrapper can distinguish the two and only strip\n // its OWN injection, leaving an ambient `ELECTRON_RUN_AS_NODE` the consumer set\n // themselves (e.g. for an unrelated reason, predating this option entirely)\n // untouched, preserving today's forwarding behavior for that case. Set ONLY\n // when the final env's `ELECTRON_RUN_AS_NODE` is truly ours (see\n // `weInjectedElectronRunAsNode` above) — never when the consumer's own\n // `wrapperEnv` takes ownership of that key, even to the same `'1'` value.\n ADK_CLAUDE_CODE_CLI_STRIP_RUN_AS_NODE_FROM_GRANDCHILD: '1',\n }\n : {}),\n ...merged.wrapperEnv,\n }\n : undefined\n let child: ReturnType<ExecaLike>\n try {\n child = execaFn(\n wrapperExecPath,\n [wrapperPath],\n wrapperEnv !== undefined ? { cleanup: true, env: wrapperEnv } : { cleanup: true }\n )\n } catch (err) {\n ctx.nack(\n new E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR([isError(err) ? err.message : String(err)])\n )\n return\n }\n\n const startupTimeoutMs = merged.startupTimeoutMs ?? 45_000\n const streamIdleTimeoutMs = merged.streamIdleTimeoutMs ?? 60_000\n const disposeGraceMs = merged.disposeGraceMs ?? 2_000\n\n let sawReady = false\n let sawInit = false\n // Set SYNCHRONOUSLY the instant a terminal `result`/`error` event is observed — before any\n // `await` (e.g. `sealCurrentMessage()`) runs. The wrapper closing stdout immediately after\n // writing its terminal line is a real, observed race: without this flag, `stdout`'s `'end'`\n // handler can fire and call `settleOnce` (nacking the turn as an unexpected exit) while the\n // `result` handler is still awaiting `sealCurrentMessage()`, even though `settleOnce` itself\n // is idempotent-guarded — the guard only helps once one of the two paths has actually run.\n let sawTerminalEvent = false\n let startupTimer: ReturnType<typeof setTimeout> | undefined\n let idleTimer: ReturnType<typeof setTimeout> | undefined\n let settled = false\n // Set once the outer `await new Promise<void>(...)` below is constructed. The startup/idle\n // timers are armed BEFORE that promise exists, so their settleOnce() callbacks must resolve\n // it through this indirection rather than a `finish` closure defined only inside it — without\n // this, a startup or stream-idle timeout would settle ctx (nack) but never resolve the outer\n // promise, hanging the executor forever.\n let resolveIteration: (() => void) | undefined\n // A fresh wrapper spawns per dispatch iteration, but `helpers`/`ctx` (and their `messageStreams`/\n // `thoughtStreams` completed-id bookkeeping) live for the WHOLE dispatch — so the wrapper's own\n // ids (unique only WITHIN one spawn, e.g. \"message-0\") must be namespaced per iteration before\n // they reach `helpers.reportMessage`/`reportThought` or `ctx.storeMessage`, or a second iteration\n // reusing the same wrapper-local id collides with the first's already-sealed stream (issue #43,\n // fix A). One nonce per executor invocation, mirroring `anthropic_messages`'s\n // `dispatchStreamId`/`responseId` convention.\n const dispatchNonce = uuidv6()\n // Keyed by the (already-namespaced) ADK message id, not the wrapper-local one — a single spawn\n // can legitimately emit more than one DISTINCT assistant message (text -> tool_use -> more\n // text), each needing its own accumulator and seal-once guard; a single flat pair of variables\n // would silently drop every message after the first, or concatenate their text together\n // (issue #43, fix C).\n const messageState = new Map<string, { buffer: string; sealed: boolean }>()\n // Count of `tool_call_request`s currently executing (accepted but not yet answered with a\n // `tool_call_response`). `streamIdleTimeoutMs` measures MODEL-stream idleness — the wrapper\n // waiting on Claude — not ADK tool-execution latency; a real tool (a web search, a sandboxed\n // run) can legitimately take longer than a short idle timeout with zero model-stream activity\n // in between, which would otherwise be falsely nacked as `STREAM_STALLED`. While this is\n // positive, the idle timer is suspended entirely; it re-arms only once EVERY in-flight call\n // has answered, using a counter (not a boolean) because the wrapper's MCP bridge hands out a\n // fresh id per JSON-RPC CallTool request and can in principle have more than one call in\n // flight before the first is answered. This intentionally does NOT add a separate\n // tool-execution timeout — that is a different feature, out of scope here.\n let inFlightToolCalls = 0\n // issue #42 defect #1: the `claude` grandchild's pid (== its own process group id, since the\n // wrapper spawns it with `detached: true`), reported via `grandchild_spawned`. Undefined\n // until that event arrives (or if talking to a wrapper build that predates it) — the\n // SIGKILL escalation below simply skips the group-kill in that case, unchanged from before.\n let grandchildPid: number | undefined\n\n const clearStartupTimer = (): void => {\n if (startupTimer) clearTimeout(startupTimer)\n startupTimer = undefined\n }\n const clearIdleTimer = (): void => {\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = undefined\n }\n const maybeClearStartupTimer = (): void => {\n if (sawReady && sawInit) clearStartupTimer()\n }\n\n const writeCommand = (command: WrapperCommand): void => {\n try {\n child.stdin?.write(encodeWrapperCommand(command))\n } catch {\n /* the wrapper's stdin may already be gone */\n }\n }\n\n const gracefulShutdown = async (): Promise<void> => {\n writeCommand({ type: 'shutdown' })\n const waitForChildExit = (timeoutMs: number): Promise<void> =>\n new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, timeoutMs)\n // This inner chain is its own, independently-floating promise (the surrounding `new\n // Promise<void>` executor above never calls `reject`, so this helper's own returned\n // promise cannot reject from this step) — `.finally()` runs its callback on EITHER\n // outcome but still re-raises the original rejection on its OWN returned promise\n // afterwards, and that returned promise is not otherwise referenced. If `child` rejects\n // (e.g. an execa spawn failure), this becomes an unhandled rejection entirely on its\n // own, regardless of whether callers attach a `.catch()` — the `.catch` below is what\n // actually closes that off.\n void Promise.resolve(child)\n .finally(() => {\n clearTimeout(timer)\n resolve()\n })\n .catch(() => {\n /* already handled above by resolving the outer promise; nothing else to do with a\n rejected child here */\n })\n })\n await waitForChildExit(disposeGraceMs)\n try {\n child.kill('SIGTERM')\n } catch {\n /* already exited */\n }\n // Escalate to SIGKILL if the wrapper is still alive after SIGTERM: a wrapper wedged deeply\n // enough to ignore its own `shutdown` command AND its own 5-second backstop timer (see\n // wrapper.ts) — e.g. the OS itself is stalled, or the process is stuck in an\n // uninterruptible syscall — must not be left running indefinitely just because this\n // adapter only ever asked nicely once. Re-uses the SAME `disposeGraceMs` window as the\n // first wait (this is a fixed, bounded, best-effort reap either way, not a precisely\n // tuned budget), so the total worst-case background teardown time is `2 * disposeGraceMs`\n // — still entirely off the executor's own settlement path (see the `result`/`error`\n // branches, both of which call `shutdownInBackground()` without awaiting it).\n await waitForChildExit(disposeGraceMs)\n try {\n child.kill('SIGKILL')\n } catch {\n /* already exited */\n }\n // issue #42 round-2 defect #1: SIGKILL cannot be caught, so if the wrapper above is the\n // one that gets killed, its own `process.on('exit', () => killGrandchildGroup(...))`\n // cleanup can never run — the `claude` grandchild's entire detached process group would\n // otherwise be orphaned. Kill that group directly, in addition to (not instead of) the\n // wrapper itself — but ONLY when there is still positive evidence the group is genuinely\n // the grandchild's own:\n //\n // 1. `grandchildPid` must still be set. It is cleared the instant a `grandchild_exited`\n // event arrives (see that branch above), so once the grandchild has actually exited,\n // this stays `undefined` and no signal is ever sent — a bare \"the group already\n // exited\" fact is not enough on its own to trust a remembered pid/pgid forever: once\n // every process in a group has exited, POSIX allows the OS to reuse that exact same\n // numeric pgid for a LATER, entirely unrelated process group, and signalling a stale\n // pid we merely haven't heard about yet would SIGKILL that unrelated group instead.\n // 2. The wrapper must not have exited NORMALLY (`exitCode === null`). A normal exit means\n // its own `process.on('exit', () => killGrandchildGroup('SIGTERM'))` handler\n // (wrapper.ts) already ran, so signalling again would be redundant at best and a\n // SIGKILL against a since-reused pgid at worst. Note this is NOT a liveness test. The\n // wrapper traps SIGTERM/SIGINT and leaves via `process.exit()`, so those end with a\n // numeric `exitCode`; only an UNTRAPPED signal — above all the `SIGKILL` sent just above\n // — leaves `exitCode === null` (the signal is in `signalCode`). That is deliberate: such\n // a wrapper never ran its exit handler, so its group is exactly the one that would be\n // orphaned, and this is the one place left to reap it.\n //\n // Residual, ACKNOWLEDGED gaps (neither can be closed from here without a way to verify\n // process-group ownership, which POSIX does not portably offer):\n //\n // - Unknown pid. If this runs before `grandchild_spawned` arrives, `grandchildPid` is\n // `undefined` and nothing is signalled. That does NOT mean `claude` hasn't spawned: the\n // wrapper may have spawned it and not yet written, or we not yet read, the event. The\n // wrapper's own `exit` handler still reaps the group on every non-SIGKILL path, so the\n // only uncovered case is a wrapper SIGKILLed between spawning `claude` and its event\n // reaching us — which can orphan that group.\n // - Stale pgid. A wrapper that is SIGSTOPped (or otherwise wedged) cannot report\n // `grandchild_exited`, so if the grandchild group has already exited and the OS has\n // reused its number within the ~`2 * disposeGraceMs` escalation window, this signals an\n // unrelated group. PID/pgid reuse that fast is unlikely under ordinary process churn,\n // but it is not ruled out.\n if (typeof grandchildPid === 'number' && child.exitCode === null) {\n try {\n process.kill(-grandchildPid, 'SIGKILL')\n } catch {\n /* group already gone, or platform doesn't support negative-pid signalling */\n }\n }\n }\n\n // Fire-and-forget `gracefulShutdown()` at every non-awaited call site below: it is async and\n // CAN reject (e.g. the `child` promise it awaits inside a `.finally` can itself reject, and\n // `child.kill('SIGTERM')`'s own try/catch only guards the synchronous call, not any of the\n // awaited steps before it) — a bare `void gracefulShutdown()` leaves that rejection with no\n // attached handler, becoming an unhandled promise rejection that crashes the host process by\n // default (Node >= 15). That is exactly the class of bug issue #39 is about; best-effort\n // teardown must never surface as one. `settleOnce`'s own resolution must also never wait on\n // this — shutdown is a courtesy to the wrapper process, not a precondition for the executor\n // settling.\n const shutdownInBackground = (): void => {\n gracefulShutdown().catch((err: unknown) => {\n const cause = toErrorCause(err)\n try {\n helpers.log.debug({\n kind: 'graceful-shutdown-rejected',\n message: `Best-effort wrapper shutdown failed; ignoring (the turn has already settled or is settling independently): ${cause.message}`,\n payload: { cause: cause.message },\n })\n } catch {\n /* logging itself must never escape a fire-and-forget cleanup path */\n }\n })\n }\n\n const abortListener = (): void => {\n shutdownInBackground()\n }\n ctx.abortSignal.addEventListener('abort', abortListener, { once: true })\n const detachAbortListener = (): void =>\n ctx.abortSignal.removeEventListener('abort', abortListener)\n\n // `fn` used to run with no try/catch: a throw inside a settlement callback (e.g.\n // `helpers.reportGenerationStats(...)` or `ctx.ack()`/`ctx.nack()` throwing\n // `E_LLM_EXECUTION_ALREADY_SIGNALLED` on a lost race) propagated out of `settleOnce` itself\n // AFTER `settled` had already flipped true. EVERY settlement call site (the startup/idle\n // timers, the `result` branch, the `error` branch, the Fix-B `onEvent(...).catch(...)`\n // handler, the stdout `'end'` handler, the wrapper-process `.then/.catch`) resolves the\n // iteration promise from WITHIN its own `fn` — as of issue #42's part B, this now includes\n // the `result` branch too (it used to call `finish()` AFTER `settleOnce(...)` returned,\n // deliberately awaiting the wrapper's real OS exit first; it no longer waits on that at all —\n // see the long comment at that call site for why). A throw inside `fn` means that resolving\n // code never ran, and nothing else in the file resolves the promise, so the executor hangs\n // forever without the catch below.\n //\n // The catch below guarantees resolution ONLY on that failure path — nacking (unless something\n // already signalled) and force-resolving the iteration promise — without changing the timing\n // of the NORMAL, non-throwing path for any caller.\n //\n // Every step inside the `catch` is individually try/catch-guarded, and `resolveIteration?.()`\n // runs in a `finally` gated on a local `threw` flag — NOT sequentially after the log/nack/\n // shutdown calls — because review round 2 found that the original version called\n // `helpers.log.error(...)` (itself capable of throwing, e.g. a caller-supplied logger) BEFORE\n // `resolveIteration?.()`: if the logger threw, resolution was skipped entirely even though\n // `settled` was already `true`, so every LATER `settleOnce` call anywhere in the file becomes\n // a silent no-op (its own `if (settled) return` guard fires first) — hanging the executor with\n // no remaining path to resolve it, and the throw itself would escape whichever caller invoked\n // `settleOnce` (e.g. the stdout `'data'` listener's own catch block, becoming an uncaught\n // exception). Guaranteeing `resolveIteration?.()` via `finally` makes `settleOnce` itself\n // incapable of throwing or skipping resolution, regardless of which best-effort step fails.\n const settleOnce = (fn: () => void): void => {\n if (settled) return\n settled = true\n clearStartupTimer()\n clearIdleTimer()\n detachAbortListener()\n let threw = false\n try {\n fn()\n } catch (err) {\n threw = true\n try {\n const cause = toErrorCause(err)\n try {\n helpers.log.error({\n kind: 'settlement-handler-threw',\n message: `A dispatch settlement handler threw while finalising the turn; nacking (if not already signalled) instead of leaving the executor hung: ${cause.message}`,\n payload: { cause: cause.message },\n })\n } catch {\n /* a throwing logger must not itself prevent nacking/resolving below */\n }\n // `ctx.ack()`/`ctx.nack()` are single-shot and throw `E_LLM_EXECUTION_ALREADY_SIGNALLED`\n // on a second call — `fn` may have already signalled successfully before a LATER\n // statement in the same callback threw (e.g. `reportGenerationStats` throwing before\n // `ctx.ack()` runs is safe to nack; `ctx.ack()` itself throwing means it was already\n // signalled by a race, and nacking again would itself throw). Only nack if nothing has\n // signalled yet, and never let a lost race here escape as a second thrown error.\n if (!ctx.isSignalled) {\n try {\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_ERROR([cause.message], { cause }))\n } catch {\n /* lost a race with a concurrent signal between the check above and this call */\n }\n }\n } catch {\n /* toErrorCause itself is not expected to throw, but this is the last line of defence */\n }\n } finally {\n if (threw) {\n // Best-effort teardown; never lets a rejection or a synchronous throw from starting it\n // stop resolution below.\n try {\n shutdownInBackground()\n } catch {\n /* starting shutdown must never prevent forced resolution */\n }\n // `fn` threw partway through, so whatever branch called `settleOnce` never reached its\n // own `resolveIteration?.()`/`finish()` call (whether that call lived inside `fn` or,\n // like the `result` branch, was deferred until after `settleOnce` returned) — force it\n // here, unconditionally, regardless of what failed above. Calling an already-resolved\n // `resolve()` again is a safe no-op. The NORMAL (non-throwing) path is untouched: this\n // branch only runs when `fn` threw, so the `result` branch's deliberate \"resolve only\n // after awaiting the wrapper's exit\" timing is unaffected when `fn` succeeds.\n try {\n resolveIteration?.()\n } catch {\n /* resolveIteration is a bare Promise executor's resolve(); it cannot throw, but this\n call must never be what makes settleOnce itself throw */\n }\n }\n }\n }\n\n startupTimer = setTimeout(() => {\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STARTUP_TIMEOUT([startupTimeoutMs]))\n })\n }, startupTimeoutMs)\n\n const armIdleTimer = (): void => {\n if (!sawReady || !sawInit) return\n // Suspended while any ADK tool call is executing — see `inFlightToolCalls`. Re-armed by\n // `handleToolCallRequest`'s own completion path once the counter returns to zero.\n if (inFlightToolCalls > 0) return\n clearIdleTimer()\n idleTimer = setTimeout(() => {\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_STALLED([streamIdleTimeoutMs]))\n })\n }, streamIdleTimeoutMs)\n }\n\n // Seals ONE message by its (already-namespaced) ADK id. Every distinct message this iteration\n // produced gets its own `messageState` entry, so calling this once per `event.isComplete`\n // (one per message) correctly stores each of them, rather than only ever the first (issue\n // #43, fix C).\n const sealMessage = async (id: string | undefined): Promise<void> => {\n if (id === undefined) return\n const entry = messageState.get(id)\n if (entry === undefined || entry.sealed) return\n entry.sealed = true\n await ctx.storeMessage(\n new Message({\n id,\n role: 'assistant',\n content: entry.buffer,\n identity: merged.selfIdentity ?? 'assistant',\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n // The `result`-handler's defensive call site below used to seal only `currentMessageId` — the\n // single most-recently-seen message. That silently dropped any EARLIER message that was still\n // unsealed when `result` arrived (e.g. a spawn that emits two distinct messages before the\n // wrapper's `result` line, where the first message's own `isComplete` seal path was, for\n // whatever reason, never reached). Iterate every entry in `messageState` instead — Map\n // iteration order is insertion order in JS, so this seals any still-open messages in the same\n // order they were first seen — rather than defaulting to only the last one (issue #43,\n // verification-pass LOW finding against f3d7fde).\n const sealCurrentMessage = async (): Promise<void> => {\n for (const id of messageState.keys()) {\n await sealMessage(id)\n }\n }\n\n const handleToolCallRequest = async (\n requestId: string,\n toolName: string,\n rawArgs: unknown\n ): Promise<void> => {\n const tool = ctx.tools.get(toolName)\n if (!tool) {\n writeCommand({\n type: 'tool_call_response',\n requestId,\n results: {\n content: [{ type: 'text', text: `Tool not found: ${toolName}` }],\n isError: true,\n },\n })\n return\n }\n // MCP's own JSON-RPC CallTool wire always sends `arguments` as an object; a non-object\n // here would indicate a malformed request from the bridge, not a legitimate call — defend\n // the same way the Ollama battery does for its own non-object case.\n const args: string | Record<string, unknown> = isObject(rawArgs) ? rawArgs : {}\n // Rename the wrapper's per-spawn `requestId` into a turn-unique ADK id BEFORE it touches\n // any internal bookkeeping (reportToolCall/ToolCall/spoolStore/renderOutboundResult) —\n // every wrapper spawn resets its own counter to \"0\" (see mcp_bridge.ts), so a\n // multi-iteration dispatch would otherwise hand the SAME id to `ctx.storeToolCall`/\n // `helpers.reportToolCall` twice and collide with the first (already-complete) call. The\n // literal wrapper `requestId` is preserved untouched for both `tool_call_response`\n // `writeCommand` calls below — the bridge correlates those by ITS OWN id, not this one.\n const callId = (merged.toolCallIdFilter ?? deCollideToolCallIds)(requestId, ctx)\n helpers.reportToolCall(callId, { tool: tool.name, args })\n const isArtifactTool = ArtifactTool.isArtifactTool(tool)\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let toolHadError = false\n try {\n const raw = await tool.executor(ctx)(args)\n if (isArtifactTool) {\n if (Tokenizable.isTokenizable(raw)) {\n results = raw\n } else if (typeof raw === 'string') {\n results = new Tokenizable(raw)\n } else {\n throw new Error(\n `ArtifactTool \"${tool.name}\" returned a non-string/non-Tokenizable value`\n )\n }\n } else if (Media.isMedia(raw)) {\n results = raw\n } else if (Array.isArray(raw) && raw.length > 0 && raw.every((m) => Media.isMedia(m))) {\n results = raw as Media[]\n } else if (looksLikeSpooledArtifact(raw)) {\n results = raw as SpooledArtifact\n } else if (typeof raw === 'string' || isInstanceOf(raw, 'Uint8Array', Uint8Array)) {\n const reader = await spoolStore.write(callId, raw)\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n } else {\n const reader = await spoolStore.write(callId, String(raw))\n const ArtifactCtor = (tool as Tool).artifactConstructor?.() ?? SpooledArtifact\n results = new ArtifactCtor(reader)\n }\n } catch (err) {\n toolHadError = true\n results = new Tokenizable(isError(err) ? err.message : String(err))\n }\n helpers.reportToolCall(callId, { results, isError: toolHadError, isComplete: true })\n const completedAt = nowIso()\n await ctx.storeToolCall(\n new ToolCall({\n id: callId,\n tool: tool.name,\n args,\n checksum: computeChecksum(tool.name, args),\n isComplete: true,\n isError: toolHadError,\n results,\n fromArtifactTool: isArtifactTool,\n inline: isArtifactTool,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n\n let rendered: { content: OutboundContentBlock[]; isError: boolean }\n try {\n rendered = await renderOutboundResult({\n raw: results as string | Uint8Array | SpooledArtifact | Media | Media[],\n callId,\n inline: isArtifactTool,\n spoolStore,\n unsupportedResultMediaPolicy:\n merged.unsupportedResultMediaPolicy ?? merged.unsupportedMediaPolicy ?? 'throw',\n })\n } catch (err) {\n rendered = {\n content: [{ type: 'text', text: isError(err) ? err.message : String(err) }],\n isError: true,\n }\n }\n writeCommand({\n type: 'tool_call_response',\n requestId,\n results: { content: rendered.content, isError: toolHadError || rendered.isError },\n })\n }\n\n await new Promise<void>((resolve) => {\n const finish = (): void => resolve()\n resolveIteration = finish\n\n const onEvent = async (event: WrapperEvent): Promise<void> => {\n if (event.type === 'ready') {\n sawReady = true\n maybeClearStartupTimer()\n const runCommand: WrapperCommand = {\n type: 'run',\n prompt,\n appendSystemPrompt: merged.appendSystemPrompt,\n model: merged.model,\n cwd: merged.cwd,\n addDir: merged.addDir,\n allowedTools: bridgedTools.map((t) => t.name),\n maxBudgetUsd: merged.maxBudgetUsd,\n fallbackModel: merged.fallbackModel,\n auth: {\n apiKey: merged.apiKey,\n authToken: merged.authToken,\n baseUrl: merged.baseURL,\n },\n disableTelemetry: merged.disableTelemetry,\n disableErrorReporting: merged.disableErrorReporting,\n disableNonessentialTraffic: merged.disableNonessentialTraffic,\n mcpToolIdleTimeoutMs: merged.mcpToolIdleTimeoutMs,\n claudeBin,\n forwardSubagentText: merged.forwardSubagentText,\n unsupportedResultMediaPolicy: String(\n merged.unsupportedResultMediaPolicy ?? merged.unsupportedMediaPolicy ?? 'throw'\n ),\n bridgedTools,\n extraArgs: merged.extraArgs,\n }\n writeCommand(runCommand)\n // No `armIdleTimer()` call here: its own `sawReady && sawInit` gate always returns\n // immediately at this point, since `init` (per the wrapper protocol) always arrives\n // strictly after `ready` — verified by the full existing test suite passing unchanged\n // with this call removed. The `init` branch below is what actually starts the clock.\n return\n }\n if (event.type === 'grandchild_spawned') {\n // issue #42 defect #1: capture the grandchild's pid/pgid for the SIGKILL-escalation\n // path in `gracefulShutdown()` above. Additive event — a wrapper build that predates\n // it simply never sends this, and `grandchildPid` just stays undefined.\n grandchildPid = event.pid\n return\n }\n if (event.type === 'grandchild_exited') {\n // issue #42 round-2 defect #1: the grandchild is gone — clear the cached pid/pgid so\n // `gracefulShutdown()`'s escalation never signals it again. Once a process group's\n // members have all exited, the OS is free to reuse that same numeric pgid for an\n // entirely unrelated future process group; without this, a `grandchild_spawned` seen\n // early in a long-lived wrapper session could still be \"remembered\" and SIGKILLed long\n // after it stopped meaning anything.\n grandchildPid = undefined\n return\n }\n if (event.type === 'init') {\n sawInit = true\n maybeClearStartupTimer()\n helpers.log.info({\n kind: 'claude-init',\n message: 'Claude Code CLI initialized.',\n payload: event as unknown as Record<string, unknown>,\n })\n if (event.mcpServerErrors && event.mcpServerErrors.length > 0) {\n settleOnce(() => {\n finish()\n shutdownInBackground()\n ctx.nack(\n new E_CLAUDE_CODE_CLI_MCP_BRIDGE_STARTUP_FAILED([\n event.mcpServerErrors!.join(', '),\n ])\n )\n })\n return\n }\n // Genuine progress: the handshake completed cleanly, so this is what actually starts\n // the stream-idle clock (armIdleTimer's own `sawReady && sawInit` gate makes every\n // earlier call, e.g. the one in the `ready` branch above, a no-op) — NOT merely \"a\n // stdout chunk arrived\" (see the `'data'` listener below for why that distinction\n // matters).\n armIdleTimer()\n return\n }\n if (event.type === 'retry') {\n // Deliberately does NOT re-arm the idle timer. This is a diagnostic passthrough of\n // Claude's own `system/api_retry` line, not evidence that the model is making\n // progress — it fires precisely WHILE the model is stalled waiting on a retryable\n // upstream error. Under exponential backoff, retries commonly land well under\n // `streamIdleTimeoutMs` apart (e.g. 1s/2s/4s/8s/16s/32s), so treating them as\n // idle-resetting activity (as an unconditional per-chunk re-arm would) lets a\n // sustained retry storm suppress the stall timeout indefinitely. Issue #39 itself does\n // not establish what actually caused its \"dispatch hangs for 11+ minutes despite a 60s\n // streamIdleTimeoutMs\" report — this is a PLAUSIBLE mechanism, not a confirmed root\n // cause: `wrapper.ts` genuinely emits `retry` (api_retry passthrough, ~L369) and `log`\n // (e.g. `malformed-command` ~L275, `duplicate-run-command` ~L253,\n // malformed-stream-json inside `dispatchReader` ~L331) on the SAME stdout stream that\n // carries progress events, with no periodic heartbeat gating their cadence, so the\n // shape of the bug is real and reproducible (see the fix-C test below) — it is fixed\n // for THIS scenario regardless of whether it was the exact mechanism behind the\n // original report.\n helpers.log.warn({\n kind: 'claude-retry',\n message: `Claude API retry, attempt ${event.attempt}`,\n payload: event as unknown as Record<string, unknown>,\n })\n return\n }\n if (event.type === 'message_delta') {\n // Namespace the wrapper's per-spawn-local id (unique only WITHIN this spawn, e.g.\n // \"message-0\"/\"message-1\") with this iteration's nonce, so it is also unique ACROSS the\n // other iterations sharing this same `helpers`/`ctx` (issue #43, fix A) — the wrapper's\n // own reset-per-message counter (fix B, wrapper.ts) guarantees distinct wrapper-local ids\n // within one spawn; this mapping is what makes them turn-unique too.\n const id = `${dispatchNonce}:message:${event.id}`\n const entry = messageState.get(id) ?? { buffer: '', sealed: false }\n entry.buffer += event.delta\n messageState.set(id, entry)\n helpers.reportMessage(id, event.delta, { isComplete: event.isComplete })\n if (event.isComplete) {\n await sealMessage(id)\n }\n armIdleTimer()\n return\n }\n if (event.type === 'thought_delta') {\n // Same namespacing rationale as `message_delta` above, applied defensively — no live\n // wrapper code path emits `thought_delta` today (see wrapper.ts), but the wire protocol\n // and this reporting branch both support it, and an id collision here would hit the\n // exact same core stream-completion guard as messages do.\n const id = `${dispatchNonce}:thought:${event.id}`\n helpers.reportThought(id, event.delta, { isComplete: event.isComplete })\n armIdleTimer()\n return\n }\n if (event.type === 'tool_call_request') {\n // Suspend the model-stream idle clock for the duration of ADK tool EXECUTION, not just\n // the round trip's arrival/departure: `streamIdleTimeoutMs` exists to catch the wrapper\n // going silent while waiting on Claude, and a slow-but-healthy tool (a web search, a\n // sandboxed run) produces no wrapper stdout of its own while it runs. Track with a\n // counter, not a boolean, since more than one `tool_call_request` can be in flight\n // before the first is answered (the MCP bridge assigns each JSON-RPC CallTool its own\n // id independently of completion order).\n inFlightToolCalls += 1\n clearIdleTimer()\n try {\n await handleToolCallRequest(event.requestId, event.tool, event.args)\n } finally {\n inFlightToolCalls = Math.max(0, inFlightToolCalls - 1)\n }\n // Re-arm on completion, not arrival — a genuine round trip (request handled, response\n // written back to the wrapper's stdin) is progress. `armIdleTimer`'s own\n // `inFlightToolCalls > 0` gate means this is a no-op while any OTHER concurrent call is\n // still executing; the timer resumes only once the last one has answered.\n armIdleTimer()\n return\n }\n if (event.type === 'result') {\n sawTerminalEvent = true\n await sealCurrentMessage()\n settleOnce(() => {\n // `finish()` (resolving the executor's iteration promise) and `shutdownInBackground()`\n // (reaping the wrapper process) run FIRST, before the ack/nack branching below — same\n // ordering the `error` branch and both timers already use. This is issue #42's part B\n // fix: the wrapper, not the adapter, initiates its own shutdown on this path (Decision\n // D step 5) — a terminal NDJSON line proves the wrapper WROTE the result, not that the\n // OS process has actually exited yet — but the OLD code awaited `Promise.resolve(child)`\n // HERE, inside the settlement path, before ever calling `finish()`. That blocked the\n // executor's own resolution on the wrapper's (and its `claude` grandchild's) full OS\n // teardown, which is exactly backwards for a host whose wrapper legitimately takes a\n // while to exit (a large MCP bridge teardown, a slow grandchild) but whose CALLER has\n // no reason to wait on that: the turn is already fully decided (the terminal `result`\n // line IS the answer) the moment it arrives. Resolving immediately and reaping in the\n // background — exactly like the startup/idle timeouts and the `error` branch already\n // do — removes that needless latency and, more importantly, removes a dependency the\n // executor's settlement previously had on the wrapper's OWN internal shutdown sequence\n // (including the `waitForPendingWrites()` flush barrier issue #42's part A adds there)\n // ever completing at all: if that hangs for any reason, this branch no longer hangs\n // with it — `gracefulShutdown()`'s own bounded `disposeGraceMs` wait plus SIGTERM\n // escalation (reused verbatim via `shutdownInBackground()`, not reinvented) is what\n // reaps a slow-to-exit wrapper, entirely off the executor's own critical path.\n finish()\n shutdownInBackground()\n if (event.isError && event.subtype !== 'error_max_turns') {\n ctx.nack(\n new E_CLAUDE_CODE_CLI_TURN_FAILED([\n event.stopReason ?? 'unknown',\n event.resultText ?? '',\n ])\n )\n return\n }\n if (event.isError && event.subtype === 'error_max_turns') {\n helpers.log.debug({\n kind: 'claude-max-turns-reached',\n message:\n 'Claude reached the fixed single-turn limit; treating it as normal completion.',\n payload: { subtype: event.subtype },\n })\n }\n helpers.reportGenerationStats({\n provider: 'claude_code_cli',\n model: merged.model,\n raw: event.raw as Record<string, unknown> | undefined,\n })\n if (merged.autoAck) ctx.ack()\n })\n // No `await Promise.resolve(child)` here any more (see the long comment inside\n // `settleOnce`'s callback above for why) — `finish()` already ran synchronously inside\n // it. The `child.stdout.on('end', ...)` handler and the `Promise.resolve(child)\n // .then/.catch` handler at the bottom of this function both still fire after this\n // point (the child has not necessarily exited yet) — both are already guarded by\n // `sawTerminalEvent` (set unconditionally at the top of this branch, synchronously,\n // before the `sealCurrentMessage()` await above), so neither can nack a turn that\n // already settled successfully here, and `settleOnce`'s own idempotency guard means\n // even a lost race there is a safe no-op.\n return\n }\n if (event.type === 'error') {\n settleOnce(() => {\n finish()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_WRAPPER_CRASHED([event.message]))\n })\n return\n }\n if (event.type === 'log') {\n helpers.log[event.level]({\n kind: event.kind,\n message: event.message,\n payload: event.payload as Record<string, unknown> | undefined,\n })\n return\n }\n // 'shutdown_complete' — nothing further to do; the wrapper is exiting on its own.\n }\n\n const eventReader = createNdjsonLineReader<WrapperEvent>((raw) => {\n let event: WrapperEvent\n try {\n event = JSON.parse(raw) as WrapperEvent\n } catch {\n helpers.log.trace({\n kind: 'malformed-wrapper-event',\n message: 'Failed to parse wrapper event line; skipping.',\n payload: { linePreview: raw.slice(0, 256) },\n })\n return undefined\n }\n // `onEvent` is async and this callback is itself invoked synchronously from\n // `child.stdout.on('data', ...)` (below): a bare `void onEvent(event)` would leave any\n // rejection with no attached `.catch`, becoming an unhandled promise rejection that\n // crashes the host process by default (Node >= 15) — a single malformed/erroring\n // wrapper event or tool handler must fail only THIS candidate's dispatch, never the\n // host. `settleOnce`'s own idempotency guard makes this safe even when `onEvent` already\n // settled normally along another path before throwing/rejecting further down its body.\n onEvent(event).catch((err: unknown) => {\n const cause = toErrorCause(err)\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_ERROR([cause.message], { cause }))\n })\n })\n return event\n })\n\n child.stdout?.on('data', (chunk: Uint8Array) => {\n // Deliberately does NOT re-arm the idle timer unconditionally here (as an earlier\n // version of this listener did) — that treated ANY stdout chunk as \"progress\", but\n // `log`/`retry` `WrapperEvent`s (diagnostic passthroughs the wrapper emits on the same\n // stdout stream — see `wrapper.ts`'s `log()` helper and its `system/api_retry`\n // translation) carry no evidence the model is actually advancing, and a sustained\n // sequence of them (e.g. exponential-backoff API retries a few seconds apart) could\n // suppress the stall timeout indefinitely — this is a plausible mechanism for the\n // \"dispatch hangs for 11+ minutes despite a 60s streamIdleTimeoutMs\" report (see issue\n // #39), now fixed for that scenario. Each `onEvent` branch below now re-arms\n // individually, only for event types that constitute genuine progress (`init`,\n // `message_delta`, `thought_delta`, a completed `tool_call_request` round trip);\n // `ready`/`retry`/`log` do not. `init`'s own branch handles the \"very first chunk after\n // the handshake\" case that this comment used to describe, since `armIdleTimer()`'s\n // `sawReady && sawInit` gate means no earlier call in this turn could have armed it\n // anyway.\n //\n // `eventReader.push` calls `onLine` (below) SYNCHRONOUSLY, all the way down to the\n // `JSON.parse`-failure `helpers.log.trace(...)` call — a throw from either escapes this\n // listener directly, bypassing the Fix-B `onEvent(event).catch(...)` chain entirely\n // (that chain only guards `onEvent`'s own async rejection, not a synchronous throw that\n // happens before `onEvent` is even reached). An uncaught throw from inside a\n // `'data'` listener is exactly as fatal to the host process as the unhandled rejection\n // Fix B closed off, so route it through the same reliable settlement path.\n try {\n eventReader.push(chunk)\n } catch (err) {\n const cause = toErrorCause(err)\n settleOnce(() => {\n resolveIteration?.()\n shutdownInBackground()\n ctx.nack(new E_CLAUDE_CODE_CLI_STREAM_ERROR([cause.message], { cause }))\n })\n }\n })\n child.stdout?.on('end', () => {\n // A terminal `result`/`error` event was already observed and its own handler is (or will\n // shortly be) in the middle of its own `settleOnce` — defer to it rather than racing it\n // with a wrong \"stdout ended without a terminal event\" nack for what was actually a\n // successful turn. `sawTerminalEvent` is set synchronously by that handler before any\n // `await`, so it is already true here whenever this really is that race.\n if (sawTerminalEvent) return\n settleOnce(() => {\n finish()\n ctx.nack(\n new E_CLAUDE_CODE_CLI_PROCESS_EXITED_NONZERO([\n 0,\n 'stdout ended without a terminal event',\n ])\n )\n })\n })\n\n void Promise.resolve(child)\n .then((result: unknown) => {\n // Same race as the `stdout.on('end')` guard above: the `result` handler may still be\n // awaiting `sealCurrentMessage()`/the child's own exit when the wrapper process itself\n // settles — defer to the terminal-event path rather than nacking a successful turn.\n if (sawTerminalEvent) return\n const exitCode =\n isObject(result) && 'exitCode' in result\n ? ((result as { exitCode: number | null }).exitCode ?? -1)\n : -1\n settleOnce(() => {\n finish()\n ctx.nack(\n new E_CLAUDE_CODE_CLI_PROCESS_EXITED_NONZERO([\n exitCode,\n 'wrapper process exited with no terminal event observed',\n ])\n )\n })\n })\n .catch(() => {\n if (sawTerminalEvent) return\n settleOnce(() => {\n finish()\n ctx.nack(new E_CLAUDE_CODE_CLI_WRAPPER_CRASHED(['wrapper process rejected']))\n })\n })\n })\n }\n }\n\n /**\n * Returns `true` when `value` is a {@link ClaudeCodeCliAdapter} instance.\n */\n public static isClaudeCodeCliAdapter(value: unknown): value is ClaudeCodeCliAdapter {\n return isInstanceOf(value, 'ClaudeCodeCliAdapter', ClaudeCodeCliAdapter)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmGA,IAAa,kCAA0C;CAKrD,IAAI,OAAO,YAAY,cAAc,OAAO,QAAQ,YAAY,YAC9D,OAAO,QAAQ,QAAQ,sCAAsC;CAY/D,OAAO,mBACL,IAAA,IAAA,wCAAA,KAAA,CAAA,EAAA,GAAA,EAAiE,QACnE;AACF;;;;;;;;;AAUA,IAAM,eAAe,OAAO,SAAmC;CAC7D,IAAI;EACF,MAAM,KAAM,MAAM,OAAO;EACzB,OAAO,OAAO,GAAG,eAAe,cAAc,GAAG,WAAW,IAAI;CAClE,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFA,IAAM,qCAAqC,OACzC,iBACA,QAAsC,CAAC,MACF;CACrC,MAAM,QAAkB,CAAC;CACzB,IAAI;CAKJ,IAFE,MAAM,0BAA0B,KAAA,KAC/B,OAAO,YAAY,cAAc,OAAO,QAAQ,YAAY,YAE7D,IAAI;EACF,aAAa,MAAM,yBAAyB,QAAQ,SAAS,YAAY;CAC3E,SAAS,KAAK;EACZ,MAAM,KACJ,4DAA4D,eAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,GACrG;CACF;CAQF,IAAI,cAAc,KAAA,GAAW;EAC3B,MAAM,gBAAgB,mBAAmB,QAAQ,MAAM,gBAAA,CAAA,EAA4B;EACnF,IAAI,OAAO,kBAAkB,UAC3B,IAAI;GACF,MAAM,EAAE,kBAAkB,MAAM,OAAO;GACvC,YAAY,cAAc,aAAa,EAAE,QAAQ,YAAY;EAC/D,SAAS,KAAK;GACZ,MAAM,KACJ,mFAAmF,eAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,GAC5H;EACF;OAOA,MAAM,KACJ,+GACF;CAEJ;CAEA,IAAI,cAAc,KAAA,GAChB,OAAO,EAAE,MAAM;CAGjB,MAAM,YAAY,UAAU,YAAY,GAAG;CAC3C,IAAI,YAAY,GAAG;EACjB,MAAM,KACJ,2FAA2F,WAC7F;EACA,OAAO,EAAE,MAAM;CACjB;CACA,MAAM,YAAY,GAAG,UAAU,MAAM,GAAG,YAAY,CAAC,IAAI;CACzD,MAAM,KAAK,SAAS;CACpB,OAAQ,MAAM,aAAa,SAAS,IAAK;EAAE,MAAM;EAAW;CAAM,IAAI,EAAE,MAAM;AAChF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAM,iCAAiC,OACrC,QAAoC,CAAC,MACjB;CACpB,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,MAAM,iBAAiB,MAAM,kBAAkB;CAC/C,MAAM,cAAc,MAAM,eAAe;CAEzC,MAAM,QAAkB,CAAC;CAEzB,IAAI;CACJ,IAAI;EACF,WAAW,gBAAgB;CAC7B,SAAS,KAAK;EACZ,MAAM,KAAK,eAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC;CACrD;CACA,IAAI,aAAa,KAAA,GAAW;EAC1B,MAAM,KAAK,QAAQ;EACnB,IAAI,MAAM,YAAY,QAAQ,GAAG,OAAO;CAC1C;CAmBA,MAAM,UAAU,MAAM,eAJD,aAAa,KAAA,KAAa,SAAS,SAAS,MAAM,IAEnE,gCACA,6BACgD;CACpD,MAAM,KAAK,GAAG,QAAQ,KAAK;CAC3B,IAAI,QAAQ,SAAS,KAAA,GAAW,OAAO,QAAQ;CAE/C,MAAM,IAAI,iDAAA,oCAAoC,CAAC,MAAM,KAAK,IAAI,KAAK,iBAAiB,CAAC;AACvF;AAoBA,IAAM,eAAe,OAAO,aAA4D;CACtF,IAAI,QACF,mBAAmB,OAAO;CAC5B,IAAI,OAAO,UAAU,cAAc,EAAE,UAAW,QAC9C,IAAI;EACF,QAAQ,MAAO,MAAwB;CACzC,SAAS,KAAK;EAEZ,MAAM,IAAI,iDAAA,sCAAsC,CAC9C,0BAFa,eAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEnB,mEACnC,CAAC;CACH;CAEF,IAAI,eAAA,SAAS,KAAK,KAAK,WAAW,OAChC,QAAS,MAA6B;CAExC,IAAI,OAAO,UAAU,YACnB,MAAM,IAAI,iDAAA,sCAAsC,CAC9C,8CACF,CAAC;CAEH,OAAO;AACT;AAIA,IAAM,eACJ,WACkB;CAClB,IAAI;CACJ,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,OAAO;EACZ,SAAS;GAAE,GAAI,UAAW,CAAC;GAAU,GAAG;EAAM;CAChD;CACA,OAAO;AACT;AAEA,IAAM,gBACJ,UACA,MACA,UACyC;CACzC,MAAM,SAAS;EAAC;EAAkD,QAAQ,CAAC;EAAG,SAAS,CAAC;CAAC;CACzF,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,GAAG;EAC1C,IAAI,MAAM,KAAA,GAAW;EACrB,IAAI,MAAM,WAAW;EACrB,IAAI,KAAK;CACX;CAEF,MAAM,UAAU,YAAY,OAAO,KAAK,MAAM,EAAE,OAA8C,CAAC;CAC/F,IAAI,YAAY,KAAA,GAAW,IAAI,UAAU;CACzC,OAAO;AACT;AAEA,IAAM,kBACJ,cACyB;CACzB,MAAM,MAAM,aAAa,CAAC;CAC1B,OAAO;EACL,wCACE,IAAI,0CAA0C,gBAAA;EAChD,wBAAwB,IAAI,0BAA0B,gBAAA;EACtD,sBAAsB,IAAI,wBAAwB,gBAAA;EAClD,4BAA4B,IAAI,8BAA8B,gBAAA;EAC9D,gBAAgB,IAAI,kBAAkB,gBAAA;EACtC,oBAAoB,IAAI,sBAAsB,gBAAA;EAC9C,6BACE,IAAI,+BAA+B,gBAAA;EACrC,kCACE,IAAI,oCAAoC,gBAAA;EAC1C,8BACE,IAAI,gCAAgC,gBAAA;EACtC,oCACE,IAAI,sCAAsC,gBAAA;EAC5C,qCACE,IAAI,uCAAuC,gBAAA;EAC7C,eAAe,IAAI,iBAAiB,gBAAA;EACpC,gBAAgB,IAAI,kBAAkB,gBAAA;EACtC,6BACE,IAAI,+BAA+B,gBAAA;EACrC,mCACE,IAAI,qCAAqC,gBAAA;EAC3C,oCACE,IAAI,sCAAsC,8CAAA;EAC5C,mCACE,IAAI,qCAAqC,8CAAA;EAC3C,0BAA0B,IAAI,4BAA4B,8CAAA;CAC5D;AACF;AAEA,IAAM,mBAAmB,OACvB,OACA,aACoB,QAAQ,QAAQ,MAAM,eAAe,QAAyB,CAAC;AAIrF,IAAM,gCAAuB,IAAI,KAAK,GAAE,YAAY;;;;;;;;;;;;;;;AAgBpD,IAAM,gBAAgB,UAA0B;CAC9C,IAAI;EACF,IAAI,eAAA,QAAQ,KAAK,GAAG,OAAO;CAC7B,QAAQ,CAER;CACA,IAAI;CACJ,IAAI;EACF,OACE,OAAO,UAAU,WACb,QACA,UAAU,KAAA,IACR,cACC,KAAK,UAAU,KAAK,KAAK,OAAO,KAAK;CAChD,QAAQ;EACN,IAAI;GACF,OAAO,OAAO,KAAK;EACrB,QAAQ;GACN,OAAO;EACT;CACF;CACA,OAAO,IAAI,MAAM,oDAAoD,QAAQ,EAAE,OAAO,MAAM,CAAC;AAC/F;;;;;;;;AASA,IAAM,mBAAmB,MAAc,UAAA,GAAA,UAAA,QAC9B,yBAAA,mBAAmB;CAAE;CAAM;AAAK,CAAC,CAAC;AAI3C,IAAM,4BAA4B,OAChC,WACA,iCACmE;CACnE,MAAM,UAAkC,CAAC;CACzC,IAAI,iBAAiB;CACrB,KAAK,MAAM,SAAS,WAAW;EAC7B,IAAI,MAAM,SAAS,SAAS;GAC1B,QAAQ,KAAK;IAAE,MAAM;IAAS,MAAM,MAAM,MAAM,SAAS;IAAG,UAAU,MAAM;GAAS,CAAC;GACtF;EACF;EAIA,IAAI,iCAAiC,SAAS;GAC5C,iBAAiB;GACjB,QAAQ,KAAK;IACX,MAAM;IACN,MAAM,sCAAsC,MAAM,KAAK,IAAI,MAAM,SAAS;GAC5E,CAAC;GACD;EACF;EACA,MAAM,UAAU,MAAM,MAAM,WAAW,EAAE,YAAY,KAAA,CAAS;EAC9D,QAAQ,KAAK;GACX,MAAM;GACN,MAAM,WAAW,MAAM,SAAS,IAAI,MAAM,SAAS,IAAI,WAAW,UAAU;EAC9E,CAAC;CACH;CACA,OAAO;EAAE;EAAS,SAAS;CAAe;AAC5C;AAEA,IAAM,uBAAuB,OAAO,UAMkC;CACpE,MAAM,EAAE,KAAK,QAAQ,WAAW;CAEhC,IAAI,kBAAA,MAAM,QAAQ,GAAG,GACnB,OAAO,0BAA0B,CAAC,GAAG,GAAG,MAAM,4BAA4B;CAE5E,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,OAAO,MAAM,kBAAA,MAAM,QAAQ,CAAC,CAAC,GAC3E,OAAO,0BAA0B,KAAK,MAAM,4BAA4B;CAE1E,IAAI,gBAAA,yBAAyB,GAAG,GAAG;EACjC,MAAM,WAAW;EACjB,IAAI,WAAW,OAAO;GACpB,IAAI,aAAa;GACjB,IAAI,YAAY;GAChB,IAAI;IACF,aAAa,MAAM,SAAS,WAAW;GACzC,QAAQ;IACN,aAAa;GACf;GACA,IAAI;IACF,YAAY,MAAM,SAAS,UAAU;GACvC,QAAQ;IACN,YAAY;GACd;GAEA,OAAO;IAAE,SAAS,CAAC;KAAE,MAAM;KAAQ,MADtB,gBAAA,yBAAyB;MAAE;MAAQ;MAAU;MAAY;KAAU,CACvC;IAAK,CAAC;IAAG,SAAS;GAAM;EACnE;EAEA,OAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAA,MADhB,SAAS,SAAS;GACG,CAAC;GAAG,SAAS;EAAM;CAC7D;CACA,IAAI,OAAO,QAAQ,UACjB,OAAO;EAAE,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM;EAAI,CAAC;EAAG,SAAS;CAAM;CAElE,IAAI,eAAA,aAAa,KAAK,cAAc,UAAU,GAAG;EAC/C,MAAM,MAAM,WAAW,MAAM,QAAQ,GAAG;EACxC,OAAO;GACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;GAAiD,CAAC;GAClF,SAAS;EACX;CACF;CACA,OAAO;EAAE,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM,OAAO,GAAG;EAAE,CAAC;EAAG,SAAS;CAAM;AAC1E;;;;;;;;;;;;AAeA,IAAa,uBAAb,MAAa,qBAAqB;;CAEhC,OAAuB,YAAY;CAEnC;;;;;;;CAQA,YAAY,SAAkB;EAC5B,KAAKA,YAAY,iDAAA,gBAAgB,OAAO;CAC1C;;;;;CAMA,SAAS,WAAsE;EAC7E,MAAM,WAAW,KAAKA;EACtB,MAAM,eAAe;EAErB,OAAO,OAAO,KAAsB,YAAoD;GACtF,MAAM,aAAa,QAAsB;IACvC,QAAQ,IAAI,KAAK;KAAE,MAAM;KAAkB,SAAS;IAAI,CAAC;GAC3D;GAGA,MAAM,WAAW,IAAI,MAAM,IAAI,aAAa,WAAW,CAAC,CAAC;GAKzD,MAAM,SAAS,iDAAA,gBAAgB,aAAa,UAAU,WAHpD,YAAY,OAAO,aAAa,WAC3B,WACD,CAAC,CACwE,CAAC;GAEhF,IAAI,OAAO,kBAAkB,QAAQ,OAAO,kBAAkB,KAAA,GAC5D,MAAM,IAAI,iDAAA,kCAAkC,CAC1C,0DACF,CAAC;GAIH,MAAM,kBAAkB,eAAe,OAAO,OAAO;GAGrD,IAAI;GACJ,IAAI;IACF,UAAU,MAAM,aAAa,OAAO,KAAK;GAC3C,SAAS,KAAK;IACZ,IAAI,KAAK,eAAA,QAAQ,GAAG,IAAI,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;IACpD;GACF;GACA,IAAI;GACJ,IAAI;IACF,cAAc,OAAO,eAAgB,MAAM,+BAA+B;GAC5E,SAAS,KAAK;IACZ,IAAI,KAAK,eAAA,QAAQ,GAAG,IAAI,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;IACpD;GACF;GACA,MAAM,YAAY,OAAO,aAAa;GAItC,MAAM,0CAA0B,IAAI,IAAsB;GAC1D,KAAK,MAAM,MAAM,IAAI,eAAe;IAClC,MAAM,WAAW,MAAM,gBAAgB,kCAAkC;KACvE,UAAU;KACV,SAAS,GAAG;KAMZ,MAAM,IAAI,MAAM,IAAI,GAAG,IAAI;KAC3B,wBAAwB,gBAAgB;KACxC,sBAAsB,gBAAgB;KACtC,wBAAwB,OAAO,0BAA0B;KACzD,MAAM;IACR,CAAC;IACD,wBAAwB,IAAI,IAAI,QAAQ;GAC1C;GAGA,MAAM,EAAE,QAAQ,sBAAsB,MAAM,gBAAgB,yBAAyB;IACnF,cAAc,IAAI;IAClB,WAAW;IACX,sBAAsB,IAAI;IAC1B,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,UAAU,IAAI;IACd,UAAU,IAAI;IACd,WAAW,IAAI;IACf,OAAO,IAAI;IACX;IACA,aAAa,OAAO,eAAe;KACjC;KACA;KACA;KACA;IACF;IACA,cAAc,OAAO,gBAAgB;IACrC,kBAAkB,OAAO,oBAAoB;IAC7C,qBAAqB,OAAO,uBAAuB,CAAC;IACpD,wBAAwB,OAAO,0BAA0B;IACzD,mCAAmC,gBAAgB;IACnD,4BAA4B,gBAAgB;IAC5C,gBAAgB,gBAAgB;IAChC,oBAAoB,gBAAgB;IACpC,kCAAkC,gBAAgB;IAClD,8BAA8B,gBAAgB;IAC9C,oCAAoC,gBAAgB;IACpD,qCAAqC,gBAAgB;IACrD,6BAA6B,gBAAgB;IAC7C,oCAAoC,gBAAgB;IACpD,mCAAmC,gBAAgB;IACnD,eAAe,gBAAgB;IAC/B,gBAAgB,gBAAgB;IAChC,wBAAwB,gBAAgB;IACxC,sBAAsB,gBAAgB;IACtC,MAAM;GACR,CAAC;GAOD,IAAI,kBAAkB,SAAS,GAC7B,QAAQ,IAAI,MAAM;IAChB,MAAM;IACN,SAAS,GAAG,kBAAkB,OAAO;GACvC,CAAC;GAIH,MAAM,aAAa,IAAI,IAAI,OAAO,mBAAmB,CAAC,CAAC;GAEvD,MAAM,eADe,IAAI,MAAM,QAAQ,EAAE,QAAQ,MAAM,CAAC,WAAW,IAAI,EAAE,IAAI,CAClC,EAAa,KAAK,MAAM;IACjE,MAAM,YAAY,EAAE,SAAS;IAC7B,MAAM,cAAc,gBAAgB,uCAClC,UAAU,WACZ;IACA,OAAO;KACL,MAAM,UAAU;KAChB,aAAa,UAAU;KACvB,aACE,eAAe,OAAO,KAAK,WAAW,EAAE,SAAS,IAC5C,cACD;MAAE,MAAM;MAAU,YAAY,CAAC;KAAE;IACzC;GACF,CAAC;GAGD,IAAI,OAAO,kBAAkB,QAAQ,OAAO,kBAAkB,KAAA,GAAW;IACvE,MAAM,WAAW,OAAO;IAGxB,MAAM,eAAe,MAAM,iBAAiB,IAAI,oBAAA,YAAY,MAAM,GAAG,QAAQ;IAC7E,MAAM,2BAA2B,OAAO,qBACpC,MAAM,iBAAiB,IAAI,oBAAA,YAAY,OAAO,kBAAkB,GAAG,QAAQ,IAC3E;IAIJ,MAAM,kBAAkB,MAAM,iBAAiB,IAAI,cAAc,QAAQ;IACzE,IAAI,0BAA0B;IAC9B,KAAK,MAAM,SAAS,IAAI,sBACtB,2BAA2B,MAAM,iBAAiB,OAAO,QAAQ;IACnE,IAAI,cAAc;IAClB,KAAK,MAAM,SAAS,IAAI,cACtB,eAAe,MAAM,iBAAiB,MAAM,SAAS,QAAQ;IAC/D,IAAI,kBAAkB;IACtB,KAAK,MAAM,KAAK,IAAI,kBAClB,mBACE,CAAC,EAAE,UAAU,yBAAA,gBAAgB,kBAAkB,EAAE,OAAO,KAAK,EAAE,QAAQ,aAAa,IAChF,EAAE,QAAQ,qBACR,EAAE,IACF,UACA,gBAAgB,2BAClB,IACA,MAAM,iBAAiB,EAAE,SAAS,QAAQ;IAElD,IAAI,cAAc;IAClB,KAAK,MAAM,OAAO,IAAI,cACpB,IAAI,IAAI,YAAY,KAAA,GAClB,eAAe,MAAM,iBAAiB,IAAI,SAAS,QAAQ;IAC/D,KAAK,MAAM,WAAW,IAAI,cACxB,eAAe,MAAM,iBAAiB,QAAQ,SAAS,QAAQ;IACjE,KAAK,MAAM,YAAY,wBAAwB,OAAO,GACpD,eAAe,MAAM,iBAAiB,IAAI,oBAAA,YAAY,QAAQ,GAAG,QAAQ;IAM3E,MAAM,QAAQ,MAAM,iBAAiB,IAAI,oBAAA,YAAY,GAHxB,KAAK,UAAU,YAAY,EAAE,GAAG,aAC1D,KAAK,MAAM,oBAAoB,EAAE,MAAM,EACvC,KAAK,GAAG,GAC2D,GAAG,QAAQ;IACjF,MAAM,YAAY;KAChB,QAAQ;KACR,oBAAoB;KACpB;KACA,KAAK;MACH,cAAc;MACd,sBAAsB;MACtB,UAAU;MACV,cAAc;MACd,UAAU;KACZ;IACF;IACA,MAAM,QAAQ,eAAe,2BAA2B;IACxD,QAAQ,IAAI,MAAM;KAChB,MAAM;KACN,SAAS,yBAAyB,MAAM,GAAG,OAAO,cAAc;KAChE,SAAS;MAAE;MAAO,OAAO,OAAO;MAAe;MAAU;KAAU;IACrE,CAAC;IACD,IAAI,QAAQ,OAAO,eACjB,MAAM,IAAI,iDAAA,mCAAmC;KAC3C;KACA,OAAO;KACP;KACA,KAAK,UAAU,SAAS;IAC1B,CAAC;GACL;GAGA,MAAM,aAAa,OAAO,cAAc,IAAI,oCAAA,mBAAmB;GAO/D,MAAM,kBAAkB,OAAO,mBAAmB,QAAQ;GAU1D,MAAM,iBAAiB,QAAQ,SAAS,aAAa,KAAA;GACrD,MAAM,0BAA0B,OAAO,0BAA0B,SAAS;GAc1E,MAAM,qCACJ,OAAO,eAAe,KAAA,KACtB,OAAO,UAAU,eAAe,KAAK,OAAO,YAAY,sBAAsB;GAChF,MAAM,8BACJ,0BAA0B,CAAC;GAC7B,MAAM,aACJ,0BAA0B,OAAO,eAAe,KAAA,IAC5C;IACE,GAAI,yBAAyB,EAAE,sBAAsB,IAAI,IAAI,CAAC;IAC9D,GAAI,8BACA,EAgBE,uDAAuD,IACzD,IACA,CAAC;IACL,GAAG,OAAO;GACZ,IACA,KAAA;GACN,IAAI;GACJ,IAAI;IACF,QAAQ,QACN,iBACA,CAAC,WAAW,GACZ,eAAe,KAAA,IAAY;KAAE,SAAS;KAAM,KAAK;IAAW,IAAI,EAAE,SAAS,KAAK,CAClF;GACF,SAAS,KAAK;IACZ,IAAI,KACF,IAAI,iDAAA,sCAAsC,CAAC,eAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC,CACtF;IACA;GACF;GAEA,MAAM,mBAAmB,OAAO,oBAAoB;GACpD,MAAM,sBAAsB,OAAO,uBAAuB;GAC1D,MAAM,iBAAiB,OAAO,kBAAkB;GAEhD,IAAI,WAAW;GACf,IAAI,UAAU;GAOd,IAAI,mBAAmB;GACvB,IAAI;GACJ,IAAI;GACJ,IAAI,UAAU;GAMd,IAAI;GAQJ,MAAM,iBAAA,GAAA,KAAA,IAAuB;GAM7B,MAAM,+BAAe,IAAI,IAAiD;GAW1E,IAAI,oBAAoB;GAKxB,IAAI;GAEJ,MAAM,0BAAgC;IACpC,IAAI,cAAc,aAAa,YAAY;IAC3C,eAAe,KAAA;GACjB;GACA,MAAM,uBAA6B;IACjC,IAAI,WAAW,aAAa,SAAS;IACrC,YAAY,KAAA;GACd;GACA,MAAM,+BAAqC;IACzC,IAAI,YAAY,SAAS,kBAAkB;GAC7C;GAEA,MAAM,gBAAgB,YAAkC;IACtD,IAAI;KACF,MAAM,OAAO,MAAM,2CAAA,qBAAqB,OAAO,CAAC;IAClD,QAAQ,CAER;GACF;GAEA,MAAM,mBAAmB,YAA2B;IAClD,aAAa,EAAE,MAAM,WAAW,CAAC;IACjC,MAAM,oBAAoB,cACxB,IAAI,SAAe,YAAY;KAC7B,MAAM,QAAQ,WAAW,SAAS,SAAS;KAS3C,QAAa,QAAQ,KAAK,EACvB,cAAc;MACb,aAAa,KAAK;MAClB,QAAQ;KACV,CAAC,EACA,YAAY,CAGb,CAAC;IACL,CAAC;IACH,MAAM,iBAAiB,cAAc;IACrC,IAAI;KACF,MAAM,KAAK,SAAS;IACtB,QAAQ,CAER;IAUA,MAAM,iBAAiB,cAAc;IACrC,IAAI;KACF,MAAM,KAAK,SAAS;IACtB,QAAQ,CAER;IAuCA,IAAI,OAAO,kBAAkB,YAAY,MAAM,aAAa,MAC1D,IAAI;KACF,QAAQ,KAAK,CAAC,eAAe,SAAS;IACxC,QAAQ,CAER;GAEJ;GAWA,MAAM,6BAAmC;IACvC,iBAAiB,EAAE,OAAO,QAAiB;KACzC,MAAM,QAAQ,aAAa,GAAG;KAC9B,IAAI;MACF,QAAQ,IAAI,MAAM;OAChB,MAAM;OACN,SAAS,8GAA8G,MAAM;OAC7H,SAAS,EAAE,OAAO,MAAM,QAAQ;MAClC,CAAC;KACH,QAAQ,CAER;IACF,CAAC;GACH;GAEA,MAAM,sBAA4B;IAChC,qBAAqB;GACvB;GACA,IAAI,YAAY,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;GACvE,MAAM,4BACJ,IAAI,YAAY,oBAAoB,SAAS,aAAa;GA8B5D,MAAM,cAAc,OAAyB;IAC3C,IAAI,SAAS;IACb,UAAU;IACV,kBAAkB;IAClB,eAAe;IACf,oBAAoB;IACpB,IAAI,QAAQ;IACZ,IAAI;KACF,GAAG;IACL,SAAS,KAAK;KACZ,QAAQ;KACR,IAAI;MACF,MAAM,QAAQ,aAAa,GAAG;MAC9B,IAAI;OACF,QAAQ,IAAI,MAAM;QAChB,MAAM;QACN,SAAS,2IAA2I,MAAM;QAC1J,SAAS,EAAE,OAAO,MAAM,QAAQ;OAClC,CAAC;MACH,QAAQ,CAER;MAOA,IAAI,CAAC,IAAI,aACP,IAAI;OACF,IAAI,KAAK,IAAI,iDAAA,+BAA+B,CAAC,MAAM,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;MACzE,QAAQ,CAER;KAEJ,QAAQ,CAER;IACF,UAAU;KACR,IAAI,OAAO;MAGT,IAAI;OACF,qBAAqB;MACvB,QAAQ,CAER;MAQA,IAAI;OACF,mBAAmB;MACrB,QAAQ,CAGR;KACF;IACF;GACF;GAEA,eAAe,iBAAiB;IAC9B,iBAAiB;KACf,mBAAmB;KACnB,qBAAqB;KACrB,IAAI,KAAK,IAAI,iDAAA,kCAAkC,CAAC,gBAAgB,CAAC,CAAC;IACpE,CAAC;GACH,GAAG,gBAAgB;GAEnB,MAAM,qBAA2B;IAC/B,IAAI,CAAC,YAAY,CAAC,SAAS;IAG3B,IAAI,oBAAoB,GAAG;IAC3B,eAAe;IACf,YAAY,iBAAiB;KAC3B,iBAAiB;MACf,mBAAmB;MACnB,qBAAqB;MACrB,IAAI,KAAK,IAAI,iDAAA,iCAAiC,CAAC,mBAAmB,CAAC,CAAC;KACtE,CAAC;IACH,GAAG,mBAAmB;GACxB;GAMA,MAAM,cAAc,OAAO,OAA0C;IACnE,IAAI,OAAO,KAAA,GAAW;IACtB,MAAM,QAAQ,aAAa,IAAI,EAAE;IACjC,IAAI,UAAU,KAAA,KAAa,MAAM,QAAQ;IACzC,MAAM,SAAS;IACf,MAAM,IAAI,aACR,IAAI,gBAAA,QAAQ;KACV;KACA,MAAM;KACN,SAAS,MAAM;KACf,UAAU,OAAO,gBAAgB;KACjC,WAAW,OAAO;KAClB,WAAW,OAAO;IACpB,CAAC,CACH;GACF;GASA,MAAM,qBAAqB,YAA2B;IACpD,KAAK,MAAM,MAAM,aAAa,KAAK,GACjC,MAAM,YAAY,EAAE;GAExB;GAEA,MAAM,wBAAwB,OAC5B,WACA,UACA,YACkB;IAClB,MAAM,OAAO,IAAI,MAAM,IAAI,QAAQ;IACnC,IAAI,CAAC,MAAM;KACT,aAAa;MACX,MAAM;MACN;MACA,SAAS;OACP,SAAS,CAAC;QAAE,MAAM;QAAQ,MAAM,mBAAmB;OAAW,CAAC;OAC/D,SAAS;MACX;KACF,CAAC;KACD;IACF;IAIA,MAAM,OAAyC,eAAA,SAAS,OAAO,IAAI,UAAU,CAAC;IAQ9E,MAAM,UAAU,OAAO,oBAAoB,oBAAA,sBAAsB,WAAW,GAAG;IAC/E,QAAQ,eAAe,QAAQ;KAAE,MAAM,KAAK;KAAM;IAAK,CAAC;IACxD,MAAM,iBAAiB,yBAAA,aAAa,eAAe,IAAI;IACvD,IAAI,UACF,IAAI,oBAAA,YAAY,EAAE;IACpB,IAAI,eAAe;IACnB,IAAI;KACF,MAAM,MAAM,MAAM,KAAK,SAAS,GAAG,EAAE,IAAI;KACzC,IAAI,gBACF,IAAI,oBAAA,YAAY,cAAc,GAAG,GAC/B,UAAU;UACL,IAAI,OAAO,QAAQ,UACxB,UAAU,IAAI,oBAAA,YAAY,GAAG;UAE7B,MAAM,IAAI,MACR,iBAAiB,KAAK,KAAK,8CAC7B;UAEG,IAAI,kBAAA,MAAM,QAAQ,GAAG,GAC1B,UAAU;UACL,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,OAAO,MAAM,kBAAA,MAAM,QAAQ,CAAC,CAAC,GAClF,UAAU;UACL,IAAI,gBAAA,yBAAyB,GAAG,GACrC,UAAU;UACL,IAAI,OAAO,QAAQ,YAAY,eAAA,aAAa,KAAK,cAAc,UAAU,GAAG;MACjF,MAAM,SAAS,MAAM,WAAW,MAAM,QAAQ,GAAG;MAEjD,UAAU,MADY,KAAc,sBAAsB,MAAK,yBAAA,iBACpC,MAAM;KACnC,OAAO;MACL,MAAM,SAAS,MAAM,WAAW,MAAM,QAAQ,OAAO,GAAG,CAAC;MAEzD,UAAU,MADY,KAAc,sBAAsB,MAAK,yBAAA,iBACpC,MAAM;KACnC;IACF,SAAS,KAAK;KACZ,eAAe;KACf,UAAU,IAAI,oBAAA,YAAY,eAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,CAAC;IACpE;IACA,QAAQ,eAAe,QAAQ;KAAE;KAAS,SAAS;KAAc,YAAY;IAAK,CAAC;IACnF,MAAM,cAAc,OAAO;IAC3B,MAAM,IAAI,cACR,IAAI,kBAAA,SAAS;KACX,IAAI;KACJ,MAAM,KAAK;KACX;KACA,UAAU,gBAAgB,KAAK,MAAM,IAAI;KACzC,YAAY;KACZ,SAAS;KACT;KACA,kBAAkB;KAClB,QAAQ;KACR,WAAW;KACX,WAAW;KACX;IACF,CAAC,CACH;IAEA,IAAI;IACJ,IAAI;KACF,WAAW,MAAM,qBAAqB;MACpC,KAAK;MACL;MACA,QAAQ;MACR;MACA,8BACE,OAAO,gCAAgC,OAAO,0BAA0B;KAC5E,CAAC;IACH,SAAS,KAAK;KACZ,WAAW;MACT,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM,eAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;MAAE,CAAC;MAC1E,SAAS;KACX;IACF;IACA,aAAa;KACX,MAAM;KACN;KACA,SAAS;MAAE,SAAS,SAAS;MAAS,SAAS,gBAAgB,SAAS;KAAQ;IAClF,CAAC;GACH;GAEA,MAAM,IAAI,SAAe,YAAY;IACnC,MAAM,eAAqB,QAAQ;IACnC,mBAAmB;IAEnB,MAAM,UAAU,OAAO,UAAuC;KAC5D,IAAI,MAAM,SAAS,SAAS;MAC1B,WAAW;MACX,uBAAuB;MA4BvB,aAAa;OA1BX,MAAM;OACN;OACA,oBAAoB,OAAO;OAC3B,OAAO,OAAO;OACd,KAAK,OAAO;OACZ,QAAQ,OAAO;OACf,cAAc,aAAa,KAAK,MAAM,EAAE,IAAI;OAC5C,cAAc,OAAO;OACrB,eAAe,OAAO;OACtB,MAAM;QACJ,QAAQ,OAAO;QACf,WAAW,OAAO;QAClB,SAAS,OAAO;OAClB;OACA,kBAAkB,OAAO;OACzB,uBAAuB,OAAO;OAC9B,4BAA4B,OAAO;OACnC,sBAAsB,OAAO;OAC7B;OACA,qBAAqB,OAAO;OAC5B,8BAA8B,OAC5B,OAAO,gCAAgC,OAAO,0BAA0B,OAC1E;OACA;OACA,WAAW,OAAO;MAEP,CAAU;MAKvB;KACF;KACA,IAAI,MAAM,SAAS,sBAAsB;MAIvC,gBAAgB,MAAM;MACtB;KACF;KACA,IAAI,MAAM,SAAS,qBAAqB;MAOtC,gBAAgB,KAAA;MAChB;KACF;KACA,IAAI,MAAM,SAAS,QAAQ;MACzB,UAAU;MACV,uBAAuB;MACvB,QAAQ,IAAI,KAAK;OACf,MAAM;OACN,SAAS;OACT,SAAS;MACX,CAAC;MACD,IAAI,MAAM,mBAAmB,MAAM,gBAAgB,SAAS,GAAG;OAC7D,iBAAiB;QACf,OAAO;QACP,qBAAqB;QACrB,IAAI,KACF,IAAI,iDAAA,4CAA4C,CAC9C,MAAM,gBAAiB,KAAK,IAAI,CAClC,CAAC,CACH;OACF,CAAC;OACD;MACF;MAMA,aAAa;MACb;KACF;KACA,IAAI,MAAM,SAAS,SAAS;MAiB1B,QAAQ,IAAI,KAAK;OACf,MAAM;OACN,SAAS,6BAA6B,MAAM;OAC5C,SAAS;MACX,CAAC;MACD;KACF;KACA,IAAI,MAAM,SAAS,iBAAiB;MAMlC,MAAM,KAAK,GAAG,cAAc,WAAW,MAAM;MAC7C,MAAM,QAAQ,aAAa,IAAI,EAAE,KAAK;OAAE,QAAQ;OAAI,QAAQ;MAAM;MAClE,MAAM,UAAU,MAAM;MACtB,aAAa,IAAI,IAAI,KAAK;MAC1B,QAAQ,cAAc,IAAI,MAAM,OAAO,EAAE,YAAY,MAAM,WAAW,CAAC;MACvE,IAAI,MAAM,YACR,MAAM,YAAY,EAAE;MAEtB,aAAa;MACb;KACF;KACA,IAAI,MAAM,SAAS,iBAAiB;MAKlC,MAAM,KAAK,GAAG,cAAc,WAAW,MAAM;MAC7C,QAAQ,cAAc,IAAI,MAAM,OAAO,EAAE,YAAY,MAAM,WAAW,CAAC;MACvE,aAAa;MACb;KACF;KACA,IAAI,MAAM,SAAS,qBAAqB;MAQtC,qBAAqB;MACrB,eAAe;MACf,IAAI;OACF,MAAM,sBAAsB,MAAM,WAAW,MAAM,MAAM,MAAM,IAAI;MACrE,UAAU;OACR,oBAAoB,KAAK,IAAI,GAAG,oBAAoB,CAAC;MACvD;MAKA,aAAa;MACb;KACF;KACA,IAAI,MAAM,SAAS,UAAU;MAC3B,mBAAmB;MACnB,MAAM,mBAAmB;MACzB,iBAAiB;OAqBf,OAAO;OACP,qBAAqB;OACrB,IAAI,MAAM,WAAW,MAAM,YAAY,mBAAmB;QACxD,IAAI,KACF,IAAI,iDAAA,8BAA8B,CAChC,MAAM,cAAc,WACpB,MAAM,cAAc,EACtB,CAAC,CACH;QACA;OACF;OACA,IAAI,MAAM,WAAW,MAAM,YAAY,mBACrC,QAAQ,IAAI,MAAM;QAChB,MAAM;QACN,SACE;QACF,SAAS,EAAE,SAAS,MAAM,QAAQ;OACpC,CAAC;OAEH,QAAQ,sBAAsB;QAC5B,UAAU;QACV,OAAO,OAAO;QACd,KAAK,MAAM;OACb,CAAC;OACD,IAAI,OAAO,SAAS,IAAI,IAAI;MAC9B,CAAC;MAUD;KACF;KACA,IAAI,MAAM,SAAS,SAAS;MAC1B,iBAAiB;OACf,OAAO;OACP,qBAAqB;OACrB,IAAI,KAAK,IAAI,iDAAA,kCAAkC,CAAC,MAAM,OAAO,CAAC,CAAC;MACjE,CAAC;MACD;KACF;KACA,IAAI,MAAM,SAAS,OAAO;MACxB,QAAQ,IAAI,MAAM,OAAO;OACvB,MAAM,MAAM;OACZ,SAAS,MAAM;OACf,SAAS,MAAM;MACjB,CAAC;MACD;KACF;IAEF;IAEA,MAAM,cAAc,2CAAA,wBAAsC,QAAQ;KAChE,IAAI;KACJ,IAAI;MACF,QAAQ,KAAK,MAAM,GAAG;KACxB,QAAQ;MACN,QAAQ,IAAI,MAAM;OAChB,MAAM;OACN,SAAS;OACT,SAAS,EAAE,aAAa,IAAI,MAAM,GAAG,GAAG,EAAE;MAC5C,CAAC;MACD;KACF;KAQA,QAAQ,KAAK,EAAE,OAAO,QAAiB;MACrC,MAAM,QAAQ,aAAa,GAAG;MAC9B,iBAAiB;OACf,mBAAmB;OACnB,qBAAqB;OACrB,IAAI,KAAK,IAAI,iDAAA,+BAA+B,CAAC,MAAM,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;MACzE,CAAC;KACH,CAAC;KACD,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,UAAsB;KAwB9C,IAAI;MACF,YAAY,KAAK,KAAK;KACxB,SAAS,KAAK;MACZ,MAAM,QAAQ,aAAa,GAAG;MAC9B,iBAAiB;OACf,mBAAmB;OACnB,qBAAqB;OACrB,IAAI,KAAK,IAAI,iDAAA,+BAA+B,CAAC,MAAM,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;MACzE,CAAC;KACH;IACF,CAAC;IACD,MAAM,QAAQ,GAAG,aAAa;KAM5B,IAAI,kBAAkB;KACtB,iBAAiB;MACf,OAAO;MACP,IAAI,KACF,IAAI,iDAAA,yCAAyC,CAC3C,GACA,uCACF,CAAC,CACH;KACF,CAAC;IACH,CAAC;IAED,QAAa,QAAQ,KAAK,EACvB,MAAM,WAAoB;KAIzB,IAAI,kBAAkB;KACtB,MAAM,WACJ,eAAA,SAAS,MAAM,KAAK,cAAc,SAC5B,OAAuC,YAAY,KACrD;KACN,iBAAiB;MACf,OAAO;MACP,IAAI,KACF,IAAI,iDAAA,yCAAyC,CAC3C,UACA,wDACF,CAAC,CACH;KACF,CAAC;IACH,CAAC,EACA,YAAY;KACX,IAAI,kBAAkB;KACtB,iBAAiB;MACf,OAAO;MACP,IAAI,KAAK,IAAI,iDAAA,kCAAkC,CAAC,0BAA0B,CAAC,CAAC;KAC9E,CAAC;IACH,CAAC;GACL,CAAC;EACH;CACF;;;;CAKA,OAAc,uBAAuB,OAA+C;EAClF,OAAO,eAAA,aAAa,OAAO,wBAAwB,oBAAoB;CACzE;AACF"}