@promptctl/rich-js 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/README.md +9 -7
  2. package/dist/core/anchor.d.ts +45 -0
  3. package/dist/core/anchor.js +39 -0
  4. package/dist/core/ansi.d.ts +65 -0
  5. package/dist/core/ansi.js +231 -0
  6. package/dist/core/box.d.ts +145 -0
  7. package/dist/core/box.js +372 -0
  8. package/dist/core/cells.d.ts +192 -0
  9. package/dist/core/cells.js +334 -0
  10. package/dist/core/clock.d.ts +48 -0
  11. package/dist/core/clock.js +42 -0
  12. package/dist/core/color.d.ts +326 -0
  13. package/dist/core/color.js +1225 -0
  14. package/dist/core/console.d.ts +196 -0
  15. package/dist/core/console.js +596 -0
  16. package/dist/core/easing.d.ts +86 -0
  17. package/dist/core/easing.js +171 -0
  18. package/dist/core/emoji.d.ts +24 -0
  19. package/dist/core/emoji.js +391 -0
  20. package/dist/core/env.d.ts +16 -0
  21. package/dist/core/env.js +16 -0
  22. package/dist/core/export-html.d.ts +59 -0
  23. package/dist/core/export-html.js +197 -0
  24. package/dist/core/export-lines.d.ts +130 -0
  25. package/dist/core/export-lines.js +159 -0
  26. package/dist/core/export-svg.d.ts +49 -0
  27. package/dist/core/export-svg.js +213 -0
  28. package/dist/core/fnv1a.d.ts +10 -0
  29. package/dist/core/fnv1a.js +17 -0
  30. package/dist/core/highlighter.d.ts +33 -0
  31. package/dist/core/highlighter.js +190 -0
  32. package/dist/core/json.d.ts +27 -0
  33. package/dist/core/json.js +53 -0
  34. package/dist/core/markup.d.ts +140 -0
  35. package/dist/core/markup.js +654 -0
  36. package/dist/core/measure.d.ts +27 -0
  37. package/dist/core/measure.js +67 -0
  38. package/dist/core/memo.d.ts +19 -0
  39. package/dist/core/memo.js +34 -0
  40. package/dist/core/oklch.d.ts +161 -0
  41. package/dist/core/oklch.js +312 -0
  42. package/dist/core/osc8.d.ts +68 -0
  43. package/dist/core/osc8.js +78 -0
  44. package/dist/core/paint.d.ts +107 -0
  45. package/dist/core/paint.js +150 -0
  46. package/dist/core/place.d.ts +30 -0
  47. package/dist/core/place.js +49 -0
  48. package/dist/core/pretty.d.ts +247 -0
  49. package/dist/core/pretty.js +906 -0
  50. package/dist/core/protocol.d.ts +305 -0
  51. package/dist/core/protocol.js +183 -0
  52. package/dist/core/render.d.ts +87 -0
  53. package/dist/core/render.js +105 -0
  54. package/dist/core/segment.d.ts +162 -0
  55. package/dist/core/segment.js +488 -0
  56. package/dist/core/spinnerData.d.ts +12 -0
  57. package/dist/core/spinnerData.js +117 -0
  58. package/dist/core/strip.d.ts +152 -0
  59. package/dist/core/strip.js +326 -0
  60. package/dist/core/style.d.ts +189 -0
  61. package/dist/core/style.js +758 -0
  62. package/dist/core/subscription.d.ts +12 -0
  63. package/dist/core/subscription.js +12 -0
  64. package/dist/core/text.d.ts +283 -0
  65. package/dist/core/text.js +1097 -0
  66. package/dist/core/wrap.d.ts +46 -0
  67. package/dist/core/wrap.js +140 -0
  68. package/dist/host/app.d.ts +133 -0
  69. package/dist/host/app.js +285 -0
  70. package/dist/host/host-environment.d.ts +26 -0
  71. package/dist/host/host-environment.js +44 -0
  72. package/dist/host/index.d.ts +6 -0
  73. package/dist/host/index.js +3 -0
  74. package/dist/host/terminal-host.d.ts +180 -0
  75. package/dist/host/terminal-host.js +186 -0
  76. package/dist/index.d.ts +98 -0
  77. package/dist/index.js +114 -0
  78. package/dist/node/prompt.d.ts +34 -0
  79. package/dist/node/prompt.js +51 -0
  80. package/dist/node/save.d.ts +18 -0
  81. package/dist/node/save.js +24 -0
  82. package/dist/node/terminal-host.d.ts +114 -0
  83. package/dist/node/terminal-host.js +227 -0
  84. package/dist/node/traceback.d.ts +38 -0
  85. package/dist/node/traceback.js +98 -0
  86. package/dist/renderables/align.d.ts +16 -0
  87. package/dist/renderables/align.js +26 -0
  88. package/dist/renderables/columns.d.ts +77 -0
  89. package/dist/renderables/columns.js +191 -0
  90. package/dist/renderables/constrain.d.ts +15 -0
  91. package/dist/renderables/constrain.js +31 -0
  92. package/dist/renderables/effect.d.ts +98 -0
  93. package/dist/renderables/effect.js +160 -0
  94. package/dist/renderables/embed.d.ts +107 -0
  95. package/dist/renderables/embed.js +160 -0
  96. package/dist/renderables/flexStrip.d.ts +41 -0
  97. package/dist/renderables/flexStrip.js +200 -0
  98. package/dist/renderables/group.d.ts +14 -0
  99. package/dist/renderables/group.js +22 -0
  100. package/dist/renderables/layout.d.ts +75 -0
  101. package/dist/renderables/layout.js +223 -0
  102. package/dist/renderables/live.d.ts +74 -0
  103. package/dist/renderables/live.js +188 -0
  104. package/dist/renderables/markdown.d.ts +38 -0
  105. package/dist/renderables/markdown.js +587 -0
  106. package/dist/renderables/padding.d.ts +59 -0
  107. package/dist/renderables/padding.js +147 -0
  108. package/dist/renderables/panel.d.ts +114 -0
  109. package/dist/renderables/panel.js +303 -0
  110. package/dist/renderables/progress.d.ts +178 -0
  111. package/dist/renderables/progress.js +362 -0
  112. package/dist/renderables/progressBar.d.ts +31 -0
  113. package/dist/renderables/progressBar.js +64 -0
  114. package/dist/renderables/prompt.d.ts +71 -0
  115. package/dist/renderables/prompt.js +165 -0
  116. package/dist/renderables/ratio.d.ts +123 -0
  117. package/dist/renderables/ratio.js +213 -0
  118. package/dist/renderables/rule.d.ts +26 -0
  119. package/dist/renderables/rule.js +86 -0
  120. package/dist/renderables/spinner.d.ts +57 -0
  121. package/dist/renderables/spinner.js +103 -0
  122. package/dist/renderables/status.d.ts +29 -0
  123. package/dist/renderables/status.js +46 -0
  124. package/dist/renderables/syntax.d.ts +65 -0
  125. package/dist/renderables/syntax.js +166 -0
  126. package/dist/renderables/table.d.ts +232 -0
  127. package/dist/renderables/table.js +973 -0
  128. package/dist/renderables/traceback.d.ts +32 -0
  129. package/dist/renderables/traceback.js +279 -0
  130. package/dist/renderables/tree.d.ts +76 -0
  131. package/dist/renderables/tree.js +177 -0
  132. package/dist/renderables/viewport.d.ts +114 -0
  133. package/dist/renderables/viewport.js +196 -0
  134. package/dist/template-bindings/color-funcs.d.ts +109 -0
  135. package/dist/template-bindings/color-funcs.js +243 -0
  136. package/dist/template-bindings/helpers.d.ts +26 -0
  137. package/dist/template-bindings/helpers.js +33 -0
  138. package/dist/template-bindings/index.d.ts +119 -0
  139. package/dist/template-bindings/index.js +162 -0
  140. package/dist/template-bindings/palette-funcs.d.ts +96 -0
  141. package/dist/template-bindings/palette-funcs.js +145 -0
  142. package/dist/template-bindings/style-funcs.d.ts +28 -0
  143. package/dist/template-bindings/style-funcs.js +157 -0
  144. package/dist/themes/buildPalette.d.ts +57 -0
  145. package/dist/themes/buildPalette.js +100 -0
  146. package/dist/themes/colorMath.d.ts +94 -0
  147. package/dist/themes/colorMath.js +280 -0
  148. package/dist/themes/colorRef.d.ts +36 -0
  149. package/dist/themes/colorRef.js +78 -0
  150. package/dist/themes/data/ansi-tables.d.ts +14 -0
  151. package/dist/themes/data/ansi-tables.js +49 -0
  152. package/dist/themes/data/atom-one-dark.d.ts +3 -0
  153. package/dist/themes/data/atom-one-dark.js +177 -0
  154. package/dist/themes/data/atom-one-light.d.ts +3 -0
  155. package/dist/themes/data/atom-one-light.js +177 -0
  156. package/dist/themes/data/catppuccin-frappe.d.ts +3 -0
  157. package/dist/themes/data/catppuccin-frappe.js +177 -0
  158. package/dist/themes/data/catppuccin-latte.d.ts +3 -0
  159. package/dist/themes/data/catppuccin-latte.js +177 -0
  160. package/dist/themes/data/catppuccin-macchiato.d.ts +3 -0
  161. package/dist/themes/data/catppuccin-macchiato.js +177 -0
  162. package/dist/themes/data/catppuccin-mocha.d.ts +3 -0
  163. package/dist/themes/data/catppuccin-mocha.js +177 -0
  164. package/dist/themes/data/cyberpunk.d.ts +17 -0
  165. package/dist/themes/data/cyberpunk.js +193 -0
  166. package/dist/themes/data/default.d.ts +3 -0
  167. package/dist/themes/data/default.js +160 -0
  168. package/dist/themes/data/dracula.d.ts +3 -0
  169. package/dist/themes/data/dracula.js +177 -0
  170. package/dist/themes/data/flexoki.d.ts +3 -0
  171. package/dist/themes/data/flexoki.js +177 -0
  172. package/dist/themes/data/gruvbox.d.ts +3 -0
  173. package/dist/themes/data/gruvbox.js +177 -0
  174. package/dist/themes/data/index.d.ts +35 -0
  175. package/dist/themes/data/index.js +64 -0
  176. package/dist/themes/data/monokai.d.ts +3 -0
  177. package/dist/themes/data/monokai.js +177 -0
  178. package/dist/themes/data/nord.d.ts +3 -0
  179. package/dist/themes/data/nord.js +177 -0
  180. package/dist/themes/data/rose-pine-dawn.d.ts +3 -0
  181. package/dist/themes/data/rose-pine-dawn.js +177 -0
  182. package/dist/themes/data/rose-pine-moon.d.ts +3 -0
  183. package/dist/themes/data/rose-pine-moon.js +177 -0
  184. package/dist/themes/data/rose-pine.d.ts +3 -0
  185. package/dist/themes/data/rose-pine.js +177 -0
  186. package/dist/themes/data/solarized-dark.d.ts +3 -0
  187. package/dist/themes/data/solarized-dark.js +177 -0
  188. package/dist/themes/data/solarized-light.d.ts +3 -0
  189. package/dist/themes/data/solarized-light.js +177 -0
  190. package/dist/themes/data/svg-export.d.ts +3 -0
  191. package/dist/themes/data/svg-export.js +177 -0
  192. package/dist/themes/data/textual-ansi.d.ts +3 -0
  193. package/dist/themes/data/textual-ansi.js +160 -0
  194. package/dist/themes/data/textual-dark.d.ts +3 -0
  195. package/dist/themes/data/textual-dark.js +160 -0
  196. package/dist/themes/data/textual-light.d.ts +3 -0
  197. package/dist/themes/data/textual-light.js +160 -0
  198. package/dist/themes/data/tokyo-night.d.ts +3 -0
  199. package/dist/themes/data/tokyo-night.js +177 -0
  200. package/dist/themes/data/types.d.ts +31 -0
  201. package/dist/themes/data/types.js +10 -0
  202. package/dist/themes/palette.d.ts +45 -0
  203. package/dist/themes/palette.js +71 -0
  204. package/dist/themes/ramp.d.ts +70 -0
  205. package/dist/themes/ramp.js +103 -0
  206. package/dist/themes/registry.d.ts +44 -0
  207. package/dist/themes/registry.js +105 -0
  208. package/dist/themes/terminalThemes.d.ts +49 -0
  209. package/dist/themes/terminalThemes.js +63 -0
  210. package/dist/themes/transpose.d.ts +87 -0
  211. package/dist/themes/transpose.js +138 -0
  212. package/dist/widgets/button.d.ts +45 -0
  213. package/dist/widgets/button.js +177 -0
  214. package/dist/widgets/checkbox.d.ts +38 -0
  215. package/dist/widgets/checkbox.js +135 -0
  216. package/dist/widgets/dropdown.d.ts +64 -0
  217. package/dist/widgets/dropdown.js +416 -0
  218. package/dist/widgets/event-router.d.ts +71 -0
  219. package/dist/widgets/event-router.js +629 -0
  220. package/dist/widgets/focus-manager.d.ts +45 -0
  221. package/dist/widgets/focus-manager.js +191 -0
  222. package/dist/widgets/hit.d.ts +64 -0
  223. package/dist/widgets/hit.js +113 -0
  224. package/dist/widgets/index.d.ts +20 -0
  225. package/dist/widgets/index.js +14 -0
  226. package/dist/widgets/ink.d.ts +22 -0
  227. package/dist/widgets/ink.js +31 -0
  228. package/dist/widgets/slider.d.ts +54 -0
  229. package/dist/widgets/slider.js +247 -0
  230. package/dist/widgets/static-item.d.ts +34 -0
  231. package/dist/widgets/static-item.js +54 -0
  232. package/dist/widgets/text-input.d.ts +283 -0
  233. package/dist/widgets/text-input.js +1174 -0
  234. package/dist/widgets/themed-widget.d.ts +20 -0
  235. package/dist/widgets/themed-widget.js +89 -0
  236. package/dist/widgets/toggle.d.ts +41 -0
  237. package/dist/widgets/toggle.js +157 -0
  238. package/dist/widgets/types.d.ts +87 -0
  239. package/dist/widgets/types.js +30 -0
  240. package/dist/widgets/widget-app.d.ts +65 -0
  241. package/dist/widgets/widget-app.js +206 -0
  242. package/dist/widgets/widget-base.d.ts +42 -0
  243. package/dist/widgets/widget-base.js +172 -0
  244. package/package.json +16 -2
