rtrt-agent 0.1.7 → 0.2.1

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 (492) hide show
  1. package/README.ko.md +203 -15
  2. package/README.md +211 -15
  3. package/THIRD_PARTY_NOTICES/INDEX.md +120 -18
  4. package/THIRD_PARTY_NOTICES/INVENTORY.json +8151 -0
  5. package/THIRD_PARTY_NOTICES/SUPPLEMENTS.json +148 -0
  6. package/THIRD_PARTY_NOTICES/adler2@2.0.1/LICENSE-0BSD +12 -0
  7. package/THIRD_PARTY_NOTICES/adler2@2.0.1/LICENSE-APACHE +201 -0
  8. package/THIRD_PARTY_NOTICES/adler2@2.0.1/LICENSE-MIT +23 -0
  9. package/THIRD_PARTY_NOTICES/ahash@0.8.12/LICENSE-APACHE +201 -0
  10. package/THIRD_PARTY_NOTICES/ahash@0.8.12/LICENSE-MIT +25 -0
  11. package/THIRD_PARTY_NOTICES/aho-corasick@1.1.4/COPYING +3 -0
  12. package/THIRD_PARTY_NOTICES/aho-corasick@1.1.4/LICENSE-MIT +21 -0
  13. package/THIRD_PARTY_NOTICES/allocator-api2@0.2.21/LICENSE-APACHE +176 -0
  14. package/THIRD_PARTY_NOTICES/allocator-api2@0.2.21/LICENSE-MIT +23 -0
  15. package/THIRD_PARTY_NOTICES/anstream@1.0.0/LICENSE-APACHE +202 -0
  16. package/THIRD_PARTY_NOTICES/anstream@1.0.0/LICENSE-MIT +19 -0
  17. package/THIRD_PARTY_NOTICES/anstyle-parse@1.0.0/LICENSE-APACHE +202 -0
  18. package/THIRD_PARTY_NOTICES/anstyle-parse@1.0.0/LICENSE-MIT +19 -0
  19. package/THIRD_PARTY_NOTICES/anstyle-query@1.1.5/LICENSE-APACHE +202 -0
  20. package/THIRD_PARTY_NOTICES/anstyle-query@1.1.5/LICENSE-MIT +19 -0
  21. package/THIRD_PARTY_NOTICES/anstyle-wincon@3.0.11/LICENSE-APACHE +202 -0
  22. package/THIRD_PARTY_NOTICES/anstyle-wincon@3.0.11/LICENSE-MIT +19 -0
  23. package/THIRD_PARTY_NOTICES/anstyle@1.0.14/LICENSE-APACHE +202 -0
  24. package/THIRD_PARTY_NOTICES/anstyle@1.0.14/LICENSE-MIT +19 -0
  25. package/THIRD_PARTY_NOTICES/anyhow@1.0.103/LICENSE-APACHE +176 -0
  26. package/THIRD_PARTY_NOTICES/anyhow@1.0.103/LICENSE-MIT +23 -0
  27. package/THIRD_PARTY_NOTICES/async-compression@0.4.42/LICENSE-APACHE +201 -0
  28. package/THIRD_PARTY_NOTICES/async-compression@0.4.42/LICENSE-MIT +21 -0
  29. package/THIRD_PARTY_NOTICES/async-trait@0.1.92/LICENSE-APACHE +176 -0
  30. package/THIRD_PARTY_NOTICES/async-trait@0.1.92/LICENSE-MIT +23 -0
  31. package/THIRD_PARTY_NOTICES/atomic-waker@1.1.2/LICENSE-APACHE +201 -0
  32. package/THIRD_PARTY_NOTICES/atomic-waker@1.1.2/LICENSE-MIT +23 -0
  33. package/THIRD_PARTY_NOTICES/atomic-waker@1.1.2/LICENSE-THIRD-PARTY +45 -0
  34. package/THIRD_PARTY_NOTICES/autocfg@1.5.0/LICENSE-APACHE +201 -0
  35. package/THIRD_PARTY_NOTICES/autocfg@1.5.0/LICENSE-MIT +25 -0
  36. package/THIRD_PARTY_NOTICES/axum-core@0.5.6/LICENSE +27 -0
  37. package/THIRD_PARTY_NOTICES/axum-macros@0.5.1/LICENSE +7 -0
  38. package/THIRD_PARTY_NOTICES/axum@0.8.9/LICENSE +25 -0
  39. package/THIRD_PARTY_NOTICES/base64@0.22.1/LICENSE-APACHE +201 -0
  40. package/THIRD_PARTY_NOTICES/base64@0.22.1/LICENSE-MIT +21 -0
  41. package/THIRD_PARTY_NOTICES/bitflags@2.11.1/LICENSE-APACHE +201 -0
  42. package/THIRD_PARTY_NOTICES/bitflags@2.11.1/LICENSE-MIT +25 -0
  43. package/THIRD_PARTY_NOTICES/block-buffer@0.10.4/LICENSE-APACHE +201 -0
  44. package/THIRD_PARTY_NOTICES/block-buffer@0.10.4/LICENSE-MIT +25 -0
  45. package/THIRD_PARTY_NOTICES/bytes@1.11.1/LICENSE +25 -0
  46. package/THIRD_PARTY_NOTICES/cc@1.2.62/LICENSE-APACHE +201 -0
  47. package/THIRD_PARTY_NOTICES/cc@1.2.62/LICENSE-MIT +25 -0
  48. package/THIRD_PARTY_NOTICES/cfg-if@1.0.4/LICENSE-APACHE +201 -0
  49. package/THIRD_PARTY_NOTICES/cfg-if@1.0.4/LICENSE-MIT +25 -0
  50. package/THIRD_PARTY_NOTICES/chacha20@0.10.2/LICENSE-APACHE +201 -0
  51. package/THIRD_PARTY_NOTICES/chacha20@0.10.2/LICENSE-MIT +25 -0
  52. package/THIRD_PARTY_NOTICES/chrono@0.4.44/LICENSE.txt +240 -0
  53. package/THIRD_PARTY_NOTICES/clap@4.6.1/LICENSE-APACHE +202 -0
  54. package/THIRD_PARTY_NOTICES/clap@4.6.1/LICENSE-MIT +19 -0
  55. package/THIRD_PARTY_NOTICES/clap_builder@4.6.0/LICENSE-APACHE +202 -0
  56. package/THIRD_PARTY_NOTICES/clap_builder@4.6.0/LICENSE-MIT +19 -0
  57. package/THIRD_PARTY_NOTICES/clap_derive@4.6.1/LICENSE-APACHE +202 -0
  58. package/THIRD_PARTY_NOTICES/clap_derive@4.6.1/LICENSE-MIT +19 -0
  59. package/THIRD_PARTY_NOTICES/clap_lex@1.1.0/LICENSE-APACHE +202 -0
  60. package/THIRD_PARTY_NOTICES/clap_lex@1.1.0/LICENSE-MIT +19 -0
  61. package/THIRD_PARTY_NOTICES/colorchoice@1.0.5/LICENSE-APACHE +202 -0
  62. package/THIRD_PARTY_NOTICES/colorchoice@1.0.5/LICENSE-MIT +19 -0
  63. package/THIRD_PARTY_NOTICES/compression-codecs@0.4.38/LICENSE-APACHE +201 -0
  64. package/THIRD_PARTY_NOTICES/compression-codecs@0.4.38/LICENSE-MIT +21 -0
  65. package/THIRD_PARTY_NOTICES/compression-core@0.4.32/LICENSE-APACHE +201 -0
  66. package/THIRD_PARTY_NOTICES/compression-core@0.4.32/LICENSE-MIT +21 -0
  67. package/THIRD_PARTY_NOTICES/cpufeatures@0.2.17/LICENSE-APACHE +201 -0
  68. package/THIRD_PARTY_NOTICES/cpufeatures@0.2.17/LICENSE-MIT +25 -0
  69. package/THIRD_PARTY_NOTICES/cpufeatures@0.3.0/LICENSE-APACHE +201 -0
  70. package/THIRD_PARTY_NOTICES/cpufeatures@0.3.0/LICENSE-MIT +25 -0
  71. package/THIRD_PARTY_NOTICES/crc32fast@1.5.0/LICENSE-APACHE +202 -0
  72. package/THIRD_PARTY_NOTICES/crc32fast@1.5.0/LICENSE-MIT +21 -0
  73. package/THIRD_PARTY_NOTICES/crossbeam-deque@0.8.6/LICENSE-APACHE +201 -0
  74. package/THIRD_PARTY_NOTICES/crossbeam-deque@0.8.6/LICENSE-MIT +27 -0
  75. package/THIRD_PARTY_NOTICES/crossbeam-epoch@0.9.20/LICENSE-APACHE +201 -0
  76. package/THIRD_PARTY_NOTICES/crossbeam-epoch@0.9.20/LICENSE-MIT +27 -0
  77. package/THIRD_PARTY_NOTICES/crossbeam-utils@0.8.21/LICENSE-APACHE +201 -0
  78. package/THIRD_PARTY_NOTICES/crossbeam-utils@0.8.21/LICENSE-MIT +27 -0
  79. package/THIRD_PARTY_NOTICES/crypto-common@0.1.7/LICENSE-APACHE +201 -0
  80. package/THIRD_PARTY_NOTICES/crypto-common@0.1.7/LICENSE-MIT +25 -0
  81. package/THIRD_PARTY_NOTICES/darling@0.20.11/LICENSE +21 -0
  82. package/THIRD_PARTY_NOTICES/darling@0.23.0/LICENSE +21 -0
  83. package/THIRD_PARTY_NOTICES/darling_core@0.20.11/LICENSE +21 -0
  84. package/THIRD_PARTY_NOTICES/darling_core@0.23.0/LICENSE +21 -0
  85. package/THIRD_PARTY_NOTICES/darling_macro@0.20.11/LICENSE +21 -0
  86. package/THIRD_PARTY_NOTICES/darling_macro@0.23.0/LICENSE +21 -0
  87. package/THIRD_PARTY_NOTICES/derive_builder@0.20.2/LICENSE-APACHE +202 -0
  88. package/THIRD_PARTY_NOTICES/derive_builder@0.20.2/LICENSE-MIT +21 -0
  89. package/THIRD_PARTY_NOTICES/derive_builder_core@0.20.2/LICENSE-APACHE +202 -0
  90. package/THIRD_PARTY_NOTICES/derive_builder_core@0.20.2/LICENSE-MIT +21 -0
  91. package/THIRD_PARTY_NOTICES/derive_builder_macro@0.20.2/LICENSE-APACHE +202 -0
  92. package/THIRD_PARTY_NOTICES/derive_builder_macro@0.20.2/LICENSE-MIT +21 -0
  93. package/THIRD_PARTY_NOTICES/digest@0.10.7/LICENSE-APACHE +201 -0
  94. package/THIRD_PARTY_NOTICES/digest@0.10.7/LICENSE-MIT +25 -0
  95. package/THIRD_PARTY_NOTICES/dirs-sys@0.4.1/LICENSE-APACHE +174 -0
  96. package/THIRD_PARTY_NOTICES/dirs-sys@0.4.1/LICENSE-MIT +19 -0
  97. package/THIRD_PARTY_NOTICES/dirs@5.0.1/LICENSE-APACHE +174 -0
  98. package/THIRD_PARTY_NOTICES/dirs@5.0.1/LICENSE-MIT +19 -0
  99. package/THIRD_PARTY_NOTICES/displaydoc@0.2.5/LICENSE-APACHE +201 -0
  100. package/THIRD_PARTY_NOTICES/displaydoc@0.2.5/LICENSE-MIT +23 -0
  101. package/THIRD_PARTY_NOTICES/dyn-clone@1.0.20/LICENSE-APACHE +176 -0
  102. package/THIRD_PARTY_NOTICES/dyn-clone@1.0.20/LICENSE-MIT +23 -0
  103. package/THIRD_PARTY_NOTICES/either@1.16.0/LICENSE-APACHE +201 -0
  104. package/THIRD_PARTY_NOTICES/either@1.16.0/LICENSE-MIT +25 -0
  105. package/THIRD_PARTY_NOTICES/equivalent@1.0.2/LICENSE-APACHE +201 -0
  106. package/THIRD_PARTY_NOTICES/equivalent@1.0.2/LICENSE-MIT +25 -0
  107. package/THIRD_PARTY_NOTICES/errno@0.3.14/LICENSE-APACHE +201 -0
  108. package/THIRD_PARTY_NOTICES/errno@0.3.14/LICENSE-MIT +25 -0
  109. package/THIRD_PARTY_NOTICES/eventsource-stream@0.2.3/Cargo.toml +74 -0
  110. package/THIRD_PARTY_NOTICES/eventsource-stream@0.2.3/DECLARED-APACHE-2.0.txt +202 -0
  111. package/THIRD_PARTY_NOTICES/fallible-iterator@0.3.0/LICENSE-APACHE +202 -0
  112. package/THIRD_PARTY_NOTICES/fallible-iterator@0.3.0/LICENSE-MIT +19 -0
  113. package/THIRD_PARTY_NOTICES/fallible-streaming-iterator@0.1.9/LICENSE-APACHE +202 -0
  114. package/THIRD_PARTY_NOTICES/fallible-streaming-iterator@0.1.9/LICENSE-MIT +19 -0
  115. package/THIRD_PARTY_NOTICES/fastrand@2.4.1/LICENSE-APACHE +201 -0
  116. package/THIRD_PARTY_NOTICES/fastrand@2.4.1/LICENSE-MIT +23 -0
  117. package/THIRD_PARTY_NOTICES/find-msvc-tools@0.1.9/LICENSE-APACHE +201 -0
  118. package/THIRD_PARTY_NOTICES/find-msvc-tools@0.1.9/LICENSE-MIT +25 -0
  119. package/THIRD_PARTY_NOTICES/flate2@1.1.9/LICENSE-APACHE +201 -0
  120. package/THIRD_PARTY_NOTICES/flate2@1.1.9/LICENSE-MIT +25 -0
  121. package/THIRD_PARTY_NOTICES/fnv@1.0.7/LICENSE-APACHE +201 -0
  122. package/THIRD_PARTY_NOTICES/fnv@1.0.7/LICENSE-MIT +25 -0
  123. package/THIRD_PARTY_NOTICES/form_urlencoded@1.2.2/LICENSE-APACHE +201 -0
  124. package/THIRD_PARTY_NOTICES/form_urlencoded@1.2.2/LICENSE-MIT +25 -0
  125. package/THIRD_PARTY_NOTICES/fs2@0.4.3/LICENSE-APACHE +201 -0
  126. package/THIRD_PARTY_NOTICES/fs2@0.4.3/LICENSE-MIT +25 -0
  127. package/THIRD_PARTY_NOTICES/futures-channel@0.3.32/LICENSE-APACHE +202 -0
  128. package/THIRD_PARTY_NOTICES/futures-channel@0.3.32/LICENSE-MIT +26 -0
  129. package/THIRD_PARTY_NOTICES/futures-core@0.3.32/LICENSE-APACHE +202 -0
  130. package/THIRD_PARTY_NOTICES/futures-core@0.3.32/LICENSE-MIT +26 -0
  131. package/THIRD_PARTY_NOTICES/futures-executor@0.3.32/LICENSE-APACHE +202 -0
  132. package/THIRD_PARTY_NOTICES/futures-executor@0.3.32/LICENSE-MIT +26 -0
  133. package/THIRD_PARTY_NOTICES/futures-io@0.3.32/LICENSE-APACHE +202 -0
  134. package/THIRD_PARTY_NOTICES/futures-io@0.3.32/LICENSE-MIT +26 -0
  135. package/THIRD_PARTY_NOTICES/futures-macro@0.3.32/LICENSE-APACHE +202 -0
  136. package/THIRD_PARTY_NOTICES/futures-macro@0.3.32/LICENSE-MIT +26 -0
  137. package/THIRD_PARTY_NOTICES/futures-sink@0.3.32/LICENSE-APACHE +202 -0
  138. package/THIRD_PARTY_NOTICES/futures-sink@0.3.32/LICENSE-MIT +26 -0
  139. package/THIRD_PARTY_NOTICES/futures-task@0.3.32/LICENSE-APACHE +202 -0
  140. package/THIRD_PARTY_NOTICES/futures-task@0.3.32/LICENSE-MIT +26 -0
  141. package/THIRD_PARTY_NOTICES/futures-util@0.3.32/LICENSE-APACHE +202 -0
  142. package/THIRD_PARTY_NOTICES/futures-util@0.3.32/LICENSE-MIT +26 -0
  143. package/THIRD_PARTY_NOTICES/futures@0.3.32/LICENSE-APACHE +202 -0
  144. package/THIRD_PARTY_NOTICES/futures@0.3.32/LICENSE-MIT +26 -0
  145. package/THIRD_PARTY_NOTICES/generic-array@0.14.7/LICENSE +21 -0
  146. package/THIRD_PARTY_NOTICES/getrandom@0.2.17/LICENSE-APACHE +201 -0
  147. package/THIRD_PARTY_NOTICES/getrandom@0.2.17/LICENSE-MIT +26 -0
  148. package/THIRD_PARTY_NOTICES/getrandom@0.3.4/LICENSE-APACHE +201 -0
  149. package/THIRD_PARTY_NOTICES/getrandom@0.3.4/LICENSE-MIT +26 -0
  150. package/THIRD_PARTY_NOTICES/getrandom@0.4.2/LICENSE-APACHE +201 -0
  151. package/THIRD_PARTY_NOTICES/getrandom@0.4.2/LICENSE-MIT +26 -0
  152. package/THIRD_PARTY_NOTICES/handlebars@6.4.1/LICENSE +22 -0
  153. package/THIRD_PARTY_NOTICES/handlebars@6.4.1/wasm/LICENSE +22 -0
  154. package/THIRD_PARTY_NOTICES/hashbrown@0.14.5/LICENSE-APACHE +201 -0
  155. package/THIRD_PARTY_NOTICES/hashbrown@0.14.5/LICENSE-MIT +25 -0
  156. package/THIRD_PARTY_NOTICES/hashbrown@0.17.1/LICENSE-APACHE +201 -0
  157. package/THIRD_PARTY_NOTICES/hashbrown@0.17.1/LICENSE-MIT +25 -0
  158. package/THIRD_PARTY_NOTICES/hashlink@0.9.1/LICENSE-APACHE +201 -0
  159. package/THIRD_PARTY_NOTICES/hashlink@0.9.1/LICENSE-MIT +26 -0
  160. package/THIRD_PARTY_NOTICES/heck@0.5.0/LICENSE-APACHE +201 -0
  161. package/THIRD_PARTY_NOTICES/heck@0.5.0/LICENSE-MIT +25 -0
  162. package/THIRD_PARTY_NOTICES/hmac@0.12.1/LICENSE-APACHE +201 -0
  163. package/THIRD_PARTY_NOTICES/hmac@0.12.1/LICENSE-MIT +25 -0
  164. package/THIRD_PARTY_NOTICES/http-body-util@0.1.3/LICENSE +25 -0
  165. package/THIRD_PARTY_NOTICES/http-body@1.0.1/LICENSE +25 -0
  166. package/THIRD_PARTY_NOTICES/http-range-header@0.4.2/LICENSE +21 -0
  167. package/THIRD_PARTY_NOTICES/http@1.4.0/LICENSE-APACHE +201 -0
  168. package/THIRD_PARTY_NOTICES/http@1.4.0/LICENSE-MIT +25 -0
  169. package/THIRD_PARTY_NOTICES/httparse@1.10.1/LICENSE-APACHE +201 -0
  170. package/THIRD_PARTY_NOTICES/httparse@1.10.1/LICENSE-MIT +20 -0
  171. package/THIRD_PARTY_NOTICES/httpdate@1.0.3/LICENSE-APACHE +201 -0
  172. package/THIRD_PARTY_NOTICES/httpdate@1.0.3/LICENSE-MIT +19 -0
  173. package/THIRD_PARTY_NOTICES/hyper-rustls@0.27.9/LICENSE-APACHE +201 -0
  174. package/THIRD_PARTY_NOTICES/hyper-rustls@0.27.9/LICENSE-ISC +15 -0
  175. package/THIRD_PARTY_NOTICES/hyper-rustls@0.27.9/LICENSE-MIT +25 -0
  176. package/THIRD_PARTY_NOTICES/hyper-util@0.1.20/LICENSE +19 -0
  177. package/THIRD_PARTY_NOTICES/hyper@1.9.0/LICENSE +19 -0
  178. package/THIRD_PARTY_NOTICES/icu_collections@2.1.1/LICENSE +46 -0
  179. package/THIRD_PARTY_NOTICES/icu_locale_core@2.1.1/LICENSE +46 -0
  180. package/THIRD_PARTY_NOTICES/icu_normalizer@2.1.1/LICENSE +46 -0
  181. package/THIRD_PARTY_NOTICES/icu_normalizer_data@2.1.1/LICENSE +46 -0
  182. package/THIRD_PARTY_NOTICES/icu_properties@2.1.2/LICENSE +46 -0
  183. package/THIRD_PARTY_NOTICES/icu_properties_data@2.1.2/LICENSE +46 -0
  184. package/THIRD_PARTY_NOTICES/icu_provider@2.1.1/LICENSE +46 -0
  185. package/THIRD_PARTY_NOTICES/ident_case@1.0.1/LICENSE +19 -0
  186. package/THIRD_PARTY_NOTICES/idna@1.1.0/LICENSE-APACHE +201 -0
  187. package/THIRD_PARTY_NOTICES/idna@1.1.0/LICENSE-MIT +25 -0
  188. package/THIRD_PARTY_NOTICES/idna_adapter@1.2.1/LICENSE-APACHE +201 -0
  189. package/THIRD_PARTY_NOTICES/idna_adapter@1.2.1/LICENSE-MIT +25 -0
  190. package/THIRD_PARTY_NOTICES/indexmap@2.14.0/LICENSE-APACHE +201 -0
  191. package/THIRD_PARTY_NOTICES/indexmap@2.14.0/LICENSE-MIT +25 -0
  192. package/THIRD_PARTY_NOTICES/instant-distance@0.6.1/Cargo.toml +65 -0
  193. package/THIRD_PARTY_NOTICES/instant-distance@0.6.1/LICENSE +201 -0
  194. package/THIRD_PARTY_NOTICES/ipnet@2.12.0/LICENSE-APACHE +201 -0
  195. package/THIRD_PARTY_NOTICES/ipnet@2.12.0/LICENSE-MIT +7 -0
  196. package/THIRD_PARTY_NOTICES/is_terminal_polyfill@1.70.2/LICENSE-APACHE +202 -0
  197. package/THIRD_PARTY_NOTICES/is_terminal_polyfill@1.70.2/LICENSE-MIT +19 -0
  198. package/THIRD_PARTY_NOTICES/itoa@1.0.18/LICENSE-APACHE +176 -0
  199. package/THIRD_PARTY_NOTICES/itoa@1.0.18/LICENSE-MIT +23 -0
  200. package/THIRD_PARTY_NOTICES/layout-base@2.0.1/JamaJS-APACHE.txt +210 -0
  201. package/THIRD_PARTY_NOTICES/lazy_static@1.5.0/LICENSE-APACHE +201 -0
  202. package/THIRD_PARTY_NOTICES/lazy_static@1.5.0/LICENSE-MIT +25 -0
  203. package/THIRD_PARTY_NOTICES/libc@0.2.186/LICENSE-APACHE +176 -0
  204. package/THIRD_PARTY_NOTICES/libc@0.2.186/LICENSE-MIT +25 -0
  205. package/THIRD_PARTY_NOTICES/libsqlite3-sys@0.30.1/LICENSE +19 -0
  206. package/THIRD_PARTY_NOTICES/libsqlite3-sys@0.30.1/sqlcipher/LICENSE +24 -0
  207. package/THIRD_PARTY_NOTICES/linux-raw-sys@0.12.1/COPYRIGHT +29 -0
  208. package/THIRD_PARTY_NOTICES/linux-raw-sys@0.12.1/LICENSE-APACHE +201 -0
  209. package/THIRD_PARTY_NOTICES/linux-raw-sys@0.12.1/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  210. package/THIRD_PARTY_NOTICES/linux-raw-sys@0.12.1/LICENSE-MIT +23 -0
  211. package/THIRD_PARTY_NOTICES/litemap@0.8.2/LICENSE +46 -0
  212. package/THIRD_PARTY_NOTICES/lock_api@0.4.14/LICENSE-APACHE +201 -0
  213. package/THIRD_PARTY_NOTICES/lock_api@0.4.14/LICENSE-MIT +25 -0
  214. package/THIRD_PARTY_NOTICES/log@0.4.29/LICENSE-APACHE +201 -0
  215. package/THIRD_PARTY_NOTICES/log@0.4.29/LICENSE-MIT +25 -0
  216. package/THIRD_PARTY_NOTICES/matchers@0.2.0/LICENSE +19 -0
  217. package/THIRD_PARTY_NOTICES/matchit@0.8.4/LICENSE +21 -0
  218. package/THIRD_PARTY_NOTICES/matchit@0.8.4/LICENSE.httprouter +29 -0
  219. package/THIRD_PARTY_NOTICES/memchr@2.8.0/COPYING +3 -0
  220. package/THIRD_PARTY_NOTICES/memchr@2.8.0/LICENSE-MIT +21 -0
  221. package/THIRD_PARTY_NOTICES/mime@0.3.17/LICENSE-APACHE +201 -0
  222. package/THIRD_PARTY_NOTICES/mime@0.3.17/LICENSE-MIT +20 -0
  223. package/THIRD_PARTY_NOTICES/mime_guess@2.0.5/LICENSE +22 -0
  224. package/THIRD_PARTY_NOTICES/minimal-lexical@0.2.1/LICENSE-APACHE +201 -0
  225. package/THIRD_PARTY_NOTICES/minimal-lexical@0.2.1/LICENSE-MIT +23 -0
  226. package/THIRD_PARTY_NOTICES/minimal-lexical@0.2.1/LICENSE.md +37 -0
  227. package/THIRD_PARTY_NOTICES/miniz_oxide@0.8.9/LICENSE +25 -0
  228. package/THIRD_PARTY_NOTICES/miniz_oxide@0.8.9/LICENSE-APACHE.md +177 -0
  229. package/THIRD_PARTY_NOTICES/miniz_oxide@0.8.9/LICENSE-MIT.md +24 -0
  230. package/THIRD_PARTY_NOTICES/miniz_oxide@0.8.9/LICENSE-ZLIB.md +14 -0
  231. package/THIRD_PARTY_NOTICES/mio@1.2.0/LICENSE +19 -0
  232. package/THIRD_PARTY_NOTICES/nom@7.1.3/LICENSE +20 -0
  233. package/THIRD_PARTY_NOTICES/nu-ansi-term@0.50.3/LICENSE +22 -0
  234. package/THIRD_PARTY_NOTICES/num-modular@0.6.1/LICENSE +201 -0
  235. package/THIRD_PARTY_NOTICES/num-order@1.2.0/LICENSE +201 -0
  236. package/THIRD_PARTY_NOTICES/num-traits@0.2.19/LICENSE-APACHE +201 -0
  237. package/THIRD_PARTY_NOTICES/num-traits@0.2.19/LICENSE-MIT +25 -0
  238. package/THIRD_PARTY_NOTICES/num_cpus@1.17.0/LICENSE-APACHE +201 -0
  239. package/THIRD_PARTY_NOTICES/num_cpus@1.17.0/LICENSE-MIT +20 -0
  240. package/THIRD_PARTY_NOTICES/once_cell@1.21.4/LICENSE-APACHE +201 -0
  241. package/THIRD_PARTY_NOTICES/once_cell@1.21.4/LICENSE-MIT +23 -0
  242. package/THIRD_PARTY_NOTICES/once_cell_polyfill@1.70.2/LICENSE-APACHE +202 -0
  243. package/THIRD_PARTY_NOTICES/once_cell_polyfill@1.70.2/LICENSE-MIT +19 -0
  244. package/THIRD_PARTY_NOTICES/option-ext@0.2.0/SOURCE.crate +0 -0
  245. package/THIRD_PARTY_NOTICES/ordered-float@3.9.2/LICENSE-MIT +25 -0
  246. package/THIRD_PARTY_NOTICES/parking_lot@0.12.5/LICENSE-APACHE +201 -0
  247. package/THIRD_PARTY_NOTICES/parking_lot@0.12.5/LICENSE-MIT +25 -0
  248. package/THIRD_PARTY_NOTICES/parking_lot_core@0.9.12/LICENSE-APACHE +201 -0
  249. package/THIRD_PARTY_NOTICES/parking_lot_core@0.9.12/LICENSE-MIT +25 -0
  250. package/THIRD_PARTY_NOTICES/pastey@0.2.3/LICENSE-APACHE +176 -0
  251. package/THIRD_PARTY_NOTICES/pastey@0.2.3/LICENSE-MIT +23 -0
  252. package/THIRD_PARTY_NOTICES/percent-encoding@2.3.2/LICENSE-APACHE +201 -0
  253. package/THIRD_PARTY_NOTICES/percent-encoding@2.3.2/LICENSE-MIT +25 -0
  254. package/THIRD_PARTY_NOTICES/pest@2.8.6/LICENSE-APACHE +201 -0
  255. package/THIRD_PARTY_NOTICES/pest@2.8.6/LICENSE-MIT +23 -0
  256. package/THIRD_PARTY_NOTICES/pest_derive@2.8.6/LICENSE-APACHE +201 -0
  257. package/THIRD_PARTY_NOTICES/pest_derive@2.8.6/LICENSE-MIT +23 -0
  258. package/THIRD_PARTY_NOTICES/pest_generator@2.8.6/LICENSE-APACHE +201 -0
  259. package/THIRD_PARTY_NOTICES/pest_generator@2.8.6/LICENSE-MIT +23 -0
  260. package/THIRD_PARTY_NOTICES/pest_meta@2.8.6/LICENSE-APACHE +201 -0
  261. package/THIRD_PARTY_NOTICES/pest_meta@2.8.6/LICENSE-MIT +23 -0
  262. package/THIRD_PARTY_NOTICES/pin-project-lite@0.2.17/LICENSE-APACHE +177 -0
  263. package/THIRD_PARTY_NOTICES/pin-project-lite@0.2.17/LICENSE-MIT +23 -0
  264. package/THIRD_PARTY_NOTICES/pkg-config@0.3.33/LICENSE-APACHE +201 -0
  265. package/THIRD_PARTY_NOTICES/pkg-config@0.3.33/LICENSE-MIT +25 -0
  266. package/THIRD_PARTY_NOTICES/potential_utf@0.1.5/LICENSE +46 -0
  267. package/THIRD_PARTY_NOTICES/ppv-lite86@0.2.21/LICENSE-APACHE +201 -0
  268. package/THIRD_PARTY_NOTICES/ppv-lite86@0.2.21/LICENSE-MIT +25 -0
  269. package/THIRD_PARTY_NOTICES/proc-macro2@1.0.106/LICENSE-APACHE +176 -0
  270. package/THIRD_PARTY_NOTICES/proc-macro2@1.0.106/LICENSE-MIT +23 -0
  271. package/THIRD_PARTY_NOTICES/quote@1.0.45/LICENSE-APACHE +176 -0
  272. package/THIRD_PARTY_NOTICES/quote@1.0.45/LICENSE-MIT +23 -0
  273. package/THIRD_PARTY_NOTICES/rand@0.10.1/COPYRIGHT +12 -0
  274. package/THIRD_PARTY_NOTICES/rand@0.10.1/LICENSE-APACHE +176 -0
  275. package/THIRD_PARTY_NOTICES/rand@0.10.1/LICENSE-MIT +26 -0
  276. package/THIRD_PARTY_NOTICES/rand@0.8.6/COPYRIGHT +12 -0
  277. package/THIRD_PARTY_NOTICES/rand@0.8.6/LICENSE-APACHE +176 -0
  278. package/THIRD_PARTY_NOTICES/rand@0.8.6/LICENSE-MIT +26 -0
  279. package/THIRD_PARTY_NOTICES/rand_chacha@0.3.1/COPYRIGHT +12 -0
  280. package/THIRD_PARTY_NOTICES/rand_chacha@0.3.1/LICENSE-APACHE +201 -0
  281. package/THIRD_PARTY_NOTICES/rand_chacha@0.3.1/LICENSE-MIT +26 -0
  282. package/THIRD_PARTY_NOTICES/rand_core@0.10.1/COPYRIGHT +9 -0
  283. package/THIRD_PARTY_NOTICES/rand_core@0.10.1/LICENSE-APACHE +187 -0
  284. package/THIRD_PARTY_NOTICES/rand_core@0.10.1/LICENSE-MIT +25 -0
  285. package/THIRD_PARTY_NOTICES/rand_core@0.6.4/COPYRIGHT +12 -0
  286. package/THIRD_PARTY_NOTICES/rand_core@0.6.4/LICENSE-APACHE +187 -0
  287. package/THIRD_PARTY_NOTICES/rand_core@0.6.4/LICENSE-MIT +26 -0
  288. package/THIRD_PARTY_NOTICES/rayon-core@1.13.0/LICENSE-APACHE +201 -0
  289. package/THIRD_PARTY_NOTICES/rayon-core@1.13.0/LICENSE-MIT +25 -0
  290. package/THIRD_PARTY_NOTICES/rayon@1.12.0/LICENSE-APACHE +201 -0
  291. package/THIRD_PARTY_NOTICES/rayon@1.12.0/LICENSE-MIT +25 -0
  292. package/THIRD_PARTY_NOTICES/ref-cast-impl@1.0.25/LICENSE-APACHE +176 -0
  293. package/THIRD_PARTY_NOTICES/ref-cast-impl@1.0.25/LICENSE-MIT +23 -0
  294. package/THIRD_PARTY_NOTICES/ref-cast@1.0.25/LICENSE-APACHE +176 -0
  295. package/THIRD_PARTY_NOTICES/ref-cast@1.0.25/LICENSE-MIT +23 -0
  296. package/THIRD_PARTY_NOTICES/regex-automata@0.4.14/LICENSE-APACHE +201 -0
  297. package/THIRD_PARTY_NOTICES/regex-automata@0.4.14/LICENSE-MIT +25 -0
  298. package/THIRD_PARTY_NOTICES/regex-syntax@0.8.10/LICENSE-APACHE +201 -0
  299. package/THIRD_PARTY_NOTICES/regex-syntax@0.8.10/LICENSE-MIT +25 -0
  300. package/THIRD_PARTY_NOTICES/regex-syntax@0.8.10/src/unicode_tables/LICENSE-UNICODE +57 -0
  301. package/THIRD_PARTY_NOTICES/regex@1.12.3/LICENSE-APACHE +201 -0
  302. package/THIRD_PARTY_NOTICES/regex@1.12.3/LICENSE-MIT +25 -0
  303. package/THIRD_PARTY_NOTICES/reqwest@0.12.28/LICENSE-APACHE +201 -0
  304. package/THIRD_PARTY_NOTICES/reqwest@0.12.28/LICENSE-MIT +20 -0
  305. package/THIRD_PARTY_NOTICES/rmcp-macros@1.7.0/Cargo.toml +54 -0
  306. package/THIRD_PARTY_NOTICES/rmcp-macros@1.7.0/LICENSE +216 -0
  307. package/THIRD_PARTY_NOTICES/rmcp@1.7.0/Cargo.toml +683 -0
  308. package/THIRD_PARTY_NOTICES/rmcp@1.7.0/LICENSE +216 -0
  309. package/THIRD_PARTY_NOTICES/rusqlite@0.32.1/LICENSE +19 -0
  310. package/THIRD_PARTY_NOTICES/rustix@1.1.4/COPYRIGHT +29 -0
  311. package/THIRD_PARTY_NOTICES/rustix@1.1.4/LICENSE-APACHE +201 -0
  312. package/THIRD_PARTY_NOTICES/rustix@1.1.4/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  313. package/THIRD_PARTY_NOTICES/rustix@1.1.4/LICENSE-MIT +23 -0
  314. package/THIRD_PARTY_NOTICES/rustls-pki-types@1.14.1/LICENSE-APACHE +201 -0
  315. package/THIRD_PARTY_NOTICES/rustls-pki-types@1.14.1/LICENSE-MIT +25 -0
  316. package/THIRD_PARTY_NOTICES/rustls-webpki@0.103.15/LICENSE +19 -0
  317. package/THIRD_PARTY_NOTICES/rustls@0.23.45/LICENSE-APACHE +201 -0
  318. package/THIRD_PARTY_NOTICES/rustls@0.23.45/LICENSE-ISC +15 -0
  319. package/THIRD_PARTY_NOTICES/rustls@0.23.45/LICENSE-MIT +25 -0
  320. package/THIRD_PARTY_NOTICES/ryu@1.0.23/LICENSE-APACHE +176 -0
  321. package/THIRD_PARTY_NOTICES/ryu@1.0.23/LICENSE-BOOST +23 -0
  322. package/THIRD_PARTY_NOTICES/same-file@1.0.6/COPYING +3 -0
  323. package/THIRD_PARTY_NOTICES/same-file@1.0.6/LICENSE-MIT +21 -0
  324. package/THIRD_PARTY_NOTICES/schemars@0.8.22/LICENSE +21 -0
  325. package/THIRD_PARTY_NOTICES/schemars@1.2.1/LICENSE +21 -0
  326. package/THIRD_PARTY_NOTICES/schemars_derive@0.8.22/LICENSE +21 -0
  327. package/THIRD_PARTY_NOTICES/schemars_derive@1.2.1/LICENSE +21 -0
  328. package/THIRD_PARTY_NOTICES/scopeguard@1.2.0/LICENSE-APACHE +201 -0
  329. package/THIRD_PARTY_NOTICES/scopeguard@1.2.0/LICENSE-MIT +25 -0
  330. package/THIRD_PARTY_NOTICES/serde@1.0.228/LICENSE-APACHE +176 -0
  331. package/THIRD_PARTY_NOTICES/serde@1.0.228/LICENSE-MIT +23 -0
  332. package/THIRD_PARTY_NOTICES/serde_core@1.0.228/LICENSE-APACHE +176 -0
  333. package/THIRD_PARTY_NOTICES/serde_core@1.0.228/LICENSE-MIT +23 -0
  334. package/THIRD_PARTY_NOTICES/serde_derive@1.0.228/LICENSE-APACHE +176 -0
  335. package/THIRD_PARTY_NOTICES/serde_derive@1.0.228/LICENSE-MIT +23 -0
  336. package/THIRD_PARTY_NOTICES/serde_derive_internals@0.29.1/LICENSE-APACHE +176 -0
  337. package/THIRD_PARTY_NOTICES/serde_derive_internals@0.29.1/LICENSE-MIT +23 -0
  338. package/THIRD_PARTY_NOTICES/serde_json@1.0.149/LICENSE-APACHE +176 -0
  339. package/THIRD_PARTY_NOTICES/serde_json@1.0.149/LICENSE-MIT +23 -0
  340. package/THIRD_PARTY_NOTICES/serde_path_to_error@0.1.20/LICENSE-APACHE +176 -0
  341. package/THIRD_PARTY_NOTICES/serde_path_to_error@0.1.20/LICENSE-MIT +23 -0
  342. package/THIRD_PARTY_NOTICES/serde_spanned@0.6.9/LICENSE-APACHE +202 -0
  343. package/THIRD_PARTY_NOTICES/serde_spanned@0.6.9/LICENSE-MIT +19 -0
  344. package/THIRD_PARTY_NOTICES/serde_urlencoded@0.7.1/LICENSE-APACHE +176 -0
  345. package/THIRD_PARTY_NOTICES/serde_urlencoded@0.7.1/LICENSE-MIT +25 -0
  346. package/THIRD_PARTY_NOTICES/sha2@0.10.9/LICENSE-APACHE +201 -0
  347. package/THIRD_PARTY_NOTICES/sha2@0.10.9/LICENSE-MIT +27 -0
  348. package/THIRD_PARTY_NOTICES/sharded-slab@0.1.7/LICENSE +19 -0
  349. package/THIRD_PARTY_NOTICES/shlex@1.3.0/LICENSE-APACHE +13 -0
  350. package/THIRD_PARTY_NOTICES/shlex@1.3.0/LICENSE-MIT +21 -0
  351. package/THIRD_PARTY_NOTICES/signal-hook-registry@1.4.8/LICENSE-APACHE +201 -0
  352. package/THIRD_PARTY_NOTICES/signal-hook-registry@1.4.8/LICENSE-MIT +25 -0
  353. package/THIRD_PARTY_NOTICES/simd-adler32@0.3.9/LICENSE.md +21 -0
  354. package/THIRD_PARTY_NOTICES/slab@0.4.12/LICENSE +25 -0
  355. package/THIRD_PARTY_NOTICES/smallvec@1.15.1/LICENSE-APACHE +201 -0
  356. package/THIRD_PARTY_NOTICES/smallvec@1.15.1/LICENSE-MIT +25 -0
  357. package/THIRD_PARTY_NOTICES/socket2@0.6.3/LICENSE-APACHE +201 -0
  358. package/THIRD_PARTY_NOTICES/socket2@0.6.3/LICENSE-MIT +25 -0
  359. package/THIRD_PARTY_NOTICES/sse-stream@0.2.3/Cargo.toml +124 -0
  360. package/THIRD_PARTY_NOTICES/sse-stream@0.2.3/LICENSE-APACHE +202 -0
  361. package/THIRD_PARTY_NOTICES/sse-stream@0.2.3/LICENSE-MIT +21 -0
  362. package/THIRD_PARTY_NOTICES/stable_deref_trait@1.2.1/LICENSE-APACHE +201 -0
  363. package/THIRD_PARTY_NOTICES/stable_deref_trait@1.2.1/LICENSE-MIT +25 -0
  364. package/THIRD_PARTY_NOTICES/streaming-iterator@0.1.9/LICENSE-APACHE +202 -0
  365. package/THIRD_PARTY_NOTICES/streaming-iterator@0.1.9/LICENSE-MIT +19 -0
  366. package/THIRD_PARTY_NOTICES/strsim@0.11.1/LICENSE +23 -0
  367. package/THIRD_PARTY_NOTICES/syn@2.0.117/LICENSE-APACHE +176 -0
  368. package/THIRD_PARTY_NOTICES/syn@2.0.117/LICENSE-MIT +23 -0
  369. package/THIRD_PARTY_NOTICES/syn@3.0.6/LICENSE-APACHE +176 -0
  370. package/THIRD_PARTY_NOTICES/syn@3.0.6/LICENSE-MIT +23 -0
  371. package/THIRD_PARTY_NOTICES/sync_wrapper@1.0.2/LICENSE +177 -0
  372. package/THIRD_PARTY_NOTICES/synstructure@0.13.2/LICENSE +7 -0
  373. package/THIRD_PARTY_NOTICES/tempfile@3.27.0/LICENSE-APACHE +201 -0
  374. package/THIRD_PARTY_NOTICES/tempfile@3.27.0/LICENSE-MIT +25 -0
  375. package/THIRD_PARTY_NOTICES/thiserror-impl@2.0.18/LICENSE-APACHE +176 -0
  376. package/THIRD_PARTY_NOTICES/thiserror-impl@2.0.18/LICENSE-MIT +23 -0
  377. package/THIRD_PARTY_NOTICES/thiserror@2.0.18/LICENSE-APACHE +176 -0
  378. package/THIRD_PARTY_NOTICES/thiserror@2.0.18/LICENSE-MIT +23 -0
  379. package/THIRD_PARTY_NOTICES/thread_local@1.1.9/LICENSE-APACHE +201 -0
  380. package/THIRD_PARTY_NOTICES/thread_local@1.1.9/LICENSE-MIT +25 -0
  381. package/THIRD_PARTY_NOTICES/tinystr@0.8.3/LICENSE +46 -0
  382. package/THIRD_PARTY_NOTICES/tokio-macros@2.7.0/LICENSE +22 -0
  383. package/THIRD_PARTY_NOTICES/tokio-rustls@0.26.4/LICENSE-APACHE +201 -0
  384. package/THIRD_PARTY_NOTICES/tokio-rustls@0.26.4/LICENSE-MIT +25 -0
  385. package/THIRD_PARTY_NOTICES/tokio-stream@0.1.18/LICENSE +21 -0
  386. package/THIRD_PARTY_NOTICES/tokio-util@0.7.18/LICENSE +21 -0
  387. package/THIRD_PARTY_NOTICES/tokio@1.52.3/LICENSE +21 -0
  388. package/THIRD_PARTY_NOTICES/toml@0.8.23/LICENSE-APACHE +202 -0
  389. package/THIRD_PARTY_NOTICES/toml@0.8.23/LICENSE-MIT +19 -0
  390. package/THIRD_PARTY_NOTICES/toml_datetime@0.6.11/LICENSE-APACHE +202 -0
  391. package/THIRD_PARTY_NOTICES/toml_datetime@0.6.11/LICENSE-MIT +19 -0
  392. package/THIRD_PARTY_NOTICES/toml_edit@0.22.27/LICENSE-APACHE +202 -0
  393. package/THIRD_PARTY_NOTICES/toml_edit@0.22.27/LICENSE-MIT +19 -0
  394. package/THIRD_PARTY_NOTICES/toml_write@0.1.2/LICENSE-APACHE +202 -0
  395. package/THIRD_PARTY_NOTICES/toml_write@0.1.2/LICENSE-MIT +19 -0
  396. package/THIRD_PARTY_NOTICES/tower-http@0.6.11/LICENSE +25 -0
  397. package/THIRD_PARTY_NOTICES/tower-layer@0.3.3/LICENSE +25 -0
  398. package/THIRD_PARTY_NOTICES/tower-service@0.3.3/LICENSE +25 -0
  399. package/THIRD_PARTY_NOTICES/tower@0.5.3/LICENSE +25 -0
  400. package/THIRD_PARTY_NOTICES/tracing-attributes@0.1.31/LICENSE +25 -0
  401. package/THIRD_PARTY_NOTICES/tracing-core@0.1.36/LICENSE +25 -0
  402. package/THIRD_PARTY_NOTICES/tracing-core@0.1.36/src/spin/LICENSE +21 -0
  403. package/THIRD_PARTY_NOTICES/tracing-log@0.2.0/LICENSE +25 -0
  404. package/THIRD_PARTY_NOTICES/tracing-subscriber@0.3.23/LICENSE +25 -0
  405. package/THIRD_PARTY_NOTICES/tracing@0.1.44/LICENSE +25 -0
  406. package/THIRD_PARTY_NOTICES/tree-sitter-language@0.1.7/LICENSE +21 -0
  407. package/THIRD_PARTY_NOTICES/tree-sitter-python@0.23.6/Cargo.toml +60 -0
  408. package/THIRD_PARTY_NOTICES/tree-sitter-python@0.23.6/LICENSE +21 -0
  409. package/THIRD_PARTY_NOTICES/tree-sitter-rust@0.24.2/LICENSE +21 -0
  410. package/THIRD_PARTY_NOTICES/tree-sitter-typescript@0.23.2/Cargo.toml +62 -0
  411. package/THIRD_PARTY_NOTICES/tree-sitter-typescript@0.23.2/LICENSE +21 -0
  412. package/THIRD_PARTY_NOTICES/tree-sitter@0.26.9/LICENSE +21 -0
  413. package/THIRD_PARTY_NOTICES/tree-sitter@0.26.9/src/unicode/LICENSE +414 -0
  414. package/THIRD_PARTY_NOTICES/try-lock@0.2.5/LICENSE +21 -0
  415. package/THIRD_PARTY_NOTICES/typenum@1.20.0/LICENSE +1 -0
  416. package/THIRD_PARTY_NOTICES/typenum@1.20.0/LICENSE-APACHE +201 -0
  417. package/THIRD_PARTY_NOTICES/typenum@1.20.0/LICENSE-MIT +21 -0
  418. package/THIRD_PARTY_NOTICES/ucd-trie@0.1.7/LICENSE-APACHE +201 -0
  419. package/THIRD_PARTY_NOTICES/ucd-trie@0.1.7/LICENSE-MIT +21 -0
  420. package/THIRD_PARTY_NOTICES/unicase@2.9.0/LICENSE-APACHE +201 -0
  421. package/THIRD_PARTY_NOTICES/unicase@2.9.0/LICENSE-MIT +20 -0
  422. package/THIRD_PARTY_NOTICES/unicode-ident@1.0.24/LICENSE-APACHE +176 -0
  423. package/THIRD_PARTY_NOTICES/unicode-ident@1.0.24/LICENSE-MIT +23 -0
  424. package/THIRD_PARTY_NOTICES/unicode-ident@1.0.24/LICENSE-UNICODE +39 -0
  425. package/THIRD_PARTY_NOTICES/untrusted@0.9.0/LICENSE.txt +13 -0
  426. package/THIRD_PARTY_NOTICES/ureq@2.12.1/LICENSE-APACHE +201 -0
  427. package/THIRD_PARTY_NOTICES/ureq@2.12.1/LICENSE-MIT +21 -0
  428. package/THIRD_PARTY_NOTICES/ureq@2.12.1/src/chunked/LICENSE-APACHE +201 -0
  429. package/THIRD_PARTY_NOTICES/ureq@2.12.1/src/chunked/LICENSE-MIT +22 -0
  430. package/THIRD_PARTY_NOTICES/url@2.5.8/LICENSE-APACHE +201 -0
  431. package/THIRD_PARTY_NOTICES/url@2.5.8/LICENSE-MIT +25 -0
  432. package/THIRD_PARTY_NOTICES/utf8_iter@1.0.4/COPYRIGHT +42 -0
  433. package/THIRD_PARTY_NOTICES/utf8_iter@1.0.4/LICENSE-APACHE +202 -0
  434. package/THIRD_PARTY_NOTICES/utf8_iter@1.0.4/LICENSE-MIT +25 -0
  435. package/THIRD_PARTY_NOTICES/utf8parse@0.2.2/LICENSE-APACHE +176 -0
  436. package/THIRD_PARTY_NOTICES/utf8parse@0.2.2/LICENSE-MIT +25 -0
  437. package/THIRD_PARTY_NOTICES/uuid@1.23.1/LICENSE-APACHE +201 -0
  438. package/THIRD_PARTY_NOTICES/uuid@1.23.1/LICENSE-MIT +26 -0
  439. package/THIRD_PARTY_NOTICES/vcpkg@0.2.15/LICENSE-APACHE +202 -0
  440. package/THIRD_PARTY_NOTICES/vcpkg@0.2.15/LICENSE-MIT +26 -0
  441. package/THIRD_PARTY_NOTICES/version_check@0.9.5/LICENSE-APACHE +201 -0
  442. package/THIRD_PARTY_NOTICES/version_check@0.9.5/LICENSE-MIT +19 -0
  443. package/THIRD_PARTY_NOTICES/walkdir@2.5.0/COPYING +3 -0
  444. package/THIRD_PARTY_NOTICES/walkdir@2.5.0/LICENSE-MIT +21 -0
  445. package/THIRD_PARTY_NOTICES/want@0.3.1/LICENSE +20 -0
  446. package/THIRD_PARTY_NOTICES/whatlang@0.16.4/Cargo.toml +76 -0
  447. package/THIRD_PARTY_NOTICES/whatlang@0.16.4/LICENSE +26 -0
  448. package/THIRD_PARTY_NOTICES/winapi-util@0.1.11/COPYING +3 -0
  449. package/THIRD_PARTY_NOTICES/winapi-util@0.1.11/LICENSE-MIT +21 -0
  450. package/THIRD_PARTY_NOTICES/winapi@0.3.9/LICENSE-APACHE +201 -0
  451. package/THIRD_PARTY_NOTICES/winapi@0.3.9/LICENSE-MIT +19 -0
  452. package/THIRD_PARTY_NOTICES/windows-link@0.2.1/license-apache-2.0 +201 -0
  453. package/THIRD_PARTY_NOTICES/windows-link@0.2.1/license-mit +21 -0
  454. package/THIRD_PARTY_NOTICES/windows-sys@0.48.0/license-apache-2.0 +201 -0
  455. package/THIRD_PARTY_NOTICES/windows-sys@0.48.0/license-mit +21 -0
  456. package/THIRD_PARTY_NOTICES/windows-sys@0.61.2/license-apache-2.0 +201 -0
  457. package/THIRD_PARTY_NOTICES/windows-sys@0.61.2/license-mit +21 -0
  458. package/THIRD_PARTY_NOTICES/windows-targets@0.48.5/license-apache-2.0 +201 -0
  459. package/THIRD_PARTY_NOTICES/windows-targets@0.48.5/license-mit +21 -0
  460. package/THIRD_PARTY_NOTICES/windows_x86_64_msvc@0.48.5/license-apache-2.0 +201 -0
  461. package/THIRD_PARTY_NOTICES/windows_x86_64_msvc@0.48.5/license-mit +21 -0
  462. package/THIRD_PARTY_NOTICES/winnow@0.7.15/LICENSE-MIT +18 -0
  463. package/THIRD_PARTY_NOTICES/writeable@0.6.3/LICENSE +46 -0
  464. package/THIRD_PARTY_NOTICES/yoke-derive@0.8.2/LICENSE +46 -0
  465. package/THIRD_PARTY_NOTICES/yoke@0.8.2/LICENSE +46 -0
  466. package/THIRD_PARTY_NOTICES/zerocopy@0.8.48/LICENSE-APACHE +202 -0
  467. package/THIRD_PARTY_NOTICES/zerocopy@0.8.48/LICENSE-BSD +24 -0
  468. package/THIRD_PARTY_NOTICES/zerocopy@0.8.48/LICENSE-MIT +26 -0
  469. package/THIRD_PARTY_NOTICES/zerofrom-derive@0.1.7/LICENSE +46 -0
  470. package/THIRD_PARTY_NOTICES/zerofrom@0.1.8/LICENSE +46 -0
  471. package/THIRD_PARTY_NOTICES/zeroize@1.8.2/LICENSE-APACHE +202 -0
  472. package/THIRD_PARTY_NOTICES/zeroize@1.8.2/LICENSE-MIT +21 -0
  473. package/THIRD_PARTY_NOTICES/zerotrie@0.2.4/LICENSE +46 -0
  474. package/THIRD_PARTY_NOTICES/zerovec-derive@0.11.3/LICENSE +46 -0
  475. package/THIRD_PARTY_NOTICES/zerovec@0.11.6/LICENSE +46 -0
  476. package/THIRD_PARTY_NOTICES/zmij@1.0.21/LICENSE-MIT +23 -0
  477. package/package.json +45 -28
  478. package/runtime/dashboard-acl.js +22 -0
  479. package/runtime/dashboard-acl.ps1 +103 -0
  480. package/runtime/dashboard-binary.js +5 -0
  481. package/runtime/dashboard-bootstrap.js +45 -0
  482. package/runtime/dashboard-files.js +20 -3
  483. package/runtime/dashboard-process.js +6 -5
  484. package/runtime/dashboard-supervisor.js +3 -1
  485. package/server.js +98 -0
  486. package/tui/index.js +1 -0
  487. package/tui/rtrt-statusline-core.d.mts +205 -0
  488. package/tui/rtrt-statusline-core.mjs +1145 -0
  489. package/tui/v2/native-runtime.mjs +81 -0
  490. package/tui/v2/native-state.mjs +66 -0
  491. package/tui/v2/rtrt-statusline.tsx +116 -0
  492. package/v2/permissions.js +119 -0
