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
@@ -0,0 +1,239 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import { spawn } from 'node:child_process'
4
+ import type { BunPlugin } from 'bun'
5
+ import { logger } from './logger'
6
+
7
+ const SWIFT_NAMESPACE = 'swift-loader'
8
+
9
+ interface SwiftBuildCache {
10
+ [swiftPath: string]: {
11
+ result: SwiftBuildResult
12
+ buildTime: number
13
+ }
14
+ }
15
+
16
+ const buildCache: SwiftBuildCache = {}
17
+
18
+ async function buildSwiftPackage(swiftPath: string): Promise<SwiftBuildResult> {
19
+ logger.log(`Swift: building package at ${swiftPath}`)
20
+
21
+ // Check if already built and cached in memory
22
+ const cached = buildCache[swiftPath]
23
+ if (cached && fs.existsSync(cached.result.binaryPath)) {
24
+ logger.log(`Swift: using cached build at ${cached.result.binaryPath}`)
25
+ return cached.result
26
+ }
27
+
28
+ // Check if binary already exists on disk (from previous build/process)
29
+ try {
30
+ const existingResult = await findSwiftBuildResult(swiftPath)
31
+ logger.log(`Swift: found existing binary at ${existingResult.binaryPath}`)
32
+ buildCache[swiftPath] = { result: existingResult, buildTime: Date.now() }
33
+ return existingResult
34
+ } catch {
35
+ // Binary doesn't exist, need to build
36
+ }
37
+
38
+ // Run swift build using Node's spawn
39
+ // Use debug build for faster compilation (skips optimizations)
40
+ logger.log(`Swift: running swift build -c debug in ${swiftPath}`)
41
+ const exitCode = await new Promise<number>((resolve, reject) => {
42
+ const proc = spawn('swift', ['build', '-c', 'debug'], {
43
+ cwd: swiftPath,
44
+ stdio: 'inherit',
45
+ })
46
+ proc.on('error', reject)
47
+ proc.on('close', (code) => resolve(code ?? 1))
48
+ })
49
+ logger.log(`Swift: build exited with code ${exitCode}`)
50
+
51
+ if (exitCode !== 0) {
52
+ throw new Error(`Swift build failed with exit code ${exitCode}`)
53
+ }
54
+ logger.log(`Swift: build completed successfully`)
55
+
56
+ // Find the binary and generated files
57
+ const result = await findSwiftBuildResult(swiftPath)
58
+
59
+ // Cache the result
60
+ buildCache[swiftPath] = {
61
+ result,
62
+ buildTime: Date.now(),
63
+ }
64
+
65
+ logger.log(`Swift: built binary at ${result.binaryPath}`)
66
+ return result
67
+ }
68
+
69
+ interface SwiftBuildResult {
70
+ binaryPath: string
71
+ raycastJsPath: string
72
+ packageName: string
73
+ }
74
+
75
+ function findFilesRecursively(dir: string, filename: string): string[] {
76
+ const results: string[] = []
77
+
78
+ if (!fs.existsSync(dir)) {
79
+ return results
80
+ }
81
+
82
+ const entries = fs.readdirSync(dir, { withFileTypes: true })
83
+ for (const entry of entries) {
84
+ const fullPath = path.join(dir, entry.name)
85
+ if (entry.isDirectory()) {
86
+ results.push(...findFilesRecursively(fullPath, filename))
87
+ } else if (entry.name === filename) {
88
+ results.push(fullPath)
89
+ }
90
+ }
91
+ return results
92
+ }
93
+
94
+ async function findSwiftBuildResult(swiftPath: string): Promise<SwiftBuildResult> {
95
+ // Parse Package.swift to find executable target name
96
+ const packageSwiftPath = path.join(swiftPath, 'Package.swift')
97
+ const packageSwift = fs.readFileSync(packageSwiftPath, 'utf-8')
98
+
99
+ // Look for: name: "PackageName" at the top level
100
+ const nameMatch = packageSwift.match(/name:\s*"([^"]+)"/)
101
+ if (!nameMatch) {
102
+ throw new Error(`Could not find package name in ${packageSwiftPath}`)
103
+ }
104
+
105
+ const packageName = nameMatch[1]
106
+
107
+ // Find binary - check debug first, then release
108
+ const debugBinaryPath = path.join(swiftPath, '.build', 'debug', packageName)
109
+ const releaseBinaryPath = path.join(swiftPath, '.build', 'release', packageName)
110
+
111
+ let binaryPath: string
112
+ if (fs.existsSync(debugBinaryPath)) {
113
+ binaryPath = debugBinaryPath
114
+ } else if (fs.existsSync(releaseBinaryPath)) {
115
+ binaryPath = releaseBinaryPath
116
+ } else {
117
+ throw new Error(`Swift binary not found at ${debugBinaryPath} or ${releaseBinaryPath}`)
118
+ }
119
+
120
+ // Find raycast.js using glob-like search
121
+ const buildDir = path.join(swiftPath, '.build')
122
+ const raycastJsFiles = findFilesRecursively(buildDir, 'raycast.js')
123
+
124
+ // Filter to find the one from RaycastTypeScriptPlugin for our package
125
+ const matchingFiles = raycastJsFiles.filter(f =>
126
+ f.includes('RaycastTypeScriptPlugin') && f.includes(packageName)
127
+ )
128
+
129
+ if (matchingFiles.length === 0) {
130
+ throw new Error(`Generated raycast.js not found in ${buildDir}. Found files: ${raycastJsFiles.join(', ') || 'none'}`)
131
+ }
132
+
133
+ // Prefer the one in plugins/outputs (not index-build)
134
+ const raycastJsPath = matchingFiles.find(f => f.includes('plugins/outputs')) || matchingFiles[0]
135
+
136
+ logger.log(`Swift: found raycast.js at ${raycastJsPath}`)
137
+ return { binaryPath, raycastJsPath, packageName }
138
+ }
139
+
140
+ function generateSwiftModule(result: SwiftBuildResult): string {
141
+ // Read the generated raycast.js from RaycastTypeScriptPlugin
142
+ // This file exports named functions that call runSwiftFunction(functionName, ...args)
143
+ // We prepend our runSwiftFunction implementation with the binary path
144
+ const generatedJs = fs.readFileSync(result.raycastJsPath, 'utf-8')
145
+
146
+ // Prepend our runSwiftFunction implementation using Node's child_process
147
+ // Use ESM import to match the export statements in generated raycast.js
148
+ const runtime = `
149
+ import { spawn as _spawn } from 'node:child_process';
150
+
151
+ const BINARY_PATH = ${JSON.stringify(result.binaryPath)};
152
+
153
+ function runSwiftFunction(functionName, ...args) {
154
+ return new Promise((resolve, reject) => {
155
+ const jsonArgs = args.map((arg) => JSON.stringify(arg));
156
+ const proc = _spawn(BINARY_PATH, [functionName, ...jsonArgs], {
157
+ stdio: ['pipe', 'pipe', 'inherit'],
158
+ });
159
+
160
+ let stdout = '';
161
+ proc.stdout.on('data', (data) => {
162
+ stdout += data.toString();
163
+ });
164
+
165
+ proc.on('error', (err) => {
166
+ reject(new Error('Swift function "' + functionName + '" failed to spawn: ' + err.message));
167
+ });
168
+
169
+ proc.on('close', (exitCode) => {
170
+ if (exitCode !== 0) {
171
+ reject(new Error('Swift function "' + functionName + '" failed with exit code ' + exitCode));
172
+ return;
173
+ }
174
+
175
+ const trimmed = stdout.trim();
176
+ if (!trimmed) {
177
+ resolve(undefined);
178
+ return;
179
+ }
180
+
181
+ try {
182
+ resolve(JSON.parse(trimmed));
183
+ } catch {
184
+ reject(new Error('Swift function "' + functionName + '" returned invalid JSON: ' + trimmed));
185
+ }
186
+ });
187
+ });
188
+ }
189
+
190
+ `
191
+
192
+ return runtime + generatedJs
193
+ }
194
+
195
+ export const swiftLoaderPlugin: BunPlugin = {
196
+ name: 'swift-loader',
197
+ async setup(build) {
198
+ // Resolve swift: imports
199
+ build.onResolve({ filter: /^swift:/ }, (args) => {
200
+ logger.log(`Swift: onResolve called for ${args.path} from ${args.importer}`)
201
+
202
+ // Extract the path after "swift:"
203
+ const swiftRelativePath = args.path.slice(6) // Remove "swift:"
204
+
205
+ // Resolve relative to the importer's directory
206
+ const importerDir = args.importer ? path.dirname(args.importer) : process.cwd()
207
+ const resolvedSwiftPath = path.resolve(importerDir, swiftRelativePath)
208
+
209
+ logger.log(`Swift: resolved to ${resolvedSwiftPath}`)
210
+
211
+ return {
212
+ path: resolvedSwiftPath,
213
+ namespace: SWIFT_NAMESPACE,
214
+ }
215
+ })
216
+
217
+ // Load swift packages
218
+ build.onLoad({ filter: /.*/, namespace: SWIFT_NAMESPACE }, async (args) => {
219
+ logger.log(`Swift: onLoad called for ${args.path}`)
220
+ const swiftPath = args.path
221
+
222
+ // Build the Swift package and get paths to binary + generated JS
223
+ logger.log(`Swift: calling buildSwiftPackage...`)
224
+ const result = await buildSwiftPackage(swiftPath)
225
+ logger.log(`Swift: buildSwiftPackage returned, binaryPath=${result.binaryPath}`)
226
+
227
+ // Generate module by combining runtime with generated raycast.js
228
+ logger.log(`Swift: generating module...`)
229
+ const contents = generateSwiftModule(result)
230
+ logger.log(`Swift: module generated, length=${contents.length}`)
231
+ // logger.log(`Swift: module contents:\n${contents}`)
232
+
233
+ return {
234
+ contents,
235
+ loader: 'js',
236
+ }
237
+ })
238
+ },
239
+ }
@@ -0,0 +1,36 @@
1
+ import { logger } from './logger'
2
+
3
+ export async function runSwiftFunction(
4
+ binaryPath: string,
5
+ functionName: string,
6
+ ...args: unknown[]
7
+ ): Promise<unknown> {
8
+ const jsonArgs = args.map((arg) => JSON.stringify(arg))
9
+
10
+ logger.log(`Swift: calling ${functionName} with args:`, jsonArgs)
11
+
12
+ const proc = Bun.spawn([binaryPath, functionName, ...jsonArgs], {
13
+ stdout: 'pipe',
14
+ stderr: 'inherit',
15
+ })
16
+
17
+ const [stdout, exitCode] = await Promise.all([
18
+ new Response(proc.stdout).text(),
19
+ proc.exited,
20
+ ])
21
+
22
+ if (exitCode !== 0) {
23
+ throw new Error(`Swift function "${functionName}" failed with exit code ${exitCode}`)
24
+ }
25
+
26
+ const trimmed = stdout.trim()
27
+ if (!trimmed) {
28
+ return undefined
29
+ }
30
+
31
+ try {
32
+ return JSON.parse(trimmed)
33
+ } catch {
34
+ throw new Error(`Swift function "${functionName}" returned invalid JSON: ${trimmed}`)
35
+ }
36
+ }
@@ -8,6 +8,67 @@ export interface FileSystemItem {
8
8
  isDirectory: boolean
9
9
  }