@@ -0,0 +1,6 @@
1
+ export { BrowserTerminalHost } from "./terminal-host.js";
2
+ export type { TerminalHost, TerminalSize, DataHandler, ResizeHandler, ExitHandler, BrowserTerminalHostOptions, XtermTerminal, XtermDisposable, XtermResizeEvent, } from "./terminal-host.js";
3
+ export { hostEnvironment } from "./host-environment.js";
4
+ export { App } from "./app.js";
5
+ export type { AppOptions, AppPhase } from "./app.js";
6
+ export type { Surface } from "../core/paint.js";
@@ -0,0 +1,3 @@
1
+ export { BrowserTerminalHost } from "./terminal-host.js";
2
+ export { hostEnvironment } from "./host-environment.js";
3
+ export { App } from "./app.js";
@@ -0,0 +1,180 @@
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
+ import type { Env } from "../core/env.js";
41
+ export interface TerminalSize {
42
+ readonly cols: number;
43
+ readonly rows: number;
44
+ }
45
+ export type DataHandler = (chunk: Uint8Array | string) => void;
46
+ export type ResizeHandler = (size: TerminalSize) => void;
47
+ export type ExitHandler = () => void;
48
+ export interface TerminalHost {
49
+ /**
50
+ * Write raw bytes (or UTF-8 text) to the terminal as a program's output
51
+ * reaches it: no escape interpretation, no framing, and a terminal on a
52
+ * tty receives each newline as carriage return + newline, the tty's own
53
+ * output translation, which node's raw mode leaves on. A host with no tty
54
+ * in front of its terminal does that translation itself.
55
+ */
56
+ write(data: Uint8Array | string): void;
57
+ /**
58
+ * Subscribe to input data. The host emits whatever its underlying
59
+ * transport produces (Buffer on node, string on browser xterm.js); the
60
+ * runtime's parser accepts either.
61
+ */
62
+ onData(handler: DataHandler): Unsubscribe;
63
+ /**
64
+ * Subscribe to terminal resize events. The handler fires with the new
65
+ * size after a resize is observed.
66
+ */
67
+ onResize(handler: ResizeHandler): Unsubscribe;
68
+ /** Current terminal size in cells. Always returns a valid size. */
69
+ size(): TerminalSize;
70
+ /**
71
+ * Enable or disable raw mode on the input side. Implementations whose
72
+ * transport has no "cooked" mode (xterm.js, non-TTY pipes) silently
73
+ * no-op so callers don't need to branch on capability.
74
+ */
75
+ setRawMode(raw: boolean): void;
76
+ /**
77
+ * Whether the host is connected to a real interactive terminal — input and
78
+ * output both: what an interactive program checks before it starts.
79
+ */
80
+ readonly isTTY: boolean;
81
+ /**
82
+ * Whether the bytes `write` sends land on a terminal, whatever the input
83
+ * is. Colour detection asks this: a program with piped stdin and a terminal
84
+ * stdout still draws on a terminal, and `isTTY` would call it plain.
85
+ */
86
+ readonly writesToTerminal: boolean;
87
+ /**
88
+ * The environment a program running on this terminal sees — `TERM`,
89
+ * `COLORTERM`, `NO_COLOR` and the rest. Colour detection reads it: what a
90
+ * terminal can draw is a fact about the host, so it travels with the host
91
+ * rather than being read off whatever `process` the renderer happens to
92
+ * share a runtime with, which in a browser is none.
93
+ */
94
+ readonly env: Env;
95
+ /**
96
+ * Run `handler` once, when the program ends by any path this host can
97
+ * observe, so whoever changed the terminal can hand it back. The program
98
+ * still ends as it would have without the handler: a signal still
99
+ * terminates and a crash is still reported.
100
+ */
101
+ onExit(handler: ExitHandler): Unsubscribe;
102
+ /**
103
+ * Hand the terminal to whatever launched the program, and resolve once it
104
+ * hands it back. Raw mode delivers Ctrl+Z as a key rather than a signal, so
105
+ * suspending is something a program asks for, and it restores the terminal
106
+ * before asking.
107
+ */
108
+ suspend(): Promise<void>;
109
+ /**
110
+ * Begin the host's lifecycle. Implementations attach whatever resources
111
+ * they own — or no-op when there is nothing to attach. Idempotent. See
112
+ * the concrete host's own JSDoc for what its `start()` actually does:
113
+ * `NodeTerminalHost` and `BrowserTerminalHost` both no-op because their
114
+ * underlying transports (process streams; a caller-managed xterm.js
115
+ * Terminal) are already live by the time the host is constructed.
116
+ */
117
+ start(): void;
118
+ /**
119
+ * Stop the host's lifecycle. Pairs with `start`. Idempotent. After
120
+ * `stop()`, the host releases its own subscriptions to the underlying
121
+ * transport and clears its handler sets; the transport itself is not
122
+ * torn down (that is the caller's concern — process streams persist;
123
+ * an xterm.js Terminal is disposed by the caller). Re-subscribing via
124
+ * `onData` / `onResize` after `stop()` re-engages the host.
125
+ */
126
+ stop(): void;
127
+ }
128
+ /**
129
+ * Subset of xterm.js's `Terminal` surface the browser host depends on.
130
+ *
131
+ * [LAW:locality-or-seam] Declaring the dependency by *shape* — rather than
132
+ * importing xterm.js's types — keeps this package free of an xterm.js
133
+ * dev-dep at the type level, lets the browser-bundle pipeline (downstream
134
+ * ticket) pin whichever xterm.js version it wants, and lets unit tests
135
+ * pass a hand-built fake: ask for exactly the capabilities the host uses,
136
+ * no more.
137
+ */
138
+ export interface XtermDisposable {
139
+ dispose(): void;
140
+ }
141
+ export interface XtermResizeEvent {
142
+ cols: number;
143
+ rows: number;
144
+ }
145
+ export interface XtermTerminal {
146
+ readonly cols: number;
147
+ readonly rows: number;
148
+ write(data: Uint8Array | string): void;
149
+ onData(handler: (data: string) => void): XtermDisposable;
150
+ onResize(handler: (size: XtermResizeEvent) => void): XtermDisposable;
151
+ }
152
+ export interface BrowserTerminalHostOptions {
153
+ /**
154
+ * The xterm.js `Terminal` instance to wrap. The caller is responsible
155
+ * for its DOM lifecycle (`terminal.open(element)`, `terminal.dispose()`)
156
+ * — the host only owns its own subscriber lifecycle, exactly mirroring
157
+ * `NodeTerminalHost`'s relationship to `process.stdin`/`process.stdout`.
158
+ */
159
+ terminal: XtermTerminal;
160
+ }
161
+ export declare class BrowserTerminalHost implements TerminalHost {
162
+ private readonly terminal;
163
+ private readonly dataHandlers;
164
+ private readonly resizeHandlers;
165
+ private dataSubscription;
166
+ private resizeSubscription;
167
+ constructor(options: BrowserTerminalHostOptions);
168
+ get isTTY(): boolean;
169
+ get writesToTerminal(): boolean;
170
+ get env(): Env;
171
+ write(data: Uint8Array | string): void;
172
+ size(): TerminalSize;
173
+ setRawMode(_raw: boolean): void;
174
+ onExit(_handler: ExitHandler): Unsubscribe;
175
+ suspend(): Promise<void>;
176
+ onData(handler: DataHandler): Unsubscribe;
177
+ onResize(handler: ResizeHandler): Unsubscribe;
178
+ start(): void;
179
+ stop(): void;
180
+ }
@@ -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
+ }
@@ -0,0 +1,98 @@
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, parseHexColor, blendRgb, resolveColorSystem, detectColorSystem, resolveDestination, STANDARD_TABLE, EIGHT_BIT_TABLE, WINDOWS_TABLE, ANSI_COLOR_NAMES, } from "./core/color.js";
4
+ export type { ColorSystemName, 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, ColorRefError } 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 } from "./themes/ramp.js";
17
+ export type { ColorStop } from "./themes/ramp.js";
18
+ export { EASES, Phase, cubicBezier, parseEase, steps } from "./core/easing.js";
19
+ export type { Ease, StepPosition } from "./core/easing.js";
20
+ export { frameRate, systemClock } from "./core/clock.js";
21
+ export type { Clock, FrameRate } from "./core/clock.js";
22
+ export { Style, StyleSyntaxError, StyleStack, Theme, NULL_STYLE, DEFAULT_STYLES, } from "./core/style.js";
23
+ export type { StyleOptions, TextStyle, LayeredStyle } from "./core/style.js";
24
+ export { Segment, ControlType, } from "./core/segment.js";
25
+ export type { ControlCode } from "./core/segment.js";
26
+ export type { Anchor } from "./core/anchor.js";
27
+ export { Box } from "./core/box.js";
28
+ export type { EdgeChars, ContentChars, RowLevel, SubstituteOptions } from "./core/box.js";
29
+ 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";
30
+ export { isRenderable, isMeasurable, withCellWidth, withBoundedWidth, insetHeight, stackedHeight, regionRows, fitHeight, getStyle, } from "./core/protocol.js";
31
+ export type { RenderOptions, OverflowMethod, Height, Renderable, Measurable, StyleErrorHandler, } from "./core/protocol.js";
32
+ export type { Unsubscribe } from "./core/subscription.js";
33
+ export { Measurement, measureRenderables } from "./core/measure.js";
34
+ export { Span, RichText } from "./core/text.js";
35
+ export type { RichTextOptions } from "./core/text.js";
36
+ export { Strip, PowerlineJoiner, SEAM_MIN_DELTA_E, POWERLINE_JOINER_GLYPHS, CapsuleJoiner, PlainJoiner, GradientJoiner, } from "./core/strip.js";
37
+ export type { StyledRenderable, Joiner, PowerlineJoinerOptions, CapsuleJoinerOptions, PlainJoinerOptions, GradientJoinerOptions, } from "./core/strip.js";
38
+ export { renderToString, segmentToString, segmentsToString, } from "./core/render.js";
39
+ export type { RenderToStringOptions } from "./core/render.js";
40
+ export { OSC8, osc8Sequences } from "./core/osc8.js";
41
+ export type { Osc8Sequence } from "./core/osc8.js";
42
+ export { AnsiDecoder, decodeAnsi } from "./core/ansi.js";
43
+ export { MarkupRegistry, globalMarkupRegistry, renderMarkup, } from "./core/markup.js";
44
+ export type { MarkupTagContext, MarkupTagHandler, RenderMarkupOptions, } from "./core/markup.js";
45
+ export { EMOJI, emojiReplace, Emoji, NoEmoji } from "./core/emoji.js";
46
+ export { MarkupError, MarkupSyntaxError, escape as escapeMarkup } from "./core/markup.js";
47
+ export { Highlighter, NullHighlighter, RegexHighlighter, ReprHighlighter, JSONHighlighter, ISO8601Highlighter, } from "./core/highlighter.js";
48
+ export { Pretty } from "./core/pretty.js";
49
+ export type { PrettyOptions } from "./core/pretty.js";
50
+ export { JSONRenderable } from "./core/json.js";
51
+ export type { JSONOptions } from "./core/json.js";
52
+ export { SPINNERS, DEFAULT_SPINNER } from "./core/spinnerData.js";
53
+ export type { SpinnerData } from "./core/spinnerData.js";
54
+ export { Console } from "./core/console.js";
55
+ export type { ConsoleOptions, ConsoleSink, ConsoleStream, ConsoleEnvironment, LiveRegion, PrintOptions, } from "./core/console.js";
56
+ export type { Env } from "./core/env.js";
57
+ export { Constrain } from "./renderables/constrain.js";
58
+ export { Effected } from "./renderables/effect.js";
59
+ export type { CellColors, Effect, EffectCell, EffectedOptions } from "./renderables/effect.js";
60
+ export { Align } from "./renderables/align.js";
61
+ export type { Alignment } from "./core/place.js";
62
+ export { Padding } from "./renderables/padding.js";
63
+ export type { PaddingDimensions } from "./renderables/padding.js";
64
+ export { Viewport, SCROLLBAR } from "./renderables/viewport.js";
65
+ export type { Scrollbar, ScrollbarPart, ViewportOptions } from "./renderables/viewport.js";
66
+ export { Rule } from "./renderables/rule.js";
67
+ export type { RuleAlign, RuleOptions } from "./renderables/rule.js";
68
+ export { Panel } from "./renderables/panel.js";
69
+ export type { PanelOptions } from "./renderables/panel.js";
70
+ export { Group } from "./renderables/group.js";
71
+ export { ProgressBar } from "./renderables/progressBar.js";
72
+ export type { ProgressBarOptions } from "./renderables/progressBar.js";
73
+ export { Spinner } from "./renderables/spinner.js";
74
+ export type { SpinnerOptions } from "./renderables/spinner.js";
75
+ export { Table, Column } from "./renderables/table.js";
76
+ export type { TableOptions, ColumnOptions } from "./renderables/table.js";
77
+ export { Tree } from "./renderables/tree.js";
78
+ export type { TreeOptions } from "./renderables/tree.js";
79
+ export { Columns } from "./renderables/columns.js";
80
+ export type { ColumnsOptions } from "./renderables/columns.js";
81
+ export { FlexStrip } from "./renderables/flexStrip.js";
82
+ export type { FlexStripOptions, FlexAlign } from "./renderables/flexStrip.js";
83
+ export { Live } from "./renderables/live.js";
84
+ export type { LiveOptions } from "./renderables/live.js";
85
+ export { Status } from "./renderables/status.js";
86
+ export type { StatusOptions } from "./renderables/status.js";
87
+ export { Progress, TextColumn, BarColumn, TaskProgressColumn, TimeRemainingColumn, TimeElapsedColumn, SpinnerColumn, MofNCompleteColumn, track, } from "./renderables/progress.js";
88
+ export type { MofNCompleteColumnOptions, ProgressColumn, ProgressOptions, SpinnerColumnOptions, Task, TaskOptions, TaskUpdateOptions, TimeRemainingColumnOptions, } from "./renderables/progress.js";
89
+ export { Prompt, IntPrompt, FloatPrompt, Confirm } from "./renderables/prompt.js";
90
+ export type { ConfirmOptions, PromptInput, PromptOptions } from "./renderables/prompt.js";
91
+ export { Traceback } from "./renderables/traceback.js";
92
+ export type { TracebackOptions } from "./renderables/traceback.js";
93
+ export { Syntax } from "./renderables/syntax.js";
94
+ export type { SyntaxLanguage, SyntaxOptions } from "./renderables/syntax.js";
95
+ export { Markdown } from "./renderables/markdown.js";
96
+ export type { MarkdownOptions } from "./renderables/markdown.js";
97
+ export { Layout } from "./renderables/layout.js";
98
+ export type { LayoutOptions } from "./renderables/layout.js";
package/dist/index.js ADDED
@@ -0,0 +1,114 @@
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, parseHexColor, 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, ColorRefError } 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` ease, a threshold cascade) stays inside the
28
+ // theme system instead of being computed beside it.
29
+ export { ColorRamp } from "./themes/ramp.js";
30
+ // Progress in [0, 1]: phases turn seconds into it, eases reshape it. One
31
+ // vocabulary for ramps and time-based effects alike, CSS's names throughout.
32
+ export { EASES, Phase, cubicBezier, parseEase, steps } from "./core/easing.js";
33
+ // The time source and timer whoever draws frames is handed, and the one
34
+ // parser of the rate it ticks at.
35
+ export { frameRate, systemClock } from "./core/clock.js";
36
+ export { Style, StyleSyntaxError, StyleStack, Theme, NULL_STYLE, DEFAULT_STYLES, } from "./core/style.js";
37
+ export { Segment, ControlType, } from "./core/segment.js";
38
+ export { Box } from "./core/box.js";
39
+ 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";
40
+ // Protocol
41
+ export { isRenderable, isMeasurable, withCellWidth, withBoundedWidth, insetHeight, stackedHeight, regionRows, fitHeight, getStyle, } from "./core/protocol.js";
42
+ // Measurement
43
+ export { Measurement, measureRenderables } from "./core/measure.js";
44
+ // Text
45
+ export { Span, RichText } from "./core/text.js";
46
+ // Strip + Joiner
47
+ export { Strip, PowerlineJoiner, SEAM_MIN_DELTA_E, POWERLINE_JOINER_GLYPHS, CapsuleJoiner, PlainJoiner, GradientJoiner, } from "./core/strip.js";
48
+ // renderToString — stateless one-shot emission
49
+ export { renderToString, segmentToString, segmentsToString, } from "./core/render.js";
50
+ // OSC 8 hyperlink wire grammar — for consumers that read rendered bytes back
51
+ export { OSC8, osc8Sequences } from "./core/osc8.js";
52
+ // ANSI bytes back into styled text
53
+ export { AnsiDecoder, decodeAnsi } from "./core/ansi.js";
54
+ // Markup plugin tags
55
+ export { MarkupRegistry, globalMarkupRegistry, renderMarkup, } from "./core/markup.js";
56
+ // Emoji
57
+ export { EMOJI, emojiReplace, Emoji, NoEmoji } from "./core/emoji.js";
58
+ // Markup
59
+ export { MarkupError, MarkupSyntaxError, escape as escapeMarkup } from "./core/markup.js";
60
+ // Highlighter
61
+ export { Highlighter, NullHighlighter, RegexHighlighter, ReprHighlighter, JSONHighlighter, ISO8601Highlighter, } from "./core/highlighter.js";
62
+ // Pretty
63
+ export { Pretty } from "./core/pretty.js";
64
+ // JSON
65
+ export { JSONRenderable } from "./core/json.js";
66
+ // Spinner data
67
+ export { SPINNERS, DEFAULT_SPINNER } from "./core/spinnerData.js";
68
+ // Console
69
+ export { Console } from "./core/console.js";
70
+ // Renderables
71
+ export { Constrain } from "./renderables/constrain.js";
72
+ export { Effected } from "./renderables/effect.js";
73
+ export { Align } from "./renderables/align.js";
74
+ export { Padding } from "./renderables/padding.js";
75
+ export { Viewport, SCROLLBAR } from "./renderables/viewport.js";
76
+ export { Rule } from "./renderables/rule.js";
77
+ export { Panel } from "./renderables/panel.js";
78
+ export { Group } from "./renderables/group.js";
79
+ export { ProgressBar } from "./renderables/progressBar.js";
80
+ export { Spinner } from "./renderables/spinner.js";
81
+ export { Table, Column } from "./renderables/table.js";
82
+ export { Tree } from "./renderables/tree.js";
83
+ export { Columns } from "./renderables/columns.js";
84
+ export { FlexStrip } from "./renderables/flexStrip.js";
85
+ export { Live } from "./renderables/live.js";
86
+ export { Status } from "./renderables/status.js";
87
+ export { Progress, TextColumn, BarColumn, TaskProgressColumn, TimeRemainingColumn, TimeElapsedColumn, SpinnerColumn, MofNCompleteColumn, track, } from "./renderables/progress.js";
88
+ export { Prompt, IntPrompt, FloatPrompt, Confirm } from "./renderables/prompt.js";
89
+ export { Traceback } from "./renderables/traceback.js";
90
+ export { Syntax } from "./renderables/syntax.js";
91
+ export { Markdown } from "./renderables/markdown.js";
92
+ export { Layout } from "./renderables/layout.js";
93
+ // The barrel stops at `renderables/`, and the two subsystems above it are reached
94
+ // through their own `package.json#exports` subpaths instead:
95
+ //
96
+ // `@promptctl/rich-js/widgets` — the interactive layer (pulls in `mobx`)
97
+ // `@promptctl/rich-js/template-bindings` — the styling vocabulary (pulls in
98
+ // `@promptctl/go-template-js`)
99
+ //
100
+ // `@promptctl/rich-js/host` is a third subpath but a different kind of thing: the
101
+ // terminal seam has no third-party dependency at all, and sits on its own subpath
102
+ // because it is what a *non*-interactive program reaches for. Folding it into either
103
+ // neighbour is what the split was undoing — inside `widgets/` it charged mobx to
104
+ // consumers who only wanted to write bytes; in this barrel it would put an I/O
105
+ // capability in front of consumers who never touch a terminal directly.
106
+ //
107
+ // `export … from` is a static edge, so anything named here is *evaluated* by every
108
+ // consumer, including one that only wanted a Table. Re-exporting the two subsystems
109
+ // therefore charged their dependencies to the whole package — mobx and, transitively,
110
+ // @noble/hashes. The subpaths make that cost something a consumer opts into, the same
111
+ // bargain `src/node/` strikes for Node built-ins.
112
+ //
113
+ // This is also why there is no widget list here to keep in sync: `src/widgets/index.ts`
114
+ // is that list, and a copy of it in this file would be a second one to drift from.
@@ -0,0 +1,34 @@
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
+ * The prompt is printed by the `Console` it was asked on — the app's, when it
17
+ * passed one as `console`, a new default one otherwise — and then a line is
18
+ * read, as Rich's `Console.input` prints its prompt and calls `input()`. So
19
+ * the prompt is coloured exactly as that console's own output would be and
20
+ * goes to its target: a console on stderr asks on stderr, beside the
21
+ * invalid-answer messages it prints. It goes as one logical line, never broken
22
+ * at the console's width: the terminal wraps it at whatever width it has.
23
+ *
24
+ * readline reads in non-terminal mode, the terminal's own cooked line
25
+ * discipline, as Python's `input()` does without its readline module: in
26
+ * terminal mode readline redraws the line itself, prompt included, and needs a
27
+ * whole `tty.WriteStream` to draw on, which a console's target need not be.
28
+ *
29
+ * [LAW:single-enforcer] One readline interface per `nodeAsk` call —
30
+ * created, asked, closed. No shared `rl` across prompts, no listener-leak
31
+ * pitfalls when callers stack prompts in a loop.
32
+ */
33
+ import type { PromptInput } from "../renderables/prompt.js";
34
+ export declare const nodeAsk: PromptInput;