@hex1b/web-terminal 0.167.0-alpha.1561.1.093b67b → 0.167.0-alpha.1565.1.6eea363

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/README.md CHANGED
@@ -185,6 +185,7 @@ workers, fonts, and the intended WebSocket endpoint.
185
185
  | `onTitleChange` | Initial authoritative workload title, then distinct presented changes; see below. |
186
186
  | `onClose` | Native WebSocket close details, including pre-mount transport failure; not workload completion. |
187
187
  | `onProgressChange`, `onShellIntegrationChange` | Initial authoritative activity, then distinct presented changes for host-owned chrome. |
188
+ | `onWorkingDirectoryChange`, `onCommandMarkChange` | Initial authoritative OSC 7 directory and latest OSC 133 marker, then distinct presented changes; see below. |
188
189
  | `inputBindings`, `onInput`, `actions` | Per-view input policy and custom actions. |
189
190
  | `onSelectionUI` | Synchronous, cancelable UI notification hook. |
190
191
 
@@ -195,7 +196,8 @@ Font size is an integer from 8–32, defaulting to 16. Import `MIN_FONT_SIZE` an
195
196
  ownership. `requestPrimary()` explicitly requests ownership; inspect `peer` or
196
197
  `onRoleChange` to observe the result.
197
198
 
198
- The handle exposes `geometry`, `peer`, `connected`, `readOnly`, `title`, `progress`, `shellIntegration`, `stats`, `screenText`,
199
+ The handle exposes `geometry`, `peer`, `connected`, `readOnly`, `title`, `progress`, `shellIntegration`,
200
+ `workingDirectory`, `commandMark`, `stats`, `screenText`,
199
201
  `sizing`, `viewport`, `selection`, `inputBindings`, and `inputContext`.
200
202
  Metrics start empty; check optional fields before using them. History may be
201
203
  unavailable, and selection can be unavailable, none, pending, valid, or
@@ -204,7 +206,8 @@ their state-specific values. `screenText` reflects the presented viewport, not
204
206
  an independently reconstructed ANSI buffer.
205
207
 
206
208
  Callbacks include `onGeometry`, `onRoleChange`, `onTitleChange`, `onSizingChange`, `onStats`,
207
- `onProgressChange`, `onShellIntegrationChange`, `onViewportChange`, `onSelectionChange`, `onStatus`, and `onInputError`.
209
+ `onProgressChange`, `onShellIntegrationChange`, `onWorkingDirectoryChange`, `onCommandMarkChange`,
210
+ `onViewportChange`, `onSelectionChange`, `onStatus`, and `onInputError`.
208
211
 
209
212
  ### Live read-only views
210
213
 
@@ -341,11 +344,28 @@ A/B/C preserve the last reported result, and D replaces it, including clearing
341
344
  it to null when the shell omits its status. No command text, history, or output
342
345
  locations are retained by these APIs.
343
346
 
344
- Both getters return defensive copies. Their callbacks receive the first
347
+ `terminal.workingDirectory` exposes OSC 7 state as `{ uri, host, path }`, all
348
+ `null` until the first report. `uri` is the raw reported `file://` URI; `host`
349
+ and `path` are derived from it (`host` is `""` for a local/unqualified
350
+ authority). A malformed or non-`file` URI leaves the previous value unchanged.
351
+
352
+ `terminal.commandMark` exposes the single most-recently-reported OSC 133 marker
353
+ as `{ phase, exitCode, rawParameters } | null` — `null` until the first marker.
354
+ `phase` uses the same enum as `shellIntegration.phase`. `exitCode` is non-null
355
+ only on a `finished` (D) marker. `rawParameters` is the verbatim
356
+ `key=value[;key=value...]` text trailing the marker (for example a
357
+ `cmdline_url` extension on marker C), or `null` when none was present; use the
358
+ exported `parseCommandMarkParameters(rawParameters)` helper to parse it into a
359
+ `Map`, or `getCmdlineUrl(mark)` as a shortcut for the `cmdline_url` entry. This
360
+ is **not** a command-mark history — only the latest marker is exposed, mirroring
361
+ `shellIntegration`. A host that wants its own history should accumulate
362
+ distinct values from `onCommandMarkChange` itself.
363
+
364
+ All four getters return defensive copies. Their callbacks receive the first
345
365
  authoritative presented state before mount resolves, then distinct presented
346
- changes. Both getters are updated before either activity callback. Callbacks
347
- use the same direct, synchronous host-callback convention as title changes;
348
- host exceptions are not swallowed or retried.
366
+ changes. All four getters are updated before their corresponding activity
367
+ callback. Callbacks use the same direct, synchronous host-callback convention
368
+ as title changes; host exceptions are not swallowed or retried.
349
369
 
350
370
  Frames coalesce: the browser might see only Finished for a fast command, or
351
371
  miss an entire command whose final state is unchanged. These callbacks are
@@ -356,15 +376,16 @@ and a new mount receives its own baseline.
356
376
  This example creates optional chrome outside the terminal:
357
377
 
358
378
  ```ts
359
- import { WebTerminal } from "@hex1b/web-terminal";
379
+ import { WebTerminal, getCmdlineUrl } from "@hex1b/web-terminal";
360
380
 
361
381
  const status = document.createElement("span");
382
+ const cwd = document.createElement("span");
362
383
  const progress = document.createElement("progress");
363
384
  progress.max = 100;
364
385
  progress.hidden = true;
365
386
  const container = document.createElement("div");
366
387
  container.style.cssText = "width:800px;height:480px";
367
- document.body.append(status, progress, container);
388
+ document.body.append(status, cwd, progress, container);
368
389
 
369
390
  const terminal = await WebTerminal.mount(container, {
370
391
  url: "/ws/terminal",
@@ -378,6 +399,13 @@ const terminal = await WebTerminal.mount(container, {
378
399
  status.textContent = value.phase +
379
400
  (value.lastExitCode === null ? "" : ` (last exit ${value.lastExitCode})`);
380
401
  },
402
+ onWorkingDirectoryChange(value) {
403
+ cwd.textContent = value.path ?? "";
404
+ },
405
+ onCommandMarkChange(value) {
406
+ const cmdlineUrl = getCmdlineUrl(value);
407
+ if (cmdlineUrl) console.log("Command link:", cmdlineUrl);
408
+ },
381
409
  onStats(stats) {
382
410
  if (!stats.connected) {
383
411
  progress.hidden = true;
@@ -385,7 +413,7 @@ const terminal = await WebTerminal.mount(container, {
385
413
  }
386
414
  }
387
415
  });
388
- console.log(terminal.progress, terminal.shellIntegration);
416
+ console.log(terminal.progress, terminal.shellIntegration, terminal.workingDirectory, terminal.commandMark);
389
417
  ```
