@zaly/tui 0.0.11 → 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 (260) 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 +227 -732
  4. package/assets/themes/andromeeda.json +97 -0
  5. package/assets/themes/ayu-dark.json +31 -44
  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 +44 -60
  9. package/assets/themes/catppuccin-latte.json +44 -60
  10. package/assets/themes/catppuccin-macchiato.json +44 -60
  11. package/assets/themes/catppuccin-mocha.json +44 -60
  12. package/assets/themes/dark-plus.json +99 -0
  13. package/assets/themes/dracula.json +47 -66
  14. package/assets/themes/everforest-dark.json +28 -45
  15. package/assets/themes/everforest-light.json +28 -45
  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 -48
  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 -68
  36. package/assets/themes/kanagawa-lotus.json +105 -0
  37. package/assets/themes/kanagawa-wave.json +55 -68
  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 -64
  41. package/assets/themes/material-theme.json +102 -0
  42. package/assets/themes/min-dark.json +67 -28
  43. package/assets/themes/min-light.json +67 -32
  44. package/assets/themes/monokai.json +55 -67
  45. package/assets/themes/night-owl-light.json +105 -0
  46. package/assets/themes/night-owl.json +57 -68
  47. package/assets/themes/nord.json +53 -55
  48. package/assets/themes/one-dark-pro.json +46 -57
  49. package/assets/themes/one-light.json +52 -59
  50. package/assets/themes/poimandres.json +51 -68
  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 +51 -50
  54. package/assets/themes/solarized-dark.json +39 -51
  55. package/assets/themes/solarized-light.json +40 -52
  56. package/assets/themes/synthwave-84.json +48 -50
  57. package/assets/themes/tokyonight-day.json +6 -7
  58. package/assets/themes/tokyonight-moon.json +6 -6
  59. package/assets/themes/tokyonight-night.json +6 -6
  60. package/assets/themes/tokyonight-storm.json +6 -6
  61. package/assets/themes/vesper.json +51 -58
  62. package/assets/themes/vitesse-black.json +103 -0
  63. package/assets/themes/vitesse-dark.json +26 -49
  64. package/assets/themes/vitesse-light.json +26 -49
  65. package/dist/{actions-DFboj3g5.d.mts → actions--ODlgCQ5.d.mts} +4 -4
  66. package/dist/{actions-DFboj3g5.d.mts.map → actions--ODlgCQ5.d.mts.map} +1 -1
  67. package/dist/{ansi-Clq0ozyA.mjs → ansi-CMv71xVr.mjs} +38 -31
  68. package/dist/ansi-CMv71xVr.mjs.map +1 -0
  69. package/dist/ansi.d.mts +3 -1
  70. package/dist/ansi.d.mts.map +1 -1
  71. package/dist/ansi.mjs +1 -1
  72. package/dist/{autocomplete-CxzetPOo.d.mts → autocomplete-CD30kSe_.d.mts} +4 -4
  73. package/dist/{autocomplete-CxzetPOo.d.mts.map → autocomplete-CD30kSe_.d.mts.map} +1 -1
  74. package/dist/{box-DLEcEvDH.mjs → box-C_N_7ChP.mjs} +2 -2
  75. package/dist/box-C_N_7ChP.mjs.map +1 -0
  76. package/dist/builder-Chwtk0nQ.mjs +196 -0
  77. package/dist/builder-Chwtk0nQ.mjs.map +1 -0
  78. package/dist/{callbacks-D132G8dy.mjs → callbacks-DLecWn7G.mjs} +4 -4
  79. package/dist/{callbacks-D132G8dy.mjs.map → callbacks-DLecWn7G.mjs.map} +1 -1
  80. package/dist/client-CNGt-dOt.mjs +1 -0
  81. package/dist/{client-C2GXKfJ1.mjs → client-D7qz4TZt.mjs} +7 -3
  82. package/dist/client-D7qz4TZt.mjs.map +1 -0
  83. package/dist/color-DBMQLv4Y.mjs +37 -0
  84. package/dist/color-DBMQLv4Y.mjs.map +1 -0
  85. package/dist/{ctx-8Nuf5BrN.mjs → ctx-BaQ2hP5u.mjs} +3 -3
  86. package/dist/{ctx-8Nuf5BrN.mjs.map → ctx-BaQ2hP5u.mjs.map} +1 -1
  87. package/dist/ctx-CndlTp1T.mjs +1 -0
  88. package/dist/{divider-l0-JPEIm.mjs → divider-BlNNN2OS.mjs} +2 -2
  89. package/dist/divider-BlNNN2OS.mjs.map +1 -0
  90. package/dist/{files-BUsa-RVl.d.mts → files-B_5HDBPp.d.mts} +3 -3
  91. package/dist/{files-BUsa-RVl.d.mts.map → files-B_5HDBPp.d.mts.map} +1 -1
  92. package/dist/github-Cy2hfWJ7.mjs.map +1 -1
  93. package/dist/{github-D89A3F9U.d.mts → github-CyRwUQ3y.d.mts} +3 -3
  94. package/dist/{github-D89A3F9U.d.mts.map → github-CyRwUQ3y.d.mts.map} +1 -1
  95. package/dist/{image-34bU73bW.d.mts → image-BLls2F4t.d.mts} +2 -2
  96. package/dist/{image-34bU73bW.d.mts.map → image-BLls2F4t.d.mts.map} +1 -1
  97. package/dist/image-Cqtj3yRA.mjs +178 -0
  98. package/dist/image-Cqtj3yRA.mjs.map +1 -0
  99. package/dist/image.d.mts +1 -1
  100. package/dist/index.d.mts +13 -4
  101. package/dist/index.d.mts.map +1 -1
  102. package/dist/index.mjs +8 -7
  103. package/dist/index.mjs.map +1 -1
  104. package/dist/{input-D7fQEUdt.mjs → input-ET2YEMcl.mjs} +16 -11
  105. package/dist/input-ET2YEMcl.mjs.map +1 -0
  106. package/dist/{input-Dylds_sI.d.mts → input-NuD8TH8N.d.mts} +3 -3
  107. package/dist/{input-Dylds_sI.d.mts.map → input-NuD8TH8N.d.mts.map} +1 -1
  108. package/dist/{inspect-DPLRum7L.d.mts → inspect-B1uXxdKC.d.mts} +11 -15
  109. package/dist/inspect-B1uXxdKC.d.mts.map +1 -0
  110. package/dist/{inspect-CcgiZ_F9.mjs → inspect-Cxzs-W0g.mjs} +2 -2
  111. package/dist/{inspect-CcgiZ_F9.mjs.map → inspect-Cxzs-W0g.mjs.map} +1 -1
  112. package/dist/kitty-DKQYsQfH.mjs +1 -0
  113. package/dist/{log-Dy_QnPZF.mjs → log-B4djzy2m.mjs} +5 -5
  114. package/dist/log-B4djzy2m.mjs.map +1 -0
  115. package/dist/{logger-DvuX9DPS.mjs → logger-CvJCITzP.mjs} +3 -3
  116. package/dist/{logger-DvuX9DPS.mjs.map → logger-CvJCITzP.mjs.map} +1 -1
  117. package/dist/{markdown-BGPa7UzD.mjs → markdown-D3ZtRn6C.mjs} +9 -8
  118. package/dist/markdown-D3ZtRn6C.mjs.map +1 -0
  119. package/dist/markdown.d.mts +1 -1
  120. package/dist/markdown.d.mts.map +1 -1
  121. package/dist/markdown.mjs +1 -1
  122. package/dist/math-CU0wmC9N.mjs +1 -0
  123. package/dist/math-Dd7a1irv.mjs +206 -0
  124. package/dist/math-Dd7a1irv.mjs.map +1 -0
  125. package/dist/oklch-Bsh5swbC.mjs +99 -0
  126. package/dist/oklch-Bsh5swbC.mjs.map +1 -0
  127. package/dist/{overlay-9WXYiGgW.mjs → overlay-LvOjG7kn.mjs} +2 -2
  128. package/dist/{overlay-9WXYiGgW.mjs.map → overlay-LvOjG7kn.mjs.map} +1 -1
  129. package/dist/{picker-JL8lZfRH.d.mts → picker-B-OxKKnD.d.mts} +5 -5
  130. package/dist/{picker-JL8lZfRH.d.mts.map → picker-B-OxKKnD.d.mts.map} +1 -1
  131. package/dist/{picker-BqHINl_a.mjs → picker-f6xjgACX.mjs} +2 -2
  132. package/dist/{picker-BqHINl_a.mjs.map → picker-f6xjgACX.mjs.map} +1 -1
  133. package/dist/{queries-B_lOwEiE.mjs → queries-BUkBxkuM.mjs} +66 -3
  134. package/dist/queries-BUkBxkuM.mjs.map +1 -0
  135. package/dist/{queries-Cvalgu6P.d.mts → queries-C75-wG1B.d.mts} +42 -11
  136. package/dist/queries-C75-wG1B.d.mts.map +1 -0
  137. package/dist/{registry-3hLzS4ks.mjs → registry-DUWpSPoo.mjs} +208 -68
  138. package/dist/registry-DUWpSPoo.mjs.map +1 -0
  139. package/dist/{render-f7M2856V.mjs → render-B7LfNM5K.mjs} +2 -2
  140. package/dist/{render-f7M2856V.mjs.map → render-B7LfNM5K.mjs.map} +1 -1
  141. package/dist/{renderer-V6AGjbyf.mjs → renderer-BLsd-wrG.mjs} +167 -20
  142. package/dist/renderer-BLsd-wrG.mjs.map +1 -0
  143. package/dist/renderer-YHbR7JZ4.mjs +1 -0
  144. package/dist/{renderer-DesbRwjQ.mjs → renderer-aAtkFgll.mjs} +8 -7
  145. package/dist/renderer-aAtkFgll.mjs.map +1 -0
  146. package/dist/{select-zGd5pbiB.d.mts → select-BKE5LzdN.d.mts} +3 -3
  147. package/dist/{select-zGd5pbiB.d.mts.map → select-BKE5LzdN.d.mts.map} +1 -1
  148. package/dist/services/logger.d.mts +1 -1
  149. package/dist/services/logger.mjs +1 -1
  150. package/dist/services/notifier.d.mts +1 -1
  151. package/dist/services/notifier.mjs +2 -2
  152. package/dist/services/picker.d.mts +5 -5
  153. package/dist/services/picker.mjs +6 -6
  154. package/dist/services/prompt.d.mts +4 -4
  155. package/dist/services/prompt.mjs +5 -5
  156. package/dist/shiki/server.mjs +37 -14
  157. package/dist/shiki/server.mjs.map +1 -1
  158. package/dist/shiki-B4U0s8jT.mjs +635 -0
  159. package/dist/shiki-B4U0s8jT.mjs.map +1 -0
  160. package/dist/shiki-CJauRusM.mjs +20 -0
  161. package/dist/shiki-CJauRusM.mjs.map +1 -0
  162. package/dist/style-DslRHzI4.mjs +109 -0
  163. package/dist/style-DslRHzI4.mjs.map +1 -0
  164. package/dist/style.d.mts +4 -3
  165. package/dist/style.d.mts.map +1 -1
  166. package/dist/style.mjs +4 -4
  167. package/dist/{text-CRZD9KTN.mjs → text-BoJdKXLU.mjs} +2 -2
  168. package/dist/{text-CRZD9KTN.mjs.map → text-BoJdKXLU.mjs.map} +1 -1
  169. package/dist/{text-BefiXAFW.d.mts → text-CmxbA8lk.d.mts} +3 -3
  170. package/dist/{text-BefiXAFW.d.mts.map → text-CmxbA8lk.d.mts.map} +1 -1
  171. package/dist/{text-BLz1tRoC.mjs → text-DPrhma4x.mjs} +2 -2
  172. package/dist/text-DPrhma4x.mjs.map +1 -0
  173. package/dist/text.d.mts +1 -1
  174. package/dist/text.mjs +1 -1
  175. package/dist/theme-C8LkcoaK.mjs +61 -0
  176. package/dist/theme-C8LkcoaK.mjs.map +1 -0
  177. package/dist/theme-DVX8dvGG.mjs +1794 -0
  178. package/dist/theme-DVX8dvGG.mjs.map +1 -0
  179. package/dist/themes.d.mts +213 -73
  180. package/dist/themes.d.mts.map +1 -1
  181. package/dist/themes.mjs +1 -1
  182. package/dist/{tree-CArtDRec.d.mts → tree-CTvSpF9b.d.mts} +3 -3
  183. package/dist/{tree-CArtDRec.d.mts.map → tree-CTvSpF9b.d.mts.map} +1 -1
  184. package/dist/{types-C0EOLZDc.d.mts → types-C9ceMsbJ.d.mts} +137 -137
  185. package/dist/types-C9ceMsbJ.d.mts.map +1 -0
  186. package/dist/{widget-DtJU2-BJ.d.mts → widget-DlF32PRp.d.mts} +2 -2
  187. package/dist/{widget-DtJU2-BJ.d.mts.map → widget-DlF32PRp.d.mts.map} +1 -1
  188. package/dist/widgets/autocomplete.d.mts +1 -1
  189. package/dist/widgets/autocomplete.mjs +2 -2
  190. package/dist/widgets/box.d.mts +1 -1
  191. package/dist/widgets/box.mjs +1 -1
  192. package/dist/widgets/code.d.mts +4 -2
  193. package/dist/widgets/code.d.mts.map +1 -1
  194. package/dist/widgets/code.mjs +8 -7
  195. package/dist/widgets/code.mjs.map +1 -1
  196. package/dist/widgets/completions/actions.d.mts +1 -1
  197. package/dist/widgets/completions/files.d.mts +1 -1
  198. package/dist/widgets/completions/github.d.mts +1 -1
  199. package/dist/widgets/completions/index.d.mts +3 -3
  200. package/dist/widgets/diff.d.mts +2 -2
  201. package/dist/widgets/diff.d.mts.map +1 -1
  202. package/dist/widgets/diff.mjs +35 -12
  203. package/dist/widgets/diff.mjs.map +1 -1
  204. package/dist/widgets/divider.d.mts +3 -3
  205. package/dist/widgets/divider.mjs +1 -1
  206. package/dist/widgets/image.d.mts +1 -1
  207. package/dist/widgets/image.mjs +4 -4
  208. package/dist/widgets/image.mjs.map +1 -1
  209. package/dist/widgets/input.d.mts +1 -1
  210. package/dist/widgets/input.mjs +1 -1
  211. package/dist/widgets/log.d.mts +1 -1
  212. package/dist/widgets/log.mjs +1 -1
  213. package/dist/widgets/markdown.d.mts +4 -4
  214. package/dist/widgets/markdown.d.mts.map +1 -1
  215. package/dist/widgets/markdown.mjs +1 -1
  216. package/dist/widgets/overlay.d.mts +1 -1
  217. package/dist/widgets/overlay.mjs +1 -1
  218. package/dist/widgets/picker.d.mts +1 -1
  219. package/dist/widgets/picker.mjs +1 -1
  220. package/dist/widgets/progress.d.mts +4 -4
  221. package/dist/widgets/progress.mjs.map +1 -1
  222. package/dist/widgets/select.d.mts +1 -1
  223. package/dist/widgets/show.d.mts +1 -1
  224. package/dist/widgets/spinner.d.mts +2 -2
  225. package/dist/widgets/text.d.mts +1 -1
  226. package/dist/widgets/text.mjs +1 -1
  227. package/dist/widgets/tree.d.mts +1 -1
  228. package/dist/widgets/widget.d.mts +1 -1
  229. package/package.json +5 -7
  230. package/assets/themes/dracula-soft.json +0 -119
  231. package/assets/themes/github-dark.json +0 -123
  232. package/assets/themes/github-light.json +0 -123
  233. package/dist/ansi-Clq0ozyA.mjs.map +0 -1
  234. package/dist/box-DLEcEvDH.mjs.map +0 -1
  235. package/dist/builder-DC9byAmK.mjs +0 -386
  236. package/dist/builder-DC9byAmK.mjs.map +0 -1
  237. package/dist/client-C2GXKfJ1.mjs.map +0 -1
  238. package/dist/client-bzdHIDL2.mjs +0 -1
  239. package/dist/ctx-k0wTqeql.mjs +0 -1
  240. package/dist/divider-l0-JPEIm.mjs.map +0 -1
  241. package/dist/image-Cm5T-uw-.mjs +0 -108
  242. package/dist/image-Cm5T-uw-.mjs.map +0 -1
  243. package/dist/input-D7fQEUdt.mjs.map +0 -1
  244. package/dist/inspect-DPLRum7L.d.mts.map +0 -1
  245. package/dist/log-Dy_QnPZF.mjs.map +0 -1
  246. package/dist/markdown-BGPa7UzD.mjs.map +0 -1
  247. package/dist/queries-B_lOwEiE.mjs.map +0 -1
  248. package/dist/queries-Cvalgu6P.d.mts.map +0 -1
  249. package/dist/registry-3hLzS4ks.mjs.map +0 -1
  250. package/dist/renderer-BSMOuiLM.mjs +0 -1
  251. package/dist/renderer-DesbRwjQ.mjs.map +0 -1
  252. package/dist/renderer-V6AGjbyf.mjs.map +0 -1
  253. package/dist/shiki--ASSYv4_.mjs +0 -12
  254. package/dist/shiki--ASSYv4_.mjs.map +0 -1
  255. package/dist/shiki-D7l5--zz.mjs +0 -432
  256. package/dist/shiki-D7l5--zz.mjs.map +0 -1
  257. package/dist/text-BLz1tRoC.mjs.map +0 -1
  258. package/dist/theme.config-BKXX_noZ.mjs +0 -863
  259. package/dist/theme.config-BKXX_noZ.mjs.map +0 -1
  260. package/dist/types-C0EOLZDc.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";
