@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,422 @@
1
+ <!-- Product-neutral bare chat panel (messages + composer + history). The
2
+ application owns all effects (sending, stopping, history switching,
3
+ clipboard feedback, error surfacing, configuration); this component only
4
+ renders state and forwards user intent through app-supplied callbacks. It
5
+ never fetches, spawns, or stores anything. -->
6
+ <script module lang="ts">
7
+ import type { TurnState } from '../../index.js';
8
+
9
+ /** One renderable chat message. `activity` carries the live turn detail. */
10
+ export interface ChatDockMessage {
11
+ id: string;
12
+ role: 'user' | 'assistant';
13
+ content: string;
14
+ modelName?: string;
15
+ requestId?: string;
16
+ activity?: TurnState;
17
+ }
18
+
19
+ /** One entry in the conversation history picker. */
20
+ export interface ChatHistoryItem {
21
+ id: string;
22
+ title?: string | null;
23
+ message_count?: number;
24
+ }
25
+
26
+ /** Default status text for a turn. The application may override it. */
27
+ export function defaultChatStatusLabel(activity: TurnState): string {
28
+ switch (activity.status) {
29
+ case 'streaming':
30
+ return 'Responding…';
31
+ case 'awaiting_permission':
32
+ return 'Needs approval';
33
+ case 'completed':
34
+ return 'Done';
35
+ case 'cancelled':
36
+ return 'Stopped';
37
+ case 'refused':
38
+ return 'Declined';
39
+ case 'failed':
40
+ return 'Failed';
41
+ }
42
+ }
43
+ </script>
44
+
45
+ <script lang="ts">
46
+ import type { Snippet } from 'svelte';
47
+ import type { TurnState } from '../../index.js';
48
+
49
+ let {
50
+ kicker,
51
+ title,
52
+ composerId,
53
+ composerLabel,
54
+ composerPlaceholder,
55
+ sendLabel,
56
+ welcomeTitle,
57
+ welcomeBody,
58
+ welcomeExample,
59
+ messages,
60
+ draft = $bindable(''),
61
+ history = [],
62
+ activeHistoryId = null,
63
+ showHistoryPicker = false,
64
+ submitting = false,
65
+ canSend = true,
66
+ controlsLoading = false,
67
+ composerDisabled = false,
68
+ onSend,
69
+ onStop,
70
+ onSelectHistory,
71
+ onCopy,
72
+ onShowActivity,
73
+ statusLabel = defaultChatStatusLabel,
74
+ headerExtra,
75
+ statusNote,
76
+ messageBody,
77
+ activityExtra
78
+ }: {
79
+ kicker: string;
80
+ title: string;
81
+ composerId: string;
82
+ composerLabel: string;
83
+ composerPlaceholder: string;
84
+ sendLabel: string;
85
+ welcomeTitle: string;
86
+ welcomeBody: string;
87
+ welcomeExample: string;
88
+ messages: ChatDockMessage[];
89
+ draft: string;
90
+ history?: ChatHistoryItem[];
91
+ activeHistoryId?: string | null;
92
+ showHistoryPicker?: boolean;
93
+ submitting?: boolean;
94
+ canSend?: boolean;
95
+ controlsLoading?: boolean;
96
+ composerDisabled?: boolean;
97
+ onSend: (text: string) => void | Promise<void>;
98
+ onStop?: () => void;
99
+ onSelectHistory?: (id: string) => void;
100
+ onCopy?: (id: string, content: string) => void;
101
+ onShowActivity?: (msg: ChatDockMessage) => void;
102
+ statusLabel?: (activity: TurnState) => string;
103
+ headerExtra?: Snippet;
104
+ statusNote?: Snippet;
105
+ messageBody?: Snippet<[ChatDockMessage]>;
106
+ activityExtra?: Snippet<[TurnState]>;
107
+ } = $props();
108
+
109
+ const sendDisabled: boolean = $derived(
110
+ submitting || !canSend || controlsLoading || draft.trim().length === 0
111
+ );
112
+ let copiedId: string | null = $state(null);
113
+
114
+ function invoke(action: () => void | Promise<void>): void {
115
+ try {
116
+ const result = action();
117
+ if (result instanceof Promise) {
118
+ result.catch(() => {});
119
+ }
120
+ } catch {
121
+ // Handled by the application through its own operation state.
122
+ }
123
+ }
124
+
125
+ // The draft is cleared optimistically and restored when the application
126
+ // rejects, so no typed text is lost. The application surfaces the failure
127
+ // through its own operation state.
128
+ async function submit(event: SubmitEvent): Promise<void> {
129
+ event.preventDefault();
130
+ const prompt = draft.trim();
131
+ if (!prompt || submitting || !canSend || controlsLoading) {
132
+ return;
133
+ }
134
+ draft = '';
135
+ try {
136
+ await onSend(prompt);
137
+ } catch {
138
+ if (!draft) {
139
+ draft = prompt;
140
+ }
141
+ }
142
+ }
143
+
144
+ function handleComposerKeydown(event: KeyboardEvent): void {
145
+ if (event.key !== 'Enter' || event.shiftKey || event.isComposing) {
146
+ return;
147
+ }
148
+ event.preventDefault();
149
+ if (event.currentTarget instanceof HTMLTextAreaElement) {
150
+ event.currentTarget.form?.requestSubmit();
151
+ }
152
+ }
153
+
154
+ // The panel keeps its own Copied feedback; the application may add its own
155
+ // handling through onCopy.
156
+ async function copyMessage(id: string, content: string): Promise<void> {
157
+ try {
158
+ await navigator.clipboard.writeText(content);
159
+ copiedId = id;
160
+ } catch {
161
+ // Clipboard unavailable; the application decides how to report it.
162
+ }
163
+ invoke(() => onCopy?.(id, content));
164
+ }
165
+
166
+ function historyTitle(item: ChatHistoryItem): string {
167
+ const label = item.title ?? 'Untitled conversation';
168
+ return typeof item.message_count === 'number'
169
+ ? `${label} · ${item.message_count}`
170
+ : label;
171
+ }
172
+ </script>
173
+
174
+ <div class="ccht-chat-heading">
175
+ <div>
176
+ <p class="ccht-chat-kicker">{kicker}</p>
177
+ <h2 class="ccht-chat-title">{title}</h2>
178
+ </div>
179
+ <div class="ccht-chat-actions">
180
+ {#if messages.length > 0 && onSelectHistory}
181
+ <button type="button" class="ccht-chat-new-chat" onclick={() => invoke(() => onSelectHistory(''))}>
182
+ New conversation
183
+ </button>
184
+ {/if}
185
+ {#if headerExtra}{@render headerExtra()}{/if}
186
+ </div>
187
+ </div>
188
+
189
+ {#if statusNote}
190
+ <div class="ccht-chat-status-note">{@render statusNote()}</div>
191
+ {/if}
192
+
193
+ {#if showHistoryPicker}
194
+ <div class="ccht-chat-picker">
195
+ <label for="{composerId}-history">Conversation</label>
196
+ <select
197
+ id="{composerId}-history"
198
+ value={activeHistoryId ?? ''}
199
+ onchange={(event) => invoke(() => onSelectHistory?.(event.currentTarget.value))}
200
+ >
201
+ <option value="">New conversation</option>
202
+ {#each history as item (item.id)}
203
+ <option value={item.id}>{historyTitle(item)}</option>
204
+ {/each}
205
+ </select>
206
+ </div>
207
+ {/if}
208
+
209
+ <div class="ccht-chat-messages" aria-live="polite" aria-label="{title} messages">
210
+ {#if messages.length === 0}
211
+ <article class="ccht-chat-message ccht-chat-message-assistant ccht-chat-welcome">
212
+ <strong>{welcomeTitle}</strong>
213
+ <p>{welcomeBody}</p>
214
+ <p class="ccht-chat-example">{welcomeExample}</p>
215
+ </article>
216
+ {/if}
217
+ {#each messages as message (message.id)}
218
+ <article
219
+ class="ccht-chat-message"
220
+ class:ccht-chat-message-user={message.role === 'user'}
221
+ class:ccht-chat-message-assistant={message.role === 'assistant'}
222
+ >
223
+ <strong>{message.role === 'user' ? 'You' : welcomeTitle}</strong>
224
+ {#if messageBody}
225
+ {@render messageBody(message)}
226
+ {:else}
227
+ <p>{message.content}</p>
228
+ {/if}
229
+ {#if message.content}
230
+ <button type="button" class="ccht-chat-copy" onclick={() => void copyMessage(message.id, message.content)}>
231
+ {copiedId === message.id ? 'Copied' : 'Copy'}
232
+ </button>
233
+ {/if}
234
+ {#if message.modelName}<small class="ccht-chat-model">{message.modelName}</small>{/if}
235
+ {#if message.role === 'assistant' && message.requestId && !message.activity && onShowActivity}
236
+ <button type="button" class="ccht-chat-copy" onclick={() => invoke(() => onShowActivity(message))}>
237
+ Show activity
238
+ </button>
239
+ {/if}
240
+ {#if message.activity}
241
+ {@const activity = message.activity}
242
+ {#if activityExtra}
243
+ {@render activityExtra(activity)}
244
+ {:else}
245
+ {#if activity.thought_text}
246
+ <details class="ccht-chat-reasoning">
247
+ <summary>Reasoning</summary>
248
+ <p>{activity.thought_text}</p>
249
+ </details>
250
+ {/if}
251
+ {#each Object.values(activity.tools) as tool (tool.toolCallId)}
252
+ <details class="ccht-chat-tool">
253
+ <summary>{tool.title} · {tool.status ?? 'pending'}</summary>
254
+ <pre>{JSON.stringify(
255
+ { input: tool.rawInput, output: tool.rawOutput, content: tool.content },
256
+ null,
257
+ 2
258
+ )}</pre>
259
+ </details>
260
+ {/each}
261
+ {@const usage = activity.updates.usage_update as { used?: unknown; size?: unknown } | undefined}
262
+ {#if typeof usage?.used === 'number'}
263
+ <p class="ccht-chat-usage">
264
+ Context: {usage.used.toLocaleString()} / {typeof usage.size === 'number'
265
+ ? usage.size.toLocaleString()
266
+ : '?'} tokens
267
+ </p>
268
+ {/if}
269
+ {@const plan = activity.updates.plan as
270
+ | { entries?: Array<{ content?: unknown; status?: unknown }> }
271
+ | undefined}
272
+ {#if Array.isArray(plan?.entries) && plan.entries.length > 0}
273
+ <details class="ccht-chat-plan">
274
+ <summary>Plan</summary>
275
+ <ol>
276
+ {#each plan.entries as entry}
277
+ <li>{String(entry.content ?? '')} · {String(entry.status ?? '')}</li>
278
+ {/each}
279
+ </ol>
280
+ </details>
281
+ {/if}
282
+ {#if activity.permissions.length > 0}
283
+ <p class="ccht-chat-permissions">
284
+ {activity.permissions.length}
285
+ {activity.permissions.length === 1 ? 'permission request' : 'permission requests'}
286
+ pending: {activity.permissions.map((permission) => permission.request_id).join(', ')}
287
+ </p>
288
+ {/if}
289
+ {#if activity.error}
290
+ <p class="ccht-chat-error" role="alert">{activity.error.code}: {activity.error.message}</p>
291
+ {/if}
292
+ <p class="ccht-chat-status">
293
+ <span role="status">{statusLabel(activity)}</span>{#if activity.stop_reason}<span>
294
+ · {activity.stop_reason}</span>{/if}
295
+ </p>
296
+ {/if}
297
+ {/if}
298
+ </article>
299
+ {/each}
300
+ </div>
301
+
302
+ <form class="ccht-chat-composer" onsubmit={submit} aria-busy={submitting}>
303
+ <label class="ccht-chat-sr-only" for={composerId}>{composerLabel}</label>
304
+ <textarea
305
+ id={composerId}
306
+ bind:value={draft}
307
+ onkeydown={handleComposerKeydown}
308
+ rows="3"
309
+ placeholder={composerPlaceholder}
310
+ disabled={composerDisabled}
311
+ required
312
+ ></textarea>
313
+ <div class="ccht-chat-actions">
314
+ {#if submitting && onStop}
315
+ <button type="button" class="ccht-chat-stop" onclick={() => invoke(onStop)}>Stop</button>
316
+ {/if}
317
+ <button type="submit" class="ccht-chat-primary" aria-label={sendLabel} disabled={sendDisabled}>
318
+ {sendLabel}
319
+ </button>
320
+ </div>
321
+ </form>
322
+
323
+ <style>
324
+ .ccht-chat-heading {
325
+ flex: 0 0 auto; display: flex; justify-content: space-between; align-items: start; gap: 0.8rem;
326
+ padding: 0.1rem 0.1rem 0.9rem; border-bottom: 1px solid var(--ccht-border, #223049);
327
+ }
328
+ .ccht-chat-kicker {
329
+ margin: 0; font-size: 0.7rem; font-weight: 850; letter-spacing: 0.12em; text-transform: uppercase;
330
+ color: var(--ccht-kicker, var(--ccht-muted, #8fa0b7));
331
+ }
332
+ .ccht-chat-title { margin: 0.2rem 0 0; font-size: 1.02rem; overflow-wrap: anywhere; }
333
+ .ccht-chat-heading .ccht-chat-actions { display: flex; align-items: center; gap: 0.45rem; }
334
+ .ccht-chat-new-chat {
335
+ min-height: 2.4rem; padding: 0 0.55rem; border: 1px solid var(--ccht-border, #30405c);
336
+ border-radius: 0.5rem; color: var(--ccht-fg, #c2cede); background: var(--ccht-tab-bg, #111c2d);
337
+ font-size: 0.62rem; font-weight: 850; cursor: pointer;
338
+ }
339
+ .ccht-chat-new-chat:hover {
340
+ border-color: var(--ccht-accent, #53708f);
341
+ background: var(--ccht-tab-bg-hover, #17243a);
342
+ }
343
+ .ccht-chat-status-note { flex: 0 0 auto; padding-top: 0.7rem; color: var(--ccht-muted, #8fa0b7); }
344
+ .ccht-chat-picker {
345
+ flex: 0 0 auto; display: grid; grid-template-columns: auto minmax(0, 1fr);
346
+ align-items: center; gap: 0.55rem; padding: 0.7rem 0.1rem 0;
347
+ }
348
+ .ccht-chat-picker label {
349
+ color: var(--ccht-muted, #8fa0b7); font-size: 0.58rem; text-transform: uppercase; font-weight: 750;
350
+ }
351
+ .ccht-chat-picker select {
352
+ min-width: 0; min-height: 2.2rem; padding: 0.4rem 0.5rem;
353
+ border: 1px solid var(--ccht-border, #30405c); border-radius: 0.45rem;
354
+ color: var(--ccht-fg, #c2cede); background: var(--ccht-input-bg, #111c2d);
355
+ font-size: 0.68rem; font-family: inherit;
356
+ }
357
+ .ccht-chat-messages {
358
+ flex: 1 1 auto; min-height: 0; margin: 0.8rem -0.25rem 0; padding: 0 0.25rem 0.5rem;
359
+ overflow: auto; overscroll-behavior: contain;
360
+ }
361
+ .ccht-chat-message {
362
+ margin-bottom: 0.65rem; padding: 0.78rem;
363
+ border: 1px solid var(--ccht-border, #223049); border-radius: 0.65rem;
364
+ background: var(--ccht-message-bg, #111c2d);
365
+ }
366
+ .ccht-chat-message-assistant { background: var(--ccht-message-assistant-bg, #0d1625); }
367
+ .ccht-chat-message-user {
368
+ margin-left: 1.35rem; border-color: var(--ccht-accent, #53708f);
369
+ background: var(--ccht-message-user-bg, #17243a);
370
+ }
371
+ .ccht-chat-message strong { font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; }
372
+ .ccht-chat-message p {
373
+ margin: 0.35rem 0 0; color: var(--ccht-fg, #c2cede); line-height: 1.55; overflow-wrap: anywhere;
374
+ }
375
+ .ccht-chat-example { color: var(--ccht-muted, #8fa0b7); font-size: 0.75rem; }
376
+ .ccht-chat-copy {
377
+ border: 1px solid var(--ccht-border, #30405c); border-radius: 0.4rem;
378
+ background: var(--ccht-tab-bg, #111c2d); color: var(--ccht-fg, #c2cede);
379
+ padding: 0.3rem 0.5rem; margin-top: 0.4rem; cursor: pointer; font-size: 0.65rem;
380
+ }
381
+ .ccht-chat-model { display: block; color: var(--ccht-muted, #8fa0b7); margin-top: 0.4rem; overflow-wrap: anywhere; }
382
+ .ccht-chat-reasoning, .ccht-chat-plan { margin-top: 0.5rem; color: var(--ccht-muted, #8fa0b7); }
383
+ .ccht-chat-reasoning summary, .ccht-chat-plan summary, .ccht-chat-tool summary {
384
+ cursor: pointer; font-size: 0.75rem;
385
+ }
386
+ .ccht-chat-tool { margin-top: 0.5rem; color: var(--ccht-muted, #8fa0b7); }
387
+ .ccht-chat-tool pre { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 0.7rem; }
388
+ .ccht-chat-usage, .ccht-chat-permissions, .ccht-chat-status {
389
+ color: var(--ccht-muted, #8fa0b7); font-size: 0.75rem;
390
+ }
391
+ .ccht-chat-error { color: var(--ccht-error, #b91c1c); }
392
+ .ccht-chat-composer {
393
+ flex: 0 0 auto; margin: 0 -0.1rem -0.1rem; padding: 0.8rem 0.1rem 0.1rem;
394
+ border-top: 1px solid var(--ccht-border, #223049); display: grid; gap: 0.72rem;
395
+ }
396
+ .ccht-chat-composer textarea {
397
+ width: 100%; min-height: 5rem; max-height: 12rem; resize: vertical;
398
+ padding: 0.75rem 0.82rem; border: 1px solid var(--ccht-border, #30405c); border-radius: 0.5rem;
399
+ color: var(--ccht-fg, inherit); background: var(--ccht-input-bg, #111c2d);
400
+ outline: 0; font: inherit; line-height: 1.5;
401
+ }
402
+ .ccht-chat-composer .ccht-chat-actions { display: grid; gap: 0.55rem; }
403
+ .ccht-chat-primary {
404
+ min-height: 2.75rem; padding: 0.78rem 1rem; border: 0; border-radius: 0.5rem;
405
+ color: var(--ccht-primary-fg, #e2eaf5); background: var(--ccht-primary-bg, #53708f);
406
+ font-weight: 850; cursor: pointer; width: 100%;
407
+ }
408
+ .ccht-chat-primary:hover { background: var(--ccht-primary-bg-hover, #17243a); }
409
+ .ccht-chat-primary:disabled { cursor: not-allowed; opacity: 0.48; }
410
+ .ccht-chat-stop {
411
+ min-height: 2.4rem; padding: 0.55rem 0.85rem; border: 1px solid var(--ccht-border, #30405c);
412
+ border-radius: 0.5rem; color: var(--ccht-fg, #c2cede); background: var(--ccht-tab-bg, #111c2d);
413
+ font-size: 0.72rem; font-weight: 850; cursor: pointer;
414
+ }
415
+ .ccht-chat-sr-only {
416
+ position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
417
+ overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
418
+ }
419
+ @media (max-width: 640px) {
420
+ .ccht-chat-message-user { margin-left: 0.75rem; }
421
+ }
422
+ </style>
@@ -0,0 +1,92 @@
1
+ /** Browser behavior of the shared edge rail (Dock.svelte).
2
+ *
3
+ * jsdom exercises tab/panel switching, Esc handling, focus move and
4
+ * restore, and the inert contract. Fixtures only; no network or storage.
5
+ */
6
+ import { render, fireEvent, cleanup } from '@testing-library/svelte';
7
+ import { afterEach, describe, expect, test, vi } from 'vitest';
8
+ import Dock from './Dock.svelte';
9
+
10
+ afterEach(() => cleanup());
11
+
12
+ function openDock(props: Record<string, unknown> = {}) {
13
+ return render(Dock, {
14
+ side: 'left',
15
+ title: 'Scope',
16
+ open: false,
17
+ onClose: () => {},
18
+ onOpen: () => {},
19
+ tabLabel: 'Scope',
20
+ tabSummary: '3 checks',
21
+ panelId: 'scope-panel',
22
+ ...props,
23
+ });
24
+ }
25
+
26
+ describe('closed rail', () => {
27
+ test('shows the edge tab with summary and hides the panel', () => {
28
+ const { getByRole, container } = openDock();
29
+ const tab = getByRole('button', { name: 'Open Scope: 3 checks' });
30
+ expect(tab.getAttribute('aria-expanded')).toBe('false');
31
+ expect(tab.getAttribute('aria-controls')).toBe('scope-panel');
32
+ const panel = container.querySelector('#scope-panel');
33
+ expect(panel?.getAttribute('aria-hidden')).toBe('true');
34
+ expect(panel?.getAttribute('data-open')).toBe('false');
35
+ });
36
+
37
+ test('tab click calls onOpen', async () => {
38
+ const onOpen = vi.fn();
39
+ const { getByRole } = openDock({ onOpen });
40
+ await fireEvent.click(getByRole('button', { name: 'Open Scope: 3 checks' }));
41
+ expect(onOpen).toHaveBeenCalledTimes(1);
42
+ });
43
+ });
44
+
45
+ describe('open rail', () => {
46
+ test('renders dialog content and Done/Close affordances', () => {
47
+ const { getByRole } = openDock({ open: true });
48
+ const dialog = getByRole('dialog', { name: 'Scope' });
49
+ expect(dialog.getAttribute('data-open')).toBe('true');
50
+ expect(getByRole('button', { name: 'Close Scope' })).toBeTruthy();
51
+ });
52
+
53
+ test('Escape calls onClose only when open', async () => {
54
+ const onClose = vi.fn();
55
+ const closed = openDock({ onClose });
56
+ await fireEvent.keyDown(closed.container, { key: 'Escape' });
57
+ expect(onClose).not.toHaveBeenCalled();
58
+ const opened = openDock({ open: true, onClose });
59
+ await fireEvent.keyDown(opened.container.ownerDocument, { key: 'Escape' });
60
+ expect(onClose).toHaveBeenCalledTimes(1);
61
+ });
62
+
63
+ test('opening moves focus into the panel, closing returns it', async () => {
64
+ // jsdom has no layout: every getClientRects() is empty, so the filter
65
+ // correctly falls back to the panel itself. Stub rects to exercise the
66
+ // real-browser path where the first control wins.
67
+ const rects = vi.spyOn(window.Element.prototype, 'getClientRects').mockReturnValue([{} as DOMRect]);
68
+ try {
69
+ const { getByRole, rerender } = openDock();
70
+ getByRole('button', { name: 'Open Scope: 3 checks' }).focus();
71
+ await rerender({ open: true });
72
+ await new Promise((resolve) => requestAnimationFrame(() => resolve(undefined)));
73
+ expect(document.activeElement?.getAttribute('aria-label')).toBe('Close Scope');
74
+ await rerender({ open: false });
75
+ await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve(undefined))));
76
+ // The tab remounts on close; focus must land on the live node.
77
+ const liveTab = getByRole('button', { name: 'Open Scope: 3 checks' });
78
+ expect(liveTab.isConnected).toBe(true);
79
+ expect(document.activeElement).toBe(liveTab);
80
+ } finally {
81
+ rects.mockRestore();
82
+ }
83
+ });
84
+
85
+ test('opening falls back to the panel when no control is visible', async () => {
86
+ const { getByRole, rerender, container } = openDock();
87
+ await rerender({ open: true });
88
+ await new Promise((resolve) => requestAnimationFrame(() => resolve(undefined)));
89
+ expect(document.activeElement).toBe(container.querySelector('#scope-panel'));
90
+ expect(getByRole('dialog', { name: 'Scope' })).toBeTruthy();
91
+ });
92
+ });
@@ -55,10 +55,13 @@
55
55
  });
56
56
  } else if (!open && wasOpen) {
57
57
  wasOpen = false;
58
- const restore = prevFocus?.isConnected ? prevFocus : null;
58
+ // Prefer the live remounted tab over the recorded invoker: the tab
59
+ // unmounts while the panel is open, so a stored node may be stale.
60
+ const invoker = prevFocus?.isConnected ? prevFocus : null;
59
61
  prevFocus = null;
60
62
  requestAnimationFrame(() => {
61
- (restore ?? tabEl)?.focus?.();
63
+ const liveTab = tabEl?.isConnected ? tabEl : null;
64
+ (liveTab ?? invoker)?.focus?.();
62
65
  });
63
66
  }
64
67
  });
@@ -102,7 +105,7 @@
102
105
  <div class="ccht-dock-title"><h2>{title}</h2>{#if tabSummary}<p>{tabSummary}</p>{/if}</div>
103
106
  <button type="button" class="ccht-dock-close" aria-label={dismissLabel} onclick={onClose}>Close</button>
104
107
  </div>
105
- <div class="ccht-dock-body">{@render children()}</div>
108
+ <div class="ccht-dock-body">{#if children}{@render children()}{/if}</div>
106
109
  </div>
107
110
 
108
111
  <style>