@corbet-labs/ccht 0.2.2 → 0.2.4

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 (397) hide show
  1. package/LICENSE +307 -0
  2. package/LICENSE.md +30 -0
  3. package/LICENSES/GPL-3.0-only.txt +232 -0
  4. package/LICENSES/LGPL-3.0-linking-exception.txt +16 -0
  5. package/LICENSES/LGPL-3.0-only WITH LGPL-3.0-linking-exception.txt +16 -0
  6. package/LICENSES/LGPL-3.0-only.txt +304 -0
  7. package/LICENSES/dependencies/agent-client-protocol-2.1.0/LICENSE +191 -0
  8. package/LICENSES/dependencies/agent-client-protocol-derive-2.1.0/LICENSE +191 -0
  9. package/LICENSES/dependencies/agent-client-protocol-schema-1.7.0/LICENSE +190 -0
  10. package/LICENSES/dependencies/android_system_properties-0.1.6/LICENSE-APACHE +13 -0
  11. package/LICENSES/dependencies/android_system_properties-0.1.6/LICENSE-MIT +20 -0
  12. package/LICENSES/dependencies/anyhow-1.0.104/LICENSE-APACHE +176 -0
  13. package/LICENSES/dependencies/anyhow-1.0.104/LICENSE-MIT +23 -0
  14. package/LICENSES/dependencies/async-channel-2.5.0/LICENSE-APACHE +201 -0
  15. package/LICENSES/dependencies/async-channel-2.5.0/LICENSE-MIT +23 -0
  16. package/LICENSES/dependencies/async-io-2.6.0/LICENSE-APACHE +201 -0
  17. package/LICENSES/dependencies/async-io-2.6.0/LICENSE-MIT +23 -0
  18. package/LICENSES/dependencies/async-lock-3.4.2/LICENSE-APACHE +201 -0
  19. package/LICENSES/dependencies/async-lock-3.4.2/LICENSE-MIT +23 -0
  20. package/LICENSES/dependencies/async-process-2.5.0/LICENSE-APACHE +201 -0
  21. package/LICENSES/dependencies/async-process-2.5.0/LICENSE-MIT +23 -0
  22. package/LICENSES/dependencies/async-signal-0.2.14/LICENSE-APACHE +201 -0
  23. package/LICENSES/dependencies/async-signal-0.2.14/LICENSE-MIT +23 -0
  24. package/LICENSES/dependencies/async-task-4.7.1/LICENSE-APACHE +201 -0
  25. package/LICENSES/dependencies/async-task-4.7.1/LICENSE-MIT +23 -0
  26. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-APACHE +201 -0
  27. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-MIT +23 -0
  28. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-THIRD-PARTY +45 -0
  29. package/LICENSES/dependencies/autocfg-1.5.1/LICENSE-APACHE +201 -0
  30. package/LICENSES/dependencies/autocfg-1.5.1/LICENSE-MIT +25 -0
  31. package/LICENSES/dependencies/base64-0.22.1/LICENSE-APACHE +201 -0
  32. package/LICENSES/dependencies/base64-0.22.1/LICENSE-MIT +21 -0
  33. package/LICENSES/dependencies/base64-0.23.1/LICENSE-APACHE +201 -0
  34. package/LICENSES/dependencies/base64-0.23.1/LICENSE-MIT +21 -0
  35. package/LICENSES/dependencies/bitflags-1.3.2/LICENSE-APACHE +201 -0
  36. package/LICENSES/dependencies/bitflags-1.3.2/LICENSE-MIT +25 -0
  37. package/LICENSES/dependencies/bitflags-2.13.2/LICENSE-APACHE +201 -0
  38. package/LICENSES/dependencies/bitflags-2.13.2/LICENSE-MIT +25 -0
  39. package/LICENSES/dependencies/blocking-1.7.0/LICENSE-APACHE +201 -0
  40. package/LICENSES/dependencies/blocking-1.7.0/LICENSE-MIT +23 -0
  41. package/LICENSES/dependencies/bs58-0.5.1/LICENSE-APACHE +201 -0
  42. package/LICENSES/dependencies/bs58-0.5.1/LICENSE-MIT +20 -0
  43. package/LICENSES/dependencies/bumpalo-3.20.3/LICENSE-APACHE +201 -0
  44. package/LICENSES/dependencies/bumpalo-3.20.3/LICENSE-MIT +25 -0
  45. package/LICENSES/dependencies/bytes-1.12.1/LICENSE +25 -0
  46. package/LICENSES/dependencies/cc-1.4.5/LICENSE-APACHE +201 -0
  47. package/LICENSES/dependencies/cc-1.4.5/LICENSE-MIT +25 -0
  48. package/LICENSES/dependencies/cfg-if-1.0.4/LICENSE-APACHE +201 -0
  49. package/LICENSES/dependencies/cfg-if-1.0.4/LICENSE-MIT +25 -0
  50. package/LICENSES/dependencies/chrono-0.4.45/LICENSE.txt +240 -0
  51. package/LICENSES/dependencies/concurrent-queue-2.5.0/LICENSE-APACHE +201 -0
  52. package/LICENSES/dependencies/concurrent-queue-2.5.0/LICENSE-MIT +23 -0
  53. package/LICENSES/dependencies/convert_case-0.10.0/LICENSE +21 -0
  54. package/LICENSES/dependencies/core-foundation-sys-0.8.7/LICENSE-APACHE +201 -0
  55. package/LICENSES/dependencies/core-foundation-sys-0.8.7/LICENSE-MIT +25 -0
  56. package/LICENSES/dependencies/crossbeam-deque-0.8.8/LICENSE-APACHE +201 -0
  57. package/LICENSES/dependencies/crossbeam-deque-0.8.8/LICENSE-MIT +27 -0
  58. package/LICENSES/dependencies/crossbeam-epoch-0.9.21/LICENSE-APACHE +201 -0
  59. package/LICENSES/dependencies/crossbeam-epoch-0.9.21/LICENSE-MIT +27 -0
  60. package/LICENSES/dependencies/crossbeam-utils-0.8.23/LICENSE-APACHE +201 -0
  61. package/LICENSES/dependencies/crossbeam-utils-0.8.23/LICENSE-MIT +27 -0
  62. package/LICENSES/dependencies/darling-0.24.1/LICENSE +21 -0
  63. package/LICENSES/dependencies/darling_core-0.24.1/LICENSE +21 -0
  64. package/LICENSES/dependencies/darling_macro-0.24.1/LICENSE +21 -0
  65. package/LICENSES/dependencies/defmt-1.1.1/LICENSE-APACHE +201 -0
  66. package/LICENSES/dependencies/defmt-1.1.1/LICENSE-MIT +25 -0
  67. package/LICENSES/dependencies/defmt-macros-1.1.1/LICENSE-APACHE +201 -0
  68. package/LICENSES/dependencies/defmt-macros-1.1.1/LICENSE-MIT +25 -0
  69. package/LICENSES/dependencies/defmt-parser-1.0.0/LICENSE-APACHE +201 -0
  70. package/LICENSES/dependencies/defmt-parser-1.0.0/LICENSE-MIT +25 -0
  71. package/LICENSES/dependencies/deranged-0.5.8/LICENSE-Apache +202 -0
  72. package/LICENSES/dependencies/deranged-0.5.8/LICENSE-MIT +19 -0
  73. package/LICENSES/dependencies/derive_more-2.1.1/LICENSE +21 -0
  74. package/LICENSES/dependencies/derive_more-impl-2.1.1/LICENSE +21 -0
  75. package/LICENSES/dependencies/dyn-clone-1.0.20/LICENSE-APACHE +176 -0
  76. package/LICENSES/dependencies/dyn-clone-1.0.20/LICENSE-MIT +23 -0
  77. package/LICENSES/dependencies/either-1.18.0/LICENSE-APACHE +201 -0
  78. package/LICENSES/dependencies/either-1.18.0/LICENSE-MIT +25 -0
  79. package/LICENSES/dependencies/equivalent-1.0.2/LICENSE-APACHE +201 -0
  80. package/LICENSES/dependencies/equivalent-1.0.2/LICENSE-MIT +25 -0
  81. package/LICENSES/dependencies/errno-0.3.14/LICENSE-APACHE +201 -0
  82. package/LICENSES/dependencies/errno-0.3.14/LICENSE-MIT +25 -0
  83. package/LICENSES/dependencies/event-listener-5.4.2/LICENSE-APACHE +201 -0
  84. package/LICENSES/dependencies/event-listener-5.4.2/LICENSE-MIT +23 -0
  85. package/LICENSES/dependencies/event-listener-strategy-0.5.4/LICENSE-APACHE +201 -0
  86. package/LICENSES/dependencies/event-listener-strategy-0.5.4/LICENSE-MIT +23 -0
  87. package/LICENSES/dependencies/fallible-iterator-0.3.0/LICENSE-APACHE +202 -0
  88. package/LICENSES/dependencies/fallible-iterator-0.3.0/LICENSE-MIT +19 -0
  89. package/LICENSES/dependencies/fastrand-2.5.0/LICENSE-APACHE +201 -0
  90. package/LICENSES/dependencies/fastrand-2.5.0/LICENSE-MIT +23 -0
  91. package/LICENSES/dependencies/find-msvc-tools-0.1.12/LICENSE-APACHE +201 -0
  92. package/LICENSES/dependencies/find-msvc-tools-0.1.12/LICENSE-MIT +25 -0
  93. package/LICENSES/dependencies/fixedbitset-0.5.7/LICENSE-APACHE +201 -0
  94. package/LICENSES/dependencies/fixedbitset-0.5.7/LICENSE-MIT +25 -0
  95. package/LICENSES/dependencies/foldhash-0.2.0/LICENSE +19 -0
  96. package/LICENSES/dependencies/futures-0.3.34/LICENSE-APACHE +202 -0
  97. package/LICENSES/dependencies/futures-0.3.34/LICENSE-MIT +26 -0
  98. package/LICENSES/dependencies/futures-channel-0.3.34/LICENSE-APACHE +202 -0
  99. package/LICENSES/dependencies/futures-channel-0.3.34/LICENSE-MIT +26 -0
  100. package/LICENSES/dependencies/futures-concurrency-7.7.1/LICENSE-APACHE +190 -0
  101. package/LICENSES/dependencies/futures-concurrency-7.7.1/LICENSE-MIT +21 -0
  102. package/LICENSES/dependencies/futures-core-0.3.34/LICENSE-APACHE +202 -0
  103. package/LICENSES/dependencies/futures-core-0.3.34/LICENSE-MIT +26 -0
  104. package/LICENSES/dependencies/futures-executor-0.3.34/LICENSE-APACHE +202 -0
  105. package/LICENSES/dependencies/futures-executor-0.3.34/LICENSE-MIT +26 -0
  106. package/LICENSES/dependencies/futures-io-0.3.34/LICENSE-APACHE +202 -0
  107. package/LICENSES/dependencies/futures-io-0.3.34/LICENSE-MIT +26 -0
  108. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-APACHE +201 -0
  109. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-MIT +23 -0
  110. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-THIRD-PARTY +45 -0
  111. package/LICENSES/dependencies/futures-macro-0.3.34/LICENSE-APACHE +202 -0
  112. package/LICENSES/dependencies/futures-macro-0.3.34/LICENSE-MIT +26 -0
  113. package/LICENSES/dependencies/futures-sink-0.3.34/LICENSE-APACHE +202 -0
  114. package/LICENSES/dependencies/futures-sink-0.3.34/LICENSE-MIT +26 -0
  115. package/LICENSES/dependencies/futures-task-0.3.34/LICENSE-APACHE +202 -0
  116. package/LICENSES/dependencies/futures-task-0.3.34/LICENSE-MIT +26 -0
  117. package/LICENSES/dependencies/futures-util-0.3.34/LICENSE-APACHE +202 -0
  118. package/LICENSES/dependencies/futures-util-0.3.34/LICENSE-MIT +26 -0
  119. package/LICENSES/dependencies/getrandom-0.4.3/LICENSE-APACHE +201 -0
  120. package/LICENSES/dependencies/getrandom-0.4.3/LICENSE-MIT +26 -0
  121. package/LICENSES/dependencies/gimli-0.32.3/LICENSE-APACHE +201 -0
  122. package/LICENSES/dependencies/gimli-0.32.3/LICENSE-MIT +25 -0
  123. package/LICENSES/dependencies/hashbrown-0.12.3/LICENSE-APACHE +201 -0
  124. package/LICENSES/dependencies/hashbrown-0.12.3/LICENSE-MIT +25 -0
  125. package/LICENSES/dependencies/hashbrown-0.16.1/LICENSE-APACHE +201 -0
  126. package/LICENSES/dependencies/hashbrown-0.16.1/LICENSE-MIT +25 -0
  127. package/LICENSES/dependencies/hashbrown-0.17.1/LICENSE-APACHE +201 -0
  128. package/LICENSES/dependencies/hashbrown-0.17.1/LICENSE-MIT +25 -0
  129. package/LICENSES/dependencies/heck-0.5.0/LICENSE-APACHE +201 -0
  130. package/LICENSES/dependencies/heck-0.5.0/LICENSE-MIT +25 -0
  131. package/LICENSES/dependencies/hermit-abi-0.5.3/LICENSE-APACHE +201 -0
  132. package/LICENSES/dependencies/hermit-abi-0.5.3/LICENSE-MIT +23 -0
  133. package/LICENSES/dependencies/hex-0.4.3/LICENSE-APACHE +202 -0
  134. package/LICENSES/dependencies/hex-0.4.3/LICENSE-MIT +20 -0
  135. package/LICENSES/dependencies/iana-time-zone-0.1.65/LICENSE-APACHE +201 -0
  136. package/LICENSES/dependencies/iana-time-zone-0.1.65/LICENSE-MIT +25 -0
  137. package/LICENSES/dependencies/iana-time-zone-haiku-0.1.2/LICENSE-APACHE +201 -0
  138. package/LICENSES/dependencies/iana-time-zone-haiku-0.1.2/LICENSE-MIT +25 -0
  139. package/LICENSES/dependencies/id-arena-2.3.0/LICENSE-APACHE +201 -0
  140. package/LICENSES/dependencies/id-arena-2.3.0/LICENSE-MIT +25 -0
  141. package/LICENSES/dependencies/ident_case-1.0.1/LICENSE +19 -0
  142. package/LICENSES/dependencies/indexmap-1.9.3/LICENSE-APACHE +201 -0
  143. package/LICENSES/dependencies/indexmap-1.9.3/LICENSE-MIT +25 -0
  144. package/LICENSES/dependencies/indexmap-2.14.2/LICENSE-APACHE +201 -0
  145. package/LICENSES/dependencies/indexmap-2.14.2/LICENSE-MIT +25 -0
  146. package/LICENSES/dependencies/itoa-1.0.18/LICENSE-APACHE +176 -0
  147. package/LICENSES/dependencies/itoa-1.0.18/LICENSE-MIT +23 -0
  148. package/LICENSES/dependencies/jiff-0.2.35/COPYING +3 -0
  149. package/LICENSES/dependencies/jiff-0.2.35/LICENSE-MIT +21 -0
  150. package/LICENSES/dependencies/jiff-0.2.35/UNLICENSE +24 -0
  151. package/LICENSES/dependencies/jiff-core-0.1.0/COPYING +3 -0
  152. package/LICENSES/dependencies/jiff-core-0.1.0/LICENSE-MIT +21 -0
  153. package/LICENSES/dependencies/jiff-core-0.1.0/UNLICENSE +24 -0
  154. package/LICENSES/dependencies/jiff-static-0.2.35/COPYING +3 -0
  155. package/LICENSES/dependencies/jiff-static-0.2.35/LICENSE-MIT +21 -0
  156. package/LICENSES/dependencies/jiff-static-0.2.35/UNLICENSE +24 -0
  157. package/LICENSES/dependencies/jiff-tzdb-0.1.8/COPYING +3 -0
  158. package/LICENSES/dependencies/jiff-tzdb-0.1.8/LICENSE-MIT +21 -0
  159. package/LICENSES/dependencies/jiff-tzdb-0.1.8/UNLICENSE +24 -0
  160. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/COPYING +3 -0
  161. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/LICENSE-MIT +21 -0
  162. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/UNLICENSE +24 -0
  163. package/LICENSES/dependencies/js-sys-0.3.105/LICENSE-APACHE +201 -0
  164. package/LICENSES/dependencies/js-sys-0.3.105/LICENSE-MIT +25 -0
  165. package/LICENSES/dependencies/leb128-0.2.7/LICENSE-APACHE +201 -0
  166. package/LICENSES/dependencies/leb128-0.2.7/LICENSE-MIT +25 -0
  167. package/LICENSES/dependencies/leb128fmt-0.1.0/LICENSE-APACHE +201 -0
  168. package/LICENSES/dependencies/leb128fmt-0.1.0/LICENSE-MIT +23 -0
  169. package/LICENSES/dependencies/libc-0.2.189/LICENSE-APACHE +176 -0
  170. package/LICENSES/dependencies/libc-0.2.189/LICENSE-MIT +25 -0
  171. package/LICENSES/dependencies/linux-raw-sys-0.12.1/COPYRIGHT +29 -0
  172. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-APACHE +201 -0
  173. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  174. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-MIT +23 -0
  175. package/LICENSES/dependencies/log-0.4.34/LICENSE-APACHE +201 -0
  176. package/LICENSES/dependencies/log-0.4.34/LICENSE-MIT +25 -0
  177. package/LICENSES/dependencies/memchr-2.8.3/COPYING +3 -0
  178. package/LICENSES/dependencies/memchr-2.8.3/LICENSE-MIT +21 -0
  179. package/LICENSES/dependencies/memchr-2.8.3/UNLICENSE +24 -0
  180. package/LICENSES/dependencies/mio-1.2.3/LICENSE +19 -0
  181. package/LICENSES/dependencies/num-conv-0.2.2/LICENSE-Apache +177 -0
  182. package/LICENSES/dependencies/num-conv-0.2.2/LICENSE-MIT +19 -0
  183. package/LICENSES/dependencies/num-traits-0.2.19/LICENSE-APACHE +201 -0
  184. package/LICENSES/dependencies/num-traits-0.2.19/LICENSE-MIT +25 -0
  185. package/LICENSES/dependencies/once_cell-1.21.4/LICENSE-APACHE +201 -0
  186. package/LICENSES/dependencies/once_cell-1.21.4/LICENSE-MIT +23 -0
  187. package/LICENSES/dependencies/parking-2.2.1/LICENSE-APACHE +201 -0
  188. package/LICENSES/dependencies/parking-2.2.1/LICENSE-MIT +23 -0
  189. package/LICENSES/dependencies/parking-2.2.1/LICENSE-THIRD-PARTY +9 -0
  190. package/LICENSES/dependencies/pin-project-1.1.13/LICENSE-APACHE +177 -0
  191. package/LICENSES/dependencies/pin-project-1.1.13/LICENSE-MIT +23 -0
  192. package/LICENSES/dependencies/pin-project-internal-1.1.13/LICENSE-APACHE +177 -0
  193. package/LICENSES/dependencies/pin-project-internal-1.1.13/LICENSE-MIT +23 -0
  194. package/LICENSES/dependencies/pin-project-lite-0.2.17/LICENSE-APACHE +177 -0
  195. package/LICENSES/dependencies/pin-project-lite-0.2.17/LICENSE-MIT +23 -0
  196. package/LICENSES/dependencies/piper-0.2.5/LICENSE-APACHE +201 -0
  197. package/LICENSES/dependencies/piper-0.2.5/LICENSE-MIT +23 -0
  198. package/LICENSES/dependencies/polling-3.11.0/LICENSE-APACHE +201 -0
  199. package/LICENSES/dependencies/polling-3.11.0/LICENSE-MIT +23 -0
  200. package/LICENSES/dependencies/portable-atomic-1.15.0/LICENSE-APACHE +177 -0
  201. package/LICENSES/dependencies/portable-atomic-1.15.0/LICENSE-MIT +23 -0
  202. package/LICENSES/dependencies/portable-atomic-util-0.2.8/LICENSE-APACHE +177 -0
  203. package/LICENSES/dependencies/portable-atomic-util-0.2.8/LICENSE-MIT +23 -0
  204. package/LICENSES/dependencies/powerfmt-0.2.0/LICENSE-Apache +202 -0
  205. package/LICENSES/dependencies/powerfmt-0.2.0/LICENSE-MIT +19 -0
  206. package/LICENSES/dependencies/proc-macro2-1.0.107/LICENSE-APACHE +176 -0
  207. package/LICENSES/dependencies/proc-macro2-1.0.107/LICENSE-MIT +23 -0
  208. package/LICENSES/dependencies/quote-1.0.47/LICENSE-APACHE +176 -0
  209. package/LICENSES/dependencies/quote-1.0.47/LICENSE-MIT +23 -0
  210. package/LICENSES/dependencies/r-efi-6.0.0/AUTHORS +75 -0
  211. package/LICENSES/dependencies/rayon-1.12.0/LICENSE-APACHE +201 -0
  212. package/LICENSES/dependencies/rayon-1.12.0/LICENSE-MIT +25 -0
  213. package/LICENSES/dependencies/rayon-core-1.13.0/LICENSE-APACHE +201 -0
  214. package/LICENSES/dependencies/rayon-core-1.13.0/LICENSE-MIT +25 -0
  215. package/LICENSES/dependencies/ref-cast-1.0.27/LICENSE-APACHE +176 -0
  216. package/LICENSES/dependencies/ref-cast-1.0.27/LICENSE-MIT +23 -0
  217. package/LICENSES/dependencies/ref-cast-impl-1.0.27/LICENSE-APACHE +176 -0
  218. package/LICENSES/dependencies/ref-cast-impl-1.0.27/LICENSE-MIT +23 -0
  219. package/LICENSES/dependencies/rustc-demangle-0.1.28/LICENSE-APACHE +201 -0
  220. package/LICENSES/dependencies/rustc-demangle-0.1.28/LICENSE-MIT +25 -0
  221. package/LICENSES/dependencies/rustc-hash-2.1.3/LICENSE-APACHE +176 -0
  222. package/LICENSES/dependencies/rustc-hash-2.1.3/LICENSE-MIT +23 -0
  223. package/LICENSES/dependencies/rustc_version-0.4.1/LICENSE-APACHE +201 -0
  224. package/LICENSES/dependencies/rustc_version-0.4.1/LICENSE-MIT +25 -0
  225. package/LICENSES/dependencies/rustix-1.1.4/COPYRIGHT +29 -0
  226. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-APACHE +201 -0
  227. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  228. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-MIT +23 -0
  229. package/LICENSES/dependencies/rustversion-1.0.23/LICENSE-APACHE +176 -0
  230. package/LICENSES/dependencies/rustversion-1.0.23/LICENSE-MIT +23 -0
  231. package/LICENSES/dependencies/schemars-0.9.0/LICENSE +21 -0
  232. package/LICENSES/dependencies/schemars-1.2.2/LICENSE +21 -0
  233. package/LICENSES/dependencies/schemars_derive-1.2.2/LICENSE +21 -0
  234. package/LICENSES/dependencies/semver-1.0.28/LICENSE-APACHE +176 -0
  235. package/LICENSES/dependencies/semver-1.0.28/LICENSE-MIT +23 -0
  236. package/LICENSES/dependencies/serde-1.0.229/LICENSE-APACHE +176 -0
  237. package/LICENSES/dependencies/serde-1.0.229/LICENSE-MIT +23 -0
  238. package/LICENSES/dependencies/serde_core-1.0.229/LICENSE-APACHE +176 -0
  239. package/LICENSES/dependencies/serde_core-1.0.229/LICENSE-MIT +23 -0
  240. package/LICENSES/dependencies/serde_derive-1.0.229/LICENSE-APACHE +176 -0
  241. package/LICENSES/dependencies/serde_derive-1.0.229/LICENSE-MIT +23 -0
  242. package/LICENSES/dependencies/serde_derive_internals-0.30.0/LICENSE-APACHE +176 -0
  243. package/LICENSES/dependencies/serde_derive_internals-0.30.0/LICENSE-MIT +23 -0
  244. package/LICENSES/dependencies/serde_json-1.0.151/LICENSE-APACHE +176 -0
  245. package/LICENSES/dependencies/serde_json-1.0.151/LICENSE-MIT +23 -0
  246. package/LICENSES/dependencies/serde_with-3.23.0/LICENSE-APACHE +201 -0
  247. package/LICENSES/dependencies/serde_with-3.23.0/LICENSE-MIT +25 -0
  248. package/LICENSES/dependencies/serde_with_macros-3.23.0/LICENSE-APACHE +201 -0
  249. package/LICENSES/dependencies/serde_with_macros-3.23.0/LICENSE-MIT +25 -0
  250. package/LICENSES/dependencies/shell-words-1.1.1/LICENSE-APACHE +201 -0
  251. package/LICENSES/dependencies/shell-words-1.1.1/LICENSE-MIT +25 -0
  252. package/LICENSES/dependencies/shlex-2.0.1/LICENSE-APACHE +13 -0
  253. package/LICENSES/dependencies/shlex-2.0.1/LICENSE-MIT +21 -0
  254. package/LICENSES/dependencies/signal-hook-registry-1.4.8/LICENSE-APACHE +201 -0
  255. package/LICENSES/dependencies/signal-hook-registry-1.4.8/LICENSE-MIT +25 -0
  256. package/LICENSES/dependencies/slab-0.4.12/LICENSE +25 -0
  257. package/LICENSES/dependencies/smallvec-1.16.0/LICENSE-APACHE +201 -0
  258. package/LICENSES/dependencies/smallvec-1.16.0/LICENSE-MIT +25 -0
  259. package/LICENSES/dependencies/socket2-0.6.5/LICENSE-APACHE +201 -0
  260. package/LICENSES/dependencies/socket2-0.6.5/LICENSE-MIT +25 -0
  261. package/LICENSES/dependencies/stable_deref_trait-1.2.1/LICENSE-APACHE +201 -0
  262. package/LICENSES/dependencies/stable_deref_trait-1.2.1/LICENSE-MIT +25 -0
  263. package/LICENSES/dependencies/strsim-0.11.1/LICENSE +23 -0
  264. package/LICENSES/dependencies/strum-0.28.0/LICENSE +21 -0
  265. package/LICENSES/dependencies/strum_macros-0.28.0/LICENSE +21 -0
  266. package/LICENSES/dependencies/syn-2.0.119/LICENSE-APACHE +176 -0
  267. package/LICENSES/dependencies/syn-2.0.119/LICENSE-MIT +23 -0
  268. package/LICENSES/dependencies/syn-3.0.5/LICENSE-APACHE +176 -0
  269. package/LICENSES/dependencies/syn-3.0.5/LICENSE-MIT +23 -0
  270. package/LICENSES/dependencies/thiserror-2.0.20/LICENSE-APACHE +176 -0
  271. package/LICENSES/dependencies/thiserror-2.0.20/LICENSE-MIT +23 -0
  272. package/LICENSES/dependencies/thiserror-impl-2.0.20/LICENSE-APACHE +176 -0
  273. package/LICENSES/dependencies/thiserror-impl-2.0.20/LICENSE-MIT +23 -0
  274. package/LICENSES/dependencies/time-0.3.55/LICENSE-Apache +177 -0
  275. package/LICENSES/dependencies/time-0.3.55/LICENSE-MIT +19 -0
  276. package/LICENSES/dependencies/time-core-0.1.9/LICENSE-Apache +177 -0
  277. package/LICENSES/dependencies/time-core-0.1.9/LICENSE-MIT +19 -0
  278. package/LICENSES/dependencies/time-macros-0.2.32/LICENSE-Apache +177 -0
  279. package/LICENSES/dependencies/time-macros-0.2.32/LICENSE-MIT +19 -0
  280. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-APACHE.md +202 -0
  281. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-MIT.md +5 -0
  282. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-ZLIB.md +11 -0
  283. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-APACHE.md +202 -0
  284. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-MIT.md +21 -0
  285. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-ZLIB.md +20 -0
  286. package/LICENSES/dependencies/tokio-1.53.1/LICENSE +21 -0
  287. package/LICENSES/dependencies/tokio-macros-2.7.2/LICENSE +22 -0
  288. package/LICENSES/dependencies/tracing-0.1.44/LICENSE +25 -0
  289. package/LICENSES/dependencies/tracing-attributes-0.1.31/LICENSE +25 -0
  290. package/LICENSES/dependencies/tracing-core-0.1.36/LICENSE +25 -0
  291. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-APACHE +176 -0
  292. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-MIT +23 -0
  293. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-UNICODE +39 -0
  294. package/LICENSES/dependencies/unicode-segmentation-1.13.3/COPYRIGHT +7 -0
  295. package/LICENSES/dependencies/unicode-segmentation-1.13.3/LICENSE-APACHE +201 -0
  296. package/LICENSES/dependencies/unicode-segmentation-1.13.3/LICENSE-MIT +25 -0
  297. package/LICENSES/dependencies/unicode-xid-0.2.6/COPYRIGHT +7 -0
  298. package/LICENSES/dependencies/unicode-xid-0.2.6/LICENSE-APACHE +201 -0
  299. package/LICENSES/dependencies/unicode-xid-0.2.6/LICENSE-MIT +25 -0
  300. package/LICENSES/dependencies/uuid-1.26.1/LICENSE-APACHE +201 -0
  301. package/LICENSES/dependencies/uuid-1.26.1/LICENSE-MIT +26 -0
  302. package/LICENSES/dependencies/walrus-0.26.5/LICENSE-APACHE +201 -0
  303. package/LICENSES/dependencies/walrus-0.26.5/LICENSE-MIT +25 -0
  304. package/LICENSES/dependencies/walrus-macro-0.26.0/LICENSE-APACHE +201 -0
  305. package/LICENSES/dependencies/walrus-macro-0.26.0/LICENSE-MIT +25 -0
  306. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-APACHE +201 -0
  307. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  308. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-MIT +23 -0
  309. package/LICENSES/dependencies/wasm-bindgen-0.2.128/LICENSE-APACHE +201 -0
  310. package/LICENSES/dependencies/wasm-bindgen-0.2.128/LICENSE-MIT +25 -0
  311. package/LICENSES/dependencies/wasm-bindgen-cli-support-0.2.128/LICENSE-APACHE +201 -0
  312. package/LICENSES/dependencies/wasm-bindgen-cli-support-0.2.128/LICENSE-MIT +25 -0
  313. package/LICENSES/dependencies/wasm-bindgen-macro-0.2.128/LICENSE-APACHE +201 -0
  314. package/LICENSES/dependencies/wasm-bindgen-macro-0.2.128/LICENSE-MIT +25 -0
  315. package/LICENSES/dependencies/wasm-bindgen-macro-support-0.2.128/LICENSE-APACHE +201 -0
  316. package/LICENSES/dependencies/wasm-bindgen-macro-support-0.2.128/LICENSE-MIT +25 -0
  317. package/LICENSES/dependencies/wasm-bindgen-shared-0.2.128/LICENSE-APACHE +201 -0
  318. package/LICENSES/dependencies/wasm-bindgen-shared-0.2.128/LICENSE-MIT +25 -0
  319. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-APACHE +201 -0
  320. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  321. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-MIT +23 -0
  322. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-APACHE +201 -0
  323. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  324. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-MIT +23 -0
  325. package/LICENSES/dependencies/windows-core-0.62.2/license-apache-2.0 +201 -0
  326. package/LICENSES/dependencies/windows-core-0.62.2/license-mit +21 -0
  327. package/LICENSES/dependencies/windows-implement-0.60.2/license-apache-2.0 +201 -0
  328. package/LICENSES/dependencies/windows-implement-0.60.2/license-mit +21 -0
  329. package/LICENSES/dependencies/windows-interface-0.59.3/license-apache-2.0 +201 -0
  330. package/LICENSES/dependencies/windows-interface-0.59.3/license-mit +21 -0
  331. package/LICENSES/dependencies/windows-link-0.2.1/license-apache-2.0 +201 -0
  332. package/LICENSES/dependencies/windows-link-0.2.1/license-mit +21 -0
  333. package/LICENSES/dependencies/windows-result-0.4.1/license-apache-2.0 +201 -0
  334. package/LICENSES/dependencies/windows-result-0.4.1/license-mit +21 -0
  335. package/LICENSES/dependencies/windows-strings-0.5.1/license-apache-2.0 +201 -0
  336. package/LICENSES/dependencies/windows-strings-0.5.1/license-mit +21 -0
  337. package/LICENSES/dependencies/windows-sys-0.61.2/license-apache-2.0 +201 -0
  338. package/LICENSES/dependencies/windows-sys-0.61.2/license-mit +21 -0
  339. package/LICENSES/dependencies/zmij-1.0.23/LICENSE-MIT +23 -0
  340. package/README.md +70 -0
  341. package/THIRD-PARTY.md +62 -0
  342. package/package.json +48 -9
  343. package/source/.cargo/config.toml +5 -0
  344. package/source/.ci/upstream-notices/PROVENANCE.json +198 -0
  345. package/source/.ci/upstream-notices/agent-client-protocol-2.1.0/LICENSE +191 -0
  346. package/source/.ci/upstream-notices/agent-client-protocol-derive-2.1.0/LICENSE +191 -0
  347. package/source/.ci/upstream-notices/agent-client-protocol-schema-1.7.0/LICENSE +190 -0
  348. package/source/.ci/upstream-notices/defmt-parser-1.0.0/LICENSE-APACHE +201 -0
  349. package/source/.ci/upstream-notices/defmt-parser-1.0.0/LICENSE-MIT +25 -0
  350. package/source/.ci/upstream-notices/r-efi-6.0.0/AUTHORS +75 -0
  351. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-APACHE +201 -0
  352. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  353. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-MIT +23 -0
  354. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-APACHE +201 -0
  355. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  356. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-MIT +23 -0
  357. package/source/.ci/wasm-bundle/Cargo.toml +10 -0
  358. package/source/.ci/wasm-bundle/src/main.rs +17 -0
  359. package/source/CHANGELOG.md +99 -0
  360. package/source/Cargo.lock +1630 -0
  361. package/source/Cargo.toml +48 -0
  362. package/source/LICENSE +307 -0
  363. package/source/LICENSE.md +30 -0
  364. package/source/LICENSES/GPL-3.0-only.txt +232 -0
  365. package/source/LICENSES/LGPL-3.0-linking-exception.txt +16 -0
  366. package/source/LICENSES/LGPL-3.0-only WITH LGPL-3.0-linking-exception.txt +16 -0
  367. package/source/LICENSES/LGPL-3.0-only.txt +304 -0
  368. package/source/README.md +289 -0
  369. package/source/THIRD-PARTY.md +62 -0
  370. package/source/dependencies.tar.gz +0 -0
  371. package/source/examples/native.rs +45 -0
  372. package/source/src/auth.rs +435 -0
  373. package/source/src/configuration.rs +140 -0
  374. package/source/src/conversation.rs +594 -0
  375. package/source/src/dock.rs +564 -0
  376. package/source/src/lib.rs +39 -0
  377. package/source/src/native/client.rs +401 -0
  378. package/source/src/native/drivers/codex.rs +506 -0
  379. package/source/src/native/drivers/mod.rs +305 -0
  380. package/source/src/native/drivers/opencode.rs +531 -0
  381. package/source/src/native/env.rs +264 -0
  382. package/source/src/native/fixture.py +191 -0
  383. package/source/src/native/mod.rs +257 -0
  384. package/source/src/native/pool.rs +440 -0
  385. package/source/src/native/session.rs +609 -0
  386. package/source/src/native/tests.rs +667 -0
  387. package/source/src/transport.rs +330 -0
  388. package/source/src/web.rs +35 -0
  389. package/src/auth.test.ts +115 -0
  390. package/src/components/ChatDock.component.test.ts +213 -0
  391. package/src/components/ChatDock.svelte +422 -0
  392. package/src/components/Dock.component.test.ts +92 -0
  393. package/src/components/Dock.svelte +6 -3
  394. package/src/components/StepConfig.component.test.ts +185 -0
  395. package/src/components/StepConfig.svelte +247 -0
  396. package/src/dock.test.ts +226 -0
  397. package/wasm/ccht_bg.wasm +0 -0
