silvery 0.19.1 → 0.21.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 (218) hide show
  1. package/README.md +9 -4
  2. package/dist/Text-Lq0dmj8-.mjs +239 -0
  3. package/dist/Text-Lq0dmj8-.mjs.map +1 -0
  4. package/dist/UPNG-Bo33r8rA.mjs +3 -0
  5. package/dist/UPNG-DosRPdF4.mjs +5075 -0
  6. package/dist/UPNG-DosRPdF4.mjs.map +1 -0
  7. package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs +6 -0
  8. package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs.map +1 -0
  9. package/dist/{animation-Cn64yepo.mjs → animation-ZMN2_XKv.mjs} +2 -2
  10. package/dist/animation-ZMN2_XKv.mjs.map +1 -0
  11. package/dist/{ansi-Cc33mW54.d.mts → ansi-2Xn0yatP.d.mts} +1 -1
  12. package/dist/{ansi-Cc33mW54.d.mts.map → ansi-2Xn0yatP.d.mts.map} +1 -1
  13. package/dist/{ansi-CLOitHKx.mjs → ansi-D1KQMAbf.mjs} +1 -1
  14. package/dist/{ansi-CLOitHKx.mjs.map → ansi-D1KQMAbf.mjs.map} +1 -1
  15. package/dist/ansi-yC4RyBNY.mjs +22441 -0
  16. package/dist/ansi-yC4RyBNY.mjs.map +1 -0
  17. package/dist/apng-CR08rIaH.mjs +58 -0
  18. package/dist/apng-CR08rIaH.mjs.map +1 -0
  19. package/dist/apng-DaHfVaVI.mjs +3 -0
  20. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  21. package/dist/assets/skia.darwin-arm64-DQs5sT6N.node +0 -0
  22. package/dist/backend-B-WYLUib.mjs +13396 -0
  23. package/dist/backend-B-WYLUib.mjs.map +1 -0
  24. package/dist/backends-CUtan80W.mjs +3 -0
  25. package/dist/backends-DIVYzKqd.mjs +1083 -0
  26. package/dist/backends-DIVYzKqd.mjs.map +1 -0
  27. package/dist/bound-term-0sPrrzH1.d.mts +4640 -0
  28. package/dist/bound-term-0sPrrzH1.d.mts.map +1 -0
  29. package/dist/canvas-1v7dPT-_.mjs +3 -0
  30. package/dist/canvas-CSuPOMNt.mjs +1442 -0
  31. package/dist/canvas-CSuPOMNt.mjs.map +1 -0
  32. package/dist/{chunk-Vs_PY4HZ.mjs → chunk-BSw8zbkd.mjs} +1 -1
  33. package/dist/cli-dvo0r2fs.mjs +4 -0
  34. package/dist/compare-CQodSH4G.mjs +376 -0
  35. package/dist/compare-CQodSH4G.mjs.map +1 -0
  36. package/dist/compare-DHlcxEYA.mjs +3 -0
  37. package/dist/context-BU5LkkIy.mjs.map +1 -1
  38. package/dist/devtools-CJdt5H0X.mjs +2 -0
  39. package/dist/{devtools-DxkSLXDA.mjs → devtools-DcQjgyjL.mjs} +5 -4
  40. package/dist/{devtools-DxkSLXDA.mjs.map → devtools-DcQjgyjL.mjs.map} +1 -1
  41. package/dist/easing-BI-ASGMO.d.mts +24 -0
  42. package/dist/easing-BI-ASGMO.d.mts.map +1 -0
  43. package/dist/{eta-Bb3RH3wh.mjs → eta-CJlGH06n.mjs} +1 -1
  44. package/dist/{eta-Bb3RH3wh.mjs.map → eta-CJlGH06n.mjs.map} +1 -1
  45. package/dist/flexily-zero-adapter-C3Vj0fPt.mjs +306 -0
  46. package/dist/flexily-zero-adapter-C3Vj0fPt.mjs.map +1 -0
  47. package/dist/{flexily-zero-adapter-CMxXhdOL.mjs → flexily-zero-adapter-C4lW_Ov5.mjs} +1 -1
  48. package/dist/fonts-BFmhXDv7.mjs +88 -0
  49. package/dist/fonts-BFmhXDv7.mjs.map +1 -0
  50. package/dist/gif-C_AjaT9d.mjs +188 -0
  51. package/dist/gif-C_AjaT9d.mjs.map +1 -0
  52. package/dist/gif-DaC4XrxA.mjs +3 -0
  53. package/dist/gifenc-BOUT-KFB.mjs +730 -0
  54. package/dist/gifenc-BOUT-KFB.mjs.map +1 -0
  55. package/dist/image-C2Birh2x.mjs +1252 -0
  56. package/dist/image-C2Birh2x.mjs.map +1 -0
  57. package/dist/index-BUMxS65f.d.mts +453 -0
  58. package/dist/index-BUMxS65f.d.mts.map +1 -0
  59. package/dist/{index-D3saHouR.d.mts → index-CSQf13CI.d.mts} +1057 -1133
  60. package/dist/index-CSQf13CI.d.mts.map +1 -0
  61. package/dist/{index-BXslOebb.d.mts → index-Cl9KKjQ_.d.mts} +4919 -3921
  62. package/dist/index-Cl9KKjQ_.d.mts.map +1 -0
  63. package/dist/index-XbNrPhWl.d.mts +336 -0
  64. package/dist/index-XbNrPhWl.d.mts.map +1 -0
  65. package/dist/index.d.mts +8 -5
  66. package/dist/index.d.mts.map +1 -1
  67. package/dist/index.mjs +14 -12
  68. package/dist/index.mjs.map +1 -1
  69. package/dist/key-mapping-CS-YD_cD.mjs +132 -0
  70. package/dist/key-mapping-CS-YD_cD.mjs.map +1 -0
  71. package/dist/key-mapping-Yn-Jgrij.mjs +3 -0
  72. package/dist/{layout-engine-B6Cdz1yZ.mjs → layout-engine-C07LEXWT.mjs} +1 -1
  73. package/dist/layout-engine-C2px0RJE.mjs +67 -0
  74. package/dist/layout-engine-C2px0RJE.mjs.map +1 -0
  75. package/dist/layout-signals-Cnw6xk8Q.mjs +988 -0
  76. package/dist/layout-signals-Cnw6xk8Q.mjs.map +1 -0
  77. package/dist/mouse-events-Dki3ISIp.mjs +1044 -0
  78. package/dist/mouse-events-Dki3ISIp.mjs.map +1 -0
  79. package/dist/{multi-progress-Bq9Oi_WI.mjs → multi-progress-CIRjrzma.mjs} +3 -3
  80. package/dist/{multi-progress-Bq9Oi_WI.mjs.map → multi-progress-CIRjrzma.mjs.map} +1 -1
  81. package/dist/{multi-progress-DAQC7eap.d.mts → multi-progress-DHZ2xUT2.d.mts} +2 -2
  82. package/dist/{multi-progress-DAQC7eap.d.mts.map → multi-progress-DHZ2xUT2.d.mts.map} +1 -1
  83. package/dist/{node-BeWlnCPY.mjs → node-CjM5Rt-M.mjs} +4 -4
  84. package/dist/node-CjM5Rt-M.mjs.map +1 -0
  85. package/dist/playwright-D5YiZcNS.mjs +76397 -0
  86. package/dist/playwright-D5YiZcNS.mjs.map +1 -0
  87. package/dist/png-codec-Dp84742B.mjs +36 -0
  88. package/dist/png-codec-Dp84742B.mjs.map +1 -0
  89. package/dist/png-codec-QwOtJ8Zs.mjs +3 -0
  90. package/dist/progress-DB_Xo071.mjs +675 -0
  91. package/dist/progress-DB_Xo071.mjs.map +1 -0
  92. package/dist/{progress-bar-CXE5Qfkd.mjs → progress-bar-oJwq22CR.mjs} +4 -4
  93. package/dist/{progress-bar-CXE5Qfkd.mjs.map → progress-bar-oJwq22CR.mjs.map} +1 -1
  94. package/dist/rasterizer-BRXrDdWx.mjs +3 -0
  95. package/dist/rasterizer-CpEhJvdR.mjs +296 -0
  96. package/dist/rasterizer-CpEhJvdR.mjs.map +1 -0
  97. package/dist/reconciler-DldIJB93.mjs +2083 -0
  98. package/dist/reconciler-DldIJB93.mjs.map +1 -0
  99. package/dist/{render-string-0mN37DLf.mjs → render-string-BcoCpjCB.mjs} +1 -1
  100. package/dist/{render-string-X-CxpTdZ.mjs → render-string-DkQacASz.mjs} +2728 -555
  101. package/dist/render-string-DkQacASz.mjs.map +1 -0
  102. package/dist/resvg-js-DkOndZI3.mjs +203 -0
  103. package/dist/resvg-js-DkOndZI3.mjs.map +1 -0
  104. package/dist/runtime.d.mts +3 -2
  105. package/dist/runtime.mjs +3 -3
  106. package/dist/schemes-JjNp4aSl.mjs +2611 -0
  107. package/dist/schemes-JjNp4aSl.mjs.map +1 -0
  108. package/dist/{spinner-CGo34vyR.d.mts → spinner-CZINHpkV.d.mts} +2 -2
  109. package/dist/{spinner-CGo34vyR.d.mts.map → spinner-CZINHpkV.d.mts.map} +1 -1
  110. package/dist/{spinner-CeOmcuw_.mjs → spinner-D9lrHr8s.mjs} +7 -7
  111. package/dist/spinner-D9lrHr8s.mjs.map +1 -0
  112. package/dist/src-5w9QR6_8.mjs +1071 -0
  113. package/dist/src-5w9QR6_8.mjs.map +1 -0
  114. package/dist/src-BNTToU7l.mjs +4387 -0
  115. package/dist/src-BNTToU7l.mjs.map +1 -0
  116. package/dist/{src-Bd7ezSgG.mjs → src-BR4xNwdG.mjs} +10436 -2622
  117. package/dist/src-BR4xNwdG.mjs.map +1 -0
  118. package/dist/{types-Bk2yw9Qj.mjs → src-DKp-_OFG.mjs} +34 -94
  119. package/dist/src-DKp-_OFG.mjs.map +1 -0
  120. package/dist/src-bt8wSrfJ.mjs +258 -0
  121. package/dist/src-bt8wSrfJ.mjs.map +1 -0
  122. package/dist/src-e33Y6kNJ.mjs +3 -0
  123. package/dist/src-iDwu25UD.mjs +1814 -0
  124. package/dist/src-iDwu25UD.mjs.map +1 -0
  125. package/dist/steps-Bp2uNqnn.d.mts +202 -0
  126. package/dist/steps-Bp2uNqnn.d.mts.map +1 -0
  127. package/dist/svg-15lZZzxq.mjs +486 -0
  128. package/dist/svg-15lZZzxq.mjs.map +1 -0
  129. package/dist/svg-Cz0UXcDj.mjs +255 -0
  130. package/dist/svg-Cz0UXcDj.mjs.map +1 -0
  131. package/dist/svg-DY72a4HK.mjs +3 -0
  132. package/dist/svg-g1D6ErwR.d.mts +82 -0
  133. package/dist/svg-g1D6ErwR.d.mts.map +1 -0
  134. package/dist/term.d.mts +3 -0
  135. package/dist/term.mjs +9 -0
  136. package/dist/term.mjs.map +1 -0
  137. package/dist/theme.d.mts +95 -2
  138. package/dist/theme.d.mts.map +1 -0
  139. package/dist/theme.mjs +9 -3
  140. package/dist/theme.mjs.map +1 -0
  141. package/dist/{types-BH_v3iMT.d.mts → types-kt_fKR37.d.mts} +2 -15
  142. package/dist/types-kt_fKR37.d.mts.map +1 -0
  143. package/dist/ui/animation.d.mts +2 -1
  144. package/dist/ui/animation.mjs +1 -1
  145. package/dist/ui/ansi.d.mts +1 -1
  146. package/dist/ui/ansi.mjs +1 -1
  147. package/dist/ui/cli.d.mts +3 -3
  148. package/dist/ui/cli.mjs +5 -5
  149. package/dist/ui/display.d.mts +1 -1
  150. package/dist/ui/image.d.mts +2 -2
  151. package/dist/ui/image.mjs +2 -2
  152. package/dist/ui/input.d.mts +1 -1
  153. package/dist/ui/input.mjs +4 -2
  154. package/dist/ui/input.mjs.map +1 -1
  155. package/dist/ui/progress.d.mts +5 -249
  156. package/dist/ui/progress.mjs +5 -858
  157. package/dist/ui/react.d.mts +1 -1
  158. package/dist/ui/react.mjs +2 -2
  159. package/dist/ui/recording-chrome-react.d.mts +21 -0
  160. package/dist/ui/recording-chrome-react.d.mts.map +1 -0
  161. package/dist/ui/recording-chrome-react.mjs +105 -0
  162. package/dist/ui/recording-chrome-react.mjs.map +1 -0
  163. package/dist/ui/recording-chrome.d.mts +2 -0
  164. package/dist/ui/recording-chrome.mjs +2 -0
  165. package/dist/ui/utils.mjs +1 -1
  166. package/dist/ui/wrappers.d.mts +3 -3
  167. package/dist/ui/wrappers.mjs +2 -2
  168. package/dist/ui.d.mts +7 -6
  169. package/dist/ui.mjs +8 -7
  170. package/dist/{useLatest-Bg2x4bfP.d.mts → useLatest-DRDDVwjh.d.mts} +5 -25
  171. package/dist/useLatest-DRDDVwjh.d.mts.map +1 -0
  172. package/dist/{with-text-input-CRfoiFFG.d.mts → with-text-input-YeohVLeo.d.mts} +4 -55
  173. package/dist/with-text-input-YeohVLeo.d.mts.map +1 -0
  174. package/dist/wrapper-C70ATkVv.mjs +3527 -0
  175. package/dist/wrapper-C70ATkVv.mjs.map +1 -0
  176. package/dist/{wrappers-UTADQkSY.mjs → wrappers-BCUYITrY.mjs} +5 -157
  177. package/dist/wrappers-BCUYITrY.mjs.map +1 -0
  178. package/dist/{yoga-adapter-8oRGRw8V.mjs → yoga-adapter-BnZX1PAY.mjs} +28 -2
  179. package/dist/yoga-adapter-BnZX1PAY.mjs.map +1 -0
  180. package/dist/yoga-adapter-DxgsQ_gg.mjs +2 -0
  181. package/dist/zipBundle-3nqeDRtm.mjs +3 -0
  182. package/dist/zipBundle-VNAYFmqJ.mjs +2003 -0
  183. package/dist/zipBundle-VNAYFmqJ.mjs.map +1 -0
  184. package/package.json +20 -9
  185. package/dist/animation-Cn64yepo.mjs.map +0 -1
  186. package/dist/cli-BKp0YtBD.mjs +0 -4
  187. package/dist/devtools-9QY4teqI.mjs +0 -2
  188. package/dist/flexily-zero-adapter-BlQa46nr.mjs +0 -3385
  189. package/dist/flexily-zero-adapter-BlQa46nr.mjs.map +0 -1
  190. package/dist/image-CTII5QWI.mjs +0 -477
  191. package/dist/image-CTII5QWI.mjs.map +0 -1
  192. package/dist/index-BXslOebb.d.mts.map +0 -1
  193. package/dist/index-BnA7mNpo.d.mts +0 -175
  194. package/dist/index-BnA7mNpo.d.mts.map +0 -1
  195. package/dist/index-D3saHouR.d.mts.map +0 -1
  196. package/dist/layout-engine-ClUgv6jB.mjs +0 -50
  197. package/dist/layout-engine-ClUgv6jB.mjs.map +0 -1
  198. package/dist/node-BeWlnCPY.mjs.map +0 -1
  199. package/dist/reconciler-Cwgm8hRR.mjs +0 -8459
  200. package/dist/reconciler-Cwgm8hRR.mjs.map +0 -1
  201. package/dist/render-string-X-CxpTdZ.mjs.map +0 -1
  202. package/dist/spinner-CeOmcuw_.mjs.map +0 -1
  203. package/dist/src-B5GjfG7g.mjs +0 -4305
  204. package/dist/src-B5GjfG7g.mjs.map +0 -1
  205. package/dist/src-Bd7ezSgG.mjs.map +0 -1
  206. package/dist/src-CChwjk0Z.mjs +0 -738
  207. package/dist/src-CChwjk0Z.mjs.map +0 -1
  208. package/dist/src-NCKb8kE5.mjs +0 -2660
  209. package/dist/src-NCKb8kE5.mjs.map +0 -1
  210. package/dist/types-BH_v3iMT.d.mts.map +0 -1
  211. package/dist/types-Bk2yw9Qj.mjs.map +0 -1
  212. package/dist/ui/progress.d.mts.map +0 -1
  213. package/dist/ui/progress.mjs.map +0 -1
  214. package/dist/useLatest-Bg2x4bfP.d.mts.map +0 -1
  215. package/dist/with-text-input-CRfoiFFG.d.mts.map +0 -1
  216. package/dist/wrappers-UTADQkSY.mjs.map +0 -1
  217. package/dist/yoga-adapter-8oRGRw8V.mjs.map +0 -1
  218. package/dist/yoga-adapter-D_CcxSt5.mjs +0 -2
