@corbet-labs/ccht 0.1.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 (380) hide show
  1. package/LICENSE +307 -0
  2. package/LICENSE.md +25 -0
  3. package/LICENSES/GPL-3.0-only.txt +232 -0
  4. package/LICENSES/LGPL-3.0-only.txt +304 -0
  5. package/LICENSES/dependencies/agent-client-protocol-2.1.0/LICENSE +191 -0
  6. package/LICENSES/dependencies/agent-client-protocol-derive-2.1.0/LICENSE +191 -0
  7. package/LICENSES/dependencies/agent-client-protocol-schema-1.7.0/LICENSE +190 -0
  8. package/LICENSES/dependencies/android_system_properties-0.1.6/LICENSE-APACHE +13 -0
  9. package/LICENSES/dependencies/android_system_properties-0.1.6/LICENSE-MIT +20 -0
  10. package/LICENSES/dependencies/anyhow-1.0.104/LICENSE-APACHE +176 -0
  11. package/LICENSES/dependencies/anyhow-1.0.104/LICENSE-MIT +23 -0
  12. package/LICENSES/dependencies/async-channel-2.5.0/LICENSE-APACHE +201 -0
  13. package/LICENSES/dependencies/async-channel-2.5.0/LICENSE-MIT +23 -0
  14. package/LICENSES/dependencies/async-io-2.6.0/LICENSE-APACHE +201 -0
  15. package/LICENSES/dependencies/async-io-2.6.0/LICENSE-MIT +23 -0
  16. package/LICENSES/dependencies/async-lock-3.4.2/LICENSE-APACHE +201 -0
  17. package/LICENSES/dependencies/async-lock-3.4.2/LICENSE-MIT +23 -0
  18. package/LICENSES/dependencies/async-process-2.5.0/LICENSE-APACHE +201 -0
  19. package/LICENSES/dependencies/async-process-2.5.0/LICENSE-MIT +23 -0
  20. package/LICENSES/dependencies/async-signal-0.2.14/LICENSE-APACHE +201 -0
  21. package/LICENSES/dependencies/async-signal-0.2.14/LICENSE-MIT +23 -0
  22. package/LICENSES/dependencies/async-task-4.7.1/LICENSE-APACHE +201 -0
  23. package/LICENSES/dependencies/async-task-4.7.1/LICENSE-MIT +23 -0
  24. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-APACHE +201 -0
  25. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-MIT +23 -0
  26. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-THIRD-PARTY +45 -0
  27. package/LICENSES/dependencies/autocfg-1.5.1/LICENSE-APACHE +201 -0
  28. package/LICENSES/dependencies/autocfg-1.5.1/LICENSE-MIT +25 -0
  29. package/LICENSES/dependencies/base64-0.22.1/LICENSE-APACHE +201 -0
  30. package/LICENSES/dependencies/base64-0.22.1/LICENSE-MIT +21 -0
  31. package/LICENSES/dependencies/base64-0.23.1/LICENSE-APACHE +201 -0
  32. package/LICENSES/dependencies/base64-0.23.1/LICENSE-MIT +21 -0
  33. package/LICENSES/dependencies/bitflags-1.3.2/LICENSE-APACHE +201 -0
  34. package/LICENSES/dependencies/bitflags-1.3.2/LICENSE-MIT +25 -0
  35. package/LICENSES/dependencies/bitflags-2.13.2/LICENSE-APACHE +201 -0
  36. package/LICENSES/dependencies/bitflags-2.13.2/LICENSE-MIT +25 -0
  37. package/LICENSES/dependencies/blocking-1.7.0/LICENSE-APACHE +201 -0
  38. package/LICENSES/dependencies/blocking-1.7.0/LICENSE-MIT +23 -0
  39. package/LICENSES/dependencies/bs58-0.5.1/LICENSE-APACHE +201 -0
  40. package/LICENSES/dependencies/bs58-0.5.1/LICENSE-MIT +20 -0
  41. package/LICENSES/dependencies/bumpalo-3.20.3/LICENSE-APACHE +201 -0
  42. package/LICENSES/dependencies/bumpalo-3.20.3/LICENSE-MIT +25 -0
  43. package/LICENSES/dependencies/cc-1.4.5/LICENSE-APACHE +201 -0
  44. package/LICENSES/dependencies/cc-1.4.5/LICENSE-MIT +25 -0
  45. package/LICENSES/dependencies/cfg-if-1.0.4/LICENSE-APACHE +201 -0
  46. package/LICENSES/dependencies/cfg-if-1.0.4/LICENSE-MIT +25 -0
  47. package/LICENSES/dependencies/chrono-0.4.45/LICENSE.txt +240 -0
  48. package/LICENSES/dependencies/concurrent-queue-2.5.0/LICENSE-APACHE +201 -0
  49. package/LICENSES/dependencies/concurrent-queue-2.5.0/LICENSE-MIT +23 -0
  50. package/LICENSES/dependencies/convert_case-0.10.0/LICENSE +21 -0
  51. package/LICENSES/dependencies/core-foundation-sys-0.8.7/LICENSE-APACHE +201 -0
  52. package/LICENSES/dependencies/core-foundation-sys-0.8.7/LICENSE-MIT +25 -0
  53. package/LICENSES/dependencies/crossbeam-deque-0.8.8/LICENSE-APACHE +201 -0
  54. package/LICENSES/dependencies/crossbeam-deque-0.8.8/LICENSE-MIT +27 -0
  55. package/LICENSES/dependencies/crossbeam-epoch-0.9.21/LICENSE-APACHE +201 -0
  56. package/LICENSES/dependencies/crossbeam-epoch-0.9.21/LICENSE-MIT +27 -0
  57. package/LICENSES/dependencies/crossbeam-utils-0.8.23/LICENSE-APACHE +201 -0
  58. package/LICENSES/dependencies/crossbeam-utils-0.8.23/LICENSE-MIT +27 -0
  59. package/LICENSES/dependencies/darling-0.24.1/LICENSE +21 -0
  60. package/LICENSES/dependencies/darling_core-0.24.1/LICENSE +21 -0
  61. package/LICENSES/dependencies/darling_macro-0.24.1/LICENSE +21 -0
  62. package/LICENSES/dependencies/defmt-1.1.1/LICENSE-APACHE +201 -0
  63. package/LICENSES/dependencies/defmt-1.1.1/LICENSE-MIT +25 -0
  64. package/LICENSES/dependencies/defmt-macros-1.1.1/LICENSE-APACHE +201 -0
  65. package/LICENSES/dependencies/defmt-macros-1.1.1/LICENSE-MIT +25 -0
  66. package/LICENSES/dependencies/defmt-parser-1.0.0/LICENSE-APACHE +201 -0
  67. package/LICENSES/dependencies/defmt-parser-1.0.0/LICENSE-MIT +25 -0
  68. package/LICENSES/dependencies/deranged-0.5.8/LICENSE-Apache +202 -0
  69. package/LICENSES/dependencies/deranged-0.5.8/LICENSE-MIT +19 -0
  70. package/LICENSES/dependencies/derive_more-2.1.1/LICENSE +21 -0
  71. package/LICENSES/dependencies/derive_more-impl-2.1.1/LICENSE +21 -0
  72. package/LICENSES/dependencies/dyn-clone-1.0.20/LICENSE-APACHE +176 -0
  73. package/LICENSES/dependencies/dyn-clone-1.0.20/LICENSE-MIT +23 -0
  74. package/LICENSES/dependencies/either-1.18.0/LICENSE-APACHE +201 -0
  75. package/LICENSES/dependencies/either-1.18.0/LICENSE-MIT +25 -0
  76. package/LICENSES/dependencies/equivalent-1.0.2/LICENSE-APACHE +201 -0
  77. package/LICENSES/dependencies/equivalent-1.0.2/LICENSE-MIT +25 -0
  78. package/LICENSES/dependencies/errno-0.3.14/LICENSE-APACHE +201 -0
  79. package/LICENSES/dependencies/errno-0.3.14/LICENSE-MIT +25 -0
  80. package/LICENSES/dependencies/event-listener-5.4.2/LICENSE-APACHE +201 -0
  81. package/LICENSES/dependencies/event-listener-5.4.2/LICENSE-MIT +23 -0
  82. package/LICENSES/dependencies/event-listener-strategy-0.5.4/LICENSE-APACHE +201 -0
  83. package/LICENSES/dependencies/event-listener-strategy-0.5.4/LICENSE-MIT +23 -0
  84. package/LICENSES/dependencies/fallible-iterator-0.3.0/LICENSE-APACHE +202 -0
  85. package/LICENSES/dependencies/fallible-iterator-0.3.0/LICENSE-MIT +19 -0
  86. package/LICENSES/dependencies/fastrand-2.5.0/LICENSE-APACHE +201 -0
  87. package/LICENSES/dependencies/fastrand-2.5.0/LICENSE-MIT +23 -0
  88. package/LICENSES/dependencies/find-msvc-tools-0.1.12/LICENSE-APACHE +201 -0
  89. package/LICENSES/dependencies/find-msvc-tools-0.1.12/LICENSE-MIT +25 -0
  90. package/LICENSES/dependencies/fixedbitset-0.5.7/LICENSE-APACHE +201 -0
  91. package/LICENSES/dependencies/fixedbitset-0.5.7/LICENSE-MIT +25 -0
  92. package/LICENSES/dependencies/foldhash-0.2.0/LICENSE +19 -0
  93. package/LICENSES/dependencies/futures-0.3.34/LICENSE-APACHE +202 -0
  94. package/LICENSES/dependencies/futures-0.3.34/LICENSE-MIT +26 -0
  95. package/LICENSES/dependencies/futures-channel-0.3.34/LICENSE-APACHE +202 -0
  96. package/LICENSES/dependencies/futures-channel-0.3.34/LICENSE-MIT +26 -0
  97. package/LICENSES/dependencies/futures-concurrency-7.7.1/LICENSE-APACHE +190 -0
  98. package/LICENSES/dependencies/futures-concurrency-7.7.1/LICENSE-MIT +21 -0
  99. package/LICENSES/dependencies/futures-core-0.3.34/LICENSE-APACHE +202 -0
  100. package/LICENSES/dependencies/futures-core-0.3.34/LICENSE-MIT +26 -0
  101. package/LICENSES/dependencies/futures-executor-0.3.34/LICENSE-APACHE +202 -0
  102. package/LICENSES/dependencies/futures-executor-0.3.34/LICENSE-MIT +26 -0
  103. package/LICENSES/dependencies/futures-io-0.3.34/LICENSE-APACHE +202 -0
  104. package/LICENSES/dependencies/futures-io-0.3.34/LICENSE-MIT +26 -0
  105. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-APACHE +201 -0
  106. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-MIT +23 -0
  107. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-THIRD-PARTY +45 -0
  108. package/LICENSES/dependencies/futures-macro-0.3.34/LICENSE-APACHE +202 -0
  109. package/LICENSES/dependencies/futures-macro-0.3.34/LICENSE-MIT +26 -0
  110. package/LICENSES/dependencies/futures-sink-0.3.34/LICENSE-APACHE +202 -0
  111. package/LICENSES/dependencies/futures-sink-0.3.34/LICENSE-MIT +26 -0
  112. package/LICENSES/dependencies/futures-task-0.3.34/LICENSE-APACHE +202 -0
  113. package/LICENSES/dependencies/futures-task-0.3.34/LICENSE-MIT +26 -0
  114. package/LICENSES/dependencies/futures-util-0.3.34/LICENSE-APACHE +202 -0
  115. package/LICENSES/dependencies/futures-util-0.3.34/LICENSE-MIT +26 -0
  116. package/LICENSES/dependencies/getrandom-0.4.3/LICENSE-APACHE +201 -0
  117. package/LICENSES/dependencies/getrandom-0.4.3/LICENSE-MIT +26 -0
  118. package/LICENSES/dependencies/gimli-0.32.3/LICENSE-APACHE +201 -0
  119. package/LICENSES/dependencies/gimli-0.32.3/LICENSE-MIT +25 -0
  120. package/LICENSES/dependencies/hashbrown-0.12.3/LICENSE-APACHE +201 -0
  121. package/LICENSES/dependencies/hashbrown-0.12.3/LICENSE-MIT +25 -0
  122. package/LICENSES/dependencies/hashbrown-0.16.1/LICENSE-APACHE +201 -0
  123. package/LICENSES/dependencies/hashbrown-0.16.1/LICENSE-MIT +25 -0
  124. package/LICENSES/dependencies/hashbrown-0.17.1/LICENSE-APACHE +201 -0
  125. package/LICENSES/dependencies/hashbrown-0.17.1/LICENSE-MIT +25 -0
  126. package/LICENSES/dependencies/heck-0.5.0/LICENSE-APACHE +201 -0
  127. package/LICENSES/dependencies/heck-0.5.0/LICENSE-MIT +25 -0
  128. package/LICENSES/dependencies/hermit-abi-0.5.3/LICENSE-APACHE +201 -0
  129. package/LICENSES/dependencies/hermit-abi-0.5.3/LICENSE-MIT +23 -0
  130. package/LICENSES/dependencies/hex-0.4.3/LICENSE-APACHE +202 -0
  131. package/LICENSES/dependencies/hex-0.4.3/LICENSE-MIT +20 -0
  132. package/LICENSES/dependencies/iana-time-zone-0.1.65/LICENSE-APACHE +201 -0
  133. package/LICENSES/dependencies/iana-time-zone-0.1.65/LICENSE-MIT +25 -0
  134. package/LICENSES/dependencies/iana-time-zone-haiku-0.1.2/LICENSE-APACHE +201 -0
  135. package/LICENSES/dependencies/iana-time-zone-haiku-0.1.2/LICENSE-MIT +25 -0
  136. package/LICENSES/dependencies/id-arena-2.3.0/LICENSE-APACHE +201 -0
  137. package/LICENSES/dependencies/id-arena-2.3.0/LICENSE-MIT +25 -0
  138. package/LICENSES/dependencies/ident_case-1.0.1/LICENSE +19 -0
  139. package/LICENSES/dependencies/indexmap-1.9.3/LICENSE-APACHE +201 -0
  140. package/LICENSES/dependencies/indexmap-1.9.3/LICENSE-MIT +25 -0
  141. package/LICENSES/dependencies/indexmap-2.14.2/LICENSE-APACHE +201 -0
  142. package/LICENSES/dependencies/indexmap-2.14.2/LICENSE-MIT +25 -0
  143. package/LICENSES/dependencies/itoa-1.0.18/LICENSE-APACHE +176 -0
  144. package/LICENSES/dependencies/itoa-1.0.18/LICENSE-MIT +23 -0
  145. package/LICENSES/dependencies/jiff-0.2.35/COPYING +3 -0
  146. package/LICENSES/dependencies/jiff-0.2.35/LICENSE-MIT +21 -0
  147. package/LICENSES/dependencies/jiff-0.2.35/UNLICENSE +24 -0
  148. package/LICENSES/dependencies/jiff-core-0.1.0/COPYING +3 -0
  149. package/LICENSES/dependencies/jiff-core-0.1.0/LICENSE-MIT +21 -0
  150. package/LICENSES/dependencies/jiff-core-0.1.0/UNLICENSE +24 -0
  151. package/LICENSES/dependencies/jiff-static-0.2.35/COPYING +3 -0
  152. package/LICENSES/dependencies/jiff-static-0.2.35/LICENSE-MIT +21 -0
  153. package/LICENSES/dependencies/jiff-static-0.2.35/UNLICENSE +24 -0
  154. package/LICENSES/dependencies/jiff-tzdb-0.1.8/COPYING +3 -0
  155. package/LICENSES/dependencies/jiff-tzdb-0.1.8/LICENSE-MIT +21 -0
  156. package/LICENSES/dependencies/jiff-tzdb-0.1.8/UNLICENSE +24 -0
  157. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/COPYING +3 -0
  158. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/LICENSE-MIT +21 -0
  159. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/UNLICENSE +24 -0
  160. package/LICENSES/dependencies/js-sys-0.3.105/LICENSE-APACHE +201 -0
  161. package/LICENSES/dependencies/js-sys-0.3.105/LICENSE-MIT +25 -0
  162. package/LICENSES/dependencies/leb128-0.2.7/LICENSE-APACHE +201 -0
  163. package/LICENSES/dependencies/leb128-0.2.7/LICENSE-MIT +25 -0
  164. package/LICENSES/dependencies/leb128fmt-0.1.0/LICENSE-APACHE +201 -0
  165. package/LICENSES/dependencies/leb128fmt-0.1.0/LICENSE-MIT +23 -0
  166. package/LICENSES/dependencies/libc-0.2.189/LICENSE-APACHE +176 -0
  167. package/LICENSES/dependencies/libc-0.2.189/LICENSE-MIT +25 -0
  168. package/LICENSES/dependencies/linux-raw-sys-0.12.1/COPYRIGHT +29 -0
  169. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-APACHE +201 -0
  170. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  171. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-MIT +23 -0
  172. package/LICENSES/dependencies/log-0.4.34/LICENSE-APACHE +201 -0
  173. package/LICENSES/dependencies/log-0.4.34/LICENSE-MIT +25 -0
  174. package/LICENSES/dependencies/memchr-2.8.3/COPYING +3 -0
  175. package/LICENSES/dependencies/memchr-2.8.3/LICENSE-MIT +21 -0
  176. package/LICENSES/dependencies/memchr-2.8.3/UNLICENSE +24 -0
  177. package/LICENSES/dependencies/mio-1.2.3/LICENSE +19 -0
  178. package/LICENSES/dependencies/num-conv-0.2.2/LICENSE-Apache +177 -0
  179. package/LICENSES/dependencies/num-conv-0.2.2/LICENSE-MIT +19 -0
  180. package/LICENSES/dependencies/num-traits-0.2.19/LICENSE-APACHE +201 -0
  181. package/LICENSES/dependencies/num-traits-0.2.19/LICENSE-MIT +25 -0
  182. package/LICENSES/dependencies/once_cell-1.21.4/LICENSE-APACHE +201 -0
  183. package/LICENSES/dependencies/once_cell-1.21.4/LICENSE-MIT +23 -0
  184. package/LICENSES/dependencies/parking-2.2.1/LICENSE-APACHE +201 -0
  185. package/LICENSES/dependencies/parking-2.2.1/LICENSE-MIT +23 -0
  186. package/LICENSES/dependencies/parking-2.2.1/LICENSE-THIRD-PARTY +9 -0
  187. package/LICENSES/dependencies/pin-project-1.1.13/LICENSE-APACHE +177 -0
  188. package/LICENSES/dependencies/pin-project-1.1.13/LICENSE-MIT +23 -0
  189. package/LICENSES/dependencies/pin-project-internal-1.1.13/LICENSE-APACHE +177 -0
  190. package/LICENSES/dependencies/pin-project-internal-1.1.13/LICENSE-MIT +23 -0
  191. package/LICENSES/dependencies/pin-project-lite-0.2.17/LICENSE-APACHE +177 -0
  192. package/LICENSES/dependencies/pin-project-lite-0.2.17/LICENSE-MIT +23 -0
  193. package/LICENSES/dependencies/piper-0.2.5/LICENSE-APACHE +201 -0
  194. package/LICENSES/dependencies/piper-0.2.5/LICENSE-MIT +23 -0
  195. package/LICENSES/dependencies/polling-3.11.0/LICENSE-APACHE +201 -0
  196. package/LICENSES/dependencies/polling-3.11.0/LICENSE-MIT +23 -0
  197. package/LICENSES/dependencies/portable-atomic-1.15.0/LICENSE-APACHE +177 -0
  198. package/LICENSES/dependencies/portable-atomic-1.15.0/LICENSE-MIT +23 -0
  199. package/LICENSES/dependencies/portable-atomic-util-0.2.8/LICENSE-APACHE +177 -0
  200. package/LICENSES/dependencies/portable-atomic-util-0.2.8/LICENSE-MIT +23 -0
  201. package/LICENSES/dependencies/powerfmt-0.2.0/LICENSE-Apache +202 -0
  202. package/LICENSES/dependencies/powerfmt-0.2.0/LICENSE-MIT +19 -0
  203. package/LICENSES/dependencies/proc-macro2-1.0.107/LICENSE-APACHE +176 -0
  204. package/LICENSES/dependencies/proc-macro2-1.0.107/LICENSE-MIT +23 -0
  205. package/LICENSES/dependencies/quote-1.0.47/LICENSE-APACHE +176 -0
  206. package/LICENSES/dependencies/quote-1.0.47/LICENSE-MIT +23 -0
  207. package/LICENSES/dependencies/r-efi-6.0.0/AUTHORS +75 -0
  208. package/LICENSES/dependencies/rayon-1.12.0/LICENSE-APACHE +201 -0
  209. package/LICENSES/dependencies/rayon-1.12.0/LICENSE-MIT +25 -0
  210. package/LICENSES/dependencies/rayon-core-1.13.0/LICENSE-APACHE +201 -0
  211. package/LICENSES/dependencies/rayon-core-1.13.0/LICENSE-MIT +25 -0
  212. package/LICENSES/dependencies/ref-cast-1.0.27/LICENSE-APACHE +176 -0
  213. package/LICENSES/dependencies/ref-cast-1.0.27/LICENSE-MIT +23 -0
  214. package/LICENSES/dependencies/ref-cast-impl-1.0.27/LICENSE-APACHE +176 -0
  215. package/LICENSES/dependencies/ref-cast-impl-1.0.27/LICENSE-MIT +23 -0
  216. package/LICENSES/dependencies/rustc-demangle-0.1.28/LICENSE-APACHE +201 -0
  217. package/LICENSES/dependencies/rustc-demangle-0.1.28/LICENSE-MIT +25 -0
  218. package/LICENSES/dependencies/rustc-hash-2.1.3/LICENSE-APACHE +176 -0
  219. package/LICENSES/dependencies/rustc-hash-2.1.3/LICENSE-MIT +23 -0
  220. package/LICENSES/dependencies/rustc_version-0.4.1/LICENSE-APACHE +201 -0
  221. package/LICENSES/dependencies/rustc_version-0.4.1/LICENSE-MIT +25 -0
  222. package/LICENSES/dependencies/rustix-1.1.4/COPYRIGHT +29 -0
  223. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-APACHE +201 -0
  224. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  225. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-MIT +23 -0
  226. package/LICENSES/dependencies/rustversion-1.0.23/LICENSE-APACHE +176 -0
  227. package/LICENSES/dependencies/rustversion-1.0.23/LICENSE-MIT +23 -0
  228. package/LICENSES/dependencies/schemars-0.9.0/LICENSE +21 -0
  229. package/LICENSES/dependencies/schemars-1.2.2/LICENSE +21 -0
  230. package/LICENSES/dependencies/schemars_derive-1.2.2/LICENSE +21 -0
  231. package/LICENSES/dependencies/semver-1.0.28/LICENSE-APACHE +176 -0
  232. package/LICENSES/dependencies/semver-1.0.28/LICENSE-MIT +23 -0
  233. package/LICENSES/dependencies/serde-1.0.229/LICENSE-APACHE +176 -0
  234. package/LICENSES/dependencies/serde-1.0.229/LICENSE-MIT +23 -0
  235. package/LICENSES/dependencies/serde_core-1.0.229/LICENSE-APACHE +176 -0
  236. package/LICENSES/dependencies/serde_core-1.0.229/LICENSE-MIT +23 -0
  237. package/LICENSES/dependencies/serde_derive-1.0.229/LICENSE-APACHE +176 -0
  238. package/LICENSES/dependencies/serde_derive-1.0.229/LICENSE-MIT +23 -0
  239. package/LICENSES/dependencies/serde_derive_internals-0.30.0/LICENSE-APACHE +176 -0
  240. package/LICENSES/dependencies/serde_derive_internals-0.30.0/LICENSE-MIT +23 -0
  241. package/LICENSES/dependencies/serde_json-1.0.151/LICENSE-APACHE +176 -0
  242. package/LICENSES/dependencies/serde_json-1.0.151/LICENSE-MIT +23 -0
  243. package/LICENSES/dependencies/serde_with-3.23.0/LICENSE-APACHE +201 -0
  244. package/LICENSES/dependencies/serde_with-3.23.0/LICENSE-MIT +25 -0
  245. package/LICENSES/dependencies/serde_with_macros-3.23.0/LICENSE-APACHE +201 -0
  246. package/LICENSES/dependencies/serde_with_macros-3.23.0/LICENSE-MIT +25 -0
  247. package/LICENSES/dependencies/shell-words-1.1.1/LICENSE-APACHE +201 -0
  248. package/LICENSES/dependencies/shell-words-1.1.1/LICENSE-MIT +25 -0
  249. package/LICENSES/dependencies/shlex-2.0.1/LICENSE-APACHE +13 -0
  250. package/LICENSES/dependencies/shlex-2.0.1/LICENSE-MIT +21 -0
  251. package/LICENSES/dependencies/signal-hook-registry-1.4.8/LICENSE-APACHE +201 -0
  252. package/LICENSES/dependencies/signal-hook-registry-1.4.8/LICENSE-MIT +25 -0
  253. package/LICENSES/dependencies/slab-0.4.12/LICENSE +25 -0
  254. package/LICENSES/dependencies/smallvec-1.16.0/LICENSE-APACHE +201 -0
  255. package/LICENSES/dependencies/smallvec-1.16.0/LICENSE-MIT +25 -0
  256. package/LICENSES/dependencies/socket2-0.6.5/LICENSE-APACHE +201 -0
  257. package/LICENSES/dependencies/socket2-0.6.5/LICENSE-MIT +25 -0
  258. package/LICENSES/dependencies/stable_deref_trait-1.2.1/LICENSE-APACHE +201 -0
  259. package/LICENSES/dependencies/stable_deref_trait-1.2.1/LICENSE-MIT +25 -0
  260. package/LICENSES/dependencies/strsim-0.11.1/LICENSE +23 -0
  261. package/LICENSES/dependencies/strum-0.28.0/LICENSE +21 -0
  262. package/LICENSES/dependencies/strum_macros-0.28.0/LICENSE +21 -0
  263. package/LICENSES/dependencies/syn-2.0.119/LICENSE-APACHE +176 -0
  264. package/LICENSES/dependencies/syn-2.0.119/LICENSE-MIT +23 -0
  265. package/LICENSES/dependencies/syn-3.0.5/LICENSE-APACHE +176 -0
  266. package/LICENSES/dependencies/syn-3.0.5/LICENSE-MIT +23 -0
  267. package/LICENSES/dependencies/thiserror-2.0.20/LICENSE-APACHE +176 -0
  268. package/LICENSES/dependencies/thiserror-2.0.20/LICENSE-MIT +23 -0
  269. package/LICENSES/dependencies/thiserror-impl-2.0.20/LICENSE-APACHE +176 -0
  270. package/LICENSES/dependencies/thiserror-impl-2.0.20/LICENSE-MIT +23 -0
  271. package/LICENSES/dependencies/time-0.3.55/LICENSE-Apache +177 -0
  272. package/LICENSES/dependencies/time-0.3.55/LICENSE-MIT +19 -0
  273. package/LICENSES/dependencies/time-core-0.1.9/LICENSE-Apache +177 -0
  274. package/LICENSES/dependencies/time-core-0.1.9/LICENSE-MIT +19 -0
  275. package/LICENSES/dependencies/time-macros-0.2.32/LICENSE-Apache +177 -0
  276. package/LICENSES/dependencies/time-macros-0.2.32/LICENSE-MIT +19 -0
  277. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-APACHE.md +202 -0
  278. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-MIT.md +5 -0
  279. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-ZLIB.md +11 -0
  280. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-APACHE.md +202 -0
  281. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-MIT.md +21 -0
  282. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-ZLIB.md +20 -0
  283. package/LICENSES/dependencies/tokio-1.53.1/LICENSE +21 -0
  284. package/LICENSES/dependencies/tokio-macros-2.7.2/LICENSE +22 -0
  285. package/LICENSES/dependencies/tracing-0.1.44/LICENSE +25 -0
  286. package/LICENSES/dependencies/tracing-attributes-0.1.31/LICENSE +25 -0
  287. package/LICENSES/dependencies/tracing-core-0.1.36/LICENSE +25 -0
  288. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-APACHE +176 -0
  289. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-MIT +23 -0
  290. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-UNICODE +39 -0
  291. package/LICENSES/dependencies/unicode-segmentation-1.13.3/COPYRIGHT +7 -0
  292. package/LICENSES/dependencies/unicode-segmentation-1.13.3/LICENSE-APACHE +201 -0
  293. package/LICENSES/dependencies/unicode-segmentation-1.13.3/LICENSE-MIT +25 -0
  294. package/LICENSES/dependencies/unicode-xid-0.2.6/COPYRIGHT +7 -0
  295. package/LICENSES/dependencies/unicode-xid-0.2.6/LICENSE-APACHE +201 -0
  296. package/LICENSES/dependencies/unicode-xid-0.2.6/LICENSE-MIT +25 -0
  297. package/LICENSES/dependencies/uuid-1.26.1/LICENSE-APACHE +201 -0
  298. package/LICENSES/dependencies/uuid-1.26.1/LICENSE-MIT +26 -0
  299. package/LICENSES/dependencies/walrus-0.26.5/LICENSE-APACHE +201 -0
  300. package/LICENSES/dependencies/walrus-0.26.5/LICENSE-MIT +25 -0
  301. package/LICENSES/dependencies/walrus-macro-0.26.0/LICENSE-APACHE +201 -0
  302. package/LICENSES/dependencies/walrus-macro-0.26.0/LICENSE-MIT +25 -0
  303. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-APACHE +201 -0
  304. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  305. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-MIT +23 -0
  306. package/LICENSES/dependencies/wasm-bindgen-0.2.128/LICENSE-APACHE +201 -0
  307. package/LICENSES/dependencies/wasm-bindgen-0.2.128/LICENSE-MIT +25 -0
  308. package/LICENSES/dependencies/wasm-bindgen-cli-support-0.2.128/LICENSE-APACHE +201 -0
  309. package/LICENSES/dependencies/wasm-bindgen-cli-support-0.2.128/LICENSE-MIT +25 -0
  310. package/LICENSES/dependencies/wasm-bindgen-macro-0.2.128/LICENSE-APACHE +201 -0
  311. package/LICENSES/dependencies/wasm-bindgen-macro-0.2.128/LICENSE-MIT +25 -0
  312. package/LICENSES/dependencies/wasm-bindgen-macro-support-0.2.128/LICENSE-APACHE +201 -0
  313. package/LICENSES/dependencies/wasm-bindgen-macro-support-0.2.128/LICENSE-MIT +25 -0
  314. package/LICENSES/dependencies/wasm-bindgen-shared-0.2.128/LICENSE-APACHE +201 -0
  315. package/LICENSES/dependencies/wasm-bindgen-shared-0.2.128/LICENSE-MIT +25 -0
  316. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-APACHE +201 -0
  317. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  318. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-MIT +23 -0
  319. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-APACHE +201 -0
  320. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  321. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-MIT +23 -0
  322. package/LICENSES/dependencies/windows-core-0.62.2/license-apache-2.0 +201 -0
  323. package/LICENSES/dependencies/windows-core-0.62.2/license-mit +21 -0
  324. package/LICENSES/dependencies/windows-implement-0.60.2/license-apache-2.0 +201 -0
  325. package/LICENSES/dependencies/windows-implement-0.60.2/license-mit +21 -0
  326. package/LICENSES/dependencies/windows-interface-0.59.3/license-apache-2.0 +201 -0
  327. package/LICENSES/dependencies/windows-interface-0.59.3/license-mit +21 -0
  328. package/LICENSES/dependencies/windows-link-0.2.1/license-apache-2.0 +201 -0
  329. package/LICENSES/dependencies/windows-link-0.2.1/license-mit +21 -0
  330. package/LICENSES/dependencies/windows-result-0.4.1/license-apache-2.0 +201 -0
  331. package/LICENSES/dependencies/windows-result-0.4.1/license-mit +21 -0
  332. package/LICENSES/dependencies/windows-strings-0.5.1/license-apache-2.0 +201 -0
  333. package/LICENSES/dependencies/windows-strings-0.5.1/license-mit +21 -0
  334. package/LICENSES/dependencies/windows-sys-0.61.2/license-apache-2.0 +201 -0
  335. package/LICENSES/dependencies/windows-sys-0.61.2/license-mit +21 -0
  336. package/LICENSES/dependencies/zmij-1.0.23/LICENSE-MIT +23 -0
  337. package/README.md +185 -0
  338. package/THIRD-PARTY.md +45 -0
  339. package/index.d.ts +47 -0
  340. package/index.js +28 -0
  341. package/package.json +36 -0
  342. package/source/.cargo/config.toml +5 -0
  343. package/source/.ci/upstream-notices/PROVENANCE.json +198 -0
  344. package/source/.ci/upstream-notices/agent-client-protocol-2.1.0/LICENSE +191 -0
  345. package/source/.ci/upstream-notices/agent-client-protocol-derive-2.1.0/LICENSE +191 -0
  346. package/source/.ci/upstream-notices/agent-client-protocol-schema-1.7.0/LICENSE +190 -0
  347. package/source/.ci/upstream-notices/defmt-parser-1.0.0/LICENSE-APACHE +201 -0
  348. package/source/.ci/upstream-notices/defmt-parser-1.0.0/LICENSE-MIT +25 -0
  349. package/source/.ci/upstream-notices/r-efi-6.0.0/AUTHORS +75 -0
  350. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-APACHE +201 -0
  351. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  352. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-MIT +23 -0
  353. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-APACHE +201 -0
  354. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  355. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-MIT +23 -0
  356. package/source/.ci/wasm-bundle/Cargo.toml +10 -0
  357. package/source/.ci/wasm-bundle/src/main.rs +17 -0
  358. package/source/CHANGELOG.md +11 -0
  359. package/source/Cargo.lock +1622 -0
  360. package/source/Cargo.toml +48 -0
  361. package/source/LICENSE +307 -0
  362. package/source/LICENSE.md +25 -0
  363. package/source/LICENSES/GPL-3.0-only.txt +232 -0
  364. package/source/LICENSES/LGPL-3.0-only.txt +304 -0
  365. package/source/README.md +185 -0
  366. package/source/THIRD-PARTY.md +45 -0
  367. package/source/dependencies.tar.gz +0 -0
  368. package/source/examples/native.rs +45 -0
  369. package/source/src/conversation.rs +557 -0
  370. package/source/src/lib.rs +27 -0
  371. package/source/src/native/client.rs +417 -0
  372. package/source/src/native/fixture.py +104 -0
  373. package/source/src/native/mod.rs +249 -0
  374. package/source/src/native/session.rs +541 -0
  375. package/source/src/native/tests.rs +427 -0
  376. package/source/src/web.rs +35 -0
  377. package/wasm/ccht.d.ts +60 -0
  378. package/wasm/ccht.js +275 -0
  379. package/wasm/ccht_bg.wasm +0 -0
  380. package/wasm/ccht_bg.wasm.d.ts +13 -0