@@ -0,0 +1,564 @@
1
+ //! Portable headless dock state shared by native, Wasm and web consumers.
2
+ //!
3
+ //! This module only tracks which docks exist, where they are placed, and
4
+ //! whether they are open. It performs no I/O, spawns nothing, and renders no
5
+ //! UI; applications own product flows, persistence, and presentation.
6
+
7
+ use serde::{Deserialize, Serialize};
8
+
9
+ /// What a dock is for. Product-neutral; applications map kinds to views.
10
+ #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
11
+ #[serde(rename_all = "lowercase")]
12
+ pub enum DockKind {
13
+ /// Conversation or chat surface.
14
+ Chat,
15
+ /// Configuration or settings surface.
16
+ Config,
17
+ /// Application-defined surface.
18
+ Custom,
19
+ }
20
+
21
+ /// Where a dock is placed relative to the main surface.
22
+ #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
23
+ #[serde(rename_all = "lowercase")]
24
+ pub enum Placement {
25
+ /// Docked to the left side.
26
+ Left,
27
+ /// Docked to the right side.
28
+ Right,
29
+ /// Docked to the bottom.
30
+ Bottom,
31
+ /// Rendered inline with the main content.
32
+ Inline,
33
+ }
34
+
35
+ /// Validated dock identifier: non-empty, at most 64 characters, charset
36
+ /// `[a-z0-9-_]`.
37
+ #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
38
+ #[serde(transparent)]
39
+ pub struct DockId(String);
40
+
41
+ impl DockId {
42
+ /// Maximum identifier length in characters.
43
+ const MAX_LEN: usize = 64;
44
+
45
+ /// Validate an identifier without performing any I/O.
46
+ ///
47
+ /// # Errors
48
+ ///
49
+ /// Returns [`DockError::EmptyId`] for empty input,
50
+ /// [`DockError::IdTooLong`] when longer than 64 characters, or
51
+ /// [`DockError::InvalidChar`] for the first out-of-charset character.
52
+ pub fn new(id: &str) -> Result<Self, DockError> {
53
+ if id.is_empty() {
54
+ return Err(DockError::EmptyId);
55
+ }
56
+ if id.chars().count() > Self::MAX_LEN {
57
+ return Err(DockError::IdTooLong);
58
+ }
59
+ if let Some(invalid) = id
60
+ .chars()
61
+ .find(|c| !matches!(c, 'a'..='z' | '0'..='9' | '-' | '_'))
62
+ {
63
+ return Err(DockError::InvalidChar(invalid));
64
+ }
65
+ Ok(Self(id.to_owned()))
66
+ }
67
+
68
+ /// Borrow the identifier as a string slice.
69
+ #[must_use]
70
+ pub fn as_str(&self) -> &str {
71
+ &self.0
72
+ }
73
+ }
74
+
75
+ /// Dock validation and lookup failure. Messages are fixed strings and never
76
+ /// carry focus tokens or other sensitive data.
77
+ #[derive(Clone, Debug, thiserror::Error, PartialEq, Eq)]
78
+ pub enum DockError {
79
+ /// The identifier is empty.
80
+ #[error("dock id must not be empty")]
81
+ EmptyId,
82
+ /// The identifier exceeds 64 characters.
83
+ #[error("dock id must be at most 64 characters")]
84
+ IdTooLong,
85
+ /// The identifier contains a character outside `[a-z0-9-_]`.
86
+ #[error("dock id contains invalid character: {0}")]
87
+ InvalidChar(char),
88
+ /// No dock is registered under this identifier.
89
+ #[error("unknown dock: {0}")]
90
+ UnknownDock(String),
91
+ /// A dock is already registered under this identifier.
92
+ #[error("duplicate dock: {0}")]
93
+ DuplicateDock(String),
94
+ }
95
+
96
+ /// Runtime state of a single registered dock.
97
+ #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
98
+ pub struct DockState {
99
+ /// Validated dock identifier.
100
+ pub id: DockId,
101
+ /// What the dock is for.
102
+ pub kind: DockKind,
103
+ /// Where the dock is placed.
104
+ pub placement: Placement,
105
+ /// Whether the dock is currently open.
106
+ pub open: bool,
107
+ }
108
+
109
+ /// Headless registry of docks plus a transient focus token.
110
+ ///
111
+ /// The focus token is never serialized; it only travels in memory so the
112
+ /// application can restore focus after opening a dock.
113
+ #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
114
+ pub struct DockManager {
115
+ /// Registered docks in registration order.
116
+ pub docks: Vec<DockState>,
117
+ /// Transient focus token, replaced by `open_with_focus` and consumed by
118
+ /// `take_focus_token`. Skipped by serde.
119
+ #[serde(skip, default)]
120
+ pub focus_token: Option<String>,
121
+ }
122
+
123
+ impl DockManager {
124
+ /// Empty registry with no focus token.
125
+ #[must_use]
126
+ pub fn new() -> Self {
127
+ Self::default()
128
+ }
129
+
130
+ /// Find a dock index by identifier text.
131
+ fn index_of(&self, id: &str) -> Option<usize> {
132
+ self.docks.iter().position(|dock| dock.id.as_str() == id)
133
+ }
134
+
135
+ /// Register a new closed dock.
136
+ ///
137
+ /// # Errors
138
+ ///
139
+ /// Returns [`DockError::EmptyId`], [`DockError::IdTooLong`] or
140
+ /// [`DockError::InvalidChar`] for invalid identifiers, or
141
+ /// [`DockError::DuplicateDock`] when the identifier is already registered.
142
+ pub fn register(
143
+ &mut self,
144
+ id: &str,
145
+ kind: DockKind,
146
+ placement: Placement,
147
+ ) -> Result<(), DockError> {
148
+ let validated = DockId::new(id)?;
149
+ if self.docks.iter().any(|dock| dock.id == validated) {
150
+ return Err(DockError::DuplicateDock(validated.as_str().to_owned()));
151
+ }
152
+ self.docks.push(DockState {
153
+ id: validated,
154
+ kind,
155
+ placement,
156
+ open: false,
157
+ });
158
+ Ok(())
159
+ }
160
+
161
+ /// Open a dock. Idempotent; a plain open never clears a stored focus
162
+ /// token.
163
+ ///
164
+ /// # Errors
165
+ ///
166
+ /// Returns [`DockError::UnknownDock`] when the identifier is not
167
+ /// registered.
168
+ pub fn open(&mut self, id: &str) -> Result<(), DockError> {
169
+ let Some(index) = self.index_of(id) else {
170
+ return Err(DockError::UnknownDock(id.to_owned()));
171
+ };
172
+ self.docks[index].open = true;
173
+ Ok(())
174
+ }
175
+
176
+ /// Open a dock and replace the stored focus token.
177
+ ///
178
+ /// # Errors
179
+ ///
180
+ /// Returns [`DockError::UnknownDock`] when the identifier is not
181
+ /// registered.
182
+ pub fn open_with_focus(&mut self, id: &str, token: String) -> Result<(), DockError> {
183
+ let Some(index) = self.index_of(id) else {
184
+ return Err(DockError::UnknownDock(id.to_owned()));
185
+ };
186
+ self.docks[index].open = true;
187
+ self.focus_token = Some(token);
188
+ Ok(())
189
+ }
190
+
191
+ /// Close a dock. Idempotent; keeps any stored focus token.
192
+ ///
193
+ /// # Errors
194
+ ///
195
+ /// Returns [`DockError::UnknownDock`] when the identifier is not
196
+ /// registered.
197
+ pub fn close(&mut self, id: &str) -> Result<(), DockError> {
198
+ let Some(index) = self.index_of(id) else {
199
+ return Err(DockError::UnknownDock(id.to_owned()));
200
+ };
201
+ self.docks[index].open = false;
202
+ Ok(())
203
+ }
204
+
205
+ /// Toggle a dock between open and closed.
206
+ ///
207
+ /// # Errors
208
+ ///
209
+ /// Returns [`DockError::UnknownDock`] when the identifier is not
210
+ /// registered.
211
+ pub fn toggle(&mut self, id: &str) -> Result<(), DockError> {
212
+ let Some(index) = self.index_of(id) else {
213
+ return Err(DockError::UnknownDock(id.to_owned()));
214
+ };
215
+ self.docks[index].open = !self.docks[index].open;
216
+ Ok(())
217
+ }
218
+
219
+ /// Whether a dock is currently open.
220
+ ///
221
+ /// # Errors
222
+ ///
223
+ /// Returns [`DockError::UnknownDock`] when the identifier is not
224
+ /// registered.
225
+ pub fn is_open(&self, id: &str) -> Result<bool, DockError> {
226
+ let Some(index) = self.index_of(id) else {
227
+ return Err(DockError::UnknownDock(id.to_owned()));
228
+ };
229
+ Ok(self.docks[index].open)
230
+ }
231
+
232
+ /// Current placement of a dock.
233
+ ///
234
+ /// # Errors
235
+ ///
236
+ /// Returns [`DockError::UnknownDock`] when the identifier is not
237
+ /// registered.
238
+ pub fn placement(&self, id: &str) -> Result<Placement, DockError> {
239
+ let Some(index) = self.index_of(id) else {
240
+ return Err(DockError::UnknownDock(id.to_owned()));
241
+ };
242
+ Ok(self.docks[index].placement)
243
+ }
244
+
245
+ /// Move a dock without changing whether it is open.
246
+ ///
247
+ /// # Errors
248
+ ///
249
+ /// Returns [`DockError::UnknownDock`] when the identifier is not
250
+ /// registered.
251
+ pub fn set_placement(&mut self, id: &str, placement: Placement) -> Result<(), DockError> {
252
+ let Some(index) = self.index_of(id) else {
253
+ return Err(DockError::UnknownDock(id.to_owned()));
254
+ };
255
+ self.docks[index].placement = placement;
256
+ Ok(())
257
+ }
258
+
259
+ /// Currently open docks in registration order.
260
+ #[must_use]
261
+ pub fn open_docks(&self) -> Vec<&DockState> {
262
+ self.docks.iter().filter(|dock| dock.open).collect()
263
+ }
264
+
265
+ /// Take and clear the stored focus token, if any.
266
+ pub fn take_focus_token(&mut self) -> Option<String> {
267
+ self.focus_token.take()
268
+ }
269
+
270
+ /// Close every dock. Keeps any stored focus token.
271
+ pub fn close_all(&mut self) {
272
+ for dock in &mut self.docks {
273
+ dock.open = false;
274
+ }
275
+ }
276
+ }
277
+
278
+ #[cfg(test)]
279
+ mod tests {
280
+ use super::*;
281
+
282
+ fn manager_with(id: &str, kind: DockKind, placement: Placement) -> DockManager {
283
+ let mut manager = DockManager::new();
284
+ manager.register(id, kind, placement).unwrap();
285
+ manager
286
+ }
287
+
288
+ #[test]
289
+ fn id_rejects_empty() {
290
+ assert_eq!(DockId::new("").unwrap_err(), DockError::EmptyId);
291
+ }
292
+
293
+ #[test]
294
+ fn id_rejects_too_long() {
295
+ let long: String = std::iter::repeat_n('a', 65).collect();
296
+ assert_eq!(DockId::new(&long).unwrap_err(), DockError::IdTooLong);
297
+ }
298
+
299
+ #[test]
300
+ fn id_accepts_exact_64_chars() {
301
+ let exact: String = std::iter::repeat_n('a', 64).collect();
302
+ let id = DockId::new(&exact).unwrap();
303
+ assert_eq!(id.as_str(), exact);
304
+ }
305
+
306
+ #[test]
307
+ fn id_accepts_valid_charset() {
308
+ for valid in ["chat", "a-z_0-9", "abc-123_xyz", "0", "-", "_"] {
309
+ let id = DockId::new(valid).unwrap();
310
+ assert_eq!(id.as_str(), valid);
311
+ }
312
+ }
313
+
314
+ #[test]
315
+ fn id_rejects_invalid_characters() {
316
+ for invalid in [
317
+ "Chat",
318
+ "CHAT",
319
+ "has space",
320
+ "with.dot",
321
+ "with/slash",
322
+ "UPPER",
323
+ ] {
324
+ assert!(
325
+ matches!(DockId::new(invalid).unwrap_err(), DockError::InvalidChar(_)),
326
+ "expected InvalidChar for {invalid:?}"
327
+ );
328
+ }
329
+ assert_eq!(
330
+ DockId::new("ok Bad").unwrap_err(),
331
+ DockError::InvalidChar(' ')
332
+ );
333
+ assert_eq!(DockId::new("ABC").unwrap_err(), DockError::InvalidChar('A'));
334
+ assert_eq!(DockId::new("a.b").unwrap_err(), DockError::InvalidChar('.'));
335
+ }
336
+
337
+ #[test]
338
+ fn register_ok_and_duplicate() {
339
+ let mut manager = DockManager::new();
340
+ manager
341
+ .register("chat", DockKind::Chat, Placement::Right)
342
+ .unwrap();
343
+ assert!(!manager.is_open("chat").unwrap());
344
+ assert_eq!(
345
+ manager.register("chat", DockKind::Chat, Placement::Right),
346
+ Err(DockError::DuplicateDock("chat".into()))
347
+ );
348
+ // Invalid identifiers surface validation errors, not duplicates.
349
+ assert_eq!(
350
+ manager.register("", DockKind::Chat, Placement::Right),
351
+ Err(DockError::EmptyId)
352
+ );
353
+ }
354
+
355
+ #[test]
356
+ fn open_close_toggle_idempotency_and_unknown() {
357
+ let mut manager = manager_with("chat", DockKind::Chat, Placement::Right);
358
+
359
+ // Open is idempotent.
360
+ manager.open("chat").unwrap();
361
+ assert!(manager.is_open("chat").unwrap());
362
+ manager.open("chat").unwrap();
363
+ assert!(manager.is_open("chat").unwrap());
364
+
365
+ // Close is idempotent.
366
+ manager.close("chat").unwrap();
367
+ assert!(!manager.is_open("chat").unwrap());
368
+ manager.close("chat").unwrap();
369
+ assert!(!manager.is_open("chat").unwrap());
370
+
371
+ // Toggle flips each time.
372
+ manager.toggle("chat").unwrap();
373
+ assert!(manager.is_open("chat").unwrap());
374
+ manager.toggle("chat").unwrap();
375
+ assert!(!manager.is_open("chat").unwrap());
376
+
377
+ // Unknown identifiers report UnknownDock.
378
+ for result in [
379
+ manager.open("missing"),
380
+ manager.close("missing"),
381
+ manager.toggle("missing"),
382
+ manager.open_with_focus("missing", "token".into()),
383
+ manager.set_placement("missing", Placement::Left),
384
+ ] {
385
+ assert_eq!(result, Err(DockError::UnknownDock("missing".into())));
386
+ }
387
+ assert_eq!(
388
+ manager.is_open("missing"),
389
+ Err(DockError::UnknownDock("missing".into()))
390
+ );
391
+ assert_eq!(
392
+ manager.placement("missing"),
393
+ Err(DockError::UnknownDock("missing".into()))
394
+ );
395
+ }
396
+
397
+ #[test]
398
+ fn multi_open_docks_are_independent() {
399
+ let mut manager = DockManager::new();
400
+ manager
401
+ .register("chat", DockKind::Chat, Placement::Right)
402
+ .unwrap();
403
+ manager
404
+ .register("config", DockKind::Config, Placement::Left)
405
+ .unwrap();
406
+
407
+ manager.open("chat").unwrap();
408
+ assert!(manager.is_open("chat").unwrap());
409
+ assert!(!manager.is_open("config").unwrap());
410
+
411
+ manager.open("config").unwrap();
412
+ assert!(manager.is_open("chat").unwrap());
413
+ assert!(manager.is_open("config").unwrap());
414
+
415
+ manager.close("chat").unwrap();
416
+ assert!(!manager.is_open("chat").unwrap());
417
+ assert!(manager.is_open("config").unwrap());
418
+
419
+ let open = manager.open_docks();
420
+ assert_eq!(open.len(), 1);
421
+ assert_eq!(open[0].id.as_str(), "config");
422
+ }
423
+
424
+ #[test]
425
+ fn set_placement_updates_only_target() {
426
+ let mut manager = DockManager::new();
427
+ manager
428
+ .register("chat", DockKind::Chat, Placement::Right)
429
+ .unwrap();
430
+ manager
431
+ .register("config", DockKind::Config, Placement::Left)
432
+ .unwrap();
433
+
434
+ assert_eq!(manager.placement("chat").unwrap(), Placement::Right);
435
+ manager.set_placement("chat", Placement::Bottom).unwrap();
436
+ assert_eq!(manager.placement("chat").unwrap(), Placement::Bottom);
437
+ // The other dock is untouched.
438
+ assert_eq!(manager.placement("config").unwrap(), Placement::Left);
439
+
440
+ assert_eq!(
441
+ manager.set_placement("missing", Placement::Inline),
442
+ Err(DockError::UnknownDock("missing".into()))
443
+ );
444
+ }
445
+
446
+ #[test]
447
+ fn focus_token_lifecycle() {
448
+ let mut manager = manager_with("chat", DockKind::Chat, Placement::Right);
449
+
450
+ // open_with_focus stores the token.
451
+ manager.open_with_focus("chat", "first".into()).unwrap();
452
+ assert!(manager.is_open("chat").unwrap());
453
+
454
+ // Plain open preserves an existing token.
455
+ manager.open("chat").unwrap();
456
+ assert_eq!(manager.take_focus_token().as_deref(), Some("first"));
457
+ // Take clears the token.
458
+ assert_eq!(manager.take_focus_token(), None);
459
+
460
+ // open_with_focus replaces the stored token.
461
+ manager.open_with_focus("chat", "second".into()).unwrap();
462
+ manager.open_with_focus("chat", "third".into()).unwrap();
463
+ assert_eq!(manager.take_focus_token().as_deref(), Some("third"));
464
+
465
+ // Close keeps the token for a later take.
466
+ manager.open_with_focus("chat", "kept".into()).unwrap();
467
+ manager.close("chat").unwrap();
468
+ assert!(!manager.is_open("chat").unwrap());
469
+ assert_eq!(manager.take_focus_token().as_deref(), Some("kept"));
470
+ assert_eq!(manager.take_focus_token(), None);
471
+ }
472
+
473
+ #[test]
474
+ fn close_all_closes_docks_but_keeps_token() {
475
+ let mut manager = DockManager::new();
476
+ manager
477
+ .register("chat", DockKind::Chat, Placement::Right)
478
+ .unwrap();
479
+ manager
480
+ .register("config", DockKind::Config, Placement::Left)
481
+ .unwrap();
482
+ manager.open_with_focus("chat", "token".into()).unwrap();
483
+ manager.open("config").unwrap();
484
+ assert_eq!(manager.open_docks().len(), 2);
485
+
486
+ manager.close_all();
487
+ assert!(!manager.is_open("chat").unwrap());
488
+ assert!(!manager.is_open("config").unwrap());
489
+ assert!(manager.open_docks().is_empty());
490
+ assert_eq!(manager.take_focus_token().as_deref(), Some("token"));
491
+ }
492
+
493
+ #[test]
494
+ fn serde_roundtrip_preserves_state_without_focus_token() {
495
+ let mut manager = DockManager::new();
496
+ manager
497
+ .register("chat", DockKind::Chat, Placement::Bottom)
498
+ .unwrap();
499
+ manager
500
+ .register("custom-1", DockKind::Custom, Placement::Inline)
501
+ .unwrap();
502
+ manager.open("chat").unwrap();
503
+ manager
504
+ .open_with_focus("custom-1", "transient".into())
505
+ .unwrap();
506
+
507
+ let json = serde_json::to_value(&manager).unwrap();
508
+ // The transient token is never serialized.
509
+ assert!(json.get("focus_token").is_none());
510
+
511
+ let restored: DockManager = serde_json::from_value(json).unwrap();
512
+ assert!(restored.is_open("chat").unwrap());
513
+ assert!(restored.is_open("custom-1").unwrap());
514
+ assert_eq!(restored.placement("chat").unwrap(), Placement::Bottom);
515
+ assert_eq!(restored.placement("custom-1").unwrap(), Placement::Inline);
516
+ // Deserialized managers start without a focus token.
517
+ let mut restored = restored;
518
+ assert_eq!(restored.take_focus_token(), None);
519
+ assert_eq!(restored.open_docks().len(), 2);
520
+ }
521
+
522
+ #[test]
523
+ fn open_docks_content_and_order() {
524
+ let mut manager = DockManager::new();
525
+ manager
526
+ .register("one", DockKind::Chat, Placement::Left)
527
+ .unwrap();
528
+ manager
529
+ .register("two", DockKind::Config, Placement::Right)
530
+ .unwrap();
531
+ manager
532
+ .register("three", DockKind::Custom, Placement::Inline)
533
+ .unwrap();
534
+ assert!(manager.open_docks().is_empty());
535
+
536
+ manager.open("two").unwrap();
537
+ manager.open("one").unwrap();
538
+ let open = manager.open_docks();
539
+ // Registration order, not open order.
540
+ let ids: Vec<&str> = open.iter().map(|dock| dock.id.as_str()).collect();
541
+ assert_eq!(ids, vec!["one", "two"]);
542
+ assert_eq!(open[0].kind, DockKind::Chat);
543
+ assert_eq!(open[1].placement, Placement::Right);
544
+ }
545
+
546
+ #[test]
547
+ fn error_messages_never_carry_focus_tokens() {
548
+ let token = "focus-secret-token";
549
+ let mut manager = manager_with("chat", DockKind::Chat, Placement::Right);
550
+ manager.open_with_focus("chat", token.into()).unwrap();
551
+
552
+ let errors = [
553
+ DockError::EmptyId,
554
+ DockError::IdTooLong,
555
+ DockError::InvalidChar('X'),
556
+ DockError::UnknownDock("missing".into()),
557
+ DockError::DuplicateDock("chat".into()),
558
+ ];
559
+ for error in errors {
560
+ let rendered = format!("{error} {error:?}");
561
+ assert!(!rendered.contains("focus-secret-token"));
562
+ }
563
+ }
564
+ }
@@ -0,0 +1,39 @@
1
+ //! Reusable conversations for native applications and the web.
2
+ //!
3
+ //! The conversation model and event contract compile to native Rust and Wasm.
4
+ //! Native connections use the official ACP SDK; applications own their UI,
5
+ //! persistence, prompts and authorization decisions.
6
+ //!
7
+ //! ```
8
+ //! use ccht::{Conversation, Event, WireEvent, acp};
9
+ //! let mut conversation = Conversation::new("creator");
10
+ //! let event = WireEvent::new("creator", "turn-1", 1,
11
+ //! Event::Update { update: acp::SessionUpdate::AgentMessageChunk(
12
+ //! acp::ContentChunk::new("Hello".into())) });
13
+ //! conversation.apply(event).unwrap();
14
+ //! assert_eq!(conversation.turns()[0].text, "Hello");
15
+ //! ```
16
+
17
+ /// The official platform-independent ACP version 1 schema.
18
+ pub use agent_client_protocol_schema::v1 as acp;
19
+
20
+ mod configuration;
21
+ pub use configuration::*;
22
+
23
+ mod auth;
24
+ pub use auth::*;
25
+
26
+ mod conversation;
27
+ pub use conversation::*;
28
+
29
+ mod transport;
30
+ pub use transport::*;
31
+
32
+ mod dock;
33
+ pub use dock::*;
34
+
35
+ #[cfg(all(feature = "native", not(target_family = "wasm")))]
36
+ pub mod native;
37
+
38
+ #[cfg(feature = "web")]
39
+ mod web;