termcast 1.3.21 → 1.3.25

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 (429) hide show
  1. package/dist/ai.d.ts +104 -0
  2. package/dist/ai.d.ts.map +1 -0
  3. package/dist/ai.js +135 -0
  4. package/dist/ai.js.map +1 -0
  5. package/dist/apis/browser-extension.d.ts +18 -0
  6. package/dist/apis/browser-extension.d.ts.map +1 -0
  7. package/dist/apis/browser-extension.js +14 -0
  8. package/dist/apis/browser-extension.js.map +1 -0
  9. package/dist/apis/localstorage.d.ts.map +1 -1
  10. package/dist/apis/localstorage.js +4 -7
  11. package/dist/apis/localstorage.js.map +1 -1
  12. package/dist/apis/oauth.d.ts.map +1 -1
  13. package/dist/apis/oauth.js +5 -1
  14. package/dist/apis/oauth.js.map +1 -1
  15. package/dist/apis/preferences.d.ts.map +1 -1
  16. package/dist/apis/preferences.js +38 -19
  17. package/dist/apis/preferences.js.map +1 -1
  18. package/dist/apis/toast.d.ts +5 -0
  19. package/dist/apis/toast.d.ts.map +1 -1
  20. package/dist/apis/toast.js +7 -43
  21. package/dist/apis/toast.js.map +1 -1
  22. package/dist/build.d.ts.map +1 -1
  23. package/dist/build.js +3 -1
  24. package/dist/build.js.map +1 -1
  25. package/dist/cache.d.ts +32 -0
  26. package/dist/cache.d.ts.map +1 -0
  27. package/dist/cache.js +205 -0
  28. package/dist/cache.js.map +1 -0
  29. package/dist/cli.d.ts.map +1 -1
  30. package/dist/cli.js +87 -41
  31. package/dist/cli.js.map +1 -1
  32. package/dist/clipboard.d.ts +36 -0
  33. package/dist/clipboard.d.ts.map +1 -0
  34. package/dist/clipboard.js +154 -0
  35. package/dist/clipboard.js.map +1 -0
  36. package/dist/compile.d.ts +2 -1
  37. package/dist/compile.d.ts.map +1 -1
  38. package/dist/compile.js +31 -12
  39. package/dist/compile.js.map +1 -1
  40. package/dist/components/actions.d.ts.map +1 -1
  41. package/dist/components/actions.js +56 -30
  42. package/dist/components/actions.js.map +1 -1
  43. package/dist/components/detail.d.ts.map +1 -1
  44. package/dist/components/detail.js +4 -0
  45. package/dist/components/detail.js.map +1 -1
  46. package/dist/components/dropdown.d.ts.map +1 -1
  47. package/dist/components/dropdown.js +38 -15
  48. package/dist/components/dropdown.js.map +1 -1
  49. package/dist/components/extension-preferences.d.ts.map +1 -1
  50. package/dist/components/extension-preferences.js +40 -13
  51. package/dist/components/extension-preferences.js.map +1 -1
  52. package/dist/components/form/checkbox.d.ts.map +1 -1
  53. package/dist/components/form/checkbox.js +5 -3
  54. package/dist/components/form/checkbox.js.map +1 -1
  55. package/dist/components/form/date-picker.d.ts.map +1 -1
  56. package/dist/components/form/date-picker.js +5 -3
  57. package/dist/components/form/date-picker.js.map +1 -1
  58. package/dist/components/form/description.d.ts.map +1 -1
  59. package/dist/components/form/description.js +2 -2
  60. package/dist/components/form/description.js.map +1 -1
  61. package/dist/components/form/dropdown.d.ts.map +1 -1
  62. package/dist/components/form/dropdown.js +84 -80
  63. package/dist/components/form/dropdown.js.map +1 -1
  64. package/dist/components/form/file-autocomplete.d.ts +3 -6
  65. package/dist/components/form/file-autocomplete.d.ts.map +1 -1
  66. package/dist/components/form/file-autocomplete.js +61 -66
  67. package/dist/components/form/file-autocomplete.js.map +1 -1
  68. package/dist/components/form/file-picker.d.ts.map +1 -1
  69. package/dist/components/form/file-picker.js +33 -30
  70. package/dist/components/form/file-picker.js.map +1 -1
  71. package/dist/components/form/form-end.d.ts.map +1 -1
  72. package/dist/components/form/form-end.js +21 -1
  73. package/dist/components/form/form-end.js.map +1 -1
  74. package/dist/components/form/form-type-only.d.ts +174 -0
  75. package/dist/components/form/form-type-only.d.ts.map +1 -0
  76. package/dist/components/form/form-type-only.js +2 -0
  77. package/dist/components/form/form-type-only.js.map +1 -0
  78. package/dist/components/form/index.d.ts +3 -1
  79. package/dist/components/form/index.d.ts.map +1 -1
  80. package/dist/components/form/index.js +104 -30
  81. package/dist/components/form/index.js.map +1 -1
  82. package/dist/components/form/password-field.d.ts.map +1 -1
  83. package/dist/components/form/password-field.js +5 -3
  84. package/dist/components/form/password-field.js.map +1 -1
  85. package/dist/components/form/text-area.d.ts.map +1 -1
  86. package/dist/components/form/text-area.js +5 -3
  87. package/dist/components/form/text-area.js.map +1 -1
  88. package/dist/components/form/text-field.d.ts.map +1 -1
  89. package/dist/components/form/text-field.js +6 -4
  90. package/dist/components/form/text-field.js.map +1 -1
  91. package/dist/components/form/types.d.ts +5 -0
  92. package/dist/components/form/types.d.ts.map +1 -1
  93. package/dist/components/form/use-form-handling.d.ts +4 -0
  94. package/dist/components/form/use-form-handling.d.ts.map +1 -0
  95. package/dist/components/form/use-form-handling.js +37 -0
  96. package/dist/components/form/use-form-handling.js.map +1 -0
  97. package/dist/components/form/with-left-border.d.ts +2 -1
  98. package/dist/components/form/with-left-border.d.ts.map +1 -1
  99. package/dist/components/form/with-left-border.js +27 -3
  100. package/dist/components/form/with-left-border.js.map +1 -1
  101. package/dist/components/icon.d.ts +1 -0
  102. package/dist/components/icon.d.ts.map +1 -1
  103. package/dist/components/icon.js +24 -8
  104. package/dist/components/icon.js.map +1 -1
  105. package/dist/components/list.d.ts +2 -2
  106. package/dist/components/list.d.ts.map +1 -1
  107. package/dist/components/list.js +155 -70
  108. package/dist/components/list.js.map +1 -1
  109. package/dist/components/loading-bar.d.ts.map +1 -1
  110. package/dist/components/loading-bar.js +2 -2
  111. package/dist/components/loading-bar.js.map +1 -1
  112. package/dist/components/loading-text.d.ts +8 -0
  113. package/dist/components/loading-text.d.ts.map +1 -0
  114. package/dist/components/loading-text.js +58 -0
  115. package/dist/components/loading-text.js.map +1 -0
  116. package/dist/descendants.js +1 -1
  117. package/dist/descendants.js.map +1 -1
  118. package/dist/dev-ui.d.ts +7 -0
  119. package/dist/dev-ui.d.ts.map +1 -0
  120. package/dist/dev-ui.js +118 -0
  121. package/dist/dev-ui.js.map +1 -0
  122. package/dist/environment.d.ts +63 -0
  123. package/dist/environment.d.ts.map +1 -0
  124. package/dist/environment.js +189 -0
  125. package/dist/environment.js.map +1 -0
  126. package/dist/examples/datepicker.d.ts +2 -0
  127. package/dist/examples/datepicker.d.ts.map +1 -0
  128. package/dist/examples/datepicker.js +344 -0
  129. package/dist/examples/datepicker.js.map +1 -0
  130. package/dist/examples/file-autocomplete.vitest.d.ts +2 -0
  131. package/dist/examples/file-autocomplete.vitest.d.ts.map +1 -0
  132. package/dist/examples/file-autocomplete.vitest.js +223 -0
  133. package/dist/examples/file-autocomplete.vitest.js.map +1 -0
  134. package/dist/examples/form-basic-arrow-keys.vitest.d.ts +2 -0
  135. package/dist/examples/form-basic-arrow-keys.vitest.d.ts.map +1 -0
  136. package/dist/examples/form-basic-arrow-keys.vitest.js +46 -0
  137. package/dist/examples/form-basic-arrow-keys.vitest.js.map +1 -0
  138. package/dist/examples/form-basic.vitest.d.ts +2 -0
  139. package/dist/examples/form-basic.vitest.d.ts.map +1 -0
  140. package/dist/examples/form-basic.vitest.js +630 -0
  141. package/dist/examples/form-basic.vitest.js.map +1 -0
  142. package/dist/examples/form-dropdown-with-sections.d.ts +2 -0
  143. package/dist/examples/form-dropdown-with-sections.d.ts.map +1 -0
  144. package/dist/examples/form-dropdown-with-sections.js +13 -0
  145. package/dist/examples/form-dropdown-with-sections.js.map +1 -0
  146. package/dist/examples/form-dropdown-with-sections.vitest.d.ts +2 -0
  147. package/dist/examples/form-dropdown-with-sections.vitest.d.ts.map +1 -0
  148. package/dist/examples/form-dropdown-with-sections.vitest.js +75 -0
  149. package/dist/examples/form-dropdown-with-sections.vitest.js.map +1 -0
  150. package/dist/examples/form-dropdown.vitest.d.ts +2 -0
  151. package/dist/examples/form-dropdown.vitest.d.ts.map +1 -0
  152. package/dist/examples/form-dropdown.vitest.js +854 -0
  153. package/dist/examples/form-dropdown.vitest.js.map +1 -0
  154. package/dist/examples/form-multiselect-dropdown.d.ts +2 -0
  155. package/dist/examples/form-multiselect-dropdown.d.ts.map +1 -0
  156. package/dist/examples/form-multiselect-dropdown.js +13 -0
  157. package/dist/examples/form-multiselect-dropdown.js.map +1 -0
  158. package/dist/examples/form-scroll.d.ts.map +1 -1
  159. package/dist/examples/form-scroll.js +7 -1
  160. package/dist/examples/form-scroll.js.map +1 -1
  161. package/dist/examples/form-scroll.vitest.d.ts +2 -0
  162. package/dist/examples/form-scroll.vitest.d.ts.map +1 -0
  163. package/dist/examples/form-scroll.vitest.js +211 -0
  164. package/dist/examples/form-scroll.vitest.js.map +1 -0
  165. package/dist/examples/form-tagpicker.vitest.d.ts +2 -0
  166. package/dist/examples/form-tagpicker.vitest.d.ts.map +1 -0
  167. package/dist/examples/form-tagpicker.vitest.js +736 -0
  168. package/dist/examples/form-tagpicker.vitest.js.map +1 -0
  169. package/dist/examples/internal/descendants-filtering.js +1 -1
  170. package/dist/examples/internal/descendants-filtering.js.map +1 -1
  171. package/dist/examples/internal/descendants.js +1 -1
  172. package/dist/examples/internal/descendants.js.map +1 -1
  173. package/dist/examples/internal/nested-boxes.d.ts +2 -0
  174. package/dist/examples/internal/nested-boxes.d.ts.map +1 -0
  175. package/dist/examples/internal/nested-boxes.js +7 -0
  176. package/dist/examples/internal/nested-boxes.js.map +1 -0
  177. package/dist/examples/internal/rhf-custom-ref.js +2 -2
  178. package/dist/examples/internal/rhf-custom-ref.js.map +1 -1
  179. package/dist/examples/internal/scrollbox-demo.js +3 -22
  180. package/dist/examples/internal/scrollbox-demo.js.map +1 -1
  181. package/dist/examples/internal/scrollbox-descendants.d.ts +2 -0
  182. package/dist/examples/internal/scrollbox-descendants.d.ts.map +1 -0
  183. package/dist/examples/internal/scrollbox-descendants.js +83 -0
  184. package/dist/examples/internal/scrollbox-descendants.js.map +1 -0
  185. package/dist/examples/internal/scrollbox-with-descendants.js +4 -8
  186. package/dist/examples/internal/scrollbox-with-descendants.js.map +1 -1
  187. package/dist/examples/internal/simple-scrollbox.vitest.d.ts +2 -0
  188. package/dist/examples/internal/simple-scrollbox.vitest.d.ts.map +1 -0
  189. package/dist/examples/internal/simple-scrollbox.vitest.js +96 -0
  190. package/dist/examples/internal/simple-scrollbox.vitest.js.map +1 -0
  191. package/dist/examples/internal/unicode-square-repro.d.ts +2 -0
  192. package/dist/examples/internal/unicode-square-repro.d.ts.map +1 -0
  193. package/dist/examples/internal/unicode-square-repro.js +7 -0
  194. package/dist/examples/internal/unicode-square-repro.js.map +1 -0
  195. package/dist/examples/list-detail-metadata.d.ts +2 -0
  196. package/dist/examples/list-detail-metadata.d.ts.map +1 -0
  197. package/dist/examples/list-detail-metadata.js +8 -0
  198. package/dist/examples/list-detail-metadata.js.map +1 -0
  199. package/dist/examples/list-dropdown-default.vitest.d.ts +2 -0
  200. package/dist/examples/list-dropdown-default.vitest.d.ts.map +1 -0
  201. package/dist/examples/list-dropdown-default.vitest.js +234 -0
  202. package/dist/examples/list-dropdown-default.vitest.js.map +1 -0
  203. package/dist/examples/list-fetch-data.vitest.d.ts +2 -0
  204. package/dist/examples/list-fetch-data.vitest.d.ts.map +1 -0
  205. package/dist/examples/list-fetch-data.vitest.js +111 -0
  206. package/dist/examples/list-fetch-data.vitest.js.map +1 -0
  207. package/dist/examples/list-filter-navigation.d.ts +2 -0
  208. package/dist/examples/list-filter-navigation.d.ts.map +1 -0
  209. package/dist/examples/list-filter-navigation.js +8 -0
  210. package/dist/examples/list-filter-navigation.js.map +1 -0
  211. package/dist/examples/list-scrollbox.vitest.d.ts +2 -0
  212. package/dist/examples/list-scrollbox.vitest.d.ts.map +1 -0
  213. package/dist/examples/list-scrollbox.vitest.js +93 -0
  214. package/dist/examples/list-scrollbox.vitest.js.map +1 -0
  215. package/dist/examples/list-with-detail-long.d.ts +2 -0
  216. package/dist/examples/list-with-detail-long.d.ts.map +1 -0
  217. package/dist/examples/list-with-detail-long.js +53 -0
  218. package/dist/examples/list-with-detail-long.js.map +1 -0
  219. package/dist/examples/list-with-detail.vitest.d.ts +2 -0
  220. package/dist/examples/list-with-detail.vitest.d.ts.map +1 -0
  221. package/dist/examples/list-with-detail.vitest.js +434 -0
  222. package/dist/examples/list-with-detail.vitest.js.map +1 -0
  223. package/dist/examples/list-with-dropdown.vitest.d.ts +2 -0
  224. package/dist/examples/list-with-dropdown.vitest.d.ts.map +1 -0
  225. package/dist/examples/list-with-dropdown.vitest.js +337 -0
  226. package/dist/examples/list-with-dropdown.vitest.js.map +1 -0
  227. package/dist/examples/list-with-sections.js +5 -1
  228. package/dist/examples/list-with-sections.js.map +1 -1
  229. package/dist/examples/list-with-sections.vitest.d.ts +2 -0
  230. package/dist/examples/list-with-sections.vitest.d.ts.map +1 -0
  231. package/dist/examples/list-with-sections.vitest.js +601 -0
  232. package/dist/examples/list-with-sections.vitest.js.map +1 -0
  233. package/dist/examples/scrollbox-vertical-centering.d.ts +6 -0
  234. package/dist/examples/scrollbox-vertical-centering.d.ts.map +1 -0
  235. package/dist/examples/scrollbox-vertical-centering.js +17 -0
  236. package/dist/examples/scrollbox-vertical-centering.js.map +1 -0
  237. package/dist/examples/simple-file-picker.vitest.d.ts +2 -0
  238. package/dist/examples/simple-file-picker.vitest.d.ts.map +1 -0
  239. package/dist/examples/simple-file-picker.vitest.js +678 -0
  240. package/dist/examples/simple-file-picker.vitest.js.map +1 -0
  241. package/dist/examples/simple-grid.vitest.d.ts +2 -0
  242. package/dist/examples/simple-grid.vitest.d.ts.map +1 -0
  243. package/dist/examples/simple-grid.vitest.js +521 -0
  244. package/dist/examples/simple-grid.vitest.js.map +1 -0
  245. package/dist/examples/simple-navigation.js +10 -4
  246. package/dist/examples/simple-navigation.js.map +1 -1
  247. package/dist/examples/simple-navigation.vitest.d.ts +2 -0
  248. package/dist/examples/simple-navigation.vitest.d.ts.map +1 -0
  249. package/dist/examples/simple-navigation.vitest.js +718 -0
  250. package/dist/examples/simple-navigation.vitest.js.map +1 -0
  251. package/dist/examples/store.vitest.d.ts +2 -0
  252. package/dist/examples/store.vitest.d.ts.map +1 -0
  253. package/dist/examples/store.vitest.js +69 -0
  254. package/dist/examples/store.vitest.js.map +1 -0
  255. package/dist/examples/toast-variations.d.ts +2 -0
  256. package/dist/examples/toast-variations.d.ts.map +1 -0
  257. package/dist/examples/toast-variations.js +122 -0
  258. package/dist/examples/toast-variations.js.map +1 -0
  259. package/dist/extensions/dev.d.ts +4 -2
  260. package/dist/extensions/dev.d.ts.map +1 -1
  261. package/dist/extensions/dev.js +61 -10
  262. package/dist/extensions/dev.js.map +1 -1
  263. package/dist/extensions/dev.vitest.d.ts +2 -0
  264. package/dist/extensions/dev.vitest.d.ts.map +1 -0
  265. package/dist/extensions/dev.vitest.js +197 -0
  266. package/dist/extensions/dev.vitest.js.map +1 -0
  267. package/dist/extensions/home.d.ts.map +1 -1
  268. package/dist/extensions/home.js +3 -0
  269. package/dist/extensions/home.js.map +1 -1
  270. package/dist/home-command.d.ts +8 -0
  271. package/dist/home-command.d.ts.map +1 -0
  272. package/dist/home-command.js +181 -0
  273. package/dist/home-command.js.map +1 -0
  274. package/dist/hover-repro.d.ts +2 -0
  275. package/dist/hover-repro.d.ts.map +1 -0
  276. package/dist/hover-repro.js +20 -0
  277. package/dist/hover-repro.js.map +1 -0
  278. package/dist/index.d.ts +1 -0
  279. package/dist/index.d.ts.map +1 -1
  280. package/dist/index.js +2 -0
  281. package/dist/index.js.map +1 -1
  282. package/dist/internal/dialog.d.ts +1 -0
  283. package/dist/internal/dialog.d.ts.map +1 -1
  284. package/dist/internal/dialog.js +27 -18
  285. package/dist/internal/dialog.js.map +1 -1
  286. package/dist/internal/navigation.d.ts +9 -1
  287. package/dist/internal/navigation.d.ts.map +1 -1
  288. package/dist/internal/navigation.js +5 -5
  289. package/dist/internal/navigation.js.map +1 -1
  290. package/dist/internal/offscreen.d.ts +6 -0
  291. package/dist/internal/offscreen.d.ts.map +1 -0
  292. package/dist/internal/offscreen.js +10 -0
  293. package/dist/internal/offscreen.js.map +1 -0
  294. package/dist/internal/providers.d.ts.map +1 -1
  295. package/dist/internal/providers.js +2 -2
  296. package/dist/internal/providers.js.map +1 -1
  297. package/dist/internal/scrollbox.d.ts +1 -10
  298. package/dist/internal/scrollbox.d.ts.map +1 -1
  299. package/dist/internal/scrollbox.js +2 -1
  300. package/dist/internal/scrollbox.js.map +1 -1
  301. package/dist/localstorage.d.ts +13 -0
  302. package/dist/localstorage.d.ts.map +1 -0
  303. package/dist/localstorage.js +190 -0
  304. package/dist/localstorage.js.map +1 -0
  305. package/dist/oauth.d.ts +142 -0
  306. package/dist/oauth.d.ts.map +1 -0
  307. package/dist/oauth.js +551 -0
  308. package/dist/oauth.js.map +1 -0
  309. package/dist/preferences.d.ts +23 -0
  310. package/dist/preferences.d.ts.map +1 -0
  311. package/dist/preferences.js +105 -0
  312. package/dist/preferences.js.map +1 -0
  313. package/dist/release.d.ts +1 -1
  314. package/dist/release.d.ts.map +1 -1
  315. package/dist/release.js +29 -33
  316. package/dist/release.js.map +1 -1
  317. package/dist/state.d.ts +2 -0
  318. package/dist/state.d.ts.map +1 -1
  319. package/dist/state.js +3 -0
  320. package/dist/state.js.map +1 -1
  321. package/dist/store.d.ts +21 -0
  322. package/dist/store.d.ts.map +1 -0
  323. package/dist/store.js +84 -0
  324. package/dist/store.js.map +1 -0
  325. package/dist/swift-loader.d.ts +3 -0
  326. package/dist/swift-loader.d.ts.map +1 -0
  327. package/dist/swift-loader.js +193 -0
  328. package/dist/swift-loader.js.map +1 -0
  329. package/dist/swift-runtime.d.ts +2 -0
  330. package/dist/swift-runtime.d.ts.map +1 -0
  331. package/dist/swift-runtime.js +27 -0
  332. package/dist/swift-runtime.js.map +1 -0
  333. package/dist/toast.d.ts +44 -0
  334. package/dist/toast.d.ts.map +1 -0
  335. package/dist/toast.js +221 -0
  336. package/dist/toast.js.map +1 -0
  337. package/dist/utils/file-system.d.ts +9 -0
  338. package/dist/utils/file-system.d.ts.map +1 -1
  339. package/dist/utils/file-system.js +49 -0
  340. package/dist/utils/file-system.js.map +1 -1
  341. package/dist/utils/run-command.d.ts +26 -1
  342. package/dist/utils/run-command.d.ts.map +1 -1
  343. package/dist/utils/run-command.js +53 -4
  344. package/dist/utils/run-command.js.map +1 -1
  345. package/dist/window.d.ts +12 -0
  346. package/dist/window.d.ts.map +1 -0
  347. package/dist/window.js +48 -0
  348. package/dist/window.js.map +1 -0
  349. package/package.json +12 -12
  350. package/src/apis/browser-extension.tsx +29 -0
  351. package/src/apis/localstorage.test.ts +14 -6
  352. package/src/apis/localstorage.tsx +8 -5
  353. package/src/apis/oauth.tsx +5 -1
  354. package/src/apis/preferences.tsx +48 -22
  355. package/src/apis/toast.tsx +37 -62
  356. package/src/build.test.tsx +52 -0
  357. package/src/build.tsx +3 -1
  358. package/src/cli.tsx +99 -48
  359. package/src/compile.tsx +32 -11
  360. package/src/components/actions.tsx +94 -32
  361. package/src/components/detail.tsx +4 -0
  362. package/src/components/dropdown.tsx +47 -14
  363. package/src/components/extension-preferences.tsx +44 -16
  364. package/src/components/form/checkbox.tsx +12 -6
  365. package/src/components/form/date-picker.tsx +12 -6
  366. package/src/components/form/description.tsx +7 -2
  367. package/src/components/form/dropdown.tsx +131 -119
  368. package/src/components/form/file-autocomplete.tsx +90 -108
  369. package/src/components/form/file-picker.tsx +54 -43
  370. package/src/components/form/form-end.tsx +23 -2
  371. package/src/components/form/index.tsx +168 -41
  372. package/src/components/form/password-field.tsx +12 -6
  373. package/src/components/form/text-area.tsx +13 -6
  374. package/src/components/form/text-field.tsx +13 -6
  375. package/src/components/form/types.tsx +6 -0
  376. package/src/components/form/with-left-border.tsx +41 -8
  377. package/src/components/icon.tsx +27 -8
  378. package/src/components/list.tsx +243 -101
  379. package/src/components/loading-bar.tsx +3 -2
  380. package/src/components/loading-text.tsx +79 -0
  381. package/src/descendants.tsx +1 -0
  382. package/src/examples/file-autocomplete.vitest.tsx +130 -125
  383. package/src/examples/form-basic.vitest.tsx +376 -176
  384. package/src/examples/form-dropdown.vitest.tsx +126 -126
  385. package/src/examples/form-scroll.tsx +2 -0
  386. package/src/examples/form-scroll.vitest.tsx +58 -58
  387. package/src/examples/form-tagpicker.vitest.tsx +99 -99
  388. package/src/examples/internal/descendants-filtering.tsx +1 -0
  389. package/src/examples/internal/descendants.tsx +1 -0
  390. package/src/examples/internal/rhf-custom-ref.tsx +2 -0
  391. package/src/examples/internal/scrollbox-demo.tsx +3 -27
  392. package/src/examples/internal/scrollbox-with-descendants.tsx +4 -7
  393. package/src/examples/internal/simple-scrollbox.vitest.tsx +7 -5
  394. package/src/examples/list-detail-metadata.tsx +49 -0
  395. package/src/examples/list-detail-metadata.vitest.tsx +88 -0
  396. package/src/examples/list-dropdown-default.vitest.tsx +51 -51
  397. package/src/examples/list-fetch-data.vitest.tsx +4 -4
  398. package/src/examples/list-scrollbox.vitest.tsx +73 -14
  399. package/src/examples/list-with-detail-long.tsx +70 -0
  400. package/src/examples/list-with-detail.vitest.tsx +191 -85
  401. package/src/examples/list-with-dropdown.vitest.tsx +53 -53
  402. package/src/examples/list-with-sections.tsx +1 -0
  403. package/src/examples/list-with-sections.vitest.tsx +221 -97
  404. package/src/examples/list-with-toast.vitest.tsx +16 -16
  405. package/src/examples/simple-file-picker.vitest.tsx +63 -469
  406. package/src/examples/simple-grid.vitest.tsx +238 -233
  407. package/src/examples/simple-navigation.tsx +15 -7
  408. package/src/examples/simple-navigation.vitest.tsx +130 -219
  409. package/src/examples/store.vitest.tsx +1 -1
  410. package/src/examples/swift-extension.vitest.tsx +148 -0
  411. package/src/examples/synonyms.vitest.tsx +159 -0
  412. package/src/examples/toast-variations.tsx +150 -0
  413. package/src/examples/toast-variations.vitest.tsx +370 -0
  414. package/src/extensions/dev.tsx +74 -7
  415. package/src/extensions/dev.vitest.tsx +102 -34
  416. package/src/extensions/home.tsx +6 -0
  417. package/src/index.tsx +3 -0
  418. package/src/internal/dialog.tsx +43 -30
  419. package/src/internal/navigation.tsx +3 -1
  420. package/src/internal/offscreen.tsx +15 -0
  421. package/src/internal/providers.tsx +4 -2
  422. package/src/internal/scrollbox.tsx +4 -8
  423. package/src/keyboard.test.tsx +69 -0
  424. package/src/release.tsx +32 -38
  425. package/src/state.tsx +7 -0
  426. package/src/swift-loader.tsx +239 -0
  427. package/src/swift-runtime.tsx +36 -0
  428. package/src/utils/file-system.ts +61 -0
  429. package/src/utils/run-command.tsx +82 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termcast",