390
418
 
391
419
  No title, document chrome, or progress UI is changed automatically by the
@@ -0,0 +1,14 @@
1
+ import type { TerminalCommandMark } from "./types.js";
2
+ /**
3
+ * Parses a {@link TerminalCommandMark.rawParameters} string into key/value pairs, mirroring the
4
+ * server's `TerminalCommandMark.Parameters`: segments are split on `;`, each split on the first
5
+ * `=`; segments without `=` are ignored. Values are not decoded (e.g. percent-decoding is left
6
+ * to the caller for keys that use it, such as `cmdline_url`). Returns an empty map for null/"".
7
+ */
8
+ export declare function parseCommandMarkParameters(rawParameters: string | null): ReadonlyMap<string, string>;
9
+ /**
10
+ * Gets the raw (still percent-encoded) `cmdline_url` parameter from a command mark, or null when
11
+ * absent. This is a Contour-originated, non-universal extension to OSC 133;C.
12
+ */
13
+ export declare function getCmdlineUrl(mark: TerminalCommandMark | null): string | null;
14
+ //# sourceMappingURL=command-mark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-mark.d.ts","sourceRoot":"","sources":["../src/command-mark.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CASpG;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAE7E"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Parses a {@link TerminalCommandMark.rawParameters} string into key/value pairs, mirroring the
3
+ * server's `TerminalCommandMark.Parameters`: segments are split on `;`, each split on the first
4
+ * `=`; segments without `=` are ignored. Values are not decoded (e.g. percent-decoding is left
5
+ * to the caller for keys that use it, such as `cmdline_url`). Returns an empty map for null/"".
6
+ */
7
+ export function parseCommandMarkParameters(rawParameters) {
8
+ const result = new Map();
9
+ if (!rawParameters)
10
+ return result;
11
+ for (const segment of rawParameters.split(";")) {
12
+ const separator = segment.indexOf("=");
13
+ if (separator < 0)
14
+ continue;
15
+ result.set(segment.slice(0, separator), segment.slice(separator + 1));
16
+ }
17
+ return result;
18
+ }
19
+ /**
20
+ * Gets the raw (still percent-encoded) `cmdline_url` parameter from a command mark, or null when
21
+ * absent. This is a Contour-originated, non-universal extension to OSC 133;C.
22
+ */
23
+ export function getCmdlineUrl(mark) {
24
+ return mark ? parseCommandMarkParameters(mark.rawParameters).get("cmdline_url") ?? null : null;
25
+ }
26
+ //# sourceMappingURL=command-mark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-mark.js","sourceRoot":"","sources":["../src/command-mark.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,aAA4B;IACrE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,CAAC,aAAa;QAAE,OAAO,MAAM,CAAC;IAClC,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,SAAS,GAAG,CAAC;YAAE,SAAS;QAC5B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAgC;IAC5D,OAAO,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACjG,CAAC","sourcesContent":["import type { TerminalCommandMark } from \"./types.js\";\n\n/**\n * Parses a {@link TerminalCommandMark.rawParameters} string into key/value pairs, mirroring the\n * server's `TerminalCommandMark.Parameters`: segments are split on `;`, each split on the first\n * `=`; segments without `=` are ignored. Values are not decoded (e.g. percent-decoding is left\n * to the caller for keys that use it, such as `cmdline_url`). Returns an empty map for null/\"\".\n */\nexport function parseCommandMarkParameters(rawParameters: string | null): ReadonlyMap<string, string> {\n const result = new Map<string, string>();\n if (!rawParameters) return result;\n for (const segment of rawParameters.split(\";\")) {\n const separator = segment.indexOf(\"=\");\n if (separator < 0) continue;\n result.set(segment.slice(0, separator), segment.slice(separator + 1));\n }\n return result;\n}\n\n/**\n * Gets the raw (still percent-encoded) `cmdline_url` parameter from a command mark, or null when\n * absent. This is a Contour-originated, non-universal extension to OSC 133;C.\n */\nexport function getCmdlineUrl(mark: TerminalCommandMark | null): string | null {\n return mark ? parseCommandMarkParameters(mark.rawParameters).get(\"cmdline_url\") ?? null : null;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { WebTerminal } from "./web-terminal.js";
2
2
  export { InputRoute, TerminalAction, defaultInputBindings } from "./input-policy.js";
3
3
  export { MIN_FONT_SIZE, MAX_FONT_SIZE } from "./terminal-sizing.js";
4
+ export { parseCommandMarkParameters, getCmdlineUrl } from "./command-mark.js";
4
5
  export type * from "./types.js";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,mBAAmB,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9E,mBAAmB,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { WebTerminal } from "./web-terminal.js";
2
2
  export { InputRoute, TerminalAction, defaultInputBindings } from "./input-policy.js";
3
3
  export { MIN_FONT_SIZE, MAX_FONT_SIZE } from "./terminal-sizing.js";
4
+ export { parseCommandMarkParameters, getCmdlineUrl } from "./command-mark.js";
4
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC","sourcesContent":["export { WebTerminal } from \"./web-terminal.js\";\nexport { InputRoute, TerminalAction, defaultInputBindings } from \"./input-policy.js\";\nexport { MIN_FONT_SIZE, MAX_FONT_SIZE } from \"./terminal-sizing.js\";\nexport type * from \"./types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC","sourcesContent":["export { WebTerminal } from \"./web-terminal.js\";\nexport { InputRoute, TerminalAction, defaultInputBindings } from \"./input-policy.js\";\nexport { MIN_FONT_SIZE, MAX_FONT_SIZE } from \"./terminal-sizing.js\";\nexport { parseCommandMarkParameters, getCmdlineUrl } from \"./command-mark.js\";\nexport type * from \"./types.js\";\n"]}
@@ -4,6 +4,7 @@ export declare const LIMITS: Readonly<{
4
4
  frameBytes: number;
5
5
  metadataBytes: number;
6
6
  titleUnits: 4096;
7
+ commandMarkParameterUnits: 8192;
7
8
  cells: 262144;
8
9
  images: 4096;
9
10
  placements: 16384;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,eAAe,EAAiB,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIlH,eAAO,MAAM,MAAM;;;;;;;;;EASjB,CAAC;AAKH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGxD;AAyBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,GAAG,IAAI,CAqC1H;AAsID,8FAA8F;AAC9F,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,CAiD1D;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAY9G"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,eAAe,EAAiB,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIlH,eAAO,MAAM,MAAM;;;;;;;;;;EAUjB,CAAC;AAKH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGxD;AAyBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,GAAG,IAAI,CAqC1H;AA6JD,8FAA8F;AAC9F,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,CAiD1D;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAY9G"}
