@aurigax-ai/ghostty-web 0.0.0-stage → 0.1.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.
- package/GHOSTTY_COMMIT +1 -0
- package/LICENSE +22 -0
- package/README.md +90 -2
- package/ghostty-vt.wasm +0 -0
- package/lib/abi.ts +227 -0
- package/lib/addons/fit.ts +242 -0
- package/lib/buffer.ts +402 -0
- package/lib/event-emitter.ts +27 -0
- package/lib/ghostty.ts +1135 -0
- package/lib/index.ts +110 -0
- package/lib/input-handler.ts +1104 -0
- package/lib/interfaces.ts +218 -0
- package/lib/link-detector.ts +215 -0
- package/lib/marker.ts +55 -0
- package/lib/providers/osc8-link-provider.ts +144 -0
- package/lib/providers/url-regex-provider.ts +150 -0
- package/lib/renderer.ts +958 -0
- package/lib/selection-manager.ts +1052 -0
- package/lib/terminal.ts +2026 -0
- package/lib/types.ts +648 -0
- package/package.json +70 -4
package/lib/types.ts
ADDED
|
@@ -0,0 +1,648 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type definitions for libghostty-vt WASM API
|
|
3
|
+
* Based on include/ghostty/vt/*.h from Ghostty repository
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// SGR (Select Graphic Rendition) Types
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* SGR attribute tags - identifies the type of attribute
|
|
12
|
+
* From include/ghostty/vt/sgr.h
|
|
13
|
+
*/
|
|
14
|
+
export enum SgrAttributeTag {
|
|
15
|
+
UNSET = 0,
|
|
16
|
+
UNKNOWN = 1,
|
|
17
|
+
BOLD = 2,
|
|
18
|
+
RESET_BOLD = 3,
|
|
19
|
+
ITALIC = 4,
|
|
20
|
+
RESET_ITALIC = 5,
|
|
21
|
+
FAINT = 6,
|
|
22
|
+
RESET_FAINT = 7,
|
|
23
|
+
UNDERLINE = 8,
|
|
24
|
+
RESET_UNDERLINE = 9,
|
|
25
|
+
BLINK = 10,
|
|
26
|
+
RESET_BLINK = 11,
|
|
27
|
+
INVERSE = 12,
|
|
28
|
+
RESET_INVERSE = 13,
|
|
29
|
+
INVISIBLE = 14,
|
|
30
|
+
RESET_INVISIBLE = 15,
|
|
31
|
+
STRIKETHROUGH = 16,
|
|
32
|
+
RESET_STRIKETHROUGH = 17,
|
|
33
|
+
FG_8 = 18, // 8-color (0-7)
|
|
34
|
+
FG_16 = 19, // 16-color (0-15)
|
|
35
|
+
FG_256 = 20, // 256-color palette
|
|
36
|
+
FG_RGB = 21, // RGB color
|
|
37
|
+
FG_DEFAULT = 22, // Reset to default
|
|
38
|
+
BG_8 = 23, // Background 8-color
|
|
39
|
+
BG_16 = 24, // Background 16-color
|
|
40
|
+
BG_256 = 25, // Background 256-color
|
|
41
|
+
BG_RGB = 26, // Background RGB
|
|
42
|
+
BG_DEFAULT = 27, // Reset background
|
|
43
|
+
UNDERLINE_COLOR_8 = 28,
|
|
44
|
+
UNDERLINE_COLOR_16 = 29,
|
|
45
|
+
UNDERLINE_COLOR_256 = 30,
|
|
46
|
+
UNDERLINE_COLOR_RGB = 31,
|
|
47
|
+
UNDERLINE_COLOR_DEFAULT = 32,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface RGBColor {
|
|
51
|
+
r: number;
|
|
52
|
+
g: number;
|
|
53
|
+
b: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type SgrAttribute =
|
|
57
|
+
| { tag: SgrAttributeTag.BOLD }
|
|
58
|
+
| { tag: SgrAttributeTag.RESET_BOLD }
|
|
59
|
+
| { tag: SgrAttributeTag.ITALIC }
|
|
60
|
+
| { tag: SgrAttributeTag.RESET_ITALIC }
|
|
61
|
+
| { tag: SgrAttributeTag.FAINT }
|
|
62
|
+
| { tag: SgrAttributeTag.RESET_FAINT }
|
|
63
|
+
| { tag: SgrAttributeTag.UNDERLINE }
|
|
64
|
+
| { tag: SgrAttributeTag.RESET_UNDERLINE }
|
|
65
|
+
| { tag: SgrAttributeTag.BLINK }
|
|
66
|
+
| { tag: SgrAttributeTag.RESET_BLINK }
|
|
67
|
+
| { tag: SgrAttributeTag.INVERSE }
|
|
68
|
+
| { tag: SgrAttributeTag.RESET_INVERSE }
|
|
69
|
+
| { tag: SgrAttributeTag.INVISIBLE }
|
|
70
|
+
| { tag: SgrAttributeTag.RESET_INVISIBLE }
|
|
71
|
+
| { tag: SgrAttributeTag.STRIKETHROUGH }
|
|
72
|
+
| { tag: SgrAttributeTag.RESET_STRIKETHROUGH }
|
|
73
|
+
| { tag: SgrAttributeTag.FG_8; color: number }
|
|
74
|
+
| { tag: SgrAttributeTag.FG_16; color: number }
|
|
75
|
+
| { tag: SgrAttributeTag.FG_256; color: number }
|
|
76
|
+
| { tag: SgrAttributeTag.FG_RGB; color: RGBColor }
|
|
77
|
+
| { tag: SgrAttributeTag.FG_DEFAULT }
|
|
78
|
+
| { tag: SgrAttributeTag.BG_8; color: number }
|
|
79
|
+
| { tag: SgrAttributeTag.BG_16; color: number }
|
|
80
|
+
| { tag: SgrAttributeTag.BG_256; color: number }
|
|
81
|
+
| { tag: SgrAttributeTag.BG_RGB; color: RGBColor }
|
|
82
|
+
| { tag: SgrAttributeTag.BG_DEFAULT }
|
|
83
|
+
| { tag: SgrAttributeTag.UNDERLINE_COLOR_RGB; color: RGBColor }
|
|
84
|
+
| { tag: SgrAttributeTag.UNDERLINE_COLOR_DEFAULT }
|
|
85
|
+
| { tag: SgrAttributeTag.UNKNOWN; params: number[] };
|
|
86
|
+
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Key Encoder Types
|
|
89
|
+
// ============================================================================
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Kitty keyboard protocol flags
|
|
93
|
+
* From include/ghostty/vt/key/encoder.h
|
|
94
|
+
*/
|
|
95
|
+
export enum KittyKeyFlags {
|
|
96
|
+
DISABLED = 0,
|
|
97
|
+
DISAMBIGUATE = 1 << 0, // Disambiguate escape codes
|
|
98
|
+
REPORT_EVENTS = 1 << 1, // Report press and release
|
|
99
|
+
REPORT_ALTERNATES = 1 << 2, // Report alternate key codes
|
|
100
|
+
REPORT_ALL = 1 << 3, // Report all events
|
|
101
|
+
REPORT_ASSOCIATED = 1 << 4, // Report associated text
|
|
102
|
+
ALL = 0x1f, // All flags enabled
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Key encoder options
|
|
107
|
+
*/
|
|
108
|
+
export enum KeyEncoderOption {
|
|
109
|
+
CURSOR_KEY_APPLICATION = 0, // DEC mode 1
|
|
110
|
+
KEYPAD_KEY_APPLICATION = 1, // DEC mode 66
|
|
111
|
+
IGNORE_KEYPAD_WITH_NUMLOCK = 2, // DEC mode 1035
|
|
112
|
+
ALT_ESC_PREFIX = 3, // DEC mode 1036
|
|
113
|
+
MODIFY_OTHER_KEYS_STATE_2 = 4, // xterm modifyOtherKeys
|
|
114
|
+
KITTY_KEYBOARD_FLAGS = 5, // Kitty protocol flags
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Key action
|
|
119
|
+
*/
|
|
120
|
+
export enum KeyAction {
|
|
121
|
+
RELEASE = 0,
|
|
122
|
+
PRESS = 1,
|
|
123
|
+
REPEAT = 2,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Physical key codes matching Ghostty's internal Key enum.
|
|
128
|
+
* These values are used by Ghostty's key encoder to produce correct escape sequences.
|
|
129
|
+
* Reference: ghostty/src/input/key.zig
|
|
130
|
+
*/
|
|
131
|
+
export enum Key {
|
|
132
|
+
// Unidentified key
|
|
133
|
+
UNIDENTIFIED = 0,
|
|
134
|
+
|
|
135
|
+
// Writing System Keys
|
|
136
|
+
GRAVE = 1, // ` and ~
|
|
137
|
+
BACKSLASH = 2, // \ and |
|
|
138
|
+
BRACKET_LEFT = 3, // [ and {
|
|
139
|
+
BRACKET_RIGHT = 4, // ] and }
|
|
140
|
+
COMMA = 5, // , and <
|
|
141
|
+
ZERO = 6,
|
|
142
|
+
ONE = 7,
|
|
143
|
+
TWO = 8,
|
|
144
|
+
THREE = 9,
|
|
145
|
+
FOUR = 10,
|
|
146
|
+
FIVE = 11,
|
|
147
|
+
SIX = 12,
|
|
148
|
+
SEVEN = 13,
|
|
149
|
+
EIGHT = 14,
|
|
150
|
+
NINE = 15,
|
|
151
|
+
EQUAL = 16, // = and +
|
|
152
|
+
INTL_BACKSLASH = 17,
|
|
153
|
+
INTL_RO = 18,
|
|
154
|
+
INTL_YEN = 19,
|
|
155
|
+
A = 20,
|
|
156
|
+
B = 21,
|
|
157
|
+
C = 22,
|
|
158
|
+
D = 23,
|
|
159
|
+
E = 24,
|
|
160
|
+
F = 25,
|
|
161
|
+
G = 26,
|
|
162
|
+
H = 27,
|
|
163
|
+
I = 28,
|
|
164
|
+
J = 29,
|
|
165
|
+
K = 30,
|
|
166
|
+
L = 31,
|
|
167
|
+
M = 32,
|
|
168
|
+
N = 33,
|
|
169
|
+
O = 34,
|
|
170
|
+
P = 35,
|
|
171
|
+
Q = 36,
|
|
172
|
+
R = 37,
|
|
173
|
+
S = 38,
|
|
174
|
+
T = 39,
|
|
175
|
+
U = 40,
|
|
176
|
+
V = 41,
|
|
177
|
+
W = 42,
|
|
178
|
+
X = 43,
|
|
179
|
+
Y = 44,
|
|
180
|
+
Z = 45,
|
|
181
|
+
MINUS = 46, // - and _
|
|
182
|
+
PERIOD = 47, // . and >
|
|
183
|
+
QUOTE = 48, // ' and "
|
|
184
|
+
SEMICOLON = 49, // ; and :
|
|
185
|
+
SLASH = 50, // / and ?
|
|
186
|
+
|
|
187
|
+
// Functional Keys
|
|
188
|
+
ALT_LEFT = 51,
|
|
189
|
+
ALT_RIGHT = 52,
|
|
190
|
+
BACKSPACE = 53,
|
|
191
|
+
CAPS_LOCK = 54,
|
|
192
|
+
CONTEXT_MENU = 55,
|
|
193
|
+
CONTROL_LEFT = 56,
|
|
194
|
+
CONTROL_RIGHT = 57,
|
|
195
|
+
ENTER = 58,
|
|
196
|
+
META_LEFT = 59,
|
|
197
|
+
META_RIGHT = 60,
|
|
198
|
+
SHIFT_LEFT = 61,
|
|
199
|
+
SHIFT_RIGHT = 62,
|
|
200
|
+
SPACE = 63,
|
|
201
|
+
TAB = 64,
|
|
202
|
+
CONVERT = 65,
|
|
203
|
+
KANA_MODE = 66,
|
|
204
|
+
NON_CONVERT = 67,
|
|
205
|
+
|
|
206
|
+
// Control Pad Section
|
|
207
|
+
DELETE = 68,
|
|
208
|
+
END = 69,
|
|
209
|
+
HELP = 70,
|
|
210
|
+
HOME = 71,
|
|
211
|
+
INSERT = 72,
|
|
212
|
+
PAGE_DOWN = 73,
|
|
213
|
+
PAGE_UP = 74,
|
|
214
|
+
|
|
215
|
+
// Arrow Pad Section
|
|
216
|
+
DOWN = 75,
|
|
217
|
+
LEFT = 76,
|
|
218
|
+
RIGHT = 77,
|
|
219
|
+
UP = 78,
|
|
220
|
+
|
|
221
|
+
// Numpad Section
|
|
222
|
+
NUM_LOCK = 79,
|
|
223
|
+
KP_0 = 80,
|
|
224
|
+
KP_1 = 81,
|
|
225
|
+
KP_2 = 82,
|
|
226
|
+
KP_3 = 83,
|
|
227
|
+
KP_4 = 84,
|
|
228
|
+
KP_5 = 85,
|
|
229
|
+
KP_6 = 86,
|
|
230
|
+
KP_7 = 87,
|
|
231
|
+
KP_8 = 88,
|
|
232
|
+
KP_9 = 89,
|
|
233
|
+
KP_PLUS = 90, // Keypad +
|
|
234
|
+
KP_BACKSPACE = 91,
|
|
235
|
+
KP_CLEAR = 92,
|
|
236
|
+
KP_CLEAR_ENTRY = 93,
|
|
237
|
+
KP_COMMA = 94,
|
|
238
|
+
KP_PERIOD = 95, // Keypad .
|
|
239
|
+
KP_DIVIDE = 96, // Keypad /
|
|
240
|
+
KP_ENTER = 97, // Keypad Enter
|
|
241
|
+
KP_EQUAL = 98,
|
|
242
|
+
KP_MEMORY_ADD = 99,
|
|
243
|
+
KP_MEMORY_CLEAR = 100,
|
|
244
|
+
KP_MEMORY_RECALL = 101,
|
|
245
|
+
KP_MEMORY_STORE = 102,
|
|
246
|
+
KP_MEMORY_SUBTRACT = 103,
|
|
247
|
+
KP_MULTIPLY = 104, // Keypad *
|
|
248
|
+
KP_PAREN_LEFT = 105,
|
|
249
|
+
KP_PAREN_RIGHT = 106,
|
|
250
|
+
KP_MINUS = 107, // Keypad -
|
|
251
|
+
KP_SEPARATOR = 108,
|
|
252
|
+
NUMPAD_UP = 109,
|
|
253
|
+
NUMPAD_DOWN = 110,
|
|
254
|
+
NUMPAD_RIGHT = 111,
|
|
255
|
+
NUMPAD_LEFT = 112,
|
|
256
|
+
NUMPAD_BEGIN = 113,
|
|
257
|
+
NUMPAD_HOME = 114,
|
|
258
|
+
NUMPAD_END = 115,
|
|
259
|
+
NUMPAD_INSERT = 116,
|
|
260
|
+
NUMPAD_DELETE = 117,
|
|
261
|
+
NUMPAD_PAGE_UP = 118,
|
|
262
|
+
NUMPAD_PAGE_DOWN = 119,
|
|
263
|
+
|
|
264
|
+
// Function Keys
|
|
265
|
+
ESCAPE = 120,
|
|
266
|
+
F1 = 121,
|
|
267
|
+
F2 = 122,
|
|
268
|
+
F3 = 123,
|
|
269
|
+
F4 = 124,
|
|
270
|
+
F5 = 125,
|
|
271
|
+
F6 = 126,
|
|
272
|
+
F7 = 127,
|
|
273
|
+
F8 = 128,
|
|
274
|
+
F9 = 129,
|
|
275
|
+
F10 = 130,
|
|
276
|
+
F11 = 131,
|
|
277
|
+
F12 = 132,
|
|
278
|
+
F13 = 133,
|
|
279
|
+
F14 = 134,
|
|
280
|
+
F15 = 135,
|
|
281
|
+
F16 = 136,
|
|
282
|
+
F17 = 137,
|
|
283
|
+
F18 = 138,
|
|
284
|
+
F19 = 139,
|
|
285
|
+
F20 = 140,
|
|
286
|
+
F21 = 141,
|
|
287
|
+
F22 = 142,
|
|
288
|
+
F23 = 143,
|
|
289
|
+
F24 = 144,
|
|
290
|
+
F25 = 145,
|
|
291
|
+
FN_LOCK = 146,
|
|
292
|
+
PRINT_SCREEN = 147,
|
|
293
|
+
SCROLL_LOCK = 148,
|
|
294
|
+
PAUSE = 149,
|
|
295
|
+
|
|
296
|
+
// Media Keys
|
|
297
|
+
BROWSER_BACK = 150,
|
|
298
|
+
BROWSER_FAVORITES = 151,
|
|
299
|
+
BROWSER_FORWARD = 152,
|
|
300
|
+
BROWSER_HOME = 153,
|
|
301
|
+
BROWSER_REFRESH = 154,
|
|
302
|
+
BROWSER_SEARCH = 155,
|
|
303
|
+
BROWSER_STOP = 156,
|
|
304
|
+
EJECT = 157,
|
|
305
|
+
LAUNCH_APP_1 = 158,
|
|
306
|
+
LAUNCH_APP_2 = 159,
|
|
307
|
+
LAUNCH_MAIL = 160,
|
|
308
|
+
MEDIA_PLAY_PAUSE = 161,
|
|
309
|
+
MEDIA_SELECT = 162,
|
|
310
|
+
MEDIA_STOP = 163,
|
|
311
|
+
MEDIA_TRACK_NEXT = 164,
|
|
312
|
+
MEDIA_TRACK_PREVIOUS = 165,
|
|
313
|
+
POWER = 166,
|
|
314
|
+
SLEEP = 167,
|
|
315
|
+
AUDIO_VOLUME_DOWN = 168,
|
|
316
|
+
AUDIO_VOLUME_MUTE = 169,
|
|
317
|
+
AUDIO_VOLUME_UP = 170,
|
|
318
|
+
WAKE_UP = 171,
|
|
319
|
+
|
|
320
|
+
// Clipboard Keys
|
|
321
|
+
COPY = 172,
|
|
322
|
+
CUT = 173,
|
|
323
|
+
PASTE = 174,
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Modifier keys
|
|
328
|
+
*/
|
|
329
|
+
export enum Mods {
|
|
330
|
+
NONE = 0,
|
|
331
|
+
SHIFT = 1 << 0,
|
|
332
|
+
CTRL = 1 << 1,
|
|
333
|
+
ALT = 1 << 2,
|
|
334
|
+
SUPER = 1 << 3, // Windows/Command key
|
|
335
|
+
CAPSLOCK = 1 << 4,
|
|
336
|
+
NUMLOCK = 1 << 5,
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Key event structure
|
|
341
|
+
*/
|
|
342
|
+
export interface KeyEvent {
|
|
343
|
+
action: KeyAction;
|
|
344
|
+
key: Key;
|
|
345
|
+
mods: Mods;
|
|
346
|
+
consumedMods?: Mods;
|
|
347
|
+
composing?: boolean;
|
|
348
|
+
utf8?: string;
|
|
349
|
+
unshiftedCodepoint?: number;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ============================================================================
|
|
353
|
+
// Terminal Types
|
|
354
|
+
// ============================================================================
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Dirty state from RenderState
|
|
358
|
+
*/
|
|
359
|
+
export enum DirtyState {
|
|
360
|
+
NONE = 0,
|
|
361
|
+
PARTIAL = 1,
|
|
362
|
+
FULL = 2,
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Cursor state from RenderState (8 bytes packed)
|
|
367
|
+
* Layout: x(u16) + y(u16) + viewport_x(i16) + viewport_y(i16) + visible(bool) + blinking(bool) + style(u8) + _pad(u8)
|
|
368
|
+
*/
|
|
369
|
+
export interface RenderStateCursor {
|
|
370
|
+
x: number;
|
|
371
|
+
y: number;
|
|
372
|
+
viewportX: number; // -1 if not in viewport
|
|
373
|
+
viewportY: number;
|
|
374
|
+
visible: boolean;
|
|
375
|
+
blinking: boolean;
|
|
376
|
+
style: 'block' | 'underline' | 'bar';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Colors from RenderState (12 bytes packed)
|
|
381
|
+
*/
|
|
382
|
+
export interface RenderStateColors {
|
|
383
|
+
background: RGB;
|
|
384
|
+
foreground: RGB;
|
|
385
|
+
cursor: RGB | null;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Terminal configuration (passed to ghostty_terminal_new_with_config)
|
|
390
|
+
* All color values use 0xRRGGBB format. A value of 0 means "use default".
|
|
391
|
+
*/
|
|
392
|
+
export interface GhosttyTerminalConfig {
|
|
393
|
+
scrollbackLimit?: number;
|
|
394
|
+
fgColor?: number;
|
|
395
|
+
bgColor?: number;
|
|
396
|
+
cursorColor?: number;
|
|
397
|
+
palette?: number[];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Opaque terminal pointer (WASM memory address)
|
|
402
|
+
*/
|
|
403
|
+
export type TerminalHandle = number;
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Cell structure matching ghostty_cell_t in C (16 bytes)
|
|
407
|
+
*/
|
|
408
|
+
export interface GhosttyCell {
|
|
409
|
+
codepoint: number; // u32 (Unicode codepoint - first codepoint of grapheme)
|
|
410
|
+
fg_r: number; // u8 (foreground red)
|
|
411
|
+
fg_g: number; // u8 (foreground green)
|
|
412
|
+
fg_b: number; // u8 (foreground blue)
|
|
413
|
+
bg_r: number; // u8 (background red)
|
|
414
|
+
bg_g: number; // u8 (background green)
|
|
415
|
+
bg_b: number; // u8 (background blue)
|
|
416
|
+
flags: number; // u8 (style flags bitfield)
|
|
417
|
+
width: number; // u8 (character width: 1=normal, 2=wide, etc.)
|
|
418
|
+
hyperlink_id: number; // u16 (0 = no link, >0 = hyperlink ID in set)
|
|
419
|
+
grapheme_len: number; // u8 (number of extra codepoints beyond first)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* RGB color
|
|
424
|
+
*/
|
|
425
|
+
export interface RGB {
|
|
426
|
+
r: number;
|
|
427
|
+
g: number;
|
|
428
|
+
b: number;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Cell style flags (bitfield)
|
|
433
|
+
*/
|
|
434
|
+
export enum CellFlags {
|
|
435
|
+
BOLD = 1 << 0,
|
|
436
|
+
ITALIC = 1 << 1,
|
|
437
|
+
UNDERLINE = 1 << 2,
|
|
438
|
+
STRIKETHROUGH = 1 << 3,
|
|
439
|
+
INVERSE = 1 << 4,
|
|
440
|
+
INVISIBLE = 1 << 5,
|
|
441
|
+
BLINK = 1 << 6,
|
|
442
|
+
FAINT = 1 << 7,
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Cursor position and visibility
|
|
447
|
+
*/
|
|
448
|
+
export interface Cursor {
|
|
449
|
+
x: number;
|
|
450
|
+
y: number;
|
|
451
|
+
visible: boolean;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Terminal configuration (passed to ghostty_terminal_new_with_config)
|
|
456
|
+
*/
|
|
457
|
+
export interface TerminalConfig {
|
|
458
|
+
scrollback_limit: number; // Number of scrollback lines (default: 10,000)
|
|
459
|
+
fg_color: RGB; // Default foreground color
|
|
460
|
+
bg_color: RGB; // Default background color
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// ============================================================================
|
|
464
|
+
// Link Detection System
|
|
465
|
+
// ============================================================================
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Represents a coordinate in the terminal buffer
|
|
469
|
+
*/
|
|
470
|
+
export interface IBufferCellPosition {
|
|
471
|
+
x: number; // Column (0-based)
|
|
472
|
+
y: number; // Row (0-based, absolute buffer position)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Represents a range in the terminal buffer
|
|
477
|
+
* Can span multiple lines for wrapped links
|
|
478
|
+
*/
|
|
479
|
+
export interface IBufferRange {
|
|
480
|
+
start: IBufferCellPosition;
|
|
481
|
+
end: IBufferCellPosition; // Inclusive
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Represents a detected link in the terminal
|
|
486
|
+
*/
|
|
487
|
+
export interface ILink {
|
|
488
|
+
/** The URL or text of the link */
|
|
489
|
+
text: string;
|
|
490
|
+
|
|
491
|
+
/** The range of the link in the buffer (may span multiple lines) */
|
|
492
|
+
range: IBufferRange;
|
|
493
|
+
|
|
494
|
+
/** Called when the link is activated (clicked with modifier) */
|
|
495
|
+
activate(event: MouseEvent): void;
|
|
496
|
+
|
|
497
|
+
/** Optional: called when mouse enters/leaves the link */
|
|
498
|
+
hover?(isHovered: boolean): void;
|
|
499
|
+
|
|
500
|
+
/** Optional: called to clean up resources */
|
|
501
|
+
dispose?(): void;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Provides link detection for a specific type of link
|
|
506
|
+
* Examples: OSC 8 hyperlinks, URL regex detection
|
|
507
|
+
*/
|
|
508
|
+
export interface ILinkProvider {
|
|
509
|
+
/**
|
|
510
|
+
* Provide links for a given row
|
|
511
|
+
* @param y Absolute row in buffer (0-based)
|
|
512
|
+
* @param callback Called with detected links (or undefined if none)
|
|
513
|
+
*/
|
|
514
|
+
provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;
|
|
515
|
+
|
|
516
|
+
/** Optional: called when terminal is disposed */
|
|
517
|
+
dispose?(): void;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Simplified buffer line interface for link providers
|
|
522
|
+
*/
|
|
523
|
+
export interface IBufferLine {
|
|
524
|
+
/** Number of cells in this line */
|
|
525
|
+
length: number;
|
|
526
|
+
|
|
527
|
+
/** Get cell at position */
|
|
528
|
+
getCell(x: number): IBufferCell;
|
|
529
|
+
|
|
530
|
+
/** Get text content of the line */
|
|
531
|
+
translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Simplified buffer cell interface for link providers
|
|
536
|
+
*/
|
|
537
|
+
export interface IBufferCell {
|
|
538
|
+
/** Get the character codepoint */
|
|
539
|
+
getCodepoint(): number;
|
|
540
|
+
|
|
541
|
+
/** Get the hyperlink ID (0 = no link) */
|
|
542
|
+
getHyperlinkId(): number;
|
|
543
|
+
|
|
544
|
+
/** Get the width of the character (1 or 2 for wide chars) */
|
|
545
|
+
getWidth(): number;
|
|
546
|
+
|
|
547
|
+
/** Check if cell has specific flags */
|
|
548
|
+
isBold(): boolean;
|
|
549
|
+
isItalic(): boolean;
|
|
550
|
+
isDim(): boolean;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Simplified terminal buffer interface for link providers
|
|
555
|
+
*/
|
|
556
|
+
export interface IBuffer {
|
|
557
|
+
/** Number of rows in the buffer (viewport + scrollback) */
|
|
558
|
+
length: number;
|
|
559
|
+
|
|
560
|
+
/** Get line at absolute buffer position */
|
|
561
|
+
getLine(y: number): IBufferLine;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Terminal buffer manager (active vs alternate screen)
|
|
566
|
+
*/
|
|
567
|
+
export interface IBufferManager {
|
|
568
|
+
/** Currently active buffer */
|
|
569
|
+
active: IBuffer;
|
|
570
|
+
|
|
571
|
+
/** Normal screen buffer */
|
|
572
|
+
normal: IBuffer;
|
|
573
|
+
|
|
574
|
+
/** Alternate screen buffer (for fullscreen apps) */
|
|
575
|
+
alternate: IBuffer;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Event system interface (xterm.js compatible)
|
|
580
|
+
*/
|
|
581
|
+
export type IEvent<T> = (listener: (data: T) => void) => IDisposable;
|
|
582
|
+
|
|
583
|
+
export interface IDisposable {
|
|
584
|
+
dispose(): void;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Event emitter for custom events
|
|
589
|
+
*/
|
|
590
|
+
export class EventEmitter<T> {
|
|
591
|
+
private listeners: Array<(data: T) => void> = [];
|
|
592
|
+
|
|
593
|
+
/** Subscribe to events */
|
|
594
|
+
public readonly event: IEvent<T> = (listener: (data: T) => void): IDisposable => {
|
|
595
|
+
this.listeners.push(listener);
|
|
596
|
+
return {
|
|
597
|
+
dispose: () => {
|
|
598
|
+
const index = this.listeners.indexOf(listener);
|
|
599
|
+
if (index !== -1) {
|
|
600
|
+
this.listeners.splice(index, 1);
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
};
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
/** Emit an event to all listeners */
|
|
607
|
+
public fire(data: T): void {
|
|
608
|
+
for (const listener of this.listeners) {
|
|
609
|
+
listener(data);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/** Remove all listeners */
|
|
614
|
+
public dispose(): void {
|
|
615
|
+
this.listeners = [];
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Terminal mode identifiers
|
|
621
|
+
*
|
|
622
|
+
* ANSI modes (use with is_ansi = true):
|
|
623
|
+
* - INSERT = 4
|
|
624
|
+
*
|
|
625
|
+
* DEC modes (use with is_ansi = false):
|
|
626
|
+
* - CURSOR_VISIBLE = 25
|
|
627
|
+
* - MOUSE_TRACKING_NORMAL = 1000
|
|
628
|
+
* - MOUSE_TRACKING_BUTTON = 1002
|
|
629
|
+
* - MOUSE_TRACKING_ANY = 1003
|
|
630
|
+
* - FOCUS_EVENTS = 1004
|
|
631
|
+
* - ALT_SCREEN = 1047
|
|
632
|
+
* - ALT_SCREEN_WITH_CURSOR = 1049
|
|
633
|
+
* - BRACKETED_PASTE = 2004
|
|
634
|
+
*/
|
|
635
|
+
export enum TerminalMode {
|
|
636
|
+
// ANSI modes
|
|
637
|
+
INSERT = 4,
|
|
638
|
+
|
|
639
|
+
// DEC modes
|
|
640
|
+
CURSOR_VISIBLE = 25,
|
|
641
|
+
MOUSE_TRACKING_NORMAL = 1000,
|
|
642
|
+
MOUSE_TRACKING_BUTTON = 1002,
|
|
643
|
+
MOUSE_TRACKING_ANY = 1003,
|
|
644
|
+
FOCUS_EVENTS = 1004,
|
|
645
|
+
ALT_SCREEN = 1047,
|
|
646
|
+
ALT_SCREEN_WITH_CURSOR = 1049,
|
|
647
|
+
BRACKETED_PASTE = 2004,
|
|
648
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,72 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurigax-ai/ghostty-web",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Ghostty's terminal engine (libghostty-vt) in the browser: WebAssembly build, an xterm.js-shaped API and a canvas renderer. A hard fork of coder/ghostty-web.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./lib/index.ts",
|
|
7
|
+
"module": "./lib/index.ts",
|
|
8
|
+
"types": "./lib/index.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./lib/index.ts",
|
|
12
|
+
"default": "./lib/index.ts"
|
|
13
|
+
},
|
|
14
|
+
"./ghostty-vt.wasm": "./ghostty-vt.wasm"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"lib",
|
|
18
|
+
"!lib/**/*.test.ts",
|
|
19
|
+
"!lib/test-helpers.ts",
|
|
20
|
+
"ghostty-vt.wasm",
|
|
21
|
+
"GHOSTTY_COMMIT",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"terminal",
|
|
27
|
+
"terminal-emulator",
|
|
28
|
+
"ghostty",
|
|
29
|
+
"web",
|
|
30
|
+
"xterm",
|
|
31
|
+
"vt100",
|
|
32
|
+
"wasm",
|
|
33
|
+
"webassembly",
|
|
34
|
+
"ansi",
|
|
35
|
+
"tty"
|
|
36
|
+
],
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/aurigax-ai/ghostty-web.git"
|
|
40
|
+
},
|
|
41
|
+
"bugs": "https://github.com/aurigax-ai/ghostty-web/issues",
|
|
42
|
+
"homepage": "https://github.com/aurigax-ai/ghostty-web#readme",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"author": "AurigaX",
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"dev": "vite --port 8000",
|
|
50
|
+
"build": "pnpm clean && pnpm build:wasm && pnpm build:lib && cp ghostty-vt.wasm dist/",
|
|
51
|
+
"build:wasm": "./scripts/build-wasm.sh",
|
|
52
|
+
"build:lib": "vite build",
|
|
53
|
+
"clean": "rm -rf dist",
|
|
54
|
+
"test": "vitest run",
|
|
55
|
+
"typecheck": "tsc --noEmit",
|
|
56
|
+
"fmt": "prettier --check .",
|
|
57
|
+
"fmt:fix": "prettier --write --cache .",
|
|
58
|
+
"lint": "biome check .",
|
|
59
|
+
"lint:fix": "biome check --write ."
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@biomejs/biome": "^1.9.4",
|
|
63
|
+
"@types/node": "^24.19.1",
|
|
64
|
+
"happy-dom": "^15.11.7",
|
|
65
|
+
"prettier": "^3.6.2",
|
|
66
|
+
"typescript": "^5.9.3",
|
|
67
|
+
"vite": "^4.5.0",
|
|
68
|
+
"vite-plugin-dts": "^4.5.4",
|
|
69
|
+
"vitest": "^2.1.9"
|
|
70
|
+
},
|
|
71
|
+
"packageManager": "pnpm@11.10.0"
|
|
72
|
+
}
|