silvery 0.19.2 → 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.
- package/README.md +9 -4
- package/dist/Text-Lq0dmj8-.mjs +239 -0
- package/dist/Text-Lq0dmj8-.mjs.map +1 -0
- package/dist/UPNG-Bo33r8rA.mjs +3 -0
- package/dist/UPNG-DosRPdF4.mjs +5075 -0
- package/dist/UPNG-DosRPdF4.mjs.map +1 -0
- package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs +6 -0
- package/dist/__vite-browser-external-2447137e-D_JM6skp.mjs.map +1 -0
- package/dist/{animation-Cn64yepo.mjs → animation-ZMN2_XKv.mjs} +2 -2
- package/dist/animation-ZMN2_XKv.mjs.map +1 -0
- package/dist/{ansi-Cc33mW54.d.mts → ansi-2Xn0yatP.d.mts} +1 -1
- package/dist/{ansi-Cc33mW54.d.mts.map → ansi-2Xn0yatP.d.mts.map} +1 -1
- package/dist/{ansi-CLOitHKx.mjs → ansi-D1KQMAbf.mjs} +1 -1
- package/dist/{ansi-CLOitHKx.mjs.map → ansi-D1KQMAbf.mjs.map} +1 -1
- package/dist/ansi-yC4RyBNY.mjs +22441 -0
- package/dist/ansi-yC4RyBNY.mjs.map +1 -0
- package/dist/apng-CR08rIaH.mjs +58 -0
- package/dist/apng-CR08rIaH.mjs.map +1 -0
- package/dist/apng-DaHfVaVI.mjs +3 -0
- package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
- package/dist/assets/skia.darwin-arm64-DQs5sT6N.node +0 -0
- package/dist/backend-B-WYLUib.mjs +13396 -0
- package/dist/backend-B-WYLUib.mjs.map +1 -0
- package/dist/backends-CUtan80W.mjs +3 -0
- package/dist/backends-DIVYzKqd.mjs +1083 -0
- package/dist/backends-DIVYzKqd.mjs.map +1 -0
- package/dist/bound-term-0sPrrzH1.d.mts +4640 -0
- package/dist/bound-term-0sPrrzH1.d.mts.map +1 -0
- package/dist/canvas-1v7dPT-_.mjs +3 -0
- package/dist/canvas-CSuPOMNt.mjs +1442 -0
- package/dist/canvas-CSuPOMNt.mjs.map +1 -0
- package/dist/{chunk-Vs_PY4HZ.mjs → chunk-BSw8zbkd.mjs} +1 -1
- package/dist/cli-dvo0r2fs.mjs +4 -0
- package/dist/compare-CQodSH4G.mjs +376 -0
- package/dist/compare-CQodSH4G.mjs.map +1 -0
- package/dist/compare-DHlcxEYA.mjs +3 -0
- package/dist/context-BU5LkkIy.mjs.map +1 -1
- package/dist/devtools-CJdt5H0X.mjs +2 -0
- package/dist/{devtools-DxkSLXDA.mjs → devtools-DcQjgyjL.mjs} +5 -4
- package/dist/{devtools-DxkSLXDA.mjs.map → devtools-DcQjgyjL.mjs.map} +1 -1
- package/dist/easing-BI-ASGMO.d.mts +24 -0
- package/dist/easing-BI-ASGMO.d.mts.map +1 -0
- package/dist/{eta-Bb3RH3wh.mjs → eta-CJlGH06n.mjs} +1 -1
- package/dist/{eta-Bb3RH3wh.mjs.map → eta-CJlGH06n.mjs.map} +1 -1
- package/dist/flexily-zero-adapter-C3Vj0fPt.mjs +306 -0
- package/dist/flexily-zero-adapter-C3Vj0fPt.mjs.map +1 -0
- package/dist/{flexily-zero-adapter-CMxXhdOL.mjs → flexily-zero-adapter-C4lW_Ov5.mjs} +1 -1
- package/dist/fonts-BFmhXDv7.mjs +88 -0
- package/dist/fonts-BFmhXDv7.mjs.map +1 -0
- package/dist/gif-C_AjaT9d.mjs +188 -0
- package/dist/gif-C_AjaT9d.mjs.map +1 -0
- package/dist/gif-DaC4XrxA.mjs +3 -0
- package/dist/gifenc-BOUT-KFB.mjs +730 -0
- package/dist/gifenc-BOUT-KFB.mjs.map +1 -0
- package/dist/image-C2Birh2x.mjs +1252 -0
- package/dist/image-C2Birh2x.mjs.map +1 -0
- package/dist/index-BUMxS65f.d.mts +453 -0
- package/dist/index-BUMxS65f.d.mts.map +1 -0
- package/dist/{index-D3saHouR.d.mts → index-CSQf13CI.d.mts} +1057 -1133
- package/dist/index-CSQf13CI.d.mts.map +1 -0
- package/dist/{index-BXslOebb.d.mts → index-Cl9KKjQ_.d.mts} +4919 -3921
- package/dist/index-Cl9KKjQ_.d.mts.map +1 -0
- package/dist/index-XbNrPhWl.d.mts +336 -0
- package/dist/index-XbNrPhWl.d.mts.map +1 -0
- package/dist/index.d.mts +8 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +14 -12
- package/dist/index.mjs.map +1 -1
- package/dist/key-mapping-CS-YD_cD.mjs +132 -0
- package/dist/key-mapping-CS-YD_cD.mjs.map +1 -0
- package/dist/key-mapping-Yn-Jgrij.mjs +3 -0
- package/dist/{layout-engine-B6Cdz1yZ.mjs → layout-engine-C07LEXWT.mjs} +1 -1
- package/dist/layout-engine-C2px0RJE.mjs +67 -0
- package/dist/layout-engine-C2px0RJE.mjs.map +1 -0
- package/dist/layout-signals-Cnw6xk8Q.mjs +988 -0
- package/dist/layout-signals-Cnw6xk8Q.mjs.map +1 -0
- package/dist/mouse-events-Dki3ISIp.mjs +1044 -0
- package/dist/mouse-events-Dki3ISIp.mjs.map +1 -0
- package/dist/{multi-progress-Bq9Oi_WI.mjs → multi-progress-CIRjrzma.mjs} +3 -3
- package/dist/{multi-progress-Bq9Oi_WI.mjs.map → multi-progress-CIRjrzma.mjs.map} +1 -1
- package/dist/{multi-progress-DAQC7eap.d.mts → multi-progress-DHZ2xUT2.d.mts} +2 -2
- package/dist/{multi-progress-DAQC7eap.d.mts.map → multi-progress-DHZ2xUT2.d.mts.map} +1 -1
- package/dist/{node-BeWlnCPY.mjs → node-CjM5Rt-M.mjs} +4 -4
- package/dist/node-CjM5Rt-M.mjs.map +1 -0
- package/dist/playwright-D5YiZcNS.mjs +76397 -0
- package/dist/playwright-D5YiZcNS.mjs.map +1 -0
- package/dist/png-codec-Dp84742B.mjs +36 -0
- package/dist/png-codec-Dp84742B.mjs.map +1 -0
- package/dist/png-codec-QwOtJ8Zs.mjs +3 -0
- package/dist/progress-DB_Xo071.mjs +675 -0
- package/dist/progress-DB_Xo071.mjs.map +1 -0
- package/dist/{progress-bar-CXE5Qfkd.mjs → progress-bar-oJwq22CR.mjs} +4 -4
- package/dist/{progress-bar-CXE5Qfkd.mjs.map → progress-bar-oJwq22CR.mjs.map} +1 -1
- package/dist/rasterizer-BRXrDdWx.mjs +3 -0
- package/dist/rasterizer-CpEhJvdR.mjs +296 -0
- package/dist/rasterizer-CpEhJvdR.mjs.map +1 -0
- package/dist/reconciler-DldIJB93.mjs +2083 -0
- package/dist/reconciler-DldIJB93.mjs.map +1 -0
- package/dist/{render-string-CDCeYkS3.mjs → render-string-BcoCpjCB.mjs} +1 -1
- package/dist/{render-string-Darrg7ku.mjs → render-string-DkQacASz.mjs} +2707 -549
- package/dist/render-string-DkQacASz.mjs.map +1 -0
- package/dist/resvg-js-DkOndZI3.mjs +203 -0
- package/dist/resvg-js-DkOndZI3.mjs.map +1 -0
- package/dist/runtime.d.mts +3 -2
- package/dist/runtime.mjs +3 -3
- package/dist/schemes-JjNp4aSl.mjs +2611 -0
- package/dist/schemes-JjNp4aSl.mjs.map +1 -0
- package/dist/{spinner-CGo34vyR.d.mts → spinner-CZINHpkV.d.mts} +2 -2
- package/dist/{spinner-CGo34vyR.d.mts.map → spinner-CZINHpkV.d.mts.map} +1 -1
- package/dist/{spinner-CeOmcuw_.mjs → spinner-D9lrHr8s.mjs} +7 -7
- package/dist/spinner-D9lrHr8s.mjs.map +1 -0
- package/dist/src-5w9QR6_8.mjs +1071 -0
- package/dist/src-5w9QR6_8.mjs.map +1 -0
- package/dist/src-BNTToU7l.mjs +4387 -0
- package/dist/src-BNTToU7l.mjs.map +1 -0
- package/dist/{src-CF-6UN01.mjs → src-BR4xNwdG.mjs} +10436 -2622
- package/dist/src-BR4xNwdG.mjs.map +1 -0
- package/dist/{types-Bk2yw9Qj.mjs → src-DKp-_OFG.mjs} +34 -94
- package/dist/src-DKp-_OFG.mjs.map +1 -0
- package/dist/src-bt8wSrfJ.mjs +258 -0
- package/dist/src-bt8wSrfJ.mjs.map +1 -0
- package/dist/src-e33Y6kNJ.mjs +3 -0
- package/dist/src-iDwu25UD.mjs +1814 -0
- package/dist/src-iDwu25UD.mjs.map +1 -0
- package/dist/steps-Bp2uNqnn.d.mts +202 -0
- package/dist/steps-Bp2uNqnn.d.mts.map +1 -0
- package/dist/svg-15lZZzxq.mjs +486 -0
- package/dist/svg-15lZZzxq.mjs.map +1 -0
- package/dist/svg-Cz0UXcDj.mjs +255 -0
- package/dist/svg-Cz0UXcDj.mjs.map +1 -0
- package/dist/svg-DY72a4HK.mjs +3 -0
- package/dist/svg-g1D6ErwR.d.mts +82 -0
- package/dist/svg-g1D6ErwR.d.mts.map +1 -0
- package/dist/term.d.mts +3 -0
- package/dist/term.mjs +9 -0
- package/dist/term.mjs.map +1 -0
- package/dist/theme.d.mts +95 -2
- package/dist/theme.d.mts.map +1 -0
- package/dist/theme.mjs +9 -3
- package/dist/theme.mjs.map +1 -0
- package/dist/{types-BH_v3iMT.d.mts → types-kt_fKR37.d.mts} +2 -15
- package/dist/types-kt_fKR37.d.mts.map +1 -0
- package/dist/ui/animation.d.mts +2 -1
- package/dist/ui/animation.mjs +1 -1
- package/dist/ui/ansi.d.mts +1 -1
- package/dist/ui/ansi.mjs +1 -1
- package/dist/ui/cli.d.mts +3 -3
- package/dist/ui/cli.mjs +5 -5
- package/dist/ui/display.d.mts +1 -1
- package/dist/ui/image.d.mts +2 -2
- package/dist/ui/image.mjs +2 -2
- package/dist/ui/input.d.mts +1 -1
- package/dist/ui/input.mjs +4 -2
- package/dist/ui/input.mjs.map +1 -1
- package/dist/ui/progress.d.mts +5 -249
- package/dist/ui/progress.mjs +5 -858
- package/dist/ui/react.d.mts +1 -1
- package/dist/ui/react.mjs +2 -2
- package/dist/ui/recording-chrome-react.d.mts +21 -0
- package/dist/ui/recording-chrome-react.d.mts.map +1 -0
- package/dist/ui/recording-chrome-react.mjs +105 -0
- package/dist/ui/recording-chrome-react.mjs.map +1 -0
- package/dist/ui/recording-chrome.d.mts +2 -0
- package/dist/ui/recording-chrome.mjs +2 -0
- package/dist/ui/utils.mjs +1 -1
- package/dist/ui/wrappers.d.mts +3 -3
- package/dist/ui/wrappers.mjs +2 -2
- package/dist/ui.d.mts +7 -6
- package/dist/ui.mjs +8 -7
- package/dist/{useLatest-Bg2x4bfP.d.mts → useLatest-DRDDVwjh.d.mts} +5 -25
- package/dist/useLatest-DRDDVwjh.d.mts.map +1 -0
- package/dist/{with-text-input-CRfoiFFG.d.mts → with-text-input-YeohVLeo.d.mts} +4 -55
- package/dist/with-text-input-YeohVLeo.d.mts.map +1 -0
- package/dist/wrapper-C70ATkVv.mjs +3527 -0
- package/dist/wrapper-C70ATkVv.mjs.map +1 -0
- package/dist/{wrappers-UTADQkSY.mjs → wrappers-BCUYITrY.mjs} +5 -157
- package/dist/wrappers-BCUYITrY.mjs.map +1 -0
- package/dist/{yoga-adapter-8oRGRw8V.mjs → yoga-adapter-BnZX1PAY.mjs} +28 -2
- package/dist/yoga-adapter-BnZX1PAY.mjs.map +1 -0
- package/dist/yoga-adapter-DxgsQ_gg.mjs +2 -0
- package/dist/zipBundle-3nqeDRtm.mjs +3 -0
- package/dist/zipBundle-VNAYFmqJ.mjs +2003 -0
- package/dist/zipBundle-VNAYFmqJ.mjs.map +1 -0
- package/package.json +20 -9
- package/dist/animation-Cn64yepo.mjs.map +0 -1
- package/dist/cli-BKp0YtBD.mjs +0 -4
- package/dist/devtools-9QY4teqI.mjs +0 -2
- package/dist/flexily-zero-adapter-BlQa46nr.mjs +0 -3385
- package/dist/flexily-zero-adapter-BlQa46nr.mjs.map +0 -1
- package/dist/image-CTII5QWI.mjs +0 -477
- package/dist/image-CTII5QWI.mjs.map +0 -1
- package/dist/index-BXslOebb.d.mts.map +0 -1
- package/dist/index-BnA7mNpo.d.mts +0 -175
- package/dist/index-BnA7mNpo.d.mts.map +0 -1
- package/dist/index-D3saHouR.d.mts.map +0 -1
- package/dist/layout-engine-ClUgv6jB.mjs +0 -50
- package/dist/layout-engine-ClUgv6jB.mjs.map +0 -1
- package/dist/node-BeWlnCPY.mjs.map +0 -1
- package/dist/reconciler-Cwgm8hRR.mjs +0 -8459
- package/dist/reconciler-Cwgm8hRR.mjs.map +0 -1
- package/dist/render-string-Darrg7ku.mjs.map +0 -1
- package/dist/spinner-CeOmcuw_.mjs.map +0 -1
- package/dist/src-B5GjfG7g.mjs +0 -4305
- package/dist/src-B5GjfG7g.mjs.map +0 -1
- package/dist/src-CChwjk0Z.mjs +0 -738
- package/dist/src-CChwjk0Z.mjs.map +0 -1
- package/dist/src-CF-6UN01.mjs.map +0 -1
- package/dist/src-NCKb8kE5.mjs +0 -2660
- package/dist/src-NCKb8kE5.mjs.map +0 -1
- package/dist/types-BH_v3iMT.d.mts.map +0 -1
- package/dist/types-Bk2yw9Qj.mjs.map +0 -1
- package/dist/ui/progress.d.mts.map +0 -1
- package/dist/ui/progress.mjs.map +0 -1
- package/dist/useLatest-Bg2x4bfP.d.mts.map +0 -1
- package/dist/with-text-input-CRfoiFFG.d.mts.map +0 -1
- package/dist/wrappers-UTADQkSY.mjs.map +0 -1
- package/dist/yoga-adapter-8oRGRw8V.mjs.map +0 -1
- package/dist/yoga-adapter-D_CcxSt5.mjs +0 -2
|
@@ -1,136 +1,40 @@
|
|
|
1
|
-
//#region packages/ansi/src/
|
|
2
|
-
interface TerminalCaps {
|
|
3
|
-
/** Terminal program name (from TERM_PROGRAM) */
|
|
4
|
-
program: string;
|
|
5
|
-
/** TERM value */
|
|
6
|
-
term: string;
|
|
7
|
-
/** Color support level */
|
|
8
|
-
colorLevel: "none" | "basic" | "256" | "truecolor";
|
|
9
|
-
/** Kitty keyboard protocol supported */
|
|
10
|
-
kittyKeyboard: boolean;
|
|
11
|
-
/** Kitty graphics protocol (inline images) */
|
|
12
|
-
kittyGraphics: boolean;
|
|
13
|
-
/** Sixel graphics supported */
|
|
14
|
-
sixel: boolean;
|
|
15
|
-
/** OSC 52 clipboard */
|
|
16
|
-
osc52: boolean;
|
|
17
|
-
/** OSC 8 hyperlinks */
|
|
18
|
-
hyperlinks: boolean;
|
|
19
|
-
/** OSC 9/99 notifications */
|
|
20
|
-
notifications: boolean;
|
|
21
|
-
/** Bracketed paste mode */
|
|
22
|
-
bracketedPaste: boolean;
|
|
23
|
-
/** SGR mouse tracking */
|
|
24
|
-
mouse: boolean;
|
|
25
|
-
/** Synchronized output (DEC 2026) */
|
|
26
|
-
syncOutput: boolean;
|
|
27
|
-
/** Unicode/emoji support */
|
|
28
|
-
unicode: boolean;
|
|
29
|
-
/** SGR 4:x underline style subparameters (curly, dotted, dashed) */
|
|
30
|
-
underlineStyles: boolean;
|
|
31
|
-
/** SGR 58 underline color */
|
|
32
|
-
underlineColor: boolean;
|
|
33
|
-
/** Text-presentation emoji (⚠, ☑, ⭐) rendered as 2-wide.
|
|
34
|
-
* Modern terminals (Ghostty, iTerm, Kitty) render these at emoji width (2 cells).
|
|
35
|
-
* Terminal.app renders them at text width (1 cell). */
|
|
36
|
-
textEmojiWide: boolean;
|
|
37
|
-
/** OSC 66 text sizing protocol likely supported (Kitty 0.40+, Ghostty) */
|
|
38
|
-
textSizingSupported: boolean;
|
|
39
|
-
/** Heuristic: likely dark background (for theme selection) */
|
|
40
|
-
darkBackground: boolean;
|
|
41
|
-
/** Heuristic: likely has Nerd Font installed (for icon selection) */
|
|
42
|
-
nerdfont: boolean;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Default capabilities (assumes modern terminal with full support).
|
|
46
|
-
*/
|
|
47
|
-
declare function defaultCaps(): TerminalCaps;
|
|
48
|
-
/** Detect terminal capabilities from environment variables.
|
|
49
|
-
* Synchronous. Minimal I/O: may run `defaults` on macOS for Apple_Terminal.
|
|
50
|
-
*/
|
|
51
|
-
declare function detectTerminalCaps(): TerminalCaps;
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region packages/ansi/src/types.d.ts
|
|
54
|
-
/**
|
|
55
|
-
* Type definitions for @silvery/ansi
|
|
56
|
-
*/
|
|
57
|
-
/**
|
|
58
|
-
* Color level supported by terminal.
|
|
59
|
-
* - 'basic': 16 colors (SGR 30-37, 40-47)
|
|
60
|
-
* - '256': 256 colors (SGR 38;5;n)
|
|
61
|
-
* - 'truecolor': 16M colors (SGR 38;2;r;g;b)
|
|
62
|
-
*/
|
|
63
|
-
type ColorLevel = "basic" | "256" | "truecolor";
|
|
64
|
-
//#endregion
|
|
65
|
-
//#region packages/ansi/src/color-maps.d.ts
|
|
66
|
-
/**
|
|
67
|
-
* Color tier for preview quantization.
|
|
68
|
-
*
|
|
69
|
-
* Mirrors the tiers a real terminal would resolve to when the output phase
|
|
70
|
-
* emits ANSI: `truecolor` (pass-through), `256` (6×6×6 cube + grayscale ramp),
|
|
71
|
-
* `ansi16` (nearest of 16 slots), `mono` (luminance → black/white).
|
|
72
|
-
*/
|
|
73
|
-
type ColorTier = "truecolor" | "256" | "ansi16" | "mono";
|
|
1
|
+
//#region packages/ansi/src/emulator.d.ts
|
|
74
2
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* Takes any hex color and returns the hex a real terminal at that tier would
|
|
78
|
-
* actually emit. Used by the Sterling storybook to make the `1/2/3/4` tier
|
|
79
|
-
* toggle visibly different in-process — the output phase already does this
|
|
80
|
-
* when writing to a real TTY, but preview surfaces (theme swatches, rendered
|
|
81
|
-
* components inside a storybook app) bypass output-phase quantization. Apply
|
|
82
|
-
* `quantizeHex` at render time to mimic tier-specific terminal output.
|
|
3
|
+
* Terminal emulator identity — facts about *what terminal this IS*, as
|
|
4
|
+
* opposed to {@link ./caps#TerminalCaps} which describes what it can DO.
|
|
83
5
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
6
|
+
* Identity doesn't gate rendering; it's what tests, diagnostics, and
|
|
7
|
+
* probe-cache keys discriminate on (e.g. `program@version` is the cache key
|
|
8
|
+
* used by `@silvery/ag-term/text-sizing` per km-silvery.unicode-plateau
|
|
9
|
+
* Phase 2).
|
|
88
10
|
*
|
|
89
|
-
*
|
|
11
|
+
* Resolved once by {@link ./profile#createTerminalProfile} and exposed as
|
|
12
|
+
* `profile.emulator` — no other module reads TERM / TERM_PROGRAM.
|
|
90
13
|
*/
|
|
91
|
-
declare function quantizeHex(hex: string, tier: ColorTier): string;
|
|
92
14
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* Works on both the legacy ANSI Theme (flat hex tokens + `palette` array)
|
|
103
|
-
* and the Sterling Theme (nested roles + flat tokens) — the structural rule
|
|
104
|
-
* "any leaf that looks like a hex is a color value" holds for both.
|
|
105
|
-
*
|
|
106
|
-
* @example Pre-cache tier variants
|
|
107
|
-
* ```ts
|
|
108
|
-
* import { pickColorLevel } from "silvery"
|
|
109
|
-
*
|
|
110
|
-
* const themes = {
|
|
111
|
-
* truecolor: theme,
|
|
112
|
-
* ansi16: pickColorLevel(theme, "ansi16"),
|
|
113
|
-
* mono: pickColorLevel(theme, "mono"),
|
|
114
|
-
* }
|
|
115
|
-
* ```
|
|
116
|
-
*
|
|
117
|
-
* @example Storybook — show multiple tiers simultaneously
|
|
118
|
-
* ```tsx
|
|
119
|
-
* <ThemeProvider theme={pickColorLevel(theme, "ansi16")}>
|
|
120
|
-
* <AlertPreview />
|
|
121
|
-
* </ThemeProvider>
|
|
122
|
-
* ```
|
|
123
|
-
*
|
|
124
|
-
* Notes:
|
|
125
|
-
* - `truecolor` is a no-op — returns the input unchanged (identity).
|
|
126
|
-
* - The result is structurally identical to the input (same keys, same
|
|
127
|
-
* nesting); only hex leaves are remapped.
|
|
128
|
-
* - Idempotent per tier: `pickColorLevel(pickColorLevel(t, "ansi16"), "ansi16")`
|
|
129
|
-
* yields the same hex values as `pickColorLevel(t, "ansi16")`.
|
|
130
|
-
* - Does not freeze the returned object. Callers that want immutability
|
|
131
|
-
* should `Object.freeze()` (or deep-freeze) the result themselves.
|
|
15
|
+
* Environment identity — facts about what terminal this IS. Separate from
|
|
16
|
+
* {@link ./caps#TerminalCaps} because identity doesn't gate rendering; it's
|
|
17
|
+
* what tests, diagnostics, and probe-cache keys discriminate on.
|
|
18
|
+
*
|
|
19
|
+
* Post km-silvery.plateau-naming-polish (2026-04-23): renamed from
|
|
20
|
+
* `TerminalIdentity` → `TerminalEmulator` (the thing IS a terminal emulator,
|
|
21
|
+
* matches `TERM_PROGRAM` provenance) and `termName` → `TERM` (matches the
|
|
22
|
+
* env var name and shell convention).
|
|
132
23
|
*/
|
|
133
|
-
|
|
24
|
+
interface TerminalEmulator {
|
|
25
|
+
/** Terminal program name (from TERM_PROGRAM). */
|
|
26
|
+
readonly program: string;
|
|
27
|
+
/** Terminal program version string (from TERM_PROGRAM_VERSION). Empty when
|
|
28
|
+
* the host doesn't advertise a version. Together with `program`, forms the
|
|
29
|
+
* `program@version` fingerprint used as the probe-cache key in
|
|
30
|
+
* `@silvery/ag-term/text-sizing`. See km-silvery.unicode-plateau Phase 2. */
|
|
31
|
+
readonly version: string;
|
|
32
|
+
/** Value of the `TERM` env var (`"xterm-kitty"`, `"xterm-256color"`, …).
|
|
33
|
+
* Named `TERM` rather than `termName` to mirror the env-var name
|
|
34
|
+
* explicitly — the field's sole source is the `TERM` environment entry,
|
|
35
|
+
* resolved once by `createTerminalProfile`. */
|
|
36
|
+
readonly TERM: string;
|
|
37
|
+
}
|
|
134
38
|
//#endregion
|
|
135
39
|
//#region packages/ansi/src/flatten.d.ts
|
|
136
40
|
/**
|
|
@@ -219,190 +123,405 @@ declare const defaultFlattenRule: FlattenRule;
|
|
|
219
123
|
*/
|
|
220
124
|
declare function bakeFlat<T extends object>(theme: T, rule?: FlattenRule): T;
|
|
221
125
|
//#endregion
|
|
222
|
-
//#region packages/ansi/src/
|
|
126
|
+
//#region packages/ansi/src/sterling/types.d.ts
|
|
223
127
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
* - **1003** (any-event tracking): Reports ALL mouse motion — clicks, drags, AND hover.
|
|
228
|
-
* This is what makes onMouseEnter/onMouseLeave work. Without it, only clicks are reported.
|
|
229
|
-
* - **1006** (SGR encoding): Decimal coordinates with no 223-column limit.
|
|
128
|
+
* Surface-only state pair: only `bg` varies by state. Used by the status
|
|
129
|
+
* roles (`info`, `success`, `warning`, `error`) where state variants are
|
|
130
|
+
* meaningful only for surfaces (filled bg), never for text.
|
|
230
131
|
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
* Mode 1003 supersedes 1000 and 1002. Using 1000+1002 instead of 1003 silently
|
|
236
|
-
* disables hover — onMouseEnter/onMouseLeave stop firing with no error.
|
|
132
|
+
* Text tokens on status roles don't hover — `fg-error` is a status color,
|
|
133
|
+
* not an interactive link. Keeping `fg.hover` / `fg.active` on those roles
|
|
134
|
+
* invited algorithmic over-generation that produced illegible results
|
|
135
|
+
* (e.g. catppuccin-frappe `warning.active.fg` collapsing to `#FFFFFF`).
|
|
237
136
|
*/
|
|
238
|
-
|
|
137
|
+
interface BgStatePair {
|
|
138
|
+
readonly bg: string;
|
|
139
|
+
}
|
|
239
140
|
/**
|
|
240
|
-
*
|
|
141
|
+
* Interactive (link-like) state pair: both `fg` and `bg` vary by state.
|
|
142
|
+
* Used by `accent` — the canonical interactive-text role.
|
|
241
143
|
*/
|
|
242
|
-
|
|
144
|
+
interface StatePair {
|
|
145
|
+
readonly fg: string;
|
|
146
|
+
readonly bg: string;
|
|
147
|
+
}
|
|
243
148
|
/**
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
* Supported by: Ghostty, Kitty, WezTerm, foot. Ignored by unsupported terminals.
|
|
248
|
-
*
|
|
249
|
-
* Flags are a bitfield:
|
|
250
|
-
*
|
|
251
|
-
* | Flag | Bit | Description |
|
|
252
|
-
* | ---- | --- | ----------------------------------------- |
|
|
253
|
-
* | 1 | 0 | Disambiguate escape codes |
|
|
254
|
-
* | 2 | 1 | Report event types (press/repeat/release) |
|
|
255
|
-
* | 4 | 2 | Report alternate keys |
|
|
256
|
-
* | 8 | 3 | Report all keys as escape codes |
|
|
257
|
-
* | 16 | 4 | Report associated text |
|
|
149
|
+
* A status role — fg, bg, and `fgOn` (text color to draw when rendering ON
|
|
150
|
+
* a filled bg of this role). State variants apply to SURFACE (bg) only;
|
|
151
|
+
* text-color state variants are reserved for link-like roles (`accent`).
|
|
258
152
|
*
|
|
259
|
-
*
|
|
153
|
+
* Used for the four status families: `info`, `success`, `warning`, `error`.
|
|
260
154
|
*/
|
|
261
|
-
|
|
155
|
+
interface StatusRole {
|
|
156
|
+
/** Foreground hex — use for text/icon in this role. */
|
|
157
|
+
readonly fg: string;
|
|
158
|
+
/** Background hex — use as fill for emphasis. */
|
|
159
|
+
readonly bg: string;
|
|
160
|
+
/** Foreground to use when drawing ON `bg` (contrast-picked). */
|
|
161
|
+
readonly fgOn: string;
|
|
162
|
+
/** Hover state — surface only (adaptive ±L shift on bg). */
|
|
163
|
+
readonly hover: BgStatePair;
|
|
164
|
+
/** Active (pressed) state — surface only (adaptive ±L shift on bg). */
|
|
165
|
+
readonly active: BgStatePair;
|
|
166
|
+
}
|
|
262
167
|
/**
|
|
263
|
-
*
|
|
264
|
-
*
|
|
168
|
+
* @deprecated Renamed to `StatusRole` for clarity (the family lacks the
|
|
169
|
+
* `fg.hover/active` interaction states the old name implied). The alias is
|
|
170
|
+
* retained for one cycle so external consumers don't break on rename.
|
|
265
171
|
*/
|
|
266
|
-
|
|
267
|
-
//#endregion
|
|
268
|
-
//#region packages/ansi/src/style/style.d.ts
|
|
172
|
+
type InteractiveRole = StatusRole;
|
|
269
173
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
* Supports `$primary`, `$surface-bg` (hyphens stripped), `$color0`–`$color15` (palette).
|
|
274
|
-
* Non-`$` strings pass through unchanged. Returns undefined if no theme or unknown token.
|
|
275
|
-
*
|
|
276
|
-
* Compatible with @silvery/theme's Theme type (or any object with string properties).
|
|
174
|
+
* Accent — the canonical link-like interactive-text role. Has everything
|
|
175
|
+
* `StatusRole` does PLUS a focus-ring border AND `fg.hover` /
|
|
176
|
+
* `fg.active` text-color state variants (link hover treatments).
|
|
277
177
|
*/
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
178
|
+
interface AccentRole {
|
|
179
|
+
/** Foreground hex — use for text/icon in accent. */
|
|
180
|
+
readonly fg: string;
|
|
181
|
+
/** Background hex — use as fill for emphasis. */
|
|
182
|
+
readonly bg: string;
|
|
183
|
+
/** Foreground to use when drawing ON `bg` (contrast-picked). */
|
|
184
|
+
readonly fgOn: string;
|
|
185
|
+
/** Border color for focus rings using this accent. */
|
|
186
|
+
readonly border: string;
|
|
187
|
+
/** Hover state — both fg (link hover) and bg (surface hover). */
|
|
188
|
+
readonly hover: StatePair;
|
|
189
|
+
/** Active (pressed) state — both fg and bg. */
|
|
190
|
+
readonly active: StatePair;
|
|
191
|
+
}
|
|
192
|
+
/** Surface hierarchy — `default` is the canvas, subtle/raised/overlay stack upward. */
|
|
193
|
+
interface SurfaceRole {
|
|
194
|
+
readonly default: string;
|
|
195
|
+
readonly subtle: string;
|
|
196
|
+
readonly raised: string;
|
|
197
|
+
readonly overlay: string;
|
|
198
|
+
readonly hover: string;
|
|
199
|
+
}
|
|
200
|
+
/** Border roles — `focus` is the focus-ring color; `default` is normal rule line. */
|
|
201
|
+
interface BorderRole {
|
|
202
|
+
readonly default: string;
|
|
203
|
+
readonly focus: string;
|
|
204
|
+
readonly muted: string;
|
|
205
|
+
}
|
|
206
|
+
/** Cursor colors. */
|
|
207
|
+
interface CursorRole {
|
|
208
|
+
readonly fg: string;
|
|
209
|
+
readonly bg: string;
|
|
210
|
+
}
|
|
211
|
+
/** Muted role — lower-emphasis text/bg for deemphasized content. */
|
|
212
|
+
interface MutedRole {
|
|
213
|
+
readonly fg: string;
|
|
214
|
+
readonly bg: string;
|
|
215
|
+
}
|
|
281
216
|
/**
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* Layer 2: Theme — ~33 semantic tokens (what UI apps consume)
|
|
287
|
-
*
|
|
288
|
-
* Pipeline: Scheme catalog → ColorScheme (22) → deriveTheme() → Theme (33)
|
|
217
|
+
* Selected role — the highlight surface for the cursor row, mouse selection,
|
|
218
|
+
* search-match highlight, and any "this is the active item" treatment.
|
|
219
|
+
* `fgOn` is the text color drawn on `bg`; `hover.bg` is the +0.04L shift used
|
|
220
|
+
* by SelectList row hover.
|
|
289
221
|
*/
|
|
290
|
-
interface
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
black: string;
|
|
295
|
-
red: string;
|
|
296
|
-
green: string;
|
|
297
|
-
yellow: string;
|
|
298
|
-
blue: string;
|
|
299
|
-
magenta: string;
|
|
300
|
-
cyan: string;
|
|
301
|
-
white: string;
|
|
302
|
-
brightBlack: string;
|
|
303
|
-
brightRed: string;
|
|
304
|
-
brightGreen: string;
|
|
305
|
-
brightYellow: string;
|
|
306
|
-
brightBlue: string;
|
|
307
|
-
brightMagenta: string;
|
|
308
|
-
brightCyan: string;
|
|
309
|
-
brightWhite: string;
|
|
310
|
-
foreground: string;
|
|
311
|
-
background: string;
|
|
312
|
-
cursorColor: string;
|
|
313
|
-
cursorText: string;
|
|
314
|
-
selectionBackground: string;
|
|
315
|
-
selectionForeground: string;
|
|
222
|
+
interface SelectedRole {
|
|
223
|
+
readonly bg: string;
|
|
224
|
+
readonly fgOn: string;
|
|
225
|
+
readonly hover: BgStatePair;
|
|
316
226
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
surfacebg: string;
|
|
326
|
-
popover: string;
|
|
327
|
-
popoverbg: string;
|
|
328
|
-
inverse: string;
|
|
329
|
-
inversebg: string;
|
|
330
|
-
cursor: string;
|
|
331
|
-
cursorbg: string;
|
|
332
|
-
selection: string;
|
|
333
|
-
selectionbg: string;
|
|
334
|
-
primary: string;
|
|
335
|
-
primaryfg: string;
|
|
336
|
-
secondary: string;
|
|
337
|
-
secondaryfg: string;
|
|
338
|
-
accent: string;
|
|
339
|
-
accentfg: string;
|
|
340
|
-
error: string;
|
|
341
|
-
errorfg: string;
|
|
342
|
-
warning: string;
|
|
343
|
-
warningfg: string;
|
|
344
|
-
success: string;
|
|
345
|
-
successfg: string;
|
|
346
|
-
info: string;
|
|
347
|
-
infofg: string;
|
|
348
|
-
border: string;
|
|
349
|
-
inputborder: string;
|
|
350
|
-
focusborder: string;
|
|
351
|
-
link: string;
|
|
352
|
-
disabledfg: string;
|
|
353
|
-
palette: string[];
|
|
354
|
-
brand: string;
|
|
355
|
-
/** Kebab key for $brand-hover. Hover lightness shift (+0.04L OKLCH). */
|
|
356
|
-
"brand-hover": string;
|
|
357
|
-
/** Kebab key for $brand-active. Active lightness shift (+0.08L OKLCH). */
|
|
358
|
-
"brand-active": string;
|
|
359
|
-
/** Kebab key for $primary-hover. */
|
|
360
|
-
"primary-hover": string;
|
|
361
|
-
/** Kebab key for $primary-active. */
|
|
362
|
-
"primary-active": string;
|
|
363
|
-
/** Kebab key for $accent-hover. */
|
|
364
|
-
"accent-hover": string;
|
|
365
|
-
/** Kebab key for $accent-active. */
|
|
366
|
-
"accent-active": string;
|
|
367
|
-
/** Kebab key for $fg-hover. */
|
|
368
|
-
"fg-hover": string;
|
|
369
|
-
/** Kebab key for $fg-active. */
|
|
370
|
-
"fg-active": string;
|
|
371
|
-
/** Kebab key for $bg-selected-hover. */
|
|
372
|
-
"bg-selected-hover": string;
|
|
373
|
-
/** Kebab key for $bg-surface-hover. */
|
|
374
|
-
"bg-surface-hover": string;
|
|
375
|
-
red: string;
|
|
376
|
-
orange: string;
|
|
377
|
-
yellow: string;
|
|
378
|
-
green: string;
|
|
379
|
-
teal: string;
|
|
380
|
-
blue: string;
|
|
381
|
-
purple: string;
|
|
382
|
-
pink: string;
|
|
383
|
-
/**
|
|
384
|
-
* Named typography variants — resolved by `<Text variant="h1">`.
|
|
385
|
-
*
|
|
386
|
-
* Each variant is a bundle of visual defaults (color, bold, italic, dim,
|
|
387
|
-
* underlineStyle). Caller props always win over variant values — the variant
|
|
388
|
-
* is the *default*, not an override.
|
|
389
|
-
*
|
|
390
|
-
* Apps extend variants via:
|
|
391
|
-
* ```tsx
|
|
392
|
-
* <ThemeProvider tokens={{ variants: { hero: { color: "$brand", bold: true } } }}>
|
|
393
|
-
* ```
|
|
394
|
-
*/
|
|
395
|
-
variants: Record<string, Variant$1>;
|
|
227
|
+
/**
|
|
228
|
+
* Inverse role — flipped surface used for status bars, modal chrome, the
|
|
229
|
+
* "you are here" inverse band. Subtle blend of fg into bg, with `fgOn`
|
|
230
|
+
* picked for AA contrast against the resulting surface.
|
|
231
|
+
*/
|
|
232
|
+
interface InverseRole {
|
|
233
|
+
readonly bg: string;
|
|
234
|
+
readonly fgOn: string;
|
|
396
235
|
}
|
|
397
236
|
/**
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
237
|
+
* Link role — hyperlink text color. Distinct from `accent` so apps that want
|
|
238
|
+
* "link blue" (as opposed to the brand-derived accent) can opt in. Single
|
|
239
|
+
* `fg` slot — links are text, not surfaces; if a link surface is ever needed,
|
|
240
|
+
* extend with `bg` + `fgOn` then.
|
|
241
|
+
*/
|
|
242
|
+
interface LinkRole {
|
|
243
|
+
readonly fg: string;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Disabled role — neutral, deemphasized treatment for unavailable controls
|
|
247
|
+
* (read-only inputs, disabled buttons, inactive menu items). Composite-derived
|
|
248
|
+
* from the base interface tokens (`fg-default` / `border-default`) over
|
|
249
|
+
* `bg-surface-default`, NOT from accent/status families — disabled is meant
|
|
250
|
+
* to read as "absent / inactive", not as a muted error/success/etc.
|
|
251
|
+
*
|
|
252
|
+
* Derivation (per design-system.md §"Disabled derivation"):
|
|
253
|
+
* - `fg-disabled = composite(fg-default @ 0.38, bg-surface-default)`
|
|
254
|
+
* clamped to ≥3:1 contrast vs `bg-surface-default`
|
|
255
|
+
* - `border-disabled = composite(border-default @ 0.24, bg-surface-default)`
|
|
256
|
+
* - `bg-disabled = composite(border-default @ 0.12, bg-surface-default)`
|
|
257
|
+
*/
|
|
258
|
+
interface DisabledRole {
|
|
259
|
+
readonly fg: string;
|
|
260
|
+
readonly bg: string;
|
|
261
|
+
readonly border: string;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* The nested, programmatic form of a Theme. All leaf values are hex strings.
|
|
265
|
+
* Reached via `theme.accent.bg`, `theme.surface.raised`, etc.
|
|
266
|
+
*/
|
|
267
|
+
interface Roles {
|
|
268
|
+
readonly accent: AccentRole;
|
|
269
|
+
readonly info: StatusRole;
|
|
270
|
+
readonly success: StatusRole;
|
|
271
|
+
readonly warning: StatusRole;
|
|
272
|
+
readonly error: StatusRole;
|
|
273
|
+
readonly muted: MutedRole;
|
|
274
|
+
readonly surface: SurfaceRole;
|
|
275
|
+
readonly border: BorderRole;
|
|
276
|
+
readonly cursor: CursorRole;
|
|
277
|
+
readonly selected: SelectedRole;
|
|
278
|
+
readonly inverse: InverseRole;
|
|
279
|
+
readonly link: LinkRole;
|
|
280
|
+
readonly disabled: DisabledRole;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Every flat hyphen-key that Sterling emits. String-literal union so that
|
|
284
|
+
* `theme["bg-accent"]` is type-checked and typos fail the compile.
|
|
285
|
+
*
|
|
286
|
+
* Grammar: `prefix-role[-state]` or `prefix-on-role` or `prefix-role-kind[-state]`.
|
|
287
|
+
* (See design-system.md §"Flattening rule".)
|
|
288
|
+
*/
|
|
289
|
+
type FlatToken = "bg-surface-default" | "bg-surface-subtle" | "bg-surface-raised" | "bg-surface-overlay" | "bg-surface-hover" | "border-default" | "border-focus" | "border-muted" | "fg-cursor" | "bg-cursor" | "fg-muted" | "bg-muted" | "fg-accent" | "bg-accent" | "fg-on-accent" | "fg-accent-hover" | "bg-accent-hover" | "fg-accent-active" | "bg-accent-active" | "border-accent" | "fg-info" | "bg-info" | "fg-on-info" | "bg-info-hover" | "bg-info-active" | "fg-success" | "bg-success" | "fg-on-success" | "bg-success-hover" | "bg-success-active" | "fg-warning" | "bg-warning" | "fg-on-warning" | "bg-warning-hover" | "bg-warning-active" | "fg-error" | "bg-error" | "fg-on-error" | "bg-error-hover" | "bg-error-active" | "bg-selected" | "fg-on-selected" | "bg-selected-hover" | "bg-inverse" | "fg-on-inverse" | "fg-link" | "fg-disabled" | "bg-disabled" | "border-disabled" | "bg-backdrop" | "fg-default" | "bg-default";
|
|
290
|
+
/** The flat projection — every FlatToken maps to a hex string. */
|
|
291
|
+
type FlatTokens = { readonly [K in FlatToken]: string };
|
|
292
|
+
/**
|
|
293
|
+
* Per-token record of HOW a token was derived. Populated only when the
|
|
294
|
+
* derivation is called with `{ trace: true }`. Used by the Sterling
|
|
295
|
+
* storybook to visualize derivation rules.
|
|
296
|
+
*/
|
|
297
|
+
interface DerivationStep {
|
|
298
|
+
/** Token path (e.g. `"accent.hover.bg"` or flat `"bg-accent-hover"`). */
|
|
299
|
+
readonly token: string;
|
|
300
|
+
/** Human-readable rule name (e.g. `"OKLCH +0.04L on accent.bg"`). */
|
|
301
|
+
readonly rule: string;
|
|
302
|
+
/** Input hex(es) the rule operated on. */
|
|
303
|
+
readonly inputs: readonly string[];
|
|
304
|
+
/** Output hex. */
|
|
305
|
+
readonly output: string;
|
|
306
|
+
/** If auto-lift adjusted this token, the original value before adjustment. */
|
|
307
|
+
readonly liftedFrom?: string;
|
|
308
|
+
/** If pinned by scheme author, true. */
|
|
309
|
+
readonly pinned?: boolean;
|
|
310
|
+
}
|
|
311
|
+
type DerivationTrace = readonly DerivationStep[];
|
|
312
|
+
/**
|
|
313
|
+
* Categorical color ring — 8 harmonious hues for tagging, chart series,
|
|
314
|
+
* calendar categories, priority levels — any CATEGORICAL color that isn't
|
|
315
|
+
* stateful. ensureContrast-adjusted against bg at derivation time. Consumers
|
|
316
|
+
* access these via `$red`, `$orange`, …, `$pink` or direct field access.
|
|
317
|
+
*
|
|
318
|
+
* Distinguish from:
|
|
319
|
+
* - `$color0..$color15` — raw terminal ANSI (user's theme verbatim)
|
|
320
|
+
* - `$error/$warning/$success` — semantic state (communicates meaning)
|
|
321
|
+
* - `$brand` — app identity anchor (one color)
|
|
322
|
+
*/
|
|
323
|
+
interface CategoricalHues {
|
|
324
|
+
readonly red: string;
|
|
325
|
+
readonly orange: string;
|
|
326
|
+
readonly yellow: string;
|
|
327
|
+
readonly green: string;
|
|
328
|
+
readonly teal: string;
|
|
329
|
+
readonly blue: string;
|
|
330
|
+
readonly purple: string;
|
|
331
|
+
readonly pink: string;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The canonical Sterling Theme — Sterling flat tokens + nested roles on the
|
|
335
|
+
* same object, plus a small surface of non-token metadata and runtime
|
|
336
|
+
* convenience fields the framework depends on:
|
|
337
|
+
*
|
|
338
|
+
* Two access paths for every hex leaf:
|
|
339
|
+
* - Nested: `theme.accent.hover.bg`
|
|
340
|
+
* - Flat: `theme["bg-accent-hover"]`
|
|
341
|
+
* Both paths reference the same string (not copies). The object is frozen
|
|
342
|
+
* after derivation (see `flatten.ts`).
|
|
343
|
+
*
|
|
344
|
+
* Non-token metadata:
|
|
345
|
+
* - `name` — scheme display name (if derived from a named scheme)
|
|
346
|
+
* - `mode` — light/dark
|
|
347
|
+
* - `derivationTrace` — optional; present only when `{ trace: true }` was passed
|
|
348
|
+
* - `variants` — typography preset bundles (h1, body, code, …) resolved by
|
|
349
|
+
* `<Text variant="…">`
|
|
350
|
+
* - `palette` — 16-slot ANSI catalog used by `$color0` … `$color15`
|
|
351
|
+
* - categorical hues (`red`, `orange`, `yellow`, `green`, `teal`, `blue`,
|
|
352
|
+
* `purple`, `pink`) — hex strings for categorical UI
|
|
353
|
+
*
|
|
354
|
+
* Root pair:
|
|
355
|
+
* - `fg` — default text color (= `scheme.foreground`)
|
|
356
|
+
* - `bg` — default canvas color (= `scheme.background`; same value as
|
|
357
|
+
* `bg-surface-default` but exposed at the root for `$fg` / `$bg`
|
|
358
|
+
* JSX consumers and convenience access)
|
|
359
|
+
*
|
|
360
|
+
* The nested roles (`accent`, `muted`, `surface`, `border`, `cursor`, plus
|
|
361
|
+
* the status roles `info`/`success`/`warning`/`error`) are authoritative for
|
|
362
|
+
* stateful tokens. Legacy flat hex aliases for these roles (`theme.primary`,
|
|
363
|
+
* `theme.muted`, `theme.accent` as strings) are emitted as runtime
|
|
364
|
+
* conveniences via the scheme-builder but are not part of this type — they
|
|
365
|
+
* were deleted in silvery 0.19.0.
|
|
366
|
+
*/
|
|
367
|
+
type Theme = FlatTokens & Roles & {
|
|
368
|
+
readonly name?: string;
|
|
369
|
+
readonly mode: "light" | "dark";
|
|
370
|
+
readonly derivationTrace?: DerivationTrace;
|
|
371
|
+
readonly variants: Record<string, Variant>;
|
|
372
|
+
readonly palette: readonly string[]; /** Default text color (= `scheme.foreground`). Heavily used as `$fg` in JSX. */
|
|
373
|
+
readonly fg: string;
|
|
374
|
+
/**
|
|
375
|
+
* Default canvas color (= `scheme.background`). Same value as
|
|
376
|
+
* `bg-surface-default`; exposed at the root for `$bg` JSX consumers and
|
|
377
|
+
* convenience access.
|
|
378
|
+
*/
|
|
379
|
+
readonly bg: string;
|
|
380
|
+
} & CategoricalHues;
|
|
381
|
+
/**
|
|
382
|
+
* A typography variant — a named bundle of visual properties applied to a
|
|
383
|
+
* Text component via `variant="h1"`. The variant acts as a *default*: caller
|
|
384
|
+
* props always win over variant values.
|
|
385
|
+
*
|
|
386
|
+
* Color values follow the same syntax as `TextColor` — `$token` strings, hex
|
|
387
|
+
* values, ANSI names, or any string accepted by the color system.
|
|
388
|
+
*/
|
|
389
|
+
interface Variant {
|
|
390
|
+
readonly color?: string;
|
|
391
|
+
readonly backgroundColor?: string;
|
|
392
|
+
readonly bold?: boolean;
|
|
393
|
+
readonly italic?: boolean;
|
|
394
|
+
readonly dim?: boolean;
|
|
395
|
+
readonly underlineStyle?: "single" | "double" | "curly" | "dotted" | "dashed";
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Metadata describing a DesignSystem's Theme shape — for tooling (docs,
|
|
399
|
+
* storybook, CSS export). Plain data, no functions.
|
|
400
|
+
*/
|
|
401
|
+
interface ThemeShape {
|
|
402
|
+
/** The list of FlatTokens this system emits. */
|
|
403
|
+
readonly flatTokens: readonly string[];
|
|
404
|
+
/** The list of role-object keys this system emits (e.g. `["accent", "info", ...]`). */
|
|
405
|
+
readonly roles: readonly string[];
|
|
406
|
+
/** The list of state variants used on interactive roles (e.g. `["hover", "active"]`). */
|
|
407
|
+
readonly states: readonly string[];
|
|
408
|
+
}
|
|
409
|
+
/** Contrast enforcement mode for derivation. See D3 in sterling-preflight.md. */
|
|
410
|
+
type ContrastMode = /** Throw on WCAG AA failure on core role pairs. Used by catalog tests. */"strict" /** Auto-lift failing tokens via OKLCH L shifts. Used for user schemes. */ | "auto-lift";
|
|
411
|
+
/** Options accepted by all derivation entry points. */
|
|
412
|
+
interface DeriveOptions {
|
|
413
|
+
/** Default: `"auto-lift"`. */
|
|
414
|
+
readonly contrast?: ContrastMode;
|
|
415
|
+
/** If true, attach `derivationTrace` to the returned Theme. Default: false. */
|
|
416
|
+
readonly trace?: boolean;
|
|
417
|
+
/**
|
|
418
|
+
* Per-role token pins. A scheme author can pin specific tokens (e.g.
|
|
419
|
+
* `{ "error.fg": "#bf616a" }`) to skip auto-adjustment. The path syntax is
|
|
420
|
+
* nested-style: `"accent.hover.bg"`, `"error.fg"`. Flat-form pins are
|
|
421
|
+
* also accepted: `{ "bg-accent": "#...", "fg-on-error": "#..." }`.
|
|
422
|
+
*/
|
|
423
|
+
readonly pins?: Readonly<Record<string, string>>;
|
|
424
|
+
/**
|
|
425
|
+
* Force light/dark inference. By default inferred from
|
|
426
|
+
* `scheme.dark` or WCAG luminance of `scheme.background`.
|
|
427
|
+
*/
|
|
428
|
+
readonly mode?: "light" | "dark";
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* The `DesignSystem` contract. Sterling is the default implementation; other
|
|
432
|
+
* packages (e.g. `@silvery/design-material`) publish alternatives matching
|
|
433
|
+
* this shape.
|
|
434
|
+
*/
|
|
435
|
+
interface DesignSystem {
|
|
436
|
+
/** Display name for tooling (e.g. `"sterling"`). */
|
|
437
|
+
readonly name: string;
|
|
438
|
+
/** Metadata about this system's Theme shape. */
|
|
439
|
+
readonly shape: ThemeShape;
|
|
440
|
+
/**
|
|
441
|
+
* Whether the framework should auto-apply `bakeFlat` to each derivation's
|
|
442
|
+
* output — projecting hex leaves onto flat hyphen-keys on the same object.
|
|
443
|
+
*
|
|
444
|
+
* - `true` — use {@link defaultFlattenRule} (channel-role-state, Sterling style)
|
|
445
|
+
* - `FlattenRule` — system-specific rule (e.g. Material `onPrimary`)
|
|
446
|
+
* - `false` or omitted — no auto-flatten (system is responsible, or
|
|
447
|
+
* consumer only uses nested form)
|
|
448
|
+
*
|
|
449
|
+
* Sterling and anything modelled on it should set `flatten: true` —
|
|
450
|
+
* flat-projection-on-same-object is a universal feature of nested
|
|
451
|
+
* hex-leaf POJOs and Sterling users expect `theme["bg-accent"]` access.
|
|
452
|
+
*/
|
|
453
|
+
readonly flatten?: boolean | FlattenRule;
|
|
454
|
+
/** Return a raw default Theme, no input required. */
|
|
455
|
+
defaults(mode?: "light" | "dark"): Theme;
|
|
456
|
+
/**
|
|
457
|
+
* Fill partial theme values with defaults. Useful for hand-curated themes
|
|
458
|
+
* that override a few roles.
|
|
459
|
+
*/
|
|
460
|
+
theme(partial?: DeepPartial<Theme>, opts?: DeriveOptions): Theme;
|
|
461
|
+
/** Derive from a 22-color terminal scheme — Sterling's primary path. */
|
|
462
|
+
deriveFromScheme(scheme: ColorScheme, opts?: DeriveOptions): Theme;
|
|
463
|
+
/** Derive from a single seed color — Material-style. */
|
|
464
|
+
deriveFromColor(color: string, opts?: DeriveOptions & {
|
|
465
|
+
mode?: "light" | "dark";
|
|
466
|
+
}): Theme;
|
|
467
|
+
/** Derive from a light/dark scheme pair. */
|
|
468
|
+
deriveFromPair(light: ColorScheme, dark: ColorScheme, opts?: DeriveOptions): {
|
|
469
|
+
light: Theme;
|
|
470
|
+
dark: Theme;
|
|
471
|
+
};
|
|
472
|
+
/** Derive from a scheme plus a brand-color overlay (F — brand discipline). */
|
|
473
|
+
deriveFromSchemeWithBrand(scheme: ColorScheme, brand: string, opts?: DeriveOptions): Theme;
|
|
474
|
+
}
|
|
475
|
+
/** Utility: recursive `Partial` for nested Theme overrides. */
|
|
476
|
+
type DeepPartial<T> = T extends object ? T extends readonly unknown[] ? T : { [K in keyof T]?: DeepPartial<T[K]> } : T;
|
|
477
|
+
//#endregion
|
|
478
|
+
//#region packages/ansi/src/theme/types.d.ts
|
|
479
|
+
/**
|
|
480
|
+
* Core type definitions for the theme system.
|
|
481
|
+
*
|
|
482
|
+
* Two-layer architecture:
|
|
483
|
+
* Layer 1: ColorScheme — 22 terminal colors (what schemes expose; auto-detectable)
|
|
484
|
+
* Layer 2: Theme — ~33 semantic tokens (what UI apps consume)
|
|
485
|
+
*
|
|
486
|
+
* Pipeline: Scheme catalog → ColorScheme (22) → deriveTheme() → Theme (33)
|
|
487
|
+
*/
|
|
488
|
+
interface ColorScheme {
|
|
489
|
+
name?: string;
|
|
490
|
+
dark?: boolean;
|
|
491
|
+
primary?: string;
|
|
492
|
+
black: string;
|
|
493
|
+
red: string;
|
|
494
|
+
green: string;
|
|
495
|
+
yellow: string;
|
|
496
|
+
blue: string;
|
|
497
|
+
magenta: string;
|
|
498
|
+
cyan: string;
|
|
499
|
+
white: string;
|
|
500
|
+
brightBlack: string;
|
|
501
|
+
brightRed: string;
|
|
502
|
+
brightGreen: string;
|
|
503
|
+
brightYellow: string;
|
|
504
|
+
brightBlue: string;
|
|
505
|
+
brightMagenta: string;
|
|
506
|
+
brightCyan: string;
|
|
507
|
+
brightWhite: string;
|
|
508
|
+
foreground: string;
|
|
509
|
+
background: string;
|
|
510
|
+
cursorColor: string;
|
|
511
|
+
cursorText: string;
|
|
512
|
+
selectionBackground: string;
|
|
513
|
+
selectionForeground: string;
|
|
514
|
+
}
|
|
515
|
+
declare const COLOR_SCHEME_FIELDS: readonly ["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite", "foreground", "background", "cursorColor", "cursorText", "selectionBackground", "selectionForeground"];
|
|
516
|
+
/**
|
|
517
|
+
* Metadata describing how the active color scheme was determined.
|
|
518
|
+
*
|
|
519
|
+
* Returned by `detectScheme()` and surfaced at runtime via `useActiveScheme()`.
|
|
520
|
+
* Lets apps log how the theme was detected ("catppuccin-mocha at 87% confidence via
|
|
521
|
+
* fingerprint") or render a debug badge without re-running detection.
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```tsx
|
|
406
525
|
* const scheme = useActiveScheme()
|
|
407
526
|
* if (scheme?.source === "fingerprint") {
|
|
408
527
|
* console.log(`detected ${scheme.matchedName} at ${Math.round((scheme.confidence ?? 0) * 100)}%`)
|
|
@@ -421,94 +540,74 @@ interface ActiveScheme {
|
|
|
421
540
|
}
|
|
422
541
|
type AnsiPrimary = "yellow" | "cyan" | "magenta" | "green" | "red" | "blue" | "white";
|
|
423
542
|
type HueName = "red" | "orange" | "yellow" | "green" | "teal" | "blue" | "purple" | "pink";
|
|
424
|
-
/**
|
|
425
|
-
* A typography variant — a named bundle of visual properties that can be
|
|
426
|
-
* applied to a Text component via `variant="h1"`. The variant acts as a
|
|
427
|
-
* *default*: caller props always win over variant values.
|
|
428
|
-
*
|
|
429
|
-
* Color values follow the same syntax as `TextColor` — `$token` strings,
|
|
430
|
-
* hex values, ANSI names, or any string accepted by the color system.
|
|
431
|
-
*/
|
|
432
|
-
interface Variant$1 {
|
|
433
|
-
color?: string;
|
|
434
|
-
backgroundColor?: string;
|
|
435
|
-
bold?: boolean;
|
|
436
|
-
italic?: boolean;
|
|
437
|
-
dim?: boolean;
|
|
438
|
-
underlineStyle?: "single" | "double" | "curly" | "dotted" | "dashed";
|
|
439
|
-
}
|
|
440
543
|
//#endregion
|
|
441
|
-
//#region packages/ansi/src/theme/
|
|
442
|
-
interface
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
ratioBefore: number;
|
|
449
|
-
ratioAfter: number;
|
|
544
|
+
//#region packages/ansi/src/theme/detect.d.ts
|
|
545
|
+
interface DetectedScheme {
|
|
546
|
+
fg: string | null;
|
|
547
|
+
bg: string | null;
|
|
548
|
+
ansi: (string | null)[];
|
|
549
|
+
dark: boolean;
|
|
550
|
+
palette: Partial<ColorScheme>;
|
|
450
551
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
confidence: number;
|
|
467
|
-
/** Per-slot provenance. Keys are ColorScheme field names. */
|
|
468
|
-
slotSources: Partial<Record<keyof ColorScheme, SlotSource>>;
|
|
469
|
-
/** If fingerprint matched, the catalog scheme name. */
|
|
470
|
-
matchedName?: string;
|
|
552
|
+
/**
|
|
553
|
+
* Structural subset of `@silvery/ag-term/runtime` `InputOwner`. Defined
|
|
554
|
+
* locally so `@silvery/ansi` stays dependency-free — callers inside a silvery
|
|
555
|
+
* session can pass the real `InputOwner` and get nominal structural match;
|
|
556
|
+
* standalone callers who never heard of InputOwner are unaffected.
|
|
557
|
+
*/
|
|
558
|
+
interface ProbeInputOwner {
|
|
559
|
+
probe<T>(opts: {
|
|
560
|
+
query: string;
|
|
561
|
+
parse: (acc: string) => {
|
|
562
|
+
result: T;
|
|
563
|
+
consumed: number;
|
|
564
|
+
} | null;
|
|
565
|
+
timeoutMs: number;
|
|
566
|
+
}): Promise<T | null>;
|
|
471
567
|
}
|
|
472
|
-
interface
|
|
473
|
-
/**
|
|
474
|
-
override?: ColorScheme;
|
|
475
|
-
/** Catalog to fingerprint against. If empty or undefined, skip fingerprinting. */
|
|
476
|
-
catalog?: readonly ColorScheme[];
|
|
477
|
-
/** OSC probe timeout (ms). Default 150. */
|
|
568
|
+
interface ProbeColorsOptions {
|
|
569
|
+
/** Per-OSC-query timeout in ms. Default 150. */
|
|
478
570
|
timeoutMs?: number;
|
|
479
|
-
/** Force dark/light inference when no bg is probed. */
|
|
480
|
-
darkFallback?: boolean;
|
|
481
571
|
/**
|
|
482
|
-
*
|
|
483
|
-
*
|
|
572
|
+
* Optional InputOwner (from `@silvery/ag-term/runtime`) that owns the stdin
|
|
573
|
+
* raw-mode + data listener for the enclosing session. When provided,
|
|
574
|
+
* probeColors routes OSC queries through `input.probe()` instead of
|
|
575
|
+
* touching `process.stdin` directly. This avoids the wasRaw race that kills
|
|
576
|
+
* host-TUI input when probeColors runs concurrently with a TUI session.
|
|
577
|
+
*
|
|
578
|
+
* When absent (e.g. CLI tool, non-TUI caller), probeColors falls back to
|
|
579
|
+
* the standalone race-safe `didSetRaw + listenerCount > 0` guard on
|
|
580
|
+
* `process.stdin`. The standalone path stays tested and supported.
|
|
484
581
|
*/
|
|
485
|
-
|
|
486
|
-
/** Add WCAG contrast check to the invariant validation. Default `false`. */
|
|
487
|
-
wcag?: boolean;
|
|
582
|
+
input?: ProbeInputOwner;
|
|
488
583
|
}
|
|
489
|
-
//#endregion
|
|
490
|
-
//#region packages/ansi/src/theme/tokens.d.ts
|
|
491
584
|
/**
|
|
492
|
-
*
|
|
493
|
-
*
|
|
585
|
+
* Probe the terminal for its 22-slot color scheme via OSC 4/10/11 queries.
|
|
586
|
+
*
|
|
587
|
+
* Pure terminal primitive — no fingerprinting, no theme derivation. Returns the
|
|
588
|
+
* raw probed slots (or `null` if probing isn't available, e.g. non-TTY).
|
|
589
|
+
*
|
|
590
|
+
* For the full detection cascade (override → probe → fingerprint → fallback +
|
|
591
|
+
* theme derivation), use `detectScheme` from `@silvery/ansi` or
|
|
592
|
+
* `detectTheme` from `@silvery/theme`.
|
|
593
|
+
*
|
|
594
|
+
* `probeColors` is the canonical name; `detectTerminalScheme` is the legacy
|
|
595
|
+
* alias kept for backward compatibility.
|
|
596
|
+
*
|
|
597
|
+
* Call styles:
|
|
598
|
+
* await probeColors() // default timeout, standalone
|
|
599
|
+
* await probeColors(150) // legacy positional timeout
|
|
600
|
+
* await probeColors({ timeoutMs: 150 }) // options form
|
|
601
|
+
* await probeColors({ input: inputOwner, timeoutMs: 150 }) // routed through InputOwner
|
|
494
602
|
*/
|
|
495
|
-
|
|
603
|
+
declare function probeColors(timeoutOrOpts?: number | ProbeColorsOptions): Promise<DetectedScheme | null>;
|
|
496
604
|
/**
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
605
|
+
* Legacy alias for {@link probeColors}. Prefer `probeColors` in new code —
|
|
606
|
+
* the name says what it does (probes terminal color slots), and "detect" is
|
|
607
|
+
* reserved for the full cascade (`detectScheme`, `detectTheme`). Retained
|
|
608
|
+
* as a stable alias — no deprecation schedule.
|
|
500
609
|
*/
|
|
501
|
-
|
|
502
|
-
//#endregion
|
|
503
|
-
//#region packages/ansi/src/theme/detect.d.ts
|
|
504
|
-
interface DetectedScheme {
|
|
505
|
-
fg: string | null;
|
|
506
|
-
bg: string | null;
|
|
507
|
-
ansi: (string | null)[];
|
|
508
|
-
dark: boolean;
|
|
509
|
-
palette: Partial<ColorScheme>;
|
|
510
|
-
}
|
|
511
|
-
declare function detectTerminalScheme(timeoutMs?: number): Promise<DetectedScheme | null>;
|
|
610
|
+
declare const detectTerminalScheme: typeof probeColors;
|
|
512
611
|
interface DetectThemeOptions {
|
|
513
612
|
/** Fallback ColorScheme when detection fails or returns partial data.
|
|
514
613
|
* Detected colors override matching fallback fields.
|
|
@@ -523,870 +622,695 @@ interface DetectThemeOptions {
|
|
|
523
622
|
/** Timeout per OSC query in ms (default 150). */
|
|
524
623
|
timeoutMs?: number;
|
|
525
624
|
/** Terminal capabilities (from detectTerminalCaps). When provided:
|
|
526
|
-
* - colorLevel "
|
|
625
|
+
* - colorLevel `"mono"` / `"ansi16"` skips OSC detection and returns ANSI 16 theme
|
|
527
626
|
* - darkBackground informs fallback selection when detection fails */
|
|
528
627
|
caps?: {
|
|
529
628
|
colorLevel?: string;
|
|
530
629
|
darkBackground?: boolean;
|
|
531
630
|
};
|
|
631
|
+
/** Optional InputOwner — routes OSC queries through the session's stdin
|
|
632
|
+
* owner instead of directly mutating process.stdin raw mode. See
|
|
633
|
+
* {@link ProbeColorsOptions.input}. */
|
|
634
|
+
input?: ProbeInputOwner;
|
|
532
635
|
}
|
|
636
|
+
declare function detectTheme(opts?: DetectThemeOptions): Promise<Theme>;
|
|
533
637
|
//#endregion
|
|
534
|
-
//#region packages/ansi/src/
|
|
535
|
-
/**
|
|
536
|
-
* OSC 4 Terminal Color Palette Query/Set — pure ANSI protocol.
|
|
537
|
-
*/
|
|
538
|
-
declare function queryPaletteColor(index: number, write: (data: string) => void): void;
|
|
539
|
-
declare function queryMultiplePaletteColors(indices: number[], write: (data: string) => void): void;
|
|
540
|
-
declare function setPaletteColor(index: number, color: string, write: (data: string) => void): void;
|
|
541
|
-
declare function parsePaletteResponse(input: string): {
|
|
542
|
-
index: number;
|
|
543
|
-
color: string;
|
|
544
|
-
} | null;
|
|
545
|
-
//#endregion
|
|
546
|
-
//#region packages/ansi/src/osc-colors.d.ts
|
|
547
|
-
/**
|
|
548
|
-
* OSC 10/11/12 Terminal Color Queries — pure ANSI protocol.
|
|
549
|
-
*/
|
|
550
|
-
declare function queryForegroundColor(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
|
|
551
|
-
declare function queryBackgroundColor(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
|
|
552
|
-
declare function queryCursorColor(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
|
|
553
|
-
declare function setForegroundColor(write: (data: string) => void, color: string): void;
|
|
554
|
-
declare function setBackgroundColor(write: (data: string) => void, color: string): void;
|
|
555
|
-
declare function setCursorColor(write: (data: string) => void, color: string): void;
|
|
556
|
-
declare function resetForegroundColor(write: (data: string) => void): void;
|
|
557
|
-
declare function resetBackgroundColor(write: (data: string) => void): void;
|
|
558
|
-
declare function resetCursorColor(write: (data: string) => void): void;
|
|
559
|
-
declare function detectColorScheme(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<"light" | "dark" | null>;
|
|
560
|
-
//#endregion
|
|
561
|
-
//#region packages/ansi/src/theme/generate.d.ts
|
|
638
|
+
//#region packages/ansi/src/profile.d.ts
|
|
562
639
|
/**
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
640
|
+
* Which rung of the precedence chain resolved the profile's color tier.
|
|
641
|
+
*
|
|
642
|
+
* Scoped specifically to **color tier** — not whole-profile provenance. Other
|
|
643
|
+
* caps fields (unicode, kittyKeyboard, …) come from `detectTerminalProfileFromEnv`
|
|
644
|
+
* or a caller-supplied caps object; their provenance is not tracked here.
|
|
645
|
+
*
|
|
646
|
+
* - `"env"` — `NO_COLOR` or `FORCE_COLOR` env var won.
|
|
647
|
+
* - `"override"` — caller-supplied `colorLevel` won.
|
|
648
|
+
* - `"caller-caps"` — `options.caps.colorLevel` fallback won. Note this
|
|
649
|
+
* conflates "pre-detected real caps the Term committed to" with
|
|
650
|
+
* "synthetically forced caps from a test fixture / user config"; callers
|
|
651
|
+
* that need to tell those apart pass `colorLevel` explicitly instead.
|
|
652
|
+
* - `"auto"` — env-based auto-detection (TERM/COLORTERM/TERM_PROGRAM) won.
|
|
653
|
+
*
|
|
654
|
+
* Consumers that only need "was the tier forced?" should read
|
|
655
|
+
* {@link TerminalCaps.colorForced} instead of comparing against this enum.
|
|
656
|
+
* Phase 5 of `km-silvery.terminal-profile-plateau` (per /pro review 2026-04-23):
|
|
657
|
+
* the flat `source` field was retired because it read like whole-profile
|
|
658
|
+
* provenance but only described color tier.
|
|
566
659
|
*/
|
|
567
|
-
|
|
568
|
-
//#endregion
|
|
569
|
-
//#region packages/theme/src/generate.d.ts
|
|
660
|
+
type ColorProvenance = "env" | "override" | "caller-caps" | "auto";
|
|
570
661
|
/**
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
662
|
+
* A fully-resolved view of the current terminal.
|
|
663
|
+
*
|
|
664
|
+
* Bundled intentionally — callers shouldn't mix and match detection sources.
|
|
665
|
+
* `colorLevel` mirrors `caps.colorLevel`; it's exposed as a top-level field so
|
|
666
|
+
* callers that only need the tier (e.g. `createStyle({ level })`) don't have
|
|
667
|
+
* to reach into the caps object.
|
|
668
|
+
*
|
|
669
|
+
* **Immutability**: profiles are snapshot values — the whole plateau depends
|
|
670
|
+
* on `colorLevel === caps.colorLevel` never drifting. Every field is
|
|
671
|
+
* `readonly` at the type level, and `createTerminalProfile` freezes the
|
|
672
|
+
* returned object (and its nested `caps`) in dev builds so accidental
|
|
673
|
+
* mutation crashes loudly. Production builds skip the freeze to keep the
|
|
674
|
+
* allocation cheap; the type-level `readonly` already blocks TS writers.
|
|
675
|
+
*
|
|
676
|
+
* Post km-silvery.plateau-naming-polish (2026-04-23): 2-layer shape — `emulator`
|
|
677
|
+
* (what terminal IS this) and `caps` (what can it do, including `maybe*`
|
|
678
|
+
* heuristics). The original Phase 7 3-layer shape collapsed because the
|
|
679
|
+
* 3-field heuristics namespace was pulling its weight.
|
|
680
|
+
*
|
|
681
|
+
* @see createTerminalProfile
|
|
576
682
|
*/
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
|
|
683
|
+
interface TerminalProfile {
|
|
684
|
+
/** Environment identity — what terminal IS this (program, version, TERM). */
|
|
685
|
+
readonly emulator: TerminalEmulator;
|
|
686
|
+
/** Protocol-capability flags + low-confidence `maybe*` heuristics. Also
|
|
687
|
+
* carries `colorLevel` / `colorForced` / `colorProvenance`. */
|
|
688
|
+
readonly caps: TerminalCaps;
|
|
689
|
+
/** Convenience alias for `caps.colorLevel`. Exposed as a top-level field
|
|
690
|
+
* because callers that only need the tier (e.g. `createStyle({ level })`)
|
|
691
|
+
* shouldn't have to reach into the caps object. */
|
|
692
|
+
readonly colorLevel: ColorLevel;
|
|
693
|
+
/**
|
|
694
|
+
* OSC-detected terminal theme, populated only when the profile was built via
|
|
695
|
+
* {@link probeTerminalProfile}. Pre-quantized to {@link colorLevel} when the
|
|
696
|
+
* tier was {@link TerminalCaps.colorForced} so token hex values match what
|
|
697
|
+
* the pipeline will actually emit.
|
|
698
|
+
*
|
|
699
|
+
* Absent on sync {@link createTerminalProfile} — theme detection is an async
|
|
700
|
+
* OSC probe and can't run inside a sync call. Entry points that need a
|
|
701
|
+
* theme (run, createApp) should use `probeTerminalProfile` instead.
|
|
702
|
+
*
|
|
703
|
+
* Post km-silvery.plateau-profile-theme (H2 of the /big review 2026-04-23).
|
|
704
|
+
*/
|
|
705
|
+
readonly theme?: Theme;
|
|
706
|
+
}
|
|
582
707
|
/**
|
|
583
|
-
*
|
|
708
|
+
* Minimal stdout shape needed for detection.
|
|
584
709
|
*
|
|
585
|
-
*
|
|
710
|
+
* Using a structural type (not `NodeJS.WriteStream`) keeps `@silvery/ansi`
|
|
711
|
+
* browser-safe — the canvas/DOM backends can pass `{ isTTY: false }` without
|
|
712
|
+
* pulling in Node's tty types.
|
|
586
713
|
*/
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
/** Foreground/text color. Generated if omitted. */
|
|
592
|
-
foreground?: string;
|
|
593
|
-
/** Primary accent color. Generated if omitted. */
|
|
594
|
-
primary?: string;
|
|
595
|
-
/** Force dark mode. */
|
|
596
|
-
dark?: boolean;
|
|
597
|
-
/** Theme name. */
|
|
598
|
-
name?: string;
|
|
714
|
+
interface TerminalProfileStdout {
|
|
715
|
+
isTTY?: boolean;
|
|
716
|
+
columns?: number;
|
|
717
|
+
rows?: number;
|
|
599
718
|
}
|
|
600
719
|
/**
|
|
601
|
-
*
|
|
720
|
+
* Minimal stdin shape needed for input capability detection.
|
|
602
721
|
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
722
|
+
* Structural like {@link TerminalProfileStdout} — browser/canvas backends
|
|
723
|
+
* that have no stdin pass `undefined` and `caps.input` resolves to `false`
|
|
724
|
+
* via the default. Absorbed from the retired `detectInput(stdin)` helper
|
|
725
|
+
* in unicode-plateau Phase 4.
|
|
605
726
|
*/
|
|
606
|
-
|
|
727
|
+
interface TerminalProfileStdin {
|
|
728
|
+
isTTY?: boolean;
|
|
729
|
+
setRawMode?: (mode: boolean) => unknown;
|
|
730
|
+
}
|
|
607
731
|
/**
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
* @returns The ColorScheme, or undefined if not found.
|
|
732
|
+
* Options for {@link createTerminalProfile}.
|
|
611
733
|
*/
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
734
|
+
interface CreateTerminalProfileOptions {
|
|
735
|
+
/** Environment (default: `process.env`). */
|
|
736
|
+
env?: Record<string, string | undefined>;
|
|
737
|
+
/** Output stream (default: `process.stdout`). */
|
|
738
|
+
stdout?: TerminalProfileStdout;
|
|
739
|
+
/**
|
|
740
|
+
* Input stream (default: `process.stdin`). Used to derive `caps.input` —
|
|
741
|
+
* whether the host can read raw keystrokes. Pass `undefined` explicitly
|
|
742
|
+
* (or omit on non-Node targets) to force `caps.input = false`.
|
|
743
|
+
*/
|
|
744
|
+
stdin?: TerminalProfileStdin;
|
|
745
|
+
/**
|
|
746
|
+
* Explicit color tier override. Wins over `caps.colorLevel` but NOT over
|
|
747
|
+
* NO_COLOR / FORCE_COLOR env vars. `null` is accepted as an alias for
|
|
748
|
+
* `"mono"` (pre-plateau no-color spelling).
|
|
749
|
+
*/
|
|
750
|
+
colorLevel?: ColorLevel | null;
|
|
751
|
+
/**
|
|
752
|
+
* Base capabilities. When provided, skips the env-based caps detection —
|
|
753
|
+
* the profile uses these as the starting point. `caps.colorLevel` acts as
|
|
754
|
+
* the fallback tier (used only if env+override both decline to set one).
|
|
755
|
+
*
|
|
756
|
+
* Typical uses:
|
|
757
|
+
* - Term constructors already computed full caps → pass them here to avoid
|
|
758
|
+
* a redundant detection pass.
|
|
759
|
+
* - Tests want a known-good caps fixture → pass a fully-populated object.
|
|
760
|
+
*/
|
|
761
|
+
caps?: Partial<TerminalCaps>;
|
|
762
|
+
/**
|
|
763
|
+
* Base emulator identity. When provided, skips identity detection and uses
|
|
764
|
+
* these values. Typical use: Term constructors that already resolved
|
|
765
|
+
* TERM_PROGRAM from their stdin/stdout context.
|
|
766
|
+
*/
|
|
767
|
+
emulator?: Partial<TerminalEmulator>;
|
|
636
768
|
}
|
|
637
|
-
/** Create a chainable theme builder. */
|
|
638
|
-
declare function createTheme(): ThemeBuilder;
|
|
639
769
|
/**
|
|
640
|
-
*
|
|
770
|
+
* Build a {@link TerminalProfile} from the current environment.
|
|
641
771
|
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
|
|
648
|
-
declare function quickTheme(primaryOrHex: string, mode?: "dark" | "light"): Theme$1;
|
|
649
|
-
/**
|
|
650
|
-
* Create a theme from a built-in preset name.
|
|
772
|
+
* Priority for the final `colorLevel` (highest wins):
|
|
773
|
+
* 1. `NO_COLOR` env var → `"mono"`
|
|
774
|
+
* 2. `FORCE_COLOR` env var → `0/false → mono, 1 → ansi16, 2 → 256, 3 → truecolor`
|
|
775
|
+
* 3. `options.colorLevel` (caller-supplied explicit tier)
|
|
776
|
+
* 4. `options.caps.colorLevel` (base caps' pre-detected tier)
|
|
777
|
+
* 5. Auto-detected tier from env (TERM, COLORTERM, TERM_PROGRAM, …)
|
|
651
778
|
*
|
|
652
|
-
*
|
|
653
|
-
*
|
|
654
|
-
*
|
|
655
|
-
* presetTheme('nord')
|
|
656
|
-
* ```
|
|
657
|
-
*/
|
|
658
|
-
declare function presetTheme(name: string): Theme$1;
|
|
659
|
-
//#endregion
|
|
660
|
-
//#region packages/theme/src/auto-generate.d.ts
|
|
661
|
-
/**
|
|
662
|
-
* Generate a complete Theme from a single primary color.
|
|
779
|
+
* The env-var precedence (1 & 2) matches the existing `detectColor()` semantics
|
|
780
|
+
* and is observed on every silvery entry point — tests pass with explicit
|
|
781
|
+
* env vars even when a caller forces a tier via `colorLevel`.
|
|
663
782
|
*
|
|
664
|
-
*
|
|
665
|
-
* -
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
* - Status colors (error, warning, success, info) from standard hue positions
|
|
783
|
+
* When `options.caps` is provided, the profile treats those as the base
|
|
784
|
+
* capabilities and skips the env-based caps detection — only the color tier
|
|
785
|
+
* is resolved through the precedence chain above. When `options.caps` is
|
|
786
|
+
* absent, the full `detectTerminalProfileFromEnv` pass runs.
|
|
669
787
|
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
* @returns A complete Theme with all 33 semantic tokens
|
|
788
|
+
* No I/O beyond whatever `detectTerminalCaps()` already does (a `defaults read`
|
|
789
|
+
* call on macOS for Apple Terminal dark-mode heuristics — cached).
|
|
673
790
|
*
|
|
674
791
|
* @example
|
|
675
|
-
* ```
|
|
676
|
-
*
|
|
677
|
-
*
|
|
678
|
-
*
|
|
679
|
-
* const light = autoGenerateTheme("#E06C75", "light")
|
|
680
|
-
* // Generates a full light theme with red/rose as the primary accent
|
|
681
|
-
* ```
|
|
682
|
-
*/
|
|
683
|
-
declare function autoGenerateTheme(primaryColor: string, mode: "dark" | "light"): Theme$1;
|
|
684
|
-
//#endregion
|
|
685
|
-
//#region packages/theme/src/validate.d.ts
|
|
686
|
-
/** Validation result from validateColorScheme(). */
|
|
687
|
-
interface ValidationResult {
|
|
688
|
-
valid: boolean;
|
|
689
|
-
errors: string[];
|
|
690
|
-
warnings: string[];
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Validate a ColorScheme.
|
|
694
|
-
*
|
|
695
|
-
* Checks:
|
|
696
|
-
* - All 22 color fields are present and non-empty hex strings
|
|
697
|
-
* - Warns on low-contrast foreground/background combinations
|
|
698
|
-
*/
|
|
699
|
-
declare function validateColorScheme(p: ColorScheme): ValidationResult;
|
|
700
|
-
//#endregion
|
|
701
|
-
//#region packages/theme/src/validate-theme.d.ts
|
|
702
|
-
/**
|
|
703
|
-
* Theme validation — checks that all required semantic tokens are present.
|
|
792
|
+
* ```ts
|
|
793
|
+
* // Auto-detect from process.env + process.stdout
|
|
794
|
+
* const profile = createTerminalProfile()
|
|
795
|
+
* console.log(profile.colorLevel) // "truecolor" on Ghostty
|
|
704
796
|
*
|
|
705
|
-
*
|
|
706
|
-
*
|
|
707
|
-
*/
|
|
708
|
-
/** All 33 required semantic token keys on Theme (excludes `name` and `palette`). */
|
|
709
|
-
declare const THEME_TOKEN_KEYS: readonly string[];
|
|
710
|
-
/** Result of theme validation. */
|
|
711
|
-
interface ThemeValidationResult {
|
|
712
|
-
/** Whether the theme has all required tokens. */
|
|
713
|
-
valid: boolean;
|
|
714
|
-
/** Token keys that are required but missing or empty. */
|
|
715
|
-
missing: string[];
|
|
716
|
-
/** Token keys that exist on the object but are not recognized theme tokens. */
|
|
717
|
-
extra: string[];
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Validate a Theme object — check that all required tokens are present.
|
|
797
|
+
* // Force a tier (still honors NO_COLOR / FORCE_COLOR env precedence)
|
|
798
|
+
* const forced = createTerminalProfile({ colorLevel: "256" })
|
|
721
799
|
*
|
|
722
|
-
*
|
|
723
|
-
*
|
|
800
|
+
* // Term path — base caps already detected, just resolve color tier.
|
|
801
|
+
* const termProfile = createTerminalProfile({
|
|
802
|
+
* colorLevel: userColorLevel,
|
|
803
|
+
* caps: term.caps,
|
|
804
|
+
* })
|
|
724
805
|
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
* }
|
|
806
|
+
* // Headless/test fixture — zero env influence
|
|
807
|
+
* const fake = createTerminalProfile({
|
|
808
|
+
* env: {},
|
|
809
|
+
* stdout: { isTTY: true },
|
|
810
|
+
* colorLevel: "truecolor",
|
|
811
|
+
* })
|
|
731
812
|
* ```
|
|
732
813
|
*/
|
|
733
|
-
declare function
|
|
734
|
-
//#endregion
|
|
735
|
-
//#region packages/theme/src/alias.d.ts
|
|
814
|
+
declare function createTerminalProfile(options?: CreateTerminalProfileOptions): TerminalProfile;
|
|
736
815
|
/**
|
|
737
|
-
*
|
|
738
|
-
*
|
|
739
|
-
* Token values that start with `$` are treated as references to other tokens.
|
|
740
|
-
* Alias chains are followed until a concrete (non-$) value is reached.
|
|
741
|
-
* Circular references are detected via a depth limit and left unresolved.
|
|
742
|
-
*
|
|
743
|
-
* @param theme - A theme-like object where values may reference other tokens via `$name`
|
|
744
|
-
* @returns A new object with all aliases resolved to concrete values
|
|
745
|
-
*
|
|
746
|
-
* @example
|
|
747
|
-
* ```typescript
|
|
748
|
-
* const themed = resolveAliases({
|
|
749
|
-
* ...baseTheme,
|
|
750
|
-
* button: "$primary", // resolves to the value of 'primary'
|
|
751
|
-
* buttonHover: "$button", // chain: buttonHover -> button -> primary -> hex
|
|
752
|
-
* })
|
|
753
|
-
* ```
|
|
816
|
+
* Options for {@link probeTerminalProfile}. Extends the sync factory options
|
|
817
|
+
* with the async-only fields a theme probe needs.
|
|
754
818
|
*/
|
|
755
|
-
|
|
819
|
+
interface ProbeTerminalProfileOptions extends CreateTerminalProfileOptions {
|
|
820
|
+
/**
|
|
821
|
+
* Probe the terminal's theme via OSC 10/11/4 and bundle the result as
|
|
822
|
+
* `profile.theme`. Default `true` — the whole point of using the async
|
|
823
|
+
* variant is to get the theme alongside caps. Set `false` to skip the
|
|
824
|
+
* probe (no OSC writes) while still resolving a {@link TerminalProfile}
|
|
825
|
+
* identical to the sync path.
|
|
826
|
+
*/
|
|
827
|
+
probeTheme?: boolean;
|
|
828
|
+
/**
|
|
829
|
+
* Fallback scheme when the OSC probe returns partial / no data. Matches
|
|
830
|
+
* {@link DetectThemeOptions.fallbackDark}.
|
|
831
|
+
*/
|
|
832
|
+
fallbackDark?: DetectThemeOptions["fallbackDark"];
|
|
833
|
+
/** Fallback for light terminals (overrides `fallbackDark`). */
|
|
834
|
+
fallbackLight?: DetectThemeOptions["fallbackLight"];
|
|
835
|
+
/** Per-OSC-query timeout in ms (default 150 — matches `detectTheme`). */
|
|
836
|
+
timeoutMs?: number;
|
|
837
|
+
/**
|
|
838
|
+
* Optional {@link ProbeInputOwner} (the structural type `detectTheme`
|
|
839
|
+
* accepts). When provided, the probe routes OSC queries through the
|
|
840
|
+
* owner's `probe()` method instead of touching `process.stdin` directly —
|
|
841
|
+
* required inside a running TUI session. Callers in `@silvery/ag-term`
|
|
842
|
+
* construct a transient `InputOwner` around this call; standalone callers
|
|
843
|
+
* can omit it.
|
|
844
|
+
*/
|
|
845
|
+
input?: ProbeInputOwner;
|
|
846
|
+
}
|
|
756
847
|
/**
|
|
757
|
-
*
|
|
848
|
+
* Build a {@link TerminalProfile} with an OSC-detected `theme` bundled in.
|
|
758
849
|
*
|
|
759
|
-
*
|
|
850
|
+
* Async because the theme probe writes OSC queries to stdout and waits for
|
|
851
|
+
* responses on stdin. This is the Phase-H2 variant of
|
|
852
|
+
* {@link createTerminalProfile} — everything the sync factory does, plus:
|
|
760
853
|
*
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
* @
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
//#region packages/theme/src/css.d.ts
|
|
768
|
-
/**
|
|
769
|
-
* Convert a Theme to CSS custom properties.
|
|
854
|
+
* 1. Run `detectTheme` (OSC 4/10/11 probe with fallback) once.
|
|
855
|
+
* 2. Pre-quantize the resulting theme via {@link pickColorLevel} when the
|
|
856
|
+
* tier was forced ({@link TerminalCaps.colorForced} is `true`) so
|
|
857
|
+
* token hex values match what the pipeline will actually emit.
|
|
858
|
+
* 3. Return the profile with `theme` populated — one detection, one profile
|
|
859
|
+
* flowing end-to-end through run() / createApp().
|
|
770
860
|
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
*
|
|
861
|
+
* Call sites previously ran `createTerminalProfile(...)` + `detectTheme(...)`
|
|
862
|
+
* + `pickColorLevel(...)` as three separate steps on both the Term-path and
|
|
863
|
+
* options-path branches. Collapsing that into one function removes the
|
|
864
|
+
* duplication and the possibility of the three views disagreeing about
|
|
865
|
+
* what was forced.
|
|
776
866
|
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
867
|
+
* When `probeTheme` is `false`, behaves like the sync {@link createTerminalProfile}
|
|
868
|
+
* but wrapped in a Promise — useful for call sites that want uniform async
|
|
869
|
+
* treatment regardless of whether a probe is needed.
|
|
779
870
|
*
|
|
780
871
|
* @example
|
|
781
|
-
* ```
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
*
|
|
785
|
-
*
|
|
786
|
-
*
|
|
872
|
+
* ```ts
|
|
873
|
+
* // Node entry point with TUI-safe probing.
|
|
874
|
+
* const profile = await probeTerminalProfile({
|
|
875
|
+
* colorLevel: options.colorLevel,
|
|
876
|
+
* caps: term.profile.caps,
|
|
877
|
+
* fallbackDark: nord,
|
|
878
|
+
* fallbackLight: catppuccinLatte,
|
|
879
|
+
* input: probeOwner, // structural InputOwner from @silvery/ag-term
|
|
880
|
+
* })
|
|
881
|
+
* // profile.caps, profile.colorLevel, profile.caps.colorForced, profile.theme
|
|
787
882
|
* ```
|
|
883
|
+
*
|
|
884
|
+
* @see createTerminalProfile — sync variant, no theme probe
|
|
885
|
+
* @see DetectThemeOptions — the underlying probe options this wraps
|
|
788
886
|
*/
|
|
789
|
-
declare function
|
|
887
|
+
declare function probeTerminalProfile(options?: ProbeTerminalProfileOptions): Promise<TerminalProfile>;
|
|
790
888
|
//#endregion
|
|
791
|
-
//#region packages/
|
|
889
|
+
//#region packages/ansi/src/caps.d.ts
|
|
792
890
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
891
|
+
* Pure protocol capability flags plus low-confidence environment heuristics —
|
|
892
|
+
* what the terminal *can* do at the wire level, plus what the system guesses
|
|
893
|
+
* about theme/font/emoji rendering. Used by renderers / measurer for
|
|
894
|
+
* pre-flight branching.
|
|
895
|
+
*
|
|
896
|
+
* Post km-silvery.plateau-naming-polish (2026-04-23):
|
|
897
|
+
* - `TerminalHeuristics` was absorbed into this type. Guesses live alongside
|
|
898
|
+
* hard facts but carry a `maybe` prefix so the uncertainty is loud at every
|
|
899
|
+
* read site (`caps.maybeDarkBackground` vs `caps.cursor`).
|
|
900
|
+
*
|
|
901
|
+
* Post km-silvery.caps-restructure (Phase 7, 2026-04-23): the original flat
|
|
902
|
+
* 22-field shape was split into {@link TerminalCaps} (this type) and
|
|
903
|
+
* {@link TerminalEmulator} (environment identity — program/version/TERM).
|
|
904
|
+
* Both live on `profile.{caps,emulator}`.
|
|
905
|
+
*
|
|
906
|
+
* Renames from the old flat shape:
|
|
907
|
+
* - `textSizingSupported` → `textSizing` (drops the verbose suffix)
|
|
908
|
+
* - `underlineStyles: boolean` → `underlineStyles: readonly UnderlineStyle[]`
|
|
909
|
+
* so a terminal that supports curly but not dotted can report that precisely
|
|
910
|
+
* - `colorForced` + `colorProvenance` moved INTO caps (they describe color
|
|
911
|
+
* resolution, which is caps-adjacent)
|
|
912
|
+
*
|
|
913
|
+
* Phase 7 briefly renamed `colorLevel` → `colorTier` on caps, then reverted
|
|
914
|
+
* in plateau-naming-polish (2026-04-23) because `level` was already the
|
|
915
|
+
* canonical vocabulary across the stack (Style.level, createStyle({ level }),
|
|
916
|
+
* pickColorLevel, Pipeline.ColorLevel, run({ colorLevel })). Alignment won.
|
|
796
917
|
*/
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
918
|
+
interface TerminalCaps {
|
|
919
|
+
/** Can the host reposition the cursor? True when the output stream is a
|
|
920
|
+
* TTY and `TERM` is not `"dumb"`. Absorbed from the standalone
|
|
921
|
+
* `detectCursor()` helper in unicode-plateau Phase 3. */
|
|
922
|
+
readonly cursor: boolean;
|
|
923
|
+
/** Can the host read raw keystrokes? True when the input stream is a TTY
|
|
924
|
+
* and supports `setRawMode`. Absorbed from the standalone
|
|
925
|
+
* `detectInput()` helper in unicode-plateau Phase 4. */
|
|
926
|
+
readonly input: boolean;
|
|
927
|
+
/** Color support level. See {@link ColorLevel}. */
|
|
928
|
+
readonly colorLevel: ColorLevel;
|
|
929
|
+
/**
|
|
930
|
+
* Was the color tier forced by env vars (NO_COLOR / FORCE_COLOR) or a
|
|
931
|
+
* caller-supplied `colorLevel`? Equivalent to
|
|
932
|
+
* `colorProvenance === "env" || colorProvenance === "override"` — exposed
|
|
933
|
+
* as a precomputed boolean because that's the question every pre-quantize
|
|
934
|
+
* gate in run.tsx / create-app.tsx actually asks.
|
|
935
|
+
*
|
|
936
|
+
* Moved from {@link ./profile#TerminalProfile} into caps in Phase 7 — it
|
|
937
|
+
* describes *color* resolution, which is caps-adjacent, so grouping it here
|
|
938
|
+
* means all color-tier metadata travels as one unit.
|
|
939
|
+
*/
|
|
940
|
+
readonly colorForced: boolean;
|
|
941
|
+
/**
|
|
942
|
+
* Which rung of the precedence chain resolved {@link colorLevel}. Use
|
|
943
|
+
* {@link colorForced} for the common "was the tier forced?" check; use this
|
|
944
|
+
* enum only when the specific rung matters (e.g. diagnostics, theme
|
|
945
|
+
* detection, debug output).
|
|
946
|
+
*/
|
|
947
|
+
readonly colorProvenance: ColorProvenance;
|
|
948
|
+
/** Unicode/emoji support */
|
|
949
|
+
readonly unicode: boolean;
|
|
950
|
+
/**
|
|
951
|
+
* Extended SGR 4:x underline styles this terminal advertises. Empty array
|
|
952
|
+
* means "only the standard SGR 4 single underline is known to work" and
|
|
953
|
+
* consumers should fall back accordingly.
|
|
954
|
+
*
|
|
955
|
+
* Phase 7 upgrade: was a single `boolean` (all-or-nothing). With the array
|
|
956
|
+
* a terminal that supports curly but not dotted can report that precisely;
|
|
957
|
+
* style.ts now checks `caps.underlineStyles.includes("curly")` per style.
|
|
958
|
+
*/
|
|
959
|
+
readonly underlineStyles: readonly UnderlineStyle[];
|
|
960
|
+
/** SGR 58 underline color */
|
|
961
|
+
readonly underlineColor: boolean;
|
|
962
|
+
/**
|
|
963
|
+
* SGR 53/55 overline support. SGR 53 draws a line ABOVE the character cell,
|
|
964
|
+
* complementing the underline (SGR 4) below. Most modern terminals support
|
|
965
|
+
* it (Ghostty, iTerm2, xterm with extended attrs); the output phase skips
|
|
966
|
+
* emit when this is false so older terminals don't render the literal
|
|
967
|
+
* escape as text. See {@link BoxProps#overline} for the UI-facing prop.
|
|
968
|
+
*/
|
|
969
|
+
readonly overline: boolean;
|
|
970
|
+
/** OSC 66 text sizing protocol likely supported (Kitty 0.40+, Ghostty).
|
|
971
|
+
* Phase 7 rename: dropped the verbose `Supported` suffix. */
|
|
972
|
+
readonly textSizing: boolean;
|
|
973
|
+
/** Kitty keyboard protocol supported */
|
|
974
|
+
readonly kittyKeyboard: boolean;
|
|
975
|
+
/** Bracketed paste mode */
|
|
976
|
+
readonly bracketedPaste: boolean;
|
|
977
|
+
/** SGR mouse tracking */
|
|
978
|
+
readonly mouse: boolean;
|
|
979
|
+
/** Kitty graphics protocol (inline images) */
|
|
980
|
+
readonly kittyGraphics: boolean;
|
|
981
|
+
/** Sixel graphics supported */
|
|
982
|
+
readonly sixel: boolean;
|
|
983
|
+
/** OSC 52 clipboard */
|
|
984
|
+
readonly osc52: boolean;
|
|
985
|
+
/** OSC 8 hyperlinks */
|
|
986
|
+
readonly hyperlinks: boolean;
|
|
987
|
+
/** OSC 9/99 notifications */
|
|
988
|
+
readonly notifications: boolean;
|
|
989
|
+
/** Synchronized output (DEC 2026) */
|
|
990
|
+
readonly syncOutput: boolean;
|
|
991
|
+
/** Heuristic: likely dark background (for theme selection). Use
|
|
992
|
+
* {@link probeTerminalProfile} with OSC 11 to resolve definitively. */
|
|
993
|
+
readonly maybeDarkBackground: boolean;
|
|
994
|
+
/** Heuristic: likely has Nerd Font installed (for icon selection).
|
|
995
|
+
* Sniffed from TERM / LC_TERMINAL / known-modern terminal programs. */
|
|
996
|
+
readonly maybeNerdFont: boolean;
|
|
997
|
+
/** Heuristic: text-presentation emoji (`⚠` `☑` `⭐` — `Extended_Pictographic`
|
|
998
|
+
* without default `Emoji_Presentation`) rendered as 2 cells. Modern terminals
|
|
999
|
+
* (Ghostty, iTerm, Kitty) render these at emoji width (2 cells); Terminal.app
|
|
1000
|
+
* renders them at text width (1 cell). Affects measurer + layout. */
|
|
1001
|
+
readonly maybeWideEmojis: boolean;
|
|
817
1002
|
}
|
|
818
|
-
//#endregion
|
|
819
|
-
//#region packages/theme/src/import/base16.d.ts
|
|
820
1003
|
/**
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
825
|
-
* base03 → white (muted fg), base05 → foreground/brightWhite,
|
|
826
|
-
* base08 → red, base09 → brightRed, base0A → yellow,
|
|
827
|
-
* base0B → green, base0C → cyan, base0D → blue, base0E → magenta,
|
|
828
|
-
* base0F → brightMagenta.
|
|
829
|
-
*
|
|
830
|
-
* Bright color variants are derived by brightening normals.
|
|
831
|
-
* `dark` is inferred from base00 luminance.
|
|
1004
|
+
* Default capabilities — modern-terminal-ish defaults for headless / emulator /
|
|
1005
|
+
* unknown contexts. Heuristic fields (`maybe*`) bake in "probably dark, no
|
|
1006
|
+
* nerd font, wide emojis like Ghostty/iTerm" — callers override via
|
|
1007
|
+
* `createTerminalProfile({caps})`.
|
|
832
1008
|
*/
|
|
833
|
-
declare function
|
|
1009
|
+
declare function defaultCaps(): TerminalCaps;
|
|
834
1010
|
//#endregion
|
|
835
|
-
//#region packages/
|
|
1011
|
+
//#region packages/ansi/src/types.d.ts
|
|
836
1012
|
/**
|
|
837
|
-
*
|
|
838
|
-
*
|
|
839
|
-
* Mapping:
|
|
840
|
-
* background → base00, brightBlack → base01, selectionBackground → base02,
|
|
841
|
-
* white → base03, (interpolated) → base04, foreground → base05,
|
|
842
|
-
* (interpolated) → base06, (interpolated) → base07,
|
|
843
|
-
* red → base08, brightRed → base09, yellow → base0A, green → base0B,
|
|
844
|
-
* cyan → base0C, blue → base0D, magenta → base0E, brightMagenta → base0F.
|
|
1013
|
+
* Type definitions for @silvery/ansi
|
|
845
1014
|
*/
|
|
846
|
-
declare function exportBase16(palette: ColorScheme): string;
|
|
847
|
-
//#endregion
|
|
848
|
-
//#region packages/theme/src/schemes/catppuccin.d.ts
|
|
849
|
-
/** Catppuccin Mocha — the classic dark variant. */
|
|
850
|
-
declare const catppuccinMocha: ColorScheme;
|
|
851
|
-
/** Catppuccin Frappe — muted dark variant. */
|
|
852
|
-
declare const catppuccinFrappe: ColorScheme;
|
|
853
|
-
/** Catppuccin Macchiato — warm dark variant. */
|
|
854
|
-
declare const catppuccinMacchiato: ColorScheme;
|
|
855
|
-
/** Catppuccin Latte — the light variant. */
|
|
856
|
-
declare const catppuccinLatte: ColorScheme;
|
|
857
|
-
//#endregion
|
|
858
|
-
//#region packages/theme/src/schemes/nord.d.ts
|
|
859
|
-
/** Nord — the classic dark arctic theme. */
|
|
860
|
-
declare const nord: ColorScheme;
|
|
861
|
-
//#endregion
|
|
862
|
-
//#region packages/theme/src/schemes/dracula.d.ts
|
|
863
|
-
/** Dracula — vibrant dark theme. */
|
|
864
|
-
declare const dracula: ColorScheme;
|
|
865
|
-
//#endregion
|
|
866
|
-
//#region packages/theme/src/schemes/solarized.d.ts
|
|
867
|
-
/** Solarized Dark — Ethan Schoonover's classic dark variant. */
|
|
868
|
-
declare const solarizedDark: ColorScheme;
|
|
869
|
-
/** Solarized Light — Ethan Schoonover's classic light variant. */
|
|
870
|
-
declare const solarizedLight: ColorScheme;
|
|
871
|
-
//#endregion
|
|
872
|
-
//#region packages/theme/src/schemes/tokyo-night.d.ts
|
|
873
|
-
/** Tokyo Night — the default dark variant. */
|
|
874
|
-
declare const tokyoNight: ColorScheme;
|
|
875
|
-
/** Tokyo Night Storm — slightly lighter background. */
|
|
876
|
-
declare const tokyoNightStorm: ColorScheme;
|
|
877
|
-
/** Tokyo Night Day — the light variant. */
|
|
878
|
-
declare const tokyoNightDay: ColorScheme;
|
|
879
|
-
//#endregion
|
|
880
|
-
//#region packages/theme/src/schemes/one-dark.d.ts
|
|
881
|
-
/** One Dark — the classic Atom editor theme. */
|
|
882
|
-
declare const oneDark: ColorScheme;
|
|
883
|
-
//#endregion
|
|
884
|
-
//#region packages/theme/src/schemes/gruvbox.d.ts
|
|
885
|
-
/** Gruvbox Dark — warm retro dark theme. */
|
|
886
|
-
declare const gruvboxDark: ColorScheme;
|
|
887
|
-
/** Gruvbox Light — warm retro light theme. */
|
|
888
|
-
declare const gruvboxLight: ColorScheme;
|
|
889
|
-
//#endregion
|
|
890
|
-
//#region packages/theme/src/schemes/rose-pine.d.ts
|
|
891
|
-
/** Rosé Pine — the main dark variant. */
|
|
892
|
-
declare const rosePine: ColorScheme;
|
|
893
|
-
/** Rosé Pine Moon — slightly lighter dark variant. */
|
|
894
|
-
declare const rosePineMoon: ColorScheme;
|
|
895
|
-
/** Rosé Pine Dawn — the light variant. */
|
|
896
|
-
declare const rosePineDawn: ColorScheme;
|
|
897
|
-
//#endregion
|
|
898
|
-
//#region packages/theme/src/schemes/kanagawa.d.ts
|
|
899
|
-
/** Kanagawa Wave — the default dark variant, inspired by "The Great Wave off Kanagawa". */
|
|
900
|
-
declare const kanagawaWave: ColorScheme;
|
|
901
|
-
/** Kanagawa Dragon — a muted, earthy dark variant. */
|
|
902
|
-
declare const kanagawaDragon: ColorScheme;
|
|
903
|
-
/** Kanagawa Lotus — the light variant, inspired by lotus flowers. */
|
|
904
|
-
declare const kanagawaLotus: ColorScheme;
|
|
905
|
-
//#endregion
|
|
906
|
-
//#region packages/theme/src/schemes/everforest.d.ts
|
|
907
|
-
/** Everforest Dark — warm green-based dark theme (medium background). */
|
|
908
|
-
declare const everforestDark: ColorScheme;
|
|
909
|
-
/** Everforest Light — warm green-based light theme (medium background). */
|
|
910
|
-
declare const everforestLight: ColorScheme;
|
|
911
|
-
//#endregion
|
|
912
|
-
//#region packages/theme/src/schemes/monokai.d.ts
|
|
913
|
-
/** Monokai Classic — the original Sublime Text Monokai colors. */
|
|
914
|
-
declare const monokai: ColorScheme;
|
|
915
|
-
/** Monokai Pro — the modern, refined Monokai with balanced colors. */
|
|
916
|
-
declare const monokaiPro: ColorScheme;
|
|
917
|
-
//#endregion
|
|
918
|
-
//#region packages/theme/src/schemes/snazzy.d.ts
|
|
919
|
-
/** Snazzy — clean dark theme by Sindre Sorhus. */
|
|
920
|
-
declare const snazzy: ColorScheme;
|
|
921
|
-
//#endregion
|
|
922
|
-
//#region packages/theme/src/schemes/material.d.ts
|
|
923
|
-
/** Material Darker — the deep dark Material variant. */
|
|
924
|
-
declare const materialDark: ColorScheme;
|
|
925
|
-
/** Material Lighter — the light Material variant. */
|
|
926
|
-
declare const materialLight: ColorScheme;
|
|
927
|
-
//#endregion
|
|
928
|
-
//#region packages/theme/src/schemes/palenight.d.ts
|
|
929
|
-
/** Palenight — the soft, purple-tinted Material dark variant. */
|
|
930
|
-
declare const palenight: ColorScheme;
|
|
931
|
-
//#endregion
|
|
932
|
-
//#region packages/theme/src/schemes/ayu.d.ts
|
|
933
|
-
/** Ayu Dark — deep dark variant with warm accents. */
|
|
934
|
-
declare const ayuDark: ColorScheme;
|
|
935
|
-
/** Ayu Mirage — balanced dark variant with softer contrast. */
|
|
936
|
-
declare const ayuMirage: ColorScheme;
|
|
937
|
-
/** Ayu Light — clean light variant. */
|
|
938
|
-
declare const ayuLight: ColorScheme;
|
|
939
|
-
//#endregion
|
|
940
|
-
//#region packages/theme/src/schemes/nightfox.d.ts
|
|
941
|
-
/** Nightfox — dark blue-toned variant. */
|
|
942
|
-
declare const nightfox: ColorScheme;
|
|
943
|
-
/** Dawnfox — warm light variant inspired by Rose Pine Dawn. */
|
|
944
|
-
declare const dawnfox: ColorScheme;
|
|
945
|
-
//#endregion
|
|
946
|
-
//#region packages/theme/src/schemes/horizon.d.ts
|
|
947
|
-
/** Horizon — warm dark variant with vivid accents. */
|
|
948
|
-
declare const horizon: ColorScheme;
|
|
949
|
-
//#endregion
|
|
950
|
-
//#region packages/theme/src/schemes/moonfly.d.ts
|
|
951
|
-
/** Moonfly — dark charcoal theme. */
|
|
952
|
-
declare const moonfly: ColorScheme;
|
|
953
|
-
//#endregion
|
|
954
|
-
//#region packages/theme/src/schemes/nightfly.d.ts
|
|
955
|
-
/** Nightfly — midnight-blue dark theme. */
|
|
956
|
-
declare const nightfly: ColorScheme;
|
|
957
|
-
//#endregion
|
|
958
|
-
//#region packages/theme/src/schemes/oxocarbon.d.ts
|
|
959
|
-
/** Oxocarbon Dark — IBM Carbon-inspired dark variant. */
|
|
960
|
-
declare const oxocarbonDark: ColorScheme;
|
|
961
|
-
/** Oxocarbon Light — IBM Carbon-inspired light variant. */
|
|
962
|
-
declare const oxocarbonLight: ColorScheme;
|
|
963
|
-
//#endregion
|
|
964
|
-
//#region packages/theme/src/schemes/sonokai.d.ts
|
|
965
|
-
/** Sonokai — vivid dark theme with Monokai-inspired accents. */
|
|
966
|
-
declare const sonokai: ColorScheme;
|
|
967
|
-
//#endregion
|
|
968
|
-
//#region packages/theme/src/schemes/edge.d.ts
|
|
969
|
-
/** Edge Dark — clean dark variant with balanced accents. */
|
|
970
|
-
declare const edgeDark: ColorScheme;
|
|
971
|
-
/** Edge Light — clean, readable light variant. */
|
|
972
|
-
declare const edgeLight: ColorScheme;
|
|
973
|
-
//#endregion
|
|
974
|
-
//#region packages/theme/src/schemes/modus.d.ts
|
|
975
|
-
/** Modus Vivendi — elegant dark theme with maximum legibility. */
|
|
976
|
-
declare const modusVivendi: ColorScheme;
|
|
977
|
-
/** Modus Operandi — elegant light theme with maximum legibility. */
|
|
978
|
-
declare const modusOperandi: ColorScheme;
|
|
979
|
-
//#endregion
|
|
980
|
-
//#region packages/theme/src/schemes/index.d.ts
|
|
981
1015
|
/**
|
|
982
|
-
*
|
|
983
|
-
* All token values are hex strings (no ANSI slot names).
|
|
984
|
-
* Terminal rendering quantizes hex to 4-bit ANSI codes when colorLevel === "basic".
|
|
1016
|
+
* The canonical 4-state color tier supported by a terminal.
|
|
985
1017
|
*
|
|
986
|
-
*
|
|
987
|
-
*
|
|
988
|
-
*
|
|
1018
|
+
* One enum, one spelling — used everywhere a color capability is described
|
|
1019
|
+
* (caps, style level, chalk compat, tier quantization, etc.).
|
|
1020
|
+
*
|
|
1021
|
+
* - `"mono"` — no color (OSC queries disabled, monochrome attribute fallback).
|
|
1022
|
+
* - `"ansi16"` — 16-slot palette (SGR 30-37, 90-97 / 40-47, 100-107).
|
|
1023
|
+
* - `"256"` — xterm-256 palette (SGR 38;5;n).
|
|
1024
|
+
* - `"truecolor"` — 24-bit RGB (SGR 38;2;r;g;b).
|
|
1025
|
+
*
|
|
1026
|
+
* Prior to km-silvery.terminal-profile-plateau this type went by three
|
|
1027
|
+
* different names with three different spellings for the no-color case
|
|
1028
|
+
* (`null`, `"none"`, `"mono"`). Canonicalized to `ColorLevel` + `"mono"`.
|
|
989
1029
|
*/
|
|
990
|
-
|
|
1030
|
+
type ColorLevel = "mono" | "ansi16" | "256" | "truecolor";
|
|
991
1031
|
/**
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
* Terminal rendering quantizes hex to 4-bit ANSI codes when colorLevel === "basic".
|
|
995
|
-
*
|
|
996
|
-
* Sterling flat tokens baked in at construction.
|
|
1032
|
+
* RGB color tuple for underline color.
|
|
1033
|
+
* Each component is 0-255.
|
|
997
1034
|
*/
|
|
998
|
-
|
|
999
|
-
/** Dark truecolor theme — derived from Nord. Sterling flat tokens baked in. */
|
|
1000
|
-
declare const defaultDarkTheme: Theme$1;
|
|
1001
|
-
/** Light truecolor theme — derived from Catppuccin Latte. Sterling flat tokens baked in. */
|
|
1002
|
-
declare const defaultLightTheme: Theme$1;
|
|
1003
|
-
/** All built-in ColorScheme definitions (70+ palettes). */
|
|
1004
|
-
declare const builtinPalettes: Record<string, ColorScheme>;
|
|
1005
|
-
/** All built-in themes, indexed by name (includes backward-compat aliases). */
|
|
1006
|
-
declare const builtinThemes: Record<string, Theme$1>;
|
|
1007
|
-
/** Resolve a theme by name. Defaults to dark-ansi16. */
|
|
1008
|
-
declare function getThemeByName(name?: string): Theme$1;
|
|
1009
|
-
/** Resolve a palette by name. Returns undefined if not found. */
|
|
1010
|
-
declare function getSchemeByName(name: string): ColorScheme | undefined;
|
|
1011
|
-
//#endregion
|
|
1012
|
-
//#region packages/theme/src/detect.d.ts
|
|
1035
|
+
type RGB = [r: number, g: number, b: number];
|
|
1013
1036
|
/**
|
|
1014
|
-
*
|
|
1037
|
+
* Extended underline styles supported by modern terminals.
|
|
1015
1038
|
*
|
|
1016
|
-
*
|
|
1017
|
-
*
|
|
1039
|
+
* - `single`: Standard underline (SGR 4:1)
|
|
1040
|
+
* - `double`: Two parallel lines (SGR 4:2)
|
|
1041
|
+
* - `curly`: Wavy/squiggly line (SGR 4:3) - commonly used for spell check
|
|
1042
|
+
* - `dotted`: Dotted line (SGR 4:4)
|
|
1043
|
+
* - `dashed`: Dashed line (SGR 4:5)
|
|
1018
1044
|
*/
|
|
1019
|
-
|
|
1045
|
+
type UnderlineStyle = "single" | "double" | "curly" | "dotted" | "dashed";
|
|
1020
1046
|
//#endregion
|
|
1021
|
-
//#region packages/
|
|
1047
|
+
//#region packages/ansi/src/color-maps.d.ts
|
|
1022
1048
|
/**
|
|
1023
|
-
*
|
|
1024
|
-
* roles (`info`, `success`, `warning`, `error`) where state variants are
|
|
1025
|
-
* meaningful only for surfaces (filled bg), never for text.
|
|
1049
|
+
* Hex-in / hex-out quantization for previews.
|
|
1026
1050
|
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
*
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
readonly bg: string;
|
|
1034
|
-
}
|
|
1035
|
-
/**
|
|
1036
|
-
* Interactive (link-like) state pair: both `fg` and `bg` vary by state.
|
|
1037
|
-
* Used by `accent` — the canonical interactive-text role.
|
|
1038
|
-
*/
|
|
1039
|
-
interface StatePair {
|
|
1040
|
-
readonly fg: string;
|
|
1041
|
-
readonly bg: string;
|
|
1042
|
-
}
|
|
1043
|
-
/**
|
|
1044
|
-
* A status role — fg, bg, and `fgOn` (text color to draw when rendering ON
|
|
1045
|
-
* a filled bg of this role). State variants apply to SURFACE (bg) only;
|
|
1046
|
-
* text-color state variants are reserved for link-like roles (`accent`).
|
|
1047
|
-
*/
|
|
1048
|
-
interface InteractiveRole {
|
|
1049
|
-
/** Foreground hex — use for text/icon in this role. */
|
|
1050
|
-
readonly fg: string;
|
|
1051
|
-
/** Background hex — use as fill for emphasis. */
|
|
1052
|
-
readonly bg: string;
|
|
1053
|
-
/** Foreground to use when drawing ON `bg` (contrast-picked). */
|
|
1054
|
-
readonly fgOn: string;
|
|
1055
|
-
/** Hover state — surface only (adaptive ±L shift on bg). */
|
|
1056
|
-
readonly hover: BgStatePair;
|
|
1057
|
-
/** Active (pressed) state — surface only (adaptive ±L shift on bg). */
|
|
1058
|
-
readonly active: BgStatePair;
|
|
1059
|
-
}
|
|
1060
|
-
/**
|
|
1061
|
-
* Accent — the canonical link-like interactive-text role. Has everything
|
|
1062
|
-
* `InteractiveRole` does PLUS a focus-ring border AND `fg.hover` /
|
|
1063
|
-
* `fg.active` text-color state variants (link hover treatments).
|
|
1064
|
-
*/
|
|
1065
|
-
interface AccentRole {
|
|
1066
|
-
/** Foreground hex — use for text/icon in accent. */
|
|
1067
|
-
readonly fg: string;
|
|
1068
|
-
/** Background hex — use as fill for emphasis. */
|
|
1069
|
-
readonly bg: string;
|
|
1070
|
-
/** Foreground to use when drawing ON `bg` (contrast-picked). */
|
|
1071
|
-
readonly fgOn: string;
|
|
1072
|
-
/** Border color for focus rings using this accent. */
|
|
1073
|
-
readonly border: string;
|
|
1074
|
-
/** Hover state — both fg (link hover) and bg (surface hover). */
|
|
1075
|
-
readonly hover: StatePair;
|
|
1076
|
-
/** Active (pressed) state — both fg and bg. */
|
|
1077
|
-
readonly active: StatePair;
|
|
1078
|
-
}
|
|
1079
|
-
/** Surface hierarchy — `default` is the canvas, subtle/raised/overlay stack upward. */
|
|
1080
|
-
interface SurfaceRole {
|
|
1081
|
-
readonly default: string;
|
|
1082
|
-
readonly subtle: string;
|
|
1083
|
-
readonly raised: string;
|
|
1084
|
-
readonly overlay: string;
|
|
1085
|
-
readonly hover: string;
|
|
1086
|
-
}
|
|
1087
|
-
/** Border roles — `focus` is the focus-ring color; `default` is normal rule line. */
|
|
1088
|
-
interface BorderRole {
|
|
1089
|
-
readonly default: string;
|
|
1090
|
-
readonly focus: string;
|
|
1091
|
-
readonly muted: string;
|
|
1092
|
-
}
|
|
1093
|
-
/** Cursor colors. */
|
|
1094
|
-
interface CursorRole {
|
|
1095
|
-
readonly fg: string;
|
|
1096
|
-
readonly bg: string;
|
|
1097
|
-
}
|
|
1098
|
-
/** Muted role — lower-emphasis text/bg for deemphasized content. */
|
|
1099
|
-
interface MutedRole {
|
|
1100
|
-
readonly fg: string;
|
|
1101
|
-
readonly bg: string;
|
|
1102
|
-
}
|
|
1103
|
-
/**
|
|
1104
|
-
* The nested, programmatic form of a Theme. All leaf values are hex strings.
|
|
1105
|
-
* Reached via `theme.accent.bg`, `theme.surface.raised`, etc.
|
|
1106
|
-
*/
|
|
1107
|
-
interface Roles {
|
|
1108
|
-
readonly accent: AccentRole;
|
|
1109
|
-
readonly info: InteractiveRole;
|
|
1110
|
-
readonly success: InteractiveRole;
|
|
1111
|
-
readonly warning: InteractiveRole;
|
|
1112
|
-
readonly error: InteractiveRole;
|
|
1113
|
-
readonly muted: MutedRole;
|
|
1114
|
-
readonly surface: SurfaceRole;
|
|
1115
|
-
readonly border: BorderRole;
|
|
1116
|
-
readonly cursor: CursorRole;
|
|
1117
|
-
}
|
|
1118
|
-
/**
|
|
1119
|
-
* Every flat hyphen-key that Sterling emits. String-literal union so that
|
|
1120
|
-
* `theme["bg-accent"]` is type-checked and typos fail the compile.
|
|
1051
|
+
* Takes any hex color and returns the hex a real terminal at that tier would
|
|
1052
|
+
* actually emit. Used by the Sterling storybook to make the `1/2/3/4` tier
|
|
1053
|
+
* toggle visibly different in-process — the output phase already does this
|
|
1054
|
+
* when writing to a real TTY, but preview surfaces (theme swatches, rendered
|
|
1055
|
+
* components inside a storybook app) bypass output-phase quantization. Apply
|
|
1056
|
+
* `quantizeHex` at render time to mimic tier-specific terminal output.
|
|
1121
1057
|
*
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1058
|
+
* - `truecolor`: returns the input unchanged (normalized to `#rrggbb`).
|
|
1059
|
+
* - `256`: snaps to the nearest xterm-256 slot, then returns that slot's hex.
|
|
1060
|
+
* - `ansi16`: snaps to one of the 16 standard slots (canonical xterm RGB).
|
|
1061
|
+
* - `mono`: luminance threshold (>= 0.5 → `#ffffff`, else `#000000`).
|
|
1062
|
+
*
|
|
1063
|
+
* Returns the input unchanged if it cannot be parsed as a hex color.
|
|
1124
1064
|
*/
|
|
1125
|
-
|
|
1126
|
-
/** The flat projection — every FlatToken maps to a hex string. */
|
|
1127
|
-
type FlatTokens = { readonly [K in FlatToken]: string };
|
|
1065
|
+
declare function quantizeHex(hex: string, tier: ColorLevel): string;
|
|
1128
1066
|
/**
|
|
1129
|
-
*
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
1067
|
+
* Pre-quantize every hex leaf in a Theme (or any object tree) to the
|
|
1068
|
+
* requested color tier.
|
|
1069
|
+
*
|
|
1070
|
+
* Walks the input recursively — each string leaf matching `#rgb` / `#rrggbb`
|
|
1071
|
+
* is passed through {@link quantizeHex}; all other values (numbers, booleans,
|
|
1072
|
+
* non-hex strings like `"Nord"`, null/undefined, arrays of non-hex values)
|
|
1073
|
+
* pass through unchanged. Arrays and nested objects are rebuilt with
|
|
1074
|
+
* quantized leaves.
|
|
1075
|
+
*
|
|
1076
|
+
* Works on both the legacy ANSI Theme (flat hex tokens + `palette` array)
|
|
1077
|
+
* and the Sterling Theme (nested roles + flat tokens) — the structural rule
|
|
1078
|
+
* "any leaf that looks like a hex is a color value" holds for both.
|
|
1079
|
+
*
|
|
1080
|
+
* @example Pre-cache tier variants
|
|
1081
|
+
* ```ts
|
|
1082
|
+
* import { pickColorLevel } from "silvery"
|
|
1083
|
+
*
|
|
1084
|
+
* const themes = {
|
|
1085
|
+
* truecolor: theme,
|
|
1086
|
+
* ansi16: pickColorLevel(theme, "ansi16"),
|
|
1087
|
+
* mono: pickColorLevel(theme, "mono"),
|
|
1088
|
+
* }
|
|
1089
|
+
* ```
|
|
1090
|
+
*
|
|
1091
|
+
* @example Storybook — show multiple tiers simultaneously
|
|
1092
|
+
* ```tsx
|
|
1093
|
+
* <ThemeProvider theme={pickColorLevel(theme, "ansi16")}>
|
|
1094
|
+
* <AlertPreview />
|
|
1095
|
+
* </ThemeProvider>
|
|
1096
|
+
* ```
|
|
1097
|
+
*
|
|
1098
|
+
* Notes:
|
|
1099
|
+
* - `truecolor` is a no-op — returns the input unchanged (identity).
|
|
1100
|
+
* - The result is structurally identical to the input (same keys, same
|
|
1101
|
+
* nesting); only hex leaves are remapped.
|
|
1102
|
+
* - Idempotent per tier: `pickColorLevel(pickColorLevel(t, "ansi16"), "ansi16")`
|
|
1103
|
+
* yields the same hex values as `pickColorLevel(t, "ansi16")`.
|
|
1104
|
+
* - Does not freeze the returned object. Callers that want immutability
|
|
1105
|
+
* should `Object.freeze()` (or deep-freeze) the result themselves.
|
|
1132
1106
|
*/
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
/** Human-readable rule name (e.g. `"OKLCH +0.04L on accent.bg"`). */
|
|
1137
|
-
readonly rule: string;
|
|
1138
|
-
/** Input hex(es) the rule operated on. */
|
|
1139
|
-
readonly inputs: readonly string[];
|
|
1140
|
-
/** Output hex. */
|
|
1141
|
-
readonly output: string;
|
|
1142
|
-
/** If auto-lift adjusted this token, the original value before adjustment. */
|
|
1143
|
-
readonly liftedFrom?: string;
|
|
1144
|
-
/** If pinned by scheme author, true. */
|
|
1145
|
-
readonly pinned?: boolean;
|
|
1146
|
-
}
|
|
1147
|
-
type DerivationTrace = readonly DerivationStep[];
|
|
1107
|
+
declare function pickColorLevel<T>(theme: T, tier: ColorLevel): T;
|
|
1108
|
+
//#endregion
|
|
1109
|
+
//#region packages/ansi/src/terminal-control.d.ts
|
|
1148
1110
|
/**
|
|
1149
|
-
*
|
|
1150
|
-
* calendar categories, priority levels — any CATEGORICAL color that isn't
|
|
1151
|
-
* stateful. ensureContrast-adjusted against bg at derivation time. Consumers
|
|
1152
|
-
* access these via `$red`, `$orange`, …, `$pink` or direct field access.
|
|
1111
|
+
* Enable mouse tracking with full hover support.
|
|
1153
1112
|
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
*
|
|
1113
|
+
* Uses two modes:
|
|
1114
|
+
* - **1003** (any-event tracking): Reports ALL mouse motion — clicks, drags, AND hover.
|
|
1115
|
+
* This is what makes onMouseEnter/onMouseLeave work. Without it, only clicks are reported.
|
|
1116
|
+
* - **1006** (SGR encoding): Decimal coordinates with no 223-column limit.
|
|
1117
|
+
* - **1016** (SGR-Pixels): Optional pixel coordinates in the same SGR shape.
|
|
1118
|
+
*
|
|
1119
|
+
* WARNING: Do NOT replace 1003 with 1000+1002. The xterm mouse modes form a hierarchy:
|
|
1120
|
+
* 1000 = clicks only
|
|
1121
|
+
* 1002 = clicks + drag (motion while button held)
|
|
1122
|
+
* 1003 = clicks + drag + hover (ALL motion, even without button)
|
|
1123
|
+
* Mode 1003 supersedes 1000 and 1002. Using 1000+1002 instead of 1003 silently
|
|
1124
|
+
* disables hover — onMouseEnter/onMouseLeave stop firing with no error.
|
|
1158
1125
|
*/
|
|
1159
|
-
interface
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
readonly yellow: string;
|
|
1163
|
-
readonly green: string;
|
|
1164
|
-
readonly teal: string;
|
|
1165
|
-
readonly blue: string;
|
|
1166
|
-
readonly purple: string;
|
|
1167
|
-
readonly pink: string;
|
|
1126
|
+
interface MouseModeOptions {
|
|
1127
|
+
/** Enable xterm SGR-Pixels mode 1016 in addition to 1003/1006. */
|
|
1128
|
+
pixels?: boolean;
|
|
1168
1129
|
}
|
|
1130
|
+
declare function enableMouse(options?: MouseModeOptions): string;
|
|
1169
1131
|
/**
|
|
1170
|
-
*
|
|
1171
|
-
|
|
1172
|
-
|
|
1132
|
+
* Disable mouse tracking. Disables in reverse order of enabling.
|
|
1133
|
+
*/
|
|
1134
|
+
declare function disableMouse(): string;
|
|
1135
|
+
/**
|
|
1136
|
+
* Enable the Kitty keyboard protocol (push mode).
|
|
1173
1137
|
*
|
|
1174
|
-
*
|
|
1175
|
-
*
|
|
1176
|
-
* - Flat: `theme["bg-accent-hover"]`
|
|
1177
|
-
* Both paths reference the same string (not copies). The object is frozen
|
|
1178
|
-
* after derivation (see `flatten.ts`).
|
|
1138
|
+
* Sends CSI > flags u to opt into the specified modes.
|
|
1139
|
+
* Supported by: Ghostty, Kitty, WezTerm, foot. Ignored by unsupported terminals.
|
|
1179
1140
|
*
|
|
1180
|
-
*
|
|
1181
|
-
* - `name` — scheme display name (if derived from a named scheme)
|
|
1182
|
-
* - `mode` — light/dark
|
|
1183
|
-
* - `derivationTrace` — optional; present only when `{ trace: true }` was passed
|
|
1184
|
-
* - `variants` — typography preset bundles (h1, body, code, …) resolved by
|
|
1185
|
-
* `<Text variant="…">`
|
|
1186
|
-
* - `palette` — 16-slot ANSI catalog used by `$color0` … `$color15`
|
|
1187
|
-
* - categorical hues (`red`, `orange`, `yellow`, `green`, `teal`, `blue`,
|
|
1188
|
-
* `purple`, `pink`) — hex strings for categorical UI
|
|
1141
|
+
* Flags are a bitfield:
|
|
1189
1142
|
*
|
|
1190
|
-
*
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
*
|
|
1194
|
-
*
|
|
1195
|
-
*
|
|
1143
|
+
* | Flag | Bit | Description |
|
|
1144
|
+
* | ---- | --- | ----------------------------------------- |
|
|
1145
|
+
* | 1 | 0 | Disambiguate escape codes |
|
|
1146
|
+
* | 2 | 1 | Report event types (press/repeat/release) |
|
|
1147
|
+
* | 4 | 2 | Report alternate keys |
|
|
1148
|
+
* | 8 | 3 | Report all keys as escape codes |
|
|
1149
|
+
* | 16 | 4 | Report associated text |
|
|
1150
|
+
*
|
|
1151
|
+
* @param flags Bitfield of Kitty keyboard flags
|
|
1196
1152
|
*/
|
|
1197
|
-
|
|
1198
|
-
readonly name?: string;
|
|
1199
|
-
readonly mode: "light" | "dark";
|
|
1200
|
-
readonly derivationTrace?: DerivationTrace;
|
|
1201
|
-
readonly variants: Record<string, Variant>;
|
|
1202
|
-
readonly palette: readonly string[];
|
|
1203
|
-
} & CategoricalHues;
|
|
1153
|
+
declare function enableKittyKeyboard(flags?: number): string;
|
|
1204
1154
|
/**
|
|
1205
|
-
*
|
|
1206
|
-
*
|
|
1207
|
-
* props always win over variant values.
|
|
1208
|
-
*
|
|
1209
|
-
* Color values follow the same syntax as `TextColor` — `$token` strings, hex
|
|
1210
|
-
* values, ANSI names, or any string accepted by the color system.
|
|
1155
|
+
* Disable the Kitty keyboard protocol (pop mode stack).
|
|
1156
|
+
* Sends CSI < u to restore the previous keyboard mode.
|
|
1211
1157
|
*/
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
readonly bold?: boolean;
|
|
1216
|
-
readonly italic?: boolean;
|
|
1217
|
-
readonly dim?: boolean;
|
|
1218
|
-
readonly underlineStyle?: "single" | "double" | "curly" | "dotted" | "dashed";
|
|
1219
|
-
}
|
|
1158
|
+
declare function disableKittyKeyboard(): string;
|
|
1159
|
+
//#endregion
|
|
1160
|
+
//#region packages/ansi/src/style/style.d.ts
|
|
1220
1161
|
/**
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1162
|
+
* Resolve a color value against a theme — the canonical token resolver.
|
|
1163
|
+
*
|
|
1164
|
+
* If the color starts with `$`, looks up the token in the theme.
|
|
1165
|
+
* Supports `$primary`, `$surface-bg` (hyphens stripped), `$color0`–`$color15` (palette).
|
|
1166
|
+
* Non-`$` strings pass through unchanged. Returns undefined if no theme or unknown token.
|
|
1167
|
+
*
|
|
1168
|
+
* Compatible with @silvery/theme's Theme type (or any object with string properties).
|
|
1223
1169
|
*/
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
interface DeriveOptions {
|
|
1236
|
-
/** Default: `"auto-lift"`. */
|
|
1237
|
-
readonly contrast?: ContrastMode;
|
|
1238
|
-
/** If true, attach `derivationTrace` to the returned Theme. Default: false. */
|
|
1239
|
-
readonly trace?: boolean;
|
|
1240
|
-
/**
|
|
1241
|
-
* Per-role token pins. A scheme author can pin specific tokens (e.g.
|
|
1242
|
-
* `{ "error.fg": "#bf616a" }`) to skip auto-adjustment. The path syntax is
|
|
1243
|
-
* nested-style: `"accent.hover.bg"`, `"error.fg"`. Flat-form pins are
|
|
1244
|
-
* also accepted: `{ "bg-accent": "#...", "fg-on-error": "#..." }`.
|
|
1245
|
-
*/
|
|
1246
|
-
readonly pins?: Readonly<Record<string, string>>;
|
|
1247
|
-
/**
|
|
1248
|
-
* Force light/dark inference. By default inferred from
|
|
1249
|
-
* `scheme.dark` or WCAG luminance of `scheme.background`.
|
|
1250
|
-
*/
|
|
1251
|
-
readonly mode?: "light" | "dark";
|
|
1170
|
+
declare function resolveThemeColor(name: string | undefined, theme: object | undefined): string | undefined;
|
|
1171
|
+
//#endregion
|
|
1172
|
+
//#region packages/ansi/src/theme/derive.d.ts
|
|
1173
|
+
interface ThemeAdjustment {
|
|
1174
|
+
token: string;
|
|
1175
|
+
from: string;
|
|
1176
|
+
to: string;
|
|
1177
|
+
against: string;
|
|
1178
|
+
target: number;
|
|
1179
|
+
ratioBefore: number;
|
|
1180
|
+
ratioAfter: number;
|
|
1252
1181
|
}
|
|
1253
1182
|
/**
|
|
1254
|
-
*
|
|
1255
|
-
*
|
|
1256
|
-
*
|
|
1183
|
+
* Derive a Theme from a ColorScheme, with Sterling flat tokens baked in.
|
|
1184
|
+
*
|
|
1185
|
+
* Every Theme `@silvery/ansi` produces passes through `inlineSterlingTokens`
|
|
1186
|
+
* so consumers can read `$bg-accent`, `$bg-surface-overlay`, `$border-default`,
|
|
1187
|
+
* `$fg-muted`, etc. directly off the returned object. This is the one
|
|
1188
|
+
* canonical Theme shape in silvery — there is no separate "partial" Theme.
|
|
1257
1189
|
*/
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1190
|
+
declare function deriveTheme(palette: ColorScheme, mode?: "ansi16" | "truecolor", adjustments?: ThemeAdjustment[]): Theme;
|
|
1191
|
+
//#endregion
|
|
1192
|
+
//#region packages/ansi/src/theme/orchestrator.d.ts
|
|
1193
|
+
/** How the final scheme was decided. */
|
|
1194
|
+
type DetectSource = "override" | "fingerprint" | "probed" | "bg-mode" | "fallback";
|
|
1195
|
+
/** Where each slot's value came from. */
|
|
1196
|
+
type SlotSource = "probed" | "catalog" | "derived" | "fallback";
|
|
1197
|
+
interface DetectSchemeResult {
|
|
1198
|
+
/** The resolved 22-slot color scheme. */
|
|
1199
|
+
scheme: ColorScheme;
|
|
1200
|
+
/** The derived, validated Theme (via loadTheme). */
|
|
1201
|
+
theme: Theme;
|
|
1202
|
+
/** How the scheme was determined overall. */
|
|
1203
|
+
source: DetectSource;
|
|
1204
|
+
/** 0–1 confidence heuristic (exact override = 1, fingerprint = match score, fallback = 0). */
|
|
1205
|
+
confidence: number;
|
|
1206
|
+
/** Per-slot provenance. Keys are ColorScheme field names. */
|
|
1207
|
+
slotSources: Partial<Record<keyof ColorScheme, SlotSource>>;
|
|
1208
|
+
/** If fingerprint matched, the catalog scheme name. */
|
|
1209
|
+
matchedName?: string;
|
|
1210
|
+
}
|
|
1211
|
+
interface DetectSchemeOptions {
|
|
1212
|
+
/** Explicit override — if provided, skips all probing. */
|
|
1213
|
+
override?: ColorScheme;
|
|
1214
|
+
/** Catalog to fingerprint against. If empty or undefined, skip fingerprinting. */
|
|
1215
|
+
catalog?: readonly ColorScheme[];
|
|
1216
|
+
/** OSC probe timeout (ms). Default 150. */
|
|
1217
|
+
timeoutMs?: number;
|
|
1218
|
+
/** Force dark/light inference when no bg is probed. */
|
|
1219
|
+
darkFallback?: boolean;
|
|
1263
1220
|
/**
|
|
1264
|
-
*
|
|
1265
|
-
*
|
|
1266
|
-
*
|
|
1267
|
-
* - `true` — use {@link defaultFlattenRule} (channel-role-state, Sterling style)
|
|
1268
|
-
* - `FlattenRule` — system-specific rule (e.g. Material `onPrimary`)
|
|
1269
|
-
* - `false` or omitted — no auto-flatten (system is responsible, or
|
|
1270
|
-
* consumer only uses nested form)
|
|
1271
|
-
*
|
|
1272
|
-
* Sterling and anything modelled on it should set `flatten: true` —
|
|
1273
|
-
* flat-projection-on-same-object is a universal feature of nested
|
|
1274
|
-
* hex-leaf POJOs and Sterling users expect `theme["bg-accent"]` access.
|
|
1221
|
+
* Apply strict invariant validation to the loaded Theme. Default `lenient`.
|
|
1222
|
+
* See `loadTheme`'s `enforce` parameter.
|
|
1275
1223
|
*/
|
|
1276
|
-
|
|
1277
|
-
/**
|
|
1278
|
-
|
|
1224
|
+
enforce?: "strict" | "lenient" | "off";
|
|
1225
|
+
/** Add WCAG contrast check to the invariant validation. Default `false`. */
|
|
1226
|
+
wcag?: boolean;
|
|
1279
1227
|
/**
|
|
1280
|
-
*
|
|
1281
|
-
*
|
|
1228
|
+
* Optional InputOwner (from `@silvery/ag-term/runtime`). When provided,
|
|
1229
|
+
* OSC queries route through it instead of touching process.stdin directly.
|
|
1230
|
+
* See `probeColors` for the ownership rationale.
|
|
1282
1231
|
*/
|
|
1283
|
-
|
|
1284
|
-
/** Derive from a 22-color terminal scheme — Sterling's primary path. */
|
|
1285
|
-
deriveFromScheme(scheme: ColorScheme, opts?: DeriveOptions): Theme;
|
|
1286
|
-
/** Derive from a single seed color — Material-style. */
|
|
1287
|
-
deriveFromColor(color: string, opts?: DeriveOptions & {
|
|
1288
|
-
mode?: "light" | "dark";
|
|
1289
|
-
}): Theme;
|
|
1290
|
-
/** Derive from a light/dark scheme pair. */
|
|
1291
|
-
deriveFromPair(light: ColorScheme, dark: ColorScheme, opts?: DeriveOptions): {
|
|
1292
|
-
light: Theme;
|
|
1293
|
-
dark: Theme;
|
|
1294
|
-
};
|
|
1295
|
-
/** Derive from a scheme plus a brand-color overlay (F — brand discipline). */
|
|
1296
|
-
deriveFromSchemeWithBrand(scheme: ColorScheme, brand: string, opts?: DeriveOptions): Theme;
|
|
1232
|
+
input?: ProbeInputOwner;
|
|
1297
1233
|
}
|
|
1298
|
-
/** Utility: recursive `Partial` for nested Theme overrides. */
|
|
1299
|
-
type DeepPartial<T> = T extends object ? T extends readonly unknown[] ? T : { [K in keyof T]?: DeepPartial<T[K]> } : T;
|
|
1300
|
-
//#endregion
|
|
1301
|
-
//#region packages/theme/src/sterling/sterling.d.ts
|
|
1302
1234
|
/**
|
|
1303
|
-
*
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1235
|
+
* Detect the terminal's color scheme + derive a theme in one call.
|
|
1236
|
+
*
|
|
1237
|
+
* Runs the 4-layer detection cascade (override → probe → fingerprint →
|
|
1238
|
+
* fallback) and returns a fully-resolved Theme along with provenance metadata
|
|
1239
|
+
* so callers can log how the scheme was determined.
|
|
1240
|
+
*
|
|
1241
|
+
* This is the recommended entry point for apps — it handles all the gotchas
|
|
1242
|
+
* (non-TTY environments, failed probes, partial OSC responses, catalog matches,
|
|
1243
|
+
* bg-mode inference) and returns something you can hand to `ThemeProvider`.
|
|
1244
|
+
*
|
|
1245
|
+
* @example
|
|
1246
|
+
* ```ts
|
|
1247
|
+
* import { detectScheme } from "@silvery/ansi"
|
|
1248
|
+
* import { builtinPalettes } from "@silvery/theme/schemes"
|
|
1249
|
+
*
|
|
1250
|
+
* const { scheme, theme, source, matchedName, confidence } = await detectScheme({
|
|
1251
|
+
* catalog: Object.values(builtinPalettes),
|
|
1252
|
+
* enforce: "lenient",
|
|
1253
|
+
* })
|
|
1254
|
+
* console.log(`${source === "fingerprint" ? `detected ${matchedName}` : source} (${(confidence * 100).toFixed(0)}%)`)
|
|
1255
|
+
* ```
|
|
1306
1256
|
*/
|
|
1307
|
-
declare
|
|
1308
|
-
//#endregion
|
|
1309
|
-
//#region packages/theme/src/sterling/define.d.ts
|
|
1257
|
+
declare function detectScheme(opts?: DetectSchemeOptions): Promise<DetectSchemeResult>;
|
|
1310
1258
|
/**
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1259
|
+
* Shortcut: detect scheme + return the Theme only. For apps that don't care
|
|
1260
|
+
* about provenance. Same defaults as `detectScheme`.
|
|
1261
|
+
*
|
|
1262
|
+
* @example
|
|
1263
|
+
* ```ts
|
|
1264
|
+
* const theme = await detectSchemeTheme({ catalog: Object.values(builtinPalettes) })
|
|
1265
|
+
* render(<ThemeProvider theme={theme}>…</ThemeProvider>)
|
|
1266
|
+
* ```
|
|
1315
1267
|
*/
|
|
1316
|
-
declare function
|
|
1268
|
+
declare function detectSchemeTheme(opts?: DetectSchemeOptions): Promise<Theme>;
|
|
1317
1269
|
//#endregion
|
|
1318
|
-
//#region packages/
|
|
1319
|
-
/**
|
|
1320
|
-
* Sterling contrast guardrails — D3 from sterling-preflight.md.
|
|
1321
|
-
*
|
|
1322
|
-
* Two modes:
|
|
1323
|
-
* - `strict` — throw when a core role pair fails WCAG AA 4.5:1.
|
|
1324
|
-
* Used by the catalog test (all 84 shipped schemes must pass).
|
|
1325
|
-
* - `auto-lift` — adjust OKLCH lightness until AA passes (±0.04L increments
|
|
1326
|
-
* up to ~0.20L). Logs at debug; silent by default. Used for user schemes
|
|
1327
|
-
* at runtime.
|
|
1328
|
-
*
|
|
1329
|
-
* Pinned tokens (per-role overrides supplied by scheme authors) are excluded
|
|
1330
|
-
* from auto-lift and from strict-mode enforcement — the author accepts the
|
|
1331
|
-
* contrast consequence of pinning.
|
|
1332
|
-
*/
|
|
1333
|
-
/** WCAG AA threshold for normal text. */
|
|
1334
|
-
declare const WCAG_AA = 4.5;
|
|
1335
|
-
interface ContrastViolation {
|
|
1336
|
-
readonly token: string;
|
|
1337
|
-
readonly fg: string;
|
|
1338
|
-
readonly bg: string;
|
|
1339
|
-
readonly ratio: number;
|
|
1340
|
-
readonly target: number;
|
|
1341
|
-
}
|
|
1342
|
-
declare class ContrastError extends Error {
|
|
1343
|
-
readonly violations: readonly ContrastViolation[];
|
|
1344
|
-
constructor(violations: readonly ContrastViolation[]);
|
|
1345
|
-
}
|
|
1270
|
+
//#region packages/ansi/src/theme/tokens.d.ts
|
|
1346
1271
|
/**
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1272
|
+
* Built-in variant names — the standard typography presets shipped by silvery.
|
|
1273
|
+
* These are the default keys in `Theme.variants`.
|
|
1349
1274
|
*/
|
|
1350
|
-
|
|
1275
|
+
type VariantName = "h1" | "h2" | "h3" | "body" | "body-muted" | "fine-print" | "strong" | "em" | "link" | "key" | "code" | "kbd";
|
|
1351
1276
|
/**
|
|
1352
|
-
*
|
|
1353
|
-
*
|
|
1354
|
-
*
|
|
1355
|
-
*
|
|
1356
|
-
* Implementation note: binary-searches the minimum L shift achieving the
|
|
1357
|
-
* target. Falls back to a best-effort value if the target is unreachable
|
|
1358
|
-
* (e.g., yellow against white can never hit 4.5:1 at any lightness while
|
|
1359
|
-
* preserving yellow hue; the result is the darkest in-gamut yellow).
|
|
1277
|
+
* Any variant name — built-in or app-defined. The `(string & {})` tail is the
|
|
1278
|
+
* Tailwind trick: preserves IDE autocomplete for the literal union while still
|
|
1279
|
+
* accepting any runtime string value.
|
|
1360
1280
|
*/
|
|
1361
|
-
|
|
1362
|
-
value: string;
|
|
1363
|
-
lifted: boolean;
|
|
1364
|
-
};
|
|
1281
|
+
type KnownVariant = VariantName | (string & {});
|
|
1365
1282
|
//#endregion
|
|
1366
|
-
//#region packages/
|
|
1283
|
+
//#region packages/ansi/src/osc-palette.d.ts
|
|
1367
1284
|
/**
|
|
1368
|
-
*
|
|
1285
|
+
* OSC 4 Terminal Color Palette Query/Set — pure ANSI protocol.
|
|
1369
1286
|
*/
|
|
1370
|
-
declare function
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1287
|
+
declare function queryPaletteColor(index: number, write: (data: string) => void): void;
|
|
1288
|
+
declare function queryMultiplePaletteColors(indices: number[], write: (data: string) => void): void;
|
|
1289
|
+
declare function setPaletteColor(index: number, color: string, write: (data: string) => void): void;
|
|
1290
|
+
declare function parsePaletteResponse(input: string): {
|
|
1291
|
+
index: number;
|
|
1292
|
+
color: string;
|
|
1293
|
+
} | null;
|
|
1294
|
+
//#endregion
|
|
1295
|
+
//#region packages/ansi/src/osc-colors.d.ts
|
|
1296
|
+
declare function queryForegroundColor(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
|
|
1297
|
+
declare function queryBackgroundColor(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
|
|
1298
|
+
declare function queryCursorColor(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<string | null>;
|
|
1299
|
+
declare function setForegroundColor(write: (data: string) => void, color: string): void;
|
|
1300
|
+
declare function setBackgroundColor(write: (data: string) => void, color: string): void;
|
|
1301
|
+
declare function setCursorColor(write: (data: string) => void, color: string): void;
|
|
1302
|
+
declare function resetForegroundColor(write: (data: string) => void): void;
|
|
1303
|
+
declare function resetBackgroundColor(write: (data: string) => void): void;
|
|
1304
|
+
declare function resetCursorColor(write: (data: string) => void): void;
|
|
1305
|
+
declare function detectColorScheme(write: (data: string) => void, read: (timeoutMs: number) => Promise<string | null>, timeoutMs?: number): Promise<"light" | "dark" | null>;
|
|
1306
|
+
//#endregion
|
|
1307
|
+
//#region packages/ansi/src/theme/generate.d.ts
|
|
1376
1308
|
/**
|
|
1377
|
-
*
|
|
1378
|
-
* in strict mode if any role pair fails WCAG AA. Callers typically wrap this
|
|
1379
|
-
* with `flatten()` (from `flatten.ts`) to get the user-facing Theme.
|
|
1309
|
+
* Generate a complete ANSI 16 theme from a primary color + dark/light preference.
|
|
1380
1310
|
*
|
|
1381
|
-
*
|
|
1311
|
+
* All token values are ANSI color names (e.g. "yellow", "blueBright").
|
|
1382
1312
|
*/
|
|
1383
|
-
declare function
|
|
1384
|
-
//#endregion
|
|
1385
|
-
//#region packages/theme/src/sterling/flat-tokens.d.ts
|
|
1386
|
-
declare const STERLING_FLAT_TOKENS: readonly FlatToken[];
|
|
1387
|
-
//#endregion
|
|
1388
|
-
//#region packages/theme/src/sterling/defaults.d.ts
|
|
1389
|
-
declare function defaultScheme(mode?: "light" | "dark"): ColorScheme;
|
|
1313
|
+
declare function generateTheme(primary: AnsiPrimary, dark: boolean): Theme;
|
|
1390
1314
|
//#endregion
|
|
1391
|
-
export {
|
|
1392
|
-
//# sourceMappingURL=index-
|
|
1315
|
+
export { BorderRole as $, quantizeHex as A, createTerminalProfile as B, deriveTheme as C, enableKittyKeyboard as D, disableMouse as E, defaultCaps as F, detectTheme as G, DetectThemeOptions as H, ColorProvenance as I, AnsiPrimary as J, probeColors as K, CreateTerminalProfileOptions as L, RGB as M, UnderlineStyle as N, enableMouse as O, TerminalCaps as P, AccentRole as Q, ProbeTerminalProfileOptions as R, detectSchemeTheme as S, disableKittyKeyboard as T, DetectedScheme as U, probeTerminalProfile as V, detectTerminalScheme as W, ColorScheme as X, COLOR_SCHEME_FIELDS as Y, HueName as Z, DetectSchemeOptions as _, bakeFlat as _t, queryForegroundColor as a, DeriveOptions as at, SlotSource as b, resetForegroundColor as c, FlatTokens as ct, setForegroundColor as d, Roles as dt, ContrastMode as et, parsePaletteResponse as f, StatePair as ft, KnownVariant as g, FlattenRule as gt, setPaletteColor as h, ThemeShape as ht, queryCursorColor as i, DerivationTrace as it, ColorLevel as j, pickColorLevel as k, setBackgroundColor as l, InteractiveRole as lt, queryPaletteColor as m, Theme as mt, detectColorScheme as n, DeepPartial as nt, resetBackgroundColor as o, DesignSystem as ot, queryMultiplePaletteColors as p, SurfaceRole as pt, ActiveScheme as q, queryBackgroundColor as r, DerivationStep as rt, resetCursorColor as s, FlatToken as st, generateTheme as t, CursorRole as tt, setCursorColor as u, MutedRole as ut, DetectSchemeResult as v, defaultFlattenRule as vt, resolveThemeColor as w, detectScheme as x, DetectSource as y, TerminalEmulator as yt, TerminalProfile as z };
|
|
1316
|
+
//# sourceMappingURL=index-CSQf13CI.d.mts.map
|