@@ -0,0 +1,1145 @@
1
+ import { spawn as nodeSpawn } from "node:child_process"
2
+ import { performance } from "node:perf_hooks"
3
+
4
+ export const STATUSLINE_VERSION = 1
5
+ export const STATUSLINE_SEPARATOR = " · "
6
+ export const STATUSLINE_FALLBACK = "rtrt · n/a"
7
+ export const STATUSLINE_GROUP_SEPARATOR = " | "
8
+ export const STATUSLINE_WIDE_WIDTH = 100
9
+ export const STATUSLINE_MEDIUM_WIDTH = 70
10
+ export const DEFAULT_DEBOUNCE_MS = 750
11
+ export const DEFAULT_INTERVAL_MS = 15_000
12
+ export const DEFAULT_TIMEOUT_MS = 1_500
13
+ export const STATUSLINE_REFRESH_EVENTS = Object.freeze([
14
+ "server.connected",
15
+ "project.updated",
16
+ "session.created",
17
+ "session.updated",
18
+ "session.compacted",
19
+ "session.deleted",
20
+ "session.diff",
21
+ "session.error",
22
+ "session.idle",
23
+ "session.status",
24
+ ])
25
+
26
+ const MAX_OUTPUT_BYTES = 64 * 1024
27
+ const MAX_SEGMENTS = 32
28
+ const MAX_SEGMENT_LENGTH = 256
29
+ const CONTROL_CHAR = /[\u0000-\u001f\u007f-\u009f]/u
30
+ const CLI_TONES = new Set(["accent", "good", "warn", "bad", "muted"])
31
+ const monotonicNow = () => performance.now()
32
+
33
+ const fallbackPayload = Object.freeze({
34
+ version: STATUSLINE_VERSION,
35
+ stale: true,
36
+ degraded: Object.freeze(["statusline"]),
37
+ segments: Object.freeze([
38
+ Object.freeze({
39
+ id: "fallback",
40
+ text: STATUSLINE_FALLBACK,
41
+ compact: STATUSLINE_FALLBACK,
42
+ tone: "muted",
43
+ priority: 0,
44
+ }),
45
+ ]),
46
+ })
47
+
48
+ const isRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value)
49
+
50
+ const validText = (value, allowEmpty = false) => {
51
+ if (typeof value !== "string" || value.length > MAX_SEGMENT_LENGTH || CONTROL_CHAR.test(value)) return undefined
52
+ const text = value.trim()
53
+ if (!allowEmpty && !text) return undefined
54
+ return text
55
+ }
56
+
57
+ const eventSessionID = (event) => {
58
+ if (!isRecord(event) || !isRecord(event.properties)) return undefined
59
+ if (typeof event.properties.sessionID === "string") return event.properties.sessionID
60
+ for (const key of ["part", "message", "info"]) {
61
+ const child = event.properties[key]
62
+ if (!isRecord(child)) continue
63
+ if (typeof child.sessionID === "string") return child.sessionID
64
+ if (key === "info" && typeof event.type === "string" && event.type.startsWith("session.")) {
65
+ if (typeof child.id === "string") return child.id
66
+ }
67
+ }
68
+ return undefined
69
+ }
70
+
71
+ export function statuslineRefreshTarget(event, activeSessionID = "") {
72
+ const sessionID = eventSessionID(event)
73
+ if (!sessionID) return { app: true }
74
+ return { app: sessionID === activeSessionID, sessionID }
75
+ }
76
+
77
+ const hasControlChars = (value) => {
78
+ const pending = [value]
79
+ const seen = new Set()
80
+ while (pending.length) {
81
+ const item = pending.pop()
82
+ if (typeof item === "string") {
83
+ if (CONTROL_CHAR.test(item)) return true
84
+ continue
85
+ }
86
+ if (!item || typeof item !== "object" || seen.has(item)) continue
87
+ seen.add(item)
88
+ if (Array.isArray(item)) {
89
+ pending.push(...item)
90
+ continue
91
+ }
92
+ for (const [key, child] of Object.entries(item)) {
93
+ if (CONTROL_CHAR.test(key)) return true
94
+ pending.push(child)
95
+ }
96
+ }
97
+ return false
98
+ }
99
+
100
+ const normalizeSegment = (segment) => {
101
+ if (!isRecord(segment)) return undefined
102
+
103
+ const id = validText(segment.id)
104
+ const text = validText(segment.text)
105
+ const sourceTone = validText(segment.tone)
106
+ const tone = sourceTone && CLI_TONES.has(sourceTone) ? sourceTone : "muted"
107
+ const priority = segment.pri
108
+ if (!id || !text || !sourceTone || !Number.isSafeInteger(priority) || priority < 0 || priority > 255) {
109
+ return undefined
110
+ }
111
+ return { id, text, compact: text, tone, priority }
112
+ }
113
+
114
+ export function parseStatuslineJson(raw) {
115
+ if (typeof raw !== "string" || !raw.trim() || Buffer.byteLength(raw) > MAX_OUTPUT_BYTES) return undefined
116
+ try {
117
+ const value = JSON.parse(raw)
118
+ if (!isRecord(value) || value.v !== STATUSLINE_VERSION || hasControlChars(value)) return undefined
119
+ if (value.stale !== undefined && typeof value.stale !== "boolean") return undefined
120
+ if (
121
+ value.degraded !== undefined &&
122
+ (!Array.isArray(value.degraded) ||
123
+ value.degraded.length > MAX_SEGMENTS ||
124
+ value.degraded.some((item) => !validText(item)))
125
+ ) {
126
+ return undefined
127
+ }
128
+ if (!Array.isArray(value.segments) || value.segments.length < 1 || value.segments.length > MAX_SEGMENTS) {
129
+ return undefined
130
+ }
131
+ const segments = value.segments.map(normalizeSegment)
132
+ if (segments.some((segment) => !segment)) return undefined
133
+ return {
134
+ version: STATUSLINE_VERSION,
135
+ stale: value.stale === true,
136
+ degraded: value.degraded?.map((item) => item.trim()) ?? [],
137
+ segments,
138
+ }
139
+ } catch {
140
+ return undefined
141
+ }
142
+ }
143
+
144
+ const normalizedWidth = (width) => {
145
+ if (!Number.isFinite(width)) return 80
146
+ return Math.max(1, Math.min(4_096, Math.floor(width)))
147
+ }
148
+
149
+ export function statuslineCommandArgs({ cwd, session, width, model }) {
150
+ const args = [
151
+ "statusline",
152
+ "--opencode",
153
+ "--cwd",
154
+ String(cwd ?? ""),
155
+ "--session",
156
+ String(session ?? ""),
157
+ "--width",
158
+ String(normalizedWidth(width)),
159
+ ]
160
+ const selectedModel = validText(model)
161
+ if (selectedModel) args.push("--model", selectedModel)
162
+ return args
163
+ }
164
+
165
+ export function statuslineBinaryCandidates(bin, env = process.env) {
166
+ const values = [bin, env?.RTRT_BIN, "rtrt"]
167
+ const seen = new Set()
168
+ return values.flatMap((value) => {
169
+ const candidate = validText(value)
170
+ if (!candidate || seen.has(candidate)) return []
171
+ seen.add(candidate)
172
+ return [candidate]
173
+ })
174
+ }
175
+
176
+ const runCandidate = ({
177
+ binary,
178
+ args,
179
+ cwd,
180
+ spawnImpl,
181
+ timeoutMs,
182
+ signal,
183
+ setTimeoutFn,
184
+ clearTimeoutFn,
185
+ }) =>
186
+ new Promise((resolve) => {
187
+ let child
188
+ let settled = false
189
+ let bytes = 0
190
+ const chunks = []
191
+ let timeout
192
+ let abort
193
+
194
+ const finish = (payload) => {
195
+ if (settled) return
196
+ settled = true
197
+ clearTimeoutFn(timeout)
198
+ if (abort) signal?.removeEventListener("abort", abort)
199
+ resolve(payload)
200
+ }
201
+
202
+ if (signal?.aborted) {
203
+ finish(undefined)
204
+ return
205
+ }
206
+
207
+ try {
208
+ child = spawnImpl(binary, args, {
209
+ cwd: cwd || undefined,
210
+ shell: false,
211
+ stdio: ["ignore", "pipe", "ignore"],
212
+ windowsHide: true,
213
+ })
214
+ } catch {
215
+ finish(undefined)
216
+ return
217
+ }
218
+
219
+ if (!child?.stdout || typeof child.once !== "function") {
220
+ try {
221
+ child?.kill?.()
222
+ } catch {}
223
+ finish(undefined)
224
+ return
225
+ }
226
+
227
+ child.stdout.on("data", (chunk) => {
228
+ const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
229
+ bytes += data.length
230
+ if (bytes > MAX_OUTPUT_BYTES) {
231
+ try {
232
+ child.kill("SIGKILL")
233
+ } catch {}
234
+ finish(undefined)
235
+ return
236
+ }
237
+ chunks.push(data)
238
+ })
239
+ child.once("error", () => finish(undefined))
240
+ child.once("close", (code) => {
241
+ if (code !== 0) {
242
+ finish(undefined)
243
+ return
244
+ }
245
+ finish(parseStatuslineJson(Buffer.concat(chunks).toString("utf8")))
246
+ })
247
+
248
+ abort = () => {
249
+ try {
250
+ child.kill("SIGKILL")
251
+ } catch {}
252
+ finish(undefined)
253
+ }
254
+ signal?.addEventListener("abort", abort, { once: true })
255
+
256
+ timeout = setTimeoutFn(() => {
257
+ try {
258
+ child.kill("SIGKILL")
259
+ } catch {}
260
+ finish(undefined)
261
+ }, Math.max(1, timeoutMs))
262
+ timeout.unref?.()
263
+ })
264
+
265
+ export async function runStatusline({
266
+ bin,
267
+ env = process.env,
268
+ cwd,
269
+ session,
270
+ width,
271
+ model,
272
+ spawnImpl = nodeSpawn,
273
+ timeoutMs = DEFAULT_TIMEOUT_MS,
274
+ signal,
275
+ nowFn = monotonicNow,
276
+ setTimeoutFn = setTimeout,
277
+ clearTimeoutFn = clearTimeout,
278
+ }) {
279
+ const args = statuslineCommandArgs({ cwd, session, width, model })
280
+ const duration = Number.isFinite(timeoutMs) ? Math.max(1, timeoutMs) : DEFAULT_TIMEOUT_MS
281
+ const deadline = nowFn() + duration
282
+ for (const binary of statuslineBinaryCandidates(bin, env)) {
283
+ if (signal?.aborted) return undefined
284
+ const remaining = deadline - nowFn()
285
+ if (remaining <= 0) return undefined
286
+ try {
287
+ const payload = await runCandidate({
288
+ binary,
289
+ args,
290
+ cwd,
291
+ spawnImpl,
292
+ timeoutMs: Math.ceil(remaining),
293
+ signal,
294
+ setTimeoutFn,
295
+ clearTimeoutFn,
296
+ })
297
+ if (payload) return payload
298
+ } catch {}
299
+ }
300
+ return undefined
301
+ }
302
+
303
+ export function createSpawnLimiter({ concurrency = 2 } = {}) {
304
+ const limit = Number.isSafeInteger(concurrency) ? Math.max(1, Math.min(16, concurrency)) : 2
305
+ const queue = []
306
+ const running = new Set()
307
+ let active = 0
308
+ let disposed = false
309
+
310
+ const cleanup = (entry) => entry.signal?.removeEventListener("abort", entry.abort)
311
+
312
+ const finish = (entry, value) => {
313
+ if (entry.finished) return
314
+ entry.finished = true
315
+ cleanup(entry)
316
+ if (entry.started) {
317
+ active -= 1
318
+ running.delete(entry)
319
+ }
320
+ entry.resolve(value)
321
+ pump()
322
+ }
323
+
324
+ const start = (entry) => {
325
+ entry.started = true
326
+ active += 1
327
+ running.add(entry)
328
+ void (async () => {
329
+ let value
330
+ try {
331
+ value = await entry.task(entry.controller.signal)
332
+ } catch {}
333
+ finish(entry, value)
334
+ })()
335
+ }
336
+
337
+ const pump = () => {
338
+ while (!disposed && active < limit && queue.length > 0) {
339
+ let selected = 0
340
+ for (let index = 1; index < queue.length; index += 1) {
341
+ if (queue[index].priority > queue[selected].priority) selected = index
342
+ }
343
+ const [entry] = queue.splice(selected, 1)
344
+ if (!entry.finished) start(entry)
345
+ }
346
+ }
347
+
348
+ return {
349
+ run(task, { signal, priority = 0 } = {}) {
350
+ if (disposed || signal?.aborted) return Promise.resolve(undefined)
351
+ return new Promise((resolve) => {
352
+ const entry = {
353
+ task,
354
+ signal,
355
+ priority: Number.isFinite(priority) ? priority : 0,
356
+ controller: new AbortController(),
357
+ resolve,
358
+ started: false,
359
+ finished: false,
360
+ abort: undefined,
361
+ }
362
+ entry.abort = () => {
363
+ entry.controller.abort()
364
+ if (entry.started) return
365
+ const index = queue.indexOf(entry)
366
+ if (index >= 0) queue.splice(index, 1)
367
+ finish(entry, undefined)
368
+ }
369
+ signal?.addEventListener("abort", entry.abort, { once: true })
370
+ queue.push(entry)
371
+ pump()
372
+ })
373
+ },
374
+ activeCount: () => active,
375
+ queuedCount: () => queue.length,
376
+ dispose() {
377
+ if (disposed) return
378
+ disposed = true
379
+ for (const entry of queue.splice(0)) {
380
+ entry.controller.abort()
381
+ finish(entry, undefined)
382
+ }
383
+ for (const entry of running) entry.controller.abort()
384
+ },
385
+ }
386
+ }
387
+
388
+ const isWideCodePoint = (code) =>
389
+ code >= 0x1100 &&
390
+ (code <= 0x115f ||
391
+ code === 0x2329 ||
392
+ code === 0x232a ||
393
+ (code >= 0x2e80 && code <= 0xa4cf && code !== 0x303f) ||
394
+ (code >= 0xac00 && code <= 0xd7a3) ||
395
+ (code >= 0xf900 && code <= 0xfaff) ||
396
+ (code >= 0xfe10 && code <= 0xfe19) ||
397
+ (code >= 0xfe30 && code <= 0xfe6f) ||
398
+ (code >= 0xff00 && code <= 0xff60) ||
399
+ (code >= 0xffe0 && code <= 0xffe6) ||
400
+ (code >= 0x1f300 && code <= 0x1faff) ||
401
+ (code >= 0x20000 && code <= 0x3fffd))
402
+
403
+ export function cellWidth(text) {
404
+ let width = 0
405
+ for (const character of text) {
406
+ if (/\p{Mark}/u.test(character) || character === "\u200d" || character === "\ufe0f") continue
407
+ width += isWideCodePoint(character.codePointAt(0)) ? 2 : 1
408
+ }
409
+ return width
410
+ }
411
+
412
+ const truncateToWidth = (text, width) => {
413
+ if (cellWidth(text) <= width) return text
414
+ if (width <= 1) return "…".slice(0, width)
415
+ let output = ""
416
+ let used = 0
417
+ for (const character of text) {
418
+ const size = cellWidth(character)
419
+ if (used + size > width - 1) break
420
+ output += character
421
+ used += size
422
+ }
423
+ return `${output}…`
424
+ }
425
+
426
+ const findCatalogModel = (providers, providerID, modelID) => {
427
+ if (!Array.isArray(providers) || typeof providerID !== "string" || typeof modelID !== "string") {
428
+ return undefined
429
+ }
430
+ const provider = providers.find((item) => item?.id === providerID)
431
+ if (!isRecord(provider?.models)) return undefined
432
+ const direct = provider.models[modelID]
433
+ if (isRecord(direct)) return direct
434
+ return Object.values(provider.models).find(
435
+ (model) => isRecord(model) && model.id === modelID && (!model.providerID || model.providerID === providerID),
436
+ )
437
+ }
438
+
439
+ const tokenCount = (value) => (Number.isFinite(value) && value > 0 ? value : 0)
440
+
441
+ const contextTone = (percent) => {
442
+ if (percent > 100) return "warn"
443
+ if (percent >= 90) return "bad"
444
+ if (percent >= 75) return "warn"
445
+ return "good"
446
+ }
447
+
448
+ export function deriveSessionEconomics({ session, messages = [], providers = [], status } = {}) {
449
+ let cost = { text: "N/A", tone: "muted" }
450
+ if (session?.cost === 0) {
451
+ cost = { text: "$0?", tone: "muted" }
452
+ } else if (Number.isFinite(session?.cost) && session.cost > 0) {
453
+ cost = { text: `~$${session.cost.toFixed(2)}`, tone: "accent" }
454
+ }
455
+
456
+ const selected = session?.model
457
+ const selectedModel = findCatalogModel(providers, selected?.providerID, selected?.id)
458
+ const selectedText = validText(selectedModel?.name) ?? validText(selected?.id)
459
+ const model = selectedText
460
+ ? { text: truncateToWidth(selectedText.split("/").at(-1), 22), tone: "accent" }
461
+ : { text: "N/A", tone: "muted" }
462
+ const selectedProviderID = validText(selected?.providerID)
463
+ const selectedModelID = validText(selected?.id)
464
+ const modelRef =
465
+ selectedProviderID && selectedModelID ? validText(`${selectedProviderID}/${selectedModelID}`) : undefined
466
+
467
+ let context = { text: "N/A", tone: "muted" }
468
+ if (Array.isArray(messages)) {
469
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
470
+ const message = messages[index]
471
+ if (message?.role !== "assistant") continue
472
+ const tokens = message.tokens
473
+ if (message.error || !Number.isFinite(message.time?.completed) || tokenCount(tokens?.output) <= 0) {
474
+ continue
475
+ }
476
+ const used =
477
+ tokenCount(tokens?.input) +
478
+ tokenCount(tokens?.output) +
479
+ tokenCount(tokens?.reasoning) +
480
+ tokenCount(tokens?.cache?.read) +
481
+ tokenCount(tokens?.cache?.write)
482
+ if (used <= 0) continue
483
+ const exactModel = findCatalogModel(providers, message.providerID, message.modelID)
484
+ const limit = exactModel?.limit?.context
485
+ if (Number.isFinite(limit) && limit > 0) {
486
+ const percent = Math.max(0, Math.round((used / limit) * 100))
487
+ const headroom = Math.max(0, 100 - percent)
488
+ context = { text: `${percent}%`, tone: contextTone(percent), used, limit, percent, headroom }
489
+ } else {
490
+ context = { text: "N/A", tone: "muted", used }
491
+ }
492
+ break
493
+ }
494
+ }
495
+
496
+ // OpenCode omits idle sessions from the status map.
497
+ const sessionStatus = session
498
+ ? ({
499
+ busy: { text: "BUSY", tone: "accent" },
500
+ retry: { text: "RETRY", tone: "bad" },
501
+ idle: { text: "IDLE", tone: "muted" },
502
+ }[status?.type] ?? { text: "IDLE", tone: "muted" })
503
+ : { text: "UNKNOWN", tone: "muted" }
504
+
505
+ return {
506
+ cost,
507
+ context,
508
+ model,
509
+ status: sessionStatus,
510
+ week: { text: "N/A/not exposed", tone: "muted" },
511
+ modelRef,
512
+ }
513
+ }
514
+
515
+ const renderedWidth = (segments) =>
516
+ segments.reduce((sum, segment) => sum + cellWidth(segment.text), 0) +
517
+ Math.max(0, segments.length - 1) * cellWidth(STATUSLINE_SEPARATOR)
518
+
519
+ export function selectSegments(payload, { width = 80, compact = false } = {}) {
520
+ const limit = normalizedWidth(width)
521
+ let selected = payload.segments.flatMap((segment, index) => {
522
+ const text = compact ? segment.compact : segment.text
523
+ return text ? [{ ...segment, text, index }] : []
524
+ })
525
+ while (selected.length > 1 && renderedWidth(selected) > limit) {
526
+ let remove = 0
527
+ for (let index = 1; index < selected.length; index += 1) {
528
+ if (
529
+ selected[index].priority < selected[remove].priority ||
530
+ (selected[index].priority === selected[remove].priority && selected[index].index > selected[remove].index)
531
+ ) {
532
+ remove = index
533
+ }
534
+ }
535
+ selected.splice(remove, 1)
536
+ }
537
+ if (selected.length === 1) selected[0] = { ...selected[0], text: truncateToWidth(selected[0].text, limit) }
538
+ return selected.map(({ index: _index, ...segment }) => segment)
539
+ }
540
+
541
+ export function initialStatuslineState() {
542
+ return { payload: fallbackPayload, lastGood: undefined, stale: true, unavailable: true }
543
+ }
544
+
545
+ export function nextStatuslineState(previous, payload) {
546
+ if (payload) return { payload, lastGood: payload, stale: payload.stale === true, unavailable: false }
547
+ if (previous.lastGood) {
548
+ return { payload: previous.lastGood, lastGood: previous.lastGood, stale: true, unavailable: false }
549
+ }
550
+ return initialStatuslineState()
551
+ }
552
+
553
+ export function renderSegments(state, options = {}) {
554
+ const payload =
555
+ state.stale && !state.unavailable
556
+ ? {
557
+ version: STATUSLINE_VERSION,
558
+ stale: true,
559
+ segments: [
560
+ ...state.payload.segments,
561
+ { id: "stale", text: "stale", compact: "stale", tone: "muted", priority: 1_000 },
562
+ ],
563
+ }
564
+ : state.payload
565
+ const segments = selectSegments(payload, options)
566
+ return state.stale ? segments.map((segment) => ({ ...segment, tone: "muted" })) : segments
567
+ }
568
+
569
+ const viewPart = (text, role, tone, id) => ({ text, role, tone, id })
570
+
571
+ const valueGroup = (id, text, tone = "muted", role = "value") => ({
572
+ id,
573
+ parts: [viewPart(text, role, tone, id)],
574
+ })
575
+
576
+ const metricGroup = (id, label, text, tone) => ({
577
+ id,
578
+ parts: [
579
+ viewPart(`${label} `, "label", "muted", id),
580
+ viewPart(text, "value", tone, id),
581
+ ],
582
+ })
583
+
584
+ const groupText = (group) => group.parts.map((part) => part.text).join("")
585
+ const groupsWidth = (groups, separator) =>
586
+ groups.reduce((sum, group) => sum + cellWidth(groupText(group)), 0) +
587
+ Math.max(0, groups.length - 1) * cellWidth(separator)
588
+
589
+ const rowFromGroups = (id, groups, separator) => {
590
+ const parts = []
591
+ for (const [index, group] of groups.entries()) {
592
+ if (index > 0) parts.push(viewPart(separator, "separator", "muted", "separator"))
593
+ parts.push(...group.parts)
594
+ }
595
+ return { id, parts }
596
+ }
597
+
598
+ const sourceTone = (state, segment) => (state.stale ? "muted" : segment?.tone ?? "muted")
599
+
600
+ const segmentValue = (segments, id, prefix = "") => {
601
+ const segment = segments.get(id)
602
+ if (!segment) return undefined
603
+ const text = prefix && segment.text.startsWith(prefix) ? segment.text.slice(prefix.length) : segment.text
604
+ return text ? { text, segment } : undefined
605
+ }
606
+
607
+ const savingsValues = (segments) => {
608
+ const savings = segments.get("savings")
609
+ if (savings) {
610
+ const save = /(?:^|\s)save:([^\s]+)/u.exec(savings.text)?.[1]
611
+ const command = /(?:^|\s)cmd:([^\s]+)/u.exec(savings.text)?.[1]
612
+ return {
613
+ save: save ? { text: save, segment: savings } : undefined,
614
+ command: command ? { text: command, segment: savings } : undefined,
615
+ }
616
+ }
617
+ const sigma = segments.get("sigma")
618
+ if (!sigma) return {}
619
+ const text = sigma.text.replace(/^(?:Σ|sigma):?/iu, "")
620
+ return text ? { save: { text, segment: sigma } } : {}
621
+ }
622
+
623
+ const headroomValues = (segments) => {
624
+ const value = segmentValue(segments, "headroom", "room:")
625
+ if (!value) return undefined
626
+ const boundary = value.text.lastIndexOf(":")
627
+ if (boundary < 0) return { full: value.text, compact: value.text, segment: value.segment }
628
+ const target = value.text.slice(0, boundary)
629
+ const amount = value.text.slice(boundary + 1)
630
+ return {
631
+ full: target && amount ? `${target} ${amount}` : value.text,
632
+ compact: amount || value.text,
633
+ segment: value.segment,
634
+ }
635
+ }
636
+
637
+ const reportedPercentToken = (text) => {
638
+ const match = /\d+(?:\.\d+)?%/u.exec(text)
639
+ if (!match) return undefined
640
+ const before = match.index > 0 ? text[match.index - 1] : ""
641
+ const after = text[match.index + match[0].length] ?? ""
642
+ if (
643
+ (before && /[\p{Letter}\p{Number}_.+-]/u.test(before)) ||
644
+ (after && /[\p{Letter}\p{Number}_.%]/u.test(after))
645
+ ) {
646
+ return undefined
647
+ }
648
+ const value = Number(match[0].slice(0, -1))
649
+ if (!Number.isFinite(value) || value < 0 || value > 100) return undefined
650
+ return { text: match[0], index: match.index }
651
+ }
652
+
653
+ const officialLimitValue = (segments, id) => {
654
+ const segment = segments.get(id)
655
+ if (!segment) return undefined
656
+ const percentToken = reportedPercentToken(segment.text)
657
+ if (!percentToken) return undefined
658
+ const percent = percentToken.text
659
+ let reset = segment.text.slice(percentToken.index + percent.length).trim()
660
+ reset = reset
661
+ .replace(/^[|,;/-]\s*/u, "")
662
+ .replace(/^(?:reset(?:s|_at)?|r)\s*[:=]?\s*/iu, "")
663
+ .replace(/^(?:in\s+|↻\s*|@\s*)/iu, "")
664
+ .replace(/\s+/gu, "")
665
+ return {
666
+ full: reset ? `${percent}/${reset}` : percent,
667
+ percent,
668
+ segment,
669
+ }
670
+ }
671
+
672
+ const statusGroups = (state, missing) => {
673
+ const groups = []
674
+ if (state.stale && !state.unavailable) groups.push(valueGroup("stale", "STALE", "warn"))
675
+ if (state.unavailable || missing || (state.payload.degraded?.length ?? 0) > 0) {
676
+ groups.push(valueGroup("degraded", "DEGRADED", "bad"))
677
+ }
678
+ if (groups.length === 0) groups.push(valueGroup("live", "LIVE", "good"))
679
+ return groups
680
+ }
681
+
682
+ const replaceGroupText = (groups, id, text) =>
683
+ groups.map((group) => {
684
+ if (group.id !== id) return group
685
+ const last = group.parts.length - 1
686
+ return {
687
+ ...group,
688
+ parts: group.parts.map((part, index) => (index === last ? { ...part, text } : part)),
689
+ }
690
+ })
691
+
692
+ const removeGroup = (groups, id) => groups.filter((group) => group.id !== id)
693
+
694
+ const capGroupValues = (source, limits) => {
695
+ let groups = source
696
+ for (const [id, limit] of limits) {
697
+ const group = groups.find((item) => item.id === id)
698
+ if (!group) continue
699
+ const value = group.parts.at(-1)?.text ?? ""
700
+ groups = replaceGroupText(groups, id, truncateToWidth(value, limit))
701
+ }
702
+ return groups
703
+ }
704
+
705
+ const fitWideIdentityGroups = (source, width) => {
706
+ let groups = capGroupValues(source, [
707
+ ["project", 36],
708
+ ["git", 24],
709
+ ["model", 22],
710
+ ])
711
+ if (groupsWidth(groups, " ") > width) groups = removeGroup(groups, "git")
712
+ const project = groups.find((group) => group.id === "project")
713
+ if (project && groupsWidth(groups, " ") > width) {
714
+ const overflow = groupsWidth(groups, " ") - width
715
+ const current = groupText(project)
716
+ groups = replaceGroupText(groups, "project", truncateToWidth(current, Math.max(4, cellWidth(current) - overflow)))
717
+ }
718
+ if (groupsWidth(groups, " ") > width) groups = removeGroup(groups, "project")
719
+ return groups
720
+ }
721
+
722
+ const fitWideMetricGroups = (source, width) => {
723
+ let groups = capGroupValues(source, [
724
+ ["style", 12],
725
+ ["savings", 8],
726
+ ["command", 8],
727
+ ["memory", 18],
728
+ ["headroom", 18],
729
+ ["cost", 12],
730
+ ["context", 5],
731
+ ["week", 15],
732
+ ["limit-5h", 12],
733
+ ["limit-week", 12],
734
+ ])
735
+ for (const id of ["headroom", "memory", "command", "savings", "style"]) {
736
+ if (groupsWidth(groups, STATUSLINE_GROUP_SEPARATOR) <= width) break
737
+ groups = removeGroup(groups, id)
738
+ }
739
+ return groups
740
+ }
741
+
742
+ const fitMediumGroups = (source, width) => {
743
+ let groups = capGroupValues(source, [
744
+ ["project", 18],
745
+ ["model", 16],
746
+ ["style", 12],
747
+ ["savings", 8],
748
+ ["command", 8],
749
+ ["headroom", 10],
750
+ ["cost", 12],
751
+ ["context", 5],
752
+ ["week", 15],
753
+ ["limit-5h", 12],
754
+ ["limit-week", 12],
755
+ ])
756
+ for (const id of ["week", "headroom", "command"]) {
757
+ if (groupsWidth(groups, STATUSLINE_GROUP_SEPARATOR) <= width) break
758
+ groups = removeGroup(groups, id)
759
+ }
760
+ const project = groups.find((group) => group.id === "project")
761
+ if (project && groupsWidth(groups, STATUSLINE_GROUP_SEPARATOR) > width) {
762
+ const overflow = groupsWidth(groups, STATUSLINE_GROUP_SEPARATOR) - width
763
+ const current = groupText(project)
764
+ groups = replaceGroupText(groups, "project", truncateToWidth(current, Math.max(4, cellWidth(current) - overflow)))
765
+ }
766
+ for (const id of ["model", "project", "style", "savings", "badge"]) {
767
+ if (groupsWidth(groups, STATUSLINE_GROUP_SEPARATOR) <= width) break
768
+ groups = removeGroup(groups, id)
769
+ }
770
+ if (groupsWidth(groups, STATUSLINE_GROUP_SEPARATOR) <= width) {
771
+ return { groups, separator: STATUSLINE_GROUP_SEPARATOR }
772
+ }
773
+
774
+ const fallback = []
775
+ for (const id of ["savings", "cost", "context", "session-status"]) {
776
+ const group = groups.find((item) => item.id === id)
777
+ const value = group?.parts.at(-1)
778
+ if (value) fallback.push(valueGroup(id, truncateToWidth(value.text, id === "cost" ? 12 : 8), value.tone))
779
+ }
780
+ for (const [id, label] of [
781
+ ["limit-5h", "5H"],
782
+ ["limit-week", "WEEK"],
783
+ ]) {
784
+ const group = groups.find((item) => item.id === id)
785
+ const value = group?.parts.at(-1)
786
+ if (!value) continue
787
+ fallback.push(metricGroup(id, label, truncateToWidth(value.text, 12), value.tone))
788
+ }
789
+ fallback.push(...groups.filter((group) => ["stale", "degraded", "live"].includes(group.id)))
790
+ return {
791
+ groups: fitNarrowGroups(fallback, width, ["context", "cost", "savings", "session-status", "limit-5h", "limit-week"]),
792
+ separator: " ",
793
+ }
794
+ }
795
+
796
+ const fitNarrowGroups = (source, width, removalOrder = ["cost", "context", "style", "savings"]) => {
797
+ let groups = source
798
+ for (const id of removalOrder) {
799
+ if (groupsWidth(groups, " ") <= width) break
800
+ groups = removeGroup(groups, id)
801
+ }
802
+ if (groups.length === 0) groups = [valueGroup("missing", "N/A", "bad")]
803
+ if (groupsWidth(groups, " ") <= width) return groups
804
+ const text = groups.map(groupText).join(" ")
805
+ return [valueGroup("status", truncateToWidth(text, width), "bad")]
806
+ }
807
+
808
+ export function createStatuslineViewModel(state, { width = 80, economics, promptRight = false } = {}) {
809
+ const limit = normalizedWidth(width)
810
+ const layout = limit >= STATUSLINE_WIDE_WIDTH ? "wide" : limit >= STATUSLINE_MEDIUM_WIDTH ? "medium" : "narrow"
811
+ const sessionEconomics = economics ?? deriveSessionEconomics()
812
+ const segments = new Map(state.payload.segments.map((segment) => [segment.id, segment]))
813
+ const project = segmentValue(segments, "project")
814
+ const git = segmentValue(segments, "git")
815
+ const style = segmentValue(segments, "style", "opt:")
816
+ const savings = savingsValues(segments)
817
+ const memory = segmentValue(segments, "memory", "mem:")
818
+ const headroom = headroomValues(segments)
819
+ const limitsFresh = !state.stale && !state.unavailable
820
+ const limit5h = limitsFresh ? officialLimitValue(segments, "limit_5h") : undefined
821
+ const limitWeek = limitsFresh ? officialLimitValue(segments, "limit_week") : undefined
822
+ const missing = state.unavailable || (!style && !savings.save)
823
+ const statuses = statusGroups(state, missing)
824
+
825
+ if (layout === "wide") {
826
+ const identity = [valueGroup("badge", "[RTRT]", "accent", "badge")]
827
+ if (state.unavailable) {
828
+ identity.push(valueGroup("missing", "N/A", "bad"))
829
+ } else {
830
+ if (project) identity.push(valueGroup("project", truncateToWidth(project.text, 36), sourceTone(state, project.segment)))
831
+ if (git) identity.push(valueGroup("git", truncateToWidth(git.text, 24), sourceTone(state, git.segment)))
832
+ }
833
+ identity.push(
834
+ metricGroup("model", "MODEL", sessionEconomics.model.text, sessionEconomics.model.tone),
835
+ metricGroup("session-status", "STATE", sessionEconomics.status.text, sessionEconomics.status.tone),
836
+ ...statuses,
837
+ )
838
+
839
+ const metrics = []
840
+ if (state.unavailable) {
841
+ for (const label of ["OPT", "SAVE", "CMD", "MEM", "ROOM"]) {
842
+ metrics.push(metricGroup(label.toLowerCase(), label, "N/A", "bad"))
843
+ }
844
+ } else {
845
+ if (style) metrics.push(metricGroup("style", "OPT", style.text, sourceTone(state, style.segment)))
846
+ if (savings.save) metrics.push(metricGroup("savings", "SAVE", savings.save.text, sourceTone(state, savings.save.segment)))
847
+ if (savings.command) metrics.push(metricGroup("command", "CMD", savings.command.text, sourceTone(state, savings.command.segment)))
848
+ if (memory) metrics.push(metricGroup("memory", "MEM", truncateToWidth(memory.text, 18), sourceTone(state, memory.segment)))
849
+ if (headroom) metrics.push(metricGroup("headroom", "ROOM", truncateToWidth(headroom.full, 28), sourceTone(state, headroom.segment)))
850
+ if (metrics.length === 0) metrics.push(metricGroup("metrics", "METRICS", "N/A", "bad"))
851
+ }
852
+ metrics.push(
853
+ metricGroup("cost", "COST", sessionEconomics.cost.text, sessionEconomics.cost.tone),
854
+ metricGroup("context", "CTX", sessionEconomics.context.text, sessionEconomics.context.tone),
855
+ )
856
+ if (limit5h) {
857
+ metrics.push(metricGroup("limit-5h", "5H", limit5h.full, sourceTone(state, limit5h.segment)))
858
+ }
859
+ metrics.push(
860
+ limitWeek
861
+ ? metricGroup("limit-week", "WEEK", limitWeek.full, sourceTone(state, limitWeek.segment))
862
+ : metricGroup("week", "WEEK", sessionEconomics.week.text, sessionEconomics.week.tone),
863
+ )
864
+ const fittedIdentity = fitWideIdentityGroups(identity, limit)
865
+ const fittedMetrics = fitWideMetricGroups(metrics, limit)
866
+ return {
867
+ layout,
868
+ width: limit,
869
+ rows: [
870
+ rowFromGroups("identity", fittedIdentity, " "),
871
+ rowFromGroups("metrics", fittedMetrics, STATUSLINE_GROUP_SEPARATOR),
872
+ ],
873
+ }
874
+ }
875
+
876
+ if (layout === "medium") {
877
+ let groups = [valueGroup("badge", "[RTRT]", "accent", "badge")]
878
+ if (state.unavailable) {
879
+ groups.push(valueGroup("missing", "N/A", "bad"))
880
+ } else {
881
+ if (project) groups.push(valueGroup("project", truncateToWidth(project.text, 18), sourceTone(state, project.segment)))
882
+ groups.push(metricGroup("model", "MODEL", sessionEconomics.model.text, sessionEconomics.model.tone))
883
+ groups.push(metricGroup("session-status", "STATE", sessionEconomics.status.text, sessionEconomics.status.tone))
884
+ if (style) groups.push(metricGroup("style", "OPT", style.text, sourceTone(state, style.segment)))
885
+ if (savings.save) groups.push(metricGroup("savings", "SAVE", savings.save.text, sourceTone(state, savings.save.segment)))
886
+ groups.push(metricGroup("cost", "COST", sessionEconomics.cost.text, sessionEconomics.cost.tone))
887
+ groups.push(metricGroup("context", "CTX", sessionEconomics.context.text, sessionEconomics.context.tone))
888
+ if (savings.command) groups.push(metricGroup("command", "CMD", savings.command.text, sourceTone(state, savings.command.segment)))
889
+ if (headroom) groups.push(metricGroup("headroom", "ROOM", headroom.compact, sourceTone(state, headroom.segment)))
890
+ }
891
+ if (state.unavailable) {
892
+ groups.push(
893
+ metricGroup("model", "MODEL", sessionEconomics.model.text, sessionEconomics.model.tone),
894
+ metricGroup("session-status", "STATE", sessionEconomics.status.text, sessionEconomics.status.tone),
895
+ metricGroup("cost", "COST", sessionEconomics.cost.text, sessionEconomics.cost.tone),
896
+ metricGroup("context", "CTX", sessionEconomics.context.text, sessionEconomics.context.tone),
897
+ )
898
+ }
899
+ if (limit5h) {
900
+ groups.push(metricGroup("limit-5h", "5H", limit5h.full, sourceTone(state, limit5h.segment)))
901
+ }
902
+ groups.push(
903
+ limitWeek
904
+ ? metricGroup("limit-week", "WEEK", limitWeek.full, sourceTone(state, limitWeek.segment))
905
+ : metricGroup("week", "WEEK", sessionEconomics.week.text, sessionEconomics.week.tone),
906
+ ...statuses,
907
+ )
908
+ const fitted = fitMediumGroups(groups, limit)
909
+ return { layout, width: limit, rows: [rowFromGroups("summary", fitted.groups, fitted.separator)] }
910
+ }
911
+
912
+ let groups = []
913
+ if (!state.unavailable && savings.save) {
914
+ groups.push(valueGroup("savings", savings.save.text, sourceTone(state, savings.save.segment)))
915
+ }
916
+ if (!promptRight && !state.unavailable && style) {
917
+ groups.unshift(valueGroup("style", style.text, sourceTone(state, style.segment)))
918
+ }
919
+ groups.push(valueGroup("cost", sessionEconomics.cost.text, sessionEconomics.cost.tone))
920
+ if (promptRight) groups.push(valueGroup("context", sessionEconomics.context.text, sessionEconomics.context.tone))
921
+ if (promptRight && limitWeek) {
922
+ groups.push(valueGroup("limit-week", limitWeek.percent, sourceTone(state, limitWeek.segment)))
923
+ }
924
+ if (statuses[0]?.id !== "live") groups.push(...statuses)
925
+ groups = fitNarrowGroups(
926
+ groups,
927
+ limit,
928
+ promptRight ? ["limit-week", "context", "cost", "savings"] : ["cost", "style", "savings"],
929
+ )
930
+ return { layout, width: limit, rows: [rowFromGroups("core", groups, " ")] }
931
+ }
932
+
933
+ export function renderStatuslineViewText(state, options = {}) {
934
+ return createStatuslineViewModel(state, options)
935
+ .rows.map((row) => row.parts.map((part) => part.text).join(""))
936
+ .join("\n")
937
+ }
938
+
939
+ export function renderStatuslineText(state, options = {}) {
940
+ return renderStatuslineViewText(state, options)
941
+ }
942
+
943
+ export function createRefreshScheduler({
944
+ run,
945
+ debounceMs = DEFAULT_DEBOUNCE_MS,
946
+ intervalMs = DEFAULT_INTERVAL_MS,
947
+ setTimeoutFn = setTimeout,
948
+ clearTimeoutFn = clearTimeout,
949
+ setIntervalFn = setInterval,
950
+ clearIntervalFn = clearInterval,
951
+ }) {
952
+ let started = false
953
+ let disposed = false
954
+ let queued = false
955
+ let debounce
956
+ let interval
957
+ let running
958
+
959
+ const execute = () => {
960
+ if (disposed) return Promise.resolve()
961
+ if (running) {
962
+ queued = true
963
+ return running
964
+ }
965
+ running = (async () => {
966
+ do {
967
+ queued = false
968
+ try {
969
+ await run()
970
+ } catch {}
971
+ } while (queued && !disposed)
972
+ })().finally(() => {
973
+ running = undefined
974
+ if (queued && !disposed) void execute()
975
+ })
976
+ return running
977
+ }
978
+
979
+ const clearDebounce = () => {
980
+ if (debounce === undefined) return
981
+ clearTimeoutFn(debounce)
982
+ debounce = undefined
983
+ }
984
+
985
+ const request = (immediate = false) => {
986
+ if (disposed) return
987
+ clearDebounce()
988
+ if (immediate) {
989
+ void execute()
990
+ return
991
+ }
992
+ debounce = setTimeoutFn(() => {
993
+ debounce = undefined
994
+ void execute()
995
+ }, Math.max(0, debounceMs))
996
+ debounce?.unref?.()
997
+ }
998
+
999
+ return {
1000
+ start() {
1001
+ if (started || disposed) return
1002
+ started = true
1003
+ request(true)
1004
+ if (intervalMs > 0) {
1005
+ interval = setIntervalFn(() => request(true), intervalMs)
1006
+ interval?.unref?.()
1007
+ }
1008
+ },
1009
+ request,
1010
+ flush() {
1011
+ clearDebounce()
1012
+ return execute()
1013
+ },
1014
+ dispose() {
1015
+ disposed = true
1016
+ clearDebounce()
1017
+ if (interval !== undefined) clearIntervalFn(interval)
1018
+ },
1019
+ }
1020
+ }
1021
+
1022
+ export function createStatuslineController({
1023
+ load,
1024
+ onState = () => {},
1025
+ debounceMs = DEFAULT_DEBOUNCE_MS,
1026
+ intervalMs = DEFAULT_INTERVAL_MS,
1027
+ timers = {},
1028
+ }) {
1029
+ let context = { cwd: "", session: "", width: 80, model: "" }
1030
+ let state = initialStatuslineState()
1031
+ let generation = 0
1032
+ let activeRefresh
1033
+ const lifetime = new AbortController()
1034
+ const scheduler = createRefreshScheduler({
1035
+ run: async () => {
1036
+ const snapshot = { ...context }
1037
+ const startedGeneration = generation
1038
+ const refresh = new AbortController()
1039
+ const abortRefresh = () => refresh.abort()
1040
+ activeRefresh = refresh
1041
+ lifetime.signal.addEventListener("abort", abortRefresh, { once: true })
1042
+ let payload
1043
+ try {
1044
+ payload = await load(snapshot, refresh.signal)
1045
+ } catch {}
1046
+ lifetime.signal.removeEventListener("abort", abortRefresh)
1047
+ if (activeRefresh === refresh) activeRefresh = undefined
1048
+ if (
1049
+ lifetime.signal.aborted ||
1050
+ refresh.signal.aborted ||
1051
+ startedGeneration !== generation ||
1052
+ snapshot.cwd !== context.cwd ||
1053
+ snapshot.session !== context.session ||
1054
+ snapshot.width !== context.width ||
1055
+ snapshot.model !== context.model
1056
+ ) {
1057
+ return
1058
+ }
1059
+ state = nextStatuslineState(state, payload)
1060
+ try {
1061
+ onState(state)
1062
+ } catch {}
1063
+ },
1064
+ debounceMs,
1065
+ intervalMs,
1066
+ ...timers,
1067
+ })
1068
+
1069
+ return {
1070
+ start: scheduler.start,
1071
+ request: scheduler.request,
1072
+ refreshNow: scheduler.flush,
1073
+ dispose() {
1074
+ activeRefresh?.abort()
1075
+ lifetime.abort()
1076
+ scheduler.dispose()
1077
+ },
1078
+ setContext(next) {
1079
+ const updated = {
1080
+ cwd: typeof next.cwd === "string" ? next.cwd : context.cwd,
1081
+ session: typeof next.session === "string" ? next.session : context.session,
1082
+ width: next.width === undefined ? context.width : normalizedWidth(next.width),
1083
+ model: typeof next.model === "string" ? next.model : context.model,
1084
+ }
1085
+ if (
1086
+ updated.cwd === context.cwd &&
1087
+ updated.session === context.session &&
1088
+ updated.width === context.width &&
1089
+ updated.model === context.model
1090
+ ) {
1091
+ return
1092
+ }
1093
+ context = updated
1094
+ generation += 1
1095
+ activeRefresh?.abort()
1096
+ scheduler.request()
1097
+ },
1098
+ getState: () => state,
1099
+ getContext: () => ({ ...context }),
1100
+ }
1101
+ }
1102
+
1103
+ export function createKeyedControllerPool({ create }) {
1104
+ const entries = new Map()
1105
+
1106
+ const dispose = (entry) => {
1107
+ try {
1108
+ entry.value.dispose()
1109
+ } catch {}
1110
+ }
1111
+
1112
+ return {
1113
+ acquire(key) {
1114
+ let entry = entries.get(key)
1115
+ if (!entry) {
1116
+ entry = { value: create(key), refs: 0 }
1117
+ entries.set(key, entry)
1118
+ }
1119
+ entry.refs += 1
1120
+ let released = false
1121
+ return {
1122
+ value: entry.value,
1123
+ release() {
1124
+ if (released) return
1125
+ released = true
1126
+ entry.refs -= 1
1127
+ if (entry.refs > 0 || entries.get(key) !== entry) return
1128
+ entries.delete(key)
1129
+ dispose(entry)
1130
+ },
1131
+ }
1132
+ },
1133
+ get(key) {
1134
+ return entries.get(key)?.value
1135
+ },
1136
+ forEach(callback) {
1137
+ for (const [key, entry] of entries) callback(entry.value, key)
1138
+ },
1139
+ size: () => entries.size,
1140
+ dispose() {
1141
+ for (const entry of entries.values()) dispose(entry)
1142
+ entries.clear()
1143
+ },
1144
+ }
1145
+ }