@alchemy.run/sigil 0.0.0-alpha.1 → 0.0.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/README.md +499 -313
  2. package/THIRD_PARTY_NOTICES.md +98 -23
  3. package/dist/Text-DV9CuzAT.d.ts +452 -0
  4. package/dist/ansi.d.ts +217 -0
  5. package/dist/ansi.js +87 -0
  6. package/dist/capabilities.d.ts +5 -0
  7. package/dist/capabilities.js +3 -0
  8. package/dist/cell-_ZVhbfl0.js +44 -0
  9. package/dist/color-CkbalRqK.js +2 -0
  10. package/dist/color-policy-BAC9-TZX.js +592 -0
  11. package/dist/color-policy-CCxuHIdD.d.ts +22 -0
  12. package/dist/color-profile-CyeHnG1T.d.ts +97 -0
  13. package/dist/color-profile-DHhQHY55.js +36 -0
  14. package/dist/color.d.ts +21 -0
  15. package/dist/color.js +3 -0
  16. package/dist/cursor-position-D2LAkRG0.d.ts +7 -0
  17. package/dist/detect-B3dL4Q11.js +374 -0
  18. package/dist/detect-Db6GbKOm.d.ts +195 -0
  19. package/dist/{devtools-QpCMm9JH.mjs → devtools-DbthxoD1.js} +23 -24
  20. package/dist/env-YVw64yZS.js +9 -0
  21. package/dist/escapes-CB_6CWOE.d.ts +72 -0
  22. package/dist/geometry-BxXOzJgo.d.ts +11 -0
  23. package/dist/index-D48vQhhe.d.ts +21 -0
  24. package/dist/index-DDVME65c.d.ts +919 -0
  25. package/dist/index.d.ts +1310 -0
  26. package/dist/index.js +3211 -0
  27. package/dist/jsx-dev-runtime.d.ts +2 -0
  28. package/dist/jsx-dev-runtime.js +227 -0
  29. package/dist/jsx-runtime-XtwIVFsg.js +255 -0
  30. package/dist/jsx-runtime.d.ts +2 -0
  31. package/dist/jsx-runtime.js +8 -0
  32. package/dist/osc-BFKKSqpg.js +71 -0
  33. package/dist/osc-Cn0fw77g.d.ts +23 -0
  34. package/dist/paint-Cx-zC_sX.d.ts +81 -0
  35. package/dist/query-BNc2B8GD.d.ts +152 -0
  36. package/dist/react-CTZ_8dwh.js +1197 -0
  37. package/dist/react.d.ts +2 -0
  38. package/dist/react.js +49 -0
  39. package/dist/router.d.ts +392 -0
  40. package/dist/router.js +711 -0
  41. package/dist/sample-Cqw1bjUL.js +445 -0
  42. package/dist/screen-CgC2WlVM.d.ts +49 -0
  43. package/dist/screen-CiPytswf.js +342 -0
  44. package/dist/screen.d.ts +5 -0
  45. package/dist/screen.js +5 -0
  46. package/dist/semantic-text-style-DIMzC7xt.js +91 -0
  47. package/dist/serialize-BTkAZgw1.js +79 -0
  48. package/dist/session-DDQ5V300.js +723 -0
  49. package/dist/sgr-BhwaWAJB.js +246 -0
  50. package/dist/store-C1P5fOUi.d.ts +72 -0
  51. package/dist/string-width-CijQwpIk.js +69 -0
  52. package/dist/strip-BvU4toXG.js +6 -0
  53. package/dist/terminal.d.ts +121 -0
  54. package/dist/terminal.js +2 -0
  55. package/dist/tokenize-AjqbvtiT.js +1242 -0
  56. package/dist/tokenize-Dx1y_l5H.d.ts +57 -0
  57. package/dist/truncate-D31fhU6i.js +562 -0
  58. package/dist/use-focus-B5npZrJU.js +18736 -0
  59. package/dist/yoga-5jKhYCJC.js +3465 -0
  60. package/dist/yoga.d.ts +2 -0
  61. package/dist/yoga.js +2 -0
  62. package/package.json +89 -29
  63. package/src/ansi/chalk.ts +138 -0
  64. package/src/ansi/cursor.ts +46 -0
  65. package/src/ansi/east-asian-width.ts +259 -0
  66. package/src/ansi/escapes.ts +120 -0
  67. package/src/ansi/graphemes.ts +8 -0
  68. package/src/ansi/hyperlink.ts +44 -0
  69. package/src/ansi/index.ts +27 -0
  70. package/src/ansi/osc.ts +77 -0
  71. package/src/ansi/sgr.ts +234 -0
  72. package/src/ansi/slice.ts +43 -0
  73. package/src/ansi/string-width.ts +121 -0
  74. package/src/ansi/strip.ts +13 -0
  75. package/src/ansi/tokenize.ts +380 -0
  76. package/src/ansi/truncate.ts +196 -0
  77. package/src/ansi/wrap.ts +765 -0
  78. package/src/ansi-tokenizer.ts +510 -0
  79. package/src/capabilities/color-policy.ts +34 -0
  80. package/src/capabilities/detect.ts +608 -0
  81. package/src/capabilities/index.ts +37 -0
  82. package/src/capabilities/query.ts +679 -0
  83. package/src/capabilities/store.ts +394 -0
  84. package/src/code-excerpt.ts +39 -0
  85. package/src/color/index.ts +3 -0
  86. package/src/color/paint.ts +169 -0
  87. package/src/color/palette.ts +48 -0
  88. package/src/color/sample.ts +323 -0
  89. package/src/color.ts +1 -0
  90. package/src/components/AccessibilityContext.ts +5 -0
  91. package/src/components/AnimationContext.ts +24 -0
  92. package/src/components/AnsiText.tsx +42 -0
  93. package/src/components/App.tsx +878 -0
  94. package/src/components/AppContext.ts +111 -0
  95. package/src/components/BackgroundContext.ts +7 -0
  96. package/src/components/Box.tsx +100 -0
  97. package/src/components/CursorContext.ts +19 -0
  98. package/src/components/ErrorBoundary.tsx +39 -0
  99. package/src/components/ErrorOverview.tsx +135 -0
  100. package/src/components/FocusContext.ts +30 -0
  101. package/src/components/Hyperlink.tsx +56 -0
  102. package/src/components/Newline.tsx +16 -0
  103. package/src/components/Spacer.tsx +11 -0
  104. package/src/components/Static.tsx +60 -0
  105. package/src/components/StderrContext.ts +24 -0
  106. package/src/components/StdinContext.ts +48 -0
  107. package/src/components/StdoutContext.ts +26 -0
  108. package/src/components/TerminalOscContext.ts +25 -0
  109. package/src/components/Text.tsx +122 -0
  110. package/src/components/Transform.tsx +38 -0
  111. package/src/components/VirtualList.tsx +128 -0
  112. package/src/cursor-position.ts +103 -0
  113. package/src/devtools.ts +103 -0
  114. package/src/dom.ts +301 -0
  115. package/src/env.ts +12 -0
  116. package/src/get-max-width.ts +11 -0
  117. package/src/global.d.ts +38 -0
  118. package/src/glyphs.ts +99 -0
  119. package/src/hooks/use-animation.ts +142 -0
  120. package/src/hooks/use-app.ts +8 -0
  121. package/src/hooks/use-box-metrics.ts +134 -0
  122. package/src/hooks/use-capabilities.ts +73 -0
  123. package/src/hooks/use-cursor.ts +33 -0
  124. package/src/hooks/use-focus-manager.ts +62 -0
  125. package/src/hooks/use-focus.ts +82 -0
  126. package/src/hooks/use-input.ts +267 -0
  127. package/src/hooks/use-is-screen-reader-enabled.ts +12 -0
  128. package/src/hooks/use-paste.ts +78 -0
  129. package/src/hooks/use-stderr.ts +8 -0
  130. package/src/hooks/use-stdin.ts +10 -0
  131. package/src/hooks/use-stdout.ts +8 -0
  132. package/src/hooks/use-terminal-osc.ts +59 -0
  133. package/src/hooks/use-virtual-scroll.ts +84 -0
  134. package/src/hooks/use-window-size.ts +37 -0
  135. package/src/index.ts +96 -0
  136. package/src/ink.tsx +1452 -0
  137. package/src/input-parser.ts +303 -0
  138. package/src/instances.ts +9 -0
  139. package/src/jsx-dev-runtime.ts +3 -0
  140. package/src/jsx-runtime.ts +6 -0
  141. package/src/kitty-keyboard.ts +185 -0
  142. package/src/measure-element.ts +62 -0
  143. package/src/measure-text.ts +31 -0
  144. package/src/paint-tree.ts +220 -0
  145. package/src/parse-keypress.ts +515 -0
  146. package/src/parse-stack-line.ts +138 -0
  147. package/src/patch-console.ts +106 -0
  148. package/src/quick-lru.ts +85 -0
  149. package/src/react.ts +53 -0
  150. package/src/reconciler.ts +476 -0
  151. package/src/render-background.ts +59 -0
  152. package/src/render-border.ts +167 -0
  153. package/src/render-frame.ts +83 -0
  154. package/src/render-to-string.ts +146 -0
  155. package/src/render.ts +284 -0
  156. package/src/router/components.tsx +343 -0
  157. package/src/router/context.ts +41 -0
  158. package/src/router/history.ts +194 -0
  159. package/src/router/hooks.tsx +391 -0
  160. package/src/router/index.ts +34 -0
  161. package/src/router/matcher.ts +571 -0
  162. package/src/sanitize-ansi.ts +33 -0
  163. package/src/screen/ansi.ts +184 -0
  164. package/src/screen/canvas.ts +160 -0
  165. package/src/screen/cell.ts +138 -0
  166. package/src/screen/color-profile.ts +47 -0
  167. package/src/screen/geometry.ts +9 -0
  168. package/src/screen/index.ts +6 -0
  169. package/src/screen/screen.ts +305 -0
  170. package/src/screen/serialize.ts +129 -0
  171. package/src/screen.ts +1 -0
  172. package/src/semantic-text-style.ts +118 -0
  173. package/src/signal-exit.ts +106 -0
  174. package/src/squash-text-nodes.ts +37 -0
  175. package/src/stream.ts +28 -0
  176. package/src/structured-text.ts +325 -0
  177. package/src/styles.ts +753 -0
  178. package/src/terminal/index.ts +2 -0
  179. package/src/terminal/inline-presenter.ts +120 -0
  180. package/src/terminal/input.ts +92 -0
  181. package/src/terminal/render-scheduler.ts +37 -0
  182. package/src/terminal/screen-presenter.ts +242 -0
  183. package/src/terminal/session.ts +408 -0
  184. package/src/terminal-size.ts +58 -0
  185. package/src/terminal.ts +1 -0
  186. package/src/testing/browser.ts +588 -0
  187. package/src/testing/emulators.ts +205 -0
  188. package/src/testing/explorer-app/index.html +12 -0
  189. package/src/testing/explorer-app/main.ts +381 -0
  190. package/src/testing/explorer-app/style.css +194 -0
  191. package/src/testing/explorer-app/tsconfig.json +15 -0
  192. package/src/testing/explorer-app/vite-env.d.ts +1 -0
  193. package/src/testing/index.ts +26 -0
  194. package/src/testing/keys.ts +56 -0
  195. package/src/testing/live.ts +85 -0
  196. package/src/testing/matchers.ts +70 -0
  197. package/src/testing/public.ts +94 -0
  198. package/src/testing/terminal.ts +361 -0
  199. package/src/testing/vitest.ts +157 -0
  200. package/src/throttle.ts +73 -0
  201. package/src/transform-adapter.ts +14 -0
  202. package/src/types.ts +10 -0
  203. package/src/virtual-scroll.ts +133 -0
  204. package/src/wrap-text.ts +54 -0
  205. package/src/yoga/config.ts +57 -0
  206. package/src/yoga/core/absoluteLayout.ts +626 -0
  207. package/src/yoga/core/baseline.ts +66 -0
  208. package/src/yoga/core/cache.ts +136 -0
  209. package/src/yoga/core/calculateLayout.ts +2926 -0
  210. package/src/yoga/core/config.ts +104 -0
  211. package/src/yoga/core/flexLine.ts +177 -0
  212. package/src/yoga/core/helpers.ts +293 -0
  213. package/src/yoga/core/layoutResults.ts +167 -0
  214. package/src/yoga/core/node.ts +611 -0
  215. package/src/yoga/core/numeric.ts +44 -0
  216. package/src/yoga/core/pixelGrid.ts +151 -0
  217. package/src/yoga/core/style.ts +887 -0
  218. package/src/yoga/core/types.ts +224 -0
  219. package/src/yoga/generated/YGEnums.ts +263 -0
  220. package/src/yoga/index.ts +19 -0
  221. package/src/yoga/node.ts +1140 -0
  222. package/dist/index.d.mts +0 -2379
  223. package/dist/index.mjs +0 -10072
