@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,264 @@
1
+ //! Environment allowlist profile for spawning agent processes.
2
+ //!
3
+ //! Child processes inherit only explicitly allowed variables; every other
4
+ //! value is blanked to an empty string so secrets from the parent process
5
+ //! cannot silently replace native agent login. Paths and locale names are
6
+ //! not secrets, while tokens and keys must never be forwarded.
7
+
8
+ use std::collections::BTreeMap;
9
+
10
+ /// Environment allowlist applied to agent child processes.
11
+ ///
12
+ /// [`EnvProfile::Strict`] forwards a minimal locale, home, and certificate
13
+ /// set. [`EnvProfile::Permissive`] is a documented superset that additionally
14
+ /// forwards common locale and certificate-bundle variables; both profiles
15
+ /// blank every other variable to an empty string.
16
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
17
+ pub enum EnvProfile {
18
+ /// Minimal allowlist for spawned agent processes.
19
+ Strict,
20
+ /// Strict set plus extra locale and certificate-bundle variables.
21
+ Permissive,
22
+ }
23
+
24
+ impl EnvProfile {
25
+ /// Minimal profile: `PATH`, `HOME`, `XDG_*`, `LANG`/`LC_*`, `TZ`,
26
+ /// `TERM`, `TMPDIR`, `SSL_CERT_*`, and `NODE_EXTRA_CA_CERTS`.
27
+ #[must_use]
28
+ pub fn strict() -> Self {
29
+ Self::Strict
30
+ }
31
+
32
+ /// Superset of [`EnvProfile::strict`] that additionally allows
33
+ /// `LANGUAGE`, `REQUESTS_CA_BUNDLE`, `CURL_CA_BUNDLE`, and `CA_BUNDLE`.
34
+ ///
35
+ /// These extras are `TMPDIR`-independent locale and certificate path
36
+ /// variables; no secret-bearing variable is added.
37
+ #[must_use]
38
+ pub fn permissive() -> Self {
39
+ Self::Permissive
40
+ }
41
+
42
+ /// Whether this profile forwards `key` with its value intact.
43
+ fn allows(&self, key: &str) -> bool {
44
+ if is_strict_allowed(key) {
45
+ return true;
46
+ }
47
+ match self {
48
+ Self::Strict => false,
49
+ Self::Permissive => is_permissive_extra(key),
50
+ }
51
+ }
52
+
53
+ /// Copy `env`, keeping allowed values and blanking the rest to empty.
54
+ ///
55
+ /// All input keys are preserved; disallowed values become `""` so the
56
+ /// child cannot inherit ambient secrets through the environment.
57
+ #[must_use]
58
+ pub fn apply(&self, env: &BTreeMap<String, String>) -> BTreeMap<String, String> {
59
+ env.iter()
60
+ .map(|(key, value)| {
61
+ if self.allows(key) {
62
+ (key.clone(), value.clone())
63
+ } else {
64
+ (key.clone(), String::new())
65
+ }
66
+ })
67
+ .collect()
68
+ }
69
+
70
+ /// Filter [`crate::native::AgentCommand`] environment in place.
71
+ ///
72
+ /// Allowed entries keep their values; every other entry is blanked to
73
+ /// an empty string. The program and arguments are left unchanged.
74
+ pub fn apply_to_command(&self, cmd: &mut crate::native::AgentCommand) {
75
+ cmd.env = self.apply(&cmd.env);
76
+ }
77
+ }
78
+
79
+ /// Strict allowlist: exact names plus `XDG_`, `LC_`, and `SSL_CERT_` prefixes.
80
+ fn is_strict_allowed(key: &str) -> bool {
81
+ match key {
82
+ "PATH" | "HOME" | "LANG" | "TZ" | "TERM" | "TMPDIR" | "NODE_EXTRA_CA_CERTS" => true,
83
+ _ => key.starts_with("XDG_") || key.starts_with("LC_") || key.starts_with("SSL_CERT_"),
84
+ }
85
+ }
86
+
87
+ /// Permissive extras beyond the strict set; still locale/cert paths only.
88
+ fn is_permissive_extra(key: &str) -> bool {
89
+ matches!(
90
+ key,
91
+ "LANGUAGE" | "REQUESTS_CA_BUNDLE" | "CURL_CA_BUNDLE" | "CA_BUNDLE"
92
+ )
93
+ }
94
+
95
+ #[cfg(test)]
96
+ mod tests {
97
+ use super::*;
98
+ use crate::native::AgentCommand;
99
+
100
+ fn env(pairs: &[(&str, &str)]) -> BTreeMap<String, String> {
101
+ pairs
102
+ .iter()
103
+ .map(|(key, value)| ((*key).to_owned(), (*value).to_owned()))
104
+ .collect()
105
+ }
106
+
107
+ #[test]
108
+ fn strict_keeps_allowlist_and_blanks_secrets() {
109
+ let profile = EnvProfile::strict();
110
+ let input = env(&[
111
+ ("PATH", "/usr/bin"),
112
+ ("HOME", "/home/app"),
113
+ ("XDG_CONFIG_HOME", "/home/app/.config"),
114
+ ("LANG", "en_US.UTF-8"),
115
+ ("LC_MESSAGES", "en_US.UTF-8"),
116
+ ("TZ", "UTC"),
117
+ ("TERM", "xterm"),
118
+ ("TMPDIR", "/tmp"),
119
+ ("SSL_CERT_FILE", "/etc/ssl/certs.pem"),
120
+ ("NODE_EXTRA_CA_CERTS", "/etc/ssl/certs.pem"),
121
+ ("OPENAI_API_KEY", "super-secret"),
122
+ ("AWS_SECRET_ACCESS_KEY", "super-secret"),
123
+ ("GITHUB_TOKEN", "super-secret"),
124
+ ]);
125
+ let filtered = profile.apply(&input);
126
+ for (key, value) in &input {
127
+ if is_strict_allowed(key) {
128
+ assert_eq!(filtered.get(key).map(String::as_str), Some(value.as_str()));
129
+ } else {
130
+ assert_eq!(
131
+ filtered.get(key).map(String::as_str),
132
+ Some(""),
133
+ "expected blanking for {key}"
134
+ );
135
+ }
136
+ }
137
+ assert_eq!(
138
+ filtered.get("OPENAI_API_KEY").map(String::as_str),
139
+ Some(""),
140
+ "secret variables must be blanked"
141
+ );
142
+ }
143
+
144
+ #[test]
145
+ fn permissive_is_a_documented_superset_of_strict() {
146
+ let strict = EnvProfile::strict();
147
+ let permissive = EnvProfile::permissive();
148
+ let strict_keys = [
149
+ "PATH",
150
+ "HOME",
151
+ "XDG_DATA_HOME",
152
+ "LANG",
153
+ "LC_ALL",
154
+ "TZ",
155
+ "TERM",
156
+ "TMPDIR",
157
+ "SSL_CERT_DIR",
158
+ "NODE_EXTRA_CA_CERTS",
159
+ ];
160
+ let extra_keys = [
161
+ "LANGUAGE",
162
+ "REQUESTS_CA_BUNDLE",
163
+ "CURL_CA_BUNDLE",
164
+ "CA_BUNDLE",
165
+ ];
166
+ for key in strict_keys {
167
+ let input = env(&[(key, "value")]);
168
+ assert_eq!(
169
+ strict.apply(&input).get(key).map(String::as_str),
170
+ Some("value")
171
+ );
172
+ assert_eq!(
173
+ permissive.apply(&input).get(key).map(String::as_str),
174
+ Some("value"),
175
+ "permissive must keep every strict variable"
176
+ );
177
+ }
178
+ for key in extra_keys {
179
+ let input = env(&[(key, "value")]);
180
+ assert_eq!(
181
+ strict.apply(&input).get(key).map(String::as_str),
182
+ Some(""),
183
+ "extra variable must not be in the strict set"
184
+ );
185
+ assert_eq!(
186
+ permissive.apply(&input).get(key).map(String::as_str),
187
+ Some("value")
188
+ );
189
+ }
190
+ }
191
+
192
+ #[test]
193
+ fn permissive_still_blanks_secrets() {
194
+ let filtered = EnvProfile::permissive().apply(&env(&[
195
+ ("OPENAI_API_KEY", "super-secret"),
196
+ ("AWS_SESSION_TOKEN", "super-secret"),
197
+ ("ANTHROPIC_AUTH_TOKEN", "super-secret"),
198
+ ("LANGUAGE", "en"),
199
+ ]));
200
+ assert_eq!(filtered.get("OPENAI_API_KEY").map(String::as_str), Some(""));
201
+ assert_eq!(
202
+ filtered.get("AWS_SESSION_TOKEN").map(String::as_str),
203
+ Some("")
204
+ );
205
+ assert_eq!(
206
+ filtered.get("ANTHROPIC_AUTH_TOKEN").map(String::as_str),
207
+ Some("")
208
+ );
209
+ assert_eq!(filtered.get("LANGUAGE").map(String::as_str), Some("en"));
210
+ }
211
+
212
+ #[test]
213
+ fn apply_to_command_filters_env_without_touching_program() {
214
+ let mut command = AgentCommand::new("agent");
215
+ command.env.insert("PATH".into(), "/usr/bin".into());
216
+ command
217
+ .env
218
+ .insert("OPENAI_API_KEY".into(), "super-secret".into());
219
+ EnvProfile::strict().apply_to_command(&mut command);
220
+ assert_eq!(
221
+ command.program.to_str(),
222
+ Some("agent"),
223
+ "program must be unchanged"
224
+ );
225
+ assert_eq!(
226
+ command.env.get("PATH").map(String::as_str),
227
+ Some("/usr/bin")
228
+ );
229
+ assert_eq!(
230
+ command.env.get("OPENAI_API_KEY").map(String::as_str),
231
+ Some("")
232
+ );
233
+ }
234
+
235
+ #[test]
236
+ fn agent_command_debug_shows_keys_only() {
237
+ let mut command = AgentCommand::new("agent");
238
+ command
239
+ .env
240
+ .insert("OPENAI_API_KEY".into(), "super-secret-value".into());
241
+ EnvProfile::strict().apply_to_command(&mut command);
242
+ let rendered = format!("{command:?}");
243
+ assert!(
244
+ rendered.contains("OPENAI_API_KEY"),
245
+ "debug output should keep environment keys"
246
+ );
247
+ assert!(
248
+ !rendered.contains("super-secret-value"),
249
+ "debug output must never leak environment values"
250
+ );
251
+ }
252
+
253
+ #[test]
254
+ fn empty_environment_stays_empty_and_names_are_case_sensitive() {
255
+ let empty: BTreeMap<String, String> = BTreeMap::new();
256
+ assert!(EnvProfile::strict().apply(&empty).is_empty());
257
+ assert!(EnvProfile::permissive().apply(&empty).is_empty());
258
+ // Allowlist names are exact; lowercase variants must be blanked.
259
+ let input = env(&[("path", "/usr/bin"), ("Path", "/usr/bin")]);
260
+ let filtered = EnvProfile::strict().apply(&input);
261
+ assert_eq!(filtered.get("path").map(String::as_str), Some(""));
262
+ assert_eq!(filtered.get("Path").map(String::as_str), Some(""));
263
+ }
264
+ }
@@ -0,0 +1,191 @@
1
+ """Offline ACP peer for exercising the public native client through real stdio."""
2
+ import json
3
+ import os
4
+ import pathlib
5
+ import subprocess
6
+ import sys
7
+ import time
8
+
9
+ mode = sys.argv[1]
10
+ sessions = 0
11
+ configurations = {}
12
+ pending = {}
13
+ permissions = {}
14
+ permission_id = 100
15
+ if len(sys.argv) > 2 and sys.argv[2].endswith(".json"):
16
+ child = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(60)"])
17
+ pathlib.Path(sys.argv[2]).write_text(json.dumps({"agent": os.getpid(), "descendant": child.pid}))
18
+
19
+
20
+ def send(value):
21
+ print(json.dumps({"jsonrpc": "2.0", **value}), flush=True)
22
+
23
+
24
+ def response(request_id, result):
25
+ send({"id": request_id, "result": result})
26
+
27
+
28
+ def update(session, text):
29
+ send({"method": "session/update", "params": {"sessionId": session,
30
+ "update": {"sessionUpdate": "agent_message_chunk",
31
+ "content": {"type": "text", "text": text}}}})
32
+
33
+
34
+ # Fake OpenCode control server for driver tests. The Rust driver spawns:
35
+ # python3 -u -c <this file> <opencode_ok|opencode_fail|opencode_never>
36
+ # serve --hostname 127.0.0.1 --port <port>
37
+ # Only loopback is used; no real network leaves the host.
38
+ if "serve" in sys.argv:
39
+ if mode == "opencode_never":
40
+ time.sleep(60)
41
+ sys.exit(0)
42
+ port = 0
43
+ if "--port" in sys.argv:
44
+ port = int(sys.argv[sys.argv.index("--port") + 1])
45
+ from http.server import BaseHTTPRequestHandler, HTTPServer
46
+
47
+ class DriverHandler(BaseHTTPRequestHandler):
48
+ def log_message(self, format, *args):
49
+ pass
50
+
51
+ def _reply(self, code, body):
52
+ data = body if isinstance(body, bytes) else body.encode()
53
+ self.send_response(code)
54
+ self.send_header("Content-Type", "application/json")
55
+ self.send_header("Content-Length", str(len(data)))
56
+ self.send_header("Connection", "close")
57
+ self.end_headers()
58
+ self.wfile.write(data)
59
+
60
+ def do_GET(self):
61
+ path = self.path.split("?")[0]
62
+ if path == "/global/health":
63
+ self._reply(200, b"{}")
64
+ elif path == "/provider":
65
+ if mode == "opencode_fail":
66
+ self._reply(200, json.dumps({"connected": []}).encode())
67
+ else:
68
+ self._reply(200, json.dumps({"connected": ["opencode-go"]}).encode())
69
+ else:
70
+ self._reply(404, b"{}")
71
+
72
+ def do_PUT(self):
73
+ path = self.path.split("?")[0]
74
+ if path == "/auth/opencode-go":
75
+ length = int(self.headers.get("Content-Length", "0") or "0")
76
+ if length > 0:
77
+ self.rfile.read(min(length, 1_048_576))
78
+ if mode == "opencode_fail":
79
+ self._reply(500, b"{}")
80
+ else:
81
+ self._reply(200, b"{}")
82
+ else:
83
+ self._reply(404, b"{}")
84
+
85
+ HTTPServer(("127.0.0.1", port), DriverHandler).serve_forever()
86
+ sys.exit(0)
87
+
88
+
89
+ for line in sys.stdin:
90
+ message = json.loads(line)
91
+ method = message.get("method")
92
+ params = message.get("params", {})
93
+ request_id = message.get("id")
94
+ if method == "initialize":
95
+ if mode == "slow_init":
96
+ time.sleep(60)
97
+ response(request_id, {"protocolVersion": 1,
98
+ "agentCapabilities": {"loadSession": True,
99
+ "sessionCapabilities": {"resume": {}, "close": {}}},
100
+ "agentInfo": {"name": "offline-fixture", "version": "1"}})
101
+ elif method in ("session/new", "session/load", "session/resume"):
102
+ if mode == "auth_required":
103
+ send({"id": request_id, "error": {"code": -32000,
104
+ "message": "SECRET-SHOULD-NOT-ESCAPE", "data": {"token": "SECRET"}}})
105
+ continue
106
+ sessions += 1
107
+ session = params.get("sessionId", "fixture-" + str(sessions))
108
+ if method == "session/load":
109
+ update(session, "restored history")
110
+ configurations[session] = [{
111
+ "id": "model", "name": "Model", "category": "model", "type": "select",
112
+ "currentValue": "test-model", "options": [{"value": "test-model", "name": "Test"},
113
+ {"value": "second-model", "name": "Second"}]},
114
+ {"id": "thinking", "name": "Thinking", "type": "boolean", "currentValue": False}]
115
+ response(request_id, {"sessionId": session, "configOptions": configurations[session]})
116
+ elif method == "session/set_config_option":
117
+ configuration = configurations[params["sessionId"]]
118
+ for option in configuration:
119
+ if option["id"] == params["configId"]:
120
+ option["currentValue"] = params["value"]
121
+ if params["configId"] == "model":
122
+ configuration[1]["currentValue"] = params["value"] == "second-model"
123
+ response(request_id, {"configOptions": configuration})
124
+ elif method == "session/prompt":
125
+ session = params["sessionId"]
126
+ pending[session] = request_id
127
+ if mode == "exit":
128
+ sys.exit(2)
129
+ if mode in ("ask", "deny", "unsupported_host_request"):
130
+ permission_id += 1
131
+ permissions[permission_id] = session
132
+ if mode == "unsupported_host_request":
133
+ send({"id": permission_id, "method": "fs/read_text_file",
134
+ "params": {"sessionId": session, "path": "/never-read-this"}})
135
+ else:
136
+ send({"id": permission_id, "method": "session/request_permission", "params": {
137
+ "sessionId": session, "toolCall": {"toolCallId": "tool-1", "title": "Test action"},
138
+ "options": [{"optionId": "allow", "name": "Allow once", "kind": "allow_once"},
139
+ {"optionId": "reject", "name": "Reject once", "kind": "reject_once"}]}})
140
+ elif mode in ("hang", "ignore_cancel"):
141
+ update(session, "waiting")
142
+ else:
143
+ if mode == "startup_cwd":
144
+ update(session, os.getcwd())
145
+ elif mode == "burst":
146
+ for _ in range(1000):
147
+ update(session, "x")
148
+ else:
149
+ update(session, "hello ")
150
+ update(session, "world")
151
+ response(pending.pop(session), {"stopReason": "end_turn"})
152
+ elif method == "session/cancel":
153
+ session = params["sessionId"]
154
+ if mode != "ignore_cancel" and session in pending:
155
+ response(pending.pop(session), {"stopReason": "cancelled"})
156
+ elif method == "session/close":
157
+ response(request_id, {})
158
+ elif method == "account/login/start":
159
+ if mode == "codex_bad_url":
160
+ response(request_id, {"loginId": "login-1",
161
+ "verificationUrl": "http://evil.example.com/x",
162
+ "userCode": "ABCD-1234"})
163
+ elif mode == "codex_bad_code":
164
+ response(request_id, {"loginId": "login-1",
165
+ "verificationUrl": "https://auth.openai.com/codex/device",
166
+ "userCode": "!!!"})
167
+ else:
168
+ response(request_id, {"loginId": "login-1",
169
+ "verificationUrl": "https://auth.openai.com/codex/device",
170
+ "userCode": "ABCD-1234"})
171
+ if mode == "codex_ok":
172
+ send({"method": "account/login/completed",
173
+ "params": {"loginId": "login-1", "success": True}})
174
+ elif mode == "codex_declined":
175
+ send({"method": "account/login/completed",
176
+ "params": {"loginId": "login-1", "success": False}})
177
+ elif method == "account/read":
178
+ response(request_id, {"account": {"type": "chatgpt",
179
+ "email": "user@example.com"}})
180
+ elif method is None and request_id in permissions:
181
+ session = permissions.pop(request_id)
182
+ if mode == "unsupported_host_request":
183
+ assert message["error"]["code"] == -32601
184
+ text = "unsupported"
185
+ else:
186
+ outcome = message["result"]["outcome"]
187
+ text = outcome.get("optionId", outcome["outcome"])
188
+ update(session, text)
189
+ response(pending.pop(session), {"stopReason": "end_turn"})
190
+ elif request_id is not None:
191
+ send({"id": request_id, "error": {"code": -32601, "message": "Unsupported fixture request"}})