@sigx/terminal-zero 0.5.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-h5p-EcZV.js","names":[],"sources":["../src/shared/colorMath.ts","../src/shared/ticker.ts","../src/shared/textBuffer.ts","../src/shared/viewStack.ts","../src/shared/qr.ts","../src/shared/index.ts"],"sourcesContent":["/**\r\n * Pure color→color math for gradients and animated effects. Deliberately\r\n * dependency-free: token→color stays in the theme layer, color→SGR in the\r\n * renderer — this module only mixes concrete colors in between. Invalid input\r\n * degrades to white instead of throwing; these run inside render functions.\r\n */\r\n\r\nexport function parseHex(hex: string): [number, number, number] | null {\r\n const s = hex.trim().replace(/^#/, '');\r\n if (/^[0-9a-f]{6}$/i.test(s)) {\r\n return [parseInt(s.slice(0, 2), 16), parseInt(s.slice(2, 4), 16), parseInt(s.slice(4, 6), 16)];\r\n }\r\n if (/^[0-9a-f]{3}$/i.test(s)) {\r\n return [parseInt(s[0] + s[0], 16), parseInt(s[1] + s[1], 16), parseInt(s[2] + s[2], 16)];\r\n }\r\n return null;\r\n}\r\n\r\nexport function rgbToHex(r: number, g: number, b: number): string {\r\n const c = (v: number) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0');\r\n return `#${c(r)}${c(g)}${c(b)}`;\r\n}\r\n\r\n/** Per-channel linear mix of two hex colors; `t` clamped to 0..1. */\r\nexport function mixHex(a: string, b: string, t: number): string {\r\n const ca = parseHex(a) ?? [255, 255, 255];\r\n const cb = parseHex(b) ?? [255, 255, 255];\r\n const k = Math.max(0, Math.min(1, t));\r\n return rgbToHex(\r\n ca[0] + (cb[0] - ca[0]) * k,\r\n ca[1] + (cb[1] - ca[1]) * k,\r\n ca[2] + (cb[2] - ca[2]) * k,\r\n );\r\n}\r\n\r\n/** Sample `n` colors evenly across a multi-stop gradient. */\r\nexport function gradient(stops: string[], n: number): string[] {\r\n if (n <= 0) return [];\r\n if (stops.length === 0) return new Array(n).fill('#ffffff');\r\n if (stops.length === 1) return new Array(n).fill(stops[0]);\r\n const out: string[] = [];\r\n for (let i = 0; i < n; i++) {\r\n const pos = n === 1 ? 0 : i / (n - 1);\r\n const seg = pos * (stops.length - 1);\r\n const k = Math.min(Math.floor(seg), stops.length - 2);\r\n out.push(mixHex(stops[k], stops[k + 1], seg - k));\r\n }\r\n return out;\r\n}\r\n\r\nfunction rgbToHsl(r: number, g: number, b: number): [number, number, number] {\r\n r /= 255; g /= 255; b /= 255;\r\n const max = Math.max(r, g, b);\r\n const min = Math.min(r, g, b);\r\n const l = (max + min) / 2;\r\n if (max === min) return [0, 0, l];\r\n const d = max - min;\r\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\r\n let h: number;\r\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\r\n else if (max === g) h = ((b - r) / d + 2) / 6;\r\n else h = ((r - g) / d + 4) / 6;\r\n return [h, s, l];\r\n}\r\n\r\nfunction hslToRgb(h: number, s: number, l: number): [number, number, number] {\r\n if (s === 0) {\r\n const v = l * 255;\r\n return [v, v, v];\r\n }\r\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\r\n const p = 2 * l - q;\r\n const channel = (t: number) => {\r\n if (t < 0) t += 1;\r\n if (t > 1) t -= 1;\r\n if (t < 1 / 6) return p + (q - p) * 6 * t;\r\n if (t < 1 / 2) return q;\r\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\r\n return p;\r\n };\r\n return [channel(h + 1 / 3) * 255, channel(h) * 255, channel(h - 1 / 3) * 255];\r\n}\r\n\r\n/** Rotate a hex color's hue by `degrees` (HSL space). */\r\nexport function hueShift(hex: string, degrees: number): string {\r\n const rgb = parseHex(hex) ?? [255, 255, 255];\r\n const [h, s, l] = rgbToHsl(rgb[0], rgb[1], rgb[2]);\r\n const shifted = (((h + degrees / 360) % 1) + 1) % 1;\r\n const [r, g, b] = hslToRgb(shifted, s, l);\r\n return rgbToHex(r, g, b);\r\n}\r\n","/**\r\n * Shared animation ticker: ONE refcounted interval drives every animated\r\n * component (spinners, gradients, shimmers), instead of a timer per instance.\r\n * Frozen at 0 when stdout is not a TTY, so piped/CI runs render frame zero\r\n * everywhere — deterministic plain output, no wasted wakeups.\r\n */\r\nimport { signal } from '@sigx/reactivity';\r\nimport { getOutputTarget } from '@sigx/runtime-terminal';\r\n\r\n/** Global animation granularity, ms. Components derive slower rates from it. */\r\nexport const TICK_MS = 80;\r\n\r\nconst tick = signal({ t: 0 });\r\nlet timer: ReturnType<typeof setInterval> | null = null;\r\nlet refs = 0;\r\n\r\n/** Reactive frame counter — read it in a render function to re-render per tick. */\r\nexport function getTick(): number {\r\n return tick.t;\r\n}\r\n\r\n/**\r\n * Refcounted subscription: the first subscriber starts the interval, the last\r\n * unsubscribe stops it. Returns an idempotent unsubscribe function.\r\n */\r\nexport function subscribeTicker(): () => void {\r\n if (!getOutputTarget().isTTY) return () => {};\r\n refs++;\r\n if (!timer) {\r\n timer = setInterval(() => { tick.t++; }, TICK_MS);\r\n }\r\n let active = true;\r\n return () => {\r\n if (!active) return;\r\n active = false;\r\n refs--;\r\n if (refs === 0 && timer) {\r\n clearInterval(timer);\r\n timer = null;\r\n }\r\n };\r\n}\r\n","/**\r\n * Headless text-buffer core for multi-line editors: soft-wrap layout and\r\n * cursor math, all pure functions. The styled editor (`TextArea` in\r\n * @sigx/terminal-ui) renders on top of this.\r\n *\r\n * Conventions: the cursor is a CODE-POINT index into the text (0..length in\r\n * code points); columns are display cells (wide glyphs count 2, via\r\n * `charWidth`). A wide glyph never straddles a wrap boundary.\r\n */\r\nimport { charWidth } from '@sigx/runtime-terminal';\r\n\r\nexport interface TextBufferState {\r\n text: string;\r\n /** Code-point index, 0..codePointLength(text). */\r\n cursor: number;\r\n}\r\n\r\nexport interface TextRow {\r\n text: string;\r\n /** Code-point offset of the row's first character in the full text. */\r\n start: number;\r\n /** Exclusive end offset; excludes the `\\n` on hard rows. */\r\n end: number;\r\n /** True when the row ends at an explicit newline (or end of text). */\r\n hard: boolean;\r\n}\r\n\r\nexport interface TextLayout {\r\n rows: TextRow[];\r\n width: number;\r\n}\r\n\r\nconst cps = (text: string): string[] => [...text];\r\n\r\n/**\r\n * Soft-wrap `text` at `width` display cells. Explicit `\\n` always breaks a\r\n * row (hard). Overlong rows break at the last space when one exists in the\r\n * row, otherwise hard-break mid-word. Empty text yields one empty row.\r\n */\r\nexport function layoutText(text: string, width: number): TextLayout {\r\n const w = Math.max(1, width);\r\n const chars = cps(text);\r\n const rows: TextRow[] = [];\r\n\r\n let rowStart = 0;\r\n let rowCells = 0;\r\n let lastSpace = -1; // code-point index of the last space in the current row\r\n\r\n const pushRow = (end: number, hard: boolean, nextStart: number) => {\r\n rows.push({ text: chars.slice(rowStart, end).join(''), start: rowStart, end, hard });\r\n rowStart = nextStart;\r\n lastSpace = -1;\r\n };\r\n\r\n let i = 0;\r\n while (i < chars.length) {\r\n const ch = chars[i];\r\n if (ch === '\\n') {\r\n pushRow(i, true, i + 1);\r\n rowCells = 0;\r\n i++;\r\n continue;\r\n }\r\n const cw = charWidth(ch.codePointAt(0) ?? 0);\r\n if (rowCells + cw > w && i > rowStart) {\r\n // The overflowing character IS a space: break right here and\r\n // swallow it — the row before it fit exactly.\r\n if (ch === ' ') {\r\n pushRow(i, false, i + 1);\r\n rowCells = 0;\r\n i++;\r\n continue;\r\n }\r\n // Overflow: wrap at the last space if the row has one, else here.\r\n if (lastSpace > rowStart) {\r\n pushRow(lastSpace, false, lastSpace + 1); // the space is swallowed by the wrap\r\n } else {\r\n pushRow(i, false, i);\r\n }\r\n // Recompute cells for the (possibly re-started) row up to i.\r\n rowCells = 0;\r\n for (let j = rowStart; j < i; j++) {\r\n rowCells += charWidth(chars[j].codePointAt(0) ?? 0);\r\n }\r\n continue; // re-process chars[i] against the new row\r\n }\r\n if (ch === ' ') lastSpace = i;\r\n rowCells += cw;\r\n i++;\r\n }\r\n rows.push({ text: chars.slice(rowStart).join(''), start: rowStart, end: chars.length, hard: true });\r\n return { rows, width: w };\r\n}\r\n\r\n/**\r\n * Map a cursor (code-point index) to its visual row and column (cells).\r\n * A cursor sitting exactly on a soft-wrap boundary maps to the start of the\r\n * NEXT row — except at the very end of the text, where it stays on the last.\r\n */\r\nexport function cursorToRowCol(layout: TextLayout, cursor: number): { row: number; col: number } {\r\n const rows = layout.rows;\r\n for (let r = 0; r < rows.length; r++) {\r\n const row = rows[r];\r\n const isLast = r === rows.length - 1;\r\n const next = rows[r + 1];\r\n // cursor === row.end belongs to THIS row unless the next row starts\r\n // exactly there (a pure soft wrap, where the boundary cursor renders\r\n // at the start of the next row). A wrap that swallowed a space leaves\r\n // next.start === row.end + 1, so the on-the-space cursor stays here.\r\n const within = cursor >= row.start && (\r\n cursor < row.end ||\r\n (cursor === row.end && (isLast || next.start !== row.end)) ||\r\n (isLast && cursor >= row.end)\r\n );\r\n if (!within) continue;\r\n let col = 0;\r\n const chars = cps(row.text);\r\n const upto = Math.min(cursor - row.start, chars.length);\r\n for (let j = 0; j < upto; j++) {\r\n col += charWidth(chars[j].codePointAt(0) ?? 0);\r\n }\r\n return { row: r, col };\r\n }\r\n const last = rows.length - 1;\r\n return { row: last, col: cps(rows[last].text).reduce((c, ch) => c + charWidth(ch.codePointAt(0) ?? 0), 0) };\r\n}\r\n\r\n/**\r\n * Map a visual (row, goalCol) back to a cursor index. A goal column landing\r\n * inside a wide glyph snaps to the glyph start; beyond the row end clamps to\r\n * the row end.\r\n */\r\nexport function rowColToCursor(layout: TextLayout, row: number, goalCol: number): number {\r\n const r = layout.rows[Math.max(0, Math.min(row, layout.rows.length - 1))];\r\n const chars = cps(r.text);\r\n let col = 0;\r\n for (let j = 0; j < chars.length; j++) {\r\n const cw = charWidth(chars[j].codePointAt(0) ?? 0);\r\n if (col + cw > goalCol) return r.start + j;\r\n col += cw;\r\n }\r\n return r.end;\r\n}\r\n\r\nexport function insertAt(state: TextBufferState, chunk: string): TextBufferState {\r\n const chars = cps(state.text);\r\n const at = Math.max(0, Math.min(state.cursor, chars.length));\r\n const text = chars.slice(0, at).join('') + chunk + chars.slice(at).join('');\r\n return { text, cursor: at + cps(chunk).length };\r\n}\r\n\r\n/** Backspace: delete the code point before the cursor. */\r\nexport function deleteBefore(state: TextBufferState): TextBufferState {\r\n const chars = cps(state.text);\r\n const at = Math.max(0, Math.min(state.cursor, chars.length));\r\n if (at === 0) return state;\r\n return { text: chars.slice(0, at - 1).join('') + chars.slice(at).join(''), cursor: at - 1 };\r\n}\r\n\r\n/** Forward delete: delete the code point under the cursor. */\r\nexport function deleteAt(state: TextBufferState): TextBufferState {\r\n const chars = cps(state.text);\r\n const at = Math.max(0, Math.min(state.cursor, chars.length));\r\n if (at >= chars.length) return state;\r\n return { text: chars.slice(0, at).join('') + chars.slice(at + 1).join(''), cursor: at };\r\n}\r\n\r\nexport function moveLeft(state: TextBufferState): TextBufferState {\r\n return { ...state, cursor: Math.max(0, state.cursor - 1) };\r\n}\r\n\r\nexport function moveRight(state: TextBufferState): TextBufferState {\r\n return { ...state, cursor: Math.min(cps(state.text).length, state.cursor + 1) };\r\n}\r\n\r\n/**\r\n * Move the cursor a visual row up (-1) or down (+1), keeping a sticky goal\r\n * column: pass the previous call's `goalCol` back in while the user keeps\r\n * moving vertically (any horizontal move/edit resets it — caller's job).\r\n */\r\nexport function moveVertical(\r\n state: TextBufferState,\r\n width: number,\r\n dir: -1 | 1,\r\n goalCol?: number,\r\n): { state: TextBufferState; goalCol: number } {\r\n const layout = layoutText(state.text, width);\r\n const { row, col } = cursorToRowCol(layout, state.cursor);\r\n const goal = goalCol !== undefined && goalCol >= 0 ? goalCol : col;\r\n const targetRow = row + dir;\r\n if (targetRow < 0 || targetRow >= layout.rows.length) {\r\n return { state, goalCol: goal };\r\n }\r\n return { state: { ...state, cursor: rowColToCursor(layout, targetRow, goal) }, goalCol: goal };\r\n}\r\n\r\n/** Jump to the start of the cursor's visual row. */\r\nexport function moveLineStart(state: TextBufferState, width: number): TextBufferState {\r\n const layout = layoutText(state.text, width);\r\n const { row } = cursorToRowCol(layout, state.cursor);\r\n return { ...state, cursor: layout.rows[row].start };\r\n}\r\n\r\n/** Jump to the end of the cursor's visual row. */\r\nexport function moveLineEnd(state: TextBufferState, width: number): TextBufferState {\r\n const layout = layoutText(state.text, width);\r\n const { row } = cursorToRowCol(layout, state.cursor);\r\n return { ...state, cursor: layout.rows[row].end };\r\n}\r\n","/**\r\n * Reactive view/navigation stack — the headless half of screen navigation.\r\n * Push a view (a settings page, a model picker), pop back with Esc:\r\n *\r\n * const views = createViewStack<'shell' | 'model'>('shell');\r\n * onKey((key) => {\r\n * if (isEsc(key) && views.depth() > 1) {\r\n * views.pop();\r\n * return true; // consume — nothing below sees Esc\r\n * }\r\n * }, { layer: 'view' });\r\n * // render: views.current() === 'model' ? <ModelPicker/> : <Shell/>\r\n */\r\nimport { signal } from '@sigx/reactivity';\r\n\r\nexport interface ViewStack<T> {\r\n push(view: T): void;\r\n /** Pop the current view. Returns false (and stays) at the root. */\r\n pop(): boolean;\r\n /** Swap the current view without growing the stack. */\r\n replace(view: T): void;\r\n /** The top of the stack. Reactive. */\r\n current(): T;\r\n /** Stack size (root = 1). Reactive. */\r\n depth(): number;\r\n}\r\n\r\nexport function createViewStack<T>(root: T): ViewStack<T> {\r\n // The array is replaced wholesale on every mutation so signal subscribers\r\n // re-run reliably.\r\n const state = signal({ stack: [root] as T[] });\r\n\r\n return {\r\n push(view: T) {\r\n state.stack = [...state.stack, view];\r\n },\r\n pop(): boolean {\r\n if (state.stack.length <= 1) return false;\r\n state.stack = state.stack.slice(0, -1);\r\n return true;\r\n },\r\n replace(view: T) {\r\n state.stack = [...state.stack.slice(0, -1), view];\r\n },\r\n current(): T {\r\n return state.stack[state.stack.length - 1];\r\n },\r\n depth(): number {\r\n return state.stack.length;\r\n },\r\n };\r\n}\r\n","/**\r\n * Terminal QR code generator.\r\n *\r\n * Generates a QR code using Unicode block characters for display\r\n * in the terminal. Zero dependencies — implements QR encoding inline\r\n * (byte mode, versions 1–20, error-correction level L, half-block\r\n * rendering: two QR rows per terminal row).\r\n *\r\n * Extracted from @sigx/lynx-cli (packages/lynx-cli/src/qr.ts) — keep the two\r\n * in sync until lynx-cli imports `generateQR` from @sigx/terminal-zero.\r\n */\r\nimport { Buffer } from 'node:buffer';\r\n\r\n// QR code encoding constants\r\nconst MODE_BYTE = 0b0100;\r\nconst EC_LEVEL_L = 0; // ~7% error correction (sufficient for URLs on clean channel)\r\n\r\n// Version capacities for byte mode, EC level L\r\nconst VERSION_CAPACITIES: number[] = [\r\n 0, 17, 32, 53, 78, 106, 134, 154, 192, 230, 271,\r\n 321, 367, 425, 458, 520, 586, 644, 718, 792, 858,\r\n];\r\n\r\n// Error correction codewords per block for each version (EC level L)\r\nconst EC_CODEWORDS_PER_BLOCK: number[] = [\r\n 0, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18,\r\n 20, 24, 26, 30, 22, 24, 28, 30, 28, 28,\r\n];\r\n\r\n// Number of EC blocks for each version (EC level L). Source: ISO/IEC 18004\r\n// Table 9. Previously the V10–V20 counts were truncated to 4, which produced\r\n// codes that visually parsed but didn't decode in commercial scanners.\r\nconst NUM_EC_BLOCKS: number[] = [\r\n 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,\r\n 4, 4, 4, 4, 6, 6, 6, 6, 7, 8,\r\n];\r\n\r\n// Total codewords per version (data + EC). Fixed by the QR spec — the\r\n// previous \"size² minus function modules / 8\" formula was off by a few\r\n// codewords per version, which threw off data placement so ML Kit /\r\n// commercial scanners couldn't decode the result. Source: ISO/IEC 18004\r\n// Table 1. Length must match VERSION_CAPACITIES.length (21).\r\nconst TOTAL_CODEWORDS: number[] = [\r\n 0, 26, 44, 70, 100, 134, 172, 196, 242, 292, 346,\r\n 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,\r\n];\r\n\r\n// Alignment pattern positions for each version\r\nconst ALIGNMENT_PATTERNS: number[][] = [\r\n [], [], [6, 18], [6, 22], [6, 26], [6, 30], [6, 34],\r\n [6, 22, 38], [6, 24, 42], [6, 26, 46], [6, 28, 50],\r\n [6, 30, 54], [6, 32, 58], [6, 34, 62], [6, 26, 46, 66],\r\n [6, 26, 48, 70], [6, 26, 50, 74], [6, 30, 54, 78],\r\n [6, 30, 56, 82], [6, 30, 58, 86], [6, 34, 62, 90],\r\n];\r\n\r\n// Format info bits for EC level L, masks 0-7\r\nconst FORMAT_INFO: number[] = [\r\n 0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976,\r\n];\r\n\r\n// Version info bits for versions 7+\r\nconst VERSION_INFO: number[] = [\r\n 0, 0, 0, 0, 0, 0, 0,\r\n 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847,\r\n 0x0e60d, 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6,\r\n];\r\n\r\nclass BitBuffer {\r\n private buffer: number[] = [];\r\n private length = 0;\r\n\r\n put(num: number, bitLength: number) {\r\n for (let i = bitLength - 1; i >= 0; i--) {\r\n this.buffer.push((num >> i) & 1);\r\n this.length++;\r\n }\r\n }\r\n\r\n getBit(index: number): number {\r\n return this.buffer[index];\r\n }\r\n\r\n getLength(): number {\r\n return this.length;\r\n }\r\n\r\n getBuffer(): number[] {\r\n return this.buffer;\r\n }\r\n}\r\n\r\n// GF(256) arithmetic for Reed-Solomon\r\nconst GF_EXP = new Uint8Array(512);\r\nconst GF_LOG = new Uint8Array(256);\r\n\r\n(function initGaloisField() {\r\n let x = 1;\r\n for (let i = 0; i < 255; i++) {\r\n GF_EXP[i] = x;\r\n GF_LOG[x] = i;\r\n x = x << 1;\r\n if (x >= 256) x ^= 0x11d;\r\n }\r\n for (let i = 255; i < 512; i++) {\r\n GF_EXP[i] = GF_EXP[i - 255];\r\n }\r\n})();\r\n\r\nfunction gfMultiply(a: number, b: number): number {\r\n if (a === 0 || b === 0) return 0;\r\n return GF_EXP[GF_LOG[a] + GF_LOG[b]];\r\n}\r\n\r\nfunction rsEncode(data: number[], ecCount: number): number[] {\r\n // Build generator polynomial\r\n const gen = new Uint8Array(ecCount + 1);\r\n gen[0] = 1;\r\n for (let i = 0; i < ecCount; i++) {\r\n for (let j = ecCount; j >= 1; j--) {\r\n gen[j] = gen[j] ^ gfMultiply(gen[j - 1], GF_EXP[i]);\r\n }\r\n }\r\n\r\n const msg = new Uint8Array(data.length + ecCount);\r\n for (let i = 0; i < data.length; i++) msg[i] = data[i];\r\n\r\n for (let i = 0; i < data.length; i++) {\r\n const coef = msg[i];\r\n if (coef !== 0) {\r\n for (let j = 1; j <= ecCount; j++) {\r\n msg[i + j] ^= gfMultiply(gen[j], coef);\r\n }\r\n }\r\n }\r\n\r\n return Array.from(msg.slice(data.length));\r\n}\r\n\r\nfunction getVersion(dataLength: number): number {\r\n for (let v = 1; v <= 20; v++) {\r\n if (VERSION_CAPACITIES[v] >= dataLength) return v;\r\n }\r\n throw new Error('Data too long for QR code (max ~850 bytes)');\r\n}\r\n\r\nfunction getSize(version: number): number {\r\n return 17 + version * 4;\r\n}\r\n\r\nfunction createMatrix(size: number): (boolean | null)[][] {\r\n return Array.from({ length: size }, () => Array(size).fill(null));\r\n}\r\n\r\nfunction setModule(matrix: (boolean | null)[][], row: number, col: number, value: boolean) {\r\n if (row >= 0 && row < matrix.length && col >= 0 && col < matrix.length) {\r\n matrix[row][col] = value;\r\n }\r\n}\r\n\r\nfunction addFinderPattern(matrix: (boolean | null)[][], row: number, col: number) {\r\n for (let r = -1; r <= 7; r++) {\r\n for (let c = -1; c <= 7; c++) {\r\n const inOuter = r >= 0 && r <= 6 && c >= 0 && c <= 6;\r\n const inInner = r >= 2 && r <= 4 && c >= 2 && c <= 4;\r\n const onBorder = r === 0 || r === 6 || c === 0 || c === 6;\r\n const val = inOuter && (onBorder || inInner);\r\n setModule(matrix, row + r, col + c, val);\r\n }\r\n }\r\n}\r\n\r\nfunction addAlignmentPattern(matrix: (boolean | null)[][], row: number, col: number) {\r\n for (let r = -2; r <= 2; r++) {\r\n for (let c = -2; c <= 2; c++) {\r\n const val = Math.abs(r) === 2 || Math.abs(c) === 2 || (r === 0 && c === 0);\r\n if (matrix[row + r][col + c] === null) {\r\n matrix[row + r][col + c] = val;\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction addTimingPatterns(matrix: (boolean | null)[][]) {\r\n const size = matrix.length;\r\n for (let i = 8; i < size - 8; i++) {\r\n const val = i % 2 === 0;\r\n if (matrix[6][i] === null) matrix[6][i] = val;\r\n if (matrix[i][6] === null) matrix[i][6] = val;\r\n }\r\n}\r\n\r\nfunction reserveFormatArea(matrix: (boolean | null)[][]) {\r\n const size = matrix.length;\r\n // Around top-left finder\r\n for (let i = 0; i <= 8; i++) {\r\n if (matrix[8][i] === null) matrix[8][i] = false;\r\n if (matrix[i][8] === null) matrix[i][8] = false;\r\n }\r\n // Around top-right finder\r\n for (let i = 0; i <= 7; i++) {\r\n if (matrix[8][size - 1 - i] === null) matrix[8][size - 1 - i] = false;\r\n }\r\n // Around bottom-left finder\r\n for (let i = 0; i <= 7; i++) {\r\n if (matrix[size - 1 - i][8] === null) matrix[size - 1 - i][8] = false;\r\n }\r\n // Dark module\r\n matrix[size - 8][8] = true;\r\n}\r\n\r\nfunction addFormatInfo(matrix: (boolean | null)[][], maskPattern: number) {\r\n const size = matrix.length;\r\n const bits = FORMAT_INFO[maskPattern];\r\n\r\n for (let i = 0; i <= 5; i++) {\r\n matrix[8][i] = !!((bits >> (14 - i)) & 1);\r\n }\r\n matrix[8][7] = !!((bits >> 8) & 1);\r\n matrix[8][8] = !!((bits >> 7) & 1);\r\n matrix[7][8] = !!((bits >> 6) & 1);\r\n\r\n for (let i = 0; i <= 5; i++) {\r\n matrix[5 - i][8] = !!((bits >> (i)) & 1);\r\n }\r\n\r\n for (let i = 0; i <= 7; i++) {\r\n matrix[8][size - 1 - i] = !!((bits >> i) & 1);\r\n }\r\n for (let i = 0; i <= 6; i++) {\r\n matrix[size - 1 - i][8] = !!((bits >> (14 - i)) & 1);\r\n }\r\n}\r\n\r\nfunction addVersionInfo(matrix: (boolean | null)[][], version: number) {\r\n if (version < 7) return;\r\n const size = matrix.length;\r\n const bits = VERSION_INFO[version];\r\n\r\n for (let i = 0; i < 18; i++) {\r\n const bit = !!((bits >> i) & 1);\r\n const row = Math.floor(i / 3);\r\n const col = i % 3;\r\n matrix[5 - row][size - 9 - col] = bit;\r\n matrix[size - 9 - col][5 - row] = bit;\r\n }\r\n}\r\n\r\nconst MASK_FUNCTIONS: ((row: number, col: number) => boolean)[] = [\r\n (r, c) => (r + c) % 2 === 0,\r\n (r, _) => r % 2 === 0,\r\n (_, c) => c % 3 === 0,\r\n (r, c) => (r + c) % 3 === 0,\r\n (r, c) => (Math.floor(r / 2) + Math.floor(c / 3)) % 2 === 0,\r\n (r, c) => ((r * c) % 2 + (r * c) % 3) === 0,\r\n (r, c) => ((r * c) % 2 + (r * c) % 3) % 2 === 0,\r\n (r, c) => ((r + c) % 2 + (r * c) % 3) % 2 === 0,\r\n];\r\n\r\nfunction placeData(matrix: (boolean | null)[][], bits: number[]) {\r\n const size = matrix.length;\r\n let bitIndex = 0;\r\n let upward = true;\r\n\r\n for (let right = size - 1; right >= 1; right -= 2) {\r\n if (right === 6) right = 5; // Skip timing column\r\n\r\n const rows = upward\r\n ? Array.from({ length: size }, (_, i) => size - 1 - i)\r\n : Array.from({ length: size }, (_, i) => i);\r\n\r\n for (const row of rows) {\r\n for (const col of [right, right - 1]) {\r\n if (matrix[row][col] === null) {\r\n matrix[row][col] = bitIndex < bits.length ? !!bits[bitIndex] : false;\r\n bitIndex++;\r\n }\r\n }\r\n }\r\n upward = !upward;\r\n }\r\n}\r\n\r\nfunction applyMask(matrix: (boolean | null)[][], reserved: (boolean | null)[][], mask: number): boolean[][] {\r\n const size = matrix.length;\r\n const result: boolean[][] = Array.from({ length: size }, (_, r) =>\r\n Array.from({ length: size }, (_, c) => !!matrix[r][c])\r\n );\r\n\r\n const fn = MASK_FUNCTIONS[mask];\r\n for (let r = 0; r < size; r++) {\r\n for (let c = 0; c < size; c++) {\r\n if (reserved[r][c] !== null) continue; // Don't mask reserved areas\r\n if (fn(r, c)) result[r][c] = !result[r][c];\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction penaltyScore(matrix: boolean[][]): number {\r\n const size = matrix.length;\r\n let penalty = 0;\r\n\r\n // Rule 1: Runs of same color\r\n for (let r = 0; r < size; r++) {\r\n let count = 1;\r\n for (let c = 1; c < size; c++) {\r\n if (matrix[r][c] === matrix[r][c - 1]) {\r\n count++;\r\n if (count === 5) penalty += 3;\r\n else if (count > 5) penalty++;\r\n } else {\r\n count = 1;\r\n }\r\n }\r\n }\r\n for (let c = 0; c < size; c++) {\r\n let count = 1;\r\n for (let r = 1; r < size; r++) {\r\n if (matrix[r][c] === matrix[r - 1][c]) {\r\n count++;\r\n if (count === 5) penalty += 3;\r\n else if (count > 5) penalty++;\r\n } else {\r\n count = 1;\r\n }\r\n }\r\n }\r\n\r\n // Rule 2: 2x2 blocks\r\n for (let r = 0; r < size - 1; r++) {\r\n for (let c = 0; c < size - 1; c++) {\r\n const v = matrix[r][c];\r\n if (v === matrix[r][c + 1] && v === matrix[r + 1][c] && v === matrix[r + 1][c + 1]) {\r\n penalty += 3;\r\n }\r\n }\r\n }\r\n\r\n return penalty;\r\n}\r\n\r\nfunction encodeQR(data: string): boolean[][] {\r\n const bytes = Buffer.from(data, 'utf-8');\r\n const version = getVersion(bytes.length);\r\n const size = getSize(version);\r\n const ecPerBlock = EC_CODEWORDS_PER_BLOCK[version];\r\n const numBlocks = NUM_EC_BLOCKS[version];\r\n const totalCodewords = TOTAL_CODEWORDS[version];\r\n\r\n // Build data bits\r\n const bitBuf = new BitBuffer();\r\n bitBuf.put(MODE_BYTE, 4);\r\n bitBuf.put(bytes.length, version <= 9 ? 8 : 16);\r\n for (let i = 0; i < bytes.length; i++) {\r\n bitBuf.put(bytes[i], 8);\r\n }\r\n\r\n // Total data codewords\r\n const dataCodewords = totalCodewords - ecPerBlock * numBlocks;\r\n\r\n // Pad to fill data capacity\r\n const targetBits = dataCodewords * 8;\r\n if (bitBuf.getLength() < targetBits) {\r\n bitBuf.put(0, Math.min(4, targetBits - bitBuf.getLength()));\r\n }\r\n while (bitBuf.getLength() % 8 !== 0) {\r\n bitBuf.put(0, 1);\r\n }\r\n const padBytes = [0xEC, 0x11];\r\n let padIdx = 0;\r\n while (bitBuf.getLength() < targetBits) {\r\n bitBuf.put(padBytes[padIdx % 2], 8);\r\n padIdx++;\r\n }\r\n\r\n // Convert to codewords\r\n const dataWords: number[] = [];\r\n const buf = bitBuf.getBuffer();\r\n for (let i = 0; i < dataCodewords; i++) {\r\n let byte = 0;\r\n for (let j = 0; j < 8; j++) {\r\n byte = (byte << 1) | (buf[i * 8 + j] || 0);\r\n }\r\n dataWords.push(byte);\r\n }\r\n\r\n // Split into blocks and compute EC\r\n const blockSize = Math.floor(dataCodewords / numBlocks);\r\n const longBlocks = dataCodewords % numBlocks;\r\n const dataBlocks: number[][] = [];\r\n const ecBlocks: number[][] = [];\r\n\r\n let offset = 0;\r\n for (let i = 0; i < numBlocks; i++) {\r\n const bSize = blockSize + (i >= numBlocks - longBlocks ? 1 : 0);\r\n const block = dataWords.slice(offset, offset + bSize);\r\n dataBlocks.push(block);\r\n ecBlocks.push(rsEncode(block, ecPerBlock));\r\n offset += bSize;\r\n }\r\n\r\n // Interleave\r\n const allBits: number[] = [];\r\n const maxDataLen = Math.max(...dataBlocks.map(b => b.length));\r\n for (let i = 0; i < maxDataLen; i++) {\r\n for (const block of dataBlocks) {\r\n if (i < block.length) {\r\n for (let j = 7; j >= 0; j--) {\r\n allBits.push((block[i] >> j) & 1);\r\n }\r\n }\r\n }\r\n }\r\n for (let i = 0; i < ecPerBlock; i++) {\r\n for (const block of ecBlocks) {\r\n if (i < block.length) {\r\n for (let j = 7; j >= 0; j--) {\r\n allBits.push((block[i] >> j) & 1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Build matrix with reserved areas\r\n const reserved = createMatrix(size);\r\n addFinderPattern(reserved, 0, 0);\r\n addFinderPattern(reserved, 0, size - 7);\r\n addFinderPattern(reserved, size - 7, 0);\r\n addTimingPatterns(reserved);\r\n reserveFormatArea(reserved);\r\n\r\n const positions = ALIGNMENT_PATTERNS[version] || [];\r\n for (let i = 0; i < positions.length; i++) {\r\n for (let j = 0; j < positions.length; j++) {\r\n const r = positions[i], c = positions[j];\r\n if (reserved[r]?.[c] !== null) continue;\r\n addAlignmentPattern(reserved, r, c);\r\n }\r\n }\r\n\r\n // Place data on a copy\r\n const matrix = reserved.map(row => [...row]);\r\n placeData(matrix, allBits);\r\n\r\n // Try all masks, pick best\r\n let bestMask = 0;\r\n let bestPenalty = Infinity;\r\n for (let m = 0; m < 8; m++) {\r\n const masked = applyMask(matrix, reserved, m);\r\n const p = penaltyScore(masked);\r\n if (p < bestPenalty) {\r\n bestPenalty = p;\r\n bestMask = m;\r\n }\r\n }\r\n\r\n const result = applyMask(matrix, reserved, bestMask);\r\n\r\n // Write format & version info\r\n const fmtMatrix = createMatrix(size);\r\n addFinderPattern(fmtMatrix, 0, 0);\r\n addFinderPattern(fmtMatrix, 0, size - 7);\r\n addFinderPattern(fmtMatrix, size - 7, 0);\r\n addTimingPatterns(fmtMatrix);\r\n addFormatInfo(fmtMatrix, bestMask);\r\n addVersionInfo(fmtMatrix, version);\r\n\r\n // Overlay format/version info onto result\r\n for (let r = 0; r < size; r++) {\r\n for (let c = 0; c < size; c++) {\r\n if (reserved[r][c] !== null) {\r\n result[r][c] = !!fmtMatrix[r][c];\r\n }\r\n }\r\n }\r\n\r\n addFormatInfo(result as any, bestMask);\r\n if (version >= 7) addVersionInfo(result as any, version);\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Generate a QR code string for terminal display.\r\n * Uses Unicode half-block characters (▀▄█ ) to render 2 rows per line.\r\n *\r\n * @param text - The text/URL to encode\r\n * @param opts - Options: quiet zone width, colors\r\n * @returns Multi-line string ready for console.log()\r\n */\r\nexport function generateQR(text: string, opts?: { quiet?: number; invert?: boolean }): string {\r\n // Quiet zone: ISO/IEC 18004 requires at least 4 modules of white border\r\n // around the matrix. The previous default of 2 made finder-pattern\r\n // detection slow — scanners would burn many frames before lock-on.\r\n const quiet = opts?.quiet ?? 4;\r\n const invert = opts?.invert ?? false;\r\n\r\n let matrix: boolean[][];\r\n try {\r\n matrix = encodeQR(text);\r\n } catch {\r\n // Fallback: return a simple text representation\r\n return ` [QR: ${text}]`;\r\n }\r\n\r\n const size = matrix.length;\r\n const totalSize = size + quiet * 2;\r\n\r\n // Pad with quiet zone\r\n const getModule = (r: number, c: number): boolean => {\r\n const mr = r - quiet;\r\n const mc = c - quiet;\r\n if (mr < 0 || mr >= size || mc < 0 || mc >= size) return false;\r\n return matrix[mr][mc];\r\n };\r\n\r\n const lines: string[] = [];\r\n\r\n // Use half-block characters: each character represents 2 vertical pixels\r\n // ▀ = top half, ▄ = bottom half, █ = full, ' ' = empty\r\n const BLACK = invert ? false : true;\r\n\r\n for (let r = 0; r < totalSize; r += 2) {\r\n let line = '';\r\n for (let c = 0; c < totalSize; c++) {\r\n const top = getModule(r, c);\r\n const bottom = r + 1 < totalSize ? getModule(r + 1, c) : false;\r\n\r\n if (top === BLACK && bottom === BLACK) {\r\n line += '█';\r\n } else if (top === BLACK && bottom !== BLACK) {\r\n line += '▀';\r\n } else if (top !== BLACK && bottom === BLACK) {\r\n line += '▄';\r\n } else {\r\n line += ' ';\r\n }\r\n }\r\n lines.push(line);\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","/**\r\n * Shared, design-system-neutral utilities for terminal components: the glyph\r\n * set the SigX-tui spec standardizes on, interaction timings, and re-exports of\r\n * the renderer's focus + key APIs so skins depend only on `@sigx/terminal-zero`.\r\n */\r\n\r\n// Focus registry + keyboard input (re-exported from the renderer so skin\r\n// components have a single foundation import).\r\nexport {\r\n focusState,\r\n registerFocusable,\r\n unregisterFocusable,\r\n focus,\r\n focusNext,\r\n focusPrev,\r\n onKey,\r\n setScreenBackground,\r\n setScreenForeground,\r\n} from '@sigx/runtime-terminal';\r\n\r\n// Renderer device APIs the FX / log components build on: depth-aware SGR for\r\n// embedded gradient escapes, static output, and escape-safe measurement.\r\nexport {\r\n hexToSGR,\r\n resolveFg,\r\n getColorDepth,\r\n getOutputTarget,\r\n writeStatic,\r\n printStatic,\r\n displayWidth,\r\n truncateToWidth,\r\n} from '@sigx/runtime-terminal';\r\n\r\n// One-shot mount + key injection — what the imperative prompts layer builds\r\n// on. Re-exported here so skins keep their single foundation import.\r\nexport {\r\n renderTerminal,\r\n dispatchKey,\r\n type RenderTerminalOptions,\r\n type KeyLayer,\r\n type KeyHandler,\r\n} from '@sigx/runtime-terminal';\r\n\r\n// Cell measurement + background SGR for components that build their own\r\n// escape strings (text buffers, pixel art).\r\nexport {\r\n charWidth,\r\n resolveBg,\r\n} from '@sigx/runtime-terminal';\r\n\r\n// Reactive terminal size — read it in a render function to re-render on\r\n// resize (getOutputTarget().columns/rows are live but not reactive).\r\nexport {\r\n getTerminalSize,\r\n syncTerminalSize,\r\n} from '@sigx/runtime-terminal';\r\n\r\nexport * from './colorMath';\r\nexport * from './ticker';\r\nexport * from './textBuffer';\r\nexport * from './viewStack';\r\nexport { generateQR } from './qr';\r\n\r\n/**\r\n * Standard glyphs. All are width-1 in monospace fonts (Braille, geometric,\r\n * box-drawing) — except the status icons, which some terminals render as 2\r\n * cells; prefer them only where a trailing column is acceptable.\r\n */\r\nexport const GLYPHS = {\r\n checkboxOn: '◉',\r\n checkboxOff: '◯',\r\n radioOn: '●',\r\n radioOff: '○',\r\n cursor: '❯', // Select / menu pointer\r\n focusBar: '▌', // focused-control accent bar\r\n shadowCell: '▒', // drop shadow\r\n barFull: '█', // progress filled\r\n barEmpty: '░', // progress track\r\n // sub-cell progress edge, thinnest → widest (smooth bar leading edge)\r\n barEighths: ['▏', '▎', '▍', '▌', '▋', '▊', '▉'] as readonly string[],\r\n // status icons (may be 2 cells in some terminals)\r\n check: '✔',\r\n cross: '✖',\r\n warn: '⚠',\r\n info: 'ℹ',\r\n // spinner animation frames (Braille — always width 1)\r\n spinner: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] as readonly string[],\r\n} as const;\r\n\r\n/**\r\n * Spinner frame sets, selectable via the Spinner `variant` prop. All width-1\r\n * except `moon` (emoji — 2 cells; use where a wider glyph column is fine).\r\n */\r\nexport const SPINNERS = {\r\n dots: GLYPHS.spinner,\r\n line: ['—', '\\\\', '|', '/'],\r\n arc: ['◜', '◠', '◝', '◞', '◡', '◟'],\r\n circle: ['◐', '◓', '◑', '◒'],\r\n bounce: ['▁', '▃', '▄', '▅', '▆', '▇', '▆', '▅', '▄', '▃'],\r\n moon: ['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘'],\r\n} as const satisfies Record<string, readonly string[]>;\r\n\r\nexport type SpinnerVariant = keyof typeof SPINNERS;\r\n\r\n/** Milliseconds a button stays in its visual \"pressed\" state after activation. */\r\nexport const PRESS_MS = 120;\r\n\r\n/** Milliseconds to ignore input after mount (debounces the activating Enter). */\r\nexport const READY_DELAY_MS = 50;\r\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type Theme } from '../contract';
2
+ /** Register (or replace) a theme. The first registered theme becomes active. */
3
+ export declare function registerTheme(id: string, theme: Theme): void;
4
+ /** Switch the active theme. Throws on an unknown id. */
5
+ export declare function setTheme(id: string): void;
6
+ /** The active theme id (reactive). */
7
+ export declare function getTheme(): string;
8
+ /** The active theme object (reactive). */
9
+ export declare function getActiveTheme(): Theme;
10
+ /** Whether a theme id is registered. */
11
+ export declare function hasTheme(id: string): boolean;
12
+ /** All registered theme ids. */
13
+ export declare function listThemes(): string[];
14
+ /**
15
+ * Resolve a token (or raw `#hex`) to a concrete color string for the renderer.
16
+ * Reactive: re-reads the active theme + color depth on every call.
17
+ */
18
+ export declare function resolveColor(token: string | undefined): string;
19
+ /**
20
+ * Bind the renderer's screen canvas (background + default foreground) to the
21
+ * active theme. Reactive: it re-applies whenever the theme or color depth
22
+ * changes. Idempotent — calling it again returns the same stop function.
23
+ *
24
+ * Design-system packages call this on import so apps get a legible themed canvas
25
+ * automatically (especially light themes on a dark terminal). Returns a function
26
+ * that stops the binding (see also `disableThemeCanvas`).
27
+ */
28
+ export declare function applyThemeCanvas(): () => void;
29
+ /**
30
+ * Stop the theme→canvas binding and clear the canvas, so the terminal's own
31
+ * background shows through (for transparent / inline apps that don't want a
32
+ * themed canvas).
33
+ */
34
+ export declare function disableThemeCanvas(): void;
@@ -0,0 +1,71 @@
1
+ import { ANSI_NAMES as e, FALLBACK_ALIAS as t } from "../contract.js";
2
+ import { effect as n, signal as r } from "@sigx/reactivity";
3
+ import { getColorDepth as i, setScreenBackground as a, setScreenForeground as o } from "@sigx/runtime-terminal";
4
+ //#region src/theme/index.ts
5
+ var s = {}, c = r({ active: "" }), l = {
6
+ name: "Neutral",
7
+ mode: "dark",
8
+ bg: "#000000",
9
+ panel: "#0a0a0a",
10
+ chrome: "#000000",
11
+ line: "#3a3a3a",
12
+ fg: "#d0d0d0",
13
+ dim: "#808080",
14
+ faint: "#4a4a4a",
15
+ shadow: "#000000",
16
+ accent: "#5fafff",
17
+ accentSoft: "#1c2733",
18
+ accentText: "#000000",
19
+ selSoft: "#1a1f26",
20
+ success: "#5faf5f",
21
+ warn: "#d7af5f",
22
+ danger: "#d75f5f",
23
+ info: "#5fafd7",
24
+ black: "#000000",
25
+ red: "#d75f5f",
26
+ green: "#5faf5f",
27
+ yellow: "#d7af5f",
28
+ blue: "#5fafff",
29
+ magenta: "#af5fd7",
30
+ cyan: "#5fd7d7",
31
+ white: "#d0d0d0"
32
+ };
33
+ function u(e, t) {
34
+ s[e] = t, c.active ||= e;
35
+ }
36
+ u("neutral", l);
37
+ function d(e) {
38
+ if (!s[e]) throw Error(`Unknown theme: ${e}`);
39
+ c.active = e;
40
+ }
41
+ function f() {
42
+ return c.active;
43
+ }
44
+ function p() {
45
+ return s[c.active] ?? l;
46
+ }
47
+ function m(e) {
48
+ return !!s[e];
49
+ }
50
+ function h() {
51
+ return Object.keys(s);
52
+ }
53
+ function g(n) {
54
+ if (!n) return "";
55
+ if (n[0] === "#") return n;
56
+ let r = p();
57
+ return i() === "ansi16" ? e.has(n) ? n : t[n] ?? "white" : r[n] ?? n;
58
+ }
59
+ var _ = null;
60
+ function v() {
61
+ return _ ||= n(() => {
62
+ a(g("bg")), o(g("fg"));
63
+ }), y;
64
+ }
65
+ function y() {
66
+ _ &&= (_.stop?.(), null), a(void 0), o(void 0);
67
+ }
68
+ //#endregion
69
+ export { v as applyThemeCanvas, y as disableThemeCanvas, p as getActiveTheme, f as getTheme, m as hasTheme, h as listThemes, u as registerTheme, g as resolveColor, d as setTheme };
70
+
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/theme/index.ts"],"sourcesContent":["/**\r\n * The theme engine — the semantic half of the token pipeline.\r\n *\r\n * Owns the theme registry, the active-theme signal, and `resolveColor()`, which\r\n * turns a token into a concrete color string the renderer can paint:\r\n * - truecolor / 256-color terminals → the theme's hex (renderer quantizes 256)\r\n * - 16-color terminals → the `FALLBACK_ALIAS` ANSI name\r\n * It reads the renderer's detected color depth (`getColorDepth`) but never emits\r\n * SGR itself — that's the renderer's device half. Reads of the active-theme and\r\n * color-depth signals are reactive, so `setTheme()` / `setColorDepth()` repaint\r\n * any component that resolved a token during render.\r\n */\r\nimport { signal, effect, type EffectRunner } from '@sigx/reactivity';\r\nimport { getColorDepth, setScreenBackground, setScreenForeground } from '@sigx/runtime-terminal';\r\nimport { ANSI_NAMES, FALLBACK_ALIAS, type Theme } from '../contract';\r\n\r\nconst themes: Record<string, Theme> = {};\r\n\r\n// Reactive active-theme id. Empty until the first theme registers.\r\nconst themeState = signal({ active: '' });\r\n\r\n/**\r\n * A minimal neutral theme so the foundation is usable standalone, before any\r\n * design-system skin registers its palettes. Skins (e.g. @sigx/terminal-ui)\r\n * register richer themes and switch the default.\r\n */\r\nconst neutral: Theme = {\r\n name: 'Neutral', mode: 'dark',\r\n bg: '#000000', panel: '#0a0a0a', chrome: '#000000', line: '#3a3a3a',\r\n fg: '#d0d0d0', dim: '#808080', faint: '#4a4a4a', shadow: '#000000',\r\n accent: '#5fafff', accentSoft: '#1c2733', accentText: '#000000', selSoft: '#1a1f26',\r\n success: '#5faf5f', warn: '#d7af5f', danger: '#d75f5f', info: '#5fafd7',\r\n black: '#000000', red: '#d75f5f', green: '#5faf5f', yellow: '#d7af5f',\r\n blue: '#5fafff', magenta: '#af5fd7', cyan: '#5fd7d7', white: '#d0d0d0',\r\n};\r\n\r\n/** Register (or replace) a theme. The first registered theme becomes active. */\r\nexport function registerTheme(id: string, theme: Theme): void {\r\n themes[id] = theme;\r\n if (!themeState.active) themeState.active = id;\r\n}\r\n\r\nregisterTheme('neutral', neutral);\r\n\r\n/** Switch the active theme. Throws on an unknown id. */\r\nexport function setTheme(id: string): void {\r\n if (!themes[id]) throw new Error(`Unknown theme: ${id}`);\r\n themeState.active = id;\r\n}\r\n\r\n/** The active theme id (reactive). */\r\nexport function getTheme(): string {\r\n return themeState.active;\r\n}\r\n\r\n/** The active theme object (reactive). */\r\nexport function getActiveTheme(): Theme {\r\n return themes[themeState.active] ?? neutral;\r\n}\r\n\r\n/** Whether a theme id is registered. */\r\nexport function hasTheme(id: string): boolean {\r\n return !!themes[id];\r\n}\r\n\r\n/** All registered theme ids. */\r\nexport function listThemes(): string[] {\r\n return Object.keys(themes);\r\n}\r\n\r\n/**\r\n * Resolve a token (or raw `#hex`) to a concrete color string for the renderer.\r\n * Reactive: re-reads the active theme + color depth on every call.\r\n */\r\nexport function resolveColor(token: string | undefined): string {\r\n if (!token) return '';\r\n if (token[0] === '#') return token; // raw hex passes through\r\n const theme = getActiveTheme(); // tracks active-theme signal\r\n const depth = getColorDepth(); // tracks color-depth signal\r\n\r\n if (depth === 'ansi16') {\r\n // Degrade to a 16-color ANSI name the renderer paints by name.\r\n if (ANSI_NAMES.has(token)) return token;\r\n return FALLBACK_ALIAS[token] ?? 'white';\r\n }\r\n\r\n // truecolor / 256 / none: hand the renderer the theme hex (it quantizes/skips).\r\n const hex = (theme as unknown as Record<string, string>)[token];\r\n return hex ?? token;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Theme canvas — auto-paint the renderer's screen background + default\r\n// foreground from the active theme (the app-level canvas). The renderer owns\r\n// the device fill; this is the reactive binding that drives it.\r\n// ---------------------------------------------------------------------------\r\n\r\nlet canvasEffect: EffectRunner | null = null;\r\n\r\n/**\r\n * Bind the renderer's screen canvas (background + default foreground) to the\r\n * active theme. Reactive: it re-applies whenever the theme or color depth\r\n * changes. Idempotent — calling it again returns the same stop function.\r\n *\r\n * Design-system packages call this on import so apps get a legible themed canvas\r\n * automatically (especially light themes on a dark terminal). Returns a function\r\n * that stops the binding (see also `disableThemeCanvas`).\r\n */\r\nexport function applyThemeCanvas(): () => void {\r\n if (!canvasEffect) {\r\n canvasEffect = effect(() => {\r\n setScreenBackground(resolveColor('bg'));\r\n setScreenForeground(resolveColor('fg'));\r\n });\r\n }\r\n return disableThemeCanvas;\r\n}\r\n\r\n/**\r\n * Stop the theme→canvas binding and clear the canvas, so the terminal's own\r\n * background shows through (for transparent / inline apps that don't want a\r\n * themed canvas).\r\n */\r\nexport function disableThemeCanvas(): void {\r\n if (canvasEffect) {\r\n canvasEffect.stop?.();\r\n canvasEffect = null;\r\n }\r\n setScreenBackground(undefined);\r\n setScreenForeground(undefined);\r\n}\r\n"],"mappings":";;;;AAgBA,IAAM,IAAgC,EAAE,EAGlC,IAAa,EAAO,EAAE,QAAQ,IAAI,CAAC,EAOnC,IAAiB;CACnB,MAAM;CAAW,MAAM;CACvB,IAAI;CAAW,OAAO;CAAW,QAAQ;CAAW,MAAM;CAC1D,IAAI;CAAW,KAAK;CAAW,OAAO;CAAW,QAAQ;CACzD,QAAQ;CAAW,YAAY;CAAW,YAAY;CAAW,SAAS;CAC1E,SAAS;CAAW,MAAM;CAAW,QAAQ;CAAW,MAAM;CAC9D,OAAO;CAAW,KAAK;CAAW,OAAO;CAAW,QAAQ;CAC5D,MAAM;CAAW,SAAS;CAAW,MAAM;CAAW,OAAO;CAChE;AAGD,SAAgB,EAAc,GAAY,GAAoB;CAE1D,AADA,EAAO,KAAM,GACb,AAAwB,EAAW,WAAS;;AAGhD,EAAc,WAAW,EAAQ;AAGjC,SAAgB,EAAS,GAAkB;CACvC,IAAI,CAAC,EAAO,IAAK,MAAU,MAAM,kBAAkB,IAAK;CACxD,EAAW,SAAS;;AAIxB,SAAgB,IAAmB;CAC/B,OAAO,EAAW;;AAItB,SAAgB,IAAwB;CACpC,OAAO,EAAO,EAAW,WAAW;;AAIxC,SAAgB,EAAS,GAAqB;CAC1C,OAAO,CAAC,CAAC,EAAO;;AAIpB,SAAgB,IAAuB;CACnC,OAAO,OAAO,KAAK,EAAO;;AAO9B,SAAgB,EAAa,GAAmC;CAC5D,IAAI,CAAC,GAAO,OAAO;CACnB,IAAI,EAAM,OAAO,KAAK,OAAO;CAC7B,IAAM,IAAQ,GAAgB;CAW9B,OAVc,GAEV,KAAU,WAEN,EAAW,IAAI,EAAM,GAAS,IAC3B,EAAe,MAAU,UAIvB,EAA4C,MAC3C;;AASlB,IAAI,IAAoC;AAWxC,SAAgB,IAA+B;CAO3C,OANA,AACI,MAAe,QAAa;EAExB,AADA,EAAoB,EAAa,KAAK,CAAC,EACvC,EAAoB,EAAa,KAAK,CAAC;GACzC,EAEC;;AAQX,SAAgB,IAA2B;CAMvC,AALA,AAEI,OADA,EAAa,QAAQ,EACN,OAEnB,EAAoB,KAAA,EAAU,EAC9B,EAAoB,KAAA,EAAU"}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@sigx/terminal-zero",
3
+ "version": "0.5.0",
4
+ "description": "Headless, design-system-neutral foundation for SignalX terminal UIs — token contract, theme engine, and layout primitives",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./contract": {
14
+ "import": "./dist/contract.js",
15
+ "types": "./dist/contract.d.ts"
16
+ },
17
+ "./theme": {
18
+ "import": "./dist/theme/index.js",
19
+ "types": "./dist/theme/index.d.ts"
20
+ },
21
+ "./shared": {
22
+ "import": "./dist/shared/index.js",
23
+ "types": "./dist/shared/index.d.ts"
24
+ },
25
+ "./layout": {
26
+ "import": "./dist/layout/index.js",
27
+ "types": "./dist/layout/index.d.ts"
28
+ },
29
+ "./prompts": {
30
+ "import": "./dist/prompts/index.js",
31
+ "types": "./dist/prompts/index.d.ts"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "keywords": [
38
+ "sigx",
39
+ "signalx",
40
+ "terminal",
41
+ "tui",
42
+ "cli",
43
+ "design-system",
44
+ "theme"
45
+ ],
46
+ "author": "Andreas Ekdahl",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/signalxjs/terminal.git",
51
+ "directory": "packages/terminal-zero"
52
+ },
53
+ "homepage": "https://github.com/signalxjs/terminal/tree/main/packages/terminal-zero",
54
+ "bugs": {
55
+ "url": "https://github.com/signalxjs/terminal/issues"
56
+ },
57
+ "dependencies": {
58
+ "@sigx/reactivity": "^0.4.9",
59
+ "@sigx/runtime-core": "^0.4.9",
60
+ "@sigx/runtime-terminal": "^0.5.0"
61
+ },
62
+ "devDependencies": {
63
+ "@sigx/vite": "^0.4.7",
64
+ "@types/node": "^22.0.0",
65
+ "typescript": "^5.9.3",
66
+ "vite": "^8.0.3"
67
+ },
68
+ "publishConfig": {
69
+ "access": "public"
70
+ },
71
+ "scripts": {
72
+ "build": "vite build && tsgo --emitDeclarationOnly",
73
+ "dev": "vite build --watch"
74
+ }
75
+ }