@@ -0,0 +1,36 @@
1
+ import { d as rgbToAnsi, f as rgbToAnsi256, t as ansi256ToAnsi } from "./sgr-BhwaWAJB.js";
2
+ //#region src/screen/color-profile.ts
3
+ function colorProfileFromLevel(level) {
4
+ return [
5
+ "none",
6
+ "ansi16",
7
+ "ansi256",
8
+ "truecolor"
9
+ ][level];
10
+ }
11
+ /**
12
+ Quantizes a semantic color for an output profile. `undefined` means the
13
+ terminal default and is also the result for the no-color profile.
14
+ */
15
+ function quantizeColor(color, profile) {
16
+ if (!color || profile === "none") return;
17
+ if (profile === "truecolor") return color;
18
+ if (profile === "ansi256") {
19
+ if (color.model === "indexed") return color;
20
+ return {
21
+ model: "indexed",
22
+ index: rgbToAnsi256(color.red, color.green, color.blue),
23
+ encoding: "ansi256"
24
+ };
25
+ }
26
+ return {
27
+ model: "indexed",
28
+ index: ansiCodeToPaletteIndex(color.model === "indexed" ? ansi256ToAnsi(color.index) : rgbToAnsi(color.red, color.green, color.blue)),
29
+ encoding: "ansi16"
30
+ };
31
+ }
32
+ function ansiCodeToPaletteIndex(code) {
33
+ return code >= 90 ? code - 90 + 8 : code - 30;
34
+ }
35
+ //#endregion
36
+ export { quantizeColor as n, colorProfileFromLevel as t };
@@ -0,0 +1,21 @@
1
+ import { c as Color, d as RgbColor } from "./color-profile-CyeHnG1T.js";
2
+ import { _ as perimeterGradient, a as LinearGradient, c as PaintContext, d as adaptive, f as ansi, g as perProfile, h as named, i as InterpolationSpace, l as PerimeterGradient, m as linearGradient, n as ColorInput, o as NamedColor, p as ansi256, r as GradientStop, s as Paint, t as AdaptiveColor, u as ProfileColor, v as rgb } from "./paint-Cx-zC_sX.js";
3
+ import { n as Rect } from "./geometry-BxXOzJgo.js";
4
+ //#region src/color/palette.d.ts
5
+ declare const canonicalAnsiPalette: readonly RgbColor[];
6
+ declare function colorToRgb(color: Color, palette?: readonly {
7
+ r: number;
8
+ g: number;
9
+ b: number;
10
+ }[]): RgbColor;
11
+ //#endregion
12
+ //#region src/color/sample.d.ts
13
+ declare function samplePaint(paint: Paint, x: number, y: number, bounds: Rect, context?: PaintContext): Color | undefined;
14
+ declare function blend(source: Color, destination: Color, palette?: PaintContext["palette"]): Color;
15
+ /** Progressively moves a color toward white in perceptual OKLab space. */
16
+ declare function lighten(color: Color, amount: number, palette?: PaintContext["palette"]): RgbColor;
17
+ /** Progressively moves a color toward black in perceptual OKLab space. */
18
+ declare function darken(color: Color, amount: number, palette?: PaintContext["palette"]): RgbColor;
19
+ declare function interpolateColor(from: Color, to: Color, amount: number, space?: InterpolationSpace, palette?: PaintContext["palette"]): RgbColor;
20
+ //#endregion
21
+ export { AdaptiveColor, ColorInput, GradientStop, InterpolationSpace, LinearGradient, NamedColor, Paint, PaintContext, PerimeterGradient, ProfileColor, adaptive, ansi, ansi256, blend, canonicalAnsiPalette, colorToRgb, darken, interpolateColor, lighten, linearGradient, named, perProfile, perimeterGradient, rgb, samplePaint };
package/dist/color.js ADDED
@@ -0,0 +1,3 @@
1
+ import { a as samplePaint, c as adaptive, d as linearGradient, f as named, h as rgb, i as lighten, l as ansi, m as perimeterGradient, n as darken, o as canonicalAnsiPalette, p as perProfile, r as interpolateColor, s as colorToRgb, t as blend, u as ansi256 } from "./sample-Cqw1bjUL.js";
2
+ import "./color-CkbalRqK.js";
3
+ export { adaptive, ansi, ansi256, blend, canonicalAnsiPalette, colorToRgb, darken, interpolateColor, lighten, linearGradient, named, perProfile, perimeterGradient, rgb, samplePaint };
@@ -0,0 +1,7 @@
1
+ //#region src/cursor-position.d.ts
2
+ type CursorPosition = {
3
+ x: number;
4
+ y: number;
5
+ };
6
+ //#endregion
7
+ export { CursorPosition as t };
@@ -0,0 +1,374 @@
1
+ import { n as isMacos, o as isWindows, r as isScreenReader, t as isInCi } from "./env-YVw64yZS.js";
2
+ import { constants, openSync } from "node:fs";
3
+ import { WriteStream } from "node:tty";
4
+ //#region src/signal-exit.ts
5
+ const signals = isWindows ? [
6
+ "SIGHUP",
7
+ "SIGINT",
8
+ "SIGTERM",
9
+ "SIGBREAK"
10
+ ] : [
11
+ "SIGHUP",
12
+ "SIGINT",
13
+ "SIGTERM",
14
+ "SIGQUIT",
15
+ "SIGUSR2"
16
+ ];
17
+ const registrations = /* @__PURE__ */ new Set();
18
+ const signalListeners = /* @__PURE__ */ new Map();
19
+ let loaded = false;
20
+ let emitted = false;
21
+ const emitExit = (code, signal) => {
22
+ if (emitted) return;
23
+ emitted = true;
24
+ const ordered = [...registrations].toSorted((a, b) => Number(a.alwaysLast) - Number(b.alwaysLast));
25
+ for (const registration of ordered) registration.handler(code, signal);
26
+ };
27
+ const onExitEvent = (code) => {
28
+ emitExit(code, null);
29
+ };
30
+ const unload = () => {
31
+ if (!loaded) return;
32
+ loaded = false;
33
+ process.off("exit", onExitEvent);
34
+ for (const [signal, listener] of signalListeners) process.off(signal, listener);
35
+ signalListeners.clear();
36
+ };
37
+ const load = () => {
38
+ if (loaded) return;
39
+ loaded = true;
40
+ process.on("exit", onExitEvent);
41
+ for (const signal of signals) {
42
+ const listener = () => {
43
+ if (process.listenerCount(signal) === 1) {
44
+ unload();
45
+ emitExit(null, signal);
46
+ process.kill(process.pid, signal);
47
+ }
48
+ };
49
+ try {
50
+ process.on(signal, listener);
51
+ signalListeners.set(signal, listener);
52
+ } catch {}
53
+ }
54
+ };
55
+ const signalExit = (handler, options = {}) => {
56
+ const registration = {
57
+ handler,
58
+ alwaysLast: options.alwaysLast ?? false
59
+ };
60
+ registrations.add(registration);
61
+ load();
62
+ return () => {
63
+ registrations.delete(registration);
64
+ if (registrations.size === 0) unload();
65
+ };
66
+ };
67
+ //#endregion
68
+ //#region src/terminal-size.ts
69
+ const create = (columns, rows) => ({
70
+ columns: Number.parseInt(String(columns), 10),
71
+ rows: Number.parseInt(String(rows), 10)
72
+ });
73
+ const devTty = () => {
74
+ try {
75
+ const { O_EVTONLY: evtOnly } = constants;
76
+ const flags = isMacos && evtOnly !== void 0 ? evtOnly | constants.O_NONBLOCK : constants.O_NONBLOCK;
77
+ const { columns, rows } = new WriteStream(openSync("/dev/tty", flags));
78
+ if (columns && rows) return {
79
+ columns,
80
+ rows
81
+ };
82
+ } catch {}
83
+ };
84
+ const terminalSize = () => {
85
+ const { env, stdout, stderr } = process;
86
+ if (stdout?.columns && stdout?.rows) return create(stdout.columns, stdout.rows);
87
+ if (stderr?.columns && stderr?.rows) return create(stderr.columns, stderr.rows);
88
+ if (env["COLUMNS"] && env["LINES"]) return create(env["COLUMNS"], env["LINES"]);
89
+ return devTty() ?? {
90
+ columns: 80,
91
+ rows: 24
92
+ };
93
+ };
94
+ //#endregion
95
+ //#region src/capabilities/detect.ts
96
+ const { env } = process;
97
+ const terminalKnowledge = {
98
+ iterm: {
99
+ trueColor: true,
100
+ hyperlinks: { since: [3, 1] }
101
+ },
102
+ "apple-terminal": { colorLevel: 2 },
103
+ wezterm: {
104
+ trueColor: true,
105
+ hyperlinks: true
106
+ },
107
+ vscode: {
108
+ trueColor: true,
109
+ hyperlinks: { since: [1, 72] }
110
+ },
111
+ ghostty: {
112
+ trueColor: true,
113
+ hyperlinks: true
114
+ },
115
+ kitty: {
116
+ trueColor: true,
117
+ hyperlinks: true
118
+ },
119
+ alacritty: {
120
+ trueColor: true,
121
+ hyperlinks: true
122
+ },
123
+ foot: {
124
+ trueColor: true,
125
+ hyperlinks: true
126
+ },
127
+ contour: {
128
+ trueColor: true,
129
+ hyperlinks: true
130
+ },
131
+ "windows-terminal": {
132
+ trueColor: true,
133
+ hyperlinks: true
134
+ },
135
+ konsole: {
136
+ trueColor: true,
137
+ hyperlinks: true
138
+ },
139
+ vte: {
140
+ trueColor: true,
141
+ hyperlinks: { since: [0, 50] }
142
+ },
143
+ hyper: { trueColor: true },
144
+ tabby: {
145
+ trueColor: true,
146
+ hyperlinks: true
147
+ },
148
+ rio: {
149
+ trueColor: true,
150
+ hyperlinks: true
151
+ }
152
+ };
153
+ const termProgramNames = {
154
+ "iTerm.app": "iterm",
155
+ Apple_Terminal: "apple-terminal",
156
+ WezTerm: "wezterm",
157
+ vscode: "vscode",
158
+ ghostty: "ghostty",
159
+ Hyper: "hyper",
160
+ Tabby: "tabby",
161
+ rio: "rio"
162
+ };
163
+ const termNames = {
164
+ "xterm-kitty": "kitty",
165
+ "xterm-ghostty": "ghostty",
166
+ alacritty: "alacritty",
167
+ wezterm: "wezterm",
168
+ foot: "foot",
169
+ contour: "contour"
170
+ };
171
+ const parseVteVersion = (raw) => {
172
+ const numeric = Number.parseInt(raw, 10);
173
+ if (Number.isNaN(numeric)) return;
174
+ return `${Math.floor(numeric / 1e4)}.${Math.floor(numeric / 100) % 100}.${numeric % 100}`;
175
+ };
176
+ const versionAtLeast = (version, [major, minor]) => {
177
+ if (!version) return false;
178
+ const [haveMajor = 0, haveMinor = 0] = version.split(".").map((part) => Number.parseInt(part, 10) || 0);
179
+ return haveMajor > major || haveMajor === major && haveMinor >= minor;
180
+ };
181
+ function detectTerminal() {
182
+ const term = env["TERM"];
183
+ let multiplexer;
184
+ if ("TMUX" in env || env["TERM_PROGRAM"] === "tmux") multiplexer = "tmux";
185
+ else if ("ZELLIJ" in env) multiplexer = "zellij";
186
+ else if (term?.startsWith("screen")) multiplexer = "screen";
187
+ let name;
188
+ let version;
189
+ const termProgram = env["TERM_PROGRAM"];
190
+ if (termProgram && termProgram !== "tmux" && termProgram in termProgramNames) {
191
+ name = termProgramNames[termProgram];
192
+ version = env["TERM_PROGRAM_VERSION"];
193
+ } else if (term && term in termNames) name = termNames[term];
194
+ else if ("WT_SESSION" in env) name = "windows-terminal";
195
+ else if ("KONSOLE_VERSION" in env) {
196
+ name = "konsole";
197
+ version = env["KONSOLE_VERSION"];
198
+ } else if ("VTE_VERSION" in env) {
199
+ name = "vte";
200
+ version = parseVteVersion(env["VTE_VERSION"]);
201
+ }
202
+ return {
203
+ name,
204
+ version,
205
+ term,
206
+ multiplexer
207
+ };
208
+ }
209
+ const knowledgeOf = (identity) => identity.name === void 0 ? void 0 : terminalKnowledge[identity.name];
210
+ const forcedColorLevel = () => {
211
+ const forced = env["FORCE_COLOR"];
212
+ if (forced === void 0) return;
213
+ if (forced === "true" || forced.length === 0) return 1;
214
+ if (forced === "false") return 0;
215
+ return Math.min(Math.max(Number.parseInt(forced, 10) || 0, 0), 3);
216
+ };
217
+ /**
218
+ Detects the color support level for a stream from the environment. Purely
219
+ env-derived — the terminal query can upgrade this to truecolor when the
220
+ terminal confirms it via XTGETTCAP.
221
+ */
222
+ function detectColorLevel(stream) {
223
+ const forced = forcedColorLevel();
224
+ if (forced === 0) return 0;
225
+ if (env["TF_BUILD"] && env["AGENT_NAME"]) return 1;
226
+ if (stream && !stream.isTTY && forced === void 0) return 0;
227
+ const minimum = forced ?? 0;
228
+ if (env["TERM"] === "dumb") return minimum;
229
+ if (isWindows) return 3;
230
+ if (env["CI"]) {
231
+ if ([
232
+ "GITHUB_ACTIONS",
233
+ "GITEA_ACTIONS",
234
+ "CIRCLECI"
235
+ ].some((key) => key in env)) return 3;
236
+ if ([
237
+ "TRAVIS",
238
+ "APPVEYOR",
239
+ "GITLAB_CI",
240
+ "BUILDKITE",
241
+ "DRONE"
242
+ ].some((key) => key in env) || env["CI_NAME"] === "codeship") return 1;
243
+ return minimum;
244
+ }
245
+ if (env["TEAMCITY_VERSION"]) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env["TEAMCITY_VERSION"]) ? 1 : 0;
246
+ if (env["COLORTERM"] === "truecolor") return 3;
247
+ const knowledge = knowledgeOf(detectTerminal());
248
+ if (knowledge) {
249
+ if (knowledge.trueColor) return 3;
250
+ if (knowledge.colorLevel !== void 0) return knowledge.colorLevel;
251
+ }
252
+ if (/-256(color)?$/i.test(env["TERM"] ?? "")) return 2;
253
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env["TERM"] ?? "")) return 1;
254
+ if ("COLORTERM" in env) return 1;
255
+ return minimum;
256
+ }
257
+ /**
258
+ The color level in chalk's `ColorInfo` shape.
259
+ */
260
+ function createSupportsColor(stream) {
261
+ const level = detectColorLevel(stream);
262
+ if (level === 0) return false;
263
+ return {
264
+ level,
265
+ hasBasic: true,
266
+ has256: level >= 2,
267
+ has16m: level >= 3
268
+ };
269
+ }
270
+ /**
271
+ Detects OSC 8 hyperlink support for a stream from the environment.
272
+ */
273
+ function detectHyperlinkSupport(stream) {
274
+ if ("FORCE_HYPERLINK" in env) return !(env["FORCE_HYPERLINK"].length > 0 && Number.parseInt(env["FORCE_HYPERLINK"], 10) === 0);
275
+ if (detectColorLevel(stream) === 0) return false;
276
+ if (stream && !stream.isTTY) return false;
277
+ if (env["CI"] || env["TEAMCITY_VERSION"]) return false;
278
+ const identity = detectTerminal();
279
+ const hyperlinks = knowledgeOf(identity)?.hyperlinks;
280
+ if (hyperlinks === true) return true;
281
+ if (hyperlinks) return versionAtLeast(identity.version, hyperlinks.since);
282
+ return false;
283
+ }
284
+ /**
285
+ Detects whether the terminal renders unicode reliably.
286
+ */
287
+ function detectUnicodeSupport() {
288
+ if (process.platform !== "win32") return env["TERM"] !== "linux";
289
+ const { name } = detectTerminal();
290
+ return name === "windows-terminal" || name === "vscode" || name === "alacritty" || Boolean(env["TERMINUS_SUBLIME"]) || env["ConEmuTask"] === "{cmd::Cmder}" || env["TERM_PROGRAM"] === "Terminus-Sublime" || env["TERM"] === "xterm-256color" || env["TERMINAL_EMULATOR"] === "JetBrains-JediTerm";
291
+ }
292
+ const appearanceFromColorFgBg = () => {
293
+ const background = (env["COLORFGBG"]?.split(";"))?.at(-1);
294
+ if (!background || Number.isNaN(Number.parseInt(background, 10))) return;
295
+ return background === "7" || background === "15" ? "light" : "dark";
296
+ };
297
+ const colorDepths = {
298
+ 0: 1,
299
+ 1: 4,
300
+ 2: 8,
301
+ 3: 24
302
+ };
303
+ const staticCache = /* @__PURE__ */ new WeakMap();
304
+ const computeStatic = (stdout) => {
305
+ const level = detectColorLevel(stdout);
306
+ const interactive = !isInCi && Boolean(stdout.isTTY);
307
+ return {
308
+ platform: process.platform,
309
+ ci: isInCi,
310
+ ssh: "SSH_CONNECTION" in env || "SSH_CLIENT" in env || "SSH_TTY" in env,
311
+ screenReader: isScreenReader,
312
+ interactive,
313
+ terminal: detectTerminal(),
314
+ color: {
315
+ level,
316
+ depth: colorDepths[level],
317
+ trueColor: level === 3
318
+ },
319
+ supports: {
320
+ color: level > 0,
321
+ hyperlinks: detectHyperlinkSupport(stdout),
322
+ unicode: detectUnicodeSupport(),
323
+ alternateScreen: interactive && env["TERM"] !== "dumb",
324
+ kittyKeyboard: void 0,
325
+ kittyGraphics: void 0,
326
+ sixel: void 0,
327
+ focusEvents: void 0,
328
+ sgrMouse: void 0,
329
+ sgrPixelMouse: void 0,
330
+ bracketedPaste: void 0,
331
+ synchronizedOutput: void 0,
332
+ graphemeClustering: void 0,
333
+ colorSchemeUpdates: void 0,
334
+ inBandResize: void 0
335
+ }
336
+ };
337
+ };
338
+ /**
339
+ Takes a snapshot of everything knowable about the terminal from streams and
340
+ environment variables. The environment-derived parts are computed once per
341
+ stream and cached; size and theme are read fresh on every call. Fields that
342
+ require asking the terminal itself start as `undefined` — run `queryTerminal`
343
+ and merge with `applyTerminalQuery` to fill them in, or use the
344
+ `useCapabilities` hook which does both.
345
+ */
346
+ function detectCapabilities({ stdout = process.stdout } = {}) {
347
+ let staticParts = staticCache.get(stdout);
348
+ if (!staticParts) {
349
+ staticParts = computeStatic(stdout);
350
+ staticCache.set(stdout, staticParts);
351
+ }
352
+ return {
353
+ ...staticParts,
354
+ size: {
355
+ ...stdout.columns && stdout.rows ? {
356
+ columns: stdout.columns,
357
+ rows: stdout.rows
358
+ } : terminalSize(),
359
+ pixels: void 0,
360
+ source: "pty"
361
+ },
362
+ focused: void 0,
363
+ theme: {
364
+ appearance: appearanceFromColorFgBg(),
365
+ systemAppearance: void 0,
366
+ foreground: void 0,
367
+ background: void 0,
368
+ cursor: void 0,
369
+ palette: void 0
370
+ }
371
+ };
372
+ }
373
+ //#endregion
374
+ export { detectTerminal as a, detectHyperlinkSupport as i, detectCapabilities as n, detectUnicodeSupport as o, detectColorLevel as r, signalExit as s, createSupportsColor as t };
@@ -0,0 +1,195 @@
1
+ //#region src/capabilities/detect.d.ts
2
+ /**
3
+ An RGB color with 8-bit channels, as reported by the terminal.
4
+ */
5
+ type RgbColor = {
6
+ r: number;
7
+ g: number;
8
+ b: number;
9
+ };
10
+ type TerminalAppearance = "dark" | "light";
11
+ type Multiplexer = "tmux" | "screen" | "zellij";
12
+ /**
13
+ Color support level: 0 = none, 1 = 16 colors, 2 = 256 colors, 3 = truecolor.
14
+ */
15
+ type ColorSupportLevel = 0 | 1 | 2 | 3;
16
+ /**
17
+ The chalk-compatible color support shape.
18
+ */
19
+ type ColorSupport = {
20
+ readonly level: ColorSupportLevel;
21
+ readonly hasBasic: boolean;
22
+ readonly has256: boolean;
23
+ readonly has16m: boolean;
24
+ };
25
+ type ColorInfo = ColorSupport | false;
26
+ type TerminalIdentity = {
27
+ /**
28
+ Normalized terminal name (`"kitty"`, `"iterm"`, `"wezterm"`, …), or
29
+ `undefined` when unknown. `queryTerminal` can refine this with the
30
+ terminal's own XTVERSION answer.
31
+ */
32
+ name: string | undefined;
33
+ /**
34
+ The terminal's version, when the environment reports one.
35
+ */
36
+ version: string | undefined;
37
+ /**
38
+ The raw `TERM` environment variable.
39
+ */
40
+ term: string | undefined;
41
+ /**
42
+ The multiplexer the app is running under, if any. Note that inside a
43
+ multiplexer, capabilities reflect the multiplexer — not the outer terminal.
44
+ */
45
+ multiplexer: Multiplexer | undefined;
46
+ };
47
+ type PixelGeometry = {
48
+ /**
49
+ Text area size in pixels (XTWINOPS 14).
50
+ */
51
+ textArea: {
52
+ width: number;
53
+ height: number;
54
+ } | undefined;
55
+ /**
56
+ Size of a single character cell in pixels (XTWINOPS 16).
57
+ */
58
+ cell: {
59
+ width: number;
60
+ height: number;
61
+ } | undefined;
62
+ };
63
+ type Capabilities = {
64
+ /**
65
+ Current terminal dimensions in cells, plus pixel geometry once the
66
+ terminal has answered the query.
67
+
68
+ `source` tells where the cell dimensions come from. `"pty"` is the
69
+ stream's own `columns`/`rows`, updated by the OS on SIGWINCH — which says
70
+ nothing about whether the emulator has finished rewrapping its screen.
71
+ `"terminal"` is the emulator's in-band size report (mode 2048), which
72
+ arrives in the input stream after the rewrap and so describes the screen
73
+ exactly as later output will find it. While the terminal reports, its
74
+ size wins over the stream's.
75
+ */
76
+ size: {
77
+ columns: number;
78
+ rows: number;
79
+ pixels: PixelGeometry | undefined;
80
+ source: "pty" | "terminal";
81
+ };
82
+ platform: NodeJS.Platform;
83
+ /**
84
+ Running under a CI provider.
85
+ */
86
+ ci: boolean;
87
+ /**
88
+ Running over an SSH connection.
89
+ */
90
+ ssh: boolean;
91
+ screenReader: boolean;
92
+ /**
93
+ Same detection `render()` uses: stdout is a TTY and not CI.
94
+ */
95
+ interactive: boolean;
96
+ /**
97
+ Whether the terminal window has focus. Requires focus events (mode 1004),
98
+ which the capabilities store enables automatically while it has
99
+ subscribers; `undefined` until the first focus report arrives.
100
+ */
101
+ focused: boolean | undefined;
102
+ terminal: TerminalIdentity;
103
+ color: {
104
+ level: ColorSupportLevel;
105
+ /**
106
+ The same fact as bits per color: 1, 4, 8, or 24.
107
+ */
108
+ depth: 1 | 4 | 8 | 24;
109
+ trueColor: boolean;
110
+ };
111
+ theme: {
112
+ /**
113
+ The terminal's own appearance. After `queryTerminal` this is derived
114
+ from the actual background color's luminance (a dark terminal theme on
115
+ a light OS stays `"dark"`); before that it's a `COLORFGBG` guess.
116
+ */
117
+ appearance: TerminalAppearance | undefined;
118
+ /**
119
+ The operating system's color preference, from the color scheme report.
120
+ Independent of the terminal's own theme — only available after
121
+ `queryTerminal` on terminals that support the report.
122
+ */
123
+ systemAppearance: TerminalAppearance | undefined;
124
+ /**
125
+ The user's configured foreground/background/cursor colors and 16-color
126
+ palette. Only available after `queryTerminal`.
127
+ */
128
+ foreground: RgbColor | undefined;
129
+ background: RgbColor | undefined;
130
+ cursor: RgbColor | undefined;
131
+ palette: RgbColor[] | undefined;
132
+ };
133
+ /**
134
+ Feature support. Fields typed `boolean | undefined` are only knowable by
135
+ asking the terminal — they stay `undefined` until `queryTerminal` has
136
+ answered (see `TerminalQueryResult` for what each means).
137
+ */
138
+ supports: {
139
+ color: boolean;
140
+ hyperlinks: boolean;
141
+ unicode: boolean;
142
+ alternateScreen: boolean;
143
+ kittyKeyboard: boolean | undefined;
144
+ kittyGraphics: boolean | undefined;
145
+ sixel: boolean | undefined;
146
+ focusEvents: boolean | undefined;
147
+ sgrMouse: boolean | undefined;
148
+ sgrPixelMouse: boolean | undefined;
149
+ bracketedPaste: boolean | undefined;
150
+ synchronizedOutput: boolean | undefined;
151
+ graphemeClustering: boolean | undefined;
152
+ colorSchemeUpdates: boolean | undefined;
153
+ inBandResize: boolean | undefined;
154
+ };
155
+ };
156
+ declare function detectTerminal(): TerminalIdentity;
157
+ type DetectStream = {
158
+ isTTY?: boolean;
159
+ };
160
+ /**
161
+ Detects the color support level for a stream from the environment. Purely
162
+ env-derived — the terminal query can upgrade this to truecolor when the
163
+ terminal confirms it via XTGETTCAP.
164
+ */
165
+ declare function detectColorLevel(stream?: DetectStream): ColorSupportLevel;
166
+ /**
167
+ The color level in chalk's `ColorInfo` shape.
168
+ */
169
+ declare function createSupportsColor(stream?: DetectStream): ColorInfo;
170
+ /**
171
+ Detects OSC 8 hyperlink support for a stream from the environment.
172
+ */
173
+ declare function detectHyperlinkSupport(stream?: DetectStream): boolean;
174
+ /**
175
+ Detects whether the terminal renders unicode reliably.
176
+ */
177
+ declare function detectUnicodeSupport(): boolean;
178
+ type CapabilityStdout = DetectStream & {
179
+ columns?: number;
180
+ rows?: number;
181
+ };
182
+ type DetectOptions = {
183
+ stdout?: CapabilityStdout;
184
+ };
185
+ /**
186
+ Takes a snapshot of everything knowable about the terminal from streams and
187
+ environment variables. The environment-derived parts are computed once per
188
+ stream and cached; size and theme are read fresh on every call. Fields that
189
+ require asking the terminal itself start as `undefined` — run `queryTerminal`
190
+ and merge with `applyTerminalQuery` to fill them in, or use the
191
+ `useCapabilities` hook which does both.
192
+ */
193
+ declare function detectCapabilities({ stdout }?: DetectOptions): Capabilities;
194
+ //#endregion
195
+ export { Multiplexer as a, TerminalAppearance as c, detectCapabilities as d, detectColorLevel as f, detectUnicodeSupport as h, ColorSupportLevel as i, TerminalIdentity as l, detectTerminal as m, ColorInfo as n, PixelGeometry as o, detectHyperlinkSupport as p, ColorSupport as r, RgbColor as s, Capabilities as t, createSupportsColor as u };