3
- "version": "1.3.21",
3
+ "version": "1.3.25",
4
4
  "description": "Raycast for the terminal",
5
5
  "repository": "https://github.com/remorses/termcast",
6
6
  "scripts": {
@@ -11,12 +11,12 @@
11
11
  "see-raycast-types": "zed node_modules/@raycast/api/types/index.d.ts",
12
12
  "play": "bun src/cli.tsx",
13
13
  "test": "bun test && bun e2e",
14
- "e2e": "vitest --run"
14
+ "e2e": "vitest -u"
15
15
  },
16
16
  "exports": {
17
17
  ".": {
18
- "development": "./src/index.tsx",
19
- "types": "./src/index.d.ts",
18
+ "bun": "./src/index.tsx",
19
+ "types": "./dist/index.d.ts",
20
20
  "default": "./dist/index.js"
21
21
  },
22
22
  "./src/*": "./src/*.tsx"
@@ -30,18 +30,18 @@
30
30
  "author": "Tommaso De Rossi, morse <beats.by.morse@gmail.com>",
31
31
  "license": "",
32
32
  "dependencies": {
33
- "@opentui/core": "0.1.60",
34
- "@opentui/react": "0.1.60",
33
+ "@opentui/core": "0.1.61",
34
+ "@opentui/react": "0.1.61",
35
+ "@parcel/watcher": "^2.5.1",
35
36
  "@tanstack/react-query": "^5.85.5",
36
37
  "@tanstack/react-query-persist-client": "^5.85.5",
37
38
  "cac": "^6.7.14",
38
39
  "change-case": "^5.4.4",
39
- "cheerio": "^1.1.2",
40
- "chokidar": "^4.0.3",
40
+ "colord": "^2.9.3",
41
41
  "google-auth-library": "^10.3.0",
42
42
  "jszip": "^3.10.1",
43
43
  "nanoid": "^5.1.5",
44
- "node-pty": "^1.0.0",
44
+ "node-diff3": "^3.2.0",
45
45
  "react": "^19.2.0",
46
46
  "react-dom": "^19.2.0",
47
47
  "react-hook-form": "^7.62.0",
@@ -50,13 +50,13 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "tuistory": "workspace:*",
53
- "@types/bun": "^1.2.21",
54
- "@types/node": "^25.0.1",
53
+ "@types/bun": "^1.3.5",
54
+ "@types/node": "^25.0.3",
55
55
  "@raycast/api": "^1.102.5",
56
56
  "@raycast/utils": "^2.2.1",
57
57
  "@xterm/addon-serialize": "^0.13.0",
58
58
  "@xterm/headless": "^5.5.0",
59
59
  "bun-pty": "^0.4.2",
60
- "vitest": "^4.0.15"
60
+ "vitest": "^4.0.16"
61
61
  }
62
62
  }
