poly-weaver 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/crosscheck/coordinator.d.ts.map +1 -1
  2. package/dist/crosscheck/coordinator.js +1 -0
  3. package/dist/crosscheck/coordinator.js.map +1 -1
  4. package/dist/crosscheck/live-agent-session.d.ts +3 -0
  5. package/dist/crosscheck/live-agent-session.d.ts.map +1 -1
  6. package/dist/crosscheck/live-agent-session.js +12 -2
  7. package/dist/crosscheck/live-agent-session.js.map +1 -1
  8. package/dist/offscreen/controller.d.ts +1 -1
  9. package/dist/offscreen/controller.d.ts.map +1 -1
  10. package/dist/offscreen/controller.js.map +1 -1
  11. package/dist/offscreen/fork.d.ts +2 -1
  12. package/dist/offscreen/fork.d.ts.map +1 -1
  13. package/dist/offscreen/fork.js +11 -2
  14. package/dist/offscreen/fork.js.map +1 -1
  15. package/dist/providers/copilot/trust.js +1 -1
  16. package/dist/providers/copilot/trust.js.map +1 -1
  17. package/dist/terminal/color-negotiation.d.ts +37 -0
  18. package/dist/terminal/color-negotiation.d.ts.map +1 -0
  19. package/dist/terminal/color-negotiation.js +154 -0
  20. package/dist/terminal/color-negotiation.js.map +1 -0
  21. package/dist/terminal/color-protocol.d.ts +36 -0
  22. package/dist/terminal/color-protocol.d.ts.map +1 -0
  23. package/dist/terminal/color-protocol.js +88 -0
  24. package/dist/terminal/color-protocol.js.map +1 -0
  25. package/dist/terminal/host-input-mode.d.ts.map +1 -1
  26. package/dist/terminal/host-input-mode.js +6 -2
  27. package/dist/terminal/host-input-mode.js.map +1 -1
  28. package/dist/terminal/host.d.ts +13 -4
  29. package/dist/terminal/host.d.ts.map +1 -1
  30. package/dist/terminal/host.js +139 -44
  31. package/dist/terminal/host.js.map +1 -1
  32. package/dist/terminal/input-session.d.ts +23 -0
  33. package/dist/terminal/input-session.d.ts.map +1 -0
  34. package/dist/terminal/input-session.js +97 -0
  35. package/dist/terminal/input-session.js.map +1 -0
  36. package/dist/terminal/key-event-source.d.ts +5 -1
  37. package/dist/terminal/key-event-source.d.ts.map +1 -1
  38. package/dist/terminal/key-event-source.js +1 -0
  39. package/dist/terminal/key-event-source.js.map +1 -1
  40. package/dist/terminal/stdin-byte-source.d.ts +13 -8
  41. package/dist/terminal/stdin-byte-source.d.ts.map +1 -1
  42. package/dist/terminal/stdin-byte-source.js +84 -40
  43. package/dist/terminal/stdin-byte-source.js.map +1 -1
  44. package/dist/terminal/virtual-terminal.d.ts +2 -0
  45. package/dist/terminal/virtual-terminal.d.ts.map +1 -1
  46. package/dist/terminal/virtual-terminal.js +17 -0
  47. package/dist/terminal/virtual-terminal.js.map +1 -1
  48. package/dist/terminal-input.d.ts +19 -2
  49. package/dist/terminal-input.d.ts.map +1 -1
  50. package/dist/terminal-input.js +162 -6
  51. package/dist/terminal-input.js.map +1 -1
  52. package/package.json +2 -2
@@ -1,75 +1,114 @@
1
- import { TerminalKeyParser, } from "../terminal-input.js";
1
+ import { TerminalInputSession } from "./input-session.js";
2
2
  import { disableHostInputModes, enableHostInputModes, enableRightClickPasteMouseMode, } from "./host-input-mode.js";
3
3
  /**
4
4
  * Default `KeyEventSource`. Owns raw-mode on its injected stdin and
5
5
  * optional VT input-mode negotiation on its injected stdout.
6
6
  *
7
- * Internally drives a `TerminalKeyParser`; consumers only see the
8
- * structured `TerminalKey[]` stream — the byte-level parser is no
9
- * longer part of any consumer's surface.
7
+ * A private start owns a fresh input session through stop. Hosted sources
8
+ * borrow only a consumer lease; their owner's parser survives handoffs.
10
9
  */
