@zaly/tui 0.0.12 → 0.1.0

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 (250) hide show
  1. package/assets/schemas/shiki-language.schema.json +352 -0
  2. package/assets/schemas/shiki-theme.schema.json +71 -0
  3. package/assets/schemas/theme.schema.json +226 -1046
  4. package/assets/themes/andromeeda.json +97 -0
  5. package/assets/themes/ayu-dark.json +31 -25
  6. package/assets/themes/ayu-light.json +106 -0
  7. package/assets/themes/ayu-mirage.json +106 -0
  8. package/assets/themes/catppuccin-frappe.json +43 -40
  9. package/assets/themes/catppuccin-latte.json +43 -40
  10. package/assets/themes/catppuccin-macchiato.json +43 -40
  11. package/assets/themes/catppuccin-mocha.json +43 -40
  12. package/assets/themes/dark-plus.json +99 -0
  13. package/assets/themes/dracula.json +47 -47
  14. package/assets/themes/everforest-dark.json +28 -26
  15. package/assets/themes/everforest-light.json +28 -26
  16. package/assets/themes/github-dark-default.json +107 -0
  17. package/assets/themes/github-dark-dimmed.json +107 -0
  18. package/assets/themes/github-light-default.json +107 -0
  19. package/assets/themes/gruvbox-dark-hard.json +98 -0
  20. package/assets/themes/gruvbox-dark-medium.json +34 -29
  21. package/assets/themes/gruvbox-light-medium.json +98 -0
  22. package/assets/themes/horizon-bright.json +101 -0
  23. package/assets/themes/horizon.json +101 -0
  24. package/assets/themes/iterm2/LICENSE +25 -0
  25. package/assets/themes/iterm2/README.md +28 -0
  26. package/assets/themes/iterm2/catppuccin-latte.json +140 -0
  27. package/assets/themes/iterm2/catppuccin-mocha.json +140 -0
  28. package/assets/themes/iterm2/github-dark.json +140 -0
  29. package/assets/themes/iterm2/github.json +140 -0
  30. package/assets/themes/iterm2/gruvbox-dark.json +140 -0
  31. package/assets/themes/iterm2/gruvbox-light.json +140 -0
  32. package/assets/themes/iterm2/nord.json +140 -0
  33. package/assets/themes/iterm2/tokyonight-day.json +140 -0
  34. package/assets/themes/iterm2/tokyonight-moon.json +140 -0
  35. package/assets/themes/kanagawa-dragon.json +55 -49
  36. package/assets/themes/kanagawa-lotus.json +105 -0
  37. package/assets/themes/kanagawa-wave.json +56 -50
  38. package/assets/themes/light-plus.json +99 -0
  39. package/assets/themes/material-theme-lighter.json +102 -0
  40. package/assets/themes/material-theme-palenight.json +52 -45
  41. package/assets/themes/material-theme.json +102 -0
  42. package/assets/themes/min-dark.json +69 -14
  43. package/assets/themes/min-light.json +68 -17
  44. package/assets/themes/monokai.json +54 -47
  45. package/assets/themes/night-owl-light.json +105 -0
  46. package/assets/themes/night-owl.json +57 -49
  47. package/assets/themes/nord.json +53 -39
  48. package/assets/themes/one-dark-pro.json +46 -38
  49. package/assets/themes/one-light.json +52 -41
  50. package/assets/themes/poimandres.json +51 -49
  51. package/assets/themes/rose-pine-dawn.json +99 -0
  52. package/assets/themes/rose-pine-moon.json +99 -0
  53. package/assets/themes/rose-pine.json +50 -33
  54. package/assets/themes/solarized-dark.json +38 -31
  55. package/assets/themes/solarized-light.json +40 -33
  56. package/assets/themes/synthwave-84.json +47 -30
  57. package/assets/themes/tokyonight-day.json +3 -3
  58. package/assets/themes/tokyonight-moon.json +3 -2
  59. package/assets/themes/tokyonight-night.json +3 -2
  60. package/assets/themes/tokyonight-storm.json +3 -2
  61. package/assets/themes/vesper.json +50 -42
  62. package/assets/themes/vitesse-black.json +103 -0
  63. package/assets/themes/vitesse-dark.json +26 -30
  64. package/assets/themes/vitesse-light.json +26 -30
  65. package/dist/{actions-Dc4D4uSf.d.mts → actions--ODlgCQ5.d.mts} +4 -4
  66. package/dist/{actions-Dc4D4uSf.d.mts.map → actions--ODlgCQ5.d.mts.map} +1 -1
  67. package/dist/{ansi-DZlXaItJ.mjs → ansi-CMv71xVr.mjs} +3 -31
  68. package/dist/ansi-CMv71xVr.mjs.map +1 -0
  69. package/dist/ansi.d.mts +1 -1
  70. package/dist/ansi.mjs +1 -1
  71. package/dist/{autocomplete-StW1QJZJ.d.mts → autocomplete-CD30kSe_.d.mts} +4 -4
  72. package/dist/{autocomplete-StW1QJZJ.d.mts.map → autocomplete-CD30kSe_.d.mts.map} +1 -1
  73. package/dist/{box-BkP4MF82.mjs → box-C_N_7ChP.mjs} +2 -2
  74. package/dist/{box-BkP4MF82.mjs.map → box-C_N_7ChP.mjs.map} +1 -1
  75. package/dist/builder-Chwtk0nQ.mjs +196 -0
  76. package/dist/builder-Chwtk0nQ.mjs.map +1 -0
  77. package/dist/{callbacks-BwWTCqPJ.mjs → callbacks-DLecWn7G.mjs} +4 -4
  78. package/dist/{callbacks-BwWTCqPJ.mjs.map → callbacks-DLecWn7G.mjs.map} +1 -1
  79. package/dist/client-CNGt-dOt.mjs +1 -0
  80. package/dist/{client-C2GXKfJ1.mjs → client-D7qz4TZt.mjs} +7 -3
  81. package/dist/client-D7qz4TZt.mjs.map +1 -0
  82. package/dist/color-DBMQLv4Y.mjs +37 -0
  83. package/dist/color-DBMQLv4Y.mjs.map +1 -0
  84. package/dist/{ctx-B7BmPUCD.mjs → ctx-BaQ2hP5u.mjs} +3 -3
  85. package/dist/{ctx-B7BmPUCD.mjs.map → ctx-BaQ2hP5u.mjs.map} +1 -1
  86. package/dist/ctx-CndlTp1T.mjs +1 -0
  87. package/dist/{divider-TSx9NhI_.mjs → divider-BlNNN2OS.mjs} +2 -2
  88. package/dist/{divider-TSx9NhI_.mjs.map → divider-BlNNN2OS.mjs.map} +1 -1
  89. package/dist/{files-7DUYSeNc.d.mts → files-B_5HDBPp.d.mts} +3 -3
  90. package/dist/{files-7DUYSeNc.d.mts.map → files-B_5HDBPp.d.mts.map} +1 -1
  91. package/dist/{github-C1KfXk98.d.mts → github-CyRwUQ3y.d.mts} +3 -3
  92. package/dist/{github-C1KfXk98.d.mts.map → github-CyRwUQ3y.d.mts.map} +1 -1
  93. package/dist/{image-VaT7AN-S.d.mts → image-BLls2F4t.d.mts} +2 -2
  94. package/dist/{image-VaT7AN-S.d.mts.map → image-BLls2F4t.d.mts.map} +1 -1
  95. package/dist/image-Cqtj3yRA.mjs +178 -0
  96. package/dist/image-Cqtj3yRA.mjs.map +1 -0
  97. package/dist/image.d.mts +1 -1
  98. package/dist/index.d.mts +13 -4
  99. package/dist/index.d.mts.map +1 -1
  100. package/dist/index.mjs +8 -7
  101. package/dist/index.mjs.map +1 -1
  102. package/dist/{input-BGTTujDN.mjs → input-ET2YEMcl.mjs} +2 -2
  103. package/dist/{input-BGTTujDN.mjs.map → input-ET2YEMcl.mjs.map} +1 -1
  104. package/dist/{input-BAYux7qo.d.mts → input-NuD8TH8N.d.mts} +3 -3
  105. package/dist/{input-BAYux7qo.d.mts.map → input-NuD8TH8N.d.mts.map} +1 -1
  106. package/dist/{inspect-CfNydMgO.d.mts → inspect-B1uXxdKC.d.mts} +2 -2
  107. package/dist/{inspect-CfNydMgO.d.mts.map → inspect-B1uXxdKC.d.mts.map} +1 -1
  108. package/dist/{inspect-jG_W4njH.mjs → inspect-Cxzs-W0g.mjs} +2 -2
  109. package/dist/{inspect-jG_W4njH.mjs.map → inspect-Cxzs-W0g.mjs.map} +1 -1
  110. package/dist/kitty-DKQYsQfH.mjs +1 -0
  111. package/dist/{log-ByKlM4iI.mjs → log-B4djzy2m.mjs} +4 -4
  112. package/dist/{log-ByKlM4iI.mjs.map → log-B4djzy2m.mjs.map} +1 -1
  113. package/dist/{logger-DSQb0sLP.mjs → logger-CvJCITzP.mjs} +3 -3
  114. package/dist/{logger-DSQb0sLP.mjs.map → logger-CvJCITzP.mjs.map} +1 -1
  115. package/dist/{markdown-CwRmWuU6.mjs → markdown-D3ZtRn6C.mjs} +9 -8
  116. package/dist/markdown-D3ZtRn6C.mjs.map +1 -0
  117. package/dist/markdown.d.mts +1 -1
  118. package/dist/markdown.d.mts.map +1 -1
  119. package/dist/markdown.mjs +1 -1
  120. package/dist/math-CU0wmC9N.mjs +1 -0
  121. package/dist/math-Dd7a1irv.mjs +206 -0
  122. package/dist/math-Dd7a1irv.mjs.map +1 -0
  123. package/dist/oklch-Bsh5swbC.mjs +99 -0
  124. package/dist/oklch-Bsh5swbC.mjs.map +1 -0
  125. package/dist/{overlay-BnvOKtGT.mjs → overlay-LvOjG7kn.mjs} +2 -2
  126. package/dist/{overlay-BnvOKtGT.mjs.map → overlay-LvOjG7kn.mjs.map} +1 -1
  127. package/dist/{picker-DQs_IW77.d.mts → picker-B-OxKKnD.d.mts} +5 -5
  128. package/dist/{picker-DQs_IW77.d.mts.map → picker-B-OxKKnD.d.mts.map} +1 -1
  129. package/dist/{picker-Dh5IUrTk.mjs → picker-f6xjgACX.mjs} +2 -2
  130. package/dist/{picker-Dh5IUrTk.mjs.map → picker-f6xjgACX.mjs.map} +1 -1
  131. package/dist/{queries-B_lOwEiE.mjs → queries-BUkBxkuM.mjs} +66 -3
  132. package/dist/queries-BUkBxkuM.mjs.map +1 -0
  133. package/dist/{queries-BDX8mcl5.d.mts → queries-C75-wG1B.d.mts} +19 -4
  134. package/dist/{queries-BDX8mcl5.d.mts.map → queries-C75-wG1B.d.mts.map} +1 -1
  135. package/dist/{registry-D-suU3g0.mjs → registry-DUWpSPoo.mjs} +202 -57
  136. package/dist/registry-DUWpSPoo.mjs.map +1 -0
  137. package/dist/{render-DEIUNLkh.mjs → render-B7LfNM5K.mjs} +2 -2
  138. package/dist/{render-DEIUNLkh.mjs.map → render-B7LfNM5K.mjs.map} +1 -1
  139. package/dist/{renderer-zDNlAovy.mjs → renderer-BLsd-wrG.mjs} +110 -14
  140. package/dist/renderer-BLsd-wrG.mjs.map +1 -0
  141. package/dist/renderer-YHbR7JZ4.mjs +1 -0
  142. package/dist/{renderer-MQue4Da5.mjs → renderer-aAtkFgll.mjs} +8 -7
  143. package/dist/renderer-aAtkFgll.mjs.map +1 -0
  144. package/dist/{select-J2KtwxyK.d.mts → select-BKE5LzdN.d.mts} +3 -3
  145. package/dist/{select-J2KtwxyK.d.mts.map → select-BKE5LzdN.d.mts.map} +1 -1
  146. package/dist/services/logger.d.mts +1 -1
  147. package/dist/services/logger.mjs +1 -1
  148. package/dist/services/notifier.d.mts +1 -1
  149. package/dist/services/notifier.mjs +2 -2
  150. package/dist/services/picker.d.mts +5 -5
  151. package/dist/services/picker.mjs +6 -6
  152. package/dist/services/prompt.d.mts +4 -4
  153. package/dist/services/prompt.mjs +5 -5
  154. package/dist/shiki/server.mjs +37 -14
  155. package/dist/shiki/server.mjs.map +1 -1
  156. package/dist/shiki-B4U0s8jT.mjs +635 -0
  157. package/dist/shiki-B4U0s8jT.mjs.map +1 -0
  158. package/dist/shiki-CJauRusM.mjs +20 -0
  159. package/dist/shiki-CJauRusM.mjs.map +1 -0
  160. package/dist/style-DslRHzI4.mjs +109 -0
  161. package/dist/style-DslRHzI4.mjs.map +1 -0
  162. package/dist/style.d.mts +4 -3
  163. package/dist/style.d.mts.map +1 -1
  164. package/dist/style.mjs +4 -4
  165. package/dist/{text-CkQ7Irmt.mjs → text-BoJdKXLU.mjs} +2 -2
  166. package/dist/{text-CkQ7Irmt.mjs.map → text-BoJdKXLU.mjs.map} +1 -1
  167. package/dist/{text-CCYs9RB2.d.mts → text-CmxbA8lk.d.mts} +3 -3
  168. package/dist/{text-CCYs9RB2.d.mts.map → text-CmxbA8lk.d.mts.map} +1 -1
  169. package/dist/{text-XvPfweeg.mjs → text-DPrhma4x.mjs} +2 -2
  170. package/dist/{text-XvPfweeg.mjs.map → text-DPrhma4x.mjs.map} +1 -1
  171. package/dist/text.d.mts +1 -1
  172. package/dist/text.mjs +1 -1
  173. package/dist/theme-C8LkcoaK.mjs +61 -0
  174. package/dist/theme-C8LkcoaK.mjs.map +1 -0
  175. package/dist/theme-DVX8dvGG.mjs +1794 -0
  176. package/dist/theme-DVX8dvGG.mjs.map +1 -0
  177. package/dist/themes.d.mts +213 -73
  178. package/dist/themes.d.mts.map +1 -1
  179. package/dist/themes.mjs +1 -1
  180. package/dist/{tree-DJl5W_B7.d.mts → tree-CTvSpF9b.d.mts} +3 -3
  181. package/dist/{tree-DJl5W_B7.d.mts.map → tree-CTvSpF9b.d.mts.map} +1 -1
  182. package/dist/{types-D2EYlzmK.d.mts → types-C9ceMsbJ.d.mts} +136 -128
  183. package/dist/types-C9ceMsbJ.d.mts.map +1 -0
  184. package/dist/{widget-DPqBbB57.d.mts → widget-DlF32PRp.d.mts} +2 -2
  185. package/dist/{widget-DPqBbB57.d.mts.map → widget-DlF32PRp.d.mts.map} +1 -1
  186. package/dist/widgets/autocomplete.d.mts +1 -1
  187. package/dist/widgets/autocomplete.mjs +2 -2
  188. package/dist/widgets/box.d.mts +1 -1
  189. package/dist/widgets/box.mjs +1 -1
  190. package/dist/widgets/code.d.mts +4 -2
  191. package/dist/widgets/code.d.mts.map +1 -1
  192. package/dist/widgets/code.mjs +8 -7
  193. package/dist/widgets/code.mjs.map +1 -1
  194. package/dist/widgets/completions/actions.d.mts +1 -1
  195. package/dist/widgets/completions/files.d.mts +1 -1
  196. package/dist/widgets/completions/github.d.mts +1 -1
  197. package/dist/widgets/completions/index.d.mts +3 -3
  198. package/dist/widgets/diff.d.mts +2 -2
  199. package/dist/widgets/diff.d.mts.map +1 -1
  200. package/dist/widgets/diff.mjs +35 -12
  201. package/dist/widgets/diff.mjs.map +1 -1
  202. package/dist/widgets/divider.d.mts +2 -2
  203. package/dist/widgets/divider.mjs +1 -1
  204. package/dist/widgets/image.d.mts +1 -1
  205. package/dist/widgets/image.mjs +4 -4
  206. package/dist/widgets/image.mjs.map +1 -1
  207. package/dist/widgets/input.d.mts +1 -1
  208. package/dist/widgets/input.mjs +1 -1
  209. package/dist/widgets/log.d.mts +1 -1
  210. package/dist/widgets/log.mjs +1 -1
  211. package/dist/widgets/markdown.d.mts +4 -4
  212. package/dist/widgets/markdown.d.mts.map +1 -1
  213. package/dist/widgets/markdown.mjs +1 -1
  214. package/dist/widgets/overlay.d.mts +1 -1
  215. package/dist/widgets/overlay.mjs +1 -1
  216. package/dist/widgets/picker.d.mts +1 -1
  217. package/dist/widgets/picker.mjs +1 -1
  218. package/dist/widgets/progress.d.mts +2 -2
  219. package/dist/widgets/select.d.mts +1 -1
  220. package/dist/widgets/show.d.mts +1 -1
  221. package/dist/widgets/spinner.d.mts +2 -2
  222. package/dist/widgets/text.d.mts +1 -1
  223. package/dist/widgets/text.mjs +1 -1
  224. package/dist/widgets/tree.d.mts +1 -1
  225. package/dist/widgets/widget.d.mts +1 -1
  226. package/package.json +5 -7
  227. package/assets/themes/dracula-soft.json +0 -100
  228. package/assets/themes/github-dark.json +0 -104
  229. package/assets/themes/github-light.json +0 -104
  230. package/dist/ansi-DZlXaItJ.mjs.map +0 -1
  231. package/dist/builder-1z5ewEWK.mjs +0 -386
  232. package/dist/builder-1z5ewEWK.mjs.map +0 -1
  233. package/dist/client-C2GXKfJ1.mjs.map +0 -1
  234. package/dist/client-bzdHIDL2.mjs +0 -1
  235. package/dist/ctx-D_JgJ8Eo.mjs +0 -1
  236. package/dist/image-Cm5T-uw-.mjs +0 -108
  237. package/dist/image-Cm5T-uw-.mjs.map +0 -1
  238. package/dist/markdown-CwRmWuU6.mjs.map +0 -1
  239. package/dist/queries-B_lOwEiE.mjs.map +0 -1
  240. package/dist/registry-D-suU3g0.mjs.map +0 -1
  241. package/dist/renderer-DhqbEVVR.mjs +0 -1
  242. package/dist/renderer-MQue4Da5.mjs.map +0 -1
  243. package/dist/renderer-zDNlAovy.mjs.map +0 -1
  244. package/dist/shiki--ASSYv4_.mjs +0 -12
  245. package/dist/shiki--ASSYv4_.mjs.map +0 -1
  246. package/dist/shiki-D7l5--zz.mjs +0 -432
  247. package/dist/shiki-D7l5--zz.mjs.map +0 -1
  248. package/dist/theme.config-B3Yx--C2.mjs +0 -855
  249. package/dist/theme.config-B3Yx--C2.mjs.map +0 -1
  250. package/dist/types-D2EYlzmK.d.mts.map +0 -1
