restty 0.1.16 → 0.1.18

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 (53) hide show
  1. package/README.md +4 -9
  2. package/dist/app/atlas-builder.d.ts +38 -0
  3. package/dist/app/font-sources.d.ts +2 -0
  4. package/dist/app/pane-app-manager.d.ts +43 -0
  5. package/dist/app/panes-context-menu.d.ts +10 -0
  6. package/dist/app/panes-styles.d.ts +5 -0
  7. package/dist/app/panes-types.d.ts +89 -0
  8. package/dist/app/panes.d.ts +10 -0
  9. package/dist/app/restty.d.ts +20 -0
  10. package/dist/app/session.d.ts +6 -0
  11. package/dist/app/types.d.ts +123 -0
  12. package/dist/{app/index.js → chunk-53vdvhe3.js} +24014 -23787
  13. package/dist/fonts/manager.d.ts +24 -0
  14. package/dist/fonts/nerd-constraints.d.ts +4 -0
  15. package/dist/fonts/nerd-ranges.d.ts +2 -0
  16. package/dist/fonts/types.d.ts +51 -0
  17. package/dist/grid/grid.d.ts +22 -0
  18. package/dist/grid/types.d.ts +32 -0
  19. package/dist/ime/ime.d.ts +13 -0
  20. package/dist/ime/types.d.ts +8 -0
  21. package/dist/input/ansi.d.ts +3 -0
  22. package/dist/input/mouse.d.ts +10 -0
  23. package/dist/input/output.d.ts +11 -0
  24. package/dist/input/types.d.ts +7 -0
  25. package/dist/internal.js +105 -56213
  26. package/dist/pty/kitty-media.d.ts +3 -0
  27. package/dist/pty/pty.d.ts +11 -0
  28. package/dist/pty/types.d.ts +49 -0
  29. package/dist/renderer/box-drawing-map.d.ts +4 -0
  30. package/dist/renderer/shaders.d.ts +7 -0
  31. package/dist/renderer/shapes.d.ts +42 -1
  32. package/dist/renderer/types.d.ts +43 -0
  33. package/dist/renderer/webgpu.d.ts +11 -0
  34. package/dist/restty.js +20 -0
  35. package/dist/selection/selection.d.ts +24 -0
  36. package/dist/selection/types.d.ts +13 -0
  37. package/dist/theme/catalog.d.ts +5 -0
  38. package/dist/theme/ghostty.d.ts +18 -0
  39. package/dist/unicode/ghostty-symbol-ranges.d.ts +1 -0
  40. package/dist/unicode/symbols.d.ts +6 -0
  41. package/dist/wasm/embedded.d.ts +1 -0
  42. package/dist/wasm/runtime.d.ts +29 -0
  43. package/package.json +8 -61
  44. package/dist/fonts/index.js +0 -5332
  45. package/dist/grid/index.js +0 -71
  46. package/dist/ime/index.js +0 -84
  47. package/dist/index.js +0 -56210
  48. package/dist/input/index.js +0 -1047
  49. package/dist/pty/index.js +0 -338
  50. package/dist/renderer/index.js +0 -1612
  51. package/dist/selection/index.js +0 -226
  52. package/dist/theme/index.js +0 -11218
  53. package/dist/wasm/index.js +0 -6003
@@ -1,5 +1,8 @@
1
+ /** State for streaming Kitty file-based media rewriting (tracks remainder across chunks). */
1
2
  export type KittyMediaRewriteState = {
2
3
  remainder?: string;
3
4
  };
5
+ /** Callback to read file contents for Kitty file-based media payloads. */
4
6
  export type KittyMediaReadFile = (path: string) => Uint8Array;
7
+ /** Rewrite Kitty file-based media sequences (f=...) to direct base64 payloads (t=d). */
5
8
  export declare function rewriteKittyFileMediaToDirect(chunk: string, state: KittyMediaRewriteState, readFile: KittyMediaReadFile): string;
package/dist/pty/pty.d.ts CHANGED
@@ -1,9 +1,20 @@
1
1
  import type { PtyCallbacks, PtyConnectionState, PtyConnectOptions, PtyTransport } from "./types";
2
+ /** Decode a binary WebSocket frame into a UTF-8 string using a streaming TextDecoder. */
2
3
  export declare function decodePtyBinary(decoder: TextDecoder, payload: ArrayBuffer | Uint8Array, stream?: boolean): string;
4
+ /** Create a fresh idle PTY connection state. */
3
5
  export declare function createPtyConnection(): PtyConnectionState;
6
+ /**
7
+ * Open a WebSocket connection to a PTY server. Returns false if the
8
+ * connection is already active or the URL is empty.
9
+ */
4
10
  export declare function connectPty(state: PtyConnectionState, options: Pick<PtyConnectOptions, "url" | "cols" | "rows">, callbacks: PtyCallbacks): boolean;
11
+ /** Gracefully close the PTY WebSocket connection and reset state to idle. */
5
12
  export declare function disconnectPty(state: PtyConnectionState): void;
13
+ /** Send terminal input data to the PTY server. Returns false if the socket is not open. */
6
14
  export declare function sendPtyInput(state: PtyConnectionState, data: string): boolean;
15
+ /** Send a resize notification to the PTY server. Returns false if the socket is not open. */
7
16
  export declare function sendPtyResize(state: PtyConnectionState, cols: number, rows: number): boolean;
17
+ /** Check whether the PTY WebSocket is currently open and connected. */
8
18
  export declare function isPtyConnected(state: PtyConnectionState): boolean;
