@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,427 @@
1
+ use super::*;
2
+ use crate::acp::{ContentBlock, SelectedPermissionOutcome, SessionUpdate, StopReason};
3
+ use crate::{Event, Prompt, SessionEvent};
4
+ use tokio::sync::mpsc;
5
+ use tokio::time::timeout;
6
+
7
+ fn options() -> NativeOptions {
8
+ NativeOptions {
9
+ operation_timeout: Duration::from_secs(5),
10
+ prompt_timeout: Duration::from_secs(5),
11
+ permission_timeout: Duration::from_secs(2),
12
+ shutdown_timeout: Duration::from_secs(2),
13
+ ..NativeOptions::default()
14
+ }
15
+ }
16
+
17
+ fn command(mode: &str) -> AgentCommand {
18
+ AgentCommand::new("python3").args(["-u", "-c", include_str!("fixture.py"), mode])
19
+ }
20
+
21
+ fn prompt(id: &str) -> Prompt {
22
+ Prompt {
23
+ request_id: id.into(),
24
+ content: vec!["test".into()],
25
+ }
26
+ }
27
+
28
+ async fn session(
29
+ mode: &str,
30
+ options: NativeOptions,
31
+ ) -> (
32
+ NativeClient,
33
+ NativeSession,
34
+ SessionHandle,
35
+ mpsc::Receiver<SessionEvent>,
36
+ ) {
37
+ let client = NativeClient::connect(command(mode), options).await.unwrap();
38
+ let mut session = client
39
+ .new_session(SessionOptions::new(std::env::temp_dir()))
40
+ .await
41
+ .unwrap();
42
+ let handle = session.handle();
43
+ let events = session.take_events().unwrap();
44
+ (client, session, handle, events)
45
+ }
46
+
47
+ fn text(event: &SessionEvent) -> Option<&str> {
48
+ match &event.event {
49
+ Event::Update {
50
+ update: SessionUpdate::AgentMessageChunk(chunk),
51
+ } => {
52
+ if let ContentBlock::Text(content) = &chunk.content {
53
+ Some(&content.text)
54
+ } else {
55
+ None
56
+ }
57
+ }
58
+ _ => None,
59
+ }
60
+ }
61
+
62
+ #[tokio::test]
63
+ async fn ordered_stream_and_multiple_turns_keep_one_session() {
64
+ let (client, _session, handle, mut events) = session("normal", options()).await;
65
+ for id in ["first", "second"] {
66
+ assert_eq!(
67
+ handle.prompt(prompt(id)).await.unwrap(),
68
+ StopReason::EndTurn
69
+ );
70
+ let first = events.recv().await.unwrap();
71
+ let second = events.recv().await.unwrap();
72
+ let completed = events.recv().await.unwrap();
73
+ assert_eq!(first.request_id.as_deref(), Some(id));
74
+ assert_eq!(text(&first), Some("hello "));
75
+ assert_eq!(text(&second), Some("world"));
76
+ assert!(matches!(
77
+ completed.event,
78
+ Event::Completed {
79
+ stop_reason: StopReason::EndTurn
80
+ }
81
+ ));
82
+ }
83
+ handle.close().await.unwrap();
84
+ assert!(events.recv().await.is_none());
85
+ client.close().await.unwrap();
86
+ }
87
+
88
+ #[tokio::test]
89
+ async fn default_permissions_deny_without_user_approval() {
90
+ let (client, _session, handle, mut events) = session("deny", options()).await;
91
+ handle.prompt(prompt("deny")).await.unwrap();
92
+ assert_eq!(text(&events.recv().await.unwrap()), Some("cancelled"));
93
+ assert!(matches!(
94
+ events.recv().await.unwrap().event,
95
+ Event::Completed { .. }
96
+ ));
97
+ client.close().await.unwrap();
98
+ }
99
+
100
+ #[tokio::test]
101
+ async fn permission_responses_are_validated_and_isolated_between_sessions() {
102
+ let mut options = options();
103
+ options.permissions = PermissionPolicy::Ask;
104
+ let (client, _first, handle, mut events) = session("ask", options).await;
105
+ let mut second = client
106
+ .new_session(SessionOptions::new(std::env::temp_dir()))
107
+ .await
108
+ .unwrap();
109
+ let other = second.handle();
110
+ let mut other_events = second.take_events().unwrap();
111
+ let first_prompt = tokio::spawn({
112
+ let handle = handle.clone();
113
+ async move { handle.prompt(prompt("first")).await }
114
+ });
115
+ let second_prompt = tokio::spawn({
116
+ let other = other.clone();
117
+ async move { other.prompt(prompt("second")).await }
118
+ });
119
+ let first_request = events.recv().await.unwrap();
120
+ let second_request = other_events.recv().await.unwrap();
121
+ let Event::Permission {
122
+ request_id,
123
+ request,
124
+ } = first_request.event
125
+ else {
126
+ panic!("permission event expected")
127
+ };
128
+ let Event::Permission {
129
+ request_id: second_id,
130
+ request: second_request,
131
+ } = second_request.event
132
+ else {
133
+ panic!("permission event expected")
134
+ };
135
+ assert_ne!(request.session_id, second_request.session_id);
136
+ assert_ne!(request_id, second_id);
137
+ assert_eq!(
138
+ other
139
+ .respond_permission(&request_id, PermissionDecision::Cancelled)
140
+ .await
141
+ .unwrap_err(),
142
+ NativeError::UnknownPermission
143
+ );
144
+ let invalid = PermissionDecision::Selected(SelectedPermissionOutcome::new("not-offered"));
145
+ assert_eq!(
146
+ handle
147
+ .respond_permission(&request_id, invalid)
148
+ .await
149
+ .unwrap_err(),
150
+ NativeError::InvalidPermissionOption
151
+ );
152
+ handle
153
+ .respond_permission(
154
+ &request_id,
155
+ PermissionDecision::Selected(SelectedPermissionOutcome::new("allow")),
156
+ )
157
+ .await
158
+ .unwrap();
159
+ assert_eq!(first_prompt.await.unwrap().unwrap(), StopReason::EndTurn);
160
+ assert!(!second_prompt.is_finished());
161
+ other
162
+ .respond_permission(&second_id, PermissionDecision::Cancelled)
163
+ .await
164
+ .unwrap();
165
+ assert_eq!(second_prompt.await.unwrap().unwrap(), StopReason::EndTurn);
166
+ assert_eq!(
167
+ handle
168
+ .respond_permission(&request_id, PermissionDecision::Cancelled)
169
+ .await
170
+ .unwrap_err(),
171
+ NativeError::UnknownPermission
172
+ );
173
+ client.close().await.unwrap();
174
+ }
175
+
176
+ #[tokio::test]
177
+ async fn active_prompt_rejects_overlap_and_cancels_cooperatively() {
178
+ let (client, _session, handle, mut events) = session("hang", options()).await;
179
+ let running = tokio::spawn({
180
+ let handle = handle.clone();
181
+ async move { handle.prompt(prompt("first")).await }
182
+ });
183
+ assert_eq!(text(&events.recv().await.unwrap()), Some("waiting"));
184
+ assert_eq!(
185
+ handle.prompt(prompt("overlap")).await.unwrap_err(),
186
+ NativeError::Busy
187
+ );
188
+ handle.cancel().await.unwrap();
189
+ assert_eq!(running.await.unwrap().unwrap(), StopReason::Cancelled);
190
+ assert!(matches!(
191
+ events.recv().await.unwrap().event,
192
+ Event::Completed {
193
+ stop_reason: StopReason::Cancelled
194
+ }
195
+ ));
196
+ client.close().await.unwrap();
197
+ }
198
+
199
+ #[tokio::test]
200
+ async fn ignored_cancellation_and_abandoned_prompts_close_the_connection() {
201
+ let mut limits = options();
202
+ limits.shutdown_timeout = Duration::from_millis(100);
203
+ let (client, _session, handle, mut events) = session("ignore_cancel", limits).await;
204
+ let running = tokio::spawn({
205
+ let handle = handle.clone();
206
+ async move { handle.prompt(prompt("first")).await }
207
+ });
208
+ events.recv().await.unwrap();
209
+ assert_eq!(handle.cancel().await.unwrap_err(), NativeError::Timeout);
210
+ assert!(running.await.unwrap().is_err());
211
+ assert!(
212
+ client
213
+ .new_session(SessionOptions::new(std::env::temp_dir()))
214
+ .await
215
+ .is_err()
216
+ );
217
+
218
+ let (client, _session, handle, mut events) = session("hang", options()).await;
219
+ let running = tokio::spawn({
220
+ let handle = handle.clone();
221
+ async move { handle.prompt(prompt("abandoned")).await }
222
+ });
223
+ events.recv().await.unwrap();
224
+ running.abort();
225
+ let _ = running.await;
226
+ assert!(
227
+ client
228
+ .new_session(SessionOptions::new(std::env::temp_dir()))
229
+ .await
230
+ .is_err()
231
+ );
232
+ }
233
+
234
+ #[tokio::test]
235
+ async fn restoration_preserves_history_before_new_prompt_identity() {
236
+ let client = NativeClient::connect(command("normal"), options())
237
+ .await
238
+ .unwrap();
239
+ let mut restored = client
240
+ .load_session("saved-session", SessionOptions::new(std::env::temp_dir()))
241
+ .await
242
+ .unwrap();
243
+ assert_eq!(restored.handle().id(), "saved-session");
244
+ let mut events = restored.take_events().unwrap();
245
+ let history = events.recv().await.unwrap();
246
+ assert_eq!(history.request_id, None);
247
+ assert_eq!(text(&history), Some("restored history"));
248
+ restored.handle().prompt(prompt("continued")).await.unwrap();
249
+ assert_eq!(
250
+ events.recv().await.unwrap().request_id.as_deref(),
251
+ Some("continued")
252
+ );
253
+ client.close().await.unwrap();
254
+ }
255
+
256
+ #[tokio::test]
257
+ async fn auth_errors_exclude_peer_secrets_and_unknown_host_requests_fail() {
258
+ let client = NativeClient::connect(command("auth_required"), options())
259
+ .await
260
+ .unwrap();
261
+ let error = match client
262
+ .new_session(SessionOptions::new(std::env::temp_dir()))
263
+ .await
264
+ {
265
+ Ok(_) => panic!("authentication failure expected"),
266
+ Err(error) => error,
267
+ };
268
+ assert_eq!(error, NativeError::AuthenticationRequired);
269
+ assert!(!format!("{error:?} {error}").contains("SECRET"));
270
+
271
+ let (client, _session, handle, mut events) =
272
+ session("unsupported_host_request", options()).await;
273
+ handle.prompt(prompt("unsupported")).await.unwrap();
274
+ assert_eq!(text(&events.recv().await.unwrap()), Some("unsupported"));
275
+ client.close().await.unwrap();
276
+ }
277
+
278
+ #[tokio::test]
279
+ async fn slow_consumers_fail_with_bounded_buffer_and_shutdown() {
280
+ let mut limits = options();
281
+ limits.event_capacity = 2;
282
+ let (client, _session, handle, _events) = session("burst", limits).await;
283
+ let result = timeout(Duration::from_secs(5), handle.prompt(prompt("overflow")))
284
+ .await
285
+ .unwrap();
286
+ assert_eq!(result.unwrap_err(), NativeError::EventBufferFull);
287
+ assert!(
288
+ client
289
+ .new_session(SessionOptions::new(std::env::temp_dir()))
290
+ .await
291
+ .is_err()
292
+ );
293
+ }
294
+
295
+ #[tokio::test]
296
+ async fn model_selection_is_explicit_and_api_key_overrides_are_rejected() {
297
+ let client = NativeClient::connect(command("normal"), options())
298
+ .await
299
+ .unwrap();
300
+ let mut selected = SessionOptions::new(std::env::temp_dir());
301
+ selected.model = Some("test-model".into());
302
+ let mut session = client.new_session(selected.clone()).await.unwrap();
303
+ let _events = session.take_events().unwrap();
304
+ session.handle().prompt(prompt("selected")).await.unwrap();
305
+ selected.model = Some("missing-model".into());
306
+ assert!(matches!(
307
+ client.new_session(selected).await,
308
+ Err(NativeError::Unsupported(_))
309
+ ));
310
+ client.close().await.unwrap();
311
+ let mut keyed = command("normal");
312
+ keyed
313
+ .env
314
+ .insert("OPENAI_API_KEY".into(), "not-a-real-key".into());
315
+ assert!(matches!(
316
+ NativeClient::connect(keyed, options()).await,
317
+ Err(NativeError::InvalidOptions(_))
318
+ ));
319
+ }
320
+
321
+ #[cfg(target_os = "linux")]
322
+ #[tokio::test]
323
+ async fn installed_launcher_sets_the_actual_startup_directory() {
324
+ let directory = std::env::temp_dir().canonicalize().unwrap();
325
+ let launch = command("startup_cwd")
326
+ .with_working_directory(&directory)
327
+ .unwrap();
328
+ let client = NativeClient::connect(launch, options()).await.unwrap();
329
+ let mut session = client
330
+ .new_session(SessionOptions::new(&directory))
331
+ .await
332
+ .unwrap();
333
+ let mut events = session.take_events().unwrap();
334
+ session.handle().prompt(prompt("cwd")).await.unwrap();
335
+ assert_eq!(text(&events.recv().await.unwrap()), directory.to_str());
336
+ client.close().await.unwrap();
337
+ }
338
+
339
+ #[cfg(target_os = "linux")]
340
+ fn pid_fixture(mode: &str) -> (AgentCommand, PathBuf) {
341
+ use std::sync::atomic::{AtomicU64, Ordering};
342
+ static NEXT: AtomicU64 = AtomicU64::new(1);
343
+ let path = std::env::temp_dir().join(format!(
344
+ "ccht-native-pids-{}-{}.json",
345
+ std::process::id(),
346
+ NEXT.fetch_add(1, Ordering::Relaxed)
347
+ ));
348
+ let mut command = command(mode);
349
+ command.args.push(path.to_str().unwrap().into());
350
+ (command, path)
351
+ }
352
+
353
+ #[cfg(target_os = "linux")]
354
+ async fn fixture_pids(path: &std::path::Path) -> Vec<u32> {
355
+ timeout(Duration::from_secs(5), async {
356
+ loop {
357
+ if let Ok(bytes) = std::fs::read(path)
358
+ && let Ok(pids) = serde_json::from_slice::<BTreeMap<String, u32>>(&bytes)
359
+ {
360
+ return pids.into_values().collect();
361
+ }
362
+ tokio::time::sleep(Duration::from_millis(10)).await;
363
+ }
364
+ })
365
+ .await
366
+ .unwrap()
367
+ }
368
+
369
+ #[cfg(target_os = "linux")]
370
+ async fn assert_processes_stopped(pids: &[u32]) {
371
+ timeout(Duration::from_secs(5), async {
372
+ loop {
373
+ let running = pids.iter().any(|pid| {
374
+ std::fs::read_to_string(format!("/proc/{pid}/stat")).is_ok_and(|stat| {
375
+ // A zombie is terminated; reaping an orphan belongs to the
376
+ // worker's init process, not to the client under test.
377
+ !stat
378
+ .rsplit_once(") ")
379
+ .is_some_and(|(_, fields)| fields.starts_with('Z'))
380
+ })
381
+ });
382
+ if !running {
383
+ return;
384
+ }
385
+ tokio::time::sleep(Duration::from_millis(10)).await;
386
+ }
387
+ })
388
+ .await
389
+ .expect("SDK must terminate the agent and its descendant");
390
+ }
391
+
392
+ #[cfg(target_os = "linux")]
393
+ #[tokio::test]
394
+ async fn ignored_cancellation_really_terminates_the_sdk_process_group() {
395
+ let (launch, path) = pid_fixture("ignore_cancel");
396
+ let mut limits = options();
397
+ limits.shutdown_timeout = Duration::from_millis(100);
398
+ let client = NativeClient::connect(launch, limits).await.unwrap();
399
+ let pids = fixture_pids(&path).await;
400
+ let mut session = client
401
+ .new_session(SessionOptions::new(std::env::temp_dir()))
402
+ .await
403
+ .unwrap();
404
+ let handle = session.handle();
405
+ let mut events = session.take_events().unwrap();
406
+ let running = tokio::spawn({
407
+ let handle = handle.clone();
408
+ async move { handle.prompt(prompt("stop-processes")).await }
409
+ });
410
+ events.recv().await.unwrap();
411
+ assert_eq!(handle.cancel().await.unwrap_err(), NativeError::Timeout);
412
+ assert!(running.await.unwrap().is_err());
413
+ assert_processes_stopped(&pids).await;
414
+ let _ = std::fs::remove_file(path);
415
+ }
416
+
417
+ #[cfg(target_os = "linux")]
418
+ #[tokio::test]
419
+ async fn dropping_connect_during_initialization_really_terminates_its_children() {
420
+ let (launch, path) = pid_fixture("slow_init");
421
+ let connecting = tokio::spawn(NativeClient::connect(launch, options()));
422
+ let pids = fixture_pids(&path).await;
423
+ connecting.abort();
424
+ let _ = connecting.await;
425
+ assert_processes_stopped(&pids).await;
426
+ let _ = std::fs::remove_file(path);
427
+ }
@@ -0,0 +1,35 @@
1
+ //! Browser bindings for the same conversation state used by native consumers.
2
+
3
+ use wasm_bindgen::prelude::*;
4
+
5
+ /// A Rust conversation model exported to JavaScript. The application owns transport.
6
+ #[wasm_bindgen(js_name = ConversationModel)]
7
+ pub struct WebConversation {
8
+ inner: crate::Conversation,
9
+ }
10
+
11
+ #[wasm_bindgen(js_class = ConversationModel)]
12
+ impl WebConversation {
13
+ /// Create an isolated conversation state.
14
+ #[wasm_bindgen(constructor)]
15
+ pub fn new(conversation_id: String) -> Self {
16
+ Self {
17
+ inner: crate::Conversation::new(conversation_id),
18
+ }
19
+ }
20
+
21
+ /// Apply an event and report whether it changed the state.
22
+ #[wasm_bindgen(js_name = applyEvent)]
23
+ pub fn apply_event(&mut self, event_json: &str) -> Result<bool, JsValue> {
24
+ self.inner
25
+ .apply_json(event_json)
26
+ .map_err(|error| JsValue::from_str(&error.to_string()))
27
+ }
28
+
29
+ /// Return the current render state as JSON.
30
+ pub fn snapshot(&self) -> Result<String, JsValue> {
31
+ self.inner
32
+ .snapshot_json()
33
+ .map_err(|error| JsValue::from_str(&error.to_string()))
34
+ }
35
+ }
package/wasm/ccht.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /**
5
+ * A Rust conversation model exported to JavaScript. The application owns transport.
6
+ */
7
+ export class ConversationModel {
8
+ free(): void;
9
+ [Symbol.dispose](): void;
10
+ /**
11
+ * Apply an event and report whether it changed the state.
12
+ */
13
+ applyEvent(event_json: string): boolean;
14
+ /**
15
+ * Create an isolated conversation state.
16
+ */
17
+ constructor(conversation_id: string);
18
+ /**
19
+ * Return the current render state as JSON.
20
+ */
21
+ snapshot(): string;
22
+ }
23
+
24
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
25
+
26
+ export interface InitOutput {
27
+ readonly memory: WebAssembly.Memory;
28
+ readonly __wbg_conversationmodel_free: (a: number, b: number) => void;
29
+ readonly conversationmodel_applyEvent: (a: number, b: number, c: number) => [number, number, number];
30
+ readonly conversationmodel_new: (a: number, b: number) => number;
31
+ readonly conversationmodel_snapshot: (a: number) => [number, number, number, number];
32
+ readonly __wbindgen_externrefs: WebAssembly.Table;
33
+ readonly __wbindgen_malloc: (a: number, b: number) => number;
34
+ readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
35
+ readonly __externref_table_dealloc: (a: number) => void;
36
+ readonly __wbindgen_free: (a: number, b: number, c: number) => void;
37
+ readonly __wbindgen_start: () => void;
38
+ }
39
+
40
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
41
+
42
+ /**
43
+ * Instantiates the given `module`, which can either be bytes or
44
+ * a precompiled `WebAssembly.Module`.
45
+ *
46
+ * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
47
+ *
48
+ * @returns {InitOutput}
49
+ */
50
+ export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
51
+
52
+ /**
53
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
54
+ * for everything else, calls `WebAssembly.instantiate` directly.
55
+ *
56
+ * @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
57
+ *
58
+ * @returns {Promise<InitOutput>}
59
+ */
60
+ export default function __wbg_init (module_or_path: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;