@corbet-labs/ccht 0.2.0 → 0.2.2

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 (382) hide show
  1. package/README.md +194 -212
  2. package/index.d.ts +6 -1
  3. package/index.js +8 -1
  4. package/package.json +12 -26
  5. package/src/auth.ts +149 -0
  6. package/src/components/AccountConnection.svelte +201 -0
  7. package/src/components/Dock.svelte +172 -0
  8. package/src/dock.ts +244 -0
  9. package/wasm/ccht_bg.wasm +0 -0
  10. package/LICENSE +0 -307
  11. package/LICENSE.md +0 -25
  12. package/LICENSES/GPL-3.0-only.txt +0 -232
  13. package/LICENSES/LGPL-3.0-only.txt +0 -304
  14. package/LICENSES/dependencies/agent-client-protocol-2.1.0/LICENSE +0 -191
  15. package/LICENSES/dependencies/agent-client-protocol-derive-2.1.0/LICENSE +0 -191
  16. package/LICENSES/dependencies/agent-client-protocol-schema-1.7.0/LICENSE +0 -190
  17. package/LICENSES/dependencies/android_system_properties-0.1.6/LICENSE-APACHE +0 -13
  18. package/LICENSES/dependencies/android_system_properties-0.1.6/LICENSE-MIT +0 -20
  19. package/LICENSES/dependencies/anyhow-1.0.104/LICENSE-APACHE +0 -176
  20. package/LICENSES/dependencies/anyhow-1.0.104/LICENSE-MIT +0 -23
  21. package/LICENSES/dependencies/async-channel-2.5.0/LICENSE-APACHE +0 -201
  22. package/LICENSES/dependencies/async-channel-2.5.0/LICENSE-MIT +0 -23
  23. package/LICENSES/dependencies/async-io-2.6.0/LICENSE-APACHE +0 -201
  24. package/LICENSES/dependencies/async-io-2.6.0/LICENSE-MIT +0 -23
  25. package/LICENSES/dependencies/async-lock-3.4.2/LICENSE-APACHE +0 -201
  26. package/LICENSES/dependencies/async-lock-3.4.2/LICENSE-MIT +0 -23
  27. package/LICENSES/dependencies/async-process-2.5.0/LICENSE-APACHE +0 -201
  28. package/LICENSES/dependencies/async-process-2.5.0/LICENSE-MIT +0 -23
  29. package/LICENSES/dependencies/async-signal-0.2.14/LICENSE-APACHE +0 -201
  30. package/LICENSES/dependencies/async-signal-0.2.14/LICENSE-MIT +0 -23
  31. package/LICENSES/dependencies/async-task-4.7.1/LICENSE-APACHE +0 -201
  32. package/LICENSES/dependencies/async-task-4.7.1/LICENSE-MIT +0 -23
  33. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-APACHE +0 -201
  34. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-MIT +0 -23
  35. package/LICENSES/dependencies/atomic-waker-1.1.2/LICENSE-THIRD-PARTY +0 -45
  36. package/LICENSES/dependencies/autocfg-1.5.1/LICENSE-APACHE +0 -201
  37. package/LICENSES/dependencies/autocfg-1.5.1/LICENSE-MIT +0 -25
  38. package/LICENSES/dependencies/base64-0.22.1/LICENSE-APACHE +0 -201
  39. package/LICENSES/dependencies/base64-0.22.1/LICENSE-MIT +0 -21
  40. package/LICENSES/dependencies/base64-0.23.1/LICENSE-APACHE +0 -201
  41. package/LICENSES/dependencies/base64-0.23.1/LICENSE-MIT +0 -21
  42. package/LICENSES/dependencies/bitflags-1.3.2/LICENSE-APACHE +0 -201
  43. package/LICENSES/dependencies/bitflags-1.3.2/LICENSE-MIT +0 -25
  44. package/LICENSES/dependencies/bitflags-2.13.2/LICENSE-APACHE +0 -201
  45. package/LICENSES/dependencies/bitflags-2.13.2/LICENSE-MIT +0 -25
  46. package/LICENSES/dependencies/blocking-1.7.0/LICENSE-APACHE +0 -201
  47. package/LICENSES/dependencies/blocking-1.7.0/LICENSE-MIT +0 -23
  48. package/LICENSES/dependencies/bs58-0.5.1/LICENSE-APACHE +0 -201
  49. package/LICENSES/dependencies/bs58-0.5.1/LICENSE-MIT +0 -20
  50. package/LICENSES/dependencies/bumpalo-3.20.3/LICENSE-APACHE +0 -201
  51. package/LICENSES/dependencies/bumpalo-3.20.3/LICENSE-MIT +0 -25
  52. package/LICENSES/dependencies/cc-1.4.5/LICENSE-APACHE +0 -201
  53. package/LICENSES/dependencies/cc-1.4.5/LICENSE-MIT +0 -25
  54. package/LICENSES/dependencies/cfg-if-1.0.4/LICENSE-APACHE +0 -201
  55. package/LICENSES/dependencies/cfg-if-1.0.4/LICENSE-MIT +0 -25
  56. package/LICENSES/dependencies/chrono-0.4.45/LICENSE.txt +0 -240
  57. package/LICENSES/dependencies/concurrent-queue-2.5.0/LICENSE-APACHE +0 -201
  58. package/LICENSES/dependencies/concurrent-queue-2.5.0/LICENSE-MIT +0 -23
  59. package/LICENSES/dependencies/convert_case-0.10.0/LICENSE +0 -21
  60. package/LICENSES/dependencies/core-foundation-sys-0.8.7/LICENSE-APACHE +0 -201
  61. package/LICENSES/dependencies/core-foundation-sys-0.8.7/LICENSE-MIT +0 -25
  62. package/LICENSES/dependencies/crossbeam-deque-0.8.8/LICENSE-APACHE +0 -201
  63. package/LICENSES/dependencies/crossbeam-deque-0.8.8/LICENSE-MIT +0 -27
  64. package/LICENSES/dependencies/crossbeam-epoch-0.9.21/LICENSE-APACHE +0 -201
  65. package/LICENSES/dependencies/crossbeam-epoch-0.9.21/LICENSE-MIT +0 -27
  66. package/LICENSES/dependencies/crossbeam-utils-0.8.23/LICENSE-APACHE +0 -201
  67. package/LICENSES/dependencies/crossbeam-utils-0.8.23/LICENSE-MIT +0 -27
  68. package/LICENSES/dependencies/darling-0.24.1/LICENSE +0 -21
  69. package/LICENSES/dependencies/darling_core-0.24.1/LICENSE +0 -21
  70. package/LICENSES/dependencies/darling_macro-0.24.1/LICENSE +0 -21
  71. package/LICENSES/dependencies/defmt-1.1.1/LICENSE-APACHE +0 -201
  72. package/LICENSES/dependencies/defmt-1.1.1/LICENSE-MIT +0 -25
  73. package/LICENSES/dependencies/defmt-macros-1.1.1/LICENSE-APACHE +0 -201
  74. package/LICENSES/dependencies/defmt-macros-1.1.1/LICENSE-MIT +0 -25
  75. package/LICENSES/dependencies/defmt-parser-1.0.0/LICENSE-APACHE +0 -201
  76. package/LICENSES/dependencies/defmt-parser-1.0.0/LICENSE-MIT +0 -25
  77. package/LICENSES/dependencies/deranged-0.5.8/LICENSE-Apache +0 -202
  78. package/LICENSES/dependencies/deranged-0.5.8/LICENSE-MIT +0 -19
  79. package/LICENSES/dependencies/derive_more-2.1.1/LICENSE +0 -21
  80. package/LICENSES/dependencies/derive_more-impl-2.1.1/LICENSE +0 -21
  81. package/LICENSES/dependencies/dyn-clone-1.0.20/LICENSE-APACHE +0 -176
  82. package/LICENSES/dependencies/dyn-clone-1.0.20/LICENSE-MIT +0 -23
  83. package/LICENSES/dependencies/either-1.18.0/LICENSE-APACHE +0 -201
  84. package/LICENSES/dependencies/either-1.18.0/LICENSE-MIT +0 -25
  85. package/LICENSES/dependencies/equivalent-1.0.2/LICENSE-APACHE +0 -201
  86. package/LICENSES/dependencies/equivalent-1.0.2/LICENSE-MIT +0 -25
  87. package/LICENSES/dependencies/errno-0.3.14/LICENSE-APACHE +0 -201
  88. package/LICENSES/dependencies/errno-0.3.14/LICENSE-MIT +0 -25
  89. package/LICENSES/dependencies/event-listener-5.4.2/LICENSE-APACHE +0 -201
  90. package/LICENSES/dependencies/event-listener-5.4.2/LICENSE-MIT +0 -23
  91. package/LICENSES/dependencies/event-listener-strategy-0.5.4/LICENSE-APACHE +0 -201
  92. package/LICENSES/dependencies/event-listener-strategy-0.5.4/LICENSE-MIT +0 -23
  93. package/LICENSES/dependencies/fallible-iterator-0.3.0/LICENSE-APACHE +0 -202
  94. package/LICENSES/dependencies/fallible-iterator-0.3.0/LICENSE-MIT +0 -19
  95. package/LICENSES/dependencies/fastrand-2.5.0/LICENSE-APACHE +0 -201
  96. package/LICENSES/dependencies/fastrand-2.5.0/LICENSE-MIT +0 -23
  97. package/LICENSES/dependencies/find-msvc-tools-0.1.12/LICENSE-APACHE +0 -201
  98. package/LICENSES/dependencies/find-msvc-tools-0.1.12/LICENSE-MIT +0 -25
  99. package/LICENSES/dependencies/fixedbitset-0.5.7/LICENSE-APACHE +0 -201
  100. package/LICENSES/dependencies/fixedbitset-0.5.7/LICENSE-MIT +0 -25
  101. package/LICENSES/dependencies/foldhash-0.2.0/LICENSE +0 -19
  102. package/LICENSES/dependencies/futures-0.3.34/LICENSE-APACHE +0 -202
  103. package/LICENSES/dependencies/futures-0.3.34/LICENSE-MIT +0 -26
  104. package/LICENSES/dependencies/futures-channel-0.3.34/LICENSE-APACHE +0 -202
  105. package/LICENSES/dependencies/futures-channel-0.3.34/LICENSE-MIT +0 -26
  106. package/LICENSES/dependencies/futures-concurrency-7.7.1/LICENSE-APACHE +0 -190
  107. package/LICENSES/dependencies/futures-concurrency-7.7.1/LICENSE-MIT +0 -21
  108. package/LICENSES/dependencies/futures-core-0.3.34/LICENSE-APACHE +0 -202
  109. package/LICENSES/dependencies/futures-core-0.3.34/LICENSE-MIT +0 -26
  110. package/LICENSES/dependencies/futures-executor-0.3.34/LICENSE-APACHE +0 -202
  111. package/LICENSES/dependencies/futures-executor-0.3.34/LICENSE-MIT +0 -26
  112. package/LICENSES/dependencies/futures-io-0.3.34/LICENSE-APACHE +0 -202
  113. package/LICENSES/dependencies/futures-io-0.3.34/LICENSE-MIT +0 -26
  114. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-APACHE +0 -201
  115. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-MIT +0 -23
  116. package/LICENSES/dependencies/futures-lite-2.6.1/LICENSE-THIRD-PARTY +0 -45
  117. package/LICENSES/dependencies/futures-macro-0.3.34/LICENSE-APACHE +0 -202
  118. package/LICENSES/dependencies/futures-macro-0.3.34/LICENSE-MIT +0 -26
  119. package/LICENSES/dependencies/futures-sink-0.3.34/LICENSE-APACHE +0 -202
  120. package/LICENSES/dependencies/futures-sink-0.3.34/LICENSE-MIT +0 -26
  121. package/LICENSES/dependencies/futures-task-0.3.34/LICENSE-APACHE +0 -202
  122. package/LICENSES/dependencies/futures-task-0.3.34/LICENSE-MIT +0 -26
  123. package/LICENSES/dependencies/futures-util-0.3.34/LICENSE-APACHE +0 -202
  124. package/LICENSES/dependencies/futures-util-0.3.34/LICENSE-MIT +0 -26
  125. package/LICENSES/dependencies/getrandom-0.4.3/LICENSE-APACHE +0 -201
  126. package/LICENSES/dependencies/getrandom-0.4.3/LICENSE-MIT +0 -26
  127. package/LICENSES/dependencies/gimli-0.32.3/LICENSE-APACHE +0 -201
  128. package/LICENSES/dependencies/gimli-0.32.3/LICENSE-MIT +0 -25
  129. package/LICENSES/dependencies/hashbrown-0.12.3/LICENSE-APACHE +0 -201
  130. package/LICENSES/dependencies/hashbrown-0.12.3/LICENSE-MIT +0 -25
  131. package/LICENSES/dependencies/hashbrown-0.16.1/LICENSE-APACHE +0 -201
  132. package/LICENSES/dependencies/hashbrown-0.16.1/LICENSE-MIT +0 -25
  133. package/LICENSES/dependencies/hashbrown-0.17.1/LICENSE-APACHE +0 -201
  134. package/LICENSES/dependencies/hashbrown-0.17.1/LICENSE-MIT +0 -25
  135. package/LICENSES/dependencies/heck-0.5.0/LICENSE-APACHE +0 -201
  136. package/LICENSES/dependencies/heck-0.5.0/LICENSE-MIT +0 -25
  137. package/LICENSES/dependencies/hermit-abi-0.5.3/LICENSE-APACHE +0 -201
  138. package/LICENSES/dependencies/hermit-abi-0.5.3/LICENSE-MIT +0 -23
  139. package/LICENSES/dependencies/hex-0.4.3/LICENSE-APACHE +0 -202
  140. package/LICENSES/dependencies/hex-0.4.3/LICENSE-MIT +0 -20
  141. package/LICENSES/dependencies/iana-time-zone-0.1.65/LICENSE-APACHE +0 -201
  142. package/LICENSES/dependencies/iana-time-zone-0.1.65/LICENSE-MIT +0 -25
  143. package/LICENSES/dependencies/iana-time-zone-haiku-0.1.2/LICENSE-APACHE +0 -201
  144. package/LICENSES/dependencies/iana-time-zone-haiku-0.1.2/LICENSE-MIT +0 -25
  145. package/LICENSES/dependencies/id-arena-2.3.0/LICENSE-APACHE +0 -201
  146. package/LICENSES/dependencies/id-arena-2.3.0/LICENSE-MIT +0 -25
  147. package/LICENSES/dependencies/ident_case-1.0.1/LICENSE +0 -19
  148. package/LICENSES/dependencies/indexmap-1.9.3/LICENSE-APACHE +0 -201
  149. package/LICENSES/dependencies/indexmap-1.9.3/LICENSE-MIT +0 -25
  150. package/LICENSES/dependencies/indexmap-2.14.2/LICENSE-APACHE +0 -201
  151. package/LICENSES/dependencies/indexmap-2.14.2/LICENSE-MIT +0 -25
  152. package/LICENSES/dependencies/itoa-1.0.18/LICENSE-APACHE +0 -176
  153. package/LICENSES/dependencies/itoa-1.0.18/LICENSE-MIT +0 -23
  154. package/LICENSES/dependencies/jiff-0.2.35/COPYING +0 -3
  155. package/LICENSES/dependencies/jiff-0.2.35/LICENSE-MIT +0 -21
  156. package/LICENSES/dependencies/jiff-0.2.35/UNLICENSE +0 -24
  157. package/LICENSES/dependencies/jiff-core-0.1.0/COPYING +0 -3
  158. package/LICENSES/dependencies/jiff-core-0.1.0/LICENSE-MIT +0 -21
  159. package/LICENSES/dependencies/jiff-core-0.1.0/UNLICENSE +0 -24
  160. package/LICENSES/dependencies/jiff-static-0.2.35/COPYING +0 -3
  161. package/LICENSES/dependencies/jiff-static-0.2.35/LICENSE-MIT +0 -21
  162. package/LICENSES/dependencies/jiff-static-0.2.35/UNLICENSE +0 -24
  163. package/LICENSES/dependencies/jiff-tzdb-0.1.8/COPYING +0 -3
  164. package/LICENSES/dependencies/jiff-tzdb-0.1.8/LICENSE-MIT +0 -21
  165. package/LICENSES/dependencies/jiff-tzdb-0.1.8/UNLICENSE +0 -24
  166. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/COPYING +0 -3
  167. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/LICENSE-MIT +0 -21
  168. package/LICENSES/dependencies/jiff-tzdb-platform-0.1.3/UNLICENSE +0 -24
  169. package/LICENSES/dependencies/js-sys-0.3.105/LICENSE-APACHE +0 -201
  170. package/LICENSES/dependencies/js-sys-0.3.105/LICENSE-MIT +0 -25
  171. package/LICENSES/dependencies/leb128-0.2.7/LICENSE-APACHE +0 -201
  172. package/LICENSES/dependencies/leb128-0.2.7/LICENSE-MIT +0 -25
  173. package/LICENSES/dependencies/leb128fmt-0.1.0/LICENSE-APACHE +0 -201
  174. package/LICENSES/dependencies/leb128fmt-0.1.0/LICENSE-MIT +0 -23
  175. package/LICENSES/dependencies/libc-0.2.189/LICENSE-APACHE +0 -176
  176. package/LICENSES/dependencies/libc-0.2.189/LICENSE-MIT +0 -25
  177. package/LICENSES/dependencies/linux-raw-sys-0.12.1/COPYRIGHT +0 -29
  178. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-APACHE +0 -201
  179. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  180. package/LICENSES/dependencies/linux-raw-sys-0.12.1/LICENSE-MIT +0 -23
  181. package/LICENSES/dependencies/log-0.4.34/LICENSE-APACHE +0 -201
  182. package/LICENSES/dependencies/log-0.4.34/LICENSE-MIT +0 -25
  183. package/LICENSES/dependencies/memchr-2.8.3/COPYING +0 -3
  184. package/LICENSES/dependencies/memchr-2.8.3/LICENSE-MIT +0 -21
  185. package/LICENSES/dependencies/memchr-2.8.3/UNLICENSE +0 -24
  186. package/LICENSES/dependencies/mio-1.2.3/LICENSE +0 -19
  187. package/LICENSES/dependencies/num-conv-0.2.2/LICENSE-Apache +0 -177
  188. package/LICENSES/dependencies/num-conv-0.2.2/LICENSE-MIT +0 -19
  189. package/LICENSES/dependencies/num-traits-0.2.19/LICENSE-APACHE +0 -201
  190. package/LICENSES/dependencies/num-traits-0.2.19/LICENSE-MIT +0 -25
  191. package/LICENSES/dependencies/once_cell-1.21.4/LICENSE-APACHE +0 -201
  192. package/LICENSES/dependencies/once_cell-1.21.4/LICENSE-MIT +0 -23
  193. package/LICENSES/dependencies/parking-2.2.1/LICENSE-APACHE +0 -201
  194. package/LICENSES/dependencies/parking-2.2.1/LICENSE-MIT +0 -23
  195. package/LICENSES/dependencies/parking-2.2.1/LICENSE-THIRD-PARTY +0 -9
  196. package/LICENSES/dependencies/pin-project-1.1.13/LICENSE-APACHE +0 -177
  197. package/LICENSES/dependencies/pin-project-1.1.13/LICENSE-MIT +0 -23
  198. package/LICENSES/dependencies/pin-project-internal-1.1.13/LICENSE-APACHE +0 -177
  199. package/LICENSES/dependencies/pin-project-internal-1.1.13/LICENSE-MIT +0 -23
  200. package/LICENSES/dependencies/pin-project-lite-0.2.17/LICENSE-APACHE +0 -177
  201. package/LICENSES/dependencies/pin-project-lite-0.2.17/LICENSE-MIT +0 -23
  202. package/LICENSES/dependencies/piper-0.2.5/LICENSE-APACHE +0 -201
  203. package/LICENSES/dependencies/piper-0.2.5/LICENSE-MIT +0 -23
  204. package/LICENSES/dependencies/polling-3.11.0/LICENSE-APACHE +0 -201
  205. package/LICENSES/dependencies/polling-3.11.0/LICENSE-MIT +0 -23
  206. package/LICENSES/dependencies/portable-atomic-1.15.0/LICENSE-APACHE +0 -177
  207. package/LICENSES/dependencies/portable-atomic-1.15.0/LICENSE-MIT +0 -23
  208. package/LICENSES/dependencies/portable-atomic-util-0.2.8/LICENSE-APACHE +0 -177
  209. package/LICENSES/dependencies/portable-atomic-util-0.2.8/LICENSE-MIT +0 -23
  210. package/LICENSES/dependencies/powerfmt-0.2.0/LICENSE-Apache +0 -202
  211. package/LICENSES/dependencies/powerfmt-0.2.0/LICENSE-MIT +0 -19
  212. package/LICENSES/dependencies/proc-macro2-1.0.107/LICENSE-APACHE +0 -176
  213. package/LICENSES/dependencies/proc-macro2-1.0.107/LICENSE-MIT +0 -23
  214. package/LICENSES/dependencies/quote-1.0.47/LICENSE-APACHE +0 -176
  215. package/LICENSES/dependencies/quote-1.0.47/LICENSE-MIT +0 -23
  216. package/LICENSES/dependencies/r-efi-6.0.0/AUTHORS +0 -75
  217. package/LICENSES/dependencies/rayon-1.12.0/LICENSE-APACHE +0 -201
  218. package/LICENSES/dependencies/rayon-1.12.0/LICENSE-MIT +0 -25
  219. package/LICENSES/dependencies/rayon-core-1.13.0/LICENSE-APACHE +0 -201
  220. package/LICENSES/dependencies/rayon-core-1.13.0/LICENSE-MIT +0 -25
  221. package/LICENSES/dependencies/ref-cast-1.0.27/LICENSE-APACHE +0 -176
  222. package/LICENSES/dependencies/ref-cast-1.0.27/LICENSE-MIT +0 -23
  223. package/LICENSES/dependencies/ref-cast-impl-1.0.27/LICENSE-APACHE +0 -176
  224. package/LICENSES/dependencies/ref-cast-impl-1.0.27/LICENSE-MIT +0 -23
  225. package/LICENSES/dependencies/rustc-demangle-0.1.28/LICENSE-APACHE +0 -201
  226. package/LICENSES/dependencies/rustc-demangle-0.1.28/LICENSE-MIT +0 -25
  227. package/LICENSES/dependencies/rustc-hash-2.1.3/LICENSE-APACHE +0 -176
  228. package/LICENSES/dependencies/rustc-hash-2.1.3/LICENSE-MIT +0 -23
  229. package/LICENSES/dependencies/rustc_version-0.4.1/LICENSE-APACHE +0 -201
  230. package/LICENSES/dependencies/rustc_version-0.4.1/LICENSE-MIT +0 -25
  231. package/LICENSES/dependencies/rustix-1.1.4/COPYRIGHT +0 -29
  232. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-APACHE +0 -201
  233. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  234. package/LICENSES/dependencies/rustix-1.1.4/LICENSE-MIT +0 -23
  235. package/LICENSES/dependencies/rustversion-1.0.23/LICENSE-APACHE +0 -176
  236. package/LICENSES/dependencies/rustversion-1.0.23/LICENSE-MIT +0 -23
  237. package/LICENSES/dependencies/schemars-0.9.0/LICENSE +0 -21
  238. package/LICENSES/dependencies/schemars-1.2.2/LICENSE +0 -21
  239. package/LICENSES/dependencies/schemars_derive-1.2.2/LICENSE +0 -21
  240. package/LICENSES/dependencies/semver-1.0.28/LICENSE-APACHE +0 -176
  241. package/LICENSES/dependencies/semver-1.0.28/LICENSE-MIT +0 -23
  242. package/LICENSES/dependencies/serde-1.0.229/LICENSE-APACHE +0 -176
  243. package/LICENSES/dependencies/serde-1.0.229/LICENSE-MIT +0 -23
  244. package/LICENSES/dependencies/serde_core-1.0.229/LICENSE-APACHE +0 -176
  245. package/LICENSES/dependencies/serde_core-1.0.229/LICENSE-MIT +0 -23
  246. package/LICENSES/dependencies/serde_derive-1.0.229/LICENSE-APACHE +0 -176
  247. package/LICENSES/dependencies/serde_derive-1.0.229/LICENSE-MIT +0 -23
  248. package/LICENSES/dependencies/serde_derive_internals-0.30.0/LICENSE-APACHE +0 -176
  249. package/LICENSES/dependencies/serde_derive_internals-0.30.0/LICENSE-MIT +0 -23
  250. package/LICENSES/dependencies/serde_json-1.0.151/LICENSE-APACHE +0 -176
  251. package/LICENSES/dependencies/serde_json-1.0.151/LICENSE-MIT +0 -23
  252. package/LICENSES/dependencies/serde_with-3.23.0/LICENSE-APACHE +0 -201
  253. package/LICENSES/dependencies/serde_with-3.23.0/LICENSE-MIT +0 -25
  254. package/LICENSES/dependencies/serde_with_macros-3.23.0/LICENSE-APACHE +0 -201
  255. package/LICENSES/dependencies/serde_with_macros-3.23.0/LICENSE-MIT +0 -25
  256. package/LICENSES/dependencies/shell-words-1.1.1/LICENSE-APACHE +0 -201
  257. package/LICENSES/dependencies/shell-words-1.1.1/LICENSE-MIT +0 -25
  258. package/LICENSES/dependencies/shlex-2.0.1/LICENSE-APACHE +0 -13
  259. package/LICENSES/dependencies/shlex-2.0.1/LICENSE-MIT +0 -21
  260. package/LICENSES/dependencies/signal-hook-registry-1.4.8/LICENSE-APACHE +0 -201
  261. package/LICENSES/dependencies/signal-hook-registry-1.4.8/LICENSE-MIT +0 -25
  262. package/LICENSES/dependencies/slab-0.4.12/LICENSE +0 -25
  263. package/LICENSES/dependencies/smallvec-1.16.0/LICENSE-APACHE +0 -201
  264. package/LICENSES/dependencies/smallvec-1.16.0/LICENSE-MIT +0 -25
  265. package/LICENSES/dependencies/socket2-0.6.5/LICENSE-APACHE +0 -201
  266. package/LICENSES/dependencies/socket2-0.6.5/LICENSE-MIT +0 -25
  267. package/LICENSES/dependencies/stable_deref_trait-1.2.1/LICENSE-APACHE +0 -201
  268. package/LICENSES/dependencies/stable_deref_trait-1.2.1/LICENSE-MIT +0 -25
  269. package/LICENSES/dependencies/strsim-0.11.1/LICENSE +0 -23
  270. package/LICENSES/dependencies/strum-0.28.0/LICENSE +0 -21
  271. package/LICENSES/dependencies/strum_macros-0.28.0/LICENSE +0 -21
  272. package/LICENSES/dependencies/syn-2.0.119/LICENSE-APACHE +0 -176
  273. package/LICENSES/dependencies/syn-2.0.119/LICENSE-MIT +0 -23
  274. package/LICENSES/dependencies/syn-3.0.5/LICENSE-APACHE +0 -176
  275. package/LICENSES/dependencies/syn-3.0.5/LICENSE-MIT +0 -23
  276. package/LICENSES/dependencies/thiserror-2.0.20/LICENSE-APACHE +0 -176
  277. package/LICENSES/dependencies/thiserror-2.0.20/LICENSE-MIT +0 -23
  278. package/LICENSES/dependencies/thiserror-impl-2.0.20/LICENSE-APACHE +0 -176
  279. package/LICENSES/dependencies/thiserror-impl-2.0.20/LICENSE-MIT +0 -23
  280. package/LICENSES/dependencies/time-0.3.55/LICENSE-Apache +0 -177
  281. package/LICENSES/dependencies/time-0.3.55/LICENSE-MIT +0 -19
  282. package/LICENSES/dependencies/time-core-0.1.9/LICENSE-Apache +0 -177
  283. package/LICENSES/dependencies/time-core-0.1.9/LICENSE-MIT +0 -19
  284. package/LICENSES/dependencies/time-macros-0.2.32/LICENSE-Apache +0 -177
  285. package/LICENSES/dependencies/time-macros-0.2.32/LICENSE-MIT +0 -19
  286. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-APACHE.md +0 -202
  287. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-MIT.md +0 -5
  288. package/LICENSES/dependencies/tinyvec-1.13.2/LICENSE-ZLIB.md +0 -11
  289. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-APACHE.md +0 -202
  290. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-MIT.md +0 -21
  291. package/LICENSES/dependencies/tinyvec_macros-0.1.1/LICENSE-ZLIB.md +0 -20
  292. package/LICENSES/dependencies/tokio-1.53.1/LICENSE +0 -21
  293. package/LICENSES/dependencies/tokio-macros-2.7.2/LICENSE +0 -22
  294. package/LICENSES/dependencies/tracing-0.1.44/LICENSE +0 -25
  295. package/LICENSES/dependencies/tracing-attributes-0.1.31/LICENSE +0 -25
  296. package/LICENSES/dependencies/tracing-core-0.1.36/LICENSE +0 -25
  297. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-APACHE +0 -176
  298. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-MIT +0 -23
  299. package/LICENSES/dependencies/unicode-ident-1.0.24/LICENSE-UNICODE +0 -39
  300. package/LICENSES/dependencies/unicode-segmentation-1.13.3/COPYRIGHT +0 -7
  301. package/LICENSES/dependencies/unicode-segmentation-1.13.3/LICENSE-APACHE +0 -201
  302. package/LICENSES/dependencies/unicode-segmentation-1.13.3/LICENSE-MIT +0 -25
  303. package/LICENSES/dependencies/unicode-xid-0.2.6/COPYRIGHT +0 -7
  304. package/LICENSES/dependencies/unicode-xid-0.2.6/LICENSE-APACHE +0 -201
  305. package/LICENSES/dependencies/unicode-xid-0.2.6/LICENSE-MIT +0 -25
  306. package/LICENSES/dependencies/uuid-1.26.1/LICENSE-APACHE +0 -201
  307. package/LICENSES/dependencies/uuid-1.26.1/LICENSE-MIT +0 -26
  308. package/LICENSES/dependencies/walrus-0.26.5/LICENSE-APACHE +0 -201
  309. package/LICENSES/dependencies/walrus-0.26.5/LICENSE-MIT +0 -25
  310. package/LICENSES/dependencies/walrus-macro-0.26.0/LICENSE-APACHE +0 -201
  311. package/LICENSES/dependencies/walrus-macro-0.26.0/LICENSE-MIT +0 -25
  312. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-APACHE +0 -201
  313. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  314. package/LICENSES/dependencies/wasi-0.11.1+wasi-snapshot-preview1/LICENSE-MIT +0 -23
  315. package/LICENSES/dependencies/wasm-bindgen-0.2.128/LICENSE-APACHE +0 -201
  316. package/LICENSES/dependencies/wasm-bindgen-0.2.128/LICENSE-MIT +0 -25
  317. package/LICENSES/dependencies/wasm-bindgen-cli-support-0.2.128/LICENSE-APACHE +0 -201
  318. package/LICENSES/dependencies/wasm-bindgen-cli-support-0.2.128/LICENSE-MIT +0 -25
  319. package/LICENSES/dependencies/wasm-bindgen-macro-0.2.128/LICENSE-APACHE +0 -201
  320. package/LICENSES/dependencies/wasm-bindgen-macro-0.2.128/LICENSE-MIT +0 -25
  321. package/LICENSES/dependencies/wasm-bindgen-macro-support-0.2.128/LICENSE-APACHE +0 -201
  322. package/LICENSES/dependencies/wasm-bindgen-macro-support-0.2.128/LICENSE-MIT +0 -25
  323. package/LICENSES/dependencies/wasm-bindgen-shared-0.2.128/LICENSE-APACHE +0 -201
  324. package/LICENSES/dependencies/wasm-bindgen-shared-0.2.128/LICENSE-MIT +0 -25
  325. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-APACHE +0 -201
  326. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  327. package/LICENSES/dependencies/wasm-encoder-0.245.1/LICENSE-MIT +0 -23
  328. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-APACHE +0 -201
  329. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  330. package/LICENSES/dependencies/wasmparser-0.245.1/LICENSE-MIT +0 -23
  331. package/LICENSES/dependencies/windows-core-0.62.2/license-apache-2.0 +0 -201
  332. package/LICENSES/dependencies/windows-core-0.62.2/license-mit +0 -21
  333. package/LICENSES/dependencies/windows-implement-0.60.2/license-apache-2.0 +0 -201
  334. package/LICENSES/dependencies/windows-implement-0.60.2/license-mit +0 -21
  335. package/LICENSES/dependencies/windows-interface-0.59.3/license-apache-2.0 +0 -201
  336. package/LICENSES/dependencies/windows-interface-0.59.3/license-mit +0 -21
  337. package/LICENSES/dependencies/windows-link-0.2.1/license-apache-2.0 +0 -201
  338. package/LICENSES/dependencies/windows-link-0.2.1/license-mit +0 -21
  339. package/LICENSES/dependencies/windows-result-0.4.1/license-apache-2.0 +0 -201
  340. package/LICENSES/dependencies/windows-result-0.4.1/license-mit +0 -21
  341. package/LICENSES/dependencies/windows-strings-0.5.1/license-apache-2.0 +0 -201
  342. package/LICENSES/dependencies/windows-strings-0.5.1/license-mit +0 -21
  343. package/LICENSES/dependencies/windows-sys-0.61.2/license-apache-2.0 +0 -201
  344. package/LICENSES/dependencies/windows-sys-0.61.2/license-mit +0 -21
  345. package/LICENSES/dependencies/zmij-1.0.23/LICENSE-MIT +0 -23
  346. package/THIRD-PARTY.md +0 -45
  347. package/source/.cargo/config.toml +0 -5
  348. package/source/.ci/upstream-notices/PROVENANCE.json +0 -198
  349. package/source/.ci/upstream-notices/agent-client-protocol-2.1.0/LICENSE +0 -191
  350. package/source/.ci/upstream-notices/agent-client-protocol-derive-2.1.0/LICENSE +0 -191
  351. package/source/.ci/upstream-notices/agent-client-protocol-schema-1.7.0/LICENSE +0 -190
  352. package/source/.ci/upstream-notices/defmt-parser-1.0.0/LICENSE-APACHE +0 -201
  353. package/source/.ci/upstream-notices/defmt-parser-1.0.0/LICENSE-MIT +0 -25
  354. package/source/.ci/upstream-notices/r-efi-6.0.0/AUTHORS +0 -75
  355. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-APACHE +0 -201
  356. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  357. package/source/.ci/upstream-notices/wasm-encoder-0.245.1/LICENSE-MIT +0 -23
  358. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-APACHE +0 -201
  359. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-Apache-2.0_WITH_LLVM-exception +0 -220
  360. package/source/.ci/upstream-notices/wasmparser-0.245.1/LICENSE-MIT +0 -23
  361. package/source/.ci/wasm-bundle/Cargo.toml +0 -10
  362. package/source/.ci/wasm-bundle/src/main.rs +0 -17
  363. package/source/CHANGELOG.md +0 -28
  364. package/source/Cargo.lock +0 -1622
  365. package/source/Cargo.toml +0 -48
  366. package/source/LICENSE +0 -307
  367. package/source/LICENSE.md +0 -25
  368. package/source/LICENSES/GPL-3.0-only.txt +0 -232
  369. package/source/LICENSES/LGPL-3.0-only.txt +0 -304
  370. package/source/README.md +0 -234
  371. package/source/THIRD-PARTY.md +0 -45
  372. package/source/dependencies.tar.gz +0 -0
  373. package/source/examples/native.rs +0 -45
  374. package/source/src/configuration.rs +0 -89
  375. package/source/src/conversation.rs +0 -569
  376. package/source/src/lib.rs +0 -30
  377. package/source/src/native/client.rs +0 -395
  378. package/source/src/native/fixture.py +0 -114
  379. package/source/src/native/mod.rs +0 -252
  380. package/source/src/native/session.rs +0 -603
  381. package/source/src/native/tests.rs +0 -463
  382. package/source/src/web.rs +0 -35