@@ -0,0 +1,29 @@
1
+ import { logger } from 'termcast/src/logger'
2
+
3
+ export namespace BrowserExtension {
4
+ export interface Tab {
5
+ id: number
6
+ url: string
7
+ active: boolean
8
+ title?: string
9
+ favicon?: string
10
+ }
11
+ }
12
+
13
+ export const BrowserExtension = {
14
+ async getContent(options?: {
15
+ cssSelector?: string
16
+ tabId?: number
17
+ format?: 'html' | 'text' | 'markdown'
18
+ }): Promise<string> {
19
+ logger.log('BrowserExtension.getContent called (stubbed - no extension)')
20
+ // TODO: implement actual browser extension protocol
21
+ return ''
22
+ },
23
+
24
+ async getTabs(): Promise<BrowserExtension.Tab[]> {
25
+ logger.log('BrowserExtension.getTabs called (stubbed - no extension)')
26
+ // TODO: implement actual browser extension protocol
27
+ return []
28
+ },
29
+ }
@@ -1,20 +1,28 @@
1
- import { describe, test, expect, beforeEach, afterAll } from 'bun:test'
1
+ import { describe, test, expect, beforeEach, beforeAll, afterAll } from 'bun:test'
2
2
  import { LocalStorage } from './localstorage'
