@promptctl/rich-js 0.18.0 → 0.18.1
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/dist/core/anchor.d.ts +45 -0
- package/dist/core/anchor.js +39 -0
- package/dist/core/ansi.d.ts +65 -0
- package/dist/core/ansi.js +231 -0
- package/dist/core/box.d.ts +143 -0
- package/dist/core/box.js +379 -0
- package/dist/core/cells.d.ts +159 -0
- package/dist/core/cells.js +287 -0
- package/dist/core/color.d.ts +246 -0
- package/dist/core/color.js +1038 -0
- package/dist/core/console.d.ts +165 -0
- package/dist/core/console.js +527 -0
- package/dist/core/emoji.d.ts +24 -0
- package/dist/core/emoji.js +391 -0
- package/dist/core/export-html.d.ts +59 -0
- package/dist/core/export-html.js +200 -0
- package/dist/core/export-lines.d.ts +121 -0
- package/dist/core/export-lines.js +141 -0
- package/dist/core/highlighter.d.ts +33 -0
- package/dist/core/highlighter.js +124 -0
- package/dist/core/json.d.ts +27 -0
- package/dist/core/json.js +53 -0
- package/dist/core/markup.d.ts +119 -0
- package/dist/core/markup.js +731 -0
- package/dist/core/measure.d.ts +27 -0
- package/dist/core/measure.js +62 -0
- package/dist/core/oklch.d.ts +161 -0
- package/dist/core/oklch.js +312 -0
- package/dist/core/osc8.d.ts +68 -0
- package/dist/core/osc8.js +90 -0
- package/dist/core/place.d.ts +30 -0
- package/dist/core/place.js +51 -0
- package/dist/core/pretty.d.ts +144 -0
- package/dist/core/pretty.js +476 -0
- package/dist/core/protocol.d.ts +267 -0
- package/dist/core/protocol.js +163 -0
- package/dist/core/render.d.ts +84 -0
- package/dist/core/render.js +145 -0
- package/dist/core/segment.d.ts +161 -0
- package/dist/core/segment.js +492 -0
- package/dist/core/spinnerData.d.ts +12 -0
- package/dist/core/spinnerData.js +117 -0
- package/dist/core/strip.d.ts +141 -0
- package/dist/core/strip.js +305 -0
- package/dist/core/style.d.ts +169 -0
- package/dist/core/style.js +695 -0
- package/dist/core/subscription.d.ts +12 -0
- package/dist/core/subscription.js +12 -0
- package/dist/core/text.d.ts +256 -0
- package/dist/core/text.js +976 -0
- package/dist/core/wrap.d.ts +41 -0
- package/dist/core/wrap.js +127 -0
- package/dist/host/app.d.ts +121 -0
- package/dist/host/app.js +255 -0
- package/dist/host/host-environment.d.ts +26 -0
- package/dist/host/host-environment.js +44 -0
- package/dist/host/index.d.ts +5 -0
- package/dist/host/index.js +3 -0
- package/dist/host/terminal-host.d.ts +179 -0
- package/dist/host/terminal-host.js +186 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.js +107 -0
- package/dist/node/prompt.d.ts +21 -0
- package/dist/node/prompt.js +30 -0
- package/dist/node/save.d.ts +17 -0
- package/dist/node/save.js +21 -0
- package/dist/node/terminal-host.d.ts +113 -0
- package/dist/node/terminal-host.js +227 -0
- package/dist/node/traceback.d.ts +37 -0
- package/dist/node/traceback.js +134 -0
- package/dist/renderables/align.d.ts +16 -0
- package/dist/renderables/align.js +33 -0
- package/dist/renderables/columns.d.ts +61 -0
- package/dist/renderables/columns.js +152 -0
- package/dist/renderables/constrain.d.ts +15 -0
- package/dist/renderables/constrain.js +37 -0
- package/dist/renderables/embed.d.ts +50 -0
- package/dist/renderables/embed.js +71 -0
- package/dist/renderables/flexStrip.d.ts +41 -0
- package/dist/renderables/flexStrip.js +200 -0
- package/dist/renderables/group.d.ts +11 -0
- package/dist/renderables/group.js +17 -0
- package/dist/renderables/layout.d.ts +92 -0
- package/dist/renderables/layout.js +312 -0
- package/dist/renderables/live.d.ts +50 -0
- package/dist/renderables/live.js +175 -0
- package/dist/renderables/markdown.d.ts +24 -0
- package/dist/renderables/markdown.js +184 -0
- package/dist/renderables/padding.d.ts +38 -0
- package/dist/renderables/padding.js +141 -0
- package/dist/renderables/panel.d.ts +116 -0
- package/dist/renderables/panel.js +307 -0
- package/dist/renderables/progress.d.ts +90 -0
- package/dist/renderables/progress.js +238 -0
- package/dist/renderables/progressBar.d.ts +31 -0
- package/dist/renderables/progressBar.js +53 -0
- package/dist/renderables/prompt.d.ts +49 -0
- package/dist/renderables/prompt.js +125 -0
- package/dist/renderables/rule.d.ts +25 -0
- package/dist/renderables/rule.js +90 -0
- package/dist/renderables/spinner.d.ts +31 -0
- package/dist/renderables/spinner.js +70 -0
- package/dist/renderables/status.d.ts +23 -0
- package/dist/renderables/status.js +60 -0
- package/dist/renderables/syntax.d.ts +35 -0
- package/dist/renderables/syntax.js +115 -0
- package/dist/renderables/table.d.ts +194 -0
- package/dist/renderables/table.js +795 -0
- package/dist/renderables/traceback.d.ts +31 -0
- package/dist/renderables/traceback.js +108 -0
- package/dist/renderables/tree.d.ts +68 -0
- package/dist/renderables/tree.js +150 -0
- package/dist/renderables/viewport.d.ts +114 -0
- package/dist/renderables/viewport.js +198 -0
- package/dist/template-bindings/color-funcs.d.ts +87 -0
- package/dist/template-bindings/color-funcs.js +217 -0
- package/dist/template-bindings/helpers.d.ts +24 -0
- package/dist/template-bindings/helpers.js +48 -0
- package/dist/template-bindings/index.d.ts +107 -0
- package/dist/template-bindings/index.js +146 -0
- package/dist/template-bindings/palette-funcs.d.ts +94 -0
- package/dist/template-bindings/palette-funcs.js +141 -0
- package/dist/template-bindings/style-funcs.d.ts +28 -0
- package/dist/template-bindings/style-funcs.js +155 -0
- package/dist/themes/buildPalette.d.ts +36 -0
- package/dist/themes/buildPalette.js +56 -0
- package/dist/themes/colorMath.d.ts +82 -0
- package/dist/themes/colorMath.js +254 -0
- package/dist/themes/colorRef.d.ts +51 -0
- package/dist/themes/colorRef.js +96 -0
- package/dist/themes/data/ansi-tables.d.ts +14 -0
- package/dist/themes/data/ansi-tables.js +49 -0
- package/dist/themes/data/atom-one-dark.d.ts +3 -0
- package/dist/themes/data/atom-one-dark.js +177 -0
- package/dist/themes/data/atom-one-light.d.ts +3 -0
- package/dist/themes/data/atom-one-light.js +177 -0
- package/dist/themes/data/catppuccin-frappe.d.ts +3 -0
- package/dist/themes/data/catppuccin-frappe.js +177 -0
- package/dist/themes/data/catppuccin-latte.d.ts +3 -0
- package/dist/themes/data/catppuccin-latte.js +177 -0
- package/dist/themes/data/catppuccin-macchiato.d.ts +3 -0
- package/dist/themes/data/catppuccin-macchiato.js +177 -0
- package/dist/themes/data/catppuccin-mocha.d.ts +3 -0
- package/dist/themes/data/catppuccin-mocha.js +177 -0
- package/dist/themes/data/cyberpunk.d.ts +17 -0
- package/dist/themes/data/cyberpunk.js +193 -0
- package/dist/themes/data/default.d.ts +3 -0
- package/dist/themes/data/default.js +160 -0
- package/dist/themes/data/dracula.d.ts +3 -0
- package/dist/themes/data/dracula.js +177 -0
- package/dist/themes/data/flexoki.d.ts +3 -0
- package/dist/themes/data/flexoki.js +177 -0
- package/dist/themes/data/gruvbox.d.ts +3 -0
- package/dist/themes/data/gruvbox.js +177 -0
- package/dist/themes/data/index.d.ts +35 -0
- package/dist/themes/data/index.js +64 -0
- package/dist/themes/data/monokai.d.ts +3 -0
- package/dist/themes/data/monokai.js +177 -0
- package/dist/themes/data/nord.d.ts +3 -0
- package/dist/themes/data/nord.js +177 -0
- package/dist/themes/data/rose-pine-dawn.d.ts +3 -0
- package/dist/themes/data/rose-pine-dawn.js +177 -0
- package/dist/themes/data/rose-pine-moon.d.ts +3 -0
- package/dist/themes/data/rose-pine-moon.js +177 -0
- package/dist/themes/data/rose-pine.d.ts +3 -0
- package/dist/themes/data/rose-pine.js +177 -0
- package/dist/themes/data/solarized-dark.d.ts +3 -0
- package/dist/themes/data/solarized-dark.js +177 -0
- package/dist/themes/data/solarized-light.d.ts +3 -0
- package/dist/themes/data/solarized-light.js +177 -0
- package/dist/themes/data/svg-export.d.ts +3 -0
- package/dist/themes/data/svg-export.js +177 -0
- package/dist/themes/data/textual-ansi.d.ts +3 -0
- package/dist/themes/data/textual-ansi.js +160 -0
- package/dist/themes/data/textual-dark.d.ts +3 -0
- package/dist/themes/data/textual-dark.js +160 -0
- package/dist/themes/data/textual-light.d.ts +3 -0
- package/dist/themes/data/textual-light.js +160 -0
- package/dist/themes/data/tokyo-night.d.ts +3 -0
- package/dist/themes/data/tokyo-night.js +177 -0
- package/dist/themes/data/types.d.ts +31 -0
- package/dist/themes/data/types.js +10 -0
- package/dist/themes/palette.d.ts +21 -0
- package/dist/themes/palette.js +28 -0
- package/dist/themes/ramp.d.ts +83 -0
- package/dist/themes/ramp.js +122 -0
- package/dist/themes/registry.d.ts +44 -0
- package/dist/themes/registry.js +94 -0
- package/dist/themes/terminalThemes.d.ts +49 -0
- package/dist/themes/terminalThemes.js +63 -0
- package/dist/themes/transpose.d.ts +87 -0
- package/dist/themes/transpose.js +138 -0
- package/dist/widgets/button.d.ts +49 -0
- package/dist/widgets/button.js +208 -0
- package/dist/widgets/checkbox.d.ts +41 -0
- package/dist/widgets/checkbox.js +157 -0
- package/dist/widgets/dropdown.d.ts +67 -0
- package/dist/widgets/dropdown.js +450 -0
- package/dist/widgets/event-router.d.ts +71 -0
- package/dist/widgets/event-router.js +629 -0
- package/dist/widgets/focus-manager.d.ts +45 -0
- package/dist/widgets/focus-manager.js +191 -0
- package/dist/widgets/hit.d.ts +64 -0
- package/dist/widgets/hit.js +113 -0
- package/dist/widgets/index.d.ts +20 -0
- package/dist/widgets/index.js +14 -0
- package/dist/widgets/slider.d.ts +57 -0
- package/dist/widgets/slider.js +270 -0
- package/dist/widgets/static-item.d.ts +34 -0
- package/dist/widgets/static-item.js +54 -0
- package/dist/widgets/text-input.d.ts +274 -0
- package/dist/widgets/text-input.js +1165 -0
- package/dist/widgets/toggle.d.ts +44 -0
- package/dist/widgets/toggle.js +180 -0
- package/dist/widgets/types.d.ts +87 -0
- package/dist/widgets/types.js +30 -0
- package/dist/widgets/widget-app.d.ts +63 -0
- package/dist/widgets/widget-app.js +199 -0
- package/dist/widgets/widget-base.d.ts +40 -0
- package/dist/widgets/widget-base.js +165 -0
- package/package.json +6 -2
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TerminalHost — the capability seam between the interactive runtime and its
|
|
3
|
+
* I/O environment.
|
|
4
|
+
*
|
|
5
|
+
* [LAW:locality-or-seam] The missing seam *was* the missing type. Before this
|
|
6
|
+
* type existed, Screen and EventRouter reached for ambient `process.stdin`/
|
|
7
|
+
* `process.stdout`, which crystallised them to node. With a `TerminalHost`
|
|
8
|
+
* value flowing across one boundary, the same runtime code runs against any
|
|
9
|
+
* implementation — node's TTY (`NodeTerminalHost`, on the `node/terminal-host`
|
|
10
|
+
* subpath) or a browser xterm.js terminal (`BrowserTerminalHost`, below).
|
|
11
|
+
*
|
|
12
|
+
* [LAW:dataflow-not-control-flow] The runtime never branches on "am I in
|
|
13
|
+
* node or browser." The host is the value that differs; the code path is
|
|
14
|
+
* the same. Variability lives in which host is constructed at the program
|
|
15
|
+
* entry, not in any `if` inside the runtime.
|
|
16
|
+
*
|
|
17
|
+
* [LAW:one-way-deps] The interface and the browser host live here, on the
|
|
18
|
+
* `host` subpath; the node host lives in `src/node/terminal-host.ts`, behind
|
|
19
|
+
* its own subpath, because it reads `process.stdin` / `process.stdout`. The
|
|
20
|
+
* dependency runs one way — the node adapter imports this seam; nothing here
|
|
21
|
+
* imports the adapter — so importing a browser-facing entry point cannot
|
|
22
|
+
* reach the ambient `process` global by any path, rather than merely not
|
|
23
|
+
* reaching it in practice. `test/seam/browser-safe.test.ts` is what holds
|
|
24
|
+
* that direction; who reads the host at all is `HOST_ACCESS` in
|
|
25
|
+
* `test/seam/ambient-process.ts`, and neither list is repeated here.
|
|
26
|
+
*
|
|
27
|
+
* [LAW:decomposition] This seam is not part of the interactive layer, which is
|
|
28
|
+
* why it is not in it. It sits below `src/widgets/` and imports nothing from
|
|
29
|
+
* it, so a program that wants to write bytes through a host — every non-
|
|
30
|
+
* interactive consumer — reaches one without loading the widget set or its
|
|
31
|
+
* `mobx` dependency.
|
|
32
|
+
*
|
|
33
|
+
* [boundaries: capabilities over context] A `TerminalHost` grants exactly
|
|
34
|
+
* the I/O capabilities the runtime needs: write bytes, read input, query
|
|
35
|
+
* size, observe resize, switch raw mode, read the terminal's environment,
|
|
36
|
+
* hear the program end, hand the terminal back for a while, lifecycle. It is
|
|
37
|
+
* not an omniscient handle to "the process."
|
|
38
|
+
*/
|
|
39
|
+
import type { Unsubscribe } from "../core/subscription.js";
|
|
40
|
+
export interface TerminalSize {
|
|
41
|
+
readonly cols: number;
|
|
42
|
+
readonly rows: number;
|
|
43
|
+
}
|
|
44
|
+
export type DataHandler = (chunk: Uint8Array | string) => void;
|
|
45
|
+
export type ResizeHandler = (size: TerminalSize) => void;
|
|
46
|
+
export type ExitHandler = () => void;
|
|
47
|
+
export interface TerminalHost {
|
|
48
|
+
/**
|
|
49
|
+
* Write raw bytes (or UTF-8 text) to the terminal as a program's output
|
|
50
|
+
* reaches it: no escape interpretation, no framing, and a terminal on a
|
|
51
|
+
* tty receives each newline as carriage return + newline, the tty's own
|
|
52
|
+
* output translation, which node's raw mode leaves on. A host with no tty
|
|
53
|
+
* in front of its terminal does that translation itself.
|
|
54
|
+
*/
|
|
55
|
+
write(data: Uint8Array | string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Subscribe to input data. The host emits whatever its underlying
|
|
58
|
+
* transport produces (Buffer on node, string on browser xterm.js); the
|
|
59
|
+
* runtime's parser accepts either.
|
|
60
|
+
*/
|
|
61
|
+
onData(handler: DataHandler): Unsubscribe;
|
|
62
|
+
/**
|
|
63
|
+
* Subscribe to terminal resize events. The handler fires with the new
|
|
64
|
+
* size after a resize is observed.
|
|
65
|
+
*/
|
|
66
|
+
onResize(handler: ResizeHandler): Unsubscribe;
|
|
67
|
+
/** Current terminal size in cells. Always returns a valid size. */
|
|
68
|
+
size(): TerminalSize;
|
|
69
|
+
/**
|
|
70
|
+
* Enable or disable raw mode on the input side. Implementations whose
|
|
71
|
+
* transport has no "cooked" mode (xterm.js, non-TTY pipes) silently
|
|
72
|
+
* no-op so callers don't need to branch on capability.
|
|
73
|
+
*/
|
|
74
|
+
setRawMode(raw: boolean): void;
|
|
75
|
+
/**
|
|
76
|
+
* Whether the host is connected to a real interactive terminal — input and
|
|
77
|
+
* output both: what an interactive program checks before it starts.
|
|
78
|
+
*/
|
|
79
|
+
readonly isTTY: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Whether the bytes `write` sends land on a terminal, whatever the input
|
|
82
|
+
* is. Colour detection asks this: a program with piped stdin and a terminal
|
|
83
|
+
* stdout still draws on a terminal, and `isTTY` would call it plain.
|
|
84
|
+
*/
|
|
85
|
+
readonly writesToTerminal: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* The environment a program running on this terminal sees — `TERM`,
|
|
88
|
+
* `COLORTERM`, `NO_COLOR` and the rest. Colour detection reads it: what a
|
|
89
|
+
* terminal can draw is a fact about the host, so it travels with the host
|
|
90
|
+
* rather than being read off whatever `process` the renderer happens to
|
|
91
|
+
* share a runtime with, which in a browser is none.
|
|
92
|
+
*/
|
|
93
|
+
readonly env: NodeJS.ProcessEnv;
|
|
94
|
+
/**
|
|
95
|
+
* Run `handler` once, when the program ends by any path this host can
|
|
96
|
+
* observe, so whoever changed the terminal can hand it back. The program
|
|
97
|
+
* still ends as it would have without the handler: a signal still
|
|
98
|
+
* terminates and a crash is still reported.
|
|
99
|
+
*/
|
|
100
|
+
onExit(handler: ExitHandler): Unsubscribe;
|
|
101
|
+
/**
|
|
102
|
+
* Hand the terminal to whatever launched the program, and resolve once it
|
|
103
|
+
* hands it back. Raw mode delivers Ctrl+Z as a key rather than a signal, so
|
|
104
|
+
* suspending is something a program asks for, and it restores the terminal
|
|
105
|
+
* before asking.
|
|
106
|
+
*/
|
|
107
|
+
suspend(): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Begin the host's lifecycle. Implementations attach whatever resources
|
|
110
|
+
* they own — or no-op when there is nothing to attach. Idempotent. See
|
|
111
|
+
* the concrete host's own JSDoc for what its `start()` actually does:
|
|
112
|
+
* `NodeTerminalHost` and `BrowserTerminalHost` both no-op because their
|
|
113
|
+
* underlying transports (process streams; a caller-managed xterm.js
|
|
114
|
+
* Terminal) are already live by the time the host is constructed.
|
|
115
|
+
*/
|
|
116
|
+
start(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Stop the host's lifecycle. Pairs with `start`. Idempotent. After
|
|
119
|
+
* `stop()`, the host releases its own subscriptions to the underlying
|
|
120
|
+
* transport and clears its handler sets; the transport itself is not
|
|
121
|
+
* torn down (that is the caller's concern — process streams persist;
|
|
122
|
+
* an xterm.js Terminal is disposed by the caller). Re-subscribing via
|
|
123
|
+
* `onData` / `onResize` after `stop()` re-engages the host.
|
|
124
|
+
*/
|
|
125
|
+
stop(): void;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Subset of xterm.js's `Terminal` surface the browser host depends on.
|
|
129
|
+
*
|
|
130
|
+
* [LAW:locality-or-seam] Declaring the dependency by *shape* — rather than
|
|
131
|
+
* importing xterm.js's types — keeps this package free of an xterm.js
|
|
132
|
+
* dev-dep at the type level, lets the browser-bundle pipeline (downstream
|
|
133
|
+
* ticket) pin whichever xterm.js version it wants, and lets unit tests
|
|
134
|
+
* pass a hand-built fake: ask for exactly the capabilities the host uses,
|
|
135
|
+
* no more.
|
|
136
|
+
*/
|
|
137
|
+
export interface XtermDisposable {
|
|
138
|
+
dispose(): void;
|
|
139
|
+
}
|
|
140
|
+
export interface XtermResizeEvent {
|
|
141
|
+
cols: number;
|
|
142
|
+
rows: number;
|
|
143
|
+
}
|
|
144
|
+
export interface XtermTerminal {
|
|
145
|
+
readonly cols: number;
|
|
146
|
+
readonly rows: number;
|
|
147
|
+
write(data: Uint8Array | string): void;
|
|
148
|
+
onData(handler: (data: string) => void): XtermDisposable;
|
|
149
|
+
onResize(handler: (size: XtermResizeEvent) => void): XtermDisposable;
|
|
150
|
+
}
|
|
151
|
+
export interface BrowserTerminalHostOptions {
|
|
152
|
+
/**
|
|
153
|
+
* The xterm.js `Terminal` instance to wrap. The caller is responsible
|
|
154
|
+
* for its DOM lifecycle (`terminal.open(element)`, `terminal.dispose()`)
|
|
155
|
+
* — the host only owns its own subscriber lifecycle, exactly mirroring
|
|
156
|
+
* `NodeTerminalHost`'s relationship to `process.stdin`/`process.stdout`.
|
|
157
|
+
*/
|
|
158
|
+
terminal: XtermTerminal;
|
|
159
|
+
}
|
|
160
|
+
export declare class BrowserTerminalHost implements TerminalHost {
|
|
161
|
+
private readonly terminal;
|
|
162
|
+
private readonly dataHandlers;
|
|
163
|
+
private readonly resizeHandlers;
|
|
164
|
+
private dataSubscription;
|
|
165
|
+
private resizeSubscription;
|
|
166
|
+
constructor(options: BrowserTerminalHostOptions);
|
|
167
|
+
get isTTY(): boolean;
|
|
168
|
+
get writesToTerminal(): boolean;
|
|
169
|
+
get env(): NodeJS.ProcessEnv;
|
|
170
|
+
write(data: Uint8Array | string): void;
|
|
171
|
+
size(): TerminalSize;
|
|
172
|
+
setRawMode(_raw: boolean): void;
|
|
173
|
+
onExit(_handler: ExitHandler): Unsubscribe;
|
|
174
|
+
suspend(): Promise<void>;
|
|
175
|
+
onData(handler: DataHandler): Unsubscribe;
|
|
176
|
+
onResize(handler: ResizeHandler): Unsubscribe;
|
|
177
|
+
start(): void;
|
|
178
|
+
stop(): void;
|
|
179
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TerminalHost — the capability seam between the interactive runtime and its
|
|
3
|
+
* I/O environment.
|
|
4
|
+
*
|
|
5
|
+
* [LAW:locality-or-seam] The missing seam *was* the missing type. Before this
|
|
6
|
+
* type existed, Screen and EventRouter reached for ambient `process.stdin`/
|
|
7
|
+
* `process.stdout`, which crystallised them to node. With a `TerminalHost`
|
|
8
|
+
* value flowing across one boundary, the same runtime code runs against any
|
|
9
|
+
* implementation — node's TTY (`NodeTerminalHost`, on the `node/terminal-host`
|
|
10
|
+
* subpath) or a browser xterm.js terminal (`BrowserTerminalHost`, below).
|
|
11
|
+
*
|
|
12
|
+
* [LAW:dataflow-not-control-flow] The runtime never branches on "am I in
|
|
13
|
+
* node or browser." The host is the value that differs; the code path is
|
|
14
|
+
* the same. Variability lives in which host is constructed at the program
|
|
15
|
+
* entry, not in any `if` inside the runtime.
|
|
16
|
+
*
|
|
17
|
+
* [LAW:one-way-deps] The interface and the browser host live here, on the
|
|
18
|
+
* `host` subpath; the node host lives in `src/node/terminal-host.ts`, behind
|
|
19
|
+
* its own subpath, because it reads `process.stdin` / `process.stdout`. The
|
|
20
|
+
* dependency runs one way — the node adapter imports this seam; nothing here
|
|
21
|
+
* imports the adapter — so importing a browser-facing entry point cannot
|
|
22
|
+
* reach the ambient `process` global by any path, rather than merely not
|
|
23
|
+
* reaching it in practice. `test/seam/browser-safe.test.ts` is what holds
|
|
24
|
+
* that direction; who reads the host at all is `HOST_ACCESS` in
|
|
25
|
+
* `test/seam/ambient-process.ts`, and neither list is repeated here.
|
|
26
|
+
*
|
|
27
|
+
* [LAW:decomposition] This seam is not part of the interactive layer, which is
|
|
28
|
+
* why it is not in it. It sits below `src/widgets/` and imports nothing from
|
|
29
|
+
* it, so a program that wants to write bytes through a host — every non-
|
|
30
|
+
* interactive consumer — reaches one without loading the widget set or its
|
|
31
|
+
* `mobx` dependency.
|
|
32
|
+
*
|
|
33
|
+
* [boundaries: capabilities over context] A `TerminalHost` grants exactly
|
|
34
|
+
* the I/O capabilities the runtime needs: write bytes, read input, query
|
|
35
|
+
* size, observe resize, switch raw mode, read the terminal's environment,
|
|
36
|
+
* hear the program end, hand the terminal back for a while, lifecycle. It is
|
|
37
|
+
* not an omniscient handle to "the process."
|
|
38
|
+
*/
|
|
39
|
+
const XTERM_ENV = Object.freeze({
|
|
40
|
+
TERM: "xterm-256color",
|
|
41
|
+
COLORTERM: "truecolor",
|
|
42
|
+
});
|
|
43
|
+
export class BrowserTerminalHost {
|
|
44
|
+
terminal;
|
|
45
|
+
dataHandlers = new Set();
|
|
46
|
+
resizeHandlers = new Set();
|
|
47
|
+
dataSubscription;
|
|
48
|
+
resizeSubscription;
|
|
49
|
+
constructor(options) {
|
|
50
|
+
this.terminal = options.terminal;
|
|
51
|
+
}
|
|
52
|
+
// [LAW:dataflow-not-control-flow] xterm.js is always an interactive
|
|
53
|
+
// terminal — there is no "non-TTY" code path in the browser. The
|
|
54
|
+
// runtime never branches on the value; this is the only sensible
|
|
55
|
+
// constant for this host.
|
|
56
|
+
get isTTY() {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
get writesToTerminal() {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
// What xterm.js is, stated the way a terminal states it: it identifies as
|
|
63
|
+
// `xterm-256color` and draws 24-bit SGR. With no env at all, detection saw
|
|
64
|
+
// an unnamed TTY and drew every colour at 16-colour depth.
|
|
65
|
+
get env() {
|
|
66
|
+
return XTERM_ENV;
|
|
67
|
+
}
|
|
68
|
+
// [LAW:single-enforcer] xterm.js is a terminal with no tty in front of
|
|
69
|
+
// it, so this host is where the tty's newline translation happens. Left to
|
|
70
|
+
// the terminal, a bare newline moves down without returning, and every row
|
|
71
|
+
// a Console writes starts where the last one ended — every demo drew as a
|
|
72
|
+
// staircase. Here and not in each page's xterm options, so every writer
|
|
73
|
+
// through this host gets it.
|
|
74
|
+
write(data) {
|
|
75
|
+
this.terminal.write(returnBeforeNewline(data));
|
|
76
|
+
}
|
|
77
|
+
size() {
|
|
78
|
+
return { cols: this.terminal.cols, rows: this.terminal.rows };
|
|
79
|
+
}
|
|
80
|
+
// [LAW:dataflow-not-control-flow] xterm.js delivers keystrokes raw
|
|
81
|
+
// unconditionally — there is no cooked mode to toggle. The no-op
|
|
82
|
+
// matches the TerminalHost contract's documented "silently no-op when
|
|
83
|
+
// the transport has no cooked mode," so callers stay uniform across
|
|
84
|
+
// hosts. (Mirror: NodeTerminalHost on a non-TTY stream takes the same
|
|
85
|
+
// no-op path via the optional-chain in `applyRawMode`.)
|
|
86
|
+
setRawMode(_raw) { }
|
|
87
|
+
// The page owns the terminal's life: a program here ends when the page
|
|
88
|
+
// does, and nothing is left to restore.
|
|
89
|
+
onExit(_handler) {
|
|
90
|
+
return () => { };
|
|
91
|
+
}
|
|
92
|
+
// Nothing launched the program that could take the terminal back, so the
|
|
93
|
+
// hand-back is immediate.
|
|
94
|
+
suspend() {
|
|
95
|
+
return Promise.resolve();
|
|
96
|
+
}
|
|
97
|
+
// [LAW:single-enforcer] One underlying `terminal.onData` subscription
|
|
98
|
+
// fans out to every host-level handler — the same lazy-attach,
|
|
99
|
+
// last-unsubscribe-detaches shape as NodeTerminalHost.onData. The
|
|
100
|
+
// runtime never sees the underlying subscription; it sees a single
|
|
101
|
+
// uniform `(handler) => Unsubscribe` API across hosts.
|
|
102
|
+
onData(handler) {
|
|
103
|
+
this.dataHandlers.add(handler);
|
|
104
|
+
if (!this.dataSubscription) {
|
|
105
|
+
this.dataSubscription = this.terminal.onData((chunk) => {
|
|
106
|
+
for (const h of this.dataHandlers)
|
|
107
|
+
h(chunk);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return () => {
|
|
111
|
+
this.dataHandlers.delete(handler);
|
|
112
|
+
if (this.dataHandlers.size === 0 && this.dataSubscription) {
|
|
113
|
+
this.dataSubscription.dispose();
|
|
114
|
+
this.dataSubscription = undefined;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
onResize(handler) {
|
|
119
|
+
this.resizeHandlers.add(handler);
|
|
120
|
+
if (!this.resizeSubscription) {
|
|
121
|
+
this.resizeSubscription = this.terminal.onResize((size) => {
|
|
122
|
+
const snapshot = { cols: size.cols, rows: size.rows };
|
|
123
|
+
for (const h of this.resizeHandlers)
|
|
124
|
+
h(snapshot);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return () => {
|
|
128
|
+
this.resizeHandlers.delete(handler);
|
|
129
|
+
if (this.resizeHandlers.size === 0 && this.resizeSubscription) {
|
|
130
|
+
this.resizeSubscription.dispose();
|
|
131
|
+
this.resizeSubscription = undefined;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
start() {
|
|
136
|
+
// [LAW:one-source-of-truth] The host does NOT own the terminal's DOM
|
|
137
|
+
// lifecycle (`terminal.open` / `terminal.dispose`). That is the
|
|
138
|
+
// caller's responsibility, exactly as NodeTerminalHost does not own
|
|
139
|
+
// `process.stdin`/`process.stdout`. start() is here so the runtime
|
|
140
|
+
// can call it uniformly across hosts; for this host there is
|
|
141
|
+
// nothing to do at this seam.
|
|
142
|
+
}
|
|
143
|
+
stop() {
|
|
144
|
+
// [LAW:one-source-of-truth] Symmetric teardown mirroring
|
|
145
|
+
// NodeTerminalHost.stop: drop every host-level subscriber and
|
|
146
|
+
// dispose the underlying terminal subscriptions. The terminal
|
|
147
|
+
// itself stays alive — re-subscribing via onData/onResize after
|
|
148
|
+
// stop() works, since the lazy-attach path re-creates the
|
|
149
|
+
// subscription on next subscribe. Calling stop() repeatedly is
|
|
150
|
+
// safe — the subscription guards make later calls no-ops.
|
|
151
|
+
if (this.dataSubscription) {
|
|
152
|
+
this.dataSubscription.dispose();
|
|
153
|
+
this.dataSubscription = undefined;
|
|
154
|
+
}
|
|
155
|
+
if (this.resizeSubscription) {
|
|
156
|
+
this.resizeSubscription.dispose();
|
|
157
|
+
this.resizeSubscription = undefined;
|
|
158
|
+
}
|
|
159
|
+
this.dataHandlers.clear();
|
|
160
|
+
this.resizeHandlers.clear();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* `data` with a carriage return before every newline — the tty's ONLCR. A
|
|
165
|
+
* newline byte never occurs inside a multi-byte UTF-8 character, so the bytes
|
|
166
|
+
* are translated as bytes. A newline already preceded by a carriage return
|
|
167
|
+
* gains a second one, which returns to a column the cursor is already in, as
|
|
168
|
+
* the kernel's translation does.
|
|
169
|
+
*/
|
|
170
|
+
function returnBeforeNewline(data) {
|
|
171
|
+
if (typeof data === "string")
|
|
172
|
+
return data.replaceAll("\n", "\r\n");
|
|
173
|
+
let newlines = 0;
|
|
174
|
+
for (let i = 0; i < data.length; i++)
|
|
175
|
+
newlines += Number(data[i] === 0x0a);
|
|
176
|
+
if (newlines === 0)
|
|
177
|
+
return data;
|
|
178
|
+
const out = new Uint8Array(data.length + newlines);
|
|
179
|
+
let at = 0;
|
|
180
|
+
for (let i = 0; i < data.length; i++) {
|
|
181
|
+
if (data[i] === 0x0a)
|
|
182
|
+
out[at++] = 0x0d;
|
|
183
|
+
out[at++] = data[i];
|
|
184
|
+
}
|
|
185
|
+
return out;
|
|
186
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export { cellLen, setCellSize, splitText, chopCells, cellFit, asCellCol, asCodePoint, } from "./core/cells.js";
|
|
2
|
+
export type { CellCol, CodeUnit, CodePoint } from "./core/cells.js";
|
|
3
|
+
export { ColorRgba, ColorTable, ColorDepth, ColorSpec, ColorParseError, TerminalTheme, parseRgbHex, parseRgbaHex, blendRgb, resolveColorSystem, detectColorSystem, resolveDestination, STANDARD_TABLE, EIGHT_BIT_TABLE, WINDOWS_TABLE, ANSI_COLOR_NAMES, } from "./core/color.js";
|
|
4
|
+
export type { DetectColorOptions, Destination } from "./core/color.js";
|
|
5
|
+
export { Oklch, IDENTITY, INVERT_LIGHTNESS, isIdentityKey, } from "./core/oklch.js";
|
|
6
|
+
export type { ThemeKey, OklchWeights } from "./core/oklch.js";
|
|
7
|
+
export { Palette } from "./themes/palette.js";
|
|
8
|
+
export { resolveColorRef, parseHexColor, ColorRefError, HEX_COLOR_RE, } from "./themes/colorRef.js";
|
|
9
|
+
export { buildPalette } from "./themes/buildPalette.js";
|
|
10
|
+
export type { BaseColors } from "./themes/buildPalette.js";
|
|
11
|
+
export { DEFAULT_TERMINAL_THEME, MONOKAI, SVG_EXPORT_THEME, NORD, GRUVBOX, DRACULA, TOKYO_NIGHT, FLEXOKI, CYBERPUNK, CATPPUCCIN_MOCHA, CATPPUCCIN_LATTE, CATPPUCCIN_FRAPPE, CATPPUCCIN_MACCHIATO, SOLARIZED_DARK, SOLARIZED_LIGHT, ROSE_PINE, ROSE_PINE_MOON, ROSE_PINE_DAWN, ATOM_ONE_DARK, ATOM_ONE_LIGHT, TEXTUAL_DARK, TEXTUAL_LIGHT, TEXTUAL_ANSI, } from "./themes/terminalThemes.js";
|
|
12
|
+
export { getThemePalette, listThemePalettes } from "./themes/registry.js";
|
|
13
|
+
export type { ThemeName } from "./themes/registry.js";
|
|
14
|
+
export { transposePalette, themeKeyForRoot, isAnchored, ANCHORED_ROOTS, } from "./themes/transpose.js";
|
|
15
|
+
export { lighten, darken, relativeLuminance, contrastRatio, contrastFor, ensureContrast, ensureDrawn, drawnColour, } from "./themes/colorMath.js";
|
|
16
|
+
export { ColorRamp, RAMP_EASING_NAMES, parseRampEasing } from "./themes/ramp.js";
|
|
17
|
+
export type { ColorStop, RampEasing } from "./themes/ramp.js";
|
|
18
|
+
export { Style, StyleSyntaxError, StyleStack, Theme, NULL_STYLE, DEFAULT_STYLES, } from "./core/style.js";
|
|
19
|
+
export type { StyleOptions } from "./core/style.js";
|
|
20
|
+
export { Segment, ControlType, } from "./core/segment.js";
|
|
21
|
+
export type { ControlCode } from "./core/segment.js";
|
|
22
|
+
export type { Anchor } from "./core/anchor.js";
|
|
23
|
+
export { Box } from "./core/box.js";
|
|
24
|
+
export type { EdgeChars, ContentChars, RowLevel, SubstituteOptions } from "./core/box.js";
|
|
25
|
+
export { ASCII, ASCII2, ASCII_DOUBLE_HEAD, SQUARE, SQUARE_DOUBLE_HEAD, MINIMAL, MINIMAL_HEAVY_HEAD, MINIMAL_DOUBLE_HEAD, SIMPLE, SIMPLE_HEAD, SIMPLE_HEAVY, HORIZONTALS, ROUNDED, HEAVY, HEAVY_EDGE, HEAVY_HEAD, DOUBLE, DOUBLE_EDGE, MARKDOWN, } from "./core/box.js";
|
|
26
|
+
export { isRenderable, isMeasurable, withCellWidth, withBoundedWidth, insetHeight, stackedHeight, regionRows, fitHeight, getStyle, } from "./core/protocol.js";
|
|
27
|
+
export type { RenderOptions, OverflowMethod, Height, Renderable, Measurable, StyleErrorHandler, } from "./core/protocol.js";
|
|
28
|
+
export type { Unsubscribe } from "./core/subscription.js";
|
|
29
|
+
export { Measurement, measureRenderables } from "./core/measure.js";
|
|
30
|
+
export { Span, RichText } from "./core/text.js";
|
|
31
|
+
export type { RichTextOptions } from "./core/text.js";
|
|
32
|
+
export { Strip, PowerlineJoiner, SEAM_MIN_DELTA_E, POWERLINE_JOINER_GLYPHS, CapsuleJoiner, PlainJoiner, GradientJoiner, } from "./core/strip.js";
|
|
33
|
+
export type { StyledRenderable, Joiner, PowerlineJoinerOptions, CapsuleJoinerOptions, PlainJoinerOptions, GradientJoinerOptions, } from "./core/strip.js";
|
|
34
|
+
export { renderToString, segmentToString, segmentsToString, } from "./core/render.js";
|
|
35
|
+
export type { RenderToStringOptions } from "./core/render.js";
|
|
36
|
+
export { OSC8, osc8Sequences } from "./core/osc8.js";
|
|
37
|
+
export type { Osc8Sequence } from "./core/osc8.js";
|
|
38
|
+
export { AnsiDecoder, decodeAnsi } from "./core/ansi.js";
|
|
39
|
+
export { MarkupRegistry, globalMarkupRegistry, renderMarkup, } from "./core/markup.js";
|
|
40
|
+
export type { MarkupTagContext, MarkupTagHandler, RenderMarkupOptions, } from "./core/markup.js";
|
|
41
|
+
export { EMOJI, emojiReplace, Emoji, NoEmoji } from "./core/emoji.js";
|
|
42
|
+
export { MarkupError, MarkupSyntaxError, escape as escapeMarkup } from "./core/markup.js";
|
|
43
|
+
export { Highlighter, NullHighlighter, RegexHighlighter, ReprHighlighter, JSONHighlighter, ISO8601Highlighter, } from "./core/highlighter.js";
|
|
44
|
+
export { Pretty } from "./core/pretty.js";
|
|
45
|
+
export type { PrettyOptions } from "./core/pretty.js";
|
|
46
|
+
export { JSONRenderable } from "./core/json.js";
|
|
47
|
+
export type { JSONOptions } from "./core/json.js";
|
|
48
|
+
export { SPINNERS, DEFAULT_SPINNER } from "./core/spinnerData.js";
|
|
49
|
+
export type { SpinnerData } from "./core/spinnerData.js";
|
|
50
|
+
export { Console } from "./core/console.js";
|
|
51
|
+
export type { ConsoleOptions, ConsoleSink, ConsoleStream, ConsoleEnvironment, PrintOptions, } from "./core/console.js";
|
|
52
|
+
export { Constrain } from "./renderables/constrain.js";
|
|
53
|
+
export { Align } from "./renderables/align.js";
|
|
54
|
+
export type { Alignment } from "./core/place.js";
|
|
55
|
+
export { Padding } from "./renderables/padding.js";
|
|
56
|
+
export type { PaddingDimensions } from "./renderables/padding.js";
|
|
57
|
+
export { Viewport, SCROLLBAR } from "./renderables/viewport.js";
|
|
58
|
+
export type { Scrollbar, ScrollbarPart, ViewportOptions } from "./renderables/viewport.js";
|
|
59
|
+
export { Rule } from "./renderables/rule.js";
|
|
60
|
+
export type { RuleAlign, RuleOptions } from "./renderables/rule.js";
|
|
61
|
+
export { Panel } from "./renderables/panel.js";
|
|
62
|
+
export type { PanelOptions } from "./renderables/panel.js";
|
|
63
|
+
export { Group } from "./renderables/group.js";
|
|
64
|
+
export { ProgressBar } from "./renderables/progressBar.js";
|
|
65
|
+
export type { ProgressBarOptions } from "./renderables/progressBar.js";
|
|
66
|
+
export { Spinner } from "./renderables/spinner.js";
|
|
67
|
+
export type { SpinnerOptions } from "./renderables/spinner.js";
|
|
68
|
+
export { Table, Column } from "./renderables/table.js";
|
|
69
|
+
export type { TableOptions, ColumnOptions } from "./renderables/table.js";
|
|
70
|
+
export { Tree } from "./renderables/tree.js";
|
|
71
|
+
export type { TreeOptions } from "./renderables/tree.js";
|
|
72
|
+
export { Columns } from "./renderables/columns.js";
|
|
73
|
+
export type { ColumnsOptions } from "./renderables/columns.js";
|
|
74
|
+
export { FlexStrip } from "./renderables/flexStrip.js";
|
|
75
|
+
export type { FlexStripOptions, FlexAlign } from "./renderables/flexStrip.js";
|
|
76
|
+
export { Live } from "./renderables/live.js";
|
|
77
|
+
export type { LiveOptions } from "./renderables/live.js";
|
|
78
|
+
export { Status } from "./renderables/status.js";
|
|
79
|
+
export type { StatusOptions } from "./renderables/status.js";
|
|
80
|
+
export { Progress, TextColumn, BarColumn, TaskProgressColumn, TimeRemainingColumn, TimeElapsedColumn, SpinnerColumn, MofNCompleteColumn, track, } from "./renderables/progress.js";
|
|
81
|
+
export type { ProgressOptions, TaskOptions, TaskUpdateOptions } from "./renderables/progress.js";
|
|
82
|
+
export { Prompt, IntPrompt, FloatPrompt, Confirm } from "./renderables/prompt.js";
|
|
83
|
+
export type { PromptInput, PromptOptions } from "./renderables/prompt.js";
|
|
84
|
+
export { Traceback } from "./renderables/traceback.js";
|
|
85
|
+
export type { TracebackOptions } from "./renderables/traceback.js";
|
|
86
|
+
export { Syntax } from "./renderables/syntax.js";
|
|
87
|
+
export type { SyntaxOptions } from "./renderables/syntax.js";
|
|
88
|
+
export { Markdown } from "./renderables/markdown.js";
|
|
89
|
+
export type { MarkdownOptions } from "./renderables/markdown.js";
|
|
90
|
+
export { Layout } from "./renderables/layout.js";
|
|
91
|
+
export type { LayoutOptions } from "./renderables/layout.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Core primitives
|
|
2
|
+
export { cellLen, setCellSize, splitText, chopCells, cellFit, asCellCol, asCodePoint, } from "./core/cells.js";
|
|
3
|
+
export { ColorRgba, ColorTable, ColorDepth, ColorSpec, ColorParseError, TerminalTheme, parseRgbHex, parseRgbaHex, blendRgb, resolveColorSystem, detectColorSystem, resolveDestination, STANDARD_TABLE, EIGHT_BIT_TABLE, WINDOWS_TABLE, ANSI_COLOR_NAMES, } from "./core/color.js";
|
|
4
|
+
// Perceptually-uniform color space (manipulation, transposition).
|
|
5
|
+
export { Oklch, IDENTITY, INVERT_LIGHTNESS, isIdentityKey, } from "./core/oklch.js";
|
|
6
|
+
// Themes — semantic palettes (distinct from ColorTable quantization LUTs)
|
|
7
|
+
export { Palette } from "./themes/palette.js";
|
|
8
|
+
// The one checkpoint turning an author-written colour string — a palette
|
|
9
|
+
// variable name or a `#RRGGBB` literal — into a colour. [LAW:parse-dont-validate]
|
|
10
|
+
export { resolveColorRef, parseHexColor, ColorRefError, HEX_COLOR_RE, } from "./themes/colorRef.js";
|
|
11
|
+
export { buildPalette } from "./themes/buildPalette.js";
|
|
12
|
+
export { DEFAULT_TERMINAL_THEME, MONOKAI, SVG_EXPORT_THEME, NORD, GRUVBOX, DRACULA, TOKYO_NIGHT, FLEXOKI, CYBERPUNK, CATPPUCCIN_MOCHA, CATPPUCCIN_LATTE, CATPPUCCIN_FRAPPE, CATPPUCCIN_MACCHIATO, SOLARIZED_DARK, SOLARIZED_LIGHT, ROSE_PINE, ROSE_PINE_MOON, ROSE_PINE_DAWN, ATOM_ONE_DARK, ATOM_ONE_LIGHT, TEXTUAL_DARK, TEXTUAL_LIGHT, TEXTUAL_ANSI, } from "./themes/terminalThemes.js";
|
|
13
|
+
export { getThemePalette, listThemePalettes } from "./themes/registry.js";
|
|
14
|
+
export { transposePalette, themeKeyForRoot, isAnchored, ANCHORED_ROOTS, } from "./themes/transpose.js";
|
|
15
|
+
// WCAG contrast toolkit — accessibility-aware color for styled output.
|
|
16
|
+
// `ensureContrast` keeps a color's hue and only slides its OKLCH lightness to
|
|
17
|
+
// meet the ratio, so themed text stays themed; `contrastFor` picks black/white
|
|
18
|
+
// from scratch when there is no color to preserve.
|
|
19
|
+
// `lighten`/`darken` slide a color's HSL lightness by whole "levels" (each
|
|
20
|
+
// level ≈ 10%), returning a new ColorRgba — the relative transform a consumer
|
|
21
|
+
// reaches for to tint a resolved color against itself (e.g. a focused-while-open
|
|
22
|
+
// menu cell lightening its inherited background) without re-deriving from a
|
|
23
|
+
// palette name. Negative levels invert (lighten(c,-n) === darken(c,n)).
|
|
24
|
+
export { lighten, darken, relativeLuminance, contrastRatio, contrastFor, ensureContrast, ensureDrawn, drawnColour, } from "./themes/colorMath.js";
|
|
25
|
+
// A number → a color through ordered stops, interpolated in OKLCH — the one
|
|
26
|
+
// color operation whose input is a measurement rather than a color, so a
|
|
27
|
+
// gradient (or, with the `step` easing, a threshold cascade) stays inside the
|
|
28
|
+
// theme system instead of being computed beside it.
|
|
29
|
+
export { ColorRamp, RAMP_EASING_NAMES, parseRampEasing } from "./themes/ramp.js";
|
|
30
|
+
export { Style, StyleSyntaxError, StyleStack, Theme, NULL_STYLE, DEFAULT_STYLES, } from "./core/style.js";
|
|
31
|
+
export { Segment, ControlType, } from "./core/segment.js";
|
|
32
|
+
export { Box } from "./core/box.js";
|
|
33
|
+
export { ASCII, ASCII2, ASCII_DOUBLE_HEAD, SQUARE, SQUARE_DOUBLE_HEAD, MINIMAL, MINIMAL_HEAVY_HEAD, MINIMAL_DOUBLE_HEAD, SIMPLE, SIMPLE_HEAD, SIMPLE_HEAVY, HORIZONTALS, ROUNDED, HEAVY, HEAVY_EDGE, HEAVY_HEAD, DOUBLE, DOUBLE_EDGE, MARKDOWN, } from "./core/box.js";
|
|
34
|
+
// Protocol
|
|
35
|
+
export { isRenderable, isMeasurable, withCellWidth, withBoundedWidth, insetHeight, stackedHeight, regionRows, fitHeight, getStyle, } from "./core/protocol.js";
|
|
36
|
+
// Measurement
|
|
37
|
+
export { Measurement, measureRenderables } from "./core/measure.js";
|
|
38
|
+
// Text
|
|
39
|
+
export { Span, RichText } from "./core/text.js";
|
|
40
|
+
// Strip + Joiner
|
|
41
|
+
export { Strip, PowerlineJoiner, SEAM_MIN_DELTA_E, POWERLINE_JOINER_GLYPHS, CapsuleJoiner, PlainJoiner, GradientJoiner, } from "./core/strip.js";
|
|
42
|
+
// renderToString — stateless one-shot emission
|
|
43
|
+
export { renderToString, segmentToString, segmentsToString, } from "./core/render.js";
|
|
44
|
+
// OSC 8 hyperlink wire grammar — for consumers that read rendered bytes back
|
|
45
|
+
export { OSC8, osc8Sequences } from "./core/osc8.js";
|
|
46
|
+
// ANSI bytes back into styled text
|
|
47
|
+
export { AnsiDecoder, decodeAnsi } from "./core/ansi.js";
|
|
48
|
+
// Markup plugin tags
|
|
49
|
+
export { MarkupRegistry, globalMarkupRegistry, renderMarkup, } from "./core/markup.js";
|
|
50
|
+
// Emoji
|
|
51
|
+
export { EMOJI, emojiReplace, Emoji, NoEmoji } from "./core/emoji.js";
|
|
52
|
+
// Markup
|
|
53
|
+
export { MarkupError, MarkupSyntaxError, escape as escapeMarkup } from "./core/markup.js";
|
|
54
|
+
// Highlighter
|
|
55
|
+
export { Highlighter, NullHighlighter, RegexHighlighter, ReprHighlighter, JSONHighlighter, ISO8601Highlighter, } from "./core/highlighter.js";
|
|
56
|
+
// Pretty
|
|
57
|
+
export { Pretty } from "./core/pretty.js";
|
|
58
|
+
// JSON
|
|
59
|
+
export { JSONRenderable } from "./core/json.js";
|
|
60
|
+
// Spinner data
|
|
61
|
+
export { SPINNERS, DEFAULT_SPINNER } from "./core/spinnerData.js";
|
|
62
|
+
// Console
|
|
63
|
+
export { Console } from "./core/console.js";
|
|
64
|
+
// Renderables
|
|
65
|
+
export { Constrain } from "./renderables/constrain.js";
|
|
66
|
+
export { Align } from "./renderables/align.js";
|
|
67
|
+
export { Padding } from "./renderables/padding.js";
|
|
68
|
+
export { Viewport, SCROLLBAR } from "./renderables/viewport.js";
|
|
69
|
+
export { Rule } from "./renderables/rule.js";
|
|
70
|
+
export { Panel } from "./renderables/panel.js";
|
|
71
|
+
export { Group } from "./renderables/group.js";
|
|
72
|
+
export { ProgressBar } from "./renderables/progressBar.js";
|
|
73
|
+
export { Spinner } from "./renderables/spinner.js";
|
|
74
|
+
export { Table, Column } from "./renderables/table.js";
|
|
75
|
+
export { Tree } from "./renderables/tree.js";
|
|
76
|
+
export { Columns } from "./renderables/columns.js";
|
|
77
|
+
export { FlexStrip } from "./renderables/flexStrip.js";
|
|
78
|
+
export { Live } from "./renderables/live.js";
|
|
79
|
+
export { Status } from "./renderables/status.js";
|
|
80
|
+
export { Progress, TextColumn, BarColumn, TaskProgressColumn, TimeRemainingColumn, TimeElapsedColumn, SpinnerColumn, MofNCompleteColumn, track, } from "./renderables/progress.js";
|
|
81
|
+
export { Prompt, IntPrompt, FloatPrompt, Confirm } from "./renderables/prompt.js";
|
|
82
|
+
export { Traceback } from "./renderables/traceback.js";
|
|
83
|
+
export { Syntax } from "./renderables/syntax.js";
|
|
84
|
+
export { Markdown } from "./renderables/markdown.js";
|
|
85
|
+
export { Layout } from "./renderables/layout.js";
|
|
86
|
+
// The barrel stops at `renderables/`, and the two subsystems above it are reached
|
|
87
|
+
// through their own `package.json#exports` subpaths instead:
|
|
88
|
+
//
|
|
89
|
+
// `@promptctl/rich-js/widgets` — the interactive layer (pulls in `mobx`)
|
|
90
|
+
// `@promptctl/rich-js/template-bindings` — the styling vocabulary (pulls in
|
|
91
|
+
// `@promptctl/go-template-js`)
|
|
92
|
+
//
|
|
93
|
+
// `@promptctl/rich-js/host` is a third subpath but a different kind of thing: the
|
|
94
|
+
// terminal seam has no third-party dependency at all, and sits on its own subpath
|
|
95
|
+
// because it is what a *non*-interactive program reaches for. Folding it into either
|
|
96
|
+
// neighbour is what the split was undoing — inside `widgets/` it charged mobx to
|
|
97
|
+
// consumers who only wanted to write bytes; in this barrel it would put an I/O
|
|
98
|
+
// capability in front of consumers who never touch a terminal directly.
|
|
99
|
+
//
|
|
100
|
+
// `export … from` is a static edge, so anything named here is *evaluated* by every
|
|
101
|
+
// consumer, including one that only wanted a Table. Re-exporting the two subsystems
|
|
102
|
+
// therefore charged their dependencies to the whole package — mobx and, transitively,
|
|
103
|
+
// @noble/hashes. The subpaths make that cost something a consumer opts into, the same
|
|
104
|
+
// bargain `src/node/` strikes for Node built-ins.
|
|
105
|
+
//
|
|
106
|
+
// This is also why there is no widget list here to keep in sync: `src/widgets/index.ts`
|
|
107
|
+
// is that list, and a copy of it in this file would be a second one to drift from.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* node:prompt — readline-backed `PromptInput` for use with the prompt
|
|
3
|
+
* renderable in a Node runtime.
|
|
4
|
+
*
|
|
5
|
+
* [LAW:locality-or-seam] `node:readline` lives only here, on the node side
|
|
6
|
+
* of the API boundary. The main barrel stays browser-safe; consumers that
|
|
7
|
+
* want interactive prompts in Node opt in by importing `nodeAsk` and
|
|
8
|
+
* passing it as the input capability:
|
|
9
|
+
*
|
|
10
|
+
* import { Prompt } from "@promptctl/rich-js";
|
|
11
|
+
* import { nodeAsk } from "@promptctl/rich-js/node/prompt";
|
|
12
|
+
* const answer = await Prompt.ask("What's your name?", nodeAsk);
|
|
13
|
+
* // or with options:
|
|
14
|
+
* const choice = await Prompt.ask("Pick one", nodeAsk, { choices: ["a", "b"] });
|
|
15
|
+
*
|
|
16
|
+
* [LAW:single-enforcer] One readline interface per `nodeAsk` call —
|
|
17
|
+
* created, asked, closed. No shared `rl` across prompts, no listener-leak
|
|
18
|
+
* pitfalls when callers stack prompts in a loop.
|
|
19
|
+
*/
|
|
20
|
+
import type { PromptInput } from "../renderables/prompt.js";
|
|
21
|
+
export declare const nodeAsk: PromptInput;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* node:prompt — readline-backed `PromptInput` for use with the prompt
|
|
3
|
+
* renderable in a Node runtime.
|
|
4
|
+
*
|
|
5
|
+
* [LAW:locality-or-seam] `node:readline` lives only here, on the node side
|
|
6
|
+
* of the API boundary. The main barrel stays browser-safe; consumers that
|
|
7
|
+
* want interactive prompts in Node opt in by importing `nodeAsk` and
|
|
8
|
+
* passing it as the input capability:
|
|
9
|
+
*
|
|
10
|
+
* import { Prompt } from "@promptctl/rich-js";
|
|
11
|
+
* import { nodeAsk } from "@promptctl/rich-js/node/prompt";
|
|
12
|
+
* const answer = await Prompt.ask("What's your name?", nodeAsk);
|
|
13
|
+
* // or with options:
|
|
14
|
+
* const choice = await Prompt.ask("Pick one", nodeAsk, { choices: ["a", "b"] });
|
|
15
|
+
*
|
|
16
|
+
* [LAW:single-enforcer] One readline interface per `nodeAsk` call —
|
|
17
|
+
* created, asked, closed. No shared `rl` across prompts, no listener-leak
|
|
18
|
+
* pitfalls when callers stack prompts in a loop.
|
|
19
|
+
*/
|
|
20
|
+
import * as readline from "node:readline";
|
|
21
|
+
export const nodeAsk = (prompt) => new Promise((resolve) => {
|
|
22
|
+
const rl = readline.createInterface({
|
|
23
|
+
input: process.stdin,
|
|
24
|
+
output: process.stdout,
|
|
25
|
+
});
|
|
26
|
+
rl.question(prompt, (answer) => {
|
|
27
|
+
rl.close();
|
|
28
|
+
resolve(answer);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* node:save — node-only file helpers that persist recorded console output.
|
|
3
|
+
*
|
|
4
|
+
* [LAW:locality-or-seam] These functions live outside the main barrel so
|
|
5
|
+
* Console can stop importing `fs`. Importing `Console` itself stays
|
|
6
|
+
* browser-safe; importing this module is the explicit opt-in for the
|
|
7
|
+
* fs-backed surface, and bundlers targeting the browser will (correctly)
|
|
8
|
+
* refuse to resolve `fs` if a consumer ever pulls it in by accident.
|
|
9
|
+
*
|
|
10
|
+
* [LAW:single-enforcer] One funnel per format: `saveText` consumes
|
|
11
|
+
* `Console.exportText()` and `saveHtml` consumes `Console.exportHtml()`.
|
|
12
|
+
* The encoding and recording logic stays on Console; this file is purely
|
|
13
|
+
* the IO sink.
|
|
14
|
+
*/
|
|
15
|
+
import type { Console } from "../core/console.js";
|
|
16
|
+
export declare function saveText(out: Console, path: string, options?: Parameters<Console["exportText"]>[0]): void;
|
|
17
|
+
export declare function saveHtml(out: Console, path: string, options?: Parameters<Console["exportHtml"]>[0]): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* node:save — node-only file helpers that persist recorded console output.
|
|
3
|
+
*
|
|
4
|
+
* [LAW:locality-or-seam] These functions live outside the main barrel so
|
|
5
|
+
* Console can stop importing `fs`. Importing `Console` itself stays
|
|
6
|
+
* browser-safe; importing this module is the explicit opt-in for the
|
|
7
|
+
* fs-backed surface, and bundlers targeting the browser will (correctly)
|
|
8
|
+
* refuse to resolve `fs` if a consumer ever pulls it in by accident.
|
|
9
|
+
*
|
|
10
|
+
* [LAW:single-enforcer] One funnel per format: `saveText` consumes
|
|
11
|
+
* `Console.exportText()` and `saveHtml` consumes `Console.exportHtml()`.
|
|
12
|
+
* The encoding and recording logic stays on Console; this file is purely
|
|
13
|
+
* the IO sink.
|
|
14
|
+
*/
|
|
15
|
+
import { writeFileSync } from "node:fs";
|
|
16
|
+
export function saveText(out, path, options) {
|
|
17
|
+
writeFileSync(path, out.exportText(options), "utf-8");
|
|
18
|
+
}
|
|
19
|
+
export function saveHtml(out, path, options) {
|
|
20
|
+
writeFileSync(path, out.exportHtml(options), "utf-8");
|
|
21
|
+
}
|