package/src/auth.ts ADDED
@@ -0,0 +1,149 @@
1
+ /** Typed mirrors of the Rust auth surface (`ccht::auth`) for web consumers.
2
+ *
3
+ * The conversation model stays in Rust/Wasm; these types only describe *who*
4
+ * may act. Transport, login ceremonies, credential storage, polling and
5
+ * product copy belong to the embedding application. Nothing here touches the
6
+ * DOM, performs network I/O, or spawns processes: effects run in the
7
+ * application backend and reach the browser through app-supplied async
8
+ * callbacks and explicit service keys.
9
+ */
10
+
11
+ /** Login state of one provider, mirroring `ccht::auth::AuthState`.
12
+ *
13
+ * The shape round-trips the Rust `snake_case` JSON byte-for-byte, so a state
14
+ * serialized by Rust deserializes here and vice versa:
15
+ * - `Unknown` becomes the string `"unknown"`.
16
+ * - `Unauthenticated` becomes the string `"unauthenticated"`.
17
+ * - `Authenticated { account }` becomes `{"authenticated": {"account": ...}}`,
18
+ * where `account` is a display-only label (string), `null`, or absent.
19
+ * The label is provenance for the UI and never an authentication proof.
20
+ */
21
+ export type AuthState = 'unknown' | 'unauthenticated' | { authenticated: { account?: string | null } };
22
+
23
+ /** Whether routine work may proceed without prompting for login first. Mirrors `AuthState::authenticated`. */
24
+ export function isAuthenticated(state: AuthState): boolean {
25
+ return typeof state === 'object' && state !== null && 'authenticated' in state;
26
+ }
27
+
28
+ /** Display-only account label (username, email, or subscription name), or null when absent. Never a secret. */
29
+ export function authAccount(state: AuthState): string | null {
30
+ if (typeof state === 'object' && state !== null && 'authenticated' in state) {
31
+ return state.authenticated.account ?? null;
32
+ }
33
+ return null;
34
+ }
35
+
36
+ /** Whether a decoded JSON value has the exact Rust `AuthState` shape. Unknown fields inside the inner object are ignored, matching serde's default. */
37
+ export function isAuthState(value: unknown): value is AuthState {
38
+ try {
39
+ parseAuthState(value);
40
+ return true;
41
+ } catch {
42
+ return false;
43
+ }
44
+ }
45
+
46
+ /** Validate a decoded JSON value as the Rust `AuthState` shape. Throws a `TypeError` when the shape differs. */
47
+ export function parseAuthState(value: unknown): AuthState {
48
+ if (value === 'unknown' || value === 'unauthenticated') {
49
+ return value;
50
+ }
51
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
52
+ const keys = Object.keys(value);
53
+ if (keys.length === 1 && keys[0] === 'authenticated') {
54
+ const inner = (value as { authenticated: unknown }).authenticated;
55
+ if (typeof inner === 'object' && inner !== null && !Array.isArray(inner)) {
56
+ const account = (inner as { account?: unknown }).account;
57
+ if (account === undefined) {
58
+ return { authenticated: {} };
59
+ }
60
+ if (account === null || typeof account === 'string') {
61
+ return { authenticated: { account } };
62
+ }
63
+ }
64
+ }
65
+ }
66
+ throw new TypeError('invalid AuthState');
67
+ }
68
+
69
+ /** Device-code challenge as exchanged during a provider login ceremony.
70
+ *
71
+ * Field names stay `snake_case` to match the wire format applications pass
72
+ * between their backend and the browser. The backend remains authoritative:
73
+ * it issues the challenge, pins any provider-specific endpoint, and polls
74
+ * for completion. The browser only displays a validated challenge and never
75
+ * invents one.
76
+ */
77
+ export interface Challenge {
78
+ verification_url: string;
79
+ user_code: string;
80
+ }
81
+
82
+ const CHALLENGE_CODE_PATTERN = /^[A-Za-z0-9-]+$/;
83
+ const CHALLENGE_CODE_MAX_LENGTH = 64;
84
+
85
+ /** Whether a value is a renderable device-code challenge.
86
+ *
87
+ * Accepts any `https:` URL with a host (applications may narrow this
88
+ * further, for example by pinning the provider's device endpoint) and a
89
+ * non-empty code of up to 64 ASCII alphanumeric or `-` characters. URLs with
90
+ * embedded credentials are rejected. Never throws; validate before rendering
91
+ * a challenge as a link or code.
92
+ */
93
+ export function validateChallenge(value: unknown): value is Challenge {
94
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
95
+ return false;
96
+ }
97
+ const { verification_url, user_code } = value as Record<string, unknown>;
98
+ if (typeof verification_url !== 'string' || typeof user_code !== 'string') {
99
+ return false;
100
+ }
101
+ if (user_code.length < 1 || user_code.length > CHALLENGE_CODE_MAX_LENGTH) {
102
+ return false;
103
+ }
104
+ if (!CHALLENGE_CODE_PATTERN.test(user_code)) {
105
+ return false;
106
+ }
107
+ let url: URL;
108
+ try {
109
+ url = new URL(verification_url);
110
+ } catch {
111
+ return false;
112
+ }
113
+ if (url.protocol !== 'https:' || url.hostname === '') {
114
+ return false;
115
+ }
116
+ if (url.username !== '' || url.password !== '') {
117
+ return false;
118
+ }
119
+ return true;
120
+ }
121
+
122
+ /** Opaque credential, mirroring `ccht::auth::Credential`.
123
+ *
124
+ * Stores treat both fields as opaque. `account` is display-only; `secret`
125
+ * holds the raw secret bytes. Encode at the application boundary (for
126
+ * example with `TextEncoder` or base64) when the backing store needs text,
127
+ * and never write secrets to logs, errors, or fixtures.
128
+ */
129
+ export interface Credential {
130
+ account: string;
131
+ secret: Uint8Array;
132
+ }
133
+
134
+ /** Application-supplied credential persistence, mirroring `ccht::auth::CredentialsProvider`.
135
+ *
136
+ * One method triple per service key. Service keys are application-defined
137
+ * opaque strings (never ambient authority); native applications back this
138
+ * with the OS keychain and web applications with origin-scoped browser
139
+ * storage. Removing a missing entry succeeds. Implementations reject the
140
+ * promise when the backing store fails.
141
+ */
142
+ export interface CredentialsProvider {
143
+ /** Read stored credentials, if any, for a service key. */
144
+ readCredentials(service: string): Promise<Credential | null>;
145
+ /** Persist credentials for a service key, replacing any previous entry. */
146
+ writeCredentials(service: string, credential: Credential): Promise<void>;
147
+ /** Remove stored credentials for a service key. Missing entries are not an error. */
148
+ deleteCredentials(service: string): Promise<void>;
149
+ }
@@ -0,0 +1,201 @@
1
+ <!-- Product-neutral account connector. The application backend owns all effects
2
+ (starting device flows, polling logins, storing keys, signing out); this
3
+ component only renders state and forwards user intent through app-supplied
4
+ async callbacks. It never spawns agents, polls, or touches credentials. -->
5
+ <script lang="ts">
6
+ import {
7
+ authAccount,
8
+ isAuthenticated,
9
+ validateChallenge,
10
+ type AuthState,
11
+ type Challenge
12
+ } from '../auth.js';
13
+
14
+ interface AccountRef {
15
+ id: string;
16
+ label: string;
17
+ kind: 'chatgpt' | 'opencode_go' | (string & {});
18
+ }
19
+
20
+ let {
21
+ account,
22
+ state: authState = 'unknown' as AuthState,
23
+ busy = false,
24
+ challenge = null as Challenge | null,
25
+ onStart,
26
+ onCancel,
27
+ onKeySubmit,
28
+ onDisconnect
29
+ }: {
30
+ account: AccountRef;
31
+ state: AuthState;
32
+ busy: boolean;
33
+ challenge?: Challenge | null;
34
+ onStart: () => void | Promise<void>;
35
+ onCancel: () => void | Promise<void>;
36
+ onKeySubmit: (key: string) => void | Promise<void>;
37
+ onDisconnect?: () => void | Promise<void>;
38
+ } = $props();
39
+
40
+ let key = $state('');
41
+ let copyError = $state('');
42
+
43
+ // Renamed locally: a binding called `state` would shadow the `$state` rune analysis.
44
+ const authenticated: boolean = $derived(isAuthenticated(authState));
45
+ const accountName: string | null = $derived(authAccount(authState));
46
+ const validChallenge: Challenge | null = $derived(
47
+ challenge != null && validateChallenge(challenge) ? challenge : null
48
+ );
49
+ const isDeviceCodeAccount: boolean = $derived(account.kind === 'chatgpt');
50
+ const isKeyAccount: boolean = $derived(account.kind === 'opencode_go');
51
+ const keyInputId: string = $derived(`ccht-key-${account.id.replace(/[^a-zA-Z0-9_-]/g, '-')}`);
52
+ const canSubmitKey: boolean = $derived(key.trim().length >= 8 && !busy);
53
+
54
+ // Callbacks run application effects; the app surfaces their failures
55
+ // through its own operation state, so a rejection here stays silent.
56
+ function invoke(action: () => void | Promise<void>): void {
57
+ try {
58
+ const result = action();
59
+ if (result instanceof Promise) {
60
+ result.catch(() => {});
61
+ }
62
+ } catch {
63
+ // Handled by the application through its own operation state.
64
+ }
65
+ }
66
+
67
+ function submitKey(event: SubmitEvent): void {
68
+ event.preventDefault();
69
+ const value = key.trim();
70
+ // Clear immediately so the secret never lingers in component state.
71
+ key = '';
72
+ if (value.length < 8) {
73
+ return;
74
+ }
75
+ invoke(() => onKeySubmit(value));
76
+ }
77
+
78
+ async function copyAndContinue(): Promise<void> {
79
+ if (!validChallenge) {
80
+ return;
81
+ }
82
+ // Open during the click so browsers do not block the sign-in window after copying.
83
+ if (typeof window !== 'undefined') {
84
+ window.open(validChallenge.verification_url, '_blank', 'noopener,noreferrer');
85
+ }
86
+ try {
87
+ await navigator.clipboard.writeText(validChallenge.user_code);
88
+ copyError = '';
89
+ } catch {
90
+ copyError = 'Could not copy automatically. Copy the code above into the sign-in page.';
91
+ }
92
+ }
93
+ </script>
94
+
95
+ <section class="ccht-account" aria-label={`${account.label} connection`}>
96
+ {#if authenticated}
97
+ <p class="ccht-status" role="status">Connected{#if accountName} · {accountName}{/if}</p>
98
+ <button
99
+ type="button"
100
+ class="ccht-button ccht-disconnect"
101
+ disabled={busy}
102
+ onclick={() => invoke(onDisconnect ?? onCancel)}
103
+ >
104
+ Disconnect
105
+ </button>
106
+ {:else if authState === 'unknown'}
107
+ <p class="ccht-status" role="status">Checking {account.label} connection status…</p>
108
+ {#if busy}
109
+ <button type="button" class="ccht-button ccht-cancel" onclick={() => invoke(onCancel)}>
110
+ Cancel
111
+ </button>
112
+ {/if}
113
+ {:else if isDeviceCodeAccount}
114
+ {#if validChallenge}
115
+ <div class="ccht-challenge" aria-live="polite">
116
+ <p class="ccht-hint">Enter this code on the {account.label} sign-in page:</p>
117
+ <code class="ccht-code">{validChallenge.user_code}</code>
118
+ <button type="button" class="ccht-button" disabled={busy} onclick={() => void copyAndContinue()}>
119
+ Copy code and continue
120
+ </button>
121
+ <p>
122
+ <a
123
+ class="ccht-link"
124
+ href={validChallenge.verification_url}
125
+ target="_blank"
126
+ rel="noopener noreferrer"
127
+ >
128
+ Continue to {account.label}
129
+ </a>
130
+ </p>
131
+ {#if copyError}<p class="ccht-error" role="alert">{copyError}</p>{/if}
132
+ </div>
133
+ {:else if busy}
134
+ <p class="ccht-status" role="status">Starting account connection…</p>
135
+ {:else}
136
+ <p class="ccht-hint">Sign in with your {account.label} account.</p>
137
+ <button type="button" class="ccht-button" onclick={() => invoke(onStart)}>
138
+ Sign in to {account.label}
139
+ </button>
140
+ {/if}
141
+ {#if busy}
142
+ <button type="button" class="ccht-button ccht-cancel" onclick={() => invoke(onCancel)}>
143
+ Cancel
144
+ </button>
145
+ {/if}
146
+ {:else if isKeyAccount}
147
+ <form class="ccht-keyform" onsubmit={submitKey}>
148
+ <label class="ccht-label" for={keyInputId}>
149
+ {account.label} account key
150
+ <input
151
+ id={keyInputId}
152
+ class="ccht-input"
153
+ type="password"
154
+ autocomplete="off"
155
+ spellcheck="false"
156
+ maxlength="4096"
157
+ bind:value={key}
158
+ disabled={busy}
159
+ />
160
+ </label>
161
+ <button type="submit" class="ccht-button" disabled={!canSubmitKey}>
162
+ Connect {account.label}
163
+ </button>
164
+ </form>
165
+ {#if busy}
166
+ <button type="button" class="ccht-button ccht-cancel" onclick={() => invoke(onCancel)}>
167
+ Cancel
168
+ </button>
169
+ {/if}
170
+ {:else}
171
+ <p class="ccht-status" role="status">Not connected</p>
172
+ <p class="ccht-hint">Sign in with your {account.label} account.</p>
173
+ <button type="button" class="ccht-button" disabled={busy} onclick={() => invoke(onStart)}>
174
+ Sign in to {account.label}
175
+ </button>
176
+ {#if busy}
177
+ <button type="button" class="ccht-button ccht-cancel" onclick={() => invoke(onCancel)}>
178
+ Cancel
179
+ </button>
180
+ {/if}
181
+ {/if}
182
+ </section>
183
+
184
+ <style>
185
+ .ccht-account {
186
+ color: var(--ccht-fg, inherit);
187
+ }
188
+ .ccht-status,
189
+ .ccht-hint {
190
+ color: var(--ccht-muted, inherit);
191
+ }
192
+ .ccht-error {
193
+ color: var(--ccht-error, #b91c1c);
194
+ }
195
+ .ccht-code {
196
+ background-color: var(--ccht-code-bg, transparent);
197
+ }
198
+ .ccht-link {
199
+ color: var(--ccht-accent, inherit);
200
+ }
201
+ </style>
@@ -0,0 +1,172 @@
1
+ <!-- Product-neutral edge rail. The application owns all effects (dock state,
2
+ persistence, focus targets beyond this panel); this component only renders
3
+ the tab and panel chrome and forwards user intent through app-supplied
4
+ open/close callbacks. It never fetches, spawns, or stores anything. -->
5
+ <script lang="ts">
6
+ import type { Snippet } from 'svelte';
7
+
8
+ let {
9
+ side = 'left',
10
+ title,
11
+ open,
12
+ onClose,
13
+ onOpen,
14
+ tabLabel,
15
+ tabSummary = '',
16
+ closeLabel,
17
+ panelId,
18
+ children
19
+ }: {
20
+ side: 'left' | 'right';
21
+ title: string;
22
+ open: boolean;
23
+ onClose: () => void;
24
+ onOpen: () => void;
25
+ tabLabel: string;
26
+ tabSummary?: string;
27
+ closeLabel?: string;
28
+ panelId: string;
29
+ children: Snippet;
30
+ } = $props();
31
+
32
+ let panelEl: HTMLElement | undefined = $state(undefined);
33
+ let tabEl: HTMLButtonElement | undefined = $state(undefined);
34
+ let wasOpen = $state(false);
35
+ let prevFocus: HTMLElement | null = $state(null);
36
+ const dismissLabel = $derived(closeLabel ?? `Close ${title}`);
37
+
38
+ function handleTabClick(event: MouseEvent) {
39
+ prevFocus = event.currentTarget as HTMLElement;
40
+ onOpen();
41
+ }
42
+
43
+ $effect(() => {
44
+ if (open && !wasOpen) {
45
+ wasOpen = true;
46
+ prevFocus ??= document.activeElement as HTMLElement | null;
47
+ requestAnimationFrame(() => {
48
+ // First visible, enabled control wins; hidden or disabled nodes
49
+ // never take focus. Fixed panels have no offsetParent, so filter
50
+ // on client rects instead.
51
+ const target = [...(panelEl?.querySelectorAll<HTMLElement>(
52
+ 'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])'
53
+ ) ?? [])].find((node) => node.getClientRects().length > 0) ?? panelEl;
54
+ target?.focus();
55
+ });
56
+ } else if (!open && wasOpen) {
57
+ wasOpen = false;
58
+ const restore = prevFocus?.isConnected ? prevFocus : null;
59
+ prevFocus = null;
60
+ requestAnimationFrame(() => {
61
+ (restore ?? tabEl)?.focus?.();
62
+ });
63
+ }
64
+ });
65
+
66
+ $effect(() => {
67
+ if (panelEl) (panelEl as HTMLElement & { inert: boolean }).inert = !open;
68
+ });
69
+
70
+ function onKeydown(event: KeyboardEvent) {
71
+ if (event.key === 'Escape' && open) onClose();
72
+ }
73
+ </script>
74
+
75
+ <svelte:window onkeydown={onKeydown} />
76
+
77
+ {#if !open}
78
+ <button
79
+ bind:this={tabEl}
80
+ type="button"
81
+ class="ccht-dock-tab"
82
+ data-side={side}
83
+ aria-expanded="false"
84
+ aria-controls={panelId}
85
+ aria-label={tabSummary ? `Open ${title}: ${tabSummary}` : `Open ${title}`}
86
+ onclick={handleTabClick}
87
+ ><span class="ccht-dock-tab-text">{tabLabel} · {tabSummary || title}</span></button>
88
+ {/if}
89
+
90
+ <div
91
+ bind:this={panelEl}
92
+ id={panelId}
93
+ class="ccht-dock-panel"
94
+ data-side={side}
95
+ data-open={open ? 'true' : 'false'}
96
+ role="dialog"
97
+ aria-label={title}
98
+ aria-hidden={!open}
99
+ tabindex="-1"
100
+ >
101
+ <div class="ccht-dock-head">
102
+ <div class="ccht-dock-title"><h2>{title}</h2>{#if tabSummary}<p>{tabSummary}</p>{/if}</div>
103
+ <button type="button" class="ccht-dock-close" aria-label={dismissLabel} onclick={onClose}>Close</button>
104
+ </div>
105
+ <div class="ccht-dock-body">{@render children()}</div>
106
+ </div>
107
+
108
+ <style>
109
+ .ccht-dock-tab {
110
+ position: fixed; top: 50%; z-index: 80; transform: translateY(-50%);
111
+ max-height: min(60vh, 30rem); max-width: 2.4rem; padding: 0.7rem 0.4rem;
112
+ display: flex; align-items: center; justify-content: center;
113
+ border: 1px solid var(--ccht-border, #30405c);
114
+ color: var(--ccht-fg, #c2cede);
115
+ background: var(--ccht-tab-bg, #111c2df2);
116
+ font: 800 0.68rem ui-monospace, monospace; cursor: pointer;
117
+ writing-mode: vertical-rl; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
118
+ }
119
+ .ccht-dock-tab[data-side='left'] { left: 0; border-left: 0; border-radius: 0 0.5rem 0.5rem 0; }
120
+ .ccht-dock-tab[data-side='right'] { right: 0; border-right: 0; border-radius: 0.5rem 0 0 0.5rem; }
121
+ .ccht-dock-tab:hover {
122
+ border-color: var(--ccht-accent, #53708f);
123
+ color: var(--ccht-fg-bright, #e2eaf5);
124
+ background: var(--ccht-tab-bg-hover, #17243af2);
125
+ }
126
+ .ccht-dock-tab-text { overflow: hidden; text-overflow: ellipsis; }
127
+ .ccht-dock-panel {
128
+ position: fixed; top: 0; bottom: 0; z-index: 70;
129
+ width: min(30rem, 100vw); display: flex; flex-direction: column;
130
+ background: var(--ccht-panel-bg, #0d1625);
131
+ color: var(--ccht-fg, #d8e2f0); visibility: hidden;
132
+ transition: transform 0.2s ease, visibility 0s linear 0.2s;
133
+ }
134
+ .ccht-dock-panel[data-side='left'] {
135
+ left: 0; border-right: 1px solid var(--ccht-border, #223049); transform: translateX(-102%);
136
+ }
137
+ .ccht-dock-panel[data-side='right'] {
138
+ right: 0; border-left: 1px solid var(--ccht-border, #223049); transform: translateX(102%);
139
+ }
140
+ .ccht-dock-panel[data-open='true'] { transform: none; visibility: visible; transition: transform 0.2s ease; }
141
+ .ccht-dock-panel[data-open='false'] { visibility: hidden; }
142
+ .ccht-dock-head {
143
+ display: flex; align-items: center; justify-content: space-between; gap: 0.8rem;
144
+ padding: 1rem 1.1rem; border-bottom: 1px solid var(--ccht-border, #223049);
145
+ }
146
+ .ccht-dock-title { min-width: 0; }
147
+ .ccht-dock-title h2 { margin: 0; font-size: 1.02rem; overflow-wrap: anywhere; }
148
+ .ccht-dock-title p {
149
+ margin: 0.3rem 0 0; overflow-wrap: anywhere;
150
+ color: var(--ccht-muted, #8fa0b7); font: 750 0.68rem ui-monospace, monospace;
151
+ }
152
+ .ccht-dock-close {
153
+ flex: 0 0 auto; min-height: 2.5rem; padding: 0.55rem 0.85rem;
154
+ border: 1px solid var(--ccht-border, #30405c); border-radius: 0.5rem;
155
+ color: var(--ccht-fg, #c2cede);
156
+ background: var(--ccht-tab-bg, #111c2d);
157
+ font-size: 0.72rem; font-weight: 850; cursor: pointer;
158
+ }
159
+ .ccht-dock-close:hover {
160
+ border-color: var(--ccht-accent, #53708f);
161
+ background: var(--ccht-tab-bg-hover, #17243a);
162
+ }
163
+ .ccht-dock-body {
164
+ flex: 1; min-height: 0; overflow: auto; padding: 1rem 1.1rem;
165
+ display: grid; gap: 0.85rem; align-content: start;
166
+ }
167
+ @media (max-width: 560px) {
168
+ .ccht-dock-panel { width: 100vw; }
169
+ .ccht-dock-head, .ccht-dock-body { padding-left: 0.85rem; padding-right: 0.85rem; }
170
+ }
171
+ @media (prefers-reduced-motion: reduce) { .ccht-dock-panel { transition: none; } }
172
+ </style>