19
+ /** Create a PtyTransport backed by a WebSocket connection. */
9
20
  export declare function createWebSocketPtyTransport(state?: PtyConnectionState): PtyTransport;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Messages sent from the client to the PTY server.
3
+ * - input: terminal keystrokes or pasted text
4
+ * - resize: window size change notification
5
+ */
1
6
  export type PtyMessage = {
2
7
  type: "input";
3
8
  data: string;
@@ -6,47 +11,91 @@ export type PtyMessage = {
6
11
  cols: number;
7
12
  rows: number;
8
13
  };
14
+ /** Server notification that the PTY session is ready, with the active shell name. */
9
15
  export type PtyStatusMessage = {
10
16
  type: "status";
11
17
  shell?: string;
12
18
  };
19
+ /** Server notification of an error during PTY operation. */
13
20
  export type PtyErrorMessage = {
14
21
  type: "error";
15
22
  message?: string;
16
23
  errors?: string[];
17
24
  };
25
+ /** Server notification that the PTY process has exited. */
18
26
  export type PtyExitMessage = {
19
27
  type: "exit";
20
28
  code?: number;
21
29
  };
30
+ /** Union of all message types sent from the PTY server to the client. */
22
31
  export type PtyServerMessage = PtyStatusMessage | PtyErrorMessage | PtyExitMessage;
32
+ /**
33
+ * PTY connection lifecycle phase.
34
+ * - idle: no active connection
35
+ * - connecting: WebSocket handshake in progress
36
+ * - connected: session is live
37
+ * - closing: teardown in progress
38
+ */
23
39
  export type PtyLifecycleState = "idle" | "connecting" | "connected" | "closing";
40
+ /**
41
+ * Internal state of a PTY WebSocket connection.
42
+ */
24
43
  export type PtyConnectionState = {
44
+ /** Active WebSocket instance, or null when disconnected. */
25
45
  socket: WebSocket | null;
46
+ /** Current lifecycle phase of the connection. */
26
47
  status: PtyLifecycleState;
48
+ /** WebSocket endpoint URL. */
27
49
  url: string;
50
+ /** Decoder for binary WebSocket frames, or null before connection. */
28
51
  decoder: TextDecoder | null;
52
+ /** Monotonic ID used to discard stale connection callbacks. */
29
53
  connectId: number;
30
54
  };
55
+ /**
56
+ * Event callbacks for PTY connection lifecycle and data flow.
57
+ */
31
58
  export type PtyCallbacks = {
59
+ /** Called when the WebSocket connection is established. */
32
60
  onConnect?: () => void;
61
+ /** Called when the connection is closed or lost. */
33
62
  onDisconnect?: () => void;
63
+ /** Called with terminal output data received from the PTY. */
34
64
  onData?: (data: string) => void;
65
+ /** Called with the shell name when the PTY reports its status. */
35
66
  onStatus?: (shell: string) => void;
67
+ /** Called when the PTY server reports an error. */
36
68
  onError?: (message: string, errors?: string[]) => void;
69
+ /** Called with the exit code when the PTY process terminates. */
37
70
  onExit?: (code: number) => void;
38
71
  };
72
+ /**
73
+ * Options for establishing a PTY connection.
74
+ */
39
75
  export type PtyConnectOptions = {
76
+ /** WebSocket endpoint URL to connect to. */
40
77
  url: string;
78
+ /** Initial terminal width in columns. */
41
79
  cols?: number;
80
+ /** Initial terminal height in rows. */
42
81
  rows?: number;
82
+ /** Event callbacks for connection lifecycle and data. */
43
83
  callbacks: PtyCallbacks;
44
84
  };
85
+ /**
86
+ * Transport abstraction for PTY communication (WebSocket, WebContainer, etc.).
87
+ */
45
88
  export type PtyTransport = {
89
+ /** Open a connection to the PTY server. */
46
90
  connect: (options: PtyConnectOptions) => void | Promise<void>;
91
+ /** Close the current connection. */
47
92
  disconnect: () => void;
93
+ /** Send terminal input data; returns true if the data was sent. */
48
94
  sendInput: (data: string) => boolean;
95
+ /** Notify the PTY of a terminal resize; returns true if the message was sent. */
49
96
  resize: (cols: number, rows: number) => boolean;
97
+ /** Whether the transport currently has an active connection. */
50
98
  isConnected: () => boolean;
99
+ /** Release all resources held by the transport. */
51
100
  destroy?: () => void | Promise<void>;
52
101
  };
@@ -1 +1,5 @@
1
+ /**
2
+ * Box drawing character line map.
3
+ * Maps Unicode codepoint to [up, right, down, left] line styles where 0=none, 1=light, 2=heavy, 3=double.
4
+ */
1
5
  export declare const BOX_LINE_MAP: Map<number, [number, number, number, number]>;
@@ -1,7 +1,14 @@
1
+ /** WebGPU WGSL shader for rendering solid-color rectangles. */
1
2
  export declare const RECT_SHADER = "\nstruct Uniforms {\n res: vec2f,\n _pad: vec2f,\n blend: vec2f,\n _pad2: vec2f,\n};\n\n@group(0) @binding(0) var<uniform> uniforms: Uniforms;\n\nstruct VSIn {\n @location(0) quad: vec2f,\n @location(1) pos: vec2f,\n @location(2) size: vec2f,\n @location(3) color: vec4f,\n};\n\nstruct VSOut {\n @builtin(position) position: vec4f,\n @location(0) color: vec4f,\n};\n\n// sRGB to linear conversion for proper blending\nfn srgbToLinear(c: f32) -> f32 {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\nfn srgbToLinear3(c: vec3f) -> vec3f {\n return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));\n}\n\n@vertex\nfn vsMain(input: VSIn) -> VSOut {\n let pixel = input.pos + input.quad * input.size;\n let clip = vec2f(\n (pixel.x / uniforms.res.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / uniforms.res.y) * 2.0\n );\n\n var out: VSOut;\n out.position = vec4f(clip.x, clip.y, 0.0, 1.0);\n out.color = input.color;\n return out;\n}\n\n@fragment\nfn fsMain(input: VSOut) -> @location(0) vec4f {\n let useLinear = uniforms.blend.x > 0.5;\n var color = input.color;\n if (useLinear) {\n color = vec4f(srgbToLinear3(color.rgb), color.a);\n }\n color = vec4f(color.rgb * color.a, color.a);\n return color;\n}\n";
3
+ /** WebGL2 vertex shader for rendering solid-color rectangles. */
2
4
  export declare const RECT_SHADER_GL_VERT = "#version 300 es\nprecision highp float;\n\nuniform vec2 u_resolution;\n\nlayout(location = 0) in vec2 a_quad;\nlayout(location = 1) in vec2 a_pos;\nlayout(location = 2) in vec2 a_size;\nlayout(location = 3) in vec4 a_color;\n\nout vec4 v_color;\n\nvoid main() {\n vec2 pixel = a_pos + a_quad * a_size;\n vec2 clip = vec2(\n (pixel.x / u_resolution.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / u_resolution.y) * 2.0\n );\n gl_Position = vec4(clip, 0.0, 1.0);\n v_color = a_color;\n}\n";
5
+ /** WebGL2 fragment shader for rendering solid-color rectangles with alpha blending. */
3
6
  export declare const RECT_SHADER_GL_FRAG = "#version 300 es\nprecision highp float;\n\nuniform vec2 u_blend;\n\nin vec4 v_color;\nout vec4 fragColor;\n\n// sRGB to linear conversion for proper blending\nfloat srgbToLinear(float c) {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinear(c.r), srgbToLinear(c.g), srgbToLinear(c.b));\n}\n\nvoid main() {\n bool useLinear = u_blend.x > 0.5;\n vec4 color = v_color;\n if (useLinear) {\n color.rgb = srgbToLinear(color.rgb);\n }\n color.rgb *= color.a;\n fragColor = color;\n}\n";
7
+ /** WebGL2 vertex shader for rendering textured glyph quads. */
4
8
  export declare const GLYPH_SHADER_GL_VERT = "#version 300 es\nprecision highp float;\n\nuniform vec2 u_resolution;\n\nlayout(location = 0) in vec2 a_quad;\nlayout(location = 1) in vec2 a_pos;\nlayout(location = 2) in vec2 a_size;\nlayout(location = 3) in vec2 a_uv0;\nlayout(location = 4) in vec2 a_uv1;\nlayout(location = 5) in vec4 a_color;\nlayout(location = 6) in vec4 a_bg;\nlayout(location = 7) in float a_slant;\nlayout(location = 8) in float a_mode;\n\nout vec2 v_uv;\nout vec4 v_color;\nout vec4 v_bg;\nout float v_mode;\n\nvoid main() {\n vec2 pixel = a_pos + vec2(a_quad.x * a_size.x + a_slant * (1.0 - a_quad.y), a_quad.y * a_size.y);\n vec2 clip = vec2(\n (pixel.x / u_resolution.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / u_resolution.y) * 2.0\n );\n v_uv = a_uv0 + (a_uv1 - a_uv0) * a_quad;\n gl_Position = vec4(clip, 0.0, 1.0);\n v_color = a_color;\n v_bg = a_bg;\n v_mode = a_mode;\n}\n";
9
+ /** WebGL2 fragment shader for sampling glyph atlas textures with linear filtering. */
5
10
  export declare const GLYPH_SHADER_GL_FRAG = "#version 300 es\nprecision highp float;\n\nuniform sampler2D u_atlas;\nuniform vec2 u_blend;\n\nin vec2 v_uv;\nin vec4 v_color;\nin vec4 v_bg;\nin float v_mode;\nout vec4 fragColor;\n\n// sRGB to linear conversion for proper blending\nfloat srgbToLinear(float c) {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\n// Linear to sRGB conversion\nfloat linearToSrgb(float c) {\n if (c <= 0.0031308) {\n return c * 12.92;\n }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\n\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinear(c.r), srgbToLinear(c.g), srgbToLinear(c.b));\n}\n\nvec3 linearToSrgb(vec3 c) {\n return vec3(linearToSrgb(c.r), linearToSrgb(c.g), linearToSrgb(c.b));\n}\n\nfloat luminance(vec3 color) {\n return dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\n\nvoid main() {\n vec4 atlasSample = texture(u_atlas, v_uv);\n bool useLinear = u_blend.x > 0.5;\n bool useCorrection = u_blend.y > 0.5;\n\n if (v_mode > 0.5) {\n vec4 color = atlasSample;\n if (useLinear) {\n color.rgb = srgbToLinear(color.rgb);\n }\n color.rgb *= color.a;\n fragColor = color;\n return;\n }\n\n vec4 fg = v_color;\n vec4 bg = v_bg;\n if (useLinear) {\n fg.rgb = srgbToLinear(fg.rgb);\n bg.rgb = srgbToLinear(bg.rgb);\n }\n fg.rgb *= fg.a;\n bg.rgb *= bg.a;\n\n float alpha = atlasSample.a;\n if (useCorrection && useLinear) {\n float fg_l = luminance(fg.rgb);\n float bg_l = luminance(bg.rgb);\n if (abs(fg_l - bg_l) > 0.001) {\n float blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));\n alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);\n }\n }\n\n vec4 color = fg * alpha;\n fragColor = color;\n}\n";
11
+ /** WebGPU WGSL shader for rendering textured glyph quads with linear atlas sampling. */
6
12
  export declare const GLYPH_SHADER = "\nstruct Uniforms {\n res: vec2f,\n _pad: vec2f,\n blend: vec2f,\n _pad2: vec2f,\n};\n\n@group(0) @binding(0) var<uniform> uniforms: Uniforms;\n@group(0) @binding(1) var atlasSampler: sampler;\n@group(0) @binding(2) var atlasTex: texture_2d<f32>;\n\nstruct VSIn {\n @location(0) quad: vec2f,\n @location(1) pos: vec2f,\n @location(2) size: vec2f,\n @location(3) uv0: vec2f,\n @location(4) uv1: vec2f,\n @location(5) color: vec4f,\n @location(6) bg: vec4f,\n @location(7) slant: f32,\n @location(8) mode: f32,\n};\n\nstruct VSOut {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) color: vec4f,\n @location(2) bg: vec4f,\n @location(3) mode: f32,\n};\n\n@vertex\nfn vsMain(input: VSIn) -> VSOut {\n let pixel = input.pos +\n vec2f(input.quad.x * input.size.x + input.slant * (1.0 - input.quad.y), input.quad.y * input.size.y);\n let clip = vec2f(\n (pixel.x / uniforms.res.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / uniforms.res.y) * 2.0\n );\n let uv = input.uv0 + (input.uv1 - input.uv0) * input.quad;\n\n var out: VSOut;\n out.position = vec4f(clip.x, clip.y, 0.0, 1.0);\n out.uv = uv;\n out.color = input.color;\n out.bg = input.bg;\n out.mode = input.mode;\n return out;\n}\n\n// sRGB to linear conversion for proper blending\nfn srgbToLinear(c: f32) -> f32 {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(c: f32) -> f32 {\n if (c <= 0.0031308) {\n return c * 12.92;\n }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\n\nfn srgbToLinear3(c: vec3f) -> vec3f {\n return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));\n}\n\nfn linearToSrgb3(c: vec3f) -> vec3f {\n return vec3f(linearToSrgb(c.x), linearToSrgb(c.y), linearToSrgb(c.z));\n}\n\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n@fragment\nfn fsMain(input: VSOut) -> @location(0) vec4f {\n let atlasSample = textureSample(atlasTex, atlasSampler, input.uv);\n let useLinear = uniforms.blend.x > 0.5;\n let useCorrection = uniforms.blend.y > 0.5;\n\n if (input.mode > 0.5) {\n var color = atlasSample;\n if (useLinear) {\n color = vec4f(srgbToLinear3(color.rgb), color.a);\n }\n return vec4f(color.rgb * color.a, color.a);\n }\n\n var alpha = atlasSample.a;\n\n var fg = input.color;\n var bg = input.bg;\n if (useLinear) {\n fg = vec4f(srgbToLinear3(fg.rgb), fg.a);\n bg = vec4f(srgbToLinear3(bg.rgb), bg.a);\n }\n fg = vec4f(fg.rgb * fg.a, fg.a);\n bg = vec4f(bg.rgb * bg.a, bg.a);\n\n if (useCorrection && useLinear) {\n let fg_l = luminance(fg.rgb);\n let bg_l = luminance(bg.rgb);\n if (abs(fg_l - bg_l) > 0.001) {\n let blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));\n alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);\n }\n }\n\n var color = fg * alpha;\n return color;\n}\n";
13
+ /** WebGPU WGSL shader for rendering textured glyph quads with nearest-neighbor atlas sampling. */
7
14
  export declare const GLYPH_SHADER_NEAREST = "\nstruct Uniforms {\n res: vec2f,\n _pad: vec2f,\n blend: vec2f,\n _pad2: vec2f,\n};\n\n@group(0) @binding(0) var<uniform> uniforms: Uniforms;\n@group(0) @binding(1) var atlasSampler: sampler;\n@group(0) @binding(2) var atlasTex: texture_2d<f32>;\n\nstruct VSIn {\n @location(0) quad: vec2f,\n @location(1) pos: vec2f,\n @location(2) size: vec2f,\n @location(3) uv0: vec2f,\n @location(4) uv1: vec2f,\n @location(5) color: vec4f,\n @location(6) bg: vec4f,\n @location(7) slant: f32,\n @location(8) mode: f32,\n};\n\nstruct VSOut {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) color: vec4f,\n @location(2) bg: vec4f,\n @location(3) mode: f32,\n};\n\n@vertex\nfn vsMain(input: VSIn) -> VSOut {\n let pixel = input.pos +\n vec2f(input.quad.x * input.size.x + input.slant * (1.0 - input.quad.y), input.quad.y * input.size.y);\n let clip = vec2f(\n (pixel.x / uniforms.res.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / uniforms.res.y) * 2.0\n );\n let uv = input.uv0 + (input.uv1 - input.uv0) * input.quad;\n\n var out: VSOut;\n out.position = vec4f(clip.x, clip.y, 0.0, 1.0);\n out.uv = uv;\n out.color = input.color;\n out.bg = input.bg;\n out.mode = input.mode;\n return out;\n}\n\n// sRGB to linear conversion for proper blending\nfn srgbToLinear(c: f32) -> f32 {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(c: f32) -> f32 {\n if (c <= 0.0031308) {\n return c * 12.92;\n }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\n\nfn srgbToLinear3(c: vec3f) -> vec3f {\n return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));\n}\n\nfn linearToSrgb3(c: vec3f) -> vec3f {\n return vec3f(linearToSrgb(c.x), linearToSrgb(c.y), linearToSrgb(c.z));\n}\n\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n@fragment\nfn fsMain(input: VSOut) -> @location(0) vec4f {\n let atlasSample = textureSample(atlasTex, atlasSampler, input.uv);\n let useLinear = uniforms.blend.x > 0.5;\n let useCorrection = uniforms.blend.y > 0.5;\n\n if (input.mode > 0.5) {\n var color = atlasSample;\n if (useLinear) {\n color = vec4f(srgbToLinear3(color.rgb), color.a);\n }\n return vec4f(color.rgb * color.a, color.a);\n }\n\n var alpha = atlasSample.a;\n\n var fg = input.color;\n var bg = input.bg;\n if (useLinear) {\n fg = vec4f(srgbToLinear3(fg.rgb), fg.a);\n bg = vec4f(srgbToLinear3(bg.rgb), bg.a);\n }\n fg = vec4f(fg.rgb * fg.a, fg.a);\n bg = vec4f(bg.rgb * bg.a, bg.a);\n\n if (useCorrection && useLinear) {\n let fg_l = luminance(fg.rgb);\n let bg_l = luminance(bg.rgb);\n if (abs(fg_l - bg_l) > 0.001) {\n let blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));\n alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);\n }\n }\n\n var color = fg * alpha;\n return color;\n}\n";
@@ -1,40 +1,81 @@
1
1
  import type { NerdConstraint } from "../fonts/nerd-constraints";
2
+ /** RGBA color tuple with components in 0-1 range. */
2
3
  export type Color = [number, number, number, number];
4
+ /** Flat array of rect instance data (x, y, w, h, r, g, b, a per rect). */
3
5
  export type RectData = number[];
6
+ /**
7
+ * Font metrics used for Nerd Font glyph constraint calculations.
8
+ */
4
9
  export type NerdMetrics = {
10
+ /** Cell width in pixels. */
5
11
  cellWidth: number;
12
+ /** Cell height in pixels. */
6
13
  cellHeight: number;
14
+ /** Font face bounding-box width. */
7
15
  faceWidth: number;
16
+ /** Font face bounding-box height. */
8
17
  faceHeight: number;
18
+ /** Vertical offset of the font face within the cell. */
9
19
  faceY: number;
20
+ /** Target icon height for multi-cell-width glyphs. */
10
21
  iconHeight: number;
22
+ /** Target icon height for single-cell-width glyphs. */
11
23
  iconHeightSingle: number;
12
24
  };
25
+ /** Positioned bounding box for a rendered glyph. */
13
26
  export type GlyphBox = {
14
27
  x: number;
15
28
  y: number;
16
29
  width: number;
17
30
  height: number;
18
31
  };
32
+ /** Box-drawing line style: no line. */
19
33
  export declare const BOX_STYLE_NONE = 0;
34
+ /** Box-drawing line style: thin/light stroke. */
20
35
  export declare const BOX_STYLE_LIGHT = 1;
36
+ /** Box-drawing line style: thick/heavy stroke. */
21
37
  export declare const BOX_STYLE_HEAVY = 2;
38
+ /** Box-drawing line style: double parallel strokes. */
22
39
  export declare const BOX_STYLE_DOUBLE = 3;
40
+ /** Test whether a codepoint falls in a Unicode Private Use Area. */
23
41
  export declare function isPrivateUse(cp: number): boolean;
42
+ /** Test whether a codepoint is a space-like character (NUL, SP, or EN SPACE). */
24
43
  export declare function isSpaceCp(cp: number): boolean;
44
+ /** Test whether a codepoint is in the Box Drawing block (U+2500-U+257F). */
25
45
  export declare function isBoxDrawing(cp: number): boolean;
46
+ /** Test whether a codepoint is in the Block Elements block (U+2580-U+259F). */
26
47
  export declare function isBlockElement(cp: number): boolean;
48
+ /** Test whether a codepoint is in the Legacy Computing Symbols blocks. */
27
49
  export declare function isLegacyComputing(cp: number): boolean;
50
+ /** Test whether a codepoint is a Powerline symbol (U+E0B0-U+E0D7). */
28
51
  export declare function isPowerline(cp: number): boolean;
52
+ /** Test whether a codepoint is in the Braille Patterns block (U+2800-U+28FF). */
29
53
  export declare function isBraille(cp: number): boolean;
54
+ /** Test whether a codepoint is any GPU-drawable graphics element (box, block, legacy, powerline). */
30
55
  export declare function isGraphicsElement(cp: number): boolean;
56
+ /** Test whether a codepoint is a symbol that may need special rendering (PUA or graphics). */
31
57
  export declare function isSymbolCp(cp: number): boolean;
58
+ /** Return a new color with its alpha channel multiplied by the given factor. */
32
59
  export declare function applyAlpha(color: Color, alpha: number): Color;
60
+ /** Append a rect instance (position, size, color) to the output array. */
33
61
  export declare function pushRect(out: RectData, x: number, y: number, w: number, h: number, color: Color): void;
62
+ /** Append a rect snapped to pixel boundaries (floor origin, ceil extent). */
34
63
  export declare function pushRectSnapped(out: RectData, x: number, y: number, w: number, h: number, color: Color): void;
64
+ /** Append a rect with rounded position and at-least-1px dimensions for box drawing. */
35
65
  export declare function pushRectBox(out: RectData, x: number, y: number, w: number, h: number, color: Color): void;
66
+ /** Rasterize a Unicode Block Element (U+2580-U+259F) into rect instances. */
36
67
  export declare function drawBlockElement(cp: number, x: number, y: number, cellW: number, cellH: number, color: Color, out: RectData): boolean;
37
- export declare function drawBoxDrawing(cp: number, x: number, y: number, cellW: number, cellH: number, color: Color, out: RectData): boolean;
68
+ /**
69
+ * Rasterize a Unicode Box Drawing character (U+2500-U+257F) into rect instances.
70
+ * Handles straight segments, dashed lines, rounded corners, and diagonal lines.
71
+ */
72
+ export declare function drawBoxDrawing(cp: number, x: number, y: number, cellW: number, cellH: number, color: Color, out: RectData, boxThicknessPx?: number): boolean;
73
+ /** Rasterize a Unicode Braille Pattern (U+2800-U+28FF) into rect dot instances. */
38
74
  export declare function drawBraille(cp: number, x: number, y: number, cellW: number, cellH: number, color: Color, out: RectData): boolean;
75
+ /** Rasterize a Powerline glyph (U+E0B0-U+E0D7) into rect scanline instances. */
39
76
  export declare function drawPowerline(cp: number, x: number, y: number, cellW: number, cellH: number, color: Color, out: RectData): boolean;
77
+ /**
78
+ * Apply a Nerd Font constraint to a glyph bounding box, adjusting size and
79
+ * alignment to fit within the cell according to the constraint rules.
80
+ */
40
81
  export declare function constrainGlyphBox(glyph: GlyphBox, constraint: NerdConstraint, metrics: NerdMetrics, constraintWidth: number): GlyphBox;
@@ -1,4 +1,7 @@
1
1
  import type { Color } from "./shapes";
2
+ /**
3
+ * Full WebGPU renderer state including device, pipelines, buffers, and atlas cache.
4
+ */
2
5
  export type WebGPUState = {
3
6
  core: WebGPUCoreState;
4
7
  device: GPUDevice;
@@ -17,6 +20,9 @@ export type WebGPUState = {
17
20
  glyphCapacity: number;
18
21
  glyphAtlases: Map<number, AtlasState>;
19
22
  };
23
+ /**
24
+ * Shared WebGPU objects needed by sub-renderers (device, format, pipelines, vertex buffer).
25
+ */
20
26
  export type WebGPUCoreState = {
21
27
  device: GPUDevice;
22
28
  format: GPUTextureFormat;
@@ -26,6 +32,9 @@ export type WebGPUCoreState = {
26
32
  glyphPipelineNearest: GPURenderPipeline;
27
33
  vertexBuffer: GPUBuffer;
28
34
  };
35
+ /**
36
+ * WebGPU glyph atlas state for a single font size/DPR combination.
37
+ */
29
38
  export type AtlasState = {
30
39
  texture: GPUTexture;
31
40
  sampler?: GPUSampler;
@@ -41,6 +50,9 @@ export type AtlasState = {
41
50
  constrainedGlyphWidths?: Map<number, number>;
42
51
  nearest?: boolean;
43
52
  };
53
+ /**
54
+ * Full WebGL2 renderer state including context, programs, buffers, and atlas cache.
55
+ */
44
56
  export type WebGLState = {
45
57
  gl: WebGL2RenderingContext;
46
58
  rectProgram: WebGLProgram;
@@ -59,6 +71,9 @@ export type WebGLState = {
59
71
  glyphCapacity: number;
60
72
  glyphAtlases: Map<number, WebGLAtlasState>;
61
73
  };
74
+ /**
75
+ * WebGL glyph atlas state for a single font size/DPR combination.
76
+ */
62
77
  export type WebGLAtlasState = {
63
78
  texture: WebGLTexture;
64
79
  width: number;
@@ -68,23 +83,51 @@ export type WebGLAtlasState = {
68
83
  constrainedGlyphWidths?: Map<number, number>;
69
84
  nearest?: boolean;
70
85
  };
86
+ /**
87
+ * Active renderer backend state.
88
+ * - WebGPUState: WebGPU backend is active
89
+ * - WebGLState: WebGL2 fallback is active
90
+ * - null: no renderer initialized
91
+ */
71
92
  export type RendererState = WebGPUState | WebGLState | null;
93
+ /**
94
+ * Renderer color configuration.
95
+ */
72
96
  export type RendererConfig = {
97
+ /** Default background color. */
73
98
  defaultBg: Color;
99
+ /** Default foreground color. */
74
100
  defaultFg: Color;
101
+ /** Selection highlight overlay color. */
75
102
  selectionColor: Color;
103
+ /** Cursor color used when the application does not specify one. */
76
104
  cursorFallback: Color;
77
105
  };
106
+ /**
107
+ * Tracks in-progress resize operations for debouncing and state diffing.
108
+ */
78
109
  export type ResizeState = {
110
+ /** Whether a resize is currently in progress. */
79
111
  active: boolean;
112
+ /** Timestamp of the last resize event. */
80
113
  lastAt: number;
114
+ /** Column count after the last resize. */
81
115
  cols: number;
116
+ /** Row count after the last resize. */
82
117
  rows: number;
118
+ /** Device pixel ratio after the last resize. */
83
119
  dpr: number;
84
120
  };
121
+ /**
122
+ * Cached scrollbar position state for change detection and fade timing.
123
+ */
85
124
  export type ScrollbarState = {
125
+ /** Timestamp of the last user scroll input. */
86
126
  lastInputAt: number;
127
+ /** Total number of scrollback lines at last update. */
87
128
  lastTotal: number;
129
+ /** Scroll offset (lines from bottom) at last update. */
88
130
  lastOffset: number;
131
+ /** Visible viewport length (rows) at last update. */
89
132
  lastLen: number;
90
133
  };
@@ -1,12 +1,22 @@
1
1
  import type { WebGPUCoreState, WebGPUState, WebGLState } from "./types";
2
+ /** Initialize shared WebGPU core state (device, pipelines, vertex buffer) from a canvas. */
2
3
  export declare function initWebGPUCore(canvas: HTMLCanvasElement): Promise<WebGPUCoreState | null>;
4
+ /**
5
+ * Initialize a full WebGPU renderer state for a canvas, including context,
6
+ * uniform buffer, and bind groups. Accepts an optional pre-initialized core.
7
+ */
3
8
  export declare function initWebGPU(canvas: HTMLCanvasElement, options?: {
4
9
  core?: WebGPUCoreState | null;
5
10
  }): Promise<WebGPUState | null>;
11
+ /** Initialize a WebGL2 fallback renderer state from a canvas. */
6
12
  export declare function initWebGL(canvas: HTMLCanvasElement): WebGLState | null;
13
+ /** Grow a WebGPU instance buffer if the required byte length exceeds current capacity. */
7
14
  export declare function ensureInstanceBuffer(state: WebGPUState, kind: "rect" | "glyph", byteLength: number): void;
15
+ /** Re-configure the WebGPU canvas context with the current device and format. */
8
16
  export declare function configureContext(state: WebGPUState): void;
17
+ /** Grow a WebGL instance buffer if the required byte length exceeds current capacity. */
9
18
  export declare function ensureGLInstanceBuffer(state: WebGLState, kind: "rect" | "glyph", byteLength: number): void;
19
+ /** Create the initial resize tracking state with default values. */
10
20
  export declare function createResizeState(): {
11
21
  active: boolean;
12
22
  lastAt: number;
@@ -14,6 +24,7 @@ export declare function createResizeState(): {
14
24
  rows: number;
15
25
  dpr: number;
16
26
  };
27
+ /** Create the initial scrollbar position state with default values. */
17
28
  export declare function createScrollbarState(): {
18
29
  lastInputAt: number;
19
30
  lastTotal: number;
package/dist/restty.js ADDED
@@ -0,0 +1,20 @@
1
+ import {
2
+ Restty,
3
+ ResttyPaneHandle,
4
+ createRestty,
5
+ getBuiltinTheme,
6
+ getBuiltinThemeSource,
7
+ isBuiltinThemeName,
8
+ listBuiltinThemeNames,
9
+ parseGhosttyTheme
10
+ } from "./chunk-53vdvhe3.js";
11
+ export {
12
+ parseGhosttyTheme,
13
+ listBuiltinThemeNames,
14
+ isBuiltinThemeName,
15
+ getBuiltinThemeSource,
16
+ getBuiltinTheme,
17
+ createRestty,
18
+ ResttyPaneHandle,
19
+ Restty
20
+ };
@@ -1,13 +1,37 @@
1
1
  import type { CellPosition, SelectionRange, SelectionState } from "./types";
2
+ /** Create an empty, inactive selection state. */
2
3
  export declare function createSelectionState(): SelectionState;
4
+ /** Reset the selection state, deactivating any active selection. */
3
5
  export declare function clearSelection(state: SelectionState): void;
6
+ /** Begin a new selection at the given cell, entering drag mode. */
4
7
  export declare function startSelection(state: SelectionState, cell: CellPosition): void;
8
+ /** Extend the active selection to a new focus cell while dragging. */
5
9
  export declare function updateSelection(state: SelectionState, cell: CellPosition): void;
10
+ /**
11
+ * Finish a drag selection at the given cell. Returns true if a non-empty
12
+ * selection was created, or false if anchor and focus are the same cell.
13
+ */
6
14
  export declare function endSelection(state: SelectionState, cell: CellPosition): boolean;
15
+ /**
16
+ * Return the selected column range for a given row, or null if the row
17
+ * is outside the selection.
18
+ */
7
19
  export declare function selectionForRow(state: SelectionState, row: number, cols: number): SelectionRange | null;
20
+ /** Callback that returns the text content of a cell by flat grid index. */
8
21
  export type CellTextGetter = (idx: number) => string;
22
+ /**
23
+ * Extract the selected text as a newline-separated string, with trailing
24
+ * whitespace trimmed from each line.
25
+ */
9
26
  export declare function getSelectionText(state: SelectionState, rows: number, cols: number, getCellText: CellTextGetter): string;
27
+ /**
28
+ * Clamp a cell position to the grid bounds and snap wide-character
29
+ * continuation cells back to the leading cell.
30
+ */
10
31
  export declare function normalizeSelectionCell(cell: CellPosition | null, rows: number, cols: number, wideFlags?: Uint8Array | null): CellPosition | null;
32
+ /** Convert client pixel coordinates to a grid cell position. */
11
33
  export declare function positionToCell(clientX: number, clientY: number, canvasRect: DOMRect, dpr: number, cellW: number, cellH: number, cols: number, rows: number): CellPosition;
34
+ /** Copy text to the system clipboard, with a legacy execCommand fallback. */
12
35
  export declare function copyToClipboard(text: string): Promise<boolean>;
36
+ /** Read text from the system clipboard, returning null on failure. */
13
37
  export declare function pasteFromClipboard(): Promise<string | null>;
@@ -1,14 +1,27 @@
1
+ /** 0-based cell coordinates within the terminal grid. */
1
2
  export type CellPosition = {
2
3
  row: number;
3
4
  col: number;
4
5
  };
6
+ /**
7
+ * Mutable state of the current text selection.
8
+ */
5
9
  export type SelectionState = {
10
+ /** Whether a selection currently exists. */
6
11
  active: boolean;
12
+ /** Whether the user is actively dragging to extend the selection. */
7
13
  dragging: boolean;
14
+ /** Cell where the selection was initiated (start point). */
8
15
  anchor: CellPosition | null;
16
+ /** Cell where the selection currently ends (moving point). */
9
17
  focus: CellPosition | null;
10
18
  };
19
+ /**
20
+ * Column span of a selection within a single row.
21
+ */
11
22
  export type SelectionRange = {
23
+ /** Inclusive start column index. */
12
24
  start: number;
25
+ /** Exclusive end column index. */
13
26
  end: number;
14
27
  };
@@ -1,7 +1,12 @@
1
1
  import { type GhosttyTheme } from "./ghostty";
2
2
  import { type BuiltinThemeName } from "./builtin-themes";
3
+ /** String literal union of all builtin theme names. */
3
4
  export type ResttyBuiltinThemeName = BuiltinThemeName;
5
+ /** Return an array of all builtin theme names. */
4
6
  export declare function listBuiltinThemeNames(): ResttyBuiltinThemeName[];
7
+ /** Check if a string is a valid builtin theme name. */
5
8
  export declare function isBuiltinThemeName(name: string): name is ResttyBuiltinThemeName;
9
+ /** Get the raw source text for a builtin theme by name. */
6
10
  export declare function getBuiltinThemeSource(name: string): string | null;
11
+ /** Get the parsed theme object for a builtin theme by name (cached). */
7
12
  export declare function getBuiltinTheme(name: string): GhosttyTheme | null;
@@ -1,23 +1,41 @@
1
+ /** RGBA color with 0-255 byte components. */
1
2
  export type ThemeColor = {
2
3
  r: number;
3
4
  g: number;
4
5
  b: number;
5
6
  a?: number;
6
7
  };
8
+ /**
9
+ * Parsed Ghostty terminal theme with semantic colors and full 256-color palette.
10
+ */
7
11
  export type GhosttyTheme = {
12
+ /** Optional theme name extracted from source. */
8
13
  name?: string;
14
+ /** Semantic colors and ANSI palette entries. */
9
15
  colors: {
16
+ /** Default background color. */
10
17
  background?: ThemeColor;
18
+ /** Default foreground (text) color. */
11
19
  foreground?: ThemeColor;
20
+ /** Cursor fill color. */
12
21
  cursor?: ThemeColor;
22
+ /** Text color under the cursor. */
13
23
  cursorText?: ThemeColor;
24
+ /** Selection background color. */
14
25
  selectionBackground?: ThemeColor;
26
+ /** Selection foreground (text) color. */
15
27
  selectionForeground?: ThemeColor;
28
+ /** 256-color palette (indices 0-255). */
16
29
  palette: Array<ThemeColor | undefined>;
17
30
  };
31
+ /** Original key-value pairs from the theme source. */
18
32
  raw: Record<string, string>;
19
33
  };
34
+ /** Parse a Ghostty color value (hex, rgb/rgba, or named color). */
20
35
  export declare function parseGhosttyColor(value: string): ThemeColor | null;
36
+ /** Convert ThemeColor to normalized RGBA floats (0.0-1.0). */
21
37
  export declare function colorToFloats(color: ThemeColor, alphaOverride?: number): [number, number, number, number];
38
+ /** Convert ThemeColor to packed 24-bit RGB integer (0xRRGGBB). */
22
39
  export declare function colorToRgbU32(color: ThemeColor): number;
40
+ /** Parse a Ghostty theme configuration from key=value format. */
23
41
  export declare function parseGhosttyTheme(text: string): GhosttyTheme;
@@ -0,0 +1 @@
1
+ export declare const GHOSTTY_SYMBOL_RANGES: ReadonlyArray<readonly [number, number]>;
@@ -0,0 +1,6 @@
1
+ /** True when cp is a Ghostty "graphics element" handled specially in renderer logic. */
2
+ export declare function isGraphicsElementCodepoint(cp: number): boolean;
3
+ /** True when cp is in Ghostty's generated is_symbol lookup table. */
4
+ export declare function isGhosttySymbolCodepoint(cp: number): boolean;
5
+ /** Symbol-like codepoint for renderer constraint/fit behavior. */
6
+ export declare function isSymbolLikeCodepoint(cp: number): boolean;