@@ -0,0 +1,417 @@
1
+ use std::sync::{Arc, Mutex};
2
+
3
+ use agent_client_protocol::schema::ProtocolVersion;
4
+ use agent_client_protocol::{AcpAgent, AcpAgentConfig, ActiveSession, Agent, Client, ConnectionTo};
5
+ use tokio::sync::{oneshot, watch};
6
+ use tokio::task::JoinHandle;
7
+ use tokio::time::timeout;
8
+
9
+ use crate::acp::{
10
+ AuthMethod, AuthenticateRequest, InitializeRequest, InitializeResponse, LoadSessionRequest,
11
+ McpServer, NewSessionRequest, ResumeSessionRequest, SessionConfigKind,
12
+ SessionConfigOptionCategory, SessionConfigSelectOptions, SetSessionConfigOptionRequest,
13
+ };
14
+
15
+ use super::{
16
+ AgentCommand, NativeError, NativeOptions, NativeSession, Result, SessionOptions, lock,
17
+ };
18
+
19
+ /// A connection to one explicitly selected, externally authenticated ACP agent.
20
+ ///
21
+ /// Clones and active sessions share this connection. Closing the client closes
22
+ /// every session on it. No credentials are stored and no API fallback is attempted.
23
+ #[derive(Clone)]
24
+ pub struct NativeClient {
25
+ pub(super) inner: Arc<ClientLease>,
26
+ }
27
+
28
+ pub(super) struct ClientLease {
29
+ pub(super) state: Arc<ClientState>,
30
+ pub(super) connection: ConnectionTo<Agent>,
31
+ pub(super) info: InitializeResponse,
32
+ pub(super) options: NativeOptions,
33
+ }
34
+
35
+ pub(super) struct ClientState {
36
+ shutdown: watch::Sender<bool>,
37
+ pub(super) closed: watch::Sender<bool>,
38
+ failure: Mutex<Option<NativeError>>,
39
+ task: Mutex<Option<JoinHandle<()>>>,
40
+ }
41
+
42
+ impl ClientState {
43
+ pub(super) fn abort(&self) {
44
+ self.shutdown.send_replace(true);
45
+ self.closed.send_replace(true);
46
+ if let Some(task) = lock(&self.task).as_ref() {
47
+ task.abort();
48
+ }
49
+ }
50
+
51
+ pub(super) fn error(&self) -> NativeError {
52
+ lock(&self.failure).clone().unwrap_or(NativeError::Closed)
53
+ }
54
+
55
+ pub(super) fn is_closed(&self) -> bool {
56
+ *self.closed.borrow()
57
+ }
58
+ }
59
+
60
+ impl Drop for ClientLease {
61
+ fn drop(&mut self) {
62
+ self.state.abort();
63
+ }
64
+ }
65
+
66
+ struct Connecting(Option<Arc<ClientState>>);
67
+
68
+ impl Drop for Connecting {
69
+ fn drop(&mut self) {
70
+ if let Some(state) = &self.0 {
71
+ state.abort();
72
+ }
73
+ }
74
+ }
75
+
76
+ impl NativeClient {
77
+ /// Spawn the configured agent through the SDK and negotiate stable ACP v1.
78
+ ///
79
+ /// Requires a caller-owned Tokio runtime. No terminal or filesystem client
80
+ /// capabilities are advertised. Authentication remains with the agent.
81
+ pub async fn connect(command: AgentCommand, options: NativeOptions) -> Result<Self> {
82
+ let runtime =
83
+ tokio::runtime::Handle::try_current().map_err(|_| NativeError::RuntimeUnavailable)?;
84
+ if command.program.as_os_str().is_empty()
85
+ || options.event_capacity == 0
86
+ || options.operation_timeout.is_zero()
87
+ || options.prompt_timeout.is_zero()
88
+ || options.permission_timeout.is_zero()
89
+ || options.shutdown_timeout.is_zero()
90
+ {
91
+ return Err(NativeError::InvalidOptions(
92
+ "executable and positive limits are required",
93
+ ));
94
+ }
95
+ if command
96
+ .env
97
+ .iter()
98
+ .any(|(key, value)| api_credential_variable(key) && !value.is_empty())
99
+ {
100
+ return Err(NativeError::InvalidOptions(
101
+ "API credential environment overrides are not accepted",
102
+ ));
103
+ }
104
+ let mut config = AcpAgentConfig::new(command.program)
105
+ .args(command.args)
106
+ .envs(command.env);
107
+ // The SDK inherits the host environment. Empty known API credential
108
+ // variables so an ambient key cannot silently replace native agent login.
109
+ // The agent's own saved credentials and billing settings remain its concern.
110
+ for (key, _) in std::env::vars_os() {
111
+ if let Some(key) = key.to_str().filter(|key| api_credential_variable(key)) {
112
+ config = config.env(key, "");
113
+ }
114
+ }
115
+ let agent = AcpAgent::new(config);
116
+ let (ready_tx, ready_rx) = oneshot::channel();
117
+ let (shutdown, mut shutdown_rx) = watch::channel(false);
118
+ let (closed, _) = watch::channel(false);
119
+ let state = Arc::new(ClientState {
120
+ shutdown,
121
+ closed,
122
+ failure: Mutex::new(None),
123
+ task: Mutex::new(None),
124
+ });
125
+ let mut guard = Connecting(Some(state.clone()));
126
+ let worker_state = Arc::downgrade(&state);
127
+ let task = runtime.spawn(async move {
128
+ let outcome = Client
129
+ .builder()
130
+ .connect_with(agent, async move |connection| {
131
+ let info = connection
132
+ .send_request(InitializeRequest::new(ProtocolVersion::V1))
133
+ .block_task()
134
+ .await?;
135
+ if info.protocol_version != ProtocolVersion::V1 {
136
+ return Err(agent_client_protocol::Error::new(
137
+ -32600,
138
+ "unsupported ACP version",
139
+ ));
140
+ }
141
+ if ready_tx.send((connection.clone(), info)).is_err() {
142
+ return Ok(());
143
+ }
144
+ tokio::select! {
145
+ _ = shutdown_rx.changed() => {},
146
+ _ = connection.incoming_closed() => {},
147
+ }
148
+ Ok(())
149
+ })
150
+ .await;
151
+ if let Some(state) = worker_state.upgrade() {
152
+ if let Err(error) = outcome {
153
+ *lock(&state.failure) = Some(error.into());
154
+ }
155
+ state.closed.send_replace(true);
156
+ }
157
+ });
158
+ *lock(&state.task) = Some(task);
159
+ let (connection, info) = match timeout(options.operation_timeout, ready_rx).await {
160
+ Ok(Ok(ready)) => ready,
161
+ Ok(Err(_)) => {
162
+ let mut closed = state.closed.subscribe();
163
+ if !state.is_closed() {
164
+ let _ = timeout(options.shutdown_timeout, closed.changed()).await;
165
+ }
166
+ return Err(state.error());
167
+ }
168
+ Err(_) => return Err(NativeError::Timeout),
169
+ };
170
+ guard.0 = None;
171
+ Ok(Self {
172
+ inner: Arc::new(ClientLease {
173
+ state,
174
+ connection,
175
+ info,
176
+ options,
177
+ }),
178
+ })
179
+ }
180
+
181
+ /// The agent's exact negotiated capabilities, implementation, and auth methods.
182
+ pub fn info(&self) -> &InitializeResponse {
183
+ &self.inner.info
184
+ }
185
+
186
+ /// Invoke an explicitly selected agent-owned authentication method.
187
+ ///
188
+ /// Terminal authentication is left to the application or the agent's CLI.
189
+ /// The method must have been advertised; none is selected automatically.
190
+ pub async fn authenticate(&self, method_id: &str) -> Result<()> {
191
+ match self
192
+ .info()
193
+ .auth_methods
194
+ .iter()
195
+ .find(|method| method.id().0.as_ref() == method_id)
196
+ {
197
+ Some(AuthMethod::Agent(_)) => {}
198
+ Some(_) => {
199
+ return Err(NativeError::Unsupported(
200
+ "terminal authentication through this client",
201
+ ));
202
+ }
203
+ None => {
204
+ return Err(NativeError::Unsupported(
205
+ "the selected authentication method",
206
+ ));
207
+ }
208
+ }
209
+ self.operation(
210
+ self.inner
211
+ .connection
212
+ .send_request(AuthenticateRequest::new(method_id.to_owned()))
213
+ .block_task(),
214
+ )
215
+ .await?;
216
+ Ok(())
217
+ }
218
+
219
+ /// Create an independent conversation in an application-selected directory.
220
+ pub async fn new_session(&self, options: SessionOptions) -> Result<NativeSession> {
221
+ self.validate_session(&options)?;
222
+ let request = NewSessionRequest::new(&options.cwd).mcp_servers(options.mcp_servers.clone());
223
+ let session = self
224
+ .operation(
225
+ self.inner
226
+ .connection
227
+ .build_session_from(request)
228
+ .block_task()
229
+ .start_session(),
230
+ )
231
+ .await?;
232
+ self.finish_session(session, options).await
233
+ }
234
+
235
+ /// Restore a known agent session, preserving the agent's replayed history events.
236
+ pub async fn load_session(
237
+ &self,
238
+ agent_session_id: &str,
239
+ options: SessionOptions,
240
+ ) -> Result<NativeSession> {
241
+ if !self.info().agent_capabilities.load_session {
242
+ return Err(NativeError::Unsupported("session history loading"));
243
+ }
244
+ self.validate_session(&options)?;
245
+ let request = LoadSessionRequest::new(agent_session_id.to_owned(), &options.cwd)
246
+ .mcp_servers(options.mcp_servers.clone());
247
+ let restored = self
248
+ .operation(
249
+ self.inner
250
+ .connection
251
+ .load_session_from(request)
252
+ .block_task()
253
+ .start_session(),
254
+ )
255
+ .await?;
256
+ self.finish_session(restored.into_session(), options).await
257
+ }
258
+
259
+ /// Resume a known session without replay, only when the agent advertises support.
260
+ pub async fn resume_session(
261
+ &self,
262
+ agent_session_id: &str,
263
+ options: SessionOptions,
264
+ ) -> Result<NativeSession> {
265
+ if self
266
+ .info()
267
+ .agent_capabilities
268
+ .session_capabilities
269
+ .resume
270
+ .is_none()
271
+ {
272
+ return Err(NativeError::Unsupported(
273
+ "session resumption without replay",
274
+ ));
275
+ }
276
+ self.validate_session(&options)?;
277
+ let request = ResumeSessionRequest::new(agent_session_id.to_owned(), &options.cwd)
278
+ .mcp_servers(options.mcp_servers.clone());
279
+ let restored = self
280
+ .operation(
281
+ self.inner
282
+ .connection
283
+ .resume_session_from(request)
284
+ .block_task()
285
+ .start_session(),
286
+ )
287
+ .await?;
288
+ self.finish_session(restored.into_session(), options).await
289
+ }
290
+
291
+ async fn finish_session(
292
+ &self,
293
+ session: ActiveSession<'static, Agent>,
294
+ options: SessionOptions,
295
+ ) -> Result<NativeSession> {
296
+ if let Some(model) = options.model {
297
+ let config = session
298
+ .config_options()
299
+ .unwrap_or_default()
300
+ .iter()
301
+ .find(|option| {
302
+ option.category == Some(SessionConfigOptionCategory::Model)
303
+ || option.id.0.as_ref() == "model"
304
+ })
305
+ .ok_or(NativeError::Unsupported("model selection"))?;
306
+ let SessionConfigKind::Select(select) = &config.kind else {
307
+ return Err(NativeError::Unsupported("model selection"));
308
+ };
309
+ let available = match &select.options {
310
+ SessionConfigSelectOptions::Ungrouped(options) => options
311
+ .iter()
312
+ .any(|option| option.value.0.as_ref() == model),
313
+ SessionConfigSelectOptions::Grouped(groups) => groups.iter().any(|group| {
314
+ group
315
+ .options
316
+ .iter()
317
+ .any(|option| option.value.0.as_ref() == model)
318
+ }),
319
+ _ => false,
320
+ };
321
+ if !available {
322
+ return Err(NativeError::Unsupported("the selected model"));
323
+ }
324
+ self.operation(
325
+ self.inner
326
+ .connection
327
+ .send_request(SetSessionConfigOptionRequest::new(
328
+ session.session_id().clone(),
329
+ config.id.clone(),
330
+ model.as_str(),
331
+ ))
332
+ .block_task(),
333
+ )
334
+ .await?;
335
+ }
336
+ NativeSession::start(self.inner.clone(), session)
337
+ }
338
+
339
+ fn validate_session(&self, options: &SessionOptions) -> Result<()> {
340
+ if self.inner.state.is_closed() {
341
+ return Err(self.inner.state.error());
342
+ }
343
+ if !options.cwd.is_absolute() || !options.cwd.is_dir() {
344
+ return Err(NativeError::InvalidOptions(
345
+ "session cwd must be an existing absolute directory",
346
+ ));
347
+ }
348
+ let capabilities = &self.info().agent_capabilities.mcp_capabilities;
349
+ for server in &options.mcp_servers {
350
+ match server {
351
+ McpServer::Stdio(_) => {}
352
+ McpServer::Http(_) if capabilities.http => {}
353
+ McpServer::Sse(_) if capabilities.sse => {}
354
+ _ => return Err(NativeError::Unsupported("the requested MCP transport")),
355
+ }
356
+ }
357
+ Ok(())
358
+ }
359
+
360
+ async fn operation<T>(
361
+ &self,
362
+ future: impl std::future::Future<Output = std::result::Result<T, agent_client_protocol::Error>>,
363
+ ) -> Result<T> {
364
+ if self.inner.state.is_closed() {
365
+ return Err(self.inner.state.error());
366
+ }
367
+ match timeout(self.inner.options.operation_timeout, future).await {
368
+ Ok(Ok(value)) => Ok(value),
369
+ Ok(Err(error)) => {
370
+ if error.code == crate::acp::ErrorCode::InternalError {
371
+ tokio::task::yield_now().await;
372
+ }
373
+ if self.inner.state.is_closed() {
374
+ Err(self.inner.state.error())
375
+ } else {
376
+ Err(error.into())
377
+ }
378
+ }
379
+ Err(_) => {
380
+ self.inner.state.abort();
381
+ Err(NativeError::Timeout)
382
+ }
383
+ }
384
+ }
385
+
386
+ /// Close every session and wait a bounded time for the SDK to clean up its child.
387
+ pub async fn close(&self) -> Result<()> {
388
+ self.inner.state.shutdown.send_replace(true);
389
+ let task = lock(&self.inner.state.task).take();
390
+ if let Some(mut task) = task
391
+ && timeout(self.inner.options.shutdown_timeout, &mut task)
392
+ .await
393
+ .is_err()
394
+ {
395
+ task.abort();
396
+ self.inner.state.closed.send_replace(true);
397
+ return Err(NativeError::Timeout);
398
+ }
399
+ self.inner.state.closed.send_replace(true);
400
+ Ok(())
401
+ }
402
+ }
403
+
404
+ fn api_credential_variable(key: &str) -> bool {
405
+ let upper = key.to_ascii_uppercase();
406
+ upper.ends_with("_API_KEY")
407
+ || matches!(
408
+ upper.as_str(),
409
+ "ANTHROPIC_AUTH_TOKEN"
410
+ | "AZURE_OPENAI_KEY"
411
+ | "AWS_BEARER_TOKEN_BEDROCK"
412
+ | "GOOGLE_APPLICATION_CREDENTIALS"
413
+ | "AWS_ACCESS_KEY_ID"
414
+ | "AWS_SECRET_ACCESS_KEY"
415
+ | "AWS_SESSION_TOKEN"
416
+ )
417
+ }
@@ -0,0 +1,104 @@
1
+ """Offline ACP peer for exercising the public native client through real stdio."""
2
+ import json
3
+ import os
4
+ import pathlib
5
+ import subprocess
6
+ import sys
7
+ import time
8
+
9
+ mode = sys.argv[1]
10
+ sessions = 0
11
+ pending = {}
12
+ permissions = {}
13
+ permission_id = 100
14
+ if len(sys.argv) > 2:
15
+ child = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(60)"])
16
+ pathlib.Path(sys.argv[2]).write_text(json.dumps({"agent": os.getpid(), "descendant": child.pid}))
17
+
18
+
19
+ def send(value):
20
+ print(json.dumps({"jsonrpc": "2.0", **value}), flush=True)
21
+
22
+
23
+ def response(request_id, result):
24
+ send({"id": request_id, "result": result})
25
+
26
+
27
+ def update(session, text):
28
+ send({"method": "session/update", "params": {"sessionId": session,
29
+ "update": {"sessionUpdate": "agent_message_chunk",
30
+ "content": {"type": "text", "text": text}}}})
31
+
32
+
33
+ for line in sys.stdin:
34
+ message = json.loads(line)
35
+ method = message.get("method")
36
+ params = message.get("params", {})
37
+ request_id = message.get("id")
38
+ if method == "initialize":
39
+ if mode == "slow_init":
40
+ time.sleep(60)
41
+ response(request_id, {"protocolVersion": 1,
42
+ "agentCapabilities": {"loadSession": True,
43
+ "sessionCapabilities": {"resume": {}, "close": {}}},
44
+ "agentInfo": {"name": "offline-fixture", "version": "1"}})
45
+ elif method in ("session/new", "session/load", "session/resume"):
46
+ if mode == "auth_required":
47
+ send({"id": request_id, "error": {"code": -32000,
48
+ "message": "SECRET-SHOULD-NOT-ESCAPE", "data": {"token": "SECRET"}}})
49
+ continue
50
+ sessions += 1
51
+ session = params.get("sessionId", "fixture-" + str(sessions))
52
+ if method == "session/load":
53
+ update(session, "restored history")
54
+ response(request_id, {"sessionId": session, "configOptions": [{
55
+ "id": "model", "name": "Model", "category": "model", "type": "select",
56
+ "currentValue": "test-model", "options": [{"value": "test-model", "name": "Test"}]}]})
57
+ elif method == "session/set_config_option":
58
+ response(request_id, {"configOptions": []})
59
+ elif method == "session/prompt":
60
+ session = params["sessionId"]
61
+ pending[session] = request_id
62
+ if mode == "exit":
63
+ sys.exit(2)
64
+ if mode in ("ask", "deny", "unsupported_host_request"):
65
+ permission_id += 1
66
+ permissions[permission_id] = session
67
+ if mode == "unsupported_host_request":
68
+ send({"id": permission_id, "method": "fs/read_text_file",
69
+ "params": {"sessionId": session, "path": "/never-read-this"}})
70
+ else:
71
+ send({"id": permission_id, "method": "session/request_permission", "params": {
72
+ "sessionId": session, "toolCall": {"toolCallId": "tool-1", "title": "Test action"},
73
+ "options": [{"optionId": "allow", "name": "Allow once", "kind": "allow_once"},
74
+ {"optionId": "reject", "name": "Reject once", "kind": "reject_once"}]}})
75
+ elif mode in ("hang", "ignore_cancel"):
76
+ update(session, "waiting")
77
+ else:
78
+ if mode == "startup_cwd":
79
+ update(session, os.getcwd())
80
+ elif mode == "burst":
81
+ for _ in range(1000):
82
+ update(session, "x")
83
+ else:
84
+ update(session, "hello ")
85
+ update(session, "world")
86
+ response(pending.pop(session), {"stopReason": "end_turn"})
87
+ elif method == "session/cancel":
88
+ session = params["sessionId"]
89
+ if mode != "ignore_cancel" and session in pending:
90
+ response(pending.pop(session), {"stopReason": "cancelled"})
91
+ elif method == "session/close":
92
+ response(request_id, {})
93
+ elif method is None and request_id in permissions:
94
+ session = permissions.pop(request_id)
95
+ if mode == "unsupported_host_request":
96
+ assert message["error"]["code"] == -32601
97
+ text = "unsupported"
98
+ else:
99
+ outcome = message["result"]["outcome"]
100
+ text = outcome.get("optionId", outcome["outcome"])
101
+ update(session, text)
102
+ response(pending.pop(session), {"stopReason": "end_turn"})
103
+ elif request_id is not None:
104
+ send({"id": request_id, "error": {"code": -32601, "message": "Unsupported fixture request"}})