11
10
  export class StdinByteSource {
12
11
  stdin;
13
12
  out;
13
+ configuredShiftEnterBytes;
14
14
  options;
15
- parser;
16
15
  subscribers = new Set();
17
- dataListener;
16
+ ownership;
17
+ activation;
18
18
  disableRightClickPasteMouseMode;
19
19
  prevRawMode = false;
20
- started = false;
20
+ modesEnabled = false;
21
+ rawAcquired = false;
21
22
  constructor(stdin, out = process.stdout, configuredShiftEnterBytes, options = {}) {
22
23
  this.stdin = stdin;
23
24
  this.out = out;
25
+ this.configuredShiftEnterBytes = configuredShiftEnterBytes;
24
26
  this.options = options;
25
- this.parser = new TerminalKeyParser(50, configuredShiftEnterBytes);
26
- this.parser.onDeferredKeys((keys) => this.fanOut(keys));
27
+ if (options.inputSession && options.inputSession.stdin !== stdin) {
28
+ throw new Error("Borrowed terminal input session uses a different stream");
29
+ }
30
+ options.inputSession?.assertLive();
31
+ this.ownership = options.inputSession
32
+ ? { kind: "borrowed", session: options.inputSession }
33
+ : { kind: "private" };
27
34
  }
28
35
  start() {
29
- if (this.started)
36
+ if (this.activation)
30
37
  return;
31
- this.started = true;
32
- if (this.stdin.isTTY) {
33
- this.prevRawMode = this.stdin.isRaw === true;
34
- this.stdin.setRawMode(true);
35
- enableHostInputModes(this.out);
36
- if (this.options.enableRightClickPaste === true) {
37
- this.disableRightClickPasteMouseMode = enableRightClickPasteMouseMode(this.out);
38
+ const session = this.ownership.kind === "borrowed" ? this.ownership.session
39
+ : new TerminalInputSession(this.stdin, this.configuredShiftEnterBytes, this.options.clock);
40
+ try {
41
+ const lease = session.acquire((events) => this.fanOut(events));
42
+ this.activation = { session, lease };
43
+ if (this.stdin.isTTY) {
44
+ this.prevRawMode = this.stdin.isRaw === true;
45
+ this.rawAcquired = true;
46
+ this.stdin.setRawMode(true);
47
+ enableHostInputModes(this.out);
48
+ this.modesEnabled = true;
49
+ if (this.options.enableRightClickPaste === true) {
50
+ this.disableRightClickPasteMouseMode = enableRightClickPasteMouseMode(this.out);
51
+ }
38
52
  }
39
- this.stdin.resume();
53
+ lease.setEnabled(this.subscribers.size > 0);
54
+ }
55
+ catch (error) {
56
+ try {
57
+ this.stop();
58
+ }
59
+ catch (cleanupError) {
60
+ throw new AggregateError([error, cleanupError], "Terminal input start and cleanup failed");
61
+ }
62
+ finally {
63
+ if (this.ownership.kind === "private")
64
+ session.dispose();
65
+ }
66
+ throw error;
40
67
  }
41
- this.dataListener = (chunk) => {
42
- const events = this.parser.parseChunk(chunk);
43
- if (events.length > 0)
44
- this.fanOut(events);
45
- };
46
- this.stdin.on("data", this.dataListener);
47
68
  }
48
69
  stop() {
49
- if (!this.started)
70
+ const activation = this.activation;
71
+ if (!activation)
50
72
  return;
51
- this.started = false;
52
- if (this.dataListener) {
53
- this.stdin.removeListener("data", this.dataListener);
54
- this.dataListener = undefined;
73
+ this.activation = undefined;
74
+ try {
75
+ activation.lease.release();
55
76
  }
56
- this.parser.cancelPendingEscape();
57
- if (this.stdin.isTTY) {
58
- this.disableRightClickPasteMouseMode?.();
59
- this.disableRightClickPasteMouseMode = undefined;
60
- disableHostInputModes(this.out);
77
+ finally {
61
78
  try {
62
- this.stdin.setRawMode(this.prevRawMode);
79
+ try {
80
+ this.disableRightClickPasteMouseMode?.();
81
+ }
82
+ finally {
83
+ this.disableRightClickPasteMouseMode = undefined;
84
+ if (this.modesEnabled) {
85
+ this.modesEnabled = false;
86
+ disableHostInputModes(this.out);
87
+ }
88
+ }
89
+ }
90
+ finally {
91
+ try {
92
+ if (this.rawAcquired) {
93
+ this.rawAcquired = false;
94
+ this.stdin.setRawMode(this.prevRawMode);
95
+ }
96
+ }
97
+ finally {
98
+ if (this.ownership.kind === "private")
99
+ activation.session.dispose();
100
+ }
63
101
  }
64
- catch { /* ignore */ }
65
- }
66
- else {
67
- this.disableRightClickPasteMouseMode = undefined;
68
102
  }
69
103
  }
70
104
  onEvents(cb) {
71
105
  this.subscribers.add(cb);
72
- return () => { this.subscribers.delete(cb); };
106
+ this.activation?.lease.setEnabled(true);
107
+ return () => {
108
+ this.subscribers.delete(cb);
109
+ if (this.subscribers.size === 0)
110
+ this.activation?.lease.setEnabled(false);
111
+ };
73
112
  }
74
113
  onResize(_cb) {
75
114
  // libuv refreshes stdout.columns/stdout.rows and fires the stdout
@@ -78,11 +117,16 @@ export class StdinByteSource {
78
117
  return () => { };
79
118
  }
80
119
  fanOut(events) {
120
+ const activation = this.activation;
121
+ if (!activation)
122
+ return;
81
123
  // Snapshot only when multiple subscribers exist so a callback that
82
124
  // unsubscribes itself does not perturb iteration. The typical single
83
125
  // host subscriber goes through the direct path without an array copy.
84
126
  if (this.subscribers.size > 1) {
85
127
  for (const cb of Array.from(this.subscribers)) {
128
+ if (this.activation !== activation)
129
+ break;
86
130
  try {
87
131
  cb(events);
88
132
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stdin-byte-source.js","sourceRoot":"","sources":["../../src/terminal/stdin-byte-source.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAO9B;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IASP;IACA;IAEA;IAXF,MAAM,CAAoB;IAC1B,WAAW,GAAG,IAAI,GAAG,EAAmC,CAAC;IAClE,YAAY,CAAwC;IACpD,+BAA+B,CAA2B;IAC1D,WAAW,GAAG,KAAK,CAAC;IACpB,OAAO,GAAG,KAAK,CAAC;IAExB,YACmB,KAAwB,EACxB,MAA6B,OAAO,CAAC,MAAM,EAC5D,yBAAkC,EACjB,UAAkC,EAAE;QAHpC,UAAK,GAAL,KAAK,CAAmB;QACxB,QAAG,GAAH,GAAG,CAAwC;QAE3C,YAAO,GAAP,OAAO,CAA6B;QAErD,IAAI,CAAC,MAAM,GAAG,IAAI,iBAAiB,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,UAAW,CAAC,IAAI,CAAC,CAAC;YAC7B,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,qBAAqB,KAAK,IAAI,EAAE,CAAC;gBAChD,IAAI,CAAC,+BAA+B,GAAG,8BAA8B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClF,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QAErB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACrD,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,+BAA+B,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,+BAA+B,GAAG,SAAS,CAAC;YACjD,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC;gBACH,IAAI,CAAC,KAAK,CAAC,UAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC3C,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,+BAA+B,GAAG,SAAS,CAAC;QACnD,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,EAAmC;QAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,QAAQ,CAAC,GAA+B;QACtC,kEAAkE;QAClE,kEAAkE;QAClE,2CAA2C;QAC3C,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAClB,CAAC;IAEO,MAAM,CAAC,MAAqB;QAClC,mEAAmE;QACnE,qEAAqE;QACrE,sEAAsE;QACtE,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC;oBAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;YAC3F,CAAC;YACD,OAAO;QACT,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC;gBAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"stdin-byte-source.js","sourceRoot":"","sources":["../../src/terminal/stdin-byte-source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAS9B;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IAUP;IACA;IACA;IACA;IAZF,WAAW,GAAG,IAAI,GAAG,EAAmC,CAAC;IACzD,SAAS,CAA4E;IAC9F,UAAU,CAAmE;IAC7E,+BAA+B,CAA2B;IAC1D,WAAW,GAAG,KAAK,CAAC;IACpB,YAAY,GAAG,KAAK,CAAC;IACrB,WAAW,GAAG,KAAK,CAAC;IAE5B,YACmB,KAAwB,EACxB,MAA6B,OAAO,CAAC,MAAM,EAC3C,yBAAkC,EAClC,UAAkC,EAAE;QAHpC,UAAK,GAAL,KAAK,CAAmB;QACxB,QAAG,GAAH,GAAG,CAAwC;QAC3C,8BAAyB,GAAzB,yBAAyB,CAAS;QAClC,YAAO,GAAP,OAAO,CAA6B;QAErD,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,YAAY;YACnC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,EAAE;YACrD,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO;YACzE,CAAC,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7F,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAC/D,IAAI,CAAC,UAAU,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;gBAC7C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,KAAK,CAAC,UAAW,CAAC,IAAI,CAAC,CAAC;gBAC7B,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBACzB,IAAI,IAAI,CAAC,OAAO,CAAC,qBAAqB,KAAK,IAAI,EAAE,CAAC;oBAChD,IAAI,CAAC,+BAA+B,GAAG,8BAA8B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClF,CAAC;YACH,CAAC;YACD,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,CAAC;YAAC,OAAO,YAAY,EAAE,CAAC;gBACtB,MAAM,IAAI,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,yCAAyC,CAAC,CAAC;YAC7F,CAAC;oBAAS,CAAC;gBACT,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS;oBAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3D,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,IAAI;QACF,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC;YACH,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,CAAC;oBACH,IAAI,CAAC,+BAA+B,EAAE,EAAE,CAAC;gBAC3C,CAAC;wBAAS,CAAC;oBACT,IAAI,CAAC,+BAA+B,GAAG,SAAS,CAAC;oBACjD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;wBAC1B,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAClC,CAAC;gBACH,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC;oBACH,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBACrB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;wBACzB,IAAI,CAAC,KAAK,CAAC,UAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBAC3C,CAAC;gBACH,CAAC;wBAAS,CAAC;oBACT,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS;wBAAE,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACtE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,EAAmC;QAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5E,CAAC,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,GAA+B;QACtC,kEAAkE;QAClE,kEAAkE;QAClE,2CAA2C;QAC3C,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAClB,CAAC;IAEO,MAAM,CAAC,MAAqB;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,mEAAmE;QACnE,qEAAqE;QACrE,sEAAsE;QACtE,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9C,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU;oBAAE,MAAM;gBAC1C,IAAI,CAAC;oBAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;YAC3F,CAAC;YACD,OAAO;QACT,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC;gBAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;CACF"}
@@ -1,6 +1,8 @@
1
1
  import type { IBuffer, IBufferCell, IMarker } from "@xterm/headless";
2
+ import { type ColorQuery } from "./color-protocol.js";
2
3
  export interface VirtualTerminalOptions {
3
4
  onOscClipboard?: (data: string) => void;
5
+ onColorQuery?: (query: ColorQuery) => void;
4
6
  }
5
7
  /**
6
8
  * Wraps `@xterm/headless` so the rest of the host doesn't need to
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-terminal.d.ts","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,OAAO,EAER,MAAM,iBAAiB,CAAC;AAKzB,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,kBAAkB,CAAQ;gBAEtB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B;IAkCzE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IAQ7D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,0DAA0D;IAC1D,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,oFAAoF;IACpF,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,8CAA8C;IAC9C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,8CAA8C;IAC9C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,gDAAgD;IAChD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,yEAAyE;IACzE,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,oFAAoF;IACpF,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,wDAAwD;IACxD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,0DAA0D;IAC1D,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,gFAAgF;IAChF,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,2DAA2D;IAC3D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK/B,8DAA8D;IAC9D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,8EAA8E;IAC9E,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKpC,uDAAuD;IACvD,WAAW,IAAI,IAAI;IAInB,mDAAmD;IACnD,cAAc,IAAI,IAAI;IAItB,2DAA2D;IAC3D,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAKnD,oFAAoF;IACpF,OAAO,IAAI,WAAW;IAItB,OAAO,IAAI,IAAI;CAGhB"}
1
+ {"version":3,"file":"virtual-terminal.d.ts","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,OAAO,EAER,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAIzE,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,kBAAkB,CAAQ;gBAEtB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B;IAiDzE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IAQ7D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,0DAA0D;IAC1D,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,oFAAoF;IACpF,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,8CAA8C;IAC9C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,8CAA8C;IAC9C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,gDAAgD;IAChD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,yEAAyE;IACzE,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,oFAAoF;IACpF,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,wDAAwD;IACxD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,0DAA0D;IAC1D,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,gFAAgF;IAChF,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,2DAA2D;IAC3D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK/B,8DAA8D;IAC9D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,8EAA8E;IAC9E,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKpC,uDAAuD;IACvD,WAAW,IAAI,IAAI;IAInB,mDAAmD;IACnD,cAAc,IAAI,IAAI;IAItB,2DAA2D;IAC3D,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAKnD,oFAAoF;IACpF,OAAO,IAAI,WAAW;IAItB,OAAO,IAAI,IAAI;CAGhB"}
@@ -1,5 +1,6 @@
1
1
  import xtermHeadless from "@xterm/headless";
2
2
  import { parseOsc52 } from "./osc52.js";
3
+ import { parseColorQueries } from "./color-protocol.js";
3
4
  const { Terminal } = xtermHeadless;
4
5
  /**
5
6
  * Wraps `@xterm/headless` so the rest of the host doesn't need to
@@ -41,6 +42,22 @@ export class VirtualTerminal {
41
42
  }
42
43
  return false;
43
44
  });
45
+ for (const command of [4, 10, 11]) {
46
+ this.term.parser.registerOscHandler(command, (data) => {
47
+ for (const query of parseColorQueries(command, data))
48
+ opts.onColorQuery?.(query);
49
+ return true;
50
+ });
51
+ }
52
+ for (const command of [104, 110, 111]) {
53
+ this.term.parser.registerOscHandler(command, () => true);
54
+ }
55
+ this.term.parser.registerCsiHandler({ prefix: "?", final: "n" }, (params) => {
56
+ if (params.length !== 1 || params[0] !== 996)
57
+ return false;
58
+ opts.onColorQuery?.({ kind: "appearance" });
59
+ return true;
60
+ });
44
61
  const onOscClipboard = opts.onOscClipboard;
45
62
  if (onOscClipboard) {
46
63
  this.term.parser.registerOscHandler(52, (data) => {
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-terminal.js","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"virtual-terminal.js","sourceRoot":"","sources":["../../src/terminal/virtual-terminal.ts"],"names":[],"mappings":"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"}
@@ -2,13 +2,15 @@
2
2
  * Shared terminal input parser — bytes → low-level key identities.
3
3
  *
4
4
  * This module owns the byte-level state machine (normal/esc/csi/utf8),
5
- * kitty keyboard protocol parsing, and escape timeout.
5
+ * kitty keyboard protocol parsing, escape timeout and bounded color-report
6
+ * separation. Covered reports use a distinct callback, never key events.
6
7
  * It produces {@link TerminalKey} events with no domain semantics.
7
8
  *
8
9
  * Consumers wrap this via composition and map TerminalKey → their own domain
9
10
  * event types. EmacsInputParser is the shared readline-style mapper for
10
11
  * prompt and TUI text-editing surfaces.
11
12
  */
13
+ import { type ColorReport, type InputClock } from "./terminal/color-protocol.js";
12
14
  export type TerminalKey = {
13
15
  kind: "printable";
14
16
  char: string;
@@ -59,6 +61,7 @@ export type TerminalKey = {
59
61
  export declare class TerminalKeyParser {
60
62
  private readonly escapeTimeoutMs;
61
63
  private readonly configuredShiftEnterBytes?;
64
+ private readonly clock;
62
65
  private state;
63
66
  private csiParams;
64
67
  private legacyMouseBytes;
@@ -70,11 +73,25 @@ export declare class TerminalKeyParser {
70
73
  private pasteEndMatch;
71
74
  private configuredShiftEnterMatch;
72
75
  private configuredShiftEnterTimer;
73
- constructor(escapeTimeoutMs?: number, configuredShiftEnterBytes?: Buffer | undefined);
76
+ private reportCandidate;
77
+ private reportFrame;
78
+ private reportDeadline;
79
+ private reportTimer;
80
+ private reportCallback;
81
+ private disposed;
82
+ constructor(escapeTimeoutMs?: number, configuredShiftEnterBytes?: Buffer | undefined, clock?: InputClock);
83
+ onReport(cb: (report: ColorReport) => void): void;
84
+ dispose(): void;
74
85
  onDeferredKeys(cb: (keys: TerminalKey[]) => void): void;
75
86
  cancelPendingEscape(): void;
76
87
  parseChunk(chunk: Buffer): TerminalKey[];
77
88
  private processByte;
89
+ private armReportTimer;
90
+ private clearReport;
91
+ private expireReport;
92
+ private flushKeyboardPrefix;
93
+ private consumeReportByte;
94
+ private processKeyboardByte;
78
95
  private processByteWithoutConfiguredShiftEnter;
79
96
  private consumeConfiguredShiftEnterByte;
80
97
  private startConfiguredShiftEnterTimer;
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-input.d.ts","sourceRoot":"","sources":["../src/terminal-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAkBnC,qBAAa,iBAAiB;IAc1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IAd7C,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,WAAW,CAA4C;IAC/D,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,yBAAyB,CAAgB;IACjD,OAAO,CAAC,yBAAyB,CAA4C;gBAG1D,eAAe,SAAK,EACpB,yBAAyB,CAAC,EAAE,MAAM,YAAA;IAGrD,cAAc,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,IAAI;IAIvD,mBAAmB,IAAI,IAAI;IAQ3B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE;IAqBxC,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,sCAAsC;IA0G9C,OAAO,CAAC,+BAA+B;IAoCvC,OAAO,CAAC,8BAA8B;IAkBtC,OAAO,CAAC,iCAAiC;IAQzC,OAAO,CAAC,QAAQ;IAqBhB,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,SAAS;IAiJjB,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,mBAAmB;CAM5B"}
1
+ {"version":3,"file":"terminal-input.d.ts","sourceRoot":"","sources":["../src/terminal-input.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,8 @@
2
2
  * Shared terminal input parser — bytes → low-level key identities.
3
3
  *
4
4
  * This module owns the byte-level state machine (normal/esc/csi/utf8),
5
- * kitty keyboard protocol parsing, and escape timeout.
5
+ * kitty keyboard protocol parsing, escape timeout and bounded color-report
6
+ * separation. Covered reports use a distinct callback, never key events.
6
7
  * It produces {@link TerminalKey} events with no domain semantics.
7
8
  *
8
9
  * Consumers wrap this via composition and map TerminalKey → their own domain
@@ -10,6 +11,7 @@
10
11
  * prompt and TUI text-editing surfaces.
11
12
  */
12
13
  import { PASTE_END } from "./ansi.js";
14
+ import { COLOR_FRAME_TIMEOUT_MS, COLOR_PREFIX_TIMEOUT_MS, COLOR_REPORT_HEADERS, MAX_COLOR_FRAME_BYTES, inputClock, parseColorReports, } from "./terminal/color-protocol.js";
13
15
  const SUPPRESSED = { tag: "suppressed" };
14
16
  const UNRECOGNIZED = { tag: "unrecognized" };
15
17
  const START_PASTE = { tag: "start-paste" };
@@ -21,6 +23,7 @@ function keys(...k) {
21
23
  export class TerminalKeyParser {
22
24
  escapeTimeoutMs;
23
25
  configuredShiftEnterBytes;
26
+ clock;
24
27
  state = "normal";
25
28
  csiParams = "";
26
29
  legacyMouseBytes = [];
@@ -32,28 +35,57 @@ export class TerminalKeyParser {
32
35
  pasteEndMatch = 0;
33
36
  configuredShiftEnterMatch = [];
34
37
  configuredShiftEnterTimer;
35
- constructor(escapeTimeoutMs = 50, configuredShiftEnterBytes) {
38
+ reportCandidate = "";
39
+ reportFrame;
40
+ reportDeadline = 0;
41
+ reportTimer;
42
+ reportCallback;
43
+ disposed = false;
44
+ constructor(escapeTimeoutMs = 50, configuredShiftEnterBytes, clock = inputClock) {
36
45
  this.escapeTimeoutMs = escapeTimeoutMs;
37
46
  this.configuredShiftEnterBytes = configuredShiftEnterBytes;
47
+ this.clock = clock;
48
+ }
49
+ onReport(cb) {
50
+ this.reportCallback = cb;
51
+ }
52
+ dispose() {
53
+ this.disposed = true;
54
+ this.cancelPendingEscape();
55
+ this.clearReport();
56
+ this.deferredCallback = undefined;
57
+ this.reportCallback = undefined;
58
+ this.state = "normal";
59
+ this.csiParams = "";
60
+ this.utf8Buffer = [];
61
+ this.legacyMouseBytes = [];
62
+ this.pasteBuffer = null;
63
+ this.pasteEndMatch = 0;
38
64
  }
39
65
  onDeferredKeys(cb) {
40
66
  this.deferredCallback = cb;
41
67
  }
42
68
  cancelPendingEscape() {
43
69
  if (this.escapeTimer != null) {
44
- clearTimeout(this.escapeTimer);
70
+ this.clock.clearTimeout(this.escapeTimer);
45
71
  this.escapeTimer = undefined;
46
72
  }
47
73
  this.cancelPendingConfiguredShiftEnter();
48
74
  }
49
75
  parseChunk(chunk) {
50
76
  const out = [];
77
+ if (this.disposed)
78
+ return out;
51
79
  for (const byte of chunk) {
80
+ if (this.disposed)
81
+ break;
52
82
  this.processByte(byte, out);
53
83
  }
54
84
  // Bare ESC at end of chunk: start escape timeout
55
85
  if (this.state === "esc" && this.escapeTimer == null) {
56
- this.escapeTimer = setTimeout(() => {
86
+ this.escapeTimer = this.clock.setTimeout(() => {
87
+ if (this.disposed)
88
+ return;
57
89
  this.escapeTimer = undefined;
58
90
  if (this.state === "esc") {
59
91
  this.state = "normal";
@@ -64,6 +96,128 @@ export class TerminalKeyParser {
64
96
  return out;
65
97
  }
66
98
  processByte(byte, out) {
99
+ this.expireReport(out);
100
+ if (this.reportFrame) {
101
+ this.consumeReportByte(byte);
102
+ return;
103
+ }
104
+ if (this.reportCandidate) {
105
+ const candidate = this.reportCandidate + String.fromCharCode(byte);
106
+ if (COLOR_REPORT_HEADERS.some((header) => header.startsWith(candidate))) {
107
+ this.reportCandidate = candidate;
108
+ if (COLOR_REPORT_HEADERS.some((header) => header === candidate)) {
109
+ // Resolve earlier keyboard bytes only once this candidate is a report.
110
+ this.flushKeyboardPrefix(out);
111
+ this.reportFrame = { header: candidate, body: "", size: candidate.length, invalid: false, st: false };
112
+ this.reportCandidate = "";
113
+ this.armReportTimer(COLOR_FRAME_TIMEOUT_MS);
114
+ }
115
+ return;
116
+ }
117
+ const pending = this.reportCandidate;
118
+ this.clearReport();
119
+ for (const ch of pending)
120
+ this.processKeyboardByte(ch.charCodeAt(0), out);
121
+ // The mismatching byte is new input, not part of the replayed prefix.
122
+ if (byte === 0x1b) {
123
+ if (this.state === "esc")
124
+ this.flushKeyboardPrefix(out);
125
+ this.processByte(byte, out);
126
+ }
127
+ else {
128
+ this.processKeyboardByte(byte, out);
129
+ }
130
+ return;
131
+ }
132
+ if (this.pasteBuffer === null && this.state === "normal" && byte === 0x1b) {
133
+ this.reportCandidate = "\x1b";
134
+ this.armReportTimer(Math.min(this.escapeTimeoutMs, COLOR_PREFIX_TIMEOUT_MS));
135
+ return;
136
+ }
137
+ this.processKeyboardByte(byte, out);
138
+ }
139
+ armReportTimer(ms) {
140
+ if (this.reportTimer !== undefined)
141
+ this.clock.clearTimeout(this.reportTimer);
142
+ this.reportDeadline = this.clock.now() + ms;
143
+ const deadline = this.reportDeadline;
144
+ const expire = () => {
145
+ if (this.disposed || this.reportDeadline !== deadline)
146
+ return;
147
+ const out = [];
148
+ this.expireReport(out);
149
+ if (this.reportDeadline === deadline) {
150
+ // Timer scheduling may round down fractional monotonic time. Keep the
151
+ // original deadline and retry rather than leaving a candidate stranded.
152
+ this.reportTimer = this.clock.setTimeout(expire, Math.max(1, Math.ceil(deadline - this.clock.now())));
153
+ }
154
+ if (out.length > 0)
155
+ this.deferredCallback?.(out);
156
+ };
157
+ this.reportTimer = this.clock.setTimeout(expire, ms);
158
+ }
159
+ clearReport() {
160
+ if (this.reportTimer !== undefined)
161
+ this.clock.clearTimeout(this.reportTimer);
162
+ this.reportTimer = undefined;
163
+ this.reportDeadline = 0;
164
+ this.reportFrame = undefined;
165
+ this.reportCandidate = "";
166
+ }
167
+ expireReport(out) {
168
+ if ((!this.reportCandidate && !this.reportFrame) || this.clock.now() < this.reportDeadline)
169
+ return;
170
+ const pending = this.reportCandidate;
171
+ this.clearReport();
172
+ for (const ch of pending)
173
+ this.processKeyboardByte(ch.charCodeAt(0), out);
174
+ if (pending) {
175
+ // Do not give a bare Esc/configured prefix another recognition budget.
176
+ this.flushKeyboardPrefix(out);
177
+ }
178
+ }
179
+ flushKeyboardPrefix(out) {
180
+ const configured = this.configuredShiftEnterMatch;
181
+ this.cancelPendingConfiguredShiftEnter();
182
+ for (const byte of configured)
183
+ this.processByteWithoutConfiguredShiftEnter(byte, out);
184
+ if (this.state === "esc") {
185
+ this.cancelPendingEscape();
186
+ this.state = "normal";
187
+ out.push({ kind: "escape" });
188
+ }
189
+ }
190
+ consumeReportByte(byte) {
191
+ const frame = this.reportFrame;
192
+ if (byte === 0x18 || byte === 0x1a) {
193
+ this.clearReport();
194
+ return;
195
+ }
196
+ const appearance = frame.header === "\x1b[?997;";
197
+ const final = appearance ? byte >= 0x40 && byte <= 0x7e
198
+ : byte === 0x07 || (frame.st && byte === 0x5c);
199
+ frame.size = Math.min(MAX_COLOR_FRAME_BYTES + 1, frame.size + 1);
200
+ if (final) {
201
+ const valid = !frame.invalid && frame.size <= MAX_COLOR_FRAME_BYTES
202
+ && (appearance ? byte === 0x6e : !frame.st || byte === 0x5c);
203
+ const reports = valid ? parseColorReports(frame.header, frame.body) : [];
204
+ this.clearReport();
205
+ for (const report of reports) {
206
+ if (!this.disposed)
207
+ this.reportCallback?.(report);
208
+ }
209
+ return;
210
+ }
211
+ if (frame.st || frame.size > MAX_COLOR_FRAME_BYTES
212
+ || (byte !== 0x1b && (byte < 0x20 || byte > 0x7e))) {
213
+ frame.invalid = true;
214
+ frame.body = "";
215
+ }
216
+ frame.st = !appearance && byte === 0x1b;
217
+ if (!frame.invalid && !frame.st)
218
+ frame.body += String.fromCharCode(byte);
219
+ }
220
+ processKeyboardByte(byte, out) {
67
221
  if (this.pasteBuffer === null
68
222
  && this.state === "normal"
69
223
  && this.consumeConfiguredShiftEnterByte(byte, out)) {
@@ -218,7 +372,9 @@ export class TerminalKeyParser {
218
372
  startConfiguredShiftEnterTimer() {
219
373
  if (this.configuredShiftEnterTimer !== undefined)
220
374
  return;
221
- this.configuredShiftEnterTimer = setTimeout(() => {
375
+ this.configuredShiftEnterTimer = this.clock.setTimeout(() => {
376
+ if (this.disposed)
377
+ return;
222
378
  this.configuredShiftEnterTimer = undefined;
223
379
  if (this.configuredShiftEnterMatch.length === 0)
224
380
  return;
@@ -238,7 +394,7 @@ export class TerminalKeyParser {
238
394
  }
239
395
  cancelPendingConfiguredShiftEnter() {
240
396
  if (this.configuredShiftEnterTimer !== undefined) {
241
- clearTimeout(this.configuredShiftEnterTimer);
397
+ this.clock.clearTimeout(this.configuredShiftEnterTimer);
242
398
  this.configuredShiftEnterTimer = undefined;
243
399
  }
244
400
  this.configuredShiftEnterMatch = [];