@gridland/web 0.2.16 → 0.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,269 @@
1
+ // Core shims barrel — aliased as @opentui/core by Vite
2
+ // Re-exports portable code from opentui and swaps in browser replacements.
3
+ // Vite aliases intercept zig, buffer, text-buffer, text-buffer-view,
4
+ // syntax-style, renderer, console, etc. before they reach the filesystem.
5
+
6
+ // ─── Pure TS re-exports ───────────────────────────────────────────────────
7
+
8
+ // RGBA and color utilities (our own copy to avoid pulling in opentui's lib/index)
9
+ export { RGBA, parseColor, hexToRgb, rgbToHex, hsvToRgb } from "./rgba"
10
+ export type { ColorInput } from "./rgba"
11
+
12
+ // Types
13
+ export {
14
+ TextAttributes,
15
+ ATTRIBUTE_BASE_BITS,
16
+ ATTRIBUTE_BASE_MASK,
17
+ getBaseAttributes,
18
+ DebugOverlayCorner,
19
+ } from "./types"
20
+ export type {
21
+ RenderContext,
22
+ ThemeMode,
23
+ CursorStyle,
24
+ CursorStyleOptions,
25
+ MousePointerStyle,
26
+ WidthMethod,
27
+ Timeout,
28
+ ViewportBounds,
29
+ Highlight,
30
+ LineInfo,
31
+ LineInfoProvider,
32
+ CapturedSpan,
33
+ CapturedLine,
34
+ CapturedFrame,
35
+ } from "./types"
36
+
37
+ // ─── Re-exports from opentui source (Vite intercepts Zig deps) ───────────
38
+
39
+ // Renderable base classes (needed by our own code — main.tsx uses RootRenderable)
40
+ // NOTE: The opentui react package imports from the real opentui barrel instead
41
+ // (redirected by the Vite plugin) to avoid cross-barrel circular dependency issues.
42
+ export {
43
+ Renderable,
44
+ BaseRenderable,
45
+ RootRenderable,
46
+ LayoutEvents,
47
+ RenderableEvents,
48
+ isRenderable,
49
+ } from "../../../../opentui/packages/core/src/Renderable"
50
+ export type {
51
+ RenderableOptions,
52
+ LayoutOptions,
53
+ BaseRenderableOptions,
54
+ Position,
55
+ RenderCommand,
56
+ } from "../../../../opentui/packages/core/src/Renderable"
57
+
58
+ // Border (pure TS)
59
+ export {
60
+ BorderChars,
61
+ BorderCharArrays,
62
+ isValidBorderStyle,
63
+ parseBorderStyle,
64
+ getBorderFromSides,
65
+ getBorderSides,
66
+ borderCharsToArray,
67
+ } from "../../../../opentui/packages/core/src/lib/border"
68
+ export type {
69
+ BorderCharacters,
70
+ BorderStyle,
71
+ BorderSides,
72
+ BorderConfig,
73
+ BoxDrawOptions,
74
+ BorderSidesConfig,
75
+ } from "../../../../opentui/packages/core/src/lib/border"
76
+
77
+ // Styled text (pure TS)
78
+ export {
79
+ StyledText,
80
+ isStyledText,
81
+ stringToStyledText,
82
+ t,
83
+ bold,
84
+ italic,
85
+ underline,
86
+ strikethrough,
87
+ dim,
88
+ reverse,
89
+ blink,
90
+ fg,
91
+ bg,
92
+ black,
93
+ red,
94
+ green,
95
+ yellow,
96
+ blue,
97
+ magenta,
98
+ cyan,
99
+ white,
100
+ } from "../../../../opentui/packages/core/src/lib/styled-text"
101
+
102
+ // Yoga options (pure TS)
103
+ export {
104
+ parseAlign,
105
+ parseAlignItems,
106
+ parseFlexDirection,
107
+ parseJustify,
108
+ parseOverflow,
109
+ parsePositionType,
110
+ parseWrap,
111
+ } from "../../../../opentui/packages/core/src/lib/yoga.options"
112
+ export type {
113
+ AlignString,
114
+ FlexDirectionString,
115
+ JustifyString,
116
+ OverflowString,
117
+ PositionTypeString,
118
+ WrapString,
119
+ } from "../../../../opentui/packages/core/src/lib/yoga.options"
120
+
121
+ // Renderable validations (pure TS)
122
+ export {
123
+ validateOptions,
124
+ isPositionType,
125
+ isDimensionType,
126
+ isFlexBasisType,
127
+ isSizeType,
128
+ isMarginType,
129
+ isPaddingType,
130
+ isPositionTypeType,
131
+ isOverflowType,
132
+ } from "../../../../opentui/packages/core/src/lib/renderable.validations"
133
+
134
+ // Selection (pure TS)
135
+ export {
136
+ Selection,
137
+ convertGlobalToLocalSelection,
138
+ } from "../../../../opentui/packages/core/src/lib/selection"
139
+
140
+ // VNode composition (pure TS)
141
+ export { maybeMakeRenderable } from "../../../../opentui/packages/core/src/renderables/composition/vnode"
142
+ export type { VNode } from "../../../../opentui/packages/core/src/renderables/composition/vnode"
143
+
144
+ // ─── Renderable subclasses (re-exported from individual files, not barrel) ─
145
+
146
+ // These are needed by @opentui/react for the component catalogue and host-config.
147
+ // File-level shims (zig, buffer, renderer, etc.) handle their internal imports.
148
+ export * from "../../../../opentui/packages/core/src/renderables/Box"
149
+ export * from "../../../../opentui/packages/core/src/renderables/Text"
150
+ export * from "../../../../opentui/packages/core/src/renderables/TextNode"
151
+ export * from "../../../../opentui/packages/core/src/renderables/Code"
152
+ export * from "../../../../opentui/packages/core/src/renderables/Diff"
153
+ export * from "../../../../opentui/packages/core/src/renderables/Input"
154
+ export * from "../../../../opentui/packages/core/src/renderables/Select"
155
+ export * from "../../../../opentui/packages/core/src/renderables/TabSelect"
156
+ export * from "../../../../opentui/packages/core/src/renderables/Textarea"
157
+ export * from "../../../../opentui/packages/core/src/renderables/ScrollBox"
158
+ export * from "../../../../opentui/packages/core/src/renderables/ScrollBar"
159
+ export * from "../../../../opentui/packages/core/src/renderables/Slider"
160
+ export * from "../../../../opentui/packages/core/src/renderables/ASCIIFont"
161
+ export * from "../../../../opentui/packages/core/src/renderables/LineNumberRenderable"
162
+ export * from "../../../../opentui/packages/core/src/renderables/Markdown"
163
+ export * from "../../../../opentui/packages/core/src/renderables/FrameBuffer"
164
+ export * from "../../../../opentui/packages/core/src/renderables/TextBufferRenderable"
165
+ import { TextBufferRenderable } from "../../../../opentui/packages/core/src/renderables/TextBufferRenderable"
166
+
167
+ // Gridland extension: textAlign property on TextBufferRenderable
168
+ // Proxies to the BrowserTextBufferView's textAlign property for centered text rendering.
169
+ Object.defineProperty(TextBufferRenderable.prototype, "textAlign", {
170
+ get(this: any) {
171
+ return this.textBufferView?.textAlign ?? "left"
172
+ },
173
+ set(this: any, value: "left" | "center" | "right") {
174
+ if (this.textBufferView) {
175
+ this.textBufferView.textAlign = value
176
+ this.requestRender()
177
+ }
178
+ },
179
+ enumerable: true,
180
+ configurable: true,
181
+ })
182
+
183
+ // ─── Browser replacements ─────────────────────────────────────────────────
184
+
185
+ // Buffer — browser replacement
186
+ export { BrowserBuffer as OptimizedBuffer } from "../browser-buffer"
187
+
188
+ // TextBuffer — browser replacement
189
+ export { BrowserTextBuffer as TextBuffer } from "../browser-text-buffer"
190
+ export type { TextChunk } from "../browser-text-buffer"
191
+
192
+ // TextBufferView — browser replacement
193
+ export { BrowserTextBufferView as TextBufferView } from "../browser-text-buffer-view"
194
+
195
+ // SyntaxStyle — browser stub
196
+ export { BrowserSyntaxStyle as SyntaxStyle } from "../browser-syntax-style"
197
+
198
+ // ─── Stubs ────────────────────────────────────────────────────────────────
199
+
200
+ export function resolveRenderLib(): any {
201
+ return null
202
+ }
203
+
204
+ export type RenderLib = any
205
+ export type Pointer = number
206
+
207
+ // KeyHandler (re-implemented for browser)
208
+ export {
209
+ BrowserKeyHandler as KeyHandler,
210
+ BrowserInternalKeyHandler as InternalKeyHandler,
211
+ } from "../browser-render-context"
212
+
213
+ // Renderer — re-exported from shimmed source path (resolved to renderer-stub.ts)
214
+ export {
215
+ CliRenderer,
216
+ CliRenderEvents,
217
+ createCliRenderer,
218
+ } from "../../../../opentui/packages/core/src/renderer"
219
+ export type { MouseEvent } from "../../../../opentui/packages/core/src/renderer"
220
+
221
+ // Timeline & engine — re-exported from shimmed source path (resolved to timeline-stub.ts)
222
+ export {
223
+ Timeline,
224
+ engine,
225
+ createTimeline,
226
+ } from "../../../../opentui/packages/core/src/animation/Timeline"
227
+
228
+ // Yoga re-export
229
+ export * as Yoga from "yoga-layout"
230
+
231
+ // Stub types for mouse
232
+ export type MouseEventType = any
233
+
234
+ // Utils
235
+ export function createTextAttributes(opts: {
236
+ bold?: boolean
237
+ italic?: boolean
238
+ underline?: boolean
239
+ dim?: boolean
240
+ blink?: boolean
241
+ inverse?: boolean
242
+ hidden?: boolean
243
+ strikethrough?: boolean
244
+ } = {}): number {
245
+ const TA = {
246
+ NONE: 0, BOLD: 1, DIM: 2, ITALIC: 4, UNDERLINE: 8,
247
+ BLINK: 16, INVERSE: 32, HIDDEN: 64, STRIKETHROUGH: 128,
248
+ }
249
+ let attr = TA.NONE
250
+ if (opts.bold) attr |= TA.BOLD
251
+ if (opts.italic) attr |= TA.ITALIC
252
+ if (opts.underline) attr |= TA.UNDERLINE
253
+ if (opts.dim) attr |= TA.DIM
254
+ if (opts.blink) attr |= TA.BLINK
255
+ if (opts.inverse) attr |= TA.INVERSE
256
+ if (opts.hidden) attr |= TA.HIDDEN
257
+ if (opts.strikethrough) attr |= TA.STRIKETHROUGH
258
+ return attr
259
+ }
260
+
261
+ export function attributesWithLink(baseAttributes: number, linkId: number): number {
262
+ return (baseAttributes & 0xff) | ((linkId & 0xffffff) << 8)
263
+ }
264
+
265
+ export function getLinkId(attributes: number): number {
266
+ return (attributes >>> 8) & 0xffffff
267
+ }
268
+
269
+ export function visualizeRenderableTree(..._args: any[]): void {}
@@ -0,0 +1,4 @@
1
+ // Forward declaration types for circular dependency resolution
2
+ export type Renderable = any
3
+ export type BaseRenderable = any
4
+ export type RootRenderable = any
@@ -0,0 +1,195 @@
1
+ // Pure-TS RGBA - copied from opentui core for standalone use
2
+ // This avoids importing from opentui which pulls in Zig
3
+
4
+ export class RGBA {
5
+ buffer: Float32Array
6
+
7
+ constructor(buffer: Float32Array) {
8
+ this.buffer = buffer
9
+ }
10
+
11
+ static fromArray(array: Float32Array): RGBA {
12
+ return new RGBA(array)
13
+ }
14
+
15
+ static fromValues(r: number, g: number, b: number, a: number = 1.0): RGBA {
16
+ return new RGBA(new Float32Array([r, g, b, a]))
17
+ }
18
+
19
+ static fromInts(r: number, g: number, b: number, a: number = 255): RGBA {
20
+ return new RGBA(new Float32Array([r / 255, g / 255, b / 255, a / 255]))
21
+ }
22
+
23
+ static fromHex(hex: string): RGBA {
24
+ return hexToRgb(hex)
25
+ }
26
+
27
+ get r(): number {
28
+ return this.buffer[0]
29
+ }
30
+ set r(v: number) {
31
+ this.buffer[0] = v
32
+ }
33
+
34
+ get g(): number {
35
+ return this.buffer[1]
36
+ }
37
+ set g(v: number) {
38
+ this.buffer[1] = v
39
+ }
40
+
41
+ get b(): number {
42
+ return this.buffer[2]
43
+ }
44
+ set b(v: number) {
45
+ this.buffer[2] = v
46
+ }
47
+
48
+ get a(): number {
49
+ return this.buffer[3]
50
+ }
51
+ set a(v: number) {
52
+ this.buffer[3] = v
53
+ }
54
+
55
+ toInts(): [number, number, number, number] {
56
+ return [
57
+ Math.round(this.buffer[0] * 255),
58
+ Math.round(this.buffer[1] * 255),
59
+ Math.round(this.buffer[2] * 255),
60
+ Math.round(this.buffer[3] * 255),
61
+ ]
62
+ }
63
+
64
+ map<R>(fn: (value: number) => R): R[] {
65
+ return [fn(this.buffer[0]), fn(this.buffer[1]), fn(this.buffer[2]), fn(this.buffer[3])]
66
+ }
67
+
68
+ toString(): string {
69
+ const [r, g, b, a] = this.toInts()
70
+ return `rgba(${r}, ${g}, ${b}, ${a / 255})`
71
+ }
72
+
73
+ equals(other?: RGBA): boolean {
74
+ if (!other) return false
75
+ return (
76
+ this.buffer[0] === other.buffer[0] &&
77
+ this.buffer[1] === other.buffer[1] &&
78
+ this.buffer[2] === other.buffer[2] &&
79
+ this.buffer[3] === other.buffer[3]
80
+ )
81
+ }
82
+ }
83
+
84
+ export type ColorInput = string | RGBA
85
+
86
+ const CSS_COLOR_NAMES: Record<string, string> = {
87
+ black: "#000000",
88
+ white: "#ffffff",
89
+ red: "#ff0000",
90
+ green: "#008000",
91
+ blue: "#0000ff",
92
+ yellow: "#ffff00",
93
+ cyan: "#00ffff",
94
+ magenta: "#ff00ff",
95
+ silver: "#c0c0c0",
96
+ gray: "#808080",
97
+ grey: "#808080",
98
+ maroon: "#800000",
99
+ olive: "#808000",
100
+ lime: "#00ff00",
101
+ aqua: "#00ffff",
102
+ teal: "#008080",
103
+ navy: "#000080",
104
+ fuchsia: "#ff00ff",
105
+ purple: "#800080",
106
+ orange: "#ffa500",
107
+ transparent: "#00000000",
108
+ brightblack: "#808080",
109
+ brightred: "#ff5555",
110
+ brightgreen: "#55ff55",
111
+ brightyellow: "#ffff55",
112
+ brightblue: "#5555ff",
113
+ brightmagenta: "#ff55ff",
114
+ brightcyan: "#55ffff",
115
+ brightwhite: "#ffffff",
116
+ }
117
+
118
+ export function hexToRgb(hex: string): RGBA {
119
+ hex = hex.replace(/^#/, "")
120
+
121
+ if (hex.length === 3) {
122
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
123
+ }
124
+
125
+ if (hex.length === 6) {
126
+ hex = hex + "ff"
127
+ }
128
+
129
+ const r = parseInt(hex.substring(0, 2), 16) / 255
130
+ const g = parseInt(hex.substring(2, 4), 16) / 255
131
+ const b = parseInt(hex.substring(4, 6), 16) / 255
132
+ const a = parseInt(hex.substring(6, 8), 16) / 255
133
+
134
+ return RGBA.fromValues(r, g, b, a)
135
+ }
136
+
137
+ export function rgbToHex(rgb: RGBA): string {
138
+ const [r, g, b] = rgb.toInts()
139
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`
140
+ }
141
+
142
+ export function hsvToRgb(h: number, s: number, v: number): RGBA {
143
+ const c = v * s
144
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1))
145
+ const m = v - c
146
+ let r = 0,
147
+ g = 0,
148
+ b = 0
149
+
150
+ if (h < 60) {
151
+ r = c; g = x; b = 0
152
+ } else if (h < 120) {
153
+ r = x; g = c; b = 0
154
+ } else if (h < 180) {
155
+ r = 0; g = c; b = x
156
+ } else if (h < 240) {
157
+ r = 0; g = x; b = c
158
+ } else if (h < 300) {
159
+ r = x; g = 0; b = c
160
+ } else {
161
+ r = c; g = 0; b = x
162
+ }
163
+
164
+ return RGBA.fromValues(r + m, g + m, b + m, 1)
165
+ }
166
+
167
+ export function parseColor(color: ColorInput): RGBA {
168
+ if (color instanceof RGBA) return color
169
+ if (typeof color !== "string") return RGBA.fromValues(1, 1, 1, 1)
170
+
171
+ const lower = color.toLowerCase().trim()
172
+
173
+ // Check CSS named colors
174
+ if (CSS_COLOR_NAMES[lower]) {
175
+ return hexToRgb(CSS_COLOR_NAMES[lower])
176
+ }
177
+
178
+ // Hex
179
+ if (lower.startsWith("#")) {
180
+ return hexToRgb(lower)
181
+ }
182
+
183
+ // rgba(r, g, b, a)
184
+ const rgbaMatch = lower.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/)
185
+ if (rgbaMatch) {
186
+ return RGBA.fromInts(
187
+ parseInt(rgbaMatch[1]),
188
+ parseInt(rgbaMatch[2]),
189
+ parseInt(rgbaMatch[3]),
190
+ rgbaMatch[4] ? Math.round(parseFloat(rgbaMatch[4]) * 255) : 255,
191
+ )
192
+ }
193
+
194
+ return RGBA.fromValues(1, 1, 1, 1)
195
+ }
@@ -0,0 +1,132 @@
1
+ // Types matching opentui core types.ts
2
+ import type { RGBA } from "./rgba"
3
+ import type { Renderable } from "./renderable-types"
4
+
5
+ export const TextAttributes = {
6
+ NONE: 0,
7
+ BOLD: 1 << 0,
8
+ DIM: 1 << 1,
9
+ ITALIC: 1 << 2,
10
+ UNDERLINE: 1 << 3,
11
+ BLINK: 1 << 4,
12
+ INVERSE: 1 << 5,
13
+ HIDDEN: 1 << 6,
14
+ STRIKETHROUGH: 1 << 7,
15
+ }
16
+
17
+ export const ATTRIBUTE_BASE_BITS = 8
18
+ export const ATTRIBUTE_BASE_MASK = 0xff
19
+
20
+ export function getBaseAttributes(attr: number): number {
21
+ return attr & 0xff
22
+ }
23
+
24
+ export type ThemeMode = "dark" | "light"
25
+ export type CursorStyle = "block" | "line" | "underline"
26
+ export type MousePointerStyle = "default" | "pointer" | "text" | "crosshair" | "move" | "not-allowed"
27
+ export type WidthMethod = "wcwidth" | "unicode"
28
+ export type Timeout = ReturnType<typeof setTimeout> | undefined
29
+
30
+ export interface CursorStyleOptions {
31
+ style?: CursorStyle
32
+ blinking?: boolean
33
+ color?: RGBA
34
+ cursor?: MousePointerStyle
35
+ }
36
+
37
+ export enum DebugOverlayCorner {
38
+ topLeft = 0,
39
+ topRight = 1,
40
+ bottomLeft = 2,
41
+ bottomRight = 3,
42
+ }
43
+
44
+ export interface RenderContext {
45
+ addToHitGrid: (x: number, y: number, width: number, height: number, id: number) => void
46
+ pushHitGridScissorRect: (x: number, y: number, width: number, height: number) => void
47
+ popHitGridScissorRect: () => void
48
+ clearHitGridScissorRects: () => void
49
+ width: number
50
+ height: number
51
+ requestRender: () => void
52
+ setCursorPosition: (x: number, y: number, visible: boolean) => void
53
+ setCursorStyle: (options: CursorStyleOptions) => void
54
+ setCursorColor: (color: RGBA) => void
55
+ setMousePointer: (shape: MousePointerStyle) => void
56
+ widthMethod: WidthMethod
57
+ capabilities: any | null
58
+ requestLive: () => void
59
+ dropLive: () => void
60
+ hasSelection: boolean
61
+ getSelection: () => any | null
62
+ requestSelectionUpdate: () => void
63
+ currentFocusedRenderable: any | null
64
+ focusRenderable: (renderable: any) => void
65
+ registerLifecyclePass: (renderable: any) => void
66
+ unregisterLifecyclePass: (renderable: any) => void
67
+ getLifecyclePasses: () => Set<any>
68
+ keyInput: any
69
+ _internalKeyInput: any
70
+ clearSelection: () => void
71
+ startSelection: (renderable: any, x: number, y: number) => void
72
+ updateSelection: (
73
+ currentRenderable: any | undefined,
74
+ x: number,
75
+ y: number,
76
+ options?: { finishDragging?: boolean },
77
+ ) => void
78
+ // EventEmitter methods
79
+ on: (event: string, listener: (...args: any[]) => void) => any
80
+ off: (event: string, listener: (...args: any[]) => void) => any
81
+ emit: (event: string, ...args: any[]) => boolean
82
+ removeAllListeners: (event?: string) => any
83
+ }
84
+
85
+ export interface ViewportBounds {
86
+ x: number
87
+ y: number
88
+ width: number
89
+ height: number
90
+ }
91
+
92
+ export interface Highlight {
93
+ start: number
94
+ end: number
95
+ styleId: number
96
+ priority?: number | null
97
+ hlRef?: number | null
98
+ }
99
+
100
+ export interface LineInfo {
101
+ lineStarts: number[]
102
+ lineWidths: number[]
103
+ maxLineWidth: number
104
+ lineSources: number[]
105
+ lineWraps: number[]
106
+ }
107
+
108
+ export interface LineInfoProvider {
109
+ get lineInfo(): LineInfo
110
+ get lineCount(): number
111
+ get virtualLineCount(): number
112
+ get scrollY(): number
113
+ }
114
+
115
+ export interface CapturedSpan {
116
+ text: string
117
+ fg: RGBA
118
+ bg: RGBA
119
+ attributes: number
120
+ width: number
121
+ }
122
+
123
+ export interface CapturedLine {
124
+ spans: CapturedSpan[]
125
+ }
126
+
127
+ export interface CapturedFrame {
128
+ cols: number
129
+ rows: number
130
+ cursor: [number, number]
131
+ lines: CapturedLine[]
132
+ }
@@ -0,0 +1,20 @@
1
+ // Shim for bun-ffi-structs
2
+ export class Struct {
3
+ constructor(_def: any) {}
4
+ }
5
+
6
+ export function defineStruct(_def: any): any {
7
+ return class StubStruct {
8
+ constructor(..._args: any[]) {}
9
+ }
10
+ }
11
+
12
+ export function defineEnum(_def: any): any {
13
+ return {}
14
+ }
15
+
16
+ export function defineUnion(_def: any): any {
17
+ return class StubUnion {
18
+ constructor(..._args: any[]) {}
19
+ }
20
+ }
@@ -0,0 +1,28 @@
1
+ // Shim for bun:ffi - provides dummy types/stubs for browser environment
2
+ export type Pointer = number
3
+
4
+ export function toArrayBuffer(_ptr: Pointer, _offset: number, _size: number): ArrayBuffer {
5
+ return new ArrayBuffer(0)
6
+ }
7
+
8
+ export function ptr(_buf: ArrayBuffer): Pointer {
9
+ return 0
10
+ }
11
+
12
+ export function read(ptr: Pointer): { ptr: Pointer } {
13
+ return { ptr: 0 }
14
+ }
15
+
16
+ export function dlopen(_path: string, _symbols: Record<string, unknown>): { symbols: Record<string, unknown>; close(): void } {
17
+ return { symbols: {}, close() {} }
18
+ }
19
+
20
+ export class JSCallback {
21
+ ptr: Pointer = 0
22
+ constructor(_fn: (...args: unknown[]) => unknown, _options?: unknown) {}
23
+ close() {}
24
+ }
25
+
26
+ export function suffix(): string {
27
+ return ""
28
+ }
@@ -0,0 +1,13 @@
1
+ // Stub for opentui/packages/core/src/console.ts
2
+ export class TerminalConsole {
3
+ constructor(..._args: any[]) {}
4
+ }
5
+
6
+ export type ConsoleOptions = any
7
+
8
+ export function capture(..._args: any[]): any {
9
+ return null
10
+ }
11
+
12
+ export class Capture {}
13
+ export class CapturedWritableStream {}
@@ -0,0 +1,3 @@
1
+ // Shim for node:console - just re-export the global console
2
+ export const Console = globalThis.console.constructor
3
+ export default globalThis.console
@@ -0,0 +1,3 @@
1
+ // Browser-safe stub for devtools-polyfill.ts
2
+ // The original file uses top-level await to import `ws` for Node.js.
3
+ // In the browser, WebSocket is natively available, so we skip the import.