@@ -1,2660 +0,0 @@
1
- import { i as __require, n as __esmMin } from "./chunk-Vs_PY4HZ.mjs";
2
- import "string-width";
3
- import { blend, brighten, checkContrast, colorDistance, complement, contrastFg, darken, deltaE, ensureContrast, hexToOklch, hexToRgb as hexToRgb$1, oklchToHex } from "@silvery/color";
4
- //#region packages/ansi/src/detection.ts
5
- /**
6
- * Detect if terminal supports cursor control (repositioning).
7
- * Returns false for dumb terminals and piped output.
8
- */
9
- function detectCursor(stdout) {
10
- if (!stdout.isTTY) return false;
11
- if (process.env.TERM === "dumb") return false;
12
- return true;
13
- }
14
- /**
15
- * Detect if terminal can read raw keystrokes.
16
- * Requires stdin to be a TTY with raw mode support.
17
- */
18
- function detectInput(stdin) {
19
- if (!stdin.isTTY) return false;
20
- return typeof stdin.setRawMode === "function";
21
- }
22
- /**
23
- * Detect color level supported by terminal.
24
- * Returns null if no color support.
25
- *
26
- * Checks (in order):
27
- * 1. NO_COLOR env var - forces no color
28
- * 2. FORCE_COLOR env var - forces color level
29
- * 3. COLORTERM=truecolor - truecolor support
30
- * 4. TERM patterns - detect from terminal type
31
- * 5. CI detection - basic colors in CI
32
- */
33
- function detectColor(stdout) {
34
- if (process.env.NO_COLOR !== void 0) return null;
35
- const forceColor = process.env.FORCE_COLOR;
36
- if (forceColor !== void 0) {
37
- if (forceColor === "0" || forceColor === "false") return null;
38
- if (forceColor === "1") return "basic";
39
- if (forceColor === "2") return "256";
40
- if (forceColor === "3") return "truecolor";
41
- return "basic";
42
- }
43
- if (!stdout.isTTY) return null;
44
- if (process.env.TERM === "dumb") return null;
45
- const colorTerm = process.env.COLORTERM;
46
- if (colorTerm === "truecolor" || colorTerm === "24bit") return "truecolor";
47
- const term = process.env.TERM ?? "";
48
- if (term.includes("truecolor") || term.includes("24bit") || term.includes("xterm-ghostty") || term.includes("xterm-kitty") || term.includes("wezterm")) return "truecolor";
49
- if (term.includes("256color") || term.includes("256")) return "256";
50
- const termProgram = process.env.TERM_PROGRAM;
51
- if (termProgram === "iTerm.app" || termProgram === "Apple_Terminal") return termProgram === "iTerm.app" ? "truecolor" : "256";
52
- if (termProgram === "Ghostty" || termProgram === "WezTerm") return "truecolor";
53
- if (process.env.KITTY_WINDOW_ID) return "truecolor";
54
- if (term.includes("xterm") || term.includes("color") || term.includes("ansi")) return "basic";
55
- if (CI_ENVS.some((env) => process.env[env] !== void 0)) return "basic";
56
- if (process.env.WT_SESSION) return "truecolor";
57
- return "basic";
58
- }
59
- /**
60
- * Detect if terminal can render unicode symbols.
61
- * Based on TERM, locale, and known terminal apps.
62
- */
63
- function detectUnicode() {
64
- if (process.env.CI) {
65
- if (process.env.GITHUB_ACTIONS) return true;
66
- }
67
- const lang = process.env.LANG ?? process.env.LC_ALL ?? process.env.LC_CTYPE ?? "";
68
- if (lang.toLowerCase().includes("utf-8") || lang.toLowerCase().includes("utf8")) return true;
69
- if (process.env.WT_SESSION) return true;
70
- const termProgram = process.env.TERM_PROGRAM ?? "";
71
- if ([
72
- "iTerm.app",
73
- "Ghostty",
74
- "WezTerm",
75
- "Apple_Terminal"
76
- ].includes(termProgram)) return true;
77
- if (process.env.KITTY_WINDOW_ID) return true;
78
- const term = process.env.TERM ?? "";
79
- if (term.includes("xterm") || term.includes("rxvt") || term.includes("screen") || term.includes("tmux")) return true;
80
- return false;
81
- }
82
- /**
83
- * Default capabilities (assumes modern terminal with full support).
84
- */
85
- function defaultCaps() {
86
- return {
87
- program: "",
88
- term: "",
89
- colorLevel: "truecolor",
90
- kittyKeyboard: false,
91
- kittyGraphics: false,
92
- sixel: false,
93
- osc52: false,
94
- hyperlinks: false,
95
- notifications: false,
96
- bracketedPaste: true,
97
- mouse: true,
98
- syncOutput: false,
99
- unicode: true,
100
- underlineStyles: true,
101
- underlineColor: true,
102
- textEmojiWide: true,
103
- textSizingSupported: false,
104
- darkBackground: true,
105
- nerdfont: false
106
- };
107
- }
108
- /**
109
- * Check if macOS is in dark mode by reading the system appearance preference.
110
- * Uses `defaults read -g AppleInterfaceStyle` — returns "Dark" when dark mode
111
- * is active, exits non-zero when light mode. ~2ms via spawnSync.
112
- *
113
- * Result is cached after first call to avoid repeated process spawns.
114
- */
115
- function detectMacOSDarkMode() {
116
- if (cachedMacOSDarkMode !== void 0) return cachedMacOSDarkMode;
117
- try {
118
- const { spawnSync } = __require("child_process");
119
- cachedMacOSDarkMode = spawnSync("defaults", [
120
- "read",
121
- "-g",
122
- "AppleInterfaceStyle"
123
- ], {
124
- encoding: "utf-8",
125
- timeout: 500
126
- }).stdout?.trim() === "Dark";
127
- } catch {
128
- cachedMacOSDarkMode = false;
129
- }
130
- return cachedMacOSDarkMode;
131
- }
132
- /** Detect terminal capabilities from environment variables.
133
- * Synchronous. Minimal I/O: may run `defaults` on macOS for Apple_Terminal.
134
- */
135
- function detectTerminalCaps() {
136
- const program = process.env.TERM_PROGRAM ?? "";
137
- const term = process.env.TERM ?? "";
138
- const colorTerm = process.env.COLORTERM ?? "";
139
- const noColor = process.env.NO_COLOR !== void 0;
140
- const isAppleTerminal = program === "Apple_Terminal";
141
- let colorLevel = "none";
142
- if (!noColor) {
143
- if (isAppleTerminal) colorLevel = "256";
144
- else if (colorTerm === "truecolor" || colorTerm === "24bit") colorLevel = "truecolor";
145
- else if (term.includes("256color")) colorLevel = "256";
146
- else if (process.stdout?.isTTY) colorLevel = "basic";
147
- }
148
- const isKitty = term === "xterm-kitty";
149
- const isITerm = program === "iTerm.app";
150
- const isGhostty = program === "ghostty";
151
- const isWezTerm = program === "WezTerm";
152
- const isAlacritty = program === "Alacritty";
153
- const isFoot = term === "foot" || term === "foot-extra";
154
- const isModern = isKitty || isITerm || isGhostty || isWezTerm || isFoot;
155
- let isKittyWithTextSizing = false;
156
- if (isKitty) {
157
- const parts = (process.env.TERM_PROGRAM_VERSION ?? "").split(".");
158
- const major = Number(parts[0]) || 0;
159
- const minor = Number(parts[1]) || 0;
160
- isKittyWithTextSizing = major > 0 || major === 0 && minor >= 40;
161
- }
162
- let darkBackground = !isAppleTerminal;
163
- const colorFgBg = process.env.COLORFGBG;
164
- if (colorFgBg) {
165
- const parts = colorFgBg.split(";");
166
- const bg = parseInt(parts[parts.length - 1] ?? "", 10);
167
- if (!isNaN(bg)) darkBackground = bg < 7;
168
- } else if (isAppleTerminal) darkBackground = detectMacOSDarkMode();
169
- let nerdfont = isModern || isAlacritty;
170
- const nfEnv = process.env.NERDFONT;
171
- if (nfEnv === "0" || nfEnv === "false") nerdfont = false;
172
- else if (nfEnv === "1" || nfEnv === "true") nerdfont = true;
173
- const underlineExtensions = isModern || isAlacritty;
174
- return {
175
- program,
176
- term,
177
- colorLevel,
178
- kittyKeyboard: isKitty || isGhostty || isWezTerm || isFoot,
179
- kittyGraphics: isKitty || isGhostty,
180
- sixel: isFoot || isWezTerm,
181
- osc52: isModern || isAlacritty,
182
- hyperlinks: isModern || isAlacritty,
183
- notifications: isITerm || isKitty,
184
- bracketedPaste: true,
185
- mouse: true,
186
- syncOutput: isModern || isAlacritty,
187
- unicode: true,
188
- underlineStyles: underlineExtensions,
189
- underlineColor: underlineExtensions,
190
- textEmojiWide: !isAppleTerminal,
191
- textSizingSupported: isKittyWithTextSizing,
192
- darkBackground,
193
- nerdfont
194
- };
195
- }
196
- var CI_ENVS, cachedMacOSDarkMode;
197
- var init_detection = __esmMin((() => {
198
- CI_ENVS = [
199
- "CI",
200
- "GITHUB_ACTIONS",
201
- "GITLAB_CI",
202
- "JENKINS_URL",
203
- "BUILDKITE",
204
- "CIRCLECI",
205
- "TRAVIS"
206
- ];
207
- }));
208
- //#endregion
209
- //#region packages/ansi/src/sgr-codes.ts
210
- /**
211
- * SGR (Select Graphic Rendition) color code helpers.
212
- *
213
- * Shared by buffer.ts (styleToAnsiCodes) and output-phase.ts (styleTransition).
214
- * Emits the shortest possible SGR code string for a given color.
215
- */
216
- /**
217
- * Emit the shortest SGR code string for a foreground color.
218
- * - Basic 0-7: 4-bit code (30+N)
219
- * - Extended 8-255: 256-color (38;5;N)
220
- * - RGB: true color (38;2;R;G;B)
221
- */
222
- function fgColorCode(color) {
223
- if (typeof color === "number") {
224
- if (color >= 0 && color <= 7) return `${30 + color}`;
225
- return `38;5;${color}`;
226
- }
227
- return `38;2;${color.r};${color.g};${color.b}`;
228
- }
229
- /**
230
- * Emit the shortest SGR code string for a background color.
231
- * - Basic 0-7: 4-bit code (40+N)
232
- * - Extended 8-255: 256-color (48;5;N)
233
- * - RGB: true color (48;2;R;G;B)
234
- */
235
- function bgColorCode(color) {
236
- if (typeof color === "number") {
237
- if (color >= 0 && color <= 7) return `${40 + color}`;
238
- return `48;5;${color}`;
239
- }
240
- return `48;2;${color.r};${color.g};${color.b}`;
241
- }
242
- var init_sgr_codes = __esmMin((() => {}));
243
- //#endregion
244
- //#region packages/ansi/src/utils.ts
245
- var init_utils = __esmMin((() => {}));
246
- //#endregion
247
- //#region packages/ansi/src/color-maps.ts
248
- /** Find nearest ANSI 16 color index for an RGB value. */
249
- function nearestAnsi16(r, g, b) {
250
- let bestIdx = 0;
251
- let bestDist = Infinity;
252
- for (let i = 0; i < 16; i++) {
253
- const [cr, cg, cb] = ANSI_16_COLORS[i];
254
- const dist = (r - cr) ** 2 + (g - cg) ** 2 + (b - cb) ** 2;
255
- if (dist < bestDist) {
256
- bestDist = dist;
257
- bestIdx = i;
258
- }
259
- }
260
- return bestIdx;
261
- }
262
- /** Convert RGB to 256-color index (using the 6x6x6 color cube). */
263
- function rgbToAnsi256(r, g, b) {
264
- if (r === g && g === b) {
265
- if (r < 8) return 16;
266
- if (r > 248) return 231;
267
- return Math.round((r - 8) / 247 * 24) + 232;
268
- }
269
- const ri = Math.round(r / 255 * 5);
270
- const gi = Math.round(g / 255 * 5);
271
- const bi = Math.round(b / 255 * 5);
272
- return 16 + 36 * ri + 6 * gi + bi;
273
- }
274
- /**
275
- * Generate SGR foreground code for an RGB color at the given color level.
276
- * Returns the SGR parameter string (e.g., "31" or "38;5;196" or "38;2;255;0;0").
277
- */
278
- function fgFromRgb(r, g, b, level) {
279
- if (level === "truecolor") return `38;2;${r};${g};${b}`;
280
- if (level === "256") return `38;5;${rgbToAnsi256(r, g, b)}`;
281
- const idx = nearestAnsi16(r, g, b);
282
- return idx < 8 ? `${30 + idx}` : `${82 + idx}`;
283
- }
284
- /**
285
- * Generate SGR background code for an RGB color at the given color level.
286
- */
287
- function bgFromRgb(r, g, b, level) {
288
- if (level === "truecolor") return `48;2;${r};${g};${b}`;
289
- if (level === "256") return `48;5;${rgbToAnsi256(r, g, b)}`;
290
- const idx = nearestAnsi16(r, g, b);
291
- return idx < 8 ? `${40 + idx}` : `${92 + idx}`;
292
- }
293
- /**
294
- * Convert a 256-palette index back to its canonical xterm hex value.
295
- *
296
- * Mirrors `rgbToAnsi256`:
297
- * - 16–231: 6×6×6 color cube. Index = 16 + 36·r + 6·g + b (each channel 0..5).
298
- * - 232–255: 24-step grayscale ramp.
299
- * - 0–15: ANSI 16 slots (reuses ANSI16_SLOT_HEX for exact parity with
300
- * `nearestAnsi16`).
301
- */
302
- function ansi256ToHex(idx) {
303
- if (idx < 0 || idx > 255 || !Number.isInteger(idx)) return "#000000";
304
- if (idx < 16) {
305
- const [r, g, b] = ANSI_16_COLORS[idx];
306
- return rgbToHexHash(r, g, b);
307
- }
308
- if (idx < 232) {
309
- const levels = [
310
- 0,
311
- 95,
312
- 135,
313
- 175,
314
- 215,
315
- 255
316
- ];
317
- const i = idx - 16;
318
- const r = levels[Math.floor(i / 36)];
319
- const g = levels[Math.floor(i % 36 / 6)];
320
- const b = levels[i % 6];
321
- return rgbToHexHash(r, g, b);
322
- }
323
- const gray = 8 + (idx - 232) * 10;
324
- return rgbToHexHash(gray, gray, gray);
325
- }
326
- function rgbToHexHash(r, g, b) {
327
- const h = (n) => n.toString(16).padStart(2, "0");
328
- return `#${h(r)}${h(g)}${h(b)}`;
329
- }
330
- function parseHexLocal(hex) {
331
- if (typeof hex !== "string") return null;
332
- let s = hex.trim();
333
- if (s.startsWith("#")) s = s.slice(1);
334
- if (s.length === 3) s = s.split("").map((c) => c + c).join("");
335
- if (s.length !== 6) return null;
336
- const r = parseInt(s.slice(0, 2), 16);
337
- const g = parseInt(s.slice(2, 4), 16);
338
- const b = parseInt(s.slice(4, 6), 16);
339
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
340
- return [
341
- r,
342
- g,
343
- b
344
- ];
345
- }
346
- /**
347
- * Hex-in / hex-out quantization for previews.
348
- *
349
- * Takes any hex color and returns the hex a real terminal at that tier would
350
- * actually emit. Used by the Sterling storybook to make the `1/2/3/4` tier
351
- * toggle visibly different in-process — the output phase already does this
352
- * when writing to a real TTY, but preview surfaces (theme swatches, rendered
353
- * components inside a storybook app) bypass output-phase quantization. Apply
354
- * `quantizeHex` at render time to mimic tier-specific terminal output.
355
- *
356
- * - `truecolor`: returns the input unchanged (normalized to `#rrggbb`).
357
- * - `256`: snaps to the nearest xterm-256 slot, then returns that slot's hex.
358
- * - `ansi16`: snaps to one of the 16 standard slots (canonical xterm RGB).
359
- * - `mono`: luminance threshold (>= 0.5 → `#ffffff`, else `#000000`).
360
- *
361
- * Returns the input unchanged if it cannot be parsed as a hex color.
362
- */
363
- function quantizeHex(hex, tier) {
364
- const rgb = parseHexLocal(hex);
365
- if (!rgb) return hex;
366
- const [r, g, b] = rgb;
367
- if (tier === "truecolor") return rgbToHexHash(r, g, b);
368
- if (tier === "256") return ansi256ToHex(rgbToAnsi256(r, g, b));
369
- if (tier === "ansi16") {
370
- const [cr, cg, cb] = ANSI_16_COLORS[nearestAnsi16(r, g, b)];
371
- return rgbToHexHash(cr, cg, cb);
372
- }
373
- return (.2126 * r + .7152 * g + .0722 * b) / 255 >= .5 ? "#ffffff" : "#000000";
374
- }
375
- function isHexLeaf$1(value) {
376
- return typeof value === "string" && HEX_LEAF_RE$1.test(value);
377
- }
378
- /**
379
- * Pre-quantize every hex leaf in a Theme (or any object tree) to the
380
- * requested color tier.
381
- *
382
- * Walks the input recursively — each string leaf matching `#rgb` / `#rrggbb`
383
- * is passed through {@link quantizeHex}; all other values (numbers, booleans,
384
- * non-hex strings like `"Nord"`, null/undefined, arrays of non-hex values)
385
- * pass through unchanged. Arrays and nested objects are rebuilt with
386
- * quantized leaves.
387
- *
388
- * Works on both the legacy ANSI Theme (flat hex tokens + `palette` array)
389
- * and the Sterling Theme (nested roles + flat tokens) — the structural rule
390
- * "any leaf that looks like a hex is a color value" holds for both.
391
- *
392
- * @example Pre-cache tier variants
393
- * ```ts
394
- * import { pickColorLevel } from "silvery"
395
- *
396
- * const themes = {
397
- * truecolor: theme,
398
- * ansi16: pickColorLevel(theme, "ansi16"),
399
- * mono: pickColorLevel(theme, "mono"),
400
- * }
401
- * ```
402
- *
403
- * @example Storybook — show multiple tiers simultaneously
404
- * ```tsx
405
- * <ThemeProvider theme={pickColorLevel(theme, "ansi16")}>
406
- * <AlertPreview />
407
- * </ThemeProvider>
408
- * ```
409
- *
410
- * Notes:
411
- * - `truecolor` is a no-op — returns the input unchanged (identity).
412
- * - The result is structurally identical to the input (same keys, same
413
- * nesting); only hex leaves are remapped.
414
- * - Idempotent per tier: `pickColorLevel(pickColorLevel(t, "ansi16"), "ansi16")`
415
- * yields the same hex values as `pickColorLevel(t, "ansi16")`.
416
- * - Does not freeze the returned object. Callers that want immutability
417
- * should `Object.freeze()` (or deep-freeze) the result themselves.
418
- */
419
- function pickColorLevel(theme, tier) {
420
- if (tier === "truecolor") return theme;
421
- return pickColorLevelWalk(theme, tier);
422
- }
423
- function pickColorLevelWalk(obj, tier) {
424
- if (obj == null) return obj;
425
- if (isHexLeaf$1(obj)) return quantizeHex(obj, tier);
426
- if (Array.isArray(obj)) return obj.map((v) => pickColorLevelWalk(v, tier));
427
- if (typeof obj === "object") {
428
- const out = {};
429
- for (const [k, v] of Object.entries(obj)) out[k] = pickColorLevelWalk(v, tier);
430
- return out;
431
- }
432
- return obj;
433
- }
434
- var MODIFIERS, FG_COLORS, BG_COLORS, ANSI_16_COLORS, ANSI16_SLOT_HEX, HEX_LEAF_RE$1;
435
- var init_color_maps = __esmMin((() => {
436
- MODIFIERS = {
437
- reset: [0, 0],
438
- bold: [1, 22],
439
- dim: [2, 22],
440
- italic: [3, 23],
441
- underline: [4, 24],
442
- inverse: [7, 27],
443
- hidden: [8, 28],
444
- strikethrough: [9, 29],
445
- overline: [53, 55]
446
- };
447
- FG_COLORS = {
448
- black: 30,
449
- red: 31,
450
- green: 32,
451
- yellow: 33,
452
- blue: 34,
453
- magenta: 35,
454
- cyan: 36,
455
- white: 37,
456
- blackBright: 90,
457
- gray: 90,
458
- grey: 90,
459
- redBright: 91,
460
- greenBright: 92,
461
- yellowBright: 93,
462
- blueBright: 94,
463
- magentaBright: 95,
464
- cyanBright: 96,
465
- whiteBright: 97
466
- };
467
- BG_COLORS = {
468
- bgBlack: 40,
469
- bgRed: 41,
470
- bgGreen: 42,
471
- bgYellow: 43,
472
- bgBlue: 44,
473
- bgMagenta: 45,
474
- bgCyan: 46,
475
- bgWhite: 47,
476
- bgBlackBright: 100,
477
- bgGray: 100,
478
- bgGrey: 100,
479
- bgRedBright: 101,
480
- bgGreenBright: 102,
481
- bgYellowBright: 103,
482
- bgBlueBright: 104,
483
- bgMagentaBright: 105,
484
- bgCyanBright: 106,
485
- bgWhiteBright: 107
486
- };
487
- ANSI_16_COLORS = [
488
- [
489
- 0,
490
- 0,
491
- 0
492
- ],
493
- [
494
- 128,
495
- 0,
496
- 0
497
- ],
498
- [
499
- 0,
500
- 128,
501
- 0
502
- ],
503
- [
504
- 128,
505
- 128,
506
- 0
507
- ],
508
- [
509
- 0,
510
- 0,
511
- 128
512
- ],
513
- [
514
- 128,
515
- 0,
516
- 128
517
- ],
518
- [
519
- 0,
520
- 128,
521
- 128
522
- ],
523
- [
524
- 192,
525
- 192,
526
- 192
527
- ],
528
- [
529
- 128,
530
- 128,
531
- 128
532
- ],
533
- [
534
- 255,
535
- 0,
536
- 0
537
- ],
538
- [
539
- 0,
540
- 255,
541
- 0
542
- ],
543
- [
544
- 255,
545
- 255,
546
- 0
547
- ],
548
- [
549
- 0,
550
- 0,
551
- 255
552
- ],
553
- [
554
- 255,
555
- 0,
556
- 255
557
- ],
558
- [
559
- 0,
560
- 255,
561
- 255
562
- ],
563
- [
564
- 255,
565
- 255,
566
- 255
567
- ]
568
- ];
569
- ANSI16_SLOT_HEX = {
570
- black: "#000000",
571
- red: "#800000",
572
- green: "#008000",
573
- yellow: "#808000",
574
- blue: "#000080",
575
- magenta: "#800080",
576
- cyan: "#008080",
577
- white: "#c0c0c0",
578
- blackBright: "#808080",
579
- gray: "#808080",
580
- grey: "#808080",
581
- redBright: "#ff0000",
582
- greenBright: "#00ff00",
583
- yellowBright: "#ffff00",
584
- blueBright: "#0000ff",
585
- magentaBright: "#ff00ff",
586
- cyanBright: "#00ffff",
587
- whiteBright: "#ffffff"
588
- };
589
- HEX_LEAF_RE$1 = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;
590
- }));
591
- //#endregion
592
- //#region packages/ansi/src/flatten.ts
593
- function isHexLeaf(value) {
594
- return typeof value === "string" && HEX_LEAF_RE.test(value);
595
- }
596
- /**
597
- * Populate flat hyphen-keys onto `theme` in-place by walking hex leaves and
598
- * asking `rule` where each leaf should also live at the root.
599
- *
600
- * Both the nested and flat forms reference the SAME string (not copies) —
601
- * `bakeFlat({...}).accent.bg === bakeFlat({...})["bg-accent"]`.
602
- *
603
- * `rule` defaults to {@link defaultFlattenRule} (channel-role-state).
604
- * Rules returning `null` for a path skip that leaf — useful for suppressing
605
- * metadata or implementing partial projections.
606
- *
607
- * The returned object is deep-frozen. The input object is mutated in place
608
- * and returned; callers that want an unfrozen copy should `structuredClone`
609
- * before calling.
610
- *
611
- * @param theme nested POJO of hex-string leaves (plus optional metadata)
612
- * @param rule how to compute flat keys from nested paths
613
- * @returns the same object, with flat keys added and frozen
614
- */
615
- function bakeFlat(theme, rule = defaultFlattenRule) {
616
- const root = theme;
617
- if (Object.isFrozen(root)) return theme;
618
- walk(root, [], root, rule);
619
- freezeDeep(root);
620
- return theme;
621
- }
622
- function walk(node, path, root, rule) {
623
- for (const key of Object.keys(node)) {
624
- if (node === root && key.includes("-")) continue;
625
- const value = node[key];
626
- const subpath = [...path, key];
627
- if (isHexLeaf(value)) {
628
- const flatKey = rule(subpath);
629
- if (flatKey !== null) root[flatKey] = value;
630
- continue;
631
- }
632
- if (value && typeof value === "object" && !Array.isArray(value)) walk(value, subpath, root, rule);
633
- }
634
- }
635
- function freezeDeep(o) {
636
- if (o === null || typeof o !== "object") return;
637
- if (Object.isFrozen(o)) return;
638
- Object.freeze(o);
639
- for (const k of Object.keys(o)) freezeDeep(o[k]);
640
- }
641
- var defaultFlattenRule, HEX_LEAF_RE;
642
- var init_flatten = __esmMin((() => {
643
- defaultFlattenRule = (path) => {
644
- if (path.length < 2) return null;
645
- const role = path[0];
646
- const last = path[path.length - 1];
647
- const mid = path.slice(1, -1);
648
- if (last === "fgOn") return `fg-on-${role}`;
649
- if (last === "fg" || last === "bg" || last === "border") {
650
- const state = mid.length > 0 ? mid.join("-") : void 0;
651
- return state ? `${last}-${role}-${state}` : `${last}-${role}`;
652
- }
653
- if (role === "surface") return `bg-surface-${last}`;
654
- if (role === "border") return `border-${last}`;
655
- return null;
656
- };
657
- HEX_LEAF_RE = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?([0-9a-fA-F]{2})?$/;
658
- }));
659
- //#endregion
660
- //#region packages/ansi/src/terminal-control.ts
661
- /**
662
- * Enable mouse tracking with full hover support.
663
- *
664
- * Uses two modes:
665
- * - **1003** (any-event tracking): Reports ALL mouse motion — clicks, drags, AND hover.
666
- * This is what makes onMouseEnter/onMouseLeave work. Without it, only clicks are reported.
667
- * - **1006** (SGR encoding): Decimal coordinates with no 223-column limit.
668
- *
669
- * WARNING: Do NOT replace 1003 with 1000+1002. The xterm mouse modes form a hierarchy:
670
- * 1000 = clicks only
671
- * 1002 = clicks + drag (motion while button held)
672
- * 1003 = clicks + drag + hover (ALL motion, even without button)
673
- * Mode 1003 supersedes 1000 and 1002. Using 1000+1002 instead of 1003 silently
674
- * disables hover — onMouseEnter/onMouseLeave stop firing with no error.
675
- */
676
- function enableMouse() {
677
- return `${CSI$1}?1003h${CSI$1}?1006h`;
678
- }
679
- /**
680
- * Disable mouse tracking. Disables in reverse order of enabling.
681
- */
682
- function disableMouse() {
683
- return `${CSI$1}?1006l${CSI$1}?1003l`;
684
- }
685
- /**
686
- * Enable the Kitty keyboard protocol (push mode).
687
- *
688
- * Sends CSI > flags u to opt into the specified modes.
689
- * Supported by: Ghostty, Kitty, WezTerm, foot. Ignored by unsupported terminals.
690
- *
691
- * Flags are a bitfield:
692
- *
693
- * | Flag | Bit | Description |
694
- * | ---- | --- | ----------------------------------------- |
695
- * | 1 | 0 | Disambiguate escape codes |
696
- * | 2 | 1 | Report event types (press/repeat/release) |
697
- * | 4 | 2 | Report alternate keys |
698
- * | 8 | 3 | Report all keys as escape codes |
699
- * | 16 | 4 | Report associated text |
700
- *
701
- * @param flags Bitfield of Kitty keyboard flags
702
- */
703
- function enableKittyKeyboard(flags = 1) {
704
- return `${CSI$1}>${flags}u`;
705
- }
706
- /**
707
- * Disable the Kitty keyboard protocol (pop mode stack).
708
- * Sends CSI < u to restore the previous keyboard mode.
709
- */
710
- function disableKittyKeyboard() {
711
- return `${CSI$1}<u`;
712
- }
713
- var ESC$3, CSI$1;
714
- var init_terminal_control = __esmMin((() => {
715
- ESC$3 = "\x1B";
716
- CSI$1 = `${ESC$3}[`;
717
- `${ESC$3}`;
718
- }));
719
- //#endregion
720
- //#region packages/ansi/src/kitty-graphics.ts
721
- /**
722
- * Derive a stable placement ID for a given (x, y) cell. Max column = 9999,
723
- * which comfortably exceeds any realistic terminal width.
724
- */
725
- function backdropPlacementId(x, y) {
726
- return x * BACKDROP_PLACEMENT_X_STRIDE + y + 1;
727
- }
728
- /**
729
- * Encode a Uint8Array as base64. Kitty expects standard base64 (with `+`/`/`
730
- * and `=` padding). We use Buffer when available (Node/Bun), fall back to
731
- * btoa for browser/canvas adapters (the canvas target may never actually
732
- * need to emit Kitty escapes — this is just defensive).
733
- */
734
- function base64Encode(bytes) {
735
- if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
736
- let binary = "";
737
- for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
738
- const g = globalThis;
739
- if (typeof g.btoa === "function") return g.btoa(binary);
740
- throw new Error("base64 encoding unavailable in this environment");
741
- }
742
- /**
743
- * Build a tiny RGBA pixel grid for the scrim overlay.
744
- *
745
- * Kitty's graphics protocol paints images at native pixel resolution scaled
746
- * to `c` x `r` cells. A 2x2 RGBA image scaled to a single cell (~10x20 px
747
- * depending on font) gives us a smooth fill. We intentionally keep the
748
- * image tiny to minimize base64 payload size on the upload frame.
749
- *
750
- * Pixel color: `(r, g, b, a)` where `r/g/b` is the scrim tint and `a` is the
751
- * alpha (0-255). For a dark backdrop we use near-black at ~50% alpha, which
752
- * darkens the emoji underneath without completely hiding it.
753
- *
754
- * Width/height = 2 pixels — 16 bytes total, ~24 bytes base64. Upload is ~60
755
- * bytes including control chars. One-time cost per modal session.
756
- */
757
- function buildScrimPixels(tint, alpha) {
758
- const a = Math.max(0, Math.min(255, Math.round(alpha)));
759
- const r = Math.max(0, Math.min(255, Math.round(tint.r)));
760
- const g = Math.max(0, Math.min(255, Math.round(tint.g)));
761
- const b = Math.max(0, Math.min(255, Math.round(tint.b)));
762
- const bytes = new Uint8Array(16);
763
- for (let i = 0; i < 4; i++) {
764
- bytes[i * 4 + 0] = r;
765
- bytes[i * 4 + 1] = g;
766
- bytes[i * 4 + 2] = b;
767
- bytes[i * 4 + 3] = a;
768
- }
769
- return bytes;
770
- }
771
- /**
772
- * APC wrapper: `\x1b_G<control>[;<payload>]\x1b\\`.
773
- *
774
- * The protocol allows chunking large payloads via `m=1` but our scrim is
775
- * tiny — always fits in one chunk.
776
- */
777
- function apc(control, payload) {
778
- if (payload === void 0 || payload === "") return `\x1b_G${control}\x1b\\`;
779
- return `\x1b_G${control};${payload}\x1b\\`;
780
- }
781
- /**
782
- * Emit a one-shot image upload. Terminal stores the RGBA pixels under
783
- * `i=<imageId>` and keeps them until explicitly freed. Subsequent placements
784
- * reference the image by ID without re-sending pixel data.
785
- *
786
- * `q=2` suppresses the terminal's OK/error reply — otherwise we'd see stray
787
- * APC sequences back on stdin.
788
- */
789
- function kittyUploadScrimImage(pixels, width, height, imageId = BACKDROP_SCRIM_IMAGE_ID) {
790
- const payload = base64Encode(pixels);
791
- return apc(`a=t,f=32,s=${width},v=${height},i=${imageId},q=2`, payload);
792
- }
793
- /**
794
- * Emit a cell placement. Places `imageId` at the current cursor position
795
- * covering `c` cols and `r` rows with z-index `z`. `C=1` prevents the cursor
796
- * from advancing after placement (critical — otherwise every placement
797
- * shifts the cursor, breaking the caller's positioning).
798
- *
799
- * Placement ID (`p=<pid>`) is stable per cell so incremental frames can
800
- * replace placements without accumulating duplicates.
801
- */
802
- function kittyPlaceAt(opts) {
803
- const imageId = opts.imageId ?? 48879;
804
- const cols = opts.cols ?? 1;
805
- const rows = opts.rows ?? 1;
806
- const z = opts.z ?? 1;
807
- return apc(`a=p,i=${imageId},p=${opts.placementId},c=${cols},r=${rows},z=${z},C=1,q=2`);
808
- }
809
- /**
810
- * Delete ALL placements of our scrim image without freeing the image.
811
- * Used when the modal closes — we leave the image cached in case another
812
- * modal opens, but remove every overlay cell at once.
813
- */
814
- function kittyDeleteAllScrimPlacements(imageId = BACKDROP_SCRIM_IMAGE_ID) {
815
- return apc(`a=d,d=i,i=${imageId},q=2`);
816
- }
817
- /**
818
- * Absolute cursor position (CUP). 1-based row/col per VT100.
819
- *
820
- * Used to position the cursor before emitting a placement so the placement
821
- * lands in the right cell. Kept small and local — the rest of the pipeline
822
- * uses more elaborate cursor tracking, but for out-of-band overlay emission
823
- * we just want a deterministic "jump here, place, done."
824
- */
825
- function cupTo(col, row) {
826
- return `\x1b[${row + 1};${col + 1}H`;
827
- }
828
- var BACKDROP_SCRIM_IMAGE_ID, BACKDROP_PLACEMENT_X_STRIDE;
829
- var init_kitty_graphics = __esmMin((() => {
830
- BACKDROP_SCRIM_IMAGE_ID = 48879;
831
- BACKDROP_PLACEMENT_X_STRIDE = 1e4;
832
- }));
833
- //#endregion
834
- //#region packages/ansi/src/style/colors.ts
835
- var THEME_TOKEN_DEFAULTS;
836
- var init_colors = __esmMin((() => {
837
- init_color_maps();
838
- THEME_TOKEN_DEFAULTS = {
839
- primary: 33,
840
- secondary: 36,
841
- accent: 35,
842
- error: 31,
843
- warning: 33,
844
- success: 32,
845
- info: 36,
846
- muted: 2,
847
- link: 34,
848
- border: 90,
849
- surface: 37
850
- };
851
- }));
852
- //#endregion
853
- //#region packages/ansi/src/style/style.ts
854
- /**
855
- * Resolve a color value against a theme — the canonical token resolver.
856
- *
857
- * If the color starts with `$`, looks up the token in the theme.
858
- * Supports `$primary`, `$surface-bg` (hyphens stripped), `$color0`–`$color15` (palette).
859
- * Non-`$` strings pass through unchanged. Returns undefined if no theme or unknown token.
860
- *
861
- * Compatible with @silvery/theme's Theme type (or any object with string properties).
862
- */
863
- function resolveThemeColor(name, theme) {
864
- if (!name) return void 0;
865
- if (!name.startsWith("$")) return name;
866
- if (!theme) return void 0;
867
- return resolveToken(name, theme);
868
- }
869
- /** Internal: resolve a token name (with or without $ prefix) against a theme.
870
- *
871
- * Resolution order:
872
- * 1. Direct key lookup — finds Sterling flat keys (`bg-accent`,
873
- * `fg-on-error`, `border-focus`, …) and legacy kebab keys
874
- * (`primary-hover`, `fg-hover`, `bg-surface-hover`) and plain names
875
- * (`bg`, `primary`, `muted`).
876
- * 2. No-hyphen fallback — `$surface-bg` → `theme.surfacebg`,
877
- * `$focus-border` → `theme.focusborder`.
878
- *
879
- * The old `LEGACY_ALIASES` table (e.g. `fgmuted` → `muted`, `bgsurface` →
880
- * `surfacebg`) was removed in 0.18.1 once every shipped default Theme ships
881
- * with Sterling flat tokens baked in — `theme["fg-muted"]` and
882
- * `theme["bg-surface-subtle"]` are direct fields now, so no alias fallback
883
- * is required for canonical Sterling tokens. Tokens that existed only as
884
- * aliases (e.g. `$bg-surface`, `$fg-on-primary`, `$border-input`,
885
- * `$fg-disabled`) no longer resolve — callers should use the canonical
886
- * Sterling equivalents (`$bg-surface-default`, `$fg-on-accent`,
887
- * `$border-default`, `$fg-muted`).
888
- */
889
- function resolveToken(name, theme) {
890
- if (!theme) return void 0;
891
- const token = name.startsWith("$") ? name.slice(1) : name;
892
- if (token.startsWith("color")) {
893
- const idx = parseInt(token.slice(5), 10);
894
- if (idx >= 0 && idx < 16 && theme.palette && idx < theme.palette.length) return theme.palette[idx];
895
- }
896
- const themeObj = theme;
897
- const direct = themeObj[token];
898
- if (typeof direct === "string") return direct;
899
- const noHyphen = token.replace(/-/g, "");
900
- if (noHyphen !== token) {
901
- const stripped = themeObj[noHyphen];
902
- if (typeof stripped === "string") return stripped;
903
- }
904
- }
905
- /** Convert chalk numeric level (0-3) to ColorLevel. */
906
- function fromChalkLevel(n) {
907
- if (n <= 0) return null;
908
- if (n === 1) return "basic";
909
- if (n === 2) return "256";
910
- return "truecolor";
911
- }
912
- /** Convert ColorLevel to chalk numeric level (0-3). */
913
- function toChalkLevel(cl) {
914
- if (cl === null) return 0;
915
- if (cl === "basic") return 1;
916
- if (cl === "256") return 2;
917
- return 3;
918
- }
919
- /**
920
- * Create a style object for terminal output.
921
- *
922
- * @param options - Color level and optional theme
923
- * @returns A chainable style object (chalk-compatible API)
924
- *
925
- * @example
926
- * ```ts
927
- * import { createStyle } from "@silvery/ansi"
928
- *
929
- * const s = createStyle()
930
- * console.log(s.bold.red("Error!"))
931
- * console.log(s.hex("#818cf8")("Indigo"))
932
- *
933
- * // With theme
934
- * const s = createStyle({ theme })
935
- * console.log(s.primary("Deploy"))
936
- * console.log(s.success("Done"))
937
- * ```
938
- */
939
- function createStyle(options) {
940
- const ref = {
941
- level: null,
942
- theme: options?.theme
943
- };
944
- if (options?.level !== void 0) ref.level = options.level;
945
- else try {
946
- ref.level = detectColor(process.stdout);
947
- } catch {
948
- ref.level = null;
949
- }
950
- return createChainWithRef({
951
- opens: [],
952
- closes: []
953
- }, ref);
954
- }
955
- /**
956
- * Create a chain that reads level from a mutable ref.
957
- * This allows `style.level = 3` to affect all subsequent calls.
958
- */
959
- function createChainWithRef(state, ref) {
960
- const proxyRef = { proxy: null };
961
- const handler = {
962
- apply(_target, _thisArg, args) {
963
- const level = ref.level;
964
- if (state.visible && level === null) return "";
965
- let text;
966
- if (args.length === 0) text = "";
967
- else if (Array.isArray(args[0]) && "raw" in args[0]) text = String.raw(args[0], ...args.slice(1));
968
- else if (args.length > 1) text = args.map((a) => String(a ?? "")).join(" ");
969
- else text = String(args[0] ?? "");
970
- if (text === "") return "";
971
- if (level === null || state.opens.length === 0) return text;
972
- const open = `${ESC$2}${state.opens.join(";")}m`;
973
- const close = `${ESC$2}${state.closes.join(";")}m`;
974
- for (const closeCode of state.closes) {
975
- const closeSeq = `${ESC$2}${closeCode}m`;
976
- const parts = text.split(closeSeq);
977
- if (parts.length > 1) text = parts.join(`${closeSeq}${open}`);
978
- }
979
- if (text.includes("\n")) text = text.replace(/\r?\n/g, `${close}$&${open}`);
980
- return `${open}${text}${close}`;
981
- },
982
- get(_target, prop) {
983
- if (typeof prop === "symbol") return void 0;
984
- if (prop === "level") return toChalkLevel(ref.level);
985
- if (prop === "resolve") return (token) => resolveToken(token, ref.theme);
986
- if (prop === "visible") return createChainWithRef({
987
- ...state,
988
- visible: true
989
- }, ref);
990
- if (prop === "call" || prop === "apply" || prop === "bind") return Function.prototype[prop].bind(proxyRef.proxy);
991
- const level = ref.level;
992
- if (prop === "hex" || prop === "bgHex") return (color) => {
993
- if (level === null) return createChainWithRef(state, ref);
994
- const rgb = hexToRgb$1(color);
995
- if (!rgb) return createChainWithRef(state, ref);
996
- const code = prop === "hex" ? fgFromRgb(rgb[0], rgb[1], rgb[2], level) : bgFromRgb(rgb[0], rgb[1], rgb[2], level);
997
- const close = prop === "hex" ? "39" : "49";
998
- return createChainWithRef({
999
- opens: [...state.opens, code],
1000
- closes: [...state.closes, close]
1001
- }, ref);
1002
- };
1003
- if (prop === "rgb" || prop === "bgRgb") return (r, g, b) => {
1004
- if (level === null) return createChainWithRef(state, ref);
1005
- const code = prop === "rgb" ? fgFromRgb(r, g, b, level) : bgFromRgb(r, g, b, level);
1006
- const close = prop === "rgb" ? "39" : "49";
1007
- return createChainWithRef({
1008
- opens: [...state.opens, code],
1009
- closes: [...state.closes, close]
1010
- }, ref);
1011
- };
1012
- if (prop === "ansi256") return (code) => {
1013
- if (level === null) return createChainWithRef(state, ref);
1014
- return createChainWithRef({
1015
- opens: [...state.opens, `38;5;${code}`],
1016
- closes: [...state.closes, "39"]
1017
- }, ref);
1018
- };
1019
- if (prop === "bgAnsi256") return (code) => {
1020
- if (level === null) return createChainWithRef(state, ref);
1021
- return createChainWithRef({
1022
- opens: [...state.opens, `48;5;${code}`],
1023
- closes: [...state.closes, "49"]
1024
- }, ref);
1025
- };
1026
- if (prop in MODIFIERS) {
1027
- if (level === null) return createChainWithRef(state, ref);
1028
- const [open, close] = MODIFIERS[prop];
1029
- return createChainWithRef({
1030
- opens: [...state.opens, String(open)],
1031
- closes: [...state.closes, String(close)]
1032
- }, ref);
1033
- }
1034
- if (prop in FG_COLORS) {
1035
- if (level === null) return createChainWithRef(state, ref);
1036
- return createChainWithRef({
1037
- opens: [...state.opens, String(FG_COLORS[prop])],
1038
- closes: [...state.closes, "39"]
1039
- }, ref);
1040
- }
1041
- if (prop in BG_COLORS) {
1042
- if (level === null) return createChainWithRef(state, ref);
1043
- return createChainWithRef({
1044
- opens: [...state.opens, String(BG_COLORS[prop])],
1045
- closes: [...state.closes, "49"]
1046
- }, ref);
1047
- }
1048
- if (THEME_TOKENS.has(prop)) {
1049
- if (level === null) return createChainWithRef(state, ref);
1050
- const hex = resolveToken(prop, ref.theme);
1051
- if (hex) {
1052
- const rgb = hexToRgb$1(hex);
1053
- if (rgb) {
1054
- const code = fgFromRgb(rgb[0], rgb[1], rgb[2], level);
1055
- if (prop === "link") return createChainWithRef({
1056
- opens: [
1057
- ...state.opens,
1058
- code,
1059
- "4"
1060
- ],
1061
- closes: [
1062
- ...state.closes,
1063
- "39",
1064
- "24"
1065
- ]
1066
- }, ref);
1067
- return createChainWithRef({
1068
- opens: [...state.opens, code],
1069
- closes: [...state.closes, "39"]
1070
- }, ref);
1071
- }
1072
- }
1073
- const fallback = THEME_TOKEN_DEFAULTS[prop];
1074
- if (fallback !== void 0) {
1075
- if (prop === "muted") return createChainWithRef({
1076
- opens: [...state.opens, String(fallback)],
1077
- closes: [...state.closes, "22"]
1078
- }, ref);
1079
- if (prop === "link") return createChainWithRef({
1080
- opens: [
1081
- ...state.opens,
1082
- String(fallback),
1083
- "4"
1084
- ],
1085
- closes: [
1086
- ...state.closes,
1087
- "39",
1088
- "24"
1089
- ]
1090
- }, ref);
1091
- return createChainWithRef({
1092
- opens: [...state.opens, String(fallback)],
1093
- closes: [...state.closes, "39"]
1094
- }, ref);
1095
- }
1096
- }
1097
- },
1098
- set(_target, prop, value) {
1099
- if (prop === "level") {
1100
- ref.level = fromChalkLevel(value);
1101
- return true;
1102
- }
1103
- return false;
1104
- },
1105
- has(_target, prop) {
1106
- if (prop === "level") return true;
1107
- if (typeof prop === "symbol") return false;
1108
- return prop in MODIFIERS || prop in FG_COLORS || prop in BG_COLORS || THEME_TOKENS.has(prop) || KNOWN_METHODS.has(prop);
1109
- }
1110
- };
1111
- const target = function() {};
1112
- const proxy = new Proxy(target, handler);
1113
- proxyRef.proxy = proxy;
1114
- return proxy;
1115
- }
1116
- var ESC$2, KNOWN_METHODS, THEME_TOKENS;
1117
- var init_style = __esmMin((() => {
1118
- init_detection();
1119
- init_colors();
1120
- ESC$2 = "\x1B[";
1121
- KNOWN_METHODS = new Set([
1122
- "hex",
1123
- "rgb",
1124
- "bgHex",
1125
- "bgRgb",
1126
- "ansi256",
1127
- "bgAnsi256",
1128
- "resolve"
1129
- ]);
1130
- THEME_TOKENS = new Set([
1131
- "primary",
1132
- "secondary",
1133
- "accent",
1134
- "error",
1135
- "warning",
1136
- "success",
1137
- "info",
1138
- "muted",
1139
- "link",
1140
- "border",
1141
- "surface"
1142
- ]);
1143
- createStyle();
1144
- }));
1145
- //#endregion
1146
- //#region packages/ansi/src/style/mixed-proxy.ts
1147
- /**
1148
- * Create a proxy that wraps a style instance with additional properties.
1149
- *
1150
- * The proxy makes the result:
1151
- * - Callable: result('text') applies current styles
1152
- * - Chainable: result.bold.red('text') chains styles
1153
- * - Extended: result.anyExtraProp accesses extra properties
1154
- *
1155
- * Extra properties take priority over style properties on name collision.
1156
- */
1157
- function createMixedStyle(style, extra) {
1158
- return createChainProxy(style, extra);
1159
- }
1160
- /**
1161
- * Internal recursive proxy builder for style chain + extra properties.
1162
- */
1163
- function createChainProxy(currentStyle, extra) {
1164
- const handler = {
1165
- apply(_target, _thisArg, args) {
1166
- return currentStyle(...args);
1167
- },
1168
- get(_target, prop) {
1169
- if (prop in extra) {
1170
- const value = extra[prop];
1171
- if (typeof value === "function") return value;
1172
- return value;
1173
- }
1174
- if (typeof prop === "symbol") {
1175
- if (prop === Symbol.dispose) return extra[Symbol.dispose];
1176
- return;
1177
- }
1178
- if (STYLE_METHODS.has(prop)) {
1179
- const method = currentStyle[prop];
1180
- if (typeof method === "function") return (...args) => {
1181
- return createChainProxy(method.apply(currentStyle, args), extra);
1182
- };
1183
- }
1184
- const styleProp = currentStyle[prop];
1185
- if (styleProp !== void 0) {
1186
- if (typeof styleProp === "function" || typeof styleProp === "object") return createChainProxy(styleProp, extra);
1187
- return styleProp;
1188
- }
1189
- },
1190
- set(_target, prop, value) {
1191
- extra[prop] = value;
1192
- return true;
1193
- },
1194
- defineProperty(_target, prop, descriptor) {
1195
- Object.defineProperty(extra, prop, descriptor);
1196
- return true;
1197
- },
1198
- has(_target, prop) {
1199
- if (prop in extra) return true;
1200
- if (typeof prop === "string" && prop in currentStyle) return true;
1201
- return false;
1202
- }
1203
- };
1204
- const proxyTarget = function() {};
1205
- return new Proxy(proxyTarget, handler);
1206
- }
1207
- var STYLE_METHODS;
1208
- var init_mixed_proxy = __esmMin((() => {
1209
- STYLE_METHODS = new Set([
1210
- "hex",
1211
- "bgHex",
1212
- "rgb",
1213
- "bgRgb",
1214
- "ansi256",
1215
- "bgAnsi256"
1216
- ]);
1217
- }));
1218
- //#endregion
1219
- //#region packages/ansi/src/theme/invariants.ts
1220
- /**
1221
- * Theme invariants — post-derivation visibility + optional WCAG checks.
1222
- *
1223
- * Two independent invariant groups:
1224
- *
1225
- * 1. **Visibility (always checked)** — selection and cursor must be
1226
- * distinguishable from bg. These fail silently because ensureContrast
1227
- * doesn't touch `bg-selected`/`bg-cursor`; you get "invisible selection"
1228
- * bugs that only surface via user complaints.
1229
- *
1230
- * 2. **WCAG contrast (opt-in)** — `deriveTheme()` already runs `ensureContrast`
1231
- * on every text/bg pair as it builds the Theme (lenient auto-adjust). A
1232
- * second validation pass is redundant for normal use. Enable it explicitly
1233
- * at build time to *verify* that shipped themes meet the targets, or when
1234
- * loading a hand-authored Theme object that skipped `deriveTheme`.
1235
- *
1236
- * This is why `validateThemeInvariants` defaults to `{ wcag: false }` — the
1237
- * existing derivation already handles contrast. Callers opt in via
1238
- * `validateThemeInvariants(theme, { wcag: true })` for strict pre-ship audits.
1239
- *
1240
- * All token access is Sterling-shaped — flat hyphen keys (`bg-accent`,
1241
- * `fg-on-error`, `border-focus`) exist on every Theme via the derive +
1242
- * bakeFlat pipeline. No concat-kebab legacy names (`primaryfg`, `mutedbg`, …)
1243
- * — those were removed in silvery 0.19.0 (Sterling interior migration).
1244
- */
1245
- function lightness(hex) {
1246
- const o = hexToOklch(hex);
1247
- return o ? o.L : null;
1248
- }
1249
- /**
1250
- * Validate post-derivation invariants on a Theme.
1251
- *
1252
- * Default: visibility checks only (selection ΔL, cursor ΔE). These are
1253
- * invariants that `deriveTheme` doesn't enforce and that matter for every
1254
- * theme regardless of authoring pedigree.
1255
- *
1256
- * Opt into WCAG contrast checks via `{ wcag: true }`. Use at build-time to
1257
- * verify bundled themes, or when loading hand-authored Theme objects that
1258
- * didn't flow through `deriveTheme`'s `ensureContrast` pass.
1259
- *
1260
- * Non-hex values (ANSI names from `ansi16` mode) are skipped with no
1261
- * violation — ANSI 16 themes can't be contrast-checked in hex space.
1262
- *
1263
- * @example
1264
- * ```ts
1265
- * // Default — visibility only, fast
1266
- * const { ok, violations } = validateThemeInvariants(theme)
1267
- *
1268
- * // Build-time audit — full WCAG check
1269
- * const audit = validateThemeInvariants(theme, { wcag: true })
1270
- * ```
1271
- */
1272
- function validateThemeInvariants(theme, opts = {}) {
1273
- const checkWcag = opts.wcag ?? false;
1274
- const checkVisibility = opts.visibility ?? true;
1275
- const violations = [];
1276
- if (checkWcag) {
1277
- const themeRecord = theme;
1278
- for (const pair of CONTRAST_PAIRS) {
1279
- const fg = themeRecord[pair.fg];
1280
- const bg = themeRecord[pair.bg];
1281
- if (typeof fg !== "string" || typeof bg !== "string") continue;
1282
- const r = checkContrast(fg, bg);
1283
- if (r === null) continue;
1284
- if (r.ratio < pair.min) violations.push({
1285
- rule: pair.rule,
1286
- tokens: [pair.fg, pair.bg],
1287
- actual: r.ratio,
1288
- required: pair.min,
1289
- message: `${pair.fg} (${fg}) on ${pair.bg} (${bg}) is ${r.ratio.toFixed(2)}:1, needs ${pair.min.toFixed(1)}:1`
1290
- });
1291
- }
1292
- }
1293
- if (checkVisibility) {
1294
- const themeAny = theme;
1295
- const selectionBg = themeAny["bg-selected"] ?? themeAny["selectionbg"] ?? "";
1296
- const cursorBg = themeAny["bg-cursor"] ?? themeAny["cursorbg"] ?? "";
1297
- const selectionKey = themeAny["bg-selected"] !== void 0 ? "bg-selected" : "selectionbg";
1298
- const cursorKey = themeAny["bg-cursor"] !== void 0 ? "bg-cursor" : "cursorbg";
1299
- const lBg = lightness(theme.bg);
1300
- const lSelBg = lightness(selectionBg);
1301
- if (lBg !== null && lSelBg !== null) {
1302
- const dL = Math.abs(lSelBg - lBg);
1303
- if (dL < .08) violations.push({
1304
- rule: "visibility:selection",
1305
- tokens: [selectionKey, "bg"],
1306
- actual: dL,
1307
- required: SELECTION_DELTA_L,
1308
- message: `${selectionKey} (${selectionBg}) differs from bg (${theme.bg}) by ΔL=${dL.toFixed(3)}, needs ≥ ${SELECTION_DELTA_L.toFixed(2)}`
1309
- });
1310
- }
1311
- const oBg = hexToOklch(theme.bg);
1312
- const oCursorBg = hexToOklch(cursorBg);
1313
- if (oBg && oCursorBg) {
1314
- const de = deltaE(oBg, oCursorBg);
1315
- if (de < .15) violations.push({
1316
- rule: "visibility:cursor",
1317
- tokens: [cursorKey, "bg"],
1318
- actual: de,
1319
- required: CURSOR_DELTA_E,
1320
- message: `${cursorKey} (${cursorBg}) differs from bg (${theme.bg}) by ΔE=${de.toFixed(3)}, needs ≥ ${CURSOR_DELTA_E.toFixed(2)}`
1321
- });
1322
- }
1323
- }
1324
- return {
1325
- ok: violations.length === 0,
1326
- violations
1327
- };
1328
- }
1329
- /**
1330
- * Format violations as a multiline error message for throws/logs.
1331
- */
1332
- function formatViolations(violations) {
1333
- if (violations.length === 0) return "";
1334
- return violations.map((v) => ` - [${v.rule}] ${v.message}`).join("\n");
1335
- }
1336
- var AA_RATIO, FAINT_RATIO, SELECTION_DELTA_L, CURSOR_DELTA_E, CONTRAST_PAIRS, ThemeInvariantError;
1337
- var init_invariants = __esmMin((() => {
1338
- AA_RATIO = 4.5;
1339
- FAINT_RATIO = 1.5;
1340
- SELECTION_DELTA_L = .08;
1341
- CURSOR_DELTA_E = .15;
1342
- CONTRAST_PAIRS = [
1343
- {
1344
- rule: "contrast:fg/bg",
1345
- fg: "fg",
1346
- bg: "bg",
1347
- min: AA_RATIO
1348
- },
1349
- {
1350
- rule: "contrast:fg/bg-surface-subtle",
1351
- fg: "fg",
1352
- bg: "bg-surface-subtle",
1353
- min: AA_RATIO
1354
- },
1355
- {
1356
- rule: "contrast:fg/bg-surface-overlay",
1357
- fg: "fg",
1358
- bg: "bg-surface-overlay",
1359
- min: AA_RATIO
1360
- },
1361
- {
1362
- rule: "contrast:fg-muted/bg-muted",
1363
- fg: "fg-muted",
1364
- bg: "bg-muted",
1365
- min: 3
1366
- },
1367
- {
1368
- rule: "contrast:fg-accent/bg",
1369
- fg: "fg-accent",
1370
- bg: "bg",
1371
- min: AA_RATIO
1372
- },
1373
- {
1374
- rule: "contrast:fg-error/bg",
1375
- fg: "fg-error",
1376
- bg: "bg",
1377
- min: AA_RATIO
1378
- },
1379
- {
1380
- rule: "contrast:fg-warning/bg",
1381
- fg: "fg-warning",
1382
- bg: "bg",
1383
- min: AA_RATIO
1384
- },
1385
- {
1386
- rule: "contrast:fg-success/bg",
1387
- fg: "fg-success",
1388
- bg: "bg",
1389
- min: AA_RATIO
1390
- },
1391
- {
1392
- rule: "contrast:fg-info/bg",
1393
- fg: "fg-info",
1394
- bg: "bg",
1395
- min: AA_RATIO
1396
- },
1397
- {
1398
- rule: "contrast:fg-on-accent/bg-accent",
1399
- fg: "fg-on-accent",
1400
- bg: "bg-accent",
1401
- min: AA_RATIO
1402
- },
1403
- {
1404
- rule: "contrast:fg-on-error/bg-error",
1405
- fg: "fg-on-error",
1406
- bg: "bg-error",
1407
- min: AA_RATIO
1408
- },
1409
- {
1410
- rule: "contrast:fg-on-warning/bg-warning",
1411
- fg: "fg-on-warning",
1412
- bg: "bg-warning",
1413
- min: AA_RATIO
1414
- },
1415
- {
1416
- rule: "contrast:fg-on-success/bg-success",
1417
- fg: "fg-on-success",
1418
- bg: "bg-success",
1419
- min: AA_RATIO
1420
- },
1421
- {
1422
- rule: "contrast:fg-on-info/bg-info",
1423
- fg: "fg-on-info",
1424
- bg: "bg-info",
1425
- min: AA_RATIO
1426
- },
1427
- {
1428
- rule: "contrast:fg-on-selected/bg-selected",
1429
- fg: "fg-on-selected",
1430
- bg: "bg-selected",
1431
- min: AA_RATIO
1432
- },
1433
- {
1434
- rule: "contrast:fg-cursor/bg-cursor",
1435
- fg: "fg-cursor",
1436
- bg: "bg-cursor",
1437
- min: AA_RATIO
1438
- },
1439
- {
1440
- rule: "contrast:border-default/bg",
1441
- fg: "border-default",
1442
- bg: "bg",
1443
- min: 3
1444
- },
1445
- {
1446
- rule: "contrast:border-focus/bg",
1447
- fg: "border-focus",
1448
- bg: "bg",
1449
- min: 3
1450
- },
1451
- {
1452
- rule: "contrast:border-muted/bg",
1453
- fg: "border-muted",
1454
- bg: "bg",
1455
- min: FAINT_RATIO
1456
- }
1457
- ];
1458
- ThemeInvariantError = class extends Error {
1459
- violations;
1460
- constructor(violations) {
1461
- super(`Theme invariants failed (${violations.length} violation${violations.length === 1 ? "" : "s"}):\n${formatViolations(violations)}`);
1462
- this.name = "ThemeInvariantError";
1463
- this.violations = violations;
1464
- }
1465
- };
1466
- }));
1467
- //#endregion
1468
- //#region packages/ansi/src/theme/derived.ts
1469
- /**
1470
- * deriveFields — single helper that fills all derived theme sections.
1471
- *
1472
- * Eliminates 4-way duplication of brand, categorical ring, state-variant, and
1473
- * variants population across:
1474
- * - derive.ts (deriveTruecolorTheme + deriveAnsi16Theme)
1475
- * - default-schemes.ts (ansi16DarkTheme + ansi16LightTheme)
1476
- * - @silvery/theme/generate.ts (generateTheme)
1477
- * - @silvery/theme/schemes/index.ts (ansi16DarkTheme + ansi16LightTheme)
1478
- *
1479
- * Canonical authority: derive.ts truecolor path. ANSI16 paths are aligned to
1480
- * deriveAnsi16Theme output (which is itself the canonical ANSI16 reference).
1481
- */
1482
- /**
1483
- * Derive the shared "delta" fields common to every theme object:
1484
- * brand tokens, categorical ring, state variants, and typography variants.
1485
- *
1486
- * Pass a `shift` function for truecolor hover/active derivation (OKLCH
1487
- * brighten/darken). Omit `shift` for ANSI16 — hover/active fall back to the
1488
- * base color (no intermediate intensities available on 16-color terminals).
1489
- *
1490
- * @example
1491
- * // Truecolor (dark theme)
1492
- * import { brighten, darken } from "@silvery/color"
1493
- * deriveFields({ shift: (hex, a) => brighten(hex, a), primary, ... })
1494
- *
1495
- * @example
1496
- * // ANSI16 — no shift function
1497
- * deriveFields({ primary, accent, fg, selectionbg, surfacebg, ring })
1498
- */
1499
- function deriveFields(input) {
1500
- const { dark, shift, primary, accent, fg, selectionbg, surfacebg, ring } = input;
1501
- const applyShift = dark !== void 0 ? (color, amount) => dark ? brighten(color, amount) : darken(color, amount) : shift ?? ((color, _amount) => color);
1502
- return {
1503
- brand: primary,
1504
- "brand-hover": applyShift(primary, .04),
1505
- "brand-active": applyShift(primary, .08),
1506
- ...ring,
1507
- "primary-hover": applyShift(primary, .04),
1508
- "primary-active": applyShift(primary, .08),
1509
- "accent-hover": applyShift(accent, .04),
1510
- "accent-active": applyShift(accent, .08),
1511
- "fg-hover": applyShift(fg, .04),
1512
- "fg-active": applyShift(fg, .08),
1513
- "bg-selected-hover": applyShift(selectionbg, .04),
1514
- "bg-surface-hover": applyShift(surfacebg, .04),
1515
- variants: DEFAULT_VARIANTS
1516
- };
1517
- }
1518
- var DEFAULT_VARIANTS;
1519
- var init_derived = __esmMin((() => {
1520
- DEFAULT_VARIANTS = {
1521
- h1: {
1522
- color: "$primary",
1523
- bold: true
1524
- },
1525
- h2: {
1526
- color: "$accent",
1527
- bold: true
1528
- },
1529
- h3: { bold: true },
1530
- body: {},
1531
- "body-muted": { color: "$muted" },
1532
- "fine-print": {
1533
- color: "$muted",
1534
- dim: true
1535
- },
1536
- strong: { bold: true },
1537
- em: { italic: true },
1538
- link: {
1539
- color: "$link",
1540
- underlineStyle: "single"
1541
- },
1542
- key: {
1543
- color: "$accent",
1544
- bold: true
1545
- },
1546
- code: { backgroundColor: "$mutedbg" },
1547
- kbd: {
1548
- backgroundColor: "$mutedbg",
1549
- color: "$accent",
1550
- bold: true
1551
- }
1552
- };
1553
- }));
1554
- //#endregion
1555
- //#region packages/ansi/src/theme/derive.ts
1556
- /**
1557
- * Theme derivation — transforms a ColorScheme into a Theme.
1558
- */
1559
- function deriveTheme(palette, mode = "truecolor", adjustments) {
1560
- if (mode === "ansi16") return deriveAnsi16Theme(palette);
1561
- return deriveTruecolorTheme(palette, adjustments);
1562
- }
1563
- /**
1564
- * Load and validate a theme from a ColorScheme.
1565
- *
1566
- * Combines `deriveTheme()` (auto-adjust via ensureContrast with project-tuned
1567
- * thresholds) with `validateThemeInvariants()` (post-derivation visibility +
1568
- * optional WCAG).
1569
- *
1570
- * We don't re-impose WCAG on top of derive's tweaked thresholds — default
1571
- * validation checks visibility invariants only (selection/cursor vs bg) that
1572
- * derive doesn't handle.
1573
- *
1574
- * @example
1575
- * ```ts
1576
- * // Default: lenient + visibility-only (derive already handled contrast)
1577
- * const theme = loadTheme(myScheme)
1578
- *
1579
- * // Build-time audit: strict + full WCAG
1580
- * const theme = loadTheme(myScheme, { enforce: "strict", wcag: true })
1581
- * ```
1582
- */
1583
- function loadTheme(palette, opts = {}) {
1584
- const mode = opts.mode ?? "truecolor";
1585
- const enforce = opts.enforce ?? "lenient";
1586
- const theme = deriveTheme(palette, mode, opts.adjustments);
1587
- if (enforce === "off") return theme;
1588
- const { ok, violations } = validateThemeInvariants(theme, { wcag: opts.wcag });
1589
- if (!ok) {
1590
- if (enforce === "strict") throw new ThemeInvariantError(violations);
1591
- if (opts.violations) opts.violations.push(...violations);
1592
- }
1593
- return theme;
1594
- }
1595
- function deriveTruecolorTheme(p, adjustments) {
1596
- const dark = p.dark ?? true;
1597
- const bg = p.background;
1598
- function ensure(token, color, against, target) {
1599
- const result = ensureContrast(color, against, target);
1600
- if (adjustments && result !== color) {
1601
- const before = checkContrast(color, against);
1602
- const after = checkContrast(result, against);
1603
- adjustments.push({
1604
- token,
1605
- from: color,
1606
- to: result,
1607
- against,
1608
- target,
1609
- ratioBefore: before?.ratio ?? 0,
1610
- ratioAfter: after?.ratio ?? 0
1611
- });
1612
- }
1613
- return result;
1614
- }
1615
- const surfacebg = blend(bg, p.foreground, .05);
1616
- const popoverbg = blend(bg, p.foreground, .08);
1617
- const fg = ensure("fg", p.foreground, popoverbg, AA);
1618
- const primary = ensure("primary", p.primary ?? (dark ? p.yellow : p.blue), bg, AA);
1619
- const accent = ensure("accent", complement(primary), bg, AA);
1620
- const secondary = ensure("secondary", blend(primary, accent, .35), bg, AA);
1621
- const error = ensure("error", p.red, bg, AA);
1622
- const warning = ensure("warning", p.yellow, bg, AA);
1623
- const success = ensure("success", p.green, bg, AA);
1624
- const info = ensure("info", blend(fg, accent, .5), bg, AA);
1625
- const link = ensure("link", dark ? p.brightBlue : p.blue, bg, AA);
1626
- const red = ensure("red", p.red, bg, AA);
1627
- const orange = ensure("orange", blend(p.red, p.yellow, .5), bg, AA);
1628
- const yellow = ensure("yellow", p.yellow, bg, AA);
1629
- const green = ensure("green", p.green, bg, AA);
1630
- const teal = ensure("teal", blend(p.green, p.cyan, .5), bg, AA);
1631
- const blue = ensure("blue", dark ? p.brightBlue : p.blue, bg, AA);
1632
- const purple = ensure("purple", p.magenta, bg, AA);
1633
- const pink = ensure("pink", blend(p.magenta, p.red, .5), bg, AA);
1634
- const mutedbg = blend(bg, p.foreground, .04);
1635
- const muted = ensure("muted", blend(fg, bg, .4), mutedbg, AA);
1636
- const disabledfg = ensure("disabledfg", blend(fg, bg, .5), bg, DIM);
1637
- const border = ensure("border", blend(bg, p.foreground, .15), bg, FAINT);
1638
- const inputborder = ensure("inputborder", blend(bg, p.foreground, .25), bg, CONTROL);
1639
- const selectionBg = repairSelectionBg(p.selectionBackground, bg);
1640
- const selection = ensure("selection", p.selectionForeground, selectionBg, AA);
1641
- const cursorBgRepaired = repairCursorBg(p.cursorColor, bg);
1642
- const cursor = ensure("cursor", p.cursorText, cursorBgRepaired, AA);
1643
- const derived = deriveFields({
1644
- dark,
1645
- primary,
1646
- accent,
1647
- fg,
1648
- selectionbg: selectionBg,
1649
- surfacebg,
1650
- ring: {
1651
- red,
1652
- orange,
1653
- yellow,
1654
- green,
1655
- teal,
1656
- blue,
1657
- purple,
1658
- pink
1659
- }
1660
- });
1661
- return {
1662
- name: p.name ?? (dark ? "derived-dark" : "derived-light"),
1663
- bg,
1664
- fg,
1665
- muted,
1666
- mutedbg,
1667
- surface: fg,
1668
- surfacebg,
1669
- popover: fg,
1670
- popoverbg,
1671
- inverse: contrastFg(blend(fg, bg, .1)),
1672
- inversebg: blend(fg, bg, .1),
1673
- cursor,
1674
- cursorbg: cursorBgRepaired,
1675
- selection,
1676
- selectionbg: selectionBg,
1677
- primary,
1678
- primaryfg: contrastFg(primary),
1679
- secondary,
1680
- secondaryfg: contrastFg(secondary),
1681
- accent,
1682
- accentfg: contrastFg(accent),
1683
- error,
1684
- errorfg: contrastFg(error),
1685
- warning,
1686
- warningfg: contrastFg(warning),
1687
- success,
1688
- successfg: contrastFg(success),
1689
- info,
1690
- infofg: contrastFg(info),
1691
- border,
1692
- inputborder,
1693
- focusborder: link,
1694
- link,
1695
- disabledfg,
1696
- palette: [
1697
- p.black,
1698
- p.red,
1699
- p.green,
1700
- p.yellow,
1701
- p.blue,
1702
- p.magenta,
1703
- p.cyan,
1704
- p.white,
1705
- p.brightBlack,
1706
- p.brightRed,
1707
- p.brightGreen,
1708
- p.brightYellow,
1709
- p.brightBlue,
1710
- p.brightMagenta,
1711
- p.brightCyan,
1712
- p.brightWhite
1713
- ],
1714
- ...derived
1715
- };
1716
- }
1717
- function deriveAnsi16Theme(p) {
1718
- const dark = p.dark ?? true;
1719
- const primaryColor = dark ? p.yellow : p.blue;
1720
- const accentColor = p.cyan;
1721
- const derived = deriveFields({
1722
- primary: primaryColor,
1723
- accent: accentColor,
1724
- fg: p.foreground,
1725
- selectionbg: p.selectionBackground,
1726
- surfacebg: p.black,
1727
- ring: {
1728
- red: dark ? p.brightRed : p.red,
1729
- orange: dark ? p.brightRed : p.red,
1730
- yellow: p.yellow,
1731
- green: dark ? p.brightGreen : p.green,
1732
- teal: p.cyan,
1733
- blue: dark ? p.brightBlue : p.blue,
1734
- purple: p.magenta,
1735
- pink: dark ? p.brightMagenta : p.magenta
1736
- }
1737
- });
1738
- return {
1739
- name: p.name ?? (dark ? "derived-ansi16-dark" : "derived-ansi16-light"),
1740
- bg: p.background,
1741
- fg: p.foreground,
1742
- muted: p.white,
1743
- mutedbg: p.black,
1744
- surface: p.foreground,
1745
- surfacebg: p.black,
1746
- popover: p.foreground,
1747
- popoverbg: p.black,
1748
- inverse: p.black,
1749
- inversebg: p.brightWhite,
1750
- cursor: p.cursorText,
1751
- cursorbg: p.cursorColor,
1752
- selection: p.selectionForeground,
1753
- selectionbg: p.selectionBackground,
1754
- primary: primaryColor,
1755
- primaryfg: p.black,
1756
- secondary: p.magenta,
1757
- secondaryfg: p.black,
1758
- accent: accentColor,
1759
- accentfg: p.black,
1760
- error: dark ? p.brightRed : p.red,
1761
- errorfg: p.black,
1762
- warning: p.yellow,
1763
- warningfg: p.black,
1764
- success: dark ? p.brightGreen : p.green,
1765
- successfg: p.black,
1766
- info: p.cyan,
1767
- infofg: p.black,
1768
- border: p.brightBlack,
1769
- inputborder: p.brightBlack,
1770
- focusborder: dark ? p.brightBlue : p.blue,
1771
- link: dark ? p.brightBlue : p.blue,
1772
- disabledfg: p.brightBlack,
1773
- palette: [
1774
- p.black,
1775
- p.red,
1776
- p.green,
1777
- p.yellow,
1778
- p.blue,
1779
- p.magenta,
1780
- p.cyan,
1781
- p.white,
1782
- p.brightBlack,
1783
- p.brightRed,
1784
- p.brightGreen,
1785
- p.brightYellow,
1786
- p.brightBlue,
1787
- p.brightMagenta,
1788
- p.brightCyan,
1789
- p.brightWhite
1790
- ],
1791
- ...derived
1792
- };
1793
- }
1794
- /**
1795
- * Nudge `selectionBg`'s OKLCH lightness until it differs from `bg` by at least
1796
- * `SELECTION_DELTA_L`. Preserves hue + chroma. Non-hex input returns unchanged.
1797
- *
1798
- * Direction: shift away from bg — if bg is dark, lift L; if bg is light, drop L.
1799
- * If the input already meets the threshold, it's returned unchanged.
1800
- */
1801
- function repairSelectionBg(selectionBg, bg) {
1802
- const oSel = hexToOklch(selectionBg);
1803
- const oBg = hexToOklch(bg);
1804
- if (!oSel || !oBg) return selectionBg;
1805
- const dL = Math.abs(oSel.L - oBg.L);
1806
- if (dL >= .08) return selectionBg;
1807
- const needed = SELECTION_DELTA_L - dL + .005;
1808
- const direction = oSel.L >= oBg.L ? 1 : -1;
1809
- return oklchToHex({
1810
- L: Math.max(0, Math.min(1, oSel.L + direction * needed)),
1811
- C: oSel.C,
1812
- H: oSel.H
1813
- });
1814
- }
1815
- /**
1816
- * Nudge `cursorBg`'s OKLCH values until it differs from `bg` by at least
1817
- * `CURSOR_DELTA_E`. Shifts lightness first (preserves hue/chroma aesthetics).
1818
- * Non-hex input returns unchanged.
1819
- */
1820
- function repairCursorBg(cursorBg, bg) {
1821
- const d = colorDistance(cursorBg, bg);
1822
- if (d === null || d >= .15) return cursorBg;
1823
- const oCur = hexToOklch(cursorBg);
1824
- const oBg = hexToOklch(bg);
1825
- const lGap = SELECTION_DELTA_L + .02;
1826
- const direction = oCur.L >= oBg.L ? 1 : -1;
1827
- const candidate = oklchToHex({
1828
- L: Math.max(0, Math.min(1, oCur.L + direction * lGap)),
1829
- C: oCur.C,
1830
- H: oCur.H
1831
- });
1832
- const d2 = colorDistance(candidate, bg);
1833
- if (d2 !== null && d2 >= .15) return candidate;
1834
- return oBg.L > .5 ? "#000000" : "#FFFFFF";
1835
- }
1836
- var AA, DIM, FAINT, CONTROL;
1837
- var init_derive = __esmMin((() => {
1838
- init_invariants();
1839
- init_derived();
1840
- AA = 4.5;
1841
- DIM = 3;
1842
- FAINT = 1.5;
1843
- CONTROL = 3;
1844
- }));
1845
- //#endregion
1846
- //#region packages/ansi/src/theme/monochrome.ts
1847
- /**
1848
- * Produce per-token monochrome attrs from a base Theme.
1849
- *
1850
- * Currently returns `DEFAULT_MONO_ATTRS` — a canonical mapping. Passed the
1851
- * theme to allow per-theme overrides in the future (e.g., a palette that
1852
- * prefers `underline` for accents over `italic`). The argument is reserved.
1853
- */
1854
- function deriveMonochromeTheme(theme) {
1855
- return DEFAULT_MONO_ATTRS;
1856
- }
1857
- /**
1858
- * Resolve mono-attrs from a color *string* — the high-level entry point
1859
- * consumed by the render pipeline.
1860
- *
1861
- * Accepts strings like `"$primary"`, `"$fg-muted"`, `"$border-focus"`. Strips
1862
- * the `$` prefix and looks the name up directly against `DEFAULT_MONO_ATTRS`,
1863
- * which carries both legacy keys (`muted`, `surfacebg`, `focusborder`, …) AND
1864
- * Sterling flat tokens (`fg-muted`, `bg-surface-default`, `border-focus`, …)
1865
- * as first-class entries. Returns `undefined` for non-token strings (hex,
1866
- * rgb(), named ANSI colors) — callers should treat this as "no attrs".
1867
- *
1868
- * A secondary no-hyphen fallback (`$surface-bg` → `surfacebg`) keeps the
1869
- * legacy hyphenated-compound form working for callers that still emit that
1870
- * shape.
1871
- *
1872
- * @param color The color string (e.g. `"$primary"`, `"#ff0000"`, `"red"`)
1873
- * @param theme Active theme (reserved for per-theme overrides)
1874
- * @returns Array of mono-attrs for the token, or `undefined` if not a
1875
- * recognized token.
1876
- */
1877
- function monoAttrsForColorString(color, theme) {
1878
- if (!color.startsWith("$")) return void 0;
1879
- const name = color.slice(1);
1880
- const attrs = deriveMonochromeTheme(theme);
1881
- const direct = attrs[name];
1882
- if (direct !== void 0) return direct;
1883
- const noHyphen = name.replace(/-/g, "");
1884
- if (noHyphen !== name) {
1885
- const stripped = attrs[noHyphen];
1886
- if (stripped !== void 0) return stripped;
1887
- }
1888
- }
1889
- var DEFAULT_MONO_ATTRS;
1890
- var init_monochrome = __esmMin((() => {
1891
- DEFAULT_MONO_ATTRS = {
1892
- bg: [],
1893
- mutedbg: [],
1894
- surfacebg: [],
1895
- popoverbg: [],
1896
- border: [],
1897
- cursorbg: [],
1898
- fg: [],
1899
- muted: ["dim"],
1900
- disabledfg: ["dim"],
1901
- surface: [],
1902
- popover: [],
1903
- inverse: ["inverse"],
1904
- primary: ["bold"],
1905
- secondary: ["bold"],
1906
- accent: ["italic", "bold"],
1907
- error: ["bold", "inverse"],
1908
- warning: ["bold"],
1909
- success: ["bold"],
1910
- info: ["italic"],
1911
- primaryfg: [],
1912
- secondaryfg: [],
1913
- accentfg: [],
1914
- errorfg: ["inverse"],
1915
- warningfg: [],
1916
- successfg: [],
1917
- infofg: [],
1918
- link: ["underline"],
1919
- focusborder: ["bold"],
1920
- inputborder: [],
1921
- selection: [],
1922
- selectionbg: ["inverse"],
1923
- cursor: [],
1924
- "fg-muted": ["dim"],
1925
- "bg-muted": [],
1926
- "fg-accent": ["italic", "bold"],
1927
- "bg-accent": [],
1928
- "fg-on-accent": [],
1929
- "border-accent": [],
1930
- "fg-accent-hover": ["italic", "bold"],
1931
- "bg-accent-hover": [],
1932
- "fg-accent-active": ["italic", "bold"],
1933
- "bg-accent-active": [],
1934
- "fg-info": ["italic"],
1935
- "bg-info": [],
1936
- "fg-on-info": [],
1937
- "bg-info-hover": [],
1938
- "bg-info-active": [],
1939
- "fg-success": ["bold"],
1940
- "bg-success": [],
1941
- "fg-on-success": [],
1942
- "bg-success-hover": [],
1943
- "bg-success-active": [],
1944
- "fg-warning": ["bold"],
1945
- "bg-warning": [],
1946
- "fg-on-warning": [],
1947
- "bg-warning-hover": [],
1948
- "bg-warning-active": [],
1949
- "fg-error": ["bold", "inverse"],
1950
- "bg-error": [],
1951
- "fg-on-error": ["inverse"],
1952
- "bg-error-hover": [],
1953
- "bg-error-active": [],
1954
- "bg-surface-default": [],
1955
- "bg-surface-subtle": [],
1956
- "bg-surface-raised": [],
1957
- "bg-surface-overlay": [],
1958
- "bg-surface-hover": [],
1959
- "border-default": [],
1960
- "border-focus": ["bold"],
1961
- "border-muted": [],
1962
- "fg-cursor": [],
1963
- "bg-cursor": []
1964
- };
1965
- }));
1966
- //#endregion
1967
- //#region packages/ansi/src/theme/fingerprint.ts
1968
- /**
1969
- * Map ΔE thresholds into a 0–1 confidence.
1970
- *
1971
- * sumΔE=0 + maxΔE=0 → 1.0 (perfect match)
1972
- * sumΔE=30 (threshold) → ~0.5
1973
- * sumΔE≥60 → ~0.0
1974
- */
1975
- function computeConfidence(sumDE, maxDE, sumThreshold) {
1976
- const sumScore = Math.max(0, 1 - sumDE / (sumThreshold * 2));
1977
- const maxScore = Math.max(0, 1 - maxDE / 16);
1978
- return Math.max(0, Math.min(1, .7 * sumScore + .3 * maxScore));
1979
- }
1980
- /**
1981
- * Match probed slots against a catalog, returning the best candidate if it
1982
- * satisfies both sum and per-slot thresholds. Returns `null` if nothing matches.
1983
- *
1984
- * `probed` is a partial ColorScheme — whatever slots OSC queries returned. Missing
1985
- * slots are skipped (still counted as "not compared"). Non-hex values are
1986
- * ignored (ΔE can't be computed).
1987
- */
1988
- function fingerprintMatch(probed, catalog, opts = {}) {
1989
- const sumThreshold = opts.sumThreshold ?? 30;
1990
- const perSlotThreshold = opts.perSlotThreshold ?? 8;
1991
- let best = null;
1992
- for (const scheme of catalog) {
1993
- let sumDE = 0;
1994
- let maxDE = 0;
1995
- let slotsCompared = 0;
1996
- for (const field of FINGERPRINT_FIELDS) {
1997
- const probedVal = probed[field];
1998
- const catalogVal = scheme[field];
1999
- if (typeof probedVal !== "string" || typeof catalogVal !== "string") continue;
2000
- const de = colorDistance(probedVal, catalogVal);
2001
- if (de === null) continue;
2002
- const scaled = de * 100;
2003
- sumDE += scaled;
2004
- if (scaled > maxDE) maxDE = scaled;
2005
- slotsCompared++;
2006
- }
2007
- if (slotsCompared === 0) continue;
2008
- if (maxDE > perSlotThreshold) continue;
2009
- if (sumDE > sumThreshold) continue;
2010
- if (best === null || sumDE < best.sumDeltaE) best = {
2011
- scheme,
2012
- sumDeltaE: sumDE,
2013
- maxDeltaE: maxDE,
2014
- slotsCompared,
2015
- confidence: computeConfidence(sumDE, maxDE, sumThreshold)
2016
- };
2017
- }
2018
- return best;
2019
- }
2020
- var FINGERPRINT_FIELDS;
2021
- var init_fingerprint = __esmMin((() => {
2022
- FINGERPRINT_FIELDS = [
2023
- "foreground",
2024
- "background",
2025
- "black",
2026
- "red",
2027
- "green",
2028
- "yellow",
2029
- "blue",
2030
- "magenta",
2031
- "cyan",
2032
- "white",
2033
- "brightBlack",
2034
- "brightRed",
2035
- "brightGreen",
2036
- "brightYellow",
2037
- "brightBlue",
2038
- "brightMagenta",
2039
- "brightCyan",
2040
- "brightWhite"
2041
- ];
2042
- }));
2043
- //#endregion
2044
- //#region packages/ansi/src/theme/types.ts
2045
- var COLOR_SCHEME_FIELDS;
2046
- var init_types = __esmMin((() => {
2047
- COLOR_SCHEME_FIELDS = [
2048
- "black",
2049
- "red",
2050
- "green",
2051
- "yellow",
2052
- "blue",
2053
- "magenta",
2054
- "cyan",
2055
- "white",
2056
- "brightBlack",
2057
- "brightRed",
2058
- "brightGreen",
2059
- "brightYellow",
2060
- "brightBlue",
2061
- "brightMagenta",
2062
- "brightCyan",
2063
- "brightWhite",
2064
- "foreground",
2065
- "background",
2066
- "cursorColor",
2067
- "cursorText",
2068
- "selectionBackground",
2069
- "selectionForeground"
2070
- ];
2071
- }));
2072
- //#endregion
2073
- //#region packages/ansi/src/theme/default-schemes.ts
2074
- var defaultDarkScheme, defaultLightScheme, ansi16DarkTheme, ansi16LightTheme;
2075
- var init_default_schemes = __esmMin((() => {
2076
- init_derive();
2077
- defaultDarkScheme = {
2078
- name: "default-dark",
2079
- dark: true,
2080
- black: "#2e3440",
2081
- red: "#bf616a",
2082
- green: "#a3be8c",
2083
- yellow: "#ebcb8b",
2084
- blue: "#81a1c1",
2085
- magenta: "#b48ead",
2086
- cyan: "#88c0d0",
2087
- white: "#d8dee9",
2088
- brightBlack: "#4c566a",
2089
- brightRed: "#bf616a",
2090
- brightGreen: "#a3be8c",
2091
- brightYellow: "#ebcb8b",
2092
- brightBlue: "#81a1c1",
2093
- brightMagenta: "#b48ead",
2094
- brightCyan: "#8fbcbb",
2095
- brightWhite: "#eceff4",
2096
- foreground: "#d8dee9",
2097
- background: "#2e3440",
2098
- cursorColor: "#d8dee9",
2099
- cursorText: "#2e3440",
2100
- selectionBackground: "#434c5e",
2101
- selectionForeground: "#d8dee9"
2102
- };
2103
- defaultLightScheme = {
2104
- name: "default-light",
2105
- dark: false,
2106
- black: "#5c6370",
2107
- red: "#d20f39",
2108
- green: "#40a02b",
2109
- yellow: "#df8e1d",
2110
- blue: "#1e66f5",
2111
- magenta: "#8839ef",
2112
- cyan: "#179299",
2113
- white: "#dce0e8",
2114
- brightBlack: "#6c7086",
2115
- brightRed: "#d20f39",
2116
- brightGreen: "#40a02b",
2117
- brightYellow: "#df8e1d",
2118
- brightBlue: "#1e66f5",
2119
- brightMagenta: "#8839ef",
2120
- brightCyan: "#179299",
2121
- brightWhite: "#eff1f5",
2122
- foreground: "#4c4f69",
2123
- background: "#eff1f5",
2124
- cursorColor: "#dc8a78",
2125
- cursorText: "#eff1f5",
2126
- selectionBackground: "#ccd0da",
2127
- selectionForeground: "#4c4f69"
2128
- };
2129
- ansi16DarkTheme = deriveAnsi16Theme(defaultDarkScheme);
2130
- ansi16LightTheme = deriveAnsi16Theme(defaultLightScheme);
2131
- }));
2132
- //#endregion
2133
- //#region packages/ansi/src/osc-palette.ts
2134
- function queryPaletteColor(index, write) {
2135
- if (index < 0 || index > 255) throw new RangeError(`Palette index must be 0-255, got ${index}`);
2136
- write(`${ESC$1}]4;${index};?${BEL$1}`);
2137
- }
2138
- function queryMultiplePaletteColors(indices, write) {
2139
- for (const index of indices) queryPaletteColor(index, write);
2140
- }
2141
- function setPaletteColor(index, color, write) {
2142
- if (index < 0 || index > 255) throw new RangeError(`Palette index must be 0-255, got ${index}`);
2143
- write(`${ESC$1}]4;${index};${color}${BEL$1}`);
2144
- }
2145
- function parsePaletteResponse(input) {
2146
- const prefixIdx = input.indexOf(OSC4_PREFIX);
2147
- if (prefixIdx === -1) return null;
2148
- const bodyStart = prefixIdx + OSC4_PREFIX.length;
2149
- let bodyEnd = input.indexOf(BEL$1, bodyStart);
2150
- if (bodyEnd === -1) bodyEnd = input.indexOf(`${ESC$1}\\`, bodyStart);
2151
- if (bodyEnd === -1) return null;
2152
- const body = input.slice(bodyStart, bodyEnd);
2153
- const match = OSC4_BODY_RE.exec(body);
2154
- if (!match) return null;
2155
- const index = Number.parseInt(match[1], 10);
2156
- if (index < 0 || index > 255) return null;
2157
- return {
2158
- index,
2159
- color: `#${normalizeHexChannel$1(match[2])}${normalizeHexChannel$1(match[3])}${normalizeHexChannel$1(match[4])}`
2160
- };
2161
- }
2162
- function normalizeHexChannel$1(hex) {
2163
- switch (hex.length) {
2164
- case 1: return hex + hex;
2165
- case 2: return hex;
2166
- default: return hex.slice(0, 2);
2167
- }
2168
- }
2169
- var ESC$1, BEL$1, OSC4_PREFIX, OSC4_BODY_RE;
2170
- var init_osc_palette = __esmMin((() => {
2171
- ESC$1 = "\x1B";
2172
- BEL$1 = "\x07";
2173
- OSC4_PREFIX = `${ESC$1}]4;`;
2174
- OSC4_BODY_RE = /^(\d+);rgb:([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})$/;
2175
- }));
2176
- //#endregion
2177
- //#region packages/ansi/src/osc-colors.ts
2178
- function normalizeHexChannel(hex) {
2179
- switch (hex.length) {
2180
- case 1: return hex + hex;
2181
- case 2: return hex;
2182
- default: return hex.slice(0, 2);
2183
- }
2184
- }
2185
- function parseOscColorResponse(input, oscCode) {
2186
- const prefix = `${ESC}]${oscCode};`;
2187
- const prefixIdx = input.indexOf(prefix);
2188
- if (prefixIdx === -1) return null;
2189
- const bodyStart = prefixIdx + prefix.length;
2190
- let bodyEnd = input.indexOf(BEL, bodyStart);
2191
- if (bodyEnd === -1) bodyEnd = input.indexOf(`${ESC}\\`, bodyStart);
2192
- if (bodyEnd === -1) return null;
2193
- const body = input.slice(bodyStart, bodyEnd);
2194
- const match = RGB_BODY_RE.exec(body);
2195
- if (!match) return null;
2196
- return `#${normalizeHexChannel(match[1])}${normalizeHexChannel(match[2])}${normalizeHexChannel(match[3])}`;
2197
- }
2198
- async function queryOscColor(write, read, oscCode, timeoutMs) {
2199
- write(`${ESC}]${oscCode};?${BEL}`);
2200
- const data = await read(timeoutMs);
2201
- if (data == null) return null;
2202
- return parseOscColorResponse(data, oscCode);
2203
- }
2204
- async function queryForegroundColor(write, read, timeoutMs = 200) {
2205
- return queryOscColor(write, read, 10, timeoutMs);
2206
- }
2207
- async function queryBackgroundColor(write, read, timeoutMs = 200) {
2208
- return queryOscColor(write, read, 11, timeoutMs);
2209
- }
2210
- async function queryCursorColor(write, read, timeoutMs = 200) {
2211
- return queryOscColor(write, read, 12, timeoutMs);
2212
- }
2213
- function setForegroundColor(write, color) {
2214
- write(`${ESC}]10;${color}${BEL}`);
2215
- }
2216
- function setBackgroundColor(write, color) {
2217
- write(`${ESC}]11;${color}${BEL}`);
2218
- }
2219
- function setCursorColor(write, color) {
2220
- write(`${ESC}]12;${color}${BEL}`);
2221
- }
2222
- function resetForegroundColor(write) {
2223
- write(`${ESC}]110${BEL}`);
2224
- }
2225
- function resetBackgroundColor(write) {
2226
- write(`${ESC}]111${BEL}`);
2227
- }
2228
- function resetCursorColor(write) {
2229
- write(`${ESC}]112${BEL}`);
2230
- }
2231
- async function detectColorScheme(write, read, timeoutMs = 200) {
2232
- const bg = await queryBackgroundColor(write, read, timeoutMs);
2233
- if (bg == null) return null;
2234
- const r = parseInt(bg.slice(1, 3), 16) / 255;
2235
- const g = parseInt(bg.slice(3, 5), 16) / 255;
2236
- const b = parseInt(bg.slice(5, 7), 16) / 255;
2237
- return .2126 * r + .7152 * g + .0722 * b > .5 ? "light" : "dark";
2238
- }
2239
- var ESC, BEL, RGB_BODY_RE;
2240
- var init_osc_colors = __esmMin((() => {
2241
- ESC = "\x1B";
2242
- BEL = "\x07";
2243
- RGB_BODY_RE = /rgb:([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})/;
2244
- }));
2245
- //#endregion
2246
- //#region packages/ansi/src/theme/detect.ts
2247
- async function detectTerminalScheme(timeoutMs = 150) {
2248
- const stdin = process.stdin;
2249
- const stdout = process.stdout;
2250
- if (!stdin.isTTY || !stdout.isTTY) return null;
2251
- const wasRaw = stdin.isRaw;
2252
- if (!wasRaw) stdin.setRawMode(true);
2253
- let buffer = "";
2254
- const onData = (chunk) => {
2255
- buffer += chunk.toString();
2256
- };
2257
- stdin.on("data", onData);
2258
- try {
2259
- const write = (s) => {
2260
- stdout.write(s);
2261
- };
2262
- const read = (ms) => new Promise((resolve) => {
2263
- if (buffer.length > 0) {
2264
- const result = buffer;
2265
- buffer = "";
2266
- resolve(result);
2267
- return;
2268
- }
2269
- const timer = setTimeout(() => {
2270
- resolve(buffer.length > 0 ? buffer : null);
2271
- buffer = "";
2272
- }, ms);
2273
- const check = (_chunk) => {
2274
- clearTimeout(timer);
2275
- stdin.removeListener("data", check);
2276
- const result = buffer;
2277
- buffer = "";
2278
- resolve(result);
2279
- };
2280
- stdin.on("data", check);
2281
- });
2282
- const bg = await queryBackgroundColor(write, read, timeoutMs);
2283
- const fg = await queryForegroundColor(write, read, timeoutMs);
2284
- const ansi = new Array(16).fill(null);
2285
- queryMultiplePaletteColors(Array.from({ length: 16 }, (_, i) => i), write);
2286
- await new Promise((resolve) => setTimeout(resolve, timeoutMs));
2287
- const remaining = buffer;
2288
- buffer = "";
2289
- if (remaining) {
2290
- const oscPrefix = "\x1B]4;";
2291
- let pos = 0;
2292
- while (pos < remaining.length) {
2293
- const nextOsc = remaining.indexOf(oscPrefix, pos);
2294
- if (nextOsc === -1) break;
2295
- let end = remaining.indexOf("\x07", nextOsc);
2296
- if (end === -1) end = remaining.indexOf("\x1B\\", nextOsc);
2297
- if (end === -1) break;
2298
- const parsed = parsePaletteResponse(remaining.slice(nextOsc, end + 1));
2299
- if (parsed && parsed.index >= 0 && parsed.index < 16) ansi[parsed.index] = parsed.color;
2300
- pos = end + 1;
2301
- }
2302
- }
2303
- const dark = bg ? isDarkColor(bg) : true;
2304
- const palette = { dark };
2305
- if (bg) palette.background = bg;
2306
- if (fg) palette.foreground = fg;
2307
- const ansiFields = [
2308
- "black",
2309
- "red",
2310
- "green",
2311
- "yellow",
2312
- "blue",
2313
- "magenta",
2314
- "cyan",
2315
- "white",
2316
- "brightBlack",
2317
- "brightRed",
2318
- "brightGreen",
2319
- "brightYellow",
2320
- "brightBlue",
2321
- "brightMagenta",
2322
- "brightCyan",
2323
- "brightWhite"
2324
- ];
2325
- for (let i = 0; i < 16; i++) if (ansi[i]) palette[ansiFields[i]] = ansi[i];
2326
- if (fg) {
2327
- palette.cursorColor = fg;
2328
- palette.selectionForeground = fg;
2329
- }
2330
- if (bg) palette.cursorText = bg;
2331
- if (ansi[4]) palette.selectionBackground = ansi[4];
2332
- return {
2333
- fg,
2334
- bg,
2335
- ansi,
2336
- dark,
2337
- palette
2338
- };
2339
- } finally {
2340
- stdin.removeListener("data", onData);
2341
- if (!wasRaw) stdin.setRawMode(false);
2342
- }
2343
- }
2344
- async function detectTheme(opts = {}) {
2345
- const colorLevel = opts.caps?.colorLevel;
2346
- if (colorLevel === "none" || colorLevel === "basic") return opts.caps?.darkBackground ?? true ? ansi16DarkTheme : ansi16LightTheme;
2347
- const detected = await detectTerminalScheme(opts.timeoutMs);
2348
- const isDark = detected?.dark ?? opts.caps?.darkBackground ?? true;
2349
- const fallback = opts.fallback ?? (isDark ? opts.fallbackDark ?? defaultDarkScheme : opts.fallbackLight ?? defaultLightScheme);
2350
- if (!detected) return deriveTheme(fallback);
2351
- return deriveTheme({
2352
- ...fallback,
2353
- ...stripNulls$1(detected.palette)
2354
- });
2355
- }
2356
- function stripNulls$1(partial) {
2357
- const result = {};
2358
- for (const [k, v] of Object.entries(partial)) if (v != null) result[k] = v;
2359
- return result;
2360
- }
2361
- function isDarkColor(hex) {
2362
- const r = parseInt(hex.slice(1, 3), 16) / 255;
2363
- const g = parseInt(hex.slice(3, 5), 16) / 255;
2364
- const b = parseInt(hex.slice(5, 7), 16) / 255;
2365
- return .2126 * r + .7152 * g + .0722 * b <= .5;
2366
- }
2367
- var init_detect = __esmMin((() => {
2368
- init_derive();
2369
- init_default_schemes();
2370
- init_osc_palette();
2371
- init_osc_colors();
2372
- }));
2373
- //#endregion
2374
- //#region packages/ansi/src/theme/orchestrator.ts
2375
- function envOverride() {
2376
- const v = process.env.SILVERY_COLOR;
2377
- if (!v) return null;
2378
- if (v === "truecolor" || v === "256" || v === "ansi16" || v === "scheme" || v === "mono" || v === "auto") return v;
2379
- return null;
2380
- }
2381
- /**
2382
- * Detect the terminal's color scheme + derive a theme in one call.
2383
- *
2384
- * Runs the 4-layer detection cascade (override → probe → fingerprint →
2385
- * fallback) and returns a fully-resolved Theme along with provenance metadata
2386
- * so callers can log how the scheme was determined.
2387
- *
2388
- * This is the recommended entry point for apps — it handles all the gotchas
2389
- * (non-TTY environments, failed probes, partial OSC responses, catalog matches,
2390
- * bg-mode inference) and returns something you can hand to `ThemeProvider`.
2391
- *
2392
- * @example
2393
- * ```ts
2394
- * import { detectScheme } from "@silvery/ansi"
2395
- * import { builtinPalettes } from "@silvery/theme/schemes"
2396
- *
2397
- * const { scheme, theme, source, matchedName, confidence } = await detectScheme({
2398
- * catalog: Object.values(builtinPalettes),
2399
- * enforce: "lenient",
2400
- * })
2401
- * console.log(`${source === "fingerprint" ? `detected ${matchedName}` : source} (${(confidence * 100).toFixed(0)}%)`)
2402
- * ```
2403
- */
2404
- async function detectScheme(opts = {}) {
2405
- const enforce = opts.enforce ?? "lenient";
2406
- const wcag = opts.wcag ?? false;
2407
- if (opts.override) {
2408
- const theme = loadTheme(opts.override, {
2409
- enforce,
2410
- wcag
2411
- });
2412
- return {
2413
- scheme: opts.override,
2414
- theme,
2415
- source: "override",
2416
- confidence: 1,
2417
- slotSources: allSlotsFrom("fallback"),
2418
- matchedName: opts.override.name
2419
- };
2420
- }
2421
- const envMode = envOverride();
2422
- if (envMode === "mono" || envMode === "ansi16") {
2423
- const fallback = opts.darkFallback !== false ? defaultDarkScheme : defaultLightScheme;
2424
- return {
2425
- scheme: fallback,
2426
- theme: loadTheme(fallback, {
2427
- enforce,
2428
- wcag
2429
- }),
2430
- source: "override",
2431
- confidence: 1,
2432
- slotSources: allSlotsFrom("fallback"),
2433
- matchedName: fallback.name
2434
- };
2435
- }
2436
- const detected = await detectTerminalScheme(opts.timeoutMs);
2437
- if (!detected) {
2438
- const fallback = opts.darkFallback !== false ? defaultDarkScheme : defaultLightScheme;
2439
- return {
2440
- scheme: fallback,
2441
- theme: loadTheme(fallback, {
2442
- enforce,
2443
- wcag
2444
- }),
2445
- source: "fallback",
2446
- confidence: 0,
2447
- slotSources: allSlotsFrom("fallback"),
2448
- matchedName: fallback.name
2449
- };
2450
- }
2451
- const catalog = opts.catalog ?? [];
2452
- if (catalog.length > 0) {
2453
- const match = fingerprintMatch(detected.palette, catalog);
2454
- if (match) {
2455
- const theme = loadTheme(match.scheme, {
2456
- enforce,
2457
- wcag
2458
- });
2459
- return {
2460
- scheme: match.scheme,
2461
- theme,
2462
- source: "fingerprint",
2463
- confidence: match.confidence,
2464
- slotSources: allSlotsFrom("catalog"),
2465
- matchedName: match.scheme.name
2466
- };
2467
- }
2468
- }
2469
- const merged = {
2470
- ...detected.dark ? defaultDarkScheme : defaultLightScheme,
2471
- ...stripNulls(detected.palette)
2472
- };
2473
- const theme = loadTheme(merged, {
2474
- enforce,
2475
- wcag
2476
- });
2477
- const slotSources = {};
2478
- for (const field of COLOR_SCHEME_FIELDS) slotSources[field] = typeof detected.palette[field] === "string" ? "probed" : "fallback";
2479
- const probedCount = Object.values(slotSources).filter((s) => s === "probed").length;
2480
- return {
2481
- scheme: merged,
2482
- theme,
2483
- source: "probed",
2484
- confidence: Math.min(1, probedCount / 18),
2485
- slotSources,
2486
- matchedName: void 0
2487
- };
2488
- }
2489
- function stripNulls(partial) {
2490
- const result = {};
2491
- for (const [k, v] of Object.entries(partial)) if (v != null) result[k] = v;
2492
- return result;
2493
- }
2494
- function allSlotsFrom(src) {
2495
- const out = {};
2496
- for (const field of COLOR_SCHEME_FIELDS) out[field] = src;
2497
- return out;
2498
- }
2499
- var init_orchestrator = __esmMin((() => {
2500
- init_types();
2501
- init_derive();
2502
- init_detect();
2503
- init_fingerprint();
2504
- init_default_schemes();
2505
- }));
2506
- //#endregion
2507
- //#region packages/ansi/src/theme/tokens.ts
2508
- var KNOWN_VARIANTS;
2509
- var init_tokens = __esmMin((() => {
2510
- KNOWN_VARIANTS = [
2511
- "h1",
2512
- "h2",
2513
- "h3",
2514
- "body",
2515
- "body-muted",
2516
- "fine-print",
2517
- "strong",
2518
- "em",
2519
- "link",
2520
- "key",
2521
- "code",
2522
- "kbd"
2523
- ];
2524
- })), CSI;
2525
- var init_color_scheme = __esmMin((() => {
2526
- CSI = `[`;
2527
- `${CSI}`;
2528
- `${CSI}`;
2529
- }));
2530
- //#endregion
2531
- //#region packages/ansi/src/theme/generators.ts
2532
- var init_generators = __esmMin((() => {}));
2533
- //#endregion
2534
- //#region packages/ansi/src/theme/auto-generate.ts
2535
- var init_auto_generate = __esmMin((() => {
2536
- init_generators();
2537
- init_derive();
2538
- }));
2539
- //#endregion
2540
- //#region packages/ansi/src/theme/generate.ts
2541
- /**
2542
- * Generate a complete ANSI 16 theme from a primary color + dark/light preference.
2543
- *
2544
- * All token values are ANSI color names (e.g. "yellow", "blueBright").
2545
- */
2546
- function generateTheme(primary, dark) {
2547
- const fg = dark ? "whiteBright" : "black";
2548
- const accent = primary;
2549
- const selectionbg = primary;
2550
- const surfacebg = dark ? "black" : "white";
2551
- const derived = deriveFields({
2552
- primary,
2553
- accent,
2554
- fg,
2555
- selectionbg,
2556
- surfacebg,
2557
- ring: {
2558
- red: dark ? "redBright" : "red",
2559
- orange: dark ? "redBright" : "red",
2560
- yellow: "yellow",
2561
- green: dark ? "greenBright" : "green",
2562
- teal: "cyan",
2563
- blue: dark ? "blueBright" : "blue",
2564
- purple: "magenta",
2565
- pink: dark ? "magentaBright" : "magenta"
2566
- }
2567
- });
2568
- return {
2569
- name: `${dark ? "dark" : "light"}-${primary}`,
2570
- bg: "",
2571
- fg,
2572
- muted: dark ? "white" : "blackBright",
2573
- mutedbg: dark ? "black" : "white",
2574
- surface: dark ? "whiteBright" : "black",
2575
- surfacebg,
2576
- popover: dark ? "whiteBright" : "black",
2577
- popoverbg: dark ? "blackBright" : "white",
2578
- inverse: dark ? "black" : "whiteBright",
2579
- inversebg: dark ? "whiteBright" : "black",
2580
- cursor: "black",
2581
- cursorbg: primary,
2582
- selection: "black",
2583
- selectionbg: primary,
2584
- primary,
2585
- primaryfg: "black",
2586
- secondary: primary,
2587
- secondaryfg: "black",
2588
- accent: primary,
2589
- accentfg: "black",
2590
- error: dark ? "redBright" : "red",
2591
- errorfg: "black",
2592
- warning: primary,
2593
- warningfg: "black",
2594
- success: dark ? "greenBright" : "green",
2595
- successfg: "black",
2596
- info: dark ? "cyanBright" : "cyan",
2597
- infofg: "black",
2598
- border: "gray",
2599
- inputborder: "gray",
2600
- focusborder: dark ? "blueBright" : "blue",
2601
- link: "blueBright",
2602
- disabledfg: "gray",
2603
- palette: [
2604
- "black",
2605
- "red",
2606
- "green",
2607
- "yellow",
2608
- "blue",
2609
- "magenta",
2610
- "cyan",
2611
- "white",
2612
- "blackBright",
2613
- "redBright",
2614
- "greenBright",
2615
- "yellowBright",
2616
- "blueBright",
2617
- "magentaBright",
2618
- "cyanBright",
2619
- "whiteBright"
2620
- ],
2621
- ...derived
2622
- };
2623
- }
2624
- var init_generate = __esmMin((() => {
2625
- init_derived();
2626
- }));
2627
- //#endregion
2628
- //#region packages/ansi/src/index.ts
2629
- var init_src = __esmMin((() => {
2630
- init_detection();
2631
- init_sgr_codes();
2632
- init_utils();
2633
- init_color_maps();
2634
- init_flatten();
2635
- init_terminal_control();
2636
- init_kitty_graphics();
2637
- init_style();
2638
- init_mixed_proxy();
2639
- init_colors();
2640
- init_derive();
2641
- init_derived();
2642
- init_monochrome();
2643
- init_fingerprint();
2644
- init_orchestrator();
2645
- init_invariants();
2646
- init_default_schemes();
2647
- init_types();
2648
- init_tokens();
2649
- init_detect();
2650
- init_osc_palette();
2651
- init_osc_colors();
2652
- init_color_scheme();
2653
- init_generators();
2654
- init_auto_generate();
2655
- init_generate();
2656
- }));
2657
- //#endregion
2658
- export { backdropPlacementId as A, bakeFlat as B, COLOR_SCHEME_FIELDS as C, createMixedStyle as D, deriveFields as E, kittyUploadScrimImage as F, bgColorCode as G, ANSI16_SLOT_HEX as H, disableKittyKeyboard as I, detectColor as J, fgColorCode as K, disableMouse as L, cupTo as M, kittyDeleteAllScrimPlacements as N, createStyle as O, kittyPlaceAt as P, detectUnicode as Q, enableKittyKeyboard as R, ansi16LightTheme as S, deriveTheme as T, pickColorLevel as U, defaultFlattenRule as V, quantizeHex as W, detectInput as X, detectCursor as Y, detectTerminalCaps as Z, parsePaletteResponse as _, detectTerminalScheme as a, setPaletteColor as b, queryBackgroundColor as c, resetBackgroundColor as d, resetCursorColor as f, setForegroundColor as g, setCursorColor as h, detectScheme as i, buildScrimPixels as j, resolveThemeColor as k, queryCursorColor as l, setBackgroundColor as m, generateTheme as n, detectTheme as o, resetForegroundColor as p, defaultCaps as q, KNOWN_VARIANTS as r, detectColorScheme as s, init_src as t, queryForegroundColor as u, queryMultiplePaletteColors as v, monoAttrsForColorString as w, ansi16DarkTheme as x, queryPaletteColor as y, enableMouse as z };
2659
-
2660
- //# sourceMappingURL=src-NCKb8kE5.mjs.map