10
10
 
11
+ /**
12
+ * Recursively list all files in a directory (up to maxDepth levels)
13
+ */
14
+ export async function listAllFiles({
15
+ basePath = '.',
16
+ maxDepth = 3,
17
+ maxFiles = 1000,
18
+ includeDirectories = true,
19
+ }: {
20
+ basePath?: string
21
+ maxDepth?: number
22
+ maxFiles?: number
23
+ includeDirectories?: boolean
24
+ } = {}): Promise<string[]> {
25
+ const results: string[] = []
26
+
27
+ // Resolve ~ to home directory
28
+ if (basePath.startsWith('~')) {
29
+ basePath = basePath.replace('~', os.homedir())
30
+ }
31
+
32
+ const resolvedBase = path.isAbsolute(basePath)
33
+ ? basePath
34
+ : path.resolve(process.cwd(), basePath)
35
+
36
+ async function walk(dir: string, depth: number) {
37
+ if (depth > maxDepth || results.length >= maxFiles) return
38
+
39
+ try {
40
+ const entries = await fs.readdir(dir, { withFileTypes: true })
41
+
42
+ for (const entry of entries) {
43
+ if (results.length >= maxFiles) break
44
+
45
+ // Skip hidden files and common ignored directories
46
+ if (entry.name.startsWith('.')) continue
47
+ if (entry.name === 'node_modules') continue
48
+ if (entry.name === 'dist') continue
49
+ if (entry.name === 'build') continue
50
+
51
+ const fullPath = path.join(dir, entry.name)
52
+ const relativePath = path.relative(resolvedBase, fullPath)
53
+
54
+ if (entry.isDirectory()) {
55
+ if (includeDirectories) {
56
+ results.push(relativePath + '/')
57
+ }
58
+ await walk(fullPath, depth + 1)
59
+ } else {
60
+ results.push(relativePath)
61
+ }
62
+ }
63
+ } catch {
64
+ // Ignore permission errors etc
65
+ }
66
+ }
67
+
68
+ await walk(resolvedBase, 0)
69
+ return results.sort()
70
+ }
71
+
11
72
  export async function searchFiles(
12
73
  searchPath: string,
13
74
  prefix: string,
@@ -1,4 +1,5 @@
1
1
  import React from 'react'
2
+ import { cac } from 'cac'
2
3
  import { useStore } from 'termcast/src/state'
3
4
  import { showToast, Toast } from 'termcast/src/apis/toast'
4
5
  import { LocalStorage } from 'termcast/src/apis/localstorage'
@@ -6,6 +7,82 @@ import { CommandArguments } from 'termcast/src/components/command-arguments'
6
7
  import { ExtensionPreferences } from 'termcast/src/components/extension-preferences'
7
8
  import type { RaycastArgument, RaycastPackageJson } from 'termcast/src/package-json'
8
9
  import type { LaunchProps } from 'termcast/src/apis/environment'
10
+ import { logger } from '../logger'
11
+
12
+ export interface CommandInfo {
13
+ name: string
14
+ title: string
15
+ description?: string
16
+ }
17
+
18
+ export interface ParsedExtensionArgs {
19
+ commandName?: string
20
+ showHelp: boolean
21
+ showVersion: boolean
22
+ }
23
+
24
+ /**
25
+ * Parse CLI args to extract command name and help flag.
26
+ * @param skipArgv - Number of subcommand args to skip (e.g. 1 for "dev" in "termcast dev")
27
+ */
28
+ export function parseExtensionArgs({ skipArgv = 0 }: { skipArgv?: number } = {}): ParsedExtensionArgs {
29
+ // Build argv for cac: keep first 2 (binary + script), skip subcommand args, keep the rest
30
+ const argv = [
31
+ process.argv[0],
32
+ process.argv[1],
33
+ ...process.argv.slice(2 + skipArgv),
34
+ ]
35
+ const parsed = cac().parse(argv, { run: false })
36
+ return {
37
+ commandName: parsed.args[0] as string | undefined,
38
+ showHelp: Boolean(parsed.options.help || parsed.options.h),
39
+ showVersion: Boolean(parsed.options.version || parsed.options.v),
40
+ }
41
+ }
42
+
43
+ function printExtensionHelp({
44
+ extensionName,
45
+ commands,
46
+ }: {
47
+ extensionName: string
48
+ commands: CommandInfo[]
49
+ }): void {
50
+ console.log(`\n${extensionName}\n`)
51
+ console.log('Usage: <binary> [command]\n')
52
+ console.log('Commands:')
53
+ for (const cmd of commands) {
54
+ const desc = cmd.description ? ` ${cmd.description}` : ''
55
+ console.log(` ${cmd.name.padEnd(20)} ${cmd.title}${desc}`)
56
+ }
57
+ console.log('\nOptions:')
58
+ console.log(' --help, -h Show this help message')
59
+ console.log(' --version, -v Show version')
60
+ console.log()
61
+ }
62
+
63
+ /**
64
+ * Check for --help and --version flags. Call before rendering.
65
+ * Exits process if help or version is shown.
66
+ */
67
+ export function handleHelpFlag({
68
+ extensionName,
69
+ commands,
70
+ skipArgv = 0,
71
+ }: {
72
+ extensionName: string
73
+ commands: CommandInfo[]
74
+ skipArgv?: number
75
+ }): void {
76
+ const { showHelp, showVersion } = parseExtensionArgs({ skipArgv })
77
+ if (showVersion) {
78
+ console.log(process.env.VERSION || 'unknown')
79
+ process.exit(0)
80
+ }
81
+ if (showHelp) {
82
+ printExtensionHelp({ extensionName, commands })
83
+ process.exit(0)
84
+ }
85
+ }
9
86
 
10
87
  export interface RunnableCommand {
11
88
  name: string
@@ -22,8 +99,6 @@ export interface RunCommandOptions {
22
99
  bundledPath?: string
23
100
  Component?: (props: LaunchProps) => any
24
101
  push: (element: React.ReactNode) => void
25
- // For dev mode, adds cache busting query param
26
- cacheBustParam?: string
27
102
  }
28
103
 
29
104
  export async function runCommand(options: RunCommandOptions): Promise<void> {
@@ -34,7 +109,6 @@ export async function runCommand(options: RunCommandOptions): Promise<void> {
34
109
  bundledPath,
35
110
  Component: BuiltInComponent,
36
111
  push,
37
- cacheBustParam,
38
112
  } = options
39
113
 
40
114
  // Check if command has required preferences that are missing
@@ -92,9 +166,11 @@ export async function runCommand(options: RunCommandOptions): Promise<void> {
92
166
  if (BuiltInComponent) {
93
167
  CommandComponent = BuiltInComponent
94
168
  } else if (bundledPath) {
95
- const importPath = cacheBustParam
96
- ? `${bundledPath}?rebuild=${cacheBustParam}`
97
- : bundledPath
169
+ const state = useStore.getState()
170
+ const devRebuildCount = state.devRebuildCount + 1
171
+ useStore.setState({ devRebuildCount })
172
+ const importPath = `${bundledPath}?rebuild=${devRebuildCount}`
173
+ // logger.log(`importing ${importPath}`)
98
174
  const module = await import(importPath)
99
175
  CommandComponent = module.default
100
176