3
+ import { useStore } from '../state'
3
4
  import * as os from 'os'
4
5
  import * as path from 'path'
5
6
  import * as fs from 'fs'
6
7
 
7
8
  describe('LocalStorage', () => {
9
+ const testExtensionPath = path.join(os.tmpdir(), 'termcast-localstorage-test')
10
+
11
+ beforeAll(() => {
12
+ // Set up extensionPath required by LocalStorage
13
+ useStore.setState({ extensionPath: testExtensionPath })
14
+ })
15
+
8
16
  beforeEach(async () => {
9
17
  await LocalStorage.clear()
10
18
  })
11
19
 
12
20
  afterAll(() => {
13
- // Optional: Clean up test database after all tests
14
- // const dbPath = path.join(os.homedir(), '.termcast.db')
15
- // if (fs.existsSync(dbPath)) {
16
- // fs.unlinkSync(dbPath)
17
- // }
21
+ // Clean up test database after all tests
22
+ const dbDir = path.join(testExtensionPath, '.termcast-bundle')
23
+ if (fs.existsSync(dbDir)) {
24
+ fs.rmSync(dbDir, { recursive: true })
25
+ }
18
26
  })
19
27
 
20
28
  describe('setItem and getItem', () => {
@@ -11,12 +11,13 @@ let currentDbPath: string | null = null
11
11
  function getCurrentDatabasePath(): string {
12
12
  const extensionPath = useStore.getState().extensionPath
13
13
 
14
- if (extensionPath) {
15
- // Use .termcast-bundle directory inside extension path
16
- return path.join(extensionPath, '.termcast-bundle', 'data.db')
17
- } else {
18
- return path.join(os.homedir(), '.termcast', '.termcast-bundle', 'data.db')
14
+ if (!extensionPath) {
15
+ throw new Error(
16
+ 'extensionPath not set - cannot access LocalStorage before extension is initialized',
17
+ )
19
18
  }
19
+ // Use .termcast-bundle directory inside extension path
20
+ return path.join(extensionPath, '.termcast-bundle', 'data.db')
20
21
  }
21
22
 
22
23
  function getDatabase(): Database {
@@ -59,6 +60,8 @@ function getDatabase(): Database {
59
60
  return db
60
61
  }
61
62
 
63
+
64
+
62
65
  export namespace LocalStorage {
63
66
  export type Value = string | number | boolean
64
67
 
@@ -405,6 +405,7 @@ export namespace OAuth {
405
405
 
406
406
  return new Promise((resolve, reject) => {
407
407
  const port = 8989
408
+ let authTimeout: ReturnType<typeof setTimeout>
408
409
 
409
410
  // Create a local server to handle the OAuth callback
410
411
  const server = http.createServer((req, res) => {
@@ -534,6 +535,7 @@ export namespace OAuth {
534
535
  res.end(JSON.stringify({ success: true }))
535
536
 
536
537
  server.close()
538
+ clearTimeout(authTimeout)
537
539
  this.isAuthorizing = false
538
540
 
539
541
  // For implicit flow, save tokens immediately since we won't do token exchange
@@ -570,6 +572,7 @@ export namespace OAuth {
570
572
  })
571
573
  res.end(JSON.stringify({ error: 'parse_error' }))
572
574
  server.close()
575
+ clearTimeout(authTimeout)
573
576
  reject(error)
574
577
  }
575
578
  })
@@ -608,11 +611,12 @@ export namespace OAuth {
608
611
 
609
612
  server.on('error', (error) => {
610
613
  logger.error('OAuth implicit flow server error:', error)
614
+ clearTimeout(authTimeout)
611
615
  reject(error)
612
616
  })
613
617
 
614
618
  // Set a timeout for the authorization
615
- setTimeout(
619
+ authTimeout = setTimeout(
616
620
  () => {
617
621
  server.close()
618
622
  reject(new Error('OAuth authorization timeout'))
@@ -35,47 +35,73 @@ export function getPreferenceValues<
35
35
  return {} as Values
36
36
  }
37
37
 
38
+ // Build defaults from preference definitions
39
+ const defaults: PreferenceValues = {}
40
+
41
+ // Extension-level preference defaults
42
+ const extensionPrefs = extensionPackageJson?.preferences || []
43
+ for (const pref of extensionPrefs) {
44
+ if (pref.default !== undefined) {
45
+ defaults[pref.name] = pref.default
46
+ }
47
+ }
48
+
49
+ // Command-specific preference defaults (override extension defaults)
50
+ if (currentCommandName && extensionPackageJson?.commands) {
51
+ const commandDef = extensionPackageJson.commands.find(
52
+ (cmd) => cmd.name === currentCommandName,
53
+ )
54
+ const commandPrefs = commandDef?.preferences || []
55
+ for (const pref of commandPrefs) {
56
+ if (pref.default !== undefined) {
57
+ defaults[pref.name] = pref.default
58
+ }
59
+ }
60
+ }
61
+
62
+ let extensionSavedValues: PreferenceValues = {}
63
+ let commandSavedValues: PreferenceValues = {}
64
+
38
65
  try {
39
- // First try to load command-specific preferences, then fall back to extension preferences
66
+ // Load extension-level preferences
67
+ const extensionPreferencesKey = `preferences.${extensionName}`
68
+ const extensionPreferences = LocalStorage.getItemSync(extensionPreferencesKey)
69
+
70
+ if (extensionPreferences && typeof extensionPreferences === 'string') {
71
+ try {
72
+ extensionSavedValues = JSON.parse(extensionPreferences)
73
+ logger.log(
74
+ `Loaded extension preferences for ${extensionName}:`,
75
+ extensionSavedValues,
76
+ )
77
+ } catch (parseError) {
78
+ logger.error(`Failed to parse extension preferences:`, parseError)
79
+ }
80
+ }
81
+
82
+ // Load command-specific preferences
40
83
  if (currentCommandName) {
41
84
  const commandPreferencesKey = `preferences.${extensionName}.${currentCommandName}`
42
85
  const commandPreferences = LocalStorage.getItemSync(commandPreferencesKey)
43
86
 
44
87
  if (commandPreferences && typeof commandPreferences === 'string') {
45
88
  try {
46
- const parsed = JSON.parse(commandPreferences)
89
+ commandSavedValues = JSON.parse(commandPreferences)
47
90
  logger.log(
48
91
  `Loaded command preferences for ${extensionName}/${currentCommandName}:`,
49
- parsed,
92
+ commandSavedValues,
50
93
  )
51
- return parsed as Values
52
94
  } catch (parseError) {
53
95
  logger.error(`Failed to parse command preferences:`, parseError)
54
96
  }
55
97
  }
56
98
  }
57
-
58
- // Fall back to extension-level preferences
59
- const extensionPreferencesKey = `preferences.${extensionName}`
60
- const extensionPreferences = LocalStorage.getItemSync(
61
- extensionPreferencesKey,
62
- )
63
-
64
- if (extensionPreferences && typeof extensionPreferences === 'string') {
65
- try {
66
- const parsed = JSON.parse(extensionPreferences)
67
- logger.log(`Loaded extension preferences for ${extensionName}:`, parsed)
68
- return parsed as Values
69
- } catch (parseError) {
70
- logger.error(`Failed to parse extension preferences:`, parseError)
71
- }
72
- }
73
99
  } catch (error) {
74
100
  logger.error(`Failed to load preferences for ${extensionName}:`, error)
75
101
  }
76
102
 
77
- // Return empty preferences if none saved
78
- return {} as Values
103
+ // Merge: defaults < extension saved < command saved
104
+ return { ...defaults, ...extensionSavedValues, ...commandSavedValues } as Values
79
105
  }
80
106
 
81
107
  /**
@@ -1,7 +1,6 @@
1
1
  import React, { useEffect, useState } from 'react'
2
2
  import { Theme } from 'termcast/src/theme'
3
3
  import { TextAttributes } from '@opentui/core'
4
- import { logger } from 'termcast/src/logger'
5
4
  import { useStore } from 'termcast/src/state'
6
5
  import { useKeyboard, useTerminalDimensions } from '@opentui/react'
7
6
  import { useIsInFocus } from 'termcast/src/internal/focus-context'
@@ -121,14 +120,13 @@ export class Toast {
121
120
  }
122
121
  }
123
122
 
124
- interface ToastContentProps {
123
+ export interface ToastContentProps {
125
124
  toast: Toast
126
125
  onHide: () => void
127
126
  }
128
127
 
129
- function ToastContent({ toast, onHide }: ToastContentProps): any {
128
+ export function ToastContent({ toast, onHide }: ToastContentProps): any {
130
129
  const [, forceUpdate] = useState(0)
131
- const dimensions = useTerminalDimensions()
132
130
  const inFocus = useIsInFocus()
133
131
 
134
132
  useEffect(() => {
@@ -203,78 +201,55 @@ function ToastContent({ toast, onHide }: ToastContentProps): any {
203
201
  const icon =
204
202
  toast.style === Toast.Style.Animated ? getIcon()[animationFrame] : getIcon()
205
203
 
206
- const wrapText = (text: string, maxWidth: number): string[] => {
207
- if (!text) return []
208
-
209
- const words = text.split(' ')
210
- const lines: string[] = []
211
- let currentLine = ''
212
-
213
- for (const word of words) {
214
- const testLine = currentLine ? `${currentLine} ${word}` : word
215
- if (testLine.length <= maxWidth) {
216
- currentLine = testLine
217
- } else {
218
- if (currentLine) {
219
- lines.push(currentLine)
220
- }
221
- currentLine = word
222
- }
223
- }
224
-
225
- if (currentLine) {
226
- lines.push(currentLine)
227
- }
228
-
229
- return lines.slice(0, 3)
230
- }
231
-
232
- const iconLength = 2
233
- const titleLength = toast.title.length
234
- const actionsLength = (() => {
235
- let length = 0
236
- if (toast.primaryAction) {
237
- length += toast.primaryAction.title.length + 4
238
- }
239
- if (toast.secondaryAction) {
240
- length += toast.secondaryAction.title.length + 4
241
- }
242
- return length
243
- })()
244
-
245
- const availableWidth =
246
- dimensions.width - iconLength - titleLength - actionsLength - 8
247
- const messageLines = toast.message
248
- ? wrapText(toast.message, Math.max(20, availableWidth))
249
- : []
250
-
251
204
  return (
252
205
  <box
253
206
  borderColor={Theme.border}
207
+ backgroundColor={Theme.background}
254
208
  paddingLeft={1}
255
209
  paddingRight={1}
256
210
  flexDirection='column'
257
211
  >
258
212
  <box flexDirection='row' alignItems='center'>
259
- <text fg={getIconColor()}>{icon} </text>
260
- <text fg={Theme.text} attributes={TextAttributes.BOLD}>
213
+ <text flexShrink={0} fg={getIconColor()}>
214
+ {icon}{' '}
215
+ </text>
216
+ <text flexShrink={0} fg={Theme.text} attributes={TextAttributes.BOLD}>
261
217
  {toast.title}
262
218
  </text>
263
- {messageLines.length > 0 && (
264
- <text fg={Theme.textMuted}> - {messageLines[0]}</text>
265
- )}
266
219
  {toast.primaryAction && (
267
- <text fg={Theme.primary}> [{toast.primaryAction.title} ↵]</text>
220
+ <box
221
+ flexShrink={0}
222
+ onMouseDown={() => {
223
+ toast.primaryAction?.onAction(toast)
224
+ }}
225
+ >
226
+ <text fg={Theme.primary}>
227
+ {' '}
228
+ [{toast.primaryAction.title} ↵]
229
+ </text>
230
+ </box>
268
231
  )}
269
232
  {toast.secondaryAction && (
270
- <text fg={Theme.textMuted}> [{toast.secondaryAction.title} ⇥]</text>
233
+ <box
234
+ flexShrink={0}
235
+ onMouseDown={() => {
236
+ toast.secondaryAction?.onAction(toast)
237
+ }}
238
+ >
239
+ <text fg={Theme.textMuted}>
240
+ {' '}
241
+ [{toast.secondaryAction.title} ⇥]
242
+ </text>
243
+ </box>
271
244
  )}
272
245
  </box>
273
- {messageLines.slice(1).map((line, index) => (
274
- <box key={index} paddingLeft={iconLength + titleLength + 3}>
275
- <text fg={Theme.textMuted}>{line}</text>
246
+ {toast.message && (
247
+ <box paddingLeft={2}>
248
+ <text flexShrink={0} fg={Theme.textMuted}>
249
+ {toast.message}
250
+ </text>
276
251
  </box>
277
- ))}
252
+ )}
278
253
  </box>
279
254
  )
280
255
  }
@@ -291,9 +266,9 @@ export function ToastOverlay(): any {
291
266
  <box
292
267
  position='absolute'
293
268
  left={0}
294
- top={dimensions.height - 3}
269
+ bottom={0}
295
270
  width={dimensions.width}
296
- height={3}
271
+ maxHeight={10}
297
272
  justifyContent='flex-end'
298
273
  alignItems='center'
299
274
  >
@@ -69,6 +69,58 @@ describe('buildExtensionCommands', () => {
69
69
  "filePath": "/BASE_PATH/fixtures/simple-extension/src/show-state.tsx",
70
70
  "exists": true,
71
71
  "bundledPath": "/BASE_PATH/fixtures/simple-extension/.termcast-bundle/show-state.js"
72
+ },
73
+ {
74
+ "name": "with-arguments",
75
+ "title": "With Arguments",
76
+ "subtitle": "Command with arguments",
77
+ "description": "Demonstrates command arguments (text, password, dropdown)",
78
+ "mode": "view",
79
+ "arguments": [
80
+ {
81
+ "name": "query",
82
+ "type": "text",
83
+ "placeholder": "Search query",
84
+ "required": true
85
+ },
86
+ {
87
+ "name": "secretKey",
88
+ "type": "password",
89
+ "placeholder": "Secret key"
90
+ },
91
+ {
92
+ "name": "category",
93
+ "type": "dropdown",
94
+ "placeholder": "Category",
95
+ "data": [
96
+ {
97
+ "title": "Work",
98
+ "value": "work"
99
+ },
100
+ {
101
+ "title": "Personal",
102
+ "value": "personal"
103
+ },
104
+ {
105
+ "title": "Other",
106
+ "value": "other"
107
+ }
108
+ ]
109
+ }
110
+ ],
111
+ "filePath": "/BASE_PATH/fixtures/simple-extension/src/with-arguments.tsx",
112
+ "exists": true,
113
+ "bundledPath": "/BASE_PATH/fixtures/simple-extension/.termcast-bundle/with-arguments.js"
114
+ },
115
+ {
116
+ "name": "quick-action",
117
+ "title": "Quick Action",
118
+ "subtitle": "No-view command",
119
+ "description": "Copies current timestamp to clipboard without showing a view",
120
+ "mode": "no-view",
121
+ "filePath": "/BASE_PATH/fixtures/simple-extension/src/quick-action.tsx",
122
+ "exists": true,
123
+ "bundledPath": "/BASE_PATH/fixtures/simple-extension/.termcast-bundle/quick-action.js"
72
124
  }
73
125
  ],
74
126
  "bundleDir": "/BASE_PATH/fixtures/simple-extension/.termcast-bundle"
package/src/build.tsx CHANGED
@@ -8,6 +8,7 @@ import * as termcastApi from './index'
8
8
  import * as opentuiReact from '@opentui/react'
9
9
  import * as opentuiCore from '@opentui/core'
10
10
  import * as react from 'react'
11
+ import { swiftLoaderPlugin } from './swift-loader'
11
12
 
12
13
  const GLOBALS_NAMESPACE = 'globals'
13
14
  const VIRTUAL_ENTRY_NAMESPACE = 'virtual-entry'
@@ -203,6 +204,7 @@ export async function buildExtensionCommands({
203
204
  if (!fs.existsSync(bundleDir)) {
204
205
  fs.mkdirSync(bundleDir, { recursive: true })
205
206
  }
207
+ fs.writeFileSync(path.join(bundleDir, '.gitignore'), '*\n')
206
208
 
207
209
  const commandsData = getCommandsWithFiles({
208
210
  packageJsonPath: path.join(resolvedPath, 'package.json'),
@@ -225,7 +227,7 @@ export async function buildExtensionCommands({
225
227
  target: target || (format === 'cjs' ? 'node' : 'bun'),
226
228
  format,
227
229
  // external: [],
228
- plugins: [aliasPlugin],
230
+ plugins: [aliasPlugin, swiftLoaderPlugin],
229
231
  naming: '[name].js',
230
232
  throw: false,
231
233
  })