@@ -1,3 +1,5 @@
1
+ import { n as isHexColor, t as blend } from "./color-DBMQLv4Y.mjs";
2
+ import { t as isDark } from "./oklch-Bsh5swbC.mjs";
1
3
  import { withError } from "@zaly/shared";
2
4
  import { createRegistry } from "@zaly/shared/registry";
3
5
  import { readFileSync } from "node:fs";
@@ -121,7 +123,8 @@ var tokyonight_moon_default = {
121
123
  "bg": "#1e2030",
122
124
  "fg": "#c8d3f5"
123
125
  },
124
- warn: "#ffc777"
126
+ warn: "#ffc777",
127
+ $schema: "https://raw.githubusercontent.com/folke/zaly/main/packages/tui/assets/schemas/theme.schema.json"
125
128
  };
126
129
  //#endregion
127
130
  //#region src/themes/builtin.ts
@@ -141,30 +144,45 @@ const importTheme = (path) => import(`#assets/themes/${path}.json`, { with: { ty
141
144
  * with no cast.
142
145
  */
143
146
  const builtin = {
147
+ andromeeda: () => importTheme("andromeeda"),
144
148
  "ayu-dark": () => importTheme("ayu-dark"),
149
+ "ayu-light": () => importTheme("ayu-light"),
150
+ "ayu-mirage": () => importTheme("ayu-mirage"),
145
151
  "catppuccin-frappe": () => importTheme("catppuccin-frappe"),
146
152
  "catppuccin-latte": () => importTheme("catppuccin-latte"),
147
153
  "catppuccin-macchiato": () => importTheme("catppuccin-macchiato"),
148
154
  "catppuccin-mocha": () => importTheme("catppuccin-mocha"),
155
+ "dark-plus": () => importTheme("dark-plus"),
149
156
  dracula: () => importTheme("dracula"),
150
- "dracula-soft": () => importTheme("dracula-soft"),
151
157
  "everforest-dark": () => importTheme("everforest-dark"),
152
158
  "everforest-light": () => importTheme("everforest-light"),
153
- "github-dark": () => importTheme("github-dark"),
154
- "github-light": () => importTheme("github-light"),
159
+ "github-dark-default": () => importTheme("github-dark-default"),
160
+ "github-dark-dimmed": () => importTheme("github-dark-dimmed"),
161
+ "github-light-default": () => importTheme("github-light-default"),
162
+ "gruvbox-dark-hard": () => importTheme("gruvbox-dark-hard"),
155
163
  "gruvbox-dark-medium": () => importTheme("gruvbox-dark-medium"),
164
+ "gruvbox-light-medium": () => importTheme("gruvbox-light-medium"),
165
+ horizon: () => importTheme("horizon"),
166
+ "horizon-bright": () => importTheme("horizon-bright"),
156
167
  "kanagawa-dragon": () => importTheme("kanagawa-dragon"),
168
+ "kanagawa-lotus": () => importTheme("kanagawa-lotus"),
157
169
  "kanagawa-wave": () => importTheme("kanagawa-wave"),
170
+ "light-plus": () => importTheme("light-plus"),
171
+ "material-theme": () => importTheme("material-theme"),
172
+ "material-theme-lighter": () => importTheme("material-theme-lighter"),
158
173
  "material-theme-palenight": () => importTheme("material-theme-palenight"),
159
174
  "min-dark": () => importTheme("min-dark"),
160
175
  "min-light": () => importTheme("min-light"),
161
176
  monokai: () => importTheme("monokai"),
162
177
  "night-owl": () => importTheme("night-owl"),
178
+ "night-owl-light": () => importTheme("night-owl-light"),
163
179
  nord: () => importTheme("nord"),
164
180
  "one-dark-pro": () => importTheme("one-dark-pro"),
165
181
  "one-light": () => importTheme("one-light"),
166
182
  poimandres: () => importTheme("poimandres"),
167
183
  "rose-pine": () => importTheme("rose-pine"),
184
+ "rose-pine-dawn": () => importTheme("rose-pine-dawn"),
185
+ "rose-pine-moon": () => importTheme("rose-pine-moon"),
168
186
  "solarized-dark": () => importTheme("solarized-dark"),
169
187
  "solarized-light": () => importTheme("solarized-light"),
170
188
  "synthwave-84": () => importTheme("synthwave-84"),
@@ -173,6 +191,7 @@ const builtin = {
173
191
  "tokyonight-night": () => importTheme("tokyonight-night"),
174
192
  "tokyonight-storm": () => importTheme("tokyonight-storm"),
175
193
  vesper: () => importTheme("vesper"),
194
+ "vitesse-black": () => importTheme("vitesse-black"),
176
195
  "vitesse-dark": () => importTheme("vitesse-dark"),
177
196
  "vitesse-light": () => importTheme("vitesse-light")
178
197
  };
@@ -186,11 +205,9 @@ const builtin = {
186
205
  * Distinct from `defaultTheme` — that's the precomputed `tokyonight-moon`
187
206
  * Theme bundled as the default palette for `createCtx()` etc.
188
207
  */
189
- const defaults = {
190
- primary: "blue",
191
- accent: "brightMagenta",
192
- bg: "inherit",
193
- fg: "inherit",
208
+ const defaultsDark = {
209
+ appearance: "dark",
210
+ shiki: "auto",
194
211
  muted: { dim: true },
195
212
  quiet: {
196
213
  dim: true,
@@ -206,31 +223,16 @@ const defaults = {
206
223
  fg: "primary"
207
224
  },
208
225
  delim: "muted",
209
- ui: { bg: "bg+5" },
226
+ ui: { bg: "bg+3" },
210
227
  overlay: { bg: "ui" },
211
- highlight: { bg: "bg+5" },
228
+ highlight: { bg: "ui" },
212
229
  divider: "bg-5",
213
- selection: {
214
- bg: "brightBlue",
215
- fg: "black"
216
- },
217
- gutter: "bg-5",
230
+ gutter: "quiet",
218
231
  prompt: "inherit",
219
- border: "black",
232
+ border: "divider",
220
233
  borderTitle: "title",
221
- code: { bg: "bg+5" },
234
+ code: { bg: "bg+3" },
222
235
  codeTitle: "title",
223
- success: "green",
224
- info: "cyan",
225
- warn: "yellow",
226
- error: "red",
227
- syntaxNumber: "brightBlue",
228
- syntaxString: "green",
229
- syntaxBoolean: "yellow",
230
- syntaxFunction: "blue",
231
- syntaxField: "white",
232
- syntaxConstant: "magenta",
233
- syntaxSpecial: "red",
234
236
  syntaxDelimiter: "delim",
235
237
  syntaxBracket: "delim",
236
238
  mdBold: { bold: true },
@@ -259,6 +261,7 @@ const defaults = {
259
261
  mdListBullet: "accent",
260
262
  mdListChecked: "primary",
261
263
  mdListUnchecked: "primary",
264
+ mdMath: { fg: "primary" },
262
265
  mdQuote: "muted",
263
266
  mdStrikethrough: { strikethrough: true },
264
267
  mdTable: "accent",
@@ -266,31 +269,170 @@ const defaults = {
266
269
  optionActive: "selection",
267
270
  optionDesc: "muted",
268
271
  optionName: "primary",
269
- diffAdd: {
270
- bg: "success-50",
271
- fg: "success"
272
- },
273
- diffContext: "highlight",
274
- diffDel: {
275
- bg: "error-50",
276
- fg: "error"
277
- },
278
- diffLine: "gutter",
279
- diffTitle: "title"
272
+ diffContext: { bg: "code" },
273
+ diffAddNum: { bg: "diffAdd+10" },
274
+ diffDelNum: { bg: "diffDel+10" },
275
+ diffContextNum: { bg: "diffContext+10" }
276
+ };
277
+ const defaultsLight = {
278
+ ...defaultsDark,
279
+ appearance: "light",
280
+ shiki: "auto",
281
+ ui: { bg: "bg-3" },
282
+ highlight: { bg: "bg-3" },
283
+ divider: "fg-5",
284
+ code: { bg: "bg-2" },
285
+ diffAddNum: { bg: "diffAdd-10" },
286
+ diffDelNum: { bg: "diffDel-10" },
287
+ diffContextNum: { bg: "diffContext-10" }
280
288
  };
281
- const ansi = {
282
- id: "ansi",
283
- name: "ANSI",
284
- ...defaults,
289
+ const defaultsSystem = {
290
+ primary: "blue",
291
+ accent: "brightMagenta",
292
+ bg: "inherit",
293
+ fg: "inherit",
294
+ selection: { inverse: true },
295
+ success: "green",
296
+ info: "cyan",
297
+ warn: "yellow",
298
+ error: "red",
299
+ syntaxNumber: "brightBlue",
300
+ syntaxString: "green",
301
+ syntaxBoolean: "yellow",
302
+ syntaxFunction: "blue",
303
+ syntaxField: "white",
304
+ syntaxConstant: "magenta",
305
+ syntaxSpecial: "red"
306
+ };
307
+ const defaultsAnsi = {
285
308
  divider: "brightBlue",
286
309
  border: "brightBlue",
287
310
  highlight: { bg: "brightBlack" },
288
- ui: { bg: "brightBlack" },
289
- selection: { inverse: true },
311
+ ui: {},
312
+ code: {},
290
313
  diffAdd: { fg: "success" },
291
314
  diffDel: { fg: "error" }
292
315
  };
293
316
  //#endregion
317
+ //#region src/themes/system.ts
318
+ const ANSI_NAMES = [
319
+ "black",
320
+ "red",
321
+ "green",
322
+ "yellow",
323
+ "blue",
324
+ "magenta",
325
+ "cyan",
326
+ "white",
327
+ "brightBlack",
328
+ "brightRed",
329
+ "brightGreen",
330
+ "brightYellow",
331
+ "brightBlue",
332
+ "brightMagenta",
333
+ "brightCyan",
334
+ "brightWhite"
335
+ ];
336
+ /** @internal Replace palette-name bases while retaining authored lightness adjustments. */
337
+ function internalizePalette(theme, colors) {
338
+ const color = (value) => {
339
+ const [, base, suffix = ""] = value.match(/^(.+?)([+-]\d+)?$/) ?? ["", value];
340
+ const hex = colors.get(base);
341
+ return hex === void 0 ? value : `${hex}${suffix}`;
342
+ };
343
+ return Object.fromEntries(Object.entries(theme).map(([key, value]) => {
344
+ if ([
345
+ "$schema",
346
+ "id",
347
+ "name",
348
+ "shiki",
349
+ "appearance"
350
+ ].includes(key)) return [key, value];
351
+ if (typeof value === "string") return [key, color(value)];
352
+ if (typeof value !== "object") return [key, value];
353
+ const style = { ...value };
354
+ if (style.fg !== void 0) style.fg = color(style.fg);
355
+ if (style.bg !== void 0) style.bg = color(style.bg);
356
+ return [key, style];
357
+ }));
358
+ }
359
+ /** Freeze a complete terminal palette into a file-compatible RGB theme. */
360
+ function themeFromPalette(palette) {
361
+ if (palette.ansi.length !== 16) throw new Error("A terminal palette requires exactly 16 ANSI colors");
362
+ const appearance = palette.appearance ?? (isDark(palette.bg) ? "dark" : "light");
363
+ const colors = new Map(ANSI_NAMES.map((name, i) => [name, palette.ansi[i]]));
364
+ for (const name of [
365
+ "brightGray",
366
+ "brightGrey",
367
+ "gray",
368
+ "grey"
369
+ ]) colors.set(name, palette.ansi[8]);
370
+ const theme = {
371
+ ...appearance === "dark" ? defaultsDark : defaultsLight,
372
+ ...defaultsSystem,
373
+ ...Object.fromEntries(colors),
374
+ appearance,
375
+ bg: palette.bg,
376
+ diffAdd: {
377
+ bg: blend(palette.ansi[2], palette.bg, .2),
378
+ fg: "success"
379
+ },
380
+ diffDel: {
381
+ bg: blend(palette.ansi[1], palette.bg, .2),
382
+ fg: "error"
383
+ },
384
+ fg: palette.fg,
385
+ muted: blend(palette.fg, palette.bg, .5),
386
+ selection: { bg: blend(palette.ansi[12], palette.bg, .3) },
387
+ syntaxField: "fg"
388
+ };
389
+ if (palette.selectionBg) theme.selection = {
390
+ bg: palette.selectionBg,
391
+ fg: palette.selectionFg
392
+ };
393
+ return internalizePalette(theme, colors);
394
+ }
395
+ /** Choose the richest coherent strategy supported by this terminal snapshot. */
396
+ function systemTheme(snapshot, reportedAppearance = "dark") {
397
+ let appearance = reportedAppearance;
398
+ if (snapshot?.bg) appearance = isDark(snapshot.bg) ? "dark" : "light";
399
+ const identity = {
400
+ appearance,
401
+ id: "system",
402
+ name: "System",
403
+ shiki: "auto"
404
+ };
405
+ if (snapshot?.bg && snapshot.fg && snapshot.ansi.length === 16 && snapshot.ansi.every((color) => color !== void 0)) return {
406
+ ...themeFromPalette({
407
+ ...snapshot,
408
+ ansi: snapshot.ansi,
409
+ appearance,
410
+ bg: snapshot.bg,
411
+ fg: snapshot.fg
412
+ }),
413
+ ...identity
414
+ };
415
+ if (snapshot?.bg) return {
416
+ ...appearance === "dark" ? defaultsDark : defaultsLight,
417
+ ...defaultsSystem,
418
+ ...identity,
419
+ bg: snapshot.bg,
420
+ diffAdd: { fg: "success" },
421
+ diffDel: { fg: "error" },
422
+ fg: snapshot.fg ?? "inherit",
423
+ ...snapshot.selectionBg ? { selection: {
424
+ bg: snapshot.selectionBg,
425
+ fg: snapshot.selectionFg ?? snapshot.fg ?? "inherit"
426
+ } } : {}
427
+ };
428
+ return {
429
+ ...defaultsDark,
430
+ ...defaultsSystem,
431
+ ...defaultsAnsi,
432
+ ...identity
433
+ };
434
+ }
435
+ //#endregion
294
436
  //#region src/themes/registry.ts
295
437
  const DEFAULT_THEME = "tokyonight-moon";
296
438
  /**
@@ -298,8 +440,10 @@ const DEFAULT_THEME = "tokyonight-moon";
298
440
  * registry never awaits — loaders return `Promise<Partial<Theme>>` so
299
441
  * callers `await` explicitly.
300
442
  */
301
- const themeRegistry = createRegistry("theme").from(builtin);
302
- themeRegistry.register("ansi", async () => ({ ...ansi }));
443
+ const themeRegistry = createRegistry("theme").from({
444
+ ...builtin,
445
+ system: async () => systemTheme()
446
+ });
303
447
  async function loadTheme(o) {
304
448
  o ??= DEFAULT_THEME;
305
449
  const opts = typeof o === "string" ? { name: o } : o;
@@ -314,14 +458,16 @@ async function loadTheme(o) {
314
458
  }
315
459
  /**
316
460
  * Fill defaults on a raw theme object. Built-in JSON is dev-controlled
317
- * so we don't pay typia's ~3MB of generated assertions at startup;
461
+ * so the standalone validator stays off the main startup path;
318
462
  * user-supplied JSON goes through `loadThemeFile` which validates.
319
463
  */
320
464
  function resolveTheme(theme, id) {
321
465
  const { $schema: _, ...rest } = theme;
466
+ let appearance = rest.appearance;
467
+ if (!appearance && rest.bg && isHexColor(rest.bg)) appearance = isDark(rest.bg) ? "dark" : "light";
468
+ appearance ??= "dark";
322
469
  return {
323
- ...defaults,
324
- id,
470
+ ...appearance === "dark" ? defaultsDark : defaultsLight,
325
471
  name: id,
326
472
  ...rest
327
473
  };
@@ -331,19 +477,18 @@ function resolveTheme(theme, id) {
331
477
  * this is the escape hatch for CLIs that accept an explicit `--theme
332
478
  * /path/to/theme.json` argument.
333
479
  *
334
- * Async because typia's generated `validateTheme` (a few thousand
335
- * unrolled assertions) is dynamically imported here — it's only needed
336
- * for user-supplied JSON and should stay off the main startup path.
480
+ * The standalone validator is dynamically imported here — it is only
481
+ * needed for user-supplied JSON and stays off the main startup path.
337
482
  */
338
483
  async function loadThemeFile(path) {
339
484
  const raw = withError(() => readFileSync(path, "utf8"), `Failed to read theme file at ${path}`);
340
485
  const data = withError(() => JSON.parse(raw), `Failed to parse theme JSON at ${path}`);
341
- const { validateTheme } = await import("./theme.config-B3Yx--C2.mjs");
486
+ const { validateTheme } = await import("./theme-DVX8dvGG.mjs");
342
487
  return resolveTheme(validateTheme(data), basename(path, ".json"));
343
488
  }
344
489
  /** TokyoNight Moon — the default. Sourced from `assets/themes/tokyonight-moon.json`. */
345
490
  const defaultTheme = resolveTheme(tokyonight_moon_default, "tokyonight-moon");
346
491
  //#endregion
347
- export { loadTheme as n, themeRegistry as r, defaultTheme as t };
492
+ export { systemTheme as i, loadTheme as n, themeRegistry as r, defaultTheme as t };
348
493
 
349
- //# sourceMappingURL=registry-D-suU3g0.mjs.map
494
+ //# sourceMappingURL=registry-DUWpSPoo.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-DUWpSPoo.mjs","names":["moonJson"],"sources":["../assets/themes/tokyonight-moon.json","../src/themes/builtin.ts","../src/themes/default.ts","../src/themes/system.ts","../src/themes/registry.ts"],"sourcesContent":["","// AUTO-GENERATED by `scripts/gen-themes.ts`. DO NOT EDIT.\n// Re-run `bun scripts/gen-themes.ts` after adding/renaming a theme.\n\nimport type { CustomTheme } from \"./default.ts\"\nimport type { ThemeLoader } from \"./registry.ts\"\n\nconst importTheme = (path: string): Promise<CustomTheme> =>\n import(`#assets/themes/${path}.json`, { with: { type: \"json\" } }).then(\n (m) => m.default as CustomTheme\n )\n\n/**\n * Async loader map for every built-in theme. Each entry returns the\n * raw JSON; `themes/index.ts` wraps these with `resolveTheme` to\n * produce a fully-resolved `Theme` from the registry. Bundlers\n * code-split each `import(\"…json\")` into its own chunk, so apps only\n * pull the theme they actually load.\n *\n * `as const satisfies Record<string, ThemeLoader>` keeps the keys\n * narrow (so `BuiltinThemeName` is a literal union) but lets the\n * value type widen to `Partial<Theme>` — themes have no per-key\n * narrow types worth preserving, and the satisfies clause means\n * `themes/index.ts` can pass this map straight to `themeRegistry`\n * with no cast.\n */\nexport const builtin = {\n andromeeda: () => importTheme(\"andromeeda\"),\n \"ayu-dark\": () => importTheme(\"ayu-dark\"),\n \"ayu-light\": () => importTheme(\"ayu-light\"),\n \"ayu-mirage\": () => importTheme(\"ayu-mirage\"),\n \"catppuccin-frappe\": () => importTheme(\"catppuccin-frappe\"),\n \"catppuccin-latte\": () => importTheme(\"catppuccin-latte\"),\n \"catppuccin-macchiato\": () => importTheme(\"catppuccin-macchiato\"),\n \"catppuccin-mocha\": () => importTheme(\"catppuccin-mocha\"),\n \"dark-plus\": () => importTheme(\"dark-plus\"),\n dracula: () => importTheme(\"dracula\"),\n \"everforest-dark\": () => importTheme(\"everforest-dark\"),\n \"everforest-light\": () => importTheme(\"everforest-light\"),\n \"github-dark-default\": () => importTheme(\"github-dark-default\"),\n \"github-dark-dimmed\": () => importTheme(\"github-dark-dimmed\"),\n \"github-light-default\": () => importTheme(\"github-light-default\"),\n \"gruvbox-dark-hard\": () => importTheme(\"gruvbox-dark-hard\"),\n \"gruvbox-dark-medium\": () => importTheme(\"gruvbox-dark-medium\"),\n \"gruvbox-light-medium\": () => importTheme(\"gruvbox-light-medium\"),\n horizon: () => importTheme(\"horizon\"),\n \"horizon-bright\": () => importTheme(\"horizon-bright\"),\n \"kanagawa-dragon\": () => importTheme(\"kanagawa-dragon\"),\n \"kanagawa-lotus\": () => importTheme(\"kanagawa-lotus\"),\n \"kanagawa-wave\": () => importTheme(\"kanagawa-wave\"),\n \"light-plus\": () => importTheme(\"light-plus\"),\n \"material-theme\": () => importTheme(\"material-theme\"),\n \"material-theme-lighter\": () => importTheme(\"material-theme-lighter\"),\n \"material-theme-palenight\": () => importTheme(\"material-theme-palenight\"),\n \"min-dark\": () => importTheme(\"min-dark\"),\n \"min-light\": () => importTheme(\"min-light\"),\n monokai: () => importTheme(\"monokai\"),\n \"night-owl\": () => importTheme(\"night-owl\"),\n \"night-owl-light\": () => importTheme(\"night-owl-light\"),\n nord: () => importTheme(\"nord\"),\n \"one-dark-pro\": () => importTheme(\"one-dark-pro\"),\n \"one-light\": () => importTheme(\"one-light\"),\n poimandres: () => importTheme(\"poimandres\"),\n \"rose-pine\": () => importTheme(\"rose-pine\"),\n \"rose-pine-dawn\": () => importTheme(\"rose-pine-dawn\"),\n \"rose-pine-moon\": () => importTheme(\"rose-pine-moon\"),\n \"solarized-dark\": () => importTheme(\"solarized-dark\"),\n \"solarized-light\": () => importTheme(\"solarized-light\"),\n \"synthwave-84\": () => importTheme(\"synthwave-84\"),\n \"tokyonight-day\": () => importTheme(\"tokyonight-day\"),\n \"tokyonight-moon\": () => importTheme(\"tokyonight-moon\"),\n \"tokyonight-night\": () => importTheme(\"tokyonight-night\"),\n \"tokyonight-storm\": () => importTheme(\"tokyonight-storm\"),\n vesper: () => importTheme(\"vesper\"),\n \"vitesse-black\": () => importTheme(\"vitesse-black\"),\n \"vitesse-dark\": () => importTheme(\"vitesse-dark\"),\n \"vitesse-light\": () => importTheme(\"vitesse-light\"),\n} as const satisfies Record<string, ThemeLoader>\n","import type { Theme } from \"./types.ts\"\n\nexport type CustomTheme = Partial<Pick<Theme<false>, keyof typeof defaultsDark>> &\n Omit<Theme<false>, keyof typeof defaultsDark> & { $schema?: string }\n\n/**\n * Slot-level fallbacks. Every Theme value is shallow-merged on top of\n * this record by `resolveTheme`, so partial JSON themes only need to\n * declare slots that diverge from these defaults.\n *\n * Distinct from `defaultTheme` — that's the precomputed `tokyonight-moon`\n * Theme bundled as the default palette for `createCtx()` etc.\n */\n// oxlint-disable-next-line sort-keys\nexport const defaultsDark = {\n appearance: \"dark\",\n shiki: \"auto\",\n\n // text\n muted: { dim: true },\n quiet: { dim: true, fg: \"muted\", italic: true },\n comment: { fg: \"muted\", italic: true },\n title: { bold: true, fg: \"primary\" },\n delim: \"muted\",\n\n // surface & structure\n ui: { bg: \"bg+3\" },\n overlay: { bg: \"ui\" },\n highlight: { bg: \"ui\" },\n\n // ui primitives\n divider: \"bg-5\",\n gutter: \"quiet\",\n prompt: \"inherit\",\n border: \"divider\",\n borderTitle: \"title\",\n\n // code\n code: { bg: \"bg+3\" },\n codeTitle: \"title\",\n\n // syntax\n syntaxDelimiter: \"delim\",\n syntaxBracket: \"delim\",\n\n // markdown\n mdBold: { bold: true },\n mdCode: { bg: \"highlight\", fg: \"primary\" },\n mdCodeBlock: \"code\",\n mdCodeBlockTitle: \"title\",\n mdHeading1: \"mdHeading\",\n mdHeading2: { bold: true, fg: \"accent\" },\n mdHeading3: \"mdHeading2\",\n mdHeading4: \"mdHeading2\",\n mdHeading5: \"mdHeading2\",\n mdHeading6: \"mdHeading2\",\n mdHeading: \"title\",\n mdHr: \"accent\",\n mdItalic: { italic: true },\n mdLink: { fg: \"primary\", underline: true },\n mdListBullet: \"accent\",\n mdListChecked: \"primary\",\n mdListUnchecked: \"primary\",\n mdMath: { fg: \"primary\" },\n mdQuote: \"muted\",\n mdStrikethrough: { strikethrough: true },\n mdTable: \"accent\",\n mdTableHeader: \"title\",\n\n // menu\n optionActive: \"selection\",\n optionDesc: \"muted\",\n optionName: \"primary\",\n\n // diff\n diffContext: { bg: \"code\" },\n diffAddNum: { bg: \"diffAdd+10\" },\n diffDelNum: { bg: \"diffDel+10\" },\n diffContextNum: { bg: \"diffContext+10\" },\n} satisfies Partial<Theme<false>>\n\n// oxlint-disable-next-line sort-keys\nexport const defaultsLight = {\n ...defaultsDark,\n appearance: \"light\",\n shiki: \"auto\",\n ui: { bg: \"bg-3\" },\n highlight: { bg: \"bg-3\" },\n divider: \"fg-5\",\n code: { bg: \"bg-2\" },\n diffAddNum: { bg: \"diffAdd-10\" },\n diffDelNum: { bg: \"diffDel-10\" },\n diffContextNum: { bg: \"diffContext-10\" },\n} satisfies Partial<Theme<false>>\n\n// oxlint-disable-next-line sort-keys\nexport const defaultsSystem = {\n // base colors\n primary: \"blue\",\n accent: \"brightMagenta\",\n\n bg: \"inherit\",\n fg: \"inherit\",\n\n selection: { inverse: true },\n // log levels\n success: \"green\",\n info: \"cyan\",\n warn: \"yellow\",\n error: \"red\",\n\n // syntax\n syntaxNumber: \"brightBlue\",\n syntaxString: \"green\",\n syntaxBoolean: \"yellow\",\n syntaxFunction: \"blue\",\n syntaxField: \"white\",\n syntaxConstant: \"magenta\",\n syntaxSpecial: \"red\",\n} satisfies Partial<Theme>\n\n// oxlint-disable-next-line sort-keys\nexport const defaultsAnsi = {\n divider: \"brightBlue\",\n border: \"brightBlue\",\n highlight: { bg: \"brightBlack\" },\n ui: {},\n code: {},\n diffAdd: { fg: \"success\" },\n diffDel: { fg: \"error\" },\n} satisfies Partial<Theme>\n","import type { TerminalPaletteSnapshot } from \"../input/queries.ts\"\nimport type { Color, HexColor } from \"../style/types.ts\"\nimport type { Theme } from \"./types.ts\"\n\nimport { blend } from \"../style/color.ts\"\nimport { isDark } from \"../style/oklch.ts\"\nimport { defaultsAnsi, defaultsDark, defaultsLight, defaultsSystem } from \"./default.ts\"\n\nexport interface TerminalPalette {\n /** ANSI colors in index order, 0–15. */\n ansi: readonly HexColor[]\n bg: HexColor\n fg: HexColor\n appearance?: Theme[\"appearance\"]\n selectionBg?: HexColor\n selectionFg?: HexColor\n}\n\nconst ANSI_NAMES = [\n \"black\",\n \"red\",\n \"green\",\n \"yellow\",\n \"blue\",\n \"magenta\",\n \"cyan\",\n \"white\",\n \"brightBlack\",\n \"brightRed\",\n \"brightGreen\",\n \"brightYellow\",\n \"brightBlue\",\n \"brightMagenta\",\n \"brightCyan\",\n \"brightWhite\",\n] as const\n\n/** @internal Replace palette-name bases while retaining authored lightness adjustments. */\nexport function internalizePalette(\n theme: Omit<Theme, \"id\">,\n colors: ReadonlyMap<string, HexColor>\n): Omit<Theme<false>, \"id\"> {\n const color = (value: string) => {\n const [, base, suffix = \"\"] = value.match(/^(.+?)([+-]\\d+)?$/) ?? [\"\", value]\n const hex = colors.get(base)\n return (hex === undefined ? value : `${hex}${suffix}`) as Color\n }\n return Object.fromEntries(\n Object.entries(theme).map(([key, value]) => {\n if ([\"$schema\", \"id\", \"name\", \"shiki\", \"appearance\"].includes(key)) return [key, value]\n if (typeof value === \"string\") return [key, color(value)]\n if (typeof value !== \"object\") return [key, value]\n const style = { ...value }\n if (style.fg !== undefined) style.fg = color(style.fg)\n if (style.bg !== undefined) style.bg = color(style.bg)\n return [key, style]\n })\n ) as Omit<Theme<false>, \"id\">\n}\n\n/** Freeze a complete terminal palette into a file-compatible RGB theme. */\nexport function themeFromPalette(palette: TerminalPalette): Omit<Theme<false>, \"id\"> {\n if (palette.ansi.length !== 16)\n throw new Error(\"A terminal palette requires exactly 16 ANSI colors\")\n const appearance = palette.appearance ?? (isDark(palette.bg) ? \"dark\" : \"light\")\n const colors = new Map<string, HexColor>(ANSI_NAMES.map((name, i) => [name, palette.ansi[i]]))\n for (const name of [\"brightGray\", \"brightGrey\", \"gray\", \"grey\"]) colors.set(name, palette.ansi[8])\n const theme: Omit<Theme, \"id\"> = {\n ...(appearance === \"dark\" ? defaultsDark : defaultsLight),\n ...defaultsSystem,\n ...Object.fromEntries(colors),\n appearance,\n bg: palette.bg,\n diffAdd: { bg: blend(palette.ansi[2], palette.bg, 0.2), fg: \"success\" },\n diffDel: { bg: blend(palette.ansi[1], palette.bg, 0.2), fg: \"error\" },\n fg: palette.fg,\n muted: blend(palette.fg, palette.bg, 0.5),\n selection: { bg: blend(palette.ansi[12], palette.bg, 0.3) },\n syntaxField: \"fg\",\n }\n if (palette.selectionBg) theme.selection = { bg: palette.selectionBg, fg: palette.selectionFg }\n return internalizePalette(theme, colors)\n}\n\n/** Choose the richest coherent strategy supported by this terminal snapshot. */\nexport function systemTheme(\n snapshot?: TerminalPaletteSnapshot,\n reportedAppearance: Theme[\"appearance\"] = \"dark\"\n): Theme {\n let appearance = reportedAppearance\n if (snapshot?.bg) appearance = isDark(snapshot.bg) ? \"dark\" : \"light\"\n const identity = {\n appearance,\n id: \"system\",\n name: \"System\",\n shiki: \"auto\",\n } as const\n if (\n snapshot?.bg &&\n snapshot.fg &&\n snapshot.ansi.length === 16 &&\n snapshot.ansi.every((color) => color !== undefined)\n ) {\n return {\n ...themeFromPalette({\n ...snapshot,\n ansi: snapshot.ansi as HexColor[],\n appearance,\n bg: snapshot.bg,\n fg: snapshot.fg,\n }),\n ...identity,\n }\n }\n if (snapshot?.bg) {\n return {\n ...(appearance === \"dark\" ? defaultsDark : defaultsLight),\n ...defaultsSystem,\n ...identity,\n bg: snapshot.bg,\n diffAdd: { fg: \"success\" },\n diffDel: { fg: \"error\" },\n fg: snapshot.fg ?? \"inherit\",\n ...(snapshot.selectionBg\n ? {\n selection: {\n bg: snapshot.selectionBg,\n fg: snapshot.selectionFg ?? snapshot.fg ?? \"inherit\",\n },\n }\n : {}),\n }\n }\n return {\n ...defaultsDark,\n ...defaultsSystem,\n ...defaultsAnsi,\n ...identity,\n }\n}\n","import type { CustomTheme } from \"./default.ts\"\nimport type { Theme } from \"./types.ts\"\n\nimport { withError } from \"@zaly/shared\"\nimport { createRegistry } from \"@zaly/shared/registry\"\nimport { readFileSync } from \"node:fs\"\nimport { basename } from \"pathe\"\nimport moonJson from \"../../assets/themes/tokyonight-moon.json\" with { type: \"json\" }\nimport { isHexColor } from \"../style/color.ts\"\nimport { isDark } from \"../style/oklch.ts\"\nimport { builtin } from \"./builtin.ts\"\nimport { defaultsDark, defaultsLight } from \"./default.ts\"\nimport { systemTheme } from \"./system.ts\"\n\n/** Built-in JSON themes plus the runtime terminal palette. */\nexport type BuiltinTheme = keyof typeof builtin | \"system\"\nexport type AnyTheme = BuiltinTheme | (string & {})\nexport type ThemeLoader = () => Promise<CustomTheme | Theme>\n\nconst DEFAULT_THEME: BuiltinTheme = \"tokyonight-moon\"\n\n/**\n * Registry of built-in themes plus any registered at runtime. The\n * registry never awaits — loaders return `Promise<Partial<Theme>>` so\n * callers `await` explicitly.\n */\nexport const themeRegistry = createRegistry<ThemeLoader>(\"theme\").from({\n ...builtin,\n system: async () => systemTheme(),\n})\n\n/**\n * Load a theme by name or path.\n */\nexport async function loadTheme(name?: string): Promise<Theme>\nexport async function loadTheme(opts: { name?: string; path?: string }): Promise<Theme>\nexport async function loadTheme(o?: string | { name?: string; path?: string }): Promise<Theme> {\n o ??= DEFAULT_THEME\n const opts = typeof o === \"string\" ? { name: o } : o\n\n if (opts.name?.endsWith(\".json\")) return loadTheme({ path: opts.name })\n if (opts.path) return loadThemeFile(opts.path)\n if (opts.name) {\n if (opts.name === DEFAULT_THEME) return defaultTheme\n if (themeRegistry.has(opts.name))\n return resolveTheme(await themeRegistry.load(opts.name), opts.name)\n throw new Error(`Theme \"${opts.name}\" not found.`)\n }\n\n return defaultTheme\n}\n\n/**\n * Fill defaults on a raw theme object. Built-in JSON is dev-controlled\n * so the standalone validator stays off the main startup path;\n * user-supplied JSON goes through `loadThemeFile` which validates.\n */\nfunction resolveTheme(theme: (CustomTheme | Theme) & { $schema?: string }, id: string): Theme {\n const { $schema: _, ...rest } = theme\n let appearance: \"dark\" | \"light\" | undefined = rest.appearance\n if (!appearance && rest.bg && isHexColor(rest.bg)) appearance = isDark(rest.bg) ? \"dark\" : \"light\"\n appearance ??= \"dark\"\n return { ...(appearance === \"dark\" ? defaultsDark : defaultsLight), name: id, ...rest }\n}\n\n/**\n * Load a theme directly from a file path. No directory search happens —\n * this is the escape hatch for CLIs that accept an explicit `--theme\n * /path/to/theme.json` argument.\n *\n * The standalone validator is dynamically imported here — it is only\n * needed for user-supplied JSON and stays off the main startup path.\n */\nasync function loadThemeFile(path: string): Promise<Theme> {\n const raw = withError(() => readFileSync(path, \"utf8\"), `Failed to read theme file at ${path}`)\n const data = withError(() => JSON.parse(raw), `Failed to parse theme JSON at ${path}`)\n const { validateTheme } = await import(\"../schemas/theme.ts\")\n return resolveTheme(validateTheme(data), basename(path, \".json\"))\n}\n\n/** TokyoNight Moon — the default. Sourced from `assets/themes/tokyonight-moon.json`. */\nexport const defaultTheme = resolveTheme(moonJson as CustomTheme, \"tokyonight-moon\")\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { d as createSuspenseBoundary, i as createContext, l as createRoot, n as SuspenseContext, v as provideContext } from "./reactive-f7NpAi69.mjs";
2
- import { t as createCtx } from "./ctx-B7BmPUCD.mjs";
2
+ import { t as createCtx } from "./ctx-BaQ2hP5u.mjs";
3
3
  //#region src/core/render.ts
4
4
  const RenderContext = createContext();
5
5
  async function createRender(node, ctx = createCtx()) {
@@ -30,4 +30,4 @@ async function renderWithDrain(node, boundary, ctx) {
30
30
  //#endregion
31
31
  export { createRender as n, RenderContext as t };
32
32
 
33
- //# sourceMappingURL=render-DEIUNLkh.mjs.map
33
+ //# sourceMappingURL=render-B7LfNM5K.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-DEIUNLkh.mjs","names":[],"sources":["../src/core/render.ts"],"sourcesContent":["import type { TerminalQueries } from \"../input/queries.ts\"\nimport type { StyleBuilder } from \"../style/builder.ts\"\nimport type { Theme } from \"../themes/types.ts\"\nimport type { RenderCtx } from \"./ctx.ts\"\n// oxlint-disable no-await-in-loop\nimport type { Node } from \"./node.ts\"\nimport type { Accessor, SuspenseBoundary } from \"./reactive.ts\"\n\nimport { createCtx } from \"./ctx.ts\"\nimport {\n createContext,\n createRoot,\n createSuspenseBoundary,\n provideContext,\n SuspenseContext,\n} from \"./reactive.ts\"\n\n/** Components-facing slice of the render environment — reactive\n * accessors a widget body reads via `useContext(RenderContext)`. Use\n * this when a widget needs ambient theme/style outside an `_render`\n * call (the place where `RenderCtx` is threaded in). Width is\n * deliberately omitted — that's a per-render allotted-size concept,\n * not an ambient one. */\nexport type RenderContextValue = {\n /** Active theme. Tracked — widgets that read it re-fire on swap. */\n theme: Accessor<Theme>\n /** Theme-bound chainable style builder. Derived memo over `theme`. */\n style: Accessor<StyleBuilder>\n /** Whether to render images (when supported) */\n images: Accessor<boolean>\n queries: TerminalQueries\n}\nexport const RenderContext = createContext<RenderContextValue>()\n\n/**\n * Render a Node, draining `createAsync` work in its subtree before\n * returning final rows. Two shapes:\n *\n * - `createRender(() => node, ctx?)` — factory form. Creates a fresh\n * `SuspenseBoundary` inside a new `createRoot` and runs the\n * factory in that scope so descendants find the boundary via\n * `useContext(SuspenseContext)`. For tests, benches, REPL.\n *\n * - `createRender(node, { ...ctx, boundary })` — pre-built Node\n * with a caller-provided boundary. Used by `Stream.render`: the\n * boundary was installed at `append` time, so we just render +\n * drain without a new root scope.\n *\n * `ctx` defaults to `createCtx()` in the factory form.\n *\n * ```ts\n * const rows = await createRender(() => markdown(\"**hi**\"))\n * ```\n */\nexport async function createRender(\n node: Node,\n ctx: RenderCtx & { boundary: SuspenseBoundary }\n): Promise<string[]>\nexport async function createRender(node: () => Node, ctx?: RenderCtx): Promise<string[]>\nexport async function createRender(\n node: Node | (() => Node),\n ctx: RenderCtx & { boundary?: SuspenseBoundary } = createCtx()\n): Promise<string[]> {\n if (ctx.boundary) return renderWithDrain(node as Node, ctx.boundary, ctx)\n const boundary = createSuspenseBoundary()\n const nodeFn = node as () => Node\n return createRoot(async () => {\n provideContext(SuspenseContext, boundary)\n return renderWithDrain(nodeFn(), boundary, ctx)\n })\n}\n\n/** Wait for any pending work first, then render. On warm caches the\n * initial `whenIdle` resolves on the same microtask tick — no real\n * wait — and we render exactly once with final values. On cold the\n * wait blocks until `createAsync` settles. The follow-up `while`\n * catches the in-render case: a `_render` that fires a fresh\n * `createAsync` (signal write subscribes a new effect) bumps the\n * boundary back above zero, requiring another pass. */\nasync function renderWithDrain(\n node: Node,\n boundary: SuspenseBoundary,\n ctx: RenderCtx\n): Promise<string[]> {\n if (boundary.active()) await boundary.whenIdle()\n let rows = await node.render(ctx)\n while (boundary.active()) {\n await boundary.whenIdle()\n rows = await node.render(ctx)\n }\n return rows\n}\n"],"mappings":";;;AAgCA,MAAa,gBAAgB,cAAkC;AA2B/D,eAAsB,aACpB,MACA,MAAmD,UAAU,GAC1C;CACnB,IAAI,IAAI,UAAU,OAAO,gBAAgB,MAAc,IAAI,UAAU,GAAG;CACxE,MAAM,WAAW,uBAAuB;CACxC,MAAM,SAAS;CACf,OAAO,WAAW,YAAY;EAC5B,eAAe,iBAAiB,QAAQ;EACxC,OAAO,gBAAgB,OAAO,GAAG,UAAU,GAAG;CAChD,CAAC;AACH;;;;;;;;AASA,eAAe,gBACb,MACA,UACA,KACmB;CACnB,IAAI,SAAS,OAAO,GAAG,MAAM,SAAS,SAAS;CAC/C,IAAI,OAAO,MAAM,KAAK,OAAO,GAAG;CAChC,OAAO,SAAS,OAAO,GAAG;EACxB,MAAM,SAAS,SAAS;EACxB,OAAO,MAAM,KAAK,OAAO,GAAG;CAC9B;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"render-B7LfNM5K.mjs","names":[],"sources":["../src/core/render.ts"],"sourcesContent":["import type { TerminalQueries } from \"../input/queries.ts\"\nimport type { StyleBuilder } from \"../style/builder.ts\"\nimport type { Theme } from \"../themes/types.ts\"\nimport type { RenderCtx } from \"./ctx.ts\"\n// oxlint-disable no-await-in-loop\nimport type { Node } from \"./node.ts\"\nimport type { Accessor, SuspenseBoundary } from \"./reactive.ts\"\n\nimport { createCtx } from \"./ctx.ts\"\nimport {\n createContext,\n createRoot,\n createSuspenseBoundary,\n provideContext,\n SuspenseContext,\n} from \"./reactive.ts\"\n\n/** Components-facing slice of the render environment — reactive\n * accessors a widget body reads via `useContext(RenderContext)`. Use\n * this when a widget needs ambient theme/style outside an `_render`\n * call (the place where `RenderCtx` is threaded in). Width is\n * deliberately omitted — that's a per-render allotted-size concept,\n * not an ambient one. */\nexport type RenderContextValue = {\n /** Active theme. Tracked — widgets that read it re-fire on swap. */\n theme: Accessor<Theme>\n /** Theme-bound chainable style builder. Derived memo over `theme`. */\n style: Accessor<StyleBuilder>\n /** Whether to render images (when supported) */\n images: Accessor<boolean>\n queries: TerminalQueries\n}\nexport const RenderContext = createContext<RenderContextValue>()\n\n/**\n * Render a Node, draining `createAsync` work in its subtree before\n * returning final rows. Two shapes:\n *\n * - `createRender(() => node, ctx?)` — factory form. Creates a fresh\n * `SuspenseBoundary` inside a new `createRoot` and runs the\n * factory in that scope so descendants find the boundary via\n * `useContext(SuspenseContext)`. For tests, benches, REPL.\n *\n * - `createRender(node, { ...ctx, boundary })` — pre-built Node\n * with a caller-provided boundary. Used by `Stream.render`: the\n * boundary was installed at `append` time, so we just render +\n * drain without a new root scope.\n *\n * `ctx` defaults to `createCtx()` in the factory form.\n *\n * ```ts\n * const rows = await createRender(() => markdown(\"**hi**\"))\n * ```\n */\nexport async function createRender(\n node: Node,\n ctx: RenderCtx & { boundary: SuspenseBoundary }\n): Promise<string[]>\nexport async function createRender(node: () => Node, ctx?: RenderCtx): Promise<string[]>\nexport async function createRender(\n node: Node | (() => Node),\n ctx: RenderCtx & { boundary?: SuspenseBoundary } = createCtx()\n): Promise<string[]> {\n if (ctx.boundary) return renderWithDrain(node as Node, ctx.boundary, ctx)\n const boundary = createSuspenseBoundary()\n const nodeFn = node as () => Node\n return createRoot(async () => {\n provideContext(SuspenseContext, boundary)\n return renderWithDrain(nodeFn(), boundary, ctx)\n })\n}\n\n/** Wait for any pending work first, then render. On warm caches the\n * initial `whenIdle` resolves on the same microtask tick — no real\n * wait — and we render exactly once with final values. On cold the\n * wait blocks until `createAsync` settles. The follow-up `while`\n * catches the in-render case: a `_render` that fires a fresh\n * `createAsync` (signal write subscribes a new effect) bumps the\n * boundary back above zero, requiring another pass. */\nasync function renderWithDrain(\n node: Node,\n boundary: SuspenseBoundary,\n ctx: RenderCtx\n): Promise<string[]> {\n if (boundary.active()) await boundary.whenIdle()\n let rows = await node.render(ctx)\n while (boundary.active()) {\n await boundary.whenIdle()\n rows = await node.render(ctx)\n }\n return rows\n}\n"],"mappings":";;;AAgCA,MAAa,gBAAgB,cAAkC;AA2B/D,eAAsB,aACpB,MACA,MAAmD,UAAU,GAC1C;CACnB,IAAI,IAAI,UAAU,OAAO,gBAAgB,MAAc,IAAI,UAAU,GAAG;CACxE,MAAM,WAAW,uBAAuB;CACxC,MAAM,SAAS;CACf,OAAO,WAAW,YAAY;EAC5B,eAAe,iBAAiB,QAAQ;EACxC,OAAO,gBAAgB,OAAO,GAAG,UAAU,GAAG;CAChD,CAAC;AACH;;;;;;;;AASA,eAAe,gBACb,MACA,UACA,KACmB;CACnB,IAAI,SAAS,OAAO,GAAG,MAAM,SAAS,SAAS;CAC/C,IAAI,OAAO,MAAM,KAAK,OAAO,GAAG;CAChC,OAAO,SAAS,OAAO,GAAG;EACxB,MAAM,SAAS,SAAS;EACxB,OAAO,MAAM,KAAK,OAAO,GAAG;CAC9B;CACA,OAAO;AACT"}