@@ -5,7 +7,7 @@ import { basename } from "pathe";
5
7
  //#region assets/themes/tokyonight-moon.json
6
8
  var tokyonight_moon_default = {
7
9
  accent: "#ff966c",
8
- blend: "#222436",
10
+ bg: "#222436",
9
11
  border: "#589ed7",
10
12
  borderTitle: {
11
13
  "bold": true,
@@ -22,6 +24,7 @@ var tokyonight_moon_default = {
22
24
  diffDel: { "bg": "#4b2a3d" },
23
25
  divider: "#589ed7",
24
26
  error: "#c53b53",
27
+ fg: "#c8d3f5",
25
28
  gutter: "#3b4261",
26
29
  highlight: {
27
30
  "bg": "#2f334d",
@@ -102,7 +105,6 @@ var tokyonight_moon_default = {
102
105
  },
103
106
  selection: { "bg": "#2d3f76" },
104
107
  shiki: "tokyo-night",
105
- subtle: "#1e2030",
106
108
  success: "#4fd6be",
107
109
  syntaxBoolean: { "fg": "#65bcff" },
108
110
  syntaxBracket: { "fg": "#828bb8" },
@@ -113,16 +115,16 @@ var tokyonight_moon_default = {
113
115
  syntaxNumber: { "fg": "#ff966c" },
114
116
  syntaxSpecial: { "fg": "#65bcff" },
115
117
  syntaxString: { "fg": "#c3e88d" },
116
- text: "#c8d3f5",
117
118
  title: {
118
119
  "bold": true,
119
120
  "fg": "#82aaff"
120
121
  },
121
122
  ui: {
122
- "bg": "#222436",
123
+ "bg": "#1e2030",
123
124
  "fg": "#c8d3f5"
124
125
  },
125
- warn: "#ffc777"
126
+ warn: "#ffc777",
127
+ $schema: "https://raw.githubusercontent.com/folke/zaly/main/packages/tui/assets/schemas/theme.schema.json"
126
128
  };
127
129
  //#endregion
128
130
  //#region src/themes/builtin.ts
@@ -142,30 +144,45 @@ const importTheme = (path) => import(`#assets/themes/${path}.json`, { with: { ty
142
144
  * with no cast.
143
145
  */
144
146
  const builtin = {
147
+ andromeeda: () => importTheme("andromeeda"),
145
148
  "ayu-dark": () => importTheme("ayu-dark"),
149
+ "ayu-light": () => importTheme("ayu-light"),
150
+ "ayu-mirage": () => importTheme("ayu-mirage"),
146
151
  "catppuccin-frappe": () => importTheme("catppuccin-frappe"),
147
152
  "catppuccin-latte": () => importTheme("catppuccin-latte"),
148
153
  "catppuccin-macchiato": () => importTheme("catppuccin-macchiato"),
149
154
  "catppuccin-mocha": () => importTheme("catppuccin-mocha"),
155
+ "dark-plus": () => importTheme("dark-plus"),
150
156
  dracula: () => importTheme("dracula"),
151
- "dracula-soft": () => importTheme("dracula-soft"),
152
157
  "everforest-dark": () => importTheme("everforest-dark"),
153
158
  "everforest-light": () => importTheme("everforest-light"),
154
- "github-dark": () => importTheme("github-dark"),
155
- "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"),
156
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"),
157
167
  "kanagawa-dragon": () => importTheme("kanagawa-dragon"),
168
+ "kanagawa-lotus": () => importTheme("kanagawa-lotus"),
158
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"),
159
173
  "material-theme-palenight": () => importTheme("material-theme-palenight"),
160
174
  "min-dark": () => importTheme("min-dark"),
161
175
  "min-light": () => importTheme("min-light"),
162
176
  monokai: () => importTheme("monokai"),
163
177
  "night-owl": () => importTheme("night-owl"),
178
+ "night-owl-light": () => importTheme("night-owl-light"),
164
179
  nord: () => importTheme("nord"),
165
180
  "one-dark-pro": () => importTheme("one-dark-pro"),
166
181
  "one-light": () => importTheme("one-light"),
167
182
  poimandres: () => importTheme("poimandres"),
168
183
  "rose-pine": () => importTheme("rose-pine"),
184
+ "rose-pine-dawn": () => importTheme("rose-pine-dawn"),
185
+ "rose-pine-moon": () => importTheme("rose-pine-moon"),
169
186
  "solarized-dark": () => importTheme("solarized-dark"),
170
187
  "solarized-light": () => importTheme("solarized-light"),
171
188
  "synthwave-84": () => importTheme("synthwave-84"),
@@ -174,6 +191,7 @@ const builtin = {
174
191
  "tokyonight-night": () => importTheme("tokyonight-night"),
175
192
  "tokyonight-storm": () => importTheme("tokyonight-storm"),
176
193
  vesper: () => importTheme("vesper"),
194
+ "vitesse-black": () => importTheme("vitesse-black"),
177
195
  "vitesse-dark": () => importTheme("vitesse-dark"),
178
196
  "vitesse-light": () => importTheme("vitesse-light")
179
197
  };
@@ -187,10 +205,9 @@ const builtin = {
187
205
  * Distinct from `defaultTheme` — that's the precomputed `tokyonight-moon`
188
206
  * Theme bundled as the default palette for `createCtx()` etc.
189
207
  */
190
- const defaults = {
191
- primary: "blue",
192
- accent: "brightMagenta",
193
- text: "inherit",
208
+ const defaultsDark = {
209
+ appearance: "dark",
210
+ shiki: "auto",
194
211
  muted: { dim: true },
195
212
  quiet: {
196
213
  dim: true,
@@ -206,43 +223,24 @@ const defaults = {
206
223
  fg: "primary"
207
224
  },
208
225
  delim: "muted",
209
- subtle: "brightBlack",
210
- ui: { bg: "subtle" },
211
- overlay: { bg: "subtle" },
212
- highlight: { bg: "subtle" },
213
- divider: "subtle",
214
- selection: {
215
- bg: "brightBlue",
216
- fg: "black"
217
- },
218
- gutter: "subtle",
226
+ ui: { bg: "bg+3" },
227
+ overlay: { bg: "ui" },
228
+ highlight: { bg: "ui" },
229
+ divider: "bg-5",
230
+ gutter: "quiet",
219
231
  prompt: "inherit",
220
- border: "black",
232
+ border: "divider",
221
233
  borderTitle: "title",
222
- code: { bg: "subtle" },
234
+ code: { bg: "bg+3" },
223
235
  codeTitle: "title",
224
- success: "green",
225
- info: "cyan",
226
- warn: "yellow",
227
- error: "red",
228
- syntaxNumber: "brightBlue",
229
- syntaxString: "green",
230
- syntaxBoolean: "yellow",
231
- syntaxFunction: "blue",
232
- syntaxField: "white",
233
- syntaxConstant: "magenta",
234
- syntaxSpecial: "red",
235
236
  syntaxDelimiter: "delim",
236
237
  syntaxBracket: "delim",
237
238
  mdBold: { bold: true },
238
239
  mdCode: {
239
- bg: "primary+10",
240
- fg: "black"
241
- },
242
- mdCodeBlock: {
243
240
  bg: "highlight",
244
241
  fg: "primary"
245
242
  },
243
+ mdCodeBlock: "code",
246
244
  mdCodeBlockTitle: "title",
247
245
  mdHeading1: "mdHeading",
248
246
  mdHeading2: {
@@ -263,6 +261,7 @@ const defaults = {
263
261
  mdListBullet: "accent",
264
262
  mdListChecked: "primary",
265
263
  mdListUnchecked: "primary",
264
+ mdMath: { fg: "primary" },
266
265
  mdQuote: "muted",
267
266
  mdStrikethrough: { strikethrough: true },
268
267
  mdTable: "accent",
@@ -270,32 +269,170 @@ const defaults = {
270
269
  optionActive: "selection",
271
270
  optionDesc: "muted",
272
271
  optionName: "primary",
273
- diffAdd: {
274
- bg: "success-50",
275
- fg: "success"
276
- },
277
- diffContext: "muted",
278
- diffDel: {
279
- bg: "error-50",
280
- fg: "error"
281
- },
282
- diffLine: "gutter",
283
- 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" }
288
+ };
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"
284
306
  };
285
- const ansi = {
286
- id: "ansi",
287
- name: "ANSI",
288
- ...defaults,
289
- subtle: "inherit",
307
+ const defaultsAnsi = {
290
308
  divider: "brightBlue",
291
309
  border: "brightBlue",
292
310
  highlight: { bg: "brightBlack" },
293
- ui: { bg: "brightBlack" },
294
- selection: { inverse: true },
311
+ ui: {},
312
+ code: {},
295
313
  diffAdd: { fg: "success" },
296
314
  diffDel: { fg: "error" }
297
315
  };
298
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
299
436
  //#region src/themes/registry.ts
300
437
  const DEFAULT_THEME = "tokyonight-moon";
301
438
  /**
@@ -303,8 +440,10 @@ const DEFAULT_THEME = "tokyonight-moon";
303
440
  * registry never awaits — loaders return `Promise<Partial<Theme>>` so
304
441
  * callers `await` explicitly.
305
442
  */
306
- const themeRegistry = createRegistry("theme").from(builtin);
307
- themeRegistry.register("ansi", async () => ({ ...ansi }));
443
+ const themeRegistry = createRegistry("theme").from({
444
+ ...builtin,
445
+ system: async () => systemTheme()
446
+ });
308
447
  async function loadTheme(o) {
309
448
  o ??= DEFAULT_THEME;
310
449
  const opts = typeof o === "string" ? { name: o } : o;
@@ -319,14 +458,16 @@ async function loadTheme(o) {
319
458
  }
320
459
  /**
321
460
  * Fill defaults on a raw theme object. Built-in JSON is dev-controlled
322
- * so we don't pay typia's ~3MB of generated assertions at startup;
461
+ * so the standalone validator stays off the main startup path;
323
462
  * user-supplied JSON goes through `loadThemeFile` which validates.
324
463
  */
325
464
  function resolveTheme(theme, id) {
326
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";
327
469
  return {
328
- ...defaults,
329
- id,
470
+ ...appearance === "dark" ? defaultsDark : defaultsLight,
330
471
  name: id,
331
472
  ...rest
332
473
  };
@@ -336,19 +477,18 @@ function resolveTheme(theme, id) {
336
477
  * this is the escape hatch for CLIs that accept an explicit `--theme
337
478
  * /path/to/theme.json` argument.
338
479
  *
339
- * Async because typia's generated `validateTheme` (a few thousand
340
- * unrolled assertions) is dynamically imported here — it's only needed
341
- * 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.
342
482
  */
343
483
  async function loadThemeFile(path) {
344
484
  const raw = withError(() => readFileSync(path, "utf8"), `Failed to read theme file at ${path}`);
345
485
  const data = withError(() => JSON.parse(raw), `Failed to parse theme JSON at ${path}`);
346
- const { validateTheme } = await import("./theme.config-BKXX_noZ.mjs");
486
+ const { validateTheme } = await import("./theme-DVX8dvGG.mjs");
347
487
  return resolveTheme(validateTheme(data), basename(path, ".json"));
348
488
  }
349
489
  /** TokyoNight Moon — the default. Sourced from `assets/themes/tokyonight-moon.json`. */
350
490
  const defaultTheme = resolveTheme(tokyonight_moon_default, "tokyonight-moon");
351
491
  //#endregion
352
- export { loadTheme as n, themeRegistry as r, defaultTheme as t };
492
+ export { systemTheme as i, loadTheme as n, themeRegistry as r, defaultTheme as t };
353
493
 
354
- //# sourceMappingURL=registry-3hLzS4ks.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-8Nuf5BrN.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-f7M2856V.mjs.map
33
+ //# sourceMappingURL=render-B7LfNM5K.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-f7M2856V.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"}