@aitty/browser 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/dist/browser.d.ts +6 -0
- package/dist/browser.js +5 -0
- package/dist/frontend/ansi-sequences.d.ts +5 -0
- package/dist/frontend/ansi-sequences.js +17 -0
- package/dist/frontend/ansi-style-tracker.d.ts +37 -0
- package/dist/frontend/ansi-style-tracker.js +435 -0
- package/dist/frontend/browser-terminal-renderer.d.ts +86 -0
- package/dist/frontend/browser-terminal-renderer.js +546 -0
- package/dist/frontend/cell-width.d.ts +5 -0
- package/dist/frontend/cell-width.js +9 -0
- package/dist/frontend/terminal-app.d.ts +156 -0
- package/dist/frontend/terminal-app.js +1957 -0
- package/dist/frontend/terminal-input-policies.d.ts +24 -0
- package/dist/frontend/terminal-input-policies.js +462 -0
- package/dist/frontend/terminal-theme-protocol.d.ts +22 -0
- package/dist/frontend/terminal-theme-protocol.js +270 -0
- package/dist/frontend/terminal.css +268 -0
- package/dist/theme-source.d.ts +2 -0
- package/dist/theme-source.js +2 -0
- package/package.json +54 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
//#region src/frontend/terminal-theme-protocol.ts
|
|
2
|
+
const BEL = "\x07";
|
|
3
|
+
const ESC = "\x1B";
|
|
4
|
+
const MAX_OSC_LENGTH = 512;
|
|
5
|
+
const DEFAULT_DARK_THEME_COLORS = {
|
|
6
|
+
background: "#0d1117",
|
|
7
|
+
cursor: "#f6b967",
|
|
8
|
+
foreground: "#edf2ff"
|
|
9
|
+
};
|
|
10
|
+
const DEFAULT_LIGHT_THEME_COLORS = {
|
|
11
|
+
background: "#f4efe3",
|
|
12
|
+
cursor: "#b96e1a",
|
|
13
|
+
foreground: "#24323f"
|
|
14
|
+
};
|
|
15
|
+
function createTerminalThemeProtocolParser() {
|
|
16
|
+
const decoder = new TextDecoder();
|
|
17
|
+
let parserState = "text";
|
|
18
|
+
let oscBuffer = "";
|
|
19
|
+
const reset = () => {
|
|
20
|
+
parserState = "text";
|
|
21
|
+
oscBuffer = "";
|
|
22
|
+
};
|
|
23
|
+
const appendOscCharacter = (character) => {
|
|
24
|
+
if (oscBuffer.length < MAX_OSC_LENGTH) oscBuffer += character;
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
append(chunk) {
|
|
28
|
+
const update = {
|
|
29
|
+
colors: {},
|
|
30
|
+
palette: []
|
|
31
|
+
};
|
|
32
|
+
const text = decoder.decode(chunk, { stream: true });
|
|
33
|
+
for (const character of text) {
|
|
34
|
+
if (parserState === "escape") {
|
|
35
|
+
if (character === "]") {
|
|
36
|
+
parserState = "osc";
|
|
37
|
+
oscBuffer = "";
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
parserState = "text";
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (parserState === "osc") {
|
|
44
|
+
if (character === BEL) {
|
|
45
|
+
mergeThemeUpdate(update, parseOscThemeUpdate(oscBuffer));
|
|
46
|
+
parserState = "text";
|
|
47
|
+
oscBuffer = "";
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (character === ESC) {
|
|
51
|
+
parserState = "osc_escape";
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
appendOscCharacter(character);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (parserState === "osc_escape") {
|
|
58
|
+
if (character === "\\") {
|
|
59
|
+
mergeThemeUpdate(update, parseOscThemeUpdate(oscBuffer));
|
|
60
|
+
parserState = "text";
|
|
61
|
+
oscBuffer = "";
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
appendOscCharacter(ESC);
|
|
65
|
+
appendOscCharacter(character);
|
|
66
|
+
parserState = "osc";
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (character === ESC) parserState = "escape";
|
|
70
|
+
}
|
|
71
|
+
return hasThemeUpdate(update) ? update : null;
|
|
72
|
+
},
|
|
73
|
+
reset
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function resolveTerminalThemeQueryResponse(chunk, options) {
|
|
77
|
+
const text = typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk);
|
|
78
|
+
let response = "";
|
|
79
|
+
for (const payload of collectOscPayloads(text)) {
|
|
80
|
+
const parts = payload.split(";");
|
|
81
|
+
const command = parts[0];
|
|
82
|
+
if ((command === "10" || command === "11" || command === "12") && parts.slice(1).join(";").trim() === "?") {
|
|
83
|
+
const slot = resolveColorSlot(command);
|
|
84
|
+
const color = resolveThemeColor(options.root, slot, options.theme);
|
|
85
|
+
response += `${ESC}]${command};${toTerminalRgbColor(color)}${ESC}\\`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return response.length > 0 ? response : null;
|
|
89
|
+
}
|
|
90
|
+
function parseOscThemeUpdate(payload) {
|
|
91
|
+
const parts = payload.split(";");
|
|
92
|
+
const command = parts[0];
|
|
93
|
+
if (!command) return null;
|
|
94
|
+
if (command === "10" || command === "11" || command === "12") {
|
|
95
|
+
const color = normalizeTerminalColor(parts.slice(1).join(";"));
|
|
96
|
+
if (!color) return null;
|
|
97
|
+
const slot = resolveColorSlot(command);
|
|
98
|
+
const update = {
|
|
99
|
+
colors: { [slot]: color },
|
|
100
|
+
palette: []
|
|
101
|
+
};
|
|
102
|
+
if (slot === "background") update.theme = inferThemeFromBackground(color);
|
|
103
|
+
return update;
|
|
104
|
+
}
|
|
105
|
+
if (command === "4") return parsePaletteUpdate(parts.slice(1));
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
function parsePaletteUpdate(parts) {
|
|
109
|
+
const palette = [];
|
|
110
|
+
for (let index = 0; index + 1 < parts.length; index += 2) {
|
|
111
|
+
const colorIndex = Number.parseInt(parts[index] ?? "", 10);
|
|
112
|
+
const color = normalizeTerminalColor(parts[index + 1] ?? "");
|
|
113
|
+
if (!Number.isInteger(colorIndex) || colorIndex < 0 || colorIndex > 15 || !color) continue;
|
|
114
|
+
palette.push({
|
|
115
|
+
color,
|
|
116
|
+
index: colorIndex
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (palette.length === 0) return null;
|
|
120
|
+
return {
|
|
121
|
+
colors: {},
|
|
122
|
+
palette
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function normalizeTerminalColor(value) {
|
|
126
|
+
const color = value.trim();
|
|
127
|
+
if (color.length === 0 || color === "?") return null;
|
|
128
|
+
const rgb = parseTerminalRgbColor(color);
|
|
129
|
+
if (rgb) return `rgb(${rgb.red}, ${rgb.green}, ${rgb.blue})`;
|
|
130
|
+
const cssRgb = parseCssRgbColor(color);
|
|
131
|
+
if (cssRgb) return `rgb(${cssRgb.red}, ${cssRgb.green}, ${cssRgb.blue})`;
|
|
132
|
+
if (/^#[0-9a-fA-F]{6}$/.test(color)) return color.toLowerCase();
|
|
133
|
+
if (/^#[0-9a-fA-F]{3}$/.test(color)) return expandShortHexColor(color);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
function collectOscPayloads(text) {
|
|
137
|
+
const payloads = [];
|
|
138
|
+
let parserState = "text";
|
|
139
|
+
let oscBuffer = "";
|
|
140
|
+
const pushPayload = () => {
|
|
141
|
+
payloads.push(oscBuffer);
|
|
142
|
+
oscBuffer = "";
|
|
143
|
+
};
|
|
144
|
+
for (const character of text) {
|
|
145
|
+
if (parserState === "escape") {
|
|
146
|
+
if (character === "]") {
|
|
147
|
+
parserState = "osc";
|
|
148
|
+
oscBuffer = "";
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
parserState = "text";
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (parserState === "osc") {
|
|
155
|
+
if (character === BEL) {
|
|
156
|
+
pushPayload();
|
|
157
|
+
parserState = "text";
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (character === ESC) {
|
|
161
|
+
parserState = "osc_escape";
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (oscBuffer.length < MAX_OSC_LENGTH) oscBuffer += character;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (parserState === "osc_escape") {
|
|
168
|
+
if (character === "\\") {
|
|
169
|
+
pushPayload();
|
|
170
|
+
parserState = "text";
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (oscBuffer.length < MAX_OSC_LENGTH) {
|
|
174
|
+
oscBuffer += ESC;
|
|
175
|
+
oscBuffer += character;
|
|
176
|
+
}
|
|
177
|
+
parserState = "osc";
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (character === ESC) parserState = "escape";
|
|
181
|
+
}
|
|
182
|
+
return payloads;
|
|
183
|
+
}
|
|
184
|
+
function resolveThemeColor(root, slot, theme) {
|
|
185
|
+
const variableName = resolveThemeColorVariable(slot);
|
|
186
|
+
const computedValue = root.ownerDocument.defaultView?.getComputedStyle(root).getPropertyValue(variableName).trim();
|
|
187
|
+
const normalizedComputed = computedValue ? normalizeTerminalColor(computedValue) : null;
|
|
188
|
+
if (normalizedComputed) return normalizedComputed;
|
|
189
|
+
return (theme === "light" ? DEFAULT_LIGHT_THEME_COLORS : DEFAULT_DARK_THEME_COLORS)[slot];
|
|
190
|
+
}
|
|
191
|
+
function resolveThemeColorVariable(slot) {
|
|
192
|
+
if (slot === "background") return "--theme-term-bg";
|
|
193
|
+
if (slot === "cursor") return "--theme-term-cursor";
|
|
194
|
+
return "--theme-term-fg";
|
|
195
|
+
}
|
|
196
|
+
function toTerminalRgbColor(color) {
|
|
197
|
+
const rgb = parseCssRgbColor(color) ?? parseCssHexColor(color) ?? {
|
|
198
|
+
blue: 255,
|
|
199
|
+
green: 255,
|
|
200
|
+
red: 255
|
|
201
|
+
};
|
|
202
|
+
return `rgb:${toTerminalRgbChannel(rgb.red)}/${toTerminalRgbChannel(rgb.green)}/${toTerminalRgbChannel(rgb.blue)}`;
|
|
203
|
+
}
|
|
204
|
+
function toTerminalRgbChannel(value) {
|
|
205
|
+
return clamp(value, 0, 255).toString(16).padStart(2, "0").repeat(2);
|
|
206
|
+
}
|
|
207
|
+
function parseTerminalRgbColor(value) {
|
|
208
|
+
const match = /^rgb:([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})\/([0-9a-fA-F]{1,4})$/.exec(value);
|
|
209
|
+
if (!match) return null;
|
|
210
|
+
return {
|
|
211
|
+
blue: normalizeHexChannel(match[3] ?? ""),
|
|
212
|
+
green: normalizeHexChannel(match[2] ?? ""),
|
|
213
|
+
red: normalizeHexChannel(match[1] ?? "")
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function normalizeHexChannel(value) {
|
|
217
|
+
if (value.length === 0) return 0;
|
|
218
|
+
const expanded = value.length === 1 ? `${value}${value}` : value.slice(0, 2);
|
|
219
|
+
return clamp(Number.parseInt(expanded, 16), 0, 255);
|
|
220
|
+
}
|
|
221
|
+
function expandShortHexColor(value) {
|
|
222
|
+
const [, red = "0", green = "0", blue = "0"] = value;
|
|
223
|
+
return `#${red}${red}${green}${green}${blue}${blue}`.toLowerCase();
|
|
224
|
+
}
|
|
225
|
+
function resolveColorSlot(command) {
|
|
226
|
+
if (command === "11") return "background";
|
|
227
|
+
if (command === "12") return "cursor";
|
|
228
|
+
return "foreground";
|
|
229
|
+
}
|
|
230
|
+
function inferThemeFromBackground(color) {
|
|
231
|
+
const rgb = parseCssRgbColor(color) ?? parseCssHexColor(color);
|
|
232
|
+
if (!rgb) return "dark";
|
|
233
|
+
return .2126 * toLinearRgb(rgb.red) + .7152 * toLinearRgb(rgb.green) + .0722 * toLinearRgb(rgb.blue) > .45 ? "light" : "dark";
|
|
234
|
+
}
|
|
235
|
+
function parseCssRgbColor(color) {
|
|
236
|
+
const match = /^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.exec(color);
|
|
237
|
+
if (!match) return null;
|
|
238
|
+
return {
|
|
239
|
+
blue: clamp(Number.parseInt(match[3] ?? "", 10), 0, 255),
|
|
240
|
+
green: clamp(Number.parseInt(match[2] ?? "", 10), 0, 255),
|
|
241
|
+
red: clamp(Number.parseInt(match[1] ?? "", 10), 0, 255)
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function parseCssHexColor(color) {
|
|
245
|
+
const match = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/.exec(color);
|
|
246
|
+
if (!match) return null;
|
|
247
|
+
return {
|
|
248
|
+
blue: Number.parseInt(match[3] ?? "0", 16),
|
|
249
|
+
green: Number.parseInt(match[2] ?? "0", 16),
|
|
250
|
+
red: Number.parseInt(match[1] ?? "0", 16)
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function toLinearRgb(value) {
|
|
254
|
+
const channel = clamp(value, 0, 255) / 255;
|
|
255
|
+
return channel <= .03928 ? channel / 12.92 : ((channel + .055) / 1.055) ** 2.4;
|
|
256
|
+
}
|
|
257
|
+
function mergeThemeUpdate(target, source) {
|
|
258
|
+
if (!source) return;
|
|
259
|
+
Object.assign(target.colors, source.colors);
|
|
260
|
+
target.palette.push(...source.palette);
|
|
261
|
+
target.theme = source.theme ?? target.theme;
|
|
262
|
+
}
|
|
263
|
+
function hasThemeUpdate(update) {
|
|
264
|
+
return Object.keys(update.colors).length > 0 || update.palette.length > 0 || Boolean(update.theme);
|
|
265
|
+
}
|
|
266
|
+
function clamp(value, min, max) {
|
|
267
|
+
return Math.min(max, Math.max(min, value));
|
|
268
|
+
}
|
|
269
|
+
//#endregion
|
|
270
|
+
export { createTerminalThemeProtocolParser, resolveTerminalThemeQueryResponse };
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
.wterm {
|
|
2
|
+
--term-fg: #d4d4d4;
|
|
3
|
+
--term-bg: #1e1e1e;
|
|
4
|
+
--term-cursor: #aeafad;
|
|
5
|
+
|
|
6
|
+
--term-color-0: #1e1e1e;
|
|
7
|
+
--term-color-1: #f44747;
|
|
8
|
+
--term-color-2: #6a9955;
|
|
9
|
+
--term-color-3: #d7ba7d;
|
|
10
|
+
--term-color-4: #569cd6;
|
|
11
|
+
--term-color-5: #c586c0;
|
|
12
|
+
--term-color-6: #4ec9b0;
|
|
13
|
+
--term-color-7: #d4d4d4;
|
|
14
|
+
--term-color-8: #808080;
|
|
15
|
+
--term-color-9: #f44747;
|
|
16
|
+
--term-color-10: #6a9955;
|
|
17
|
+
--term-color-11: #d7ba7d;
|
|
18
|
+
--term-color-12: #569cd6;
|
|
19
|
+
--term-color-13: #c586c0;
|
|
20
|
+
--term-color-14: #4ec9b0;
|
|
21
|
+
--term-color-15: #ffffff;
|
|
22
|
+
|
|
23
|
+
--term-font-family: 'Menlo', 'Consolas', 'DejaVu Sans Mono', 'Courier New', monospace;
|
|
24
|
+
--term-font-size: 14px;
|
|
25
|
+
--term-line-height: 1.2;
|
|
26
|
+
--term-row-height: 17px;
|
|
27
|
+
|
|
28
|
+
position: relative;
|
|
29
|
+
background: var(--term-bg);
|
|
30
|
+
color: var(--term-fg);
|
|
31
|
+
font-family: var(--term-font-family);
|
|
32
|
+
font-size: var(--term-font-size);
|
|
33
|
+
line-height: var(--term-line-height);
|
|
34
|
+
padding: 12px;
|
|
35
|
+
border-radius: 8px;
|
|
36
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
|
37
|
+
outline: none;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.wterm:focus,
|
|
42
|
+
.wterm:focus-visible {
|
|
43
|
+
outline: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.term-grid {
|
|
47
|
+
display: block;
|
|
48
|
+
white-space: pre;
|
|
49
|
+
contain: layout paint style;
|
|
50
|
+
will-change: contents;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.term-row {
|
|
54
|
+
display: block;
|
|
55
|
+
height: var(--term-row-height);
|
|
56
|
+
line-height: var(--term-row-height);
|
|
57
|
+
contain: layout style;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.term-row > span {
|
|
61
|
+
display: inline-block;
|
|
62
|
+
height: var(--term-row-height);
|
|
63
|
+
vertical-align: top;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.term-block {
|
|
67
|
+
width: 1ch;
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.term-cursor {
|
|
72
|
+
outline: 1px solid var(--term-cursor);
|
|
73
|
+
outline-offset: -1px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.wterm.focused .term-cursor {
|
|
77
|
+
background: var(--term-cursor);
|
|
78
|
+
color: var(--term-bg);
|
|
79
|
+
outline: none;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.wterm.focused.cursor-blink .term-cursor {
|
|
83
|
+
animation: cursor-blink 1s step-end infinite;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@keyframes cursor-blink {
|
|
87
|
+
0%, 100% { background: var(--term-cursor); color: var(--term-bg); }
|
|
88
|
+
50% { background: transparent; color: inherit; }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.wterm.has-scrollback {
|
|
92
|
+
overflow-y: auto;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.wterm ::selection {
|
|
96
|
+
background: rgba(86, 156, 214, 0.3);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Solarized Dark */
|
|
100
|
+
.wterm.theme-solarized-dark {
|
|
101
|
+
--term-fg: #839496;
|
|
102
|
+
--term-bg: #002b36;
|
|
103
|
+
--term-cursor: #93a1a1;
|
|
104
|
+
--term-color-0: #073642;
|
|
105
|
+
--term-color-1: #dc322f;
|
|
106
|
+
--term-color-2: #859900;
|
|
107
|
+
--term-color-3: #b58900;
|
|
108
|
+
--term-color-4: #268bd2;
|
|
109
|
+
--term-color-5: #d33682;
|
|
110
|
+
--term-color-6: #2aa198;
|
|
111
|
+
--term-color-7: #eee8d5;
|
|
112
|
+
--term-color-8: #586e75;
|
|
113
|
+
--term-color-9: #cb4b16;
|
|
114
|
+
--term-color-10: #586e75;
|
|
115
|
+
--term-color-11: #657b83;
|
|
116
|
+
--term-color-12: #839496;
|
|
117
|
+
--term-color-13: #6c71c4;
|
|
118
|
+
--term-color-14: #93a1a1;
|
|
119
|
+
--term-color-15: #fdf6e3;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Monokai */
|
|
123
|
+
.wterm.theme-monokai {
|
|
124
|
+
--term-fg: #f8f8f2;
|
|
125
|
+
--term-bg: #272822;
|
|
126
|
+
--term-cursor: #f8f8f0;
|
|
127
|
+
--term-color-0: #272822;
|
|
128
|
+
--term-color-1: #f92672;
|
|
129
|
+
--term-color-2: #a6e22e;
|
|
130
|
+
--term-color-3: #f4bf75;
|
|
131
|
+
--term-color-4: #66d9ef;
|
|
132
|
+
--term-color-5: #ae81ff;
|
|
133
|
+
--term-color-6: #a1efe4;
|
|
134
|
+
--term-color-7: #f8f8f2;
|
|
135
|
+
--term-color-8: #75715e;
|
|
136
|
+
--term-color-9: #f92672;
|
|
137
|
+
--term-color-10: #a6e22e;
|
|
138
|
+
--term-color-11: #f4bf75;
|
|
139
|
+
--term-color-12: #66d9ef;
|
|
140
|
+
--term-color-13: #ae81ff;
|
|
141
|
+
--term-color-14: #a1efe4;
|
|
142
|
+
--term-color-15: #f9f8f5;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* Light */
|
|
146
|
+
.wterm.theme-light {
|
|
147
|
+
--term-fg: #383a42;
|
|
148
|
+
--term-bg: #fafafa;
|
|
149
|
+
--term-cursor: #526eff;
|
|
150
|
+
--term-color-0: #383a42;
|
|
151
|
+
--term-color-1: #e45649;
|
|
152
|
+
--term-color-2: #50a14f;
|
|
153
|
+
--term-color-3: #c18401;
|
|
154
|
+
--term-color-4: #4078f2;
|
|
155
|
+
--term-color-5: #a626a4;
|
|
156
|
+
--term-color-6: #0184bc;
|
|
157
|
+
--term-color-7: #fafafa;
|
|
158
|
+
--term-color-8: #a0a1a7;
|
|
159
|
+
--term-color-9: #e45649;
|
|
160
|
+
--term-color-10: #50a14f;
|
|
161
|
+
--term-color-11: #c18401;
|
|
162
|
+
--term-color-12: #4078f2;
|
|
163
|
+
--term-color-13: #a626a4;
|
|
164
|
+
--term-color-14: #0184bc;
|
|
165
|
+
--term-color-15: #ffffff;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.aitty-embed,
|
|
169
|
+
.aitty-shell,
|
|
170
|
+
.aitty-scroll-target,
|
|
171
|
+
.aitty-scroll-viewport {
|
|
172
|
+
min-width: 0;
|
|
173
|
+
min-height: 0;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.aitty-embed {
|
|
177
|
+
height: 100%;
|
|
178
|
+
min-height: 240px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.aitty-shell,
|
|
182
|
+
.aitty-scroll-target {
|
|
183
|
+
height: 100%;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.aitty-scroll-target {
|
|
187
|
+
overflow: hidden;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.aitty-scroll-viewport {
|
|
191
|
+
height: 100%;
|
|
192
|
+
outline: none;
|
|
193
|
+
overflow-x: hidden;
|
|
194
|
+
overflow-y: auto;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.aitty-scroll-content {
|
|
198
|
+
min-height: 100%;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.aitty-terminal-root {
|
|
202
|
+
position: relative;
|
|
203
|
+
min-width: 0;
|
|
204
|
+
min-height: 100%;
|
|
205
|
+
max-height: none;
|
|
206
|
+
background: transparent;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.aitty-terminal-root.wterm {
|
|
210
|
+
--term-bg: var(--theme-term-bg, transparent);
|
|
211
|
+
--term-fg: var(--theme-term-fg, #edf2ff);
|
|
212
|
+
--term-cursor: var(--theme-term-cursor, currentColor);
|
|
213
|
+
--term-color-0: var(--theme-term-color-0, #111724);
|
|
214
|
+
--term-color-1: var(--theme-term-color-1, #ff7b72);
|
|
215
|
+
--term-color-2: var(--theme-term-color-2, #8ddb8c);
|
|
216
|
+
--term-color-3: var(--theme-term-color-3, #ffd580);
|
|
217
|
+
--term-color-4: var(--theme-term-color-4, #7cc4ff);
|
|
218
|
+
--term-color-5: var(--theme-term-color-5, #d2a8ff);
|
|
219
|
+
--term-color-6: var(--theme-term-color-6, #77e0d2);
|
|
220
|
+
--term-color-7: var(--theme-term-color-7, #edf2ff);
|
|
221
|
+
--term-color-8: var(--theme-term-color-8, #5f6f86);
|
|
222
|
+
--term-color-9: var(--theme-term-color-9, #ffa198);
|
|
223
|
+
--term-color-10: var(--theme-term-color-10, #b0f2af);
|
|
224
|
+
--term-color-11: var(--theme-term-color-11, #ffe4a8);
|
|
225
|
+
--term-color-12: var(--theme-term-color-12, #a7d7ff);
|
|
226
|
+
--term-color-13: var(--theme-term-color-13, #e1c0ff);
|
|
227
|
+
--term-color-14: var(--theme-term-color-14, #9ff4ea);
|
|
228
|
+
--term-color-15: var(--theme-term-color-15, #ffffff);
|
|
229
|
+
--term-font-size: var(--theme-term-font-size, 15px);
|
|
230
|
+
--term-line-height: var(--theme-term-line-height, 1.28);
|
|
231
|
+
color: var(--term-fg);
|
|
232
|
+
padding: 0 0 var(--theme-term-padding-bottom, 24px);
|
|
233
|
+
border-radius: 0;
|
|
234
|
+
box-shadow: none;
|
|
235
|
+
overflow: visible;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.aitty-terminal-root.wterm.has-scrollback {
|
|
239
|
+
overflow-y: visible;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.aitty-terminal-root[data-session-interactive="false"] .term-cursor {
|
|
243
|
+
opacity: 0 !important;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.aitty-terminal-root[data-session-interactive="false"] textarea {
|
|
247
|
+
caret-color: transparent;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.aitty-terminal-root .term-transcript-archive {
|
|
251
|
+
margin: 0;
|
|
252
|
+
min-height: 0;
|
|
253
|
+
padding: 0;
|
|
254
|
+
color: inherit;
|
|
255
|
+
font: inherit;
|
|
256
|
+
line-height: var(--term-row-height);
|
|
257
|
+
pointer-events: none;
|
|
258
|
+
white-space: pre;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.aitty-terminal-root .term-transcript-archive:empty {
|
|
262
|
+
display: none;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.aitty-terminal-root[data-render-mode="screen"] .term-transcript-archive,
|
|
266
|
+
.aitty-terminal-root[data-render-mode="screen"] .term-scrollback-row {
|
|
267
|
+
display: none;
|
|
268
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { AittyTheme, AittyThemeControlFrame, AittyThemeSource, AittyThemeSubscription, createThemeControlFrame, normalizeTheme, readThemeSource, subscribeThemeSource } from "@aitty/protocol";
|
|
2
|
+
export { type AittyTheme, type AittyThemeControlFrame, type AittyThemeSource, type AittyThemeSubscription, createThemeControlFrame, normalizeTheme, readThemeSource, subscribeThemeSource };
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aitty/browser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser DOM terminal renderer for aitty.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agent",
|
|
7
|
+
"ai",
|
|
8
|
+
"browser",
|
|
9
|
+
"dom",
|
|
10
|
+
"terminal",
|
|
11
|
+
"wterm"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/kingsword09/aitty#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/kingsword09/aitty/issues"
|
|
16
|
+
},
|
|
17
|
+
"license": "Apache-2.0",
|
|
18
|
+
"author": "Kingsword kingsword09 <kingsword09@gmail.com>",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/kingsword09/aitty.git",
|
|
22
|
+
"directory": "packages/browser"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"sideEffects": [
|
|
26
|
+
"./dist/frontend/terminal.css"
|
|
27
|
+
],
|
|
28
|
+
"main": "./dist/browser.js",
|
|
29
|
+
"types": "./dist/browser.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/browser.d.ts",
|
|
33
|
+
"default": "./dist/browser.js"
|
|
34
|
+
},
|
|
35
|
+
"./frontend/*": {
|
|
36
|
+
"types": "./dist/frontend/*.d.ts",
|
|
37
|
+
"default": "./dist/frontend/*.js"
|
|
38
|
+
},
|
|
39
|
+
"./style.css": "./dist/frontend/terminal.css"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist"
|
|
43
|
+
],
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=20"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@aitty/protocol": "workspace:*",
|
|
52
|
+
"@wterm/dom": "^0.1.9"
|
|
53
|
+
}
|
|
54
|
+
}
|