package/dist/protocol.js CHANGED
@@ -5,6 +5,7 @@ export const LIMITS = Object.freeze({
5
5
  frameBytes: 96 * 1024 * 1024,
6
6
  metadataBytes: 8 * 1024 * 1024,
7
7
  titleUnits: 4096,
8
+ commandMarkParameterUnits: 8192,
8
9
  cells: 262144,
9
10
  images: 4096,
10
11
  placements: 16384,
@@ -124,6 +125,32 @@ function validateMetadata(metadata) {
124
125
  integer(shell.lastExitCode, "terminal shell exit code", -2147483648, 2147483647);
125
126
  if (shell.phase === "unknown" && shell.lastExitCode !== null)
126
127
  throw new Error("Unknown terminal shell phase has an exit code");
128
+ const workingDirectory = metadata.workingDirectory;
129
+ if (!isRecord(workingDirectory))
130
+ throw new Error("Invalid terminal working directory");
131
+ const wdFields = [workingDirectory.uri, workingDirectory.host, workingDirectory.path];
132
+ if (wdFields.every(field => field === null)) {
133
+ // No directory reported yet.
134
+ }
135
+ else if (wdFields.some(field => typeof field !== "string" || field.length > LIMITS.metadataBytes)) {
136
+ throw new Error("Invalid terminal working directory");
137
+ }
138
+ const commandMark = metadata.commandMark;
139
+ if (commandMark !== null) {
140
+ if (!isRecord(commandMark) || typeof commandMark.phase !== "string" ||
141
+ !["unknown", "prompt", "commandLine", "executing", "finished"].includes(commandMark.phase)) {
142
+ throw new Error("Invalid terminal command mark");
143
+ }
144
+ if (commandMark.exitCode !== null) {
145
+ integer(commandMark.exitCode, "terminal command mark exit code", -2147483648, 2147483647);
146
+ if (commandMark.phase !== "finished")
147
+ throw new Error("Non-finished terminal command mark has an exit code");
148
+ }
149
+ if (commandMark.rawParameters !== null &&
150
+ (typeof commandMark.rawParameters !== "string" || commandMark.rawParameters.length > LIMITS.commandMarkParameterUnits)) {
151
+ throw new Error("Invalid terminal command mark parameters");
152
+ }
153
+ }
127
154
  const columns = integer(metadata.columns, "columns", 1, 1024);
128
155
  const rows = integer(metadata.rows, "rows", 1, 512);
129
156
  if (typeof metadata.mouseTracking !== "number" || ![0, 9, 1000, 1002, 1003].includes(metadata.mouseTracking)) {
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameMetadata, HistoryMetadata, SelectionText, TerminalCell, TerminalFrame } from \"./wire-types.js\";\nimport { isRecord } from \"./validation.js\";\n\n// Binary validation is deliberately independent of the GPU and the transport.\nexport const LIMITS = Object.freeze({\n commandBytes: 64 * 1024,\n frameBytes: 96 * 1024 * 1024,\n metadataBytes: 8 * 1024 * 1024,\n titleUnits: 4096,\n cells: 262144,\n images: 4096,\n placements: 16384,\n textureBytes: 256 * 1024 * 1024,\n});\n\nconst utf8 = new TextDecoder(\"utf-8\", { fatal: true });\nconst utf8Encoder = new TextEncoder();\n\nexport function assertCommandSize(command: unknown): void {\n if (utf8Encoder.encode(JSON.stringify(command)).byteLength > LIMITS.commandBytes)\n throw new RangeError(\"Terminal input exceeds the 64 KiB message limit. Send a smaller amount of text.\");\n}\n\nfunction integer(value: unknown, name: string, min = 0, max = Number.MAX_SAFE_INTEGER): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < min || value > max) {\n throw new Error(`Invalid ${name}: ${String(value)}`);\n }\n return value;\n}\n\nfunction array(value: unknown, name: string, limit: number): asserts value is unknown[] {\n if (!Array.isArray(value) || value.length > limit) throw new Error(`Invalid ${name}`);\n}\n\nfunction key(value: unknown): asserts value is string {\n if (typeof value !== \"string\" || !value.length || value.length > 1024) {\n throw new Error(\"Invalid image key\");\n }\n}\n\nfunction rowId(value: unknown, name: string): asserts value is string {\n if (typeof value !== \"string\" || !/^[1-9][0-9]{0,18}$/u.test(value) || BigInt(value) > 9223372036854775807n) {\n throw new Error(`Invalid ${name}`);\n }\n}\n\nexport function validateHistory(history: unknown, columns: number, rows: number): asserts history is HistoryMetadata | null {\n if (history === null) return;\n if (!isRecord(history)) throw new Error(\"Missing history metadata\");\n rowId(history.generation, \"history generation\");\n if (history.buffer !== \"main\" && history.buffer !== \"alternate\") throw new Error(\"Invalid history buffer\");\n const totalRows = integer(history.totalRows, \"history total rows\", rows, 2147483647);\n const liveTop = integer(history.liveTop, \"history live top\", 0, totalRows - rows);\n if (liveTop !== totalRows - rows) throw new Error(\"Inconsistent history extent\");\n integer(history.top, \"history top\", 0, liveTop);\n if (typeof history.following !== \"boolean\" || (history.following && history.top !== history.liveTop)) {\n throw new Error(\"Invalid history following state\");\n }\n integer(history.requestId, \"viewport request id\");\n array(history.rowIds, \"viewport row ids\", rows);\n if (history.rowIds.length !== rows || new Set(history.rowIds).size !== rows) throw new Error(\"Invalid viewport row ids\");\n for (const id of history.rowIds) rowId(id, \"viewport row id\");\n const selection = history.selection;\n if (!isRecord(selection) || typeof selection.status !== \"string\" ||\n ![\"none\", \"valid\", \"invalidated\"].includes(selection.status)) throw new Error(\"Invalid selection status\");\n integer(selection.requestId, \"selection request id\");\n if (typeof selection.mode !== \"string\" || ![\"character\", \"word\", \"line\", \"rectangle\"].includes(selection.mode)) throw new Error(\"Invalid selection mode\");\n array(selection.ranges, \"selection ranges\", rows);\n let previousRow = -1;\n for (const range of selection.ranges) {\n if (!isRecord(range)) throw new Error(\"Invalid selection range\");\n const row = integer(range.row, \"selection range row\", previousRow + 1, rows - 1);\n const startColumn = integer(range.startColumn, \"selection start column\", 0, columns - 1);\n integer(range.endColumn, \"selection end column\", startColumn + 1, columns);\n previousRow = row;\n }\n validateSelectionText(selection);\n if (selection.status !== \"valid\" && selection.ranges.length) throw new Error(\"Inactive selection has highlight ranges\");\n if (history.copy !== null) {\n if (!isRecord(history.copy)) throw new Error(\"Missing copy metadata\");\n integer(history.copy.requestId, \"copy request id\", 1);\n validateSelectionText(history.copy);\n }\n}\n\nfunction validateSelectionText(selection: Record<string, unknown>): asserts selection is Record<string, unknown> & SelectionText {\n if (typeof selection.status !== \"string\" || ![\"none\", \"valid\", \"invalidated\"].includes(selection.status) ||\n (selection.status === \"valid\"\n ? typeof selection.text !== \"string\" || selection.text.length > LIMITS.metadataBytes\n : selection.text !== null)) {\n throw new Error(\"Invalid selection text\");\n }\n}\n\nfunction validateMetadata(metadata: unknown): asserts metadata is FrameMetadata {\n if (!isRecord(metadata) || metadata.version !== 1 || typeof metadata.full !== \"boolean\") {\n throw new Error(\"Unsupported frame metadata version\");\n }\n integer(metadata.revision, \"revision\", 1);\n integer(metadata.baseRevision, \"base revision\");\n if (typeof metadata.title !== \"string\" || metadata.title.length > LIMITS.titleUnits ||\n /[\\u0000-\\u001f\\u007f-\\u009f\\ud800-\\udfff]/u.test(metadata.title)) {\n throw new Error(\"Invalid terminal title\");\n }\n const progress = metadata.progress;\n if (!isRecord(progress) || typeof progress.state !== \"string\" ||\n ![\"none\", \"normal\", \"error\", \"indeterminate\", \"warning\"].includes(progress.state)) {\n throw new Error(\"Invalid terminal progress\");\n }\n if (progress.state === \"none\" || progress.state === \"indeterminate\") {\n if (progress.percentage !== null) throw new Error(\"Unexpected terminal progress percentage\");\n } else {\n integer(progress.percentage, \"terminal progress percentage\", 0, 100);\n }\n const shell = metadata.shellIntegration;\n if (!isRecord(shell) || typeof shell.phase !== \"string\" ||\n ![\"unknown\", \"prompt\", \"commandLine\", \"executing\", \"finished\"].includes(shell.phase)) {\n throw new Error(\"Invalid terminal shell integration\");\n }\n if (shell.lastExitCode !== null)\n integer(shell.lastExitCode, \"terminal shell exit code\", -2147483648, 2147483647);\n if (shell.phase === \"unknown\" && shell.lastExitCode !== null)\n throw new Error(\"Unknown terminal shell phase has an exit code\");\n const columns = integer(metadata.columns, \"columns\", 1, 1024);\n const rows = integer(metadata.rows, \"rows\", 1, 512);\n if (typeof metadata.mouseTracking !== \"number\" || ![0, 9, 1000, 1002, 1003].includes(metadata.mouseTracking)) {\n throw new Error(\"Unsupported mouse tracking mode\");\n }\n if (!isRecord(metadata.peer) || typeof metadata.peer.isPrimary !== \"boolean\") throw new Error(\"Invalid peer state\");\n for (const field of [\"id\", \"primaryId\"]) {\n const id = metadata.peer[field];\n if (id !== null && (typeof id !== \"string\" || !id.length || id.length > 256)) {\n throw new Error(`Invalid peer ${field}`);\n }\n }\n if (metadata.peer.id !== null && metadata.peer.isPrimary !== (metadata.peer.id === metadata.peer.primaryId)) {\n throw new Error(\"Inconsistent primary peer state\");\n }\n integer(columns * rows, \"cell count\", 1, LIMITS.cells);\n validateHistory(metadata.history, columns, rows);\n array(metadata.hyperlinks, \"hyperlinks\", columns * rows);\n let previousLinkEnd = 0;\n for (const link of metadata.hyperlinks) {\n if (!isRecord(link)) throw new Error(\"Invalid hyperlink\");\n const row = integer(link.row, \"hyperlink row\", 0, rows - 1);\n const start = integer(link.startColumn, \"hyperlink start column\", 0, columns - 1);\n const end = integer(link.endColumn, \"hyperlink end column\", start + 1, columns);\n if (row * columns + start < previousLinkEnd) throw new Error(\"Unordered or overlapping hyperlinks\");\n previousLinkEnd = row * columns + end;\n if (typeof link.uri !== \"string\" || !link.uri.length || link.uri.length > LIMITS.metadataBytes)\n throw new Error(\"Invalid hyperlink URI\");\n }\n if (metadata.cellWidth !== 10 || metadata.cellHeight !== 20) {\n throw new Error(\"This spike requires server geometry of 10 × 20 logical pixels\");\n }\n for (const field of [\"defaultBackground\", \"defaultForeground\"]) {\n if (metadata[field] !== undefined) integer(metadata[field], field, 0, 0xffffffff);\n }\n if (!isRecord(metadata.cursor) || typeof metadata.cursor.visible !== \"boolean\") throw new Error(\"Invalid cursor\");\n integer(metadata.cursor.x, \"cursor x\", -1, 1024);\n integer(metadata.cursor.y, \"cursor y\", -1, 512);\n const shapes = [\"Default\", \"BlinkingBlock\", \"SteadyBlock\", \"BlinkingUnderline\", \"SteadyUnderline\", \"BlinkingBar\", \"SteadyBar\"];\n if (typeof metadata.cursor.shape === \"string\") metadata.cursor.shape = shapes.indexOf(metadata.cursor.shape);\n integer(metadata.cursor.shape, \"cursor shape\", 0, 6);\n array(metadata.images, \"images\", LIMITS.images);\n array(metadata.retainedImages, \"retained image keys\", LIMITS.images);\n array(metadata.placements, \"placements\", LIMITS.placements);\n array(metadata.warnings, \"warnings\", 256);\n if (metadata.warnings.some(w => typeof w !== \"string\")) throw new Error(\"Invalid warning\");\n if (!isRecord(metadata.stats)) throw new Error(\"Invalid server metrics\");\n for (const field of [\"workloadBytes\", \"outputBatches\", \"captureMs\", \"elapsedMs\"]) {\n const metric = metadata.stats[field];\n if (typeof metric !== \"number\" || !Number.isFinite(metric) || metric < 0) {\n throw new Error(`Invalid server metric ${field}`);\n }\n }\n const retained = new Set<string>();\n for (const imageKey of metadata.retainedImages) {\n key(imageKey);\n if (retained.has(imageKey)) throw new Error(\"Duplicate retained image key\");\n retained.add(imageKey);\n }\n const imageKeys = new Set<string>();\n let decodedImageBytes = 0;\n for (const image of metadata.images) {\n if (!isRecord(image)) throw new Error(\"Invalid image\");\n key(image.key);\n if (imageKeys.has(image.key) || !retained.has(image.key)) throw new Error(\"Inconsistent new image keys\");\n imageKeys.add(image.key);\n const width = integer(image.width, \"image width\", 1, 16384);\n const height = integer(image.height, \"image height\", 1, 16384);\n const byteLength = integer(image.byteLength, \"image byte length\", 1, LIMITS.frameBytes);\n if (image.format !== \"rgba\" && image.format !== \"png\") throw new Error(\"Unsupported image format\");\n if (image.format === \"rgba\" && byteLength !== width * height * 4) {\n throw new Error(\"RGBA image size mismatch\");\n }\n decodedImageBytes += width * height * 4;\n if (decodedImageBytes > LIMITS.textureBytes) throw new Error(\"New images exceed decoded texture budget\");\n }\n for (const placement of metadata.placements) {\n if (!isRecord(placement)) throw new Error(\"Invalid placement\");\n key(placement.key);\n if (!retained.has(placement.key)) throw new Error(\"Placement references an unretained image\");\n if (placement.kind !== \"kgp\" && placement.kind !== \"sixel\") throw new Error(\"Invalid placement kind\");\n for (const field of [\"x\", \"y\", \"width\", \"height\", \"sourceX\", \"sourceY\", \"sourceWidth\", \"sourceHeight\", \"clipX\", \"clipY\", \"clipWidth\", \"clipHeight\", \"z\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || !Number.isFinite(coordinate) || Math.abs(coordinate) > 2147483648) {\n throw new Error(`Invalid placement ${field}`);\n }\n }\n for (const field of [\"width\", \"height\", \"sourceWidth\", \"sourceHeight\", \"clipWidth\", \"clipHeight\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || coordinate < 0) throw new Error(`Negative placement ${field}`);\n }\n }\n}\n\n/** Decode one complete, experimental HWT1 message, checking every boundary before reading. */\nexport function decodeFrame(buffer: unknown): TerminalFrame {\n if (!(buffer instanceof ArrayBuffer) || buffer.byteLength > LIMITS.frameBytes) {\n throw new Error(\"Invalid or oversized binary frame\");\n }\n const view = new DataView(buffer);\n let offset = 0;\n const requireBytes = (count: number) => {\n if (count < 0 || count > view.byteLength - offset) throw new Error(\"Truncated HWT1 frame\");\n };\n const u32 = () => { requireBytes(4); const n = view.getUint32(offset, true); offset += 4; return n; };\n if (u32() !== 0x31545748) throw new Error(\"Unsupported frame magic (expected HWT1)\");\n const metadataLength = integer(u32(), \"metadata length\", 2, LIMITS.metadataBytes);\n requireBytes(metadataLength);\n const metadata: unknown = JSON.parse(utf8.decode(new Uint8Array(buffer, offset, metadataLength)));\n offset += metadataLength;\n validateMetadata(metadata);\n const cellCount = metadata.columns * metadata.rows;\n const changedCount = integer(u32(), \"changed cell count\", 0, cellCount);\n if (changedCount > Math.floor((view.byteLength - offset) / 22)) throw new Error(\"Truncated cell records\");\n if (metadata.full && changedCount !== cellCount) throw new Error(\"Incomplete full frame\");\n const cells = [];\n const seen = new Set();\n for (let i = 0; i < changedCount; i++) {\n requireBytes(22);\n const index = u32();\n if (index >= cellCount || seen.has(index)) throw new Error(\"Invalid or duplicate cell index\");\n seen.add(index);\n const foreground = u32();\n const background = u32();\n const underlineColor = u32();\n const attributes = view.getUint16(offset, true);\n const width = view.getUint8(offset + 2);\n const underlineStyle = view.getUint8(offset + 3);\n const textLength = view.getUint16(offset + 4, true);\n offset += 6;\n if (underlineStyle > 5) throw new Error(\"Unsupported underline style\");\n requireBytes(textLength);\n const text = utf8.decode(new Uint8Array(buffer, offset, textLength));\n offset += textLength;\n cells.push({ index, foreground, background, underlineColor, attributes, width, underlineStyle, text });\n }\n const imageBytes = metadata.images.reduce((total, image) => total + image.byteLength, 0);\n if (imageBytes !== view.byteLength - offset) throw new Error(\"Image payload length mismatch\");\n const images = metadata.images.map(image => {\n const bytes = new Uint8Array(buffer, offset, image.byteLength);\n offset += image.byteLength;\n return { ...image, bytes };\n });\n return { metadata, cells, images };\n}\n\n/** Mirror text, not ANSI; continuation cells are already represented by their lead glyph. */\nexport function screenText(cells: readonly (TerminalCell | undefined)[], columns: number, rows: number): string {\n const lines = [];\n for (let y = 0; y < rows; y++) {\n let line = \"\";\n for (let x = 0; x < columns; x++) {\n const cell = cells[y * columns + x];\n if (!cell || cell.width === 0) continue;\n line += cell.attributes & 64 ? \" \".repeat(cell.width) : (cell.text || \" \");\n }\n lines.push(line.replace(/ +$/u, \"\"));\n }\n return lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameMetadata, HistoryMetadata, SelectionText, TerminalCell, TerminalFrame } from \"./wire-types.js\";\nimport { isRecord } from \"./validation.js\";\n\n// Binary validation is deliberately independent of the GPU and the transport.\nexport const LIMITS = Object.freeze({\n commandBytes: 64 * 1024,\n frameBytes: 96 * 1024 * 1024,\n metadataBytes: 8 * 1024 * 1024,\n titleUnits: 4096,\n commandMarkParameterUnits: 8192,\n cells: 262144,\n images: 4096,\n placements: 16384,\n textureBytes: 256 * 1024 * 1024,\n});\n\nconst utf8 = new TextDecoder(\"utf-8\", { fatal: true });\nconst utf8Encoder = new TextEncoder();\n\nexport function assertCommandSize(command: unknown): void {\n if (utf8Encoder.encode(JSON.stringify(command)).byteLength > LIMITS.commandBytes)\n throw new RangeError(\"Terminal input exceeds the 64 KiB message limit. Send a smaller amount of text.\");\n}\n\nfunction integer(value: unknown, name: string, min = 0, max = Number.MAX_SAFE_INTEGER): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < min || value > max) {\n throw new Error(`Invalid ${name}: ${String(value)}`);\n }\n return value;\n}\n\nfunction array(value: unknown, name: string, limit: number): asserts value is unknown[] {\n if (!Array.isArray(value) || value.length > limit) throw new Error(`Invalid ${name}`);\n}\n\nfunction key(value: unknown): asserts value is string {\n if (typeof value !== \"string\" || !value.length || value.length > 1024) {\n throw new Error(\"Invalid image key\");\n }\n}\n\nfunction rowId(value: unknown, name: string): asserts value is string {\n if (typeof value !== \"string\" || !/^[1-9][0-9]{0,18}$/u.test(value) || BigInt(value) > 9223372036854775807n) {\n throw new Error(`Invalid ${name}`);\n }\n}\n\nexport function validateHistory(history: unknown, columns: number, rows: number): asserts history is HistoryMetadata | null {\n if (history === null) return;\n if (!isRecord(history)) throw new Error(\"Missing history metadata\");\n rowId(history.generation, \"history generation\");\n if (history.buffer !== \"main\" && history.buffer !== \"alternate\") throw new Error(\"Invalid history buffer\");\n const totalRows = integer(history.totalRows, \"history total rows\", rows, 2147483647);\n const liveTop = integer(history.liveTop, \"history live top\", 0, totalRows - rows);\n if (liveTop !== totalRows - rows) throw new Error(\"Inconsistent history extent\");\n integer(history.top, \"history top\", 0, liveTop);\n if (typeof history.following !== \"boolean\" || (history.following && history.top !== history.liveTop)) {\n throw new Error(\"Invalid history following state\");\n }\n integer(history.requestId, \"viewport request id\");\n array(history.rowIds, \"viewport row ids\", rows);\n if (history.rowIds.length !== rows || new Set(history.rowIds).size !== rows) throw new Error(\"Invalid viewport row ids\");\n for (const id of history.rowIds) rowId(id, \"viewport row id\");\n const selection = history.selection;\n if (!isRecord(selection) || typeof selection.status !== \"string\" ||\n ![\"none\", \"valid\", \"invalidated\"].includes(selection.status)) throw new Error(\"Invalid selection status\");\n integer(selection.requestId, \"selection request id\");\n if (typeof selection.mode !== \"string\" || ![\"character\", \"word\", \"line\", \"rectangle\"].includes(selection.mode)) throw new Error(\"Invalid selection mode\");\n array(selection.ranges, \"selection ranges\", rows);\n let previousRow = -1;\n for (const range of selection.ranges) {\n if (!isRecord(range)) throw new Error(\"Invalid selection range\");\n const row = integer(range.row, \"selection range row\", previousRow + 1, rows - 1);\n const startColumn = integer(range.startColumn, \"selection start column\", 0, columns - 1);\n integer(range.endColumn, \"selection end column\", startColumn + 1, columns);\n previousRow = row;\n }\n validateSelectionText(selection);\n if (selection.status !== \"valid\" && selection.ranges.length) throw new Error(\"Inactive selection has highlight ranges\");\n if (history.copy !== null) {\n if (!isRecord(history.copy)) throw new Error(\"Missing copy metadata\");\n integer(history.copy.requestId, \"copy request id\", 1);\n validateSelectionText(history.copy);\n }\n}\n\nfunction validateSelectionText(selection: Record<string, unknown>): asserts selection is Record<string, unknown> & SelectionText {\n if (typeof selection.status !== \"string\" || ![\"none\", \"valid\", \"invalidated\"].includes(selection.status) ||\n (selection.status === \"valid\"\n ? typeof selection.text !== \"string\" || selection.text.length > LIMITS.metadataBytes\n : selection.text !== null)) {\n throw new Error(\"Invalid selection text\");\n }\n}\n\nfunction validateMetadata(metadata: unknown): asserts metadata is FrameMetadata {\n if (!isRecord(metadata) || metadata.version !== 1 || typeof metadata.full !== \"boolean\") {\n throw new Error(\"Unsupported frame metadata version\");\n }\n integer(metadata.revision, \"revision\", 1);\n integer(metadata.baseRevision, \"base revision\");\n if (typeof metadata.title !== \"string\" || metadata.title.length > LIMITS.titleUnits ||\n /[\\u0000-\\u001f\\u007f-\\u009f\\ud800-\\udfff]/u.test(metadata.title)) {\n throw new Error(\"Invalid terminal title\");\n }\n const progress = metadata.progress;\n if (!isRecord(progress) || typeof progress.state !== \"string\" ||\n ![\"none\", \"normal\", \"error\", \"indeterminate\", \"warning\"].includes(progress.state)) {\n throw new Error(\"Invalid terminal progress\");\n }\n if (progress.state === \"none\" || progress.state === \"indeterminate\") {\n if (progress.percentage !== null) throw new Error(\"Unexpected terminal progress percentage\");\n } else {\n integer(progress.percentage, \"terminal progress percentage\", 0, 100);\n }\n const shell = metadata.shellIntegration;\n if (!isRecord(shell) || typeof shell.phase !== \"string\" ||\n ![\"unknown\", \"prompt\", \"commandLine\", \"executing\", \"finished\"].includes(shell.phase)) {\n throw new Error(\"Invalid terminal shell integration\");\n }\n if (shell.lastExitCode !== null)\n integer(shell.lastExitCode, \"terminal shell exit code\", -2147483648, 2147483647);\n if (shell.phase === \"unknown\" && shell.lastExitCode !== null)\n throw new Error(\"Unknown terminal shell phase has an exit code\");\n const workingDirectory = metadata.workingDirectory;\n if (!isRecord(workingDirectory)) throw new Error(\"Invalid terminal working directory\");\n const wdFields = [workingDirectory.uri, workingDirectory.host, workingDirectory.path];\n if (wdFields.every(field => field === null)) {\n // No directory reported yet.\n } else if (wdFields.some(field => typeof field !== \"string\" || field.length > LIMITS.metadataBytes)) {\n throw new Error(\"Invalid terminal working directory\");\n }\n const commandMark = metadata.commandMark;\n if (commandMark !== null) {\n if (!isRecord(commandMark) || typeof commandMark.phase !== \"string\" ||\n ![\"unknown\", \"prompt\", \"commandLine\", \"executing\", \"finished\"].includes(commandMark.phase)) {\n throw new Error(\"Invalid terminal command mark\");\n }\n if (commandMark.exitCode !== null) {\n integer(commandMark.exitCode, \"terminal command mark exit code\", -2147483648, 2147483647);\n if (commandMark.phase !== \"finished\") throw new Error(\"Non-finished terminal command mark has an exit code\");\n }\n if (commandMark.rawParameters !== null &&\n (typeof commandMark.rawParameters !== \"string\" || commandMark.rawParameters.length > LIMITS.commandMarkParameterUnits)) {\n throw new Error(\"Invalid terminal command mark parameters\");\n }\n }\n const columns = integer(metadata.columns, \"columns\", 1, 1024);\n const rows = integer(metadata.rows, \"rows\", 1, 512);\n if (typeof metadata.mouseTracking !== \"number\" || ![0, 9, 1000, 1002, 1003].includes(metadata.mouseTracking)) {\n throw new Error(\"Unsupported mouse tracking mode\");\n }\n if (!isRecord(metadata.peer) || typeof metadata.peer.isPrimary !== \"boolean\") throw new Error(\"Invalid peer state\");\n for (const field of [\"id\", \"primaryId\"]) {\n const id = metadata.peer[field];\n if (id !== null && (typeof id !== \"string\" || !id.length || id.length > 256)) {\n throw new Error(`Invalid peer ${field}`);\n }\n }\n if (metadata.peer.id !== null && metadata.peer.isPrimary !== (metadata.peer.id === metadata.peer.primaryId)) {\n throw new Error(\"Inconsistent primary peer state\");\n }\n integer(columns * rows, \"cell count\", 1, LIMITS.cells);\n validateHistory(metadata.history, columns, rows);\n array(metadata.hyperlinks, \"hyperlinks\", columns * rows);\n let previousLinkEnd = 0;\n for (const link of metadata.hyperlinks) {\n if (!isRecord(link)) throw new Error(\"Invalid hyperlink\");\n const row = integer(link.row, \"hyperlink row\", 0, rows - 1);\n const start = integer(link.startColumn, \"hyperlink start column\", 0, columns - 1);\n const end = integer(link.endColumn, \"hyperlink end column\", start + 1, columns);\n if (row * columns + start < previousLinkEnd) throw new Error(\"Unordered or overlapping hyperlinks\");\n previousLinkEnd = row * columns + end;\n if (typeof link.uri !== \"string\" || !link.uri.length || link.uri.length > LIMITS.metadataBytes)\n throw new Error(\"Invalid hyperlink URI\");\n }\n if (metadata.cellWidth !== 10 || metadata.cellHeight !== 20) {\n throw new Error(\"This spike requires server geometry of 10 × 20 logical pixels\");\n }\n for (const field of [\"defaultBackground\", \"defaultForeground\"]) {\n if (metadata[field] !== undefined) integer(metadata[field], field, 0, 0xffffffff);\n }\n if (!isRecord(metadata.cursor) || typeof metadata.cursor.visible !== \"boolean\") throw new Error(\"Invalid cursor\");\n integer(metadata.cursor.x, \"cursor x\", -1, 1024);\n integer(metadata.cursor.y, \"cursor y\", -1, 512);\n const shapes = [\"Default\", \"BlinkingBlock\", \"SteadyBlock\", \"BlinkingUnderline\", \"SteadyUnderline\", \"BlinkingBar\", \"SteadyBar\"];\n if (typeof metadata.cursor.shape === \"string\") metadata.cursor.shape = shapes.indexOf(metadata.cursor.shape);\n integer(metadata.cursor.shape, \"cursor shape\", 0, 6);\n array(metadata.images, \"images\", LIMITS.images);\n array(metadata.retainedImages, \"retained image keys\", LIMITS.images);\n array(metadata.placements, \"placements\", LIMITS.placements);\n array(metadata.warnings, \"warnings\", 256);\n if (metadata.warnings.some(w => typeof w !== \"string\")) throw new Error(\"Invalid warning\");\n if (!isRecord(metadata.stats)) throw new Error(\"Invalid server metrics\");\n for (const field of [\"workloadBytes\", \"outputBatches\", \"captureMs\", \"elapsedMs\"]) {\n const metric = metadata.stats[field];\n if (typeof metric !== \"number\" || !Number.isFinite(metric) || metric < 0) {\n throw new Error(`Invalid server metric ${field}`);\n }\n }\n const retained = new Set<string>();\n for (const imageKey of metadata.retainedImages) {\n key(imageKey);\n if (retained.has(imageKey)) throw new Error(\"Duplicate retained image key\");\n retained.add(imageKey);\n }\n const imageKeys = new Set<string>();\n let decodedImageBytes = 0;\n for (const image of metadata.images) {\n if (!isRecord(image)) throw new Error(\"Invalid image\");\n key(image.key);\n if (imageKeys.has(image.key) || !retained.has(image.key)) throw new Error(\"Inconsistent new image keys\");\n imageKeys.add(image.key);\n const width = integer(image.width, \"image width\", 1, 16384);\n const height = integer(image.height, \"image height\", 1, 16384);\n const byteLength = integer(image.byteLength, \"image byte length\", 1, LIMITS.frameBytes);\n if (image.format !== \"rgba\" && image.format !== \"png\") throw new Error(\"Unsupported image format\");\n if (image.format === \"rgba\" && byteLength !== width * height * 4) {\n throw new Error(\"RGBA image size mismatch\");\n }\n decodedImageBytes += width * height * 4;\n if (decodedImageBytes > LIMITS.textureBytes) throw new Error(\"New images exceed decoded texture budget\");\n }\n for (const placement of metadata.placements) {\n if (!isRecord(placement)) throw new Error(\"Invalid placement\");\n key(placement.key);\n if (!retained.has(placement.key)) throw new Error(\"Placement references an unretained image\");\n if (placement.kind !== \"kgp\" && placement.kind !== \"sixel\") throw new Error(\"Invalid placement kind\");\n for (const field of [\"x\", \"y\", \"width\", \"height\", \"sourceX\", \"sourceY\", \"sourceWidth\", \"sourceHeight\", \"clipX\", \"clipY\", \"clipWidth\", \"clipHeight\", \"z\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || !Number.isFinite(coordinate) || Math.abs(coordinate) > 2147483648) {\n throw new Error(`Invalid placement ${field}`);\n }\n }\n for (const field of [\"width\", \"height\", \"sourceWidth\", \"sourceHeight\", \"clipWidth\", \"clipHeight\"]) {\n const coordinate = placement[field];\n if (typeof coordinate !== \"number\" || coordinate < 0) throw new Error(`Negative placement ${field}`);\n }\n }\n}\n\n/** Decode one complete, experimental HWT1 message, checking every boundary before reading. */\nexport function decodeFrame(buffer: unknown): TerminalFrame {\n if (!(buffer instanceof ArrayBuffer) || buffer.byteLength > LIMITS.frameBytes) {\n throw new Error(\"Invalid or oversized binary frame\");\n }\n const view = new DataView(buffer);\n let offset = 0;\n const requireBytes = (count: number) => {\n if (count < 0 || count > view.byteLength - offset) throw new Error(\"Truncated HWT1 frame\");\n };\n const u32 = () => { requireBytes(4); const n = view.getUint32(offset, true); offset += 4; return n; };\n if (u32() !== 0x31545748) throw new Error(\"Unsupported frame magic (expected HWT1)\");\n const metadataLength = integer(u32(), \"metadata length\", 2, LIMITS.metadataBytes);\n requireBytes(metadataLength);\n const metadata: unknown = JSON.parse(utf8.decode(new Uint8Array(buffer, offset, metadataLength)));\n offset += metadataLength;\n validateMetadata(metadata);\n const cellCount = metadata.columns * metadata.rows;\n const changedCount = integer(u32(), \"changed cell count\", 0, cellCount);\n if (changedCount > Math.floor((view.byteLength - offset) / 22)) throw new Error(\"Truncated cell records\");\n if (metadata.full && changedCount !== cellCount) throw new Error(\"Incomplete full frame\");\n const cells = [];\n const seen = new Set();\n for (let i = 0; i < changedCount; i++) {\n requireBytes(22);\n const index = u32();\n if (index >= cellCount || seen.has(index)) throw new Error(\"Invalid or duplicate cell index\");\n seen.add(index);\n const foreground = u32();\n const background = u32();\n const underlineColor = u32();\n const attributes = view.getUint16(offset, true);\n const width = view.getUint8(offset + 2);\n const underlineStyle = view.getUint8(offset + 3);\n const textLength = view.getUint16(offset + 4, true);\n offset += 6;\n if (underlineStyle > 5) throw new Error(\"Unsupported underline style\");\n requireBytes(textLength);\n const text = utf8.decode(new Uint8Array(buffer, offset, textLength));\n offset += textLength;\n cells.push({ index, foreground, background, underlineColor, attributes, width, underlineStyle, text });\n }\n const imageBytes = metadata.images.reduce((total, image) => total + image.byteLength, 0);\n if (imageBytes !== view.byteLength - offset) throw new Error(\"Image payload length mismatch\");\n const images = metadata.images.map(image => {\n const bytes = new Uint8Array(buffer, offset, image.byteLength);\n offset += image.byteLength;\n return { ...image, bytes };\n });\n return { metadata, cells, images };\n}\n\n/** Mirror text, not ANSI; continuation cells are already represented by their lead glyph. */\nexport function screenText(cells: readonly (TerminalCell | undefined)[], columns: number, rows: number): string {\n const lines = [];\n for (let y = 0; y < rows; y++) {\n let line = \"\";\n for (let x = 0; x < columns; x++) {\n const cell = cells[y * columns + x];\n if (!cell || cell.width === 0) continue;\n line += cell.attributes & 64 ? \" \".repeat(cell.width) : (cell.text || \" \");\n }\n lines.push(line.replace(/ +$/u, \"\"));\n }\n return lines.join(\"\\n\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
package/dist/renderer.js CHANGED
@@ -20,6 +20,11 @@ function rgba(packed) {
20
20
  function glyphKey(cell) {
21
21
  return `${cell.attributes & 5}/${cell.width}/${cell.text}`;
22
22
  }
23
+ function isKgpPlaceholder(cell) {
24
+ // The base scalar and following diacritics encode an image reference, not a glyph.
25
+ // Keep the authoritative text and colors intact even when no image is placed.
26
+ return cell.text.codePointAt(0) === 0x10eeee;
27
+ }
23
28
  /** Shelf packer. Plans are computed before mutating the atlas used by a submitted frame. */
24
29
  function packGlyphs(glyphs, size, scale, initial = { x: 0, y: 0, rowHeight: 0 }) {
25
30
  let { x, y, rowHeight } = initial;
@@ -210,7 +215,7 @@ export class TerminalRenderer {
210
215
  prepareGlyphs(cells) {
211
216
  const visible = new Map();
212
217
  for (const cell of cells) {
213
- if (!cell || !cell.width || !cell.text.trim() || (cell.attributes & 64))
218
+ if (!cell || !cell.width || !cell.text.trim() || (cell.attributes & 64) || isKgpPlaceholder(cell))
214
219
  continue;
215
220
  visible.set(glyphKey(cell), cell);
216
221
  }
@@ -387,7 +392,7 @@ export class TerminalRenderer {
387
392
  const y = Math.floor(i / this.columns) * CELL_HEIGHT;
388
393
  const width = Math.min(cell.width * CELL_WIDTH, this.width - x);
389
394
  const foreground = rgba(cell.foreground);
390
- const glyph = this.glyphs.get(glyphKey(cell));
395
+ const glyph = isKgpPlaceholder(cell) ? undefined : this.glyphs.get(glyphKey(cell));
391
396
  if (glyph) {
392
397
  const tint = glyph.colored ? (cell.attributes & 2 ? [0.5, 0.5, 0.5, 1] : WHITE) : foreground;
393
398
  this.quad(this.atlas, x, y, cell.width * CELL_WIDTH, CELL_HEIGHT, tint, glyph.colored ? 2 : 1, [glyph.u0, glyph.v0, glyph.u1, glyph.v1]);
@@ -448,7 +453,13 @@ export class TerminalRenderer {
448
453
  for (const image of this.images.values())
449
454
  image.destroy();
450
455
  this.images.clear();
456
+ this.textureBytes = 0;
451
457
  this.atlas?.destroy();
458
+ this.glyphs.clear();
459
+ this.glyphKeyUnits = 0;
460
+ this.batches = [];
461
+ this.quadCount = 0;
462
+ this.instances = new Float32Array(0);
452
463
  this.font?.dispose();
453
464
  this.fontMetrics.clear();
454
465
  this.backend.dispose();