poly-weaver 0.7.1 → 0.8.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 (232) hide show
  1. package/dist/agents/implementors/handler.d.ts.map +1 -1
  2. package/dist/agents/implementors/handler.js +2 -1
  3. package/dist/agents/implementors/handler.js.map +1 -1
  4. package/dist/agents/planners/handler.d.ts.map +1 -1
  5. package/dist/agents/planners/handler.js +2 -1
  6. package/dist/agents/planners/handler.js.map +1 -1
  7. package/dist/agents/reviewers/handler.d.ts.map +1 -1
  8. package/dist/agents/reviewers/handler.js +2 -1
  9. package/dist/agents/reviewers/handler.js.map +1 -1
  10. package/dist/agents/runner.d.ts +25 -0
  11. package/dist/agents/runner.d.ts.map +1 -1
  12. package/dist/agents/runner.js +63 -1
  13. package/dist/agents/runner.js.map +1 -1
  14. package/dist/agents/simplifiers/handler.d.ts.map +1 -1
  15. package/dist/agents/simplifiers/handler.js +2 -1
  16. package/dist/agents/simplifiers/handler.js.map +1 -1
  17. package/dist/ansi.d.ts +21 -0
  18. package/dist/ansi.d.ts.map +1 -1
  19. package/dist/ansi.js +45 -0
  20. package/dist/ansi.js.map +1 -1
  21. package/dist/app-header.d.ts +16 -0
  22. package/dist/app-header.d.ts.map +1 -0
  23. package/dist/app-header.js +74 -0
  24. package/dist/app-header.js.map +1 -0
  25. package/dist/cli.js +81 -59
  26. package/dist/cli.js.map +1 -1
  27. package/dist/config.d.ts +1 -0
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +6 -0
  30. package/dist/config.js.map +1 -1
  31. package/dist/dump/collector.d.ts +2 -1
  32. package/dist/dump/collector.d.ts.map +1 -1
  33. package/dist/dump/collector.js +12 -0
  34. package/dist/dump/collector.js.map +1 -1
  35. package/dist/dump/hotkey.d.ts +9 -30
  36. package/dist/dump/hotkey.d.ts.map +1 -1
  37. package/dist/dump/hotkey.js +15 -158
  38. package/dist/dump/hotkey.js.map +1 -1
  39. package/dist/dump/pty-tail-buffer.d.ts +25 -0
  40. package/dist/dump/pty-tail-buffer.d.ts.map +1 -0
  41. package/dist/dump/pty-tail-buffer.js +48 -0
  42. package/dist/dump/pty-tail-buffer.js.map +1 -0
  43. package/dist/dump/service.d.ts +3 -2
  44. package/dist/dump/service.d.ts.map +1 -1
  45. package/dist/dump/service.js +6 -1
  46. package/dist/dump/service.js.map +1 -1
  47. package/dist/dump/types.d.ts +13 -0
  48. package/dist/dump/types.d.ts.map +1 -1
  49. package/dist/dump/types.js.map +1 -1
  50. package/dist/flow/built-in/default-factory.d.ts +21 -0
  51. package/dist/flow/built-in/default-factory.d.ts.map +1 -0
  52. package/dist/flow/built-in/default-factory.js +155 -0
  53. package/dist/flow/built-in/default-factory.js.map +1 -0
  54. package/dist/flow/built-in/default.d.ts +4 -4
  55. package/dist/flow/built-in/default.d.ts.map +1 -1
  56. package/dist/flow/built-in/default.js +3 -141
  57. package/dist/flow/built-in/default.js.map +1 -1
  58. package/dist/flow/built-in/default.ts +5 -169
  59. package/dist/flow/built-in/why-so-serious-factory.d.ts +16 -0
  60. package/dist/flow/built-in/why-so-serious-factory.d.ts.map +1 -0
  61. package/dist/flow/built-in/why-so-serious-factory.js +187 -0
  62. package/dist/flow/built-in/why-so-serious-factory.js.map +1 -0
  63. package/dist/flow/built-in/why-so-serious.d.ts +3 -2
  64. package/dist/flow/built-in/why-so-serious.d.ts.map +1 -1
  65. package/dist/flow/built-in/why-so-serious.js +3 -164
  66. package/dist/flow/built-in/why-so-serious.js.map +1 -1
  67. package/dist/flow/custom/AUTHORING.md +13 -0
  68. package/dist/flow/custom/load.d.ts +16 -1
  69. package/dist/flow/custom/load.d.ts.map +1 -1
  70. package/dist/flow/custom/load.js +69 -18
  71. package/dist/flow/custom/load.js.map +1 -1
  72. package/dist/flow/dsl.js +1 -1
  73. package/dist/flow/dsl.js.map +1 -1
  74. package/dist/flow/executor.d.ts.map +1 -1
  75. package/dist/flow/executor.js +52 -9
  76. package/dist/flow/executor.js.map +1 -1
  77. package/dist/flow/types.d.ts +24 -2
  78. package/dist/flow/types.d.ts.map +1 -1
  79. package/dist/flow/types.js.map +1 -1
  80. package/dist/flow-editor/tui.d.ts.map +1 -1
  81. package/dist/flow-editor/tui.js +9 -18
  82. package/dist/flow-editor/tui.js.map +1 -1
  83. package/dist/orchestrator.d.ts +43 -0
  84. package/dist/orchestrator.d.ts.map +1 -1
  85. package/dist/orchestrator.js +230 -92
  86. package/dist/orchestrator.js.map +1 -1
  87. package/dist/providers/base-completion.d.ts +18 -0
  88. package/dist/providers/base-completion.d.ts.map +1 -1
  89. package/dist/providers/base-completion.js +29 -0
  90. package/dist/providers/base-completion.js.map +1 -1
  91. package/dist/providers/claude/completion-plan-mode.d.ts +9 -1
  92. package/dist/providers/claude/completion-plan-mode.d.ts.map +1 -1
  93. package/dist/providers/claude/completion-plan-mode.js +58 -4
  94. package/dist/providers/claude/completion-plan-mode.js.map +1 -1
  95. package/dist/providers/claude/plan-mode-pty-monitor.d.ts +51 -0
  96. package/dist/providers/claude/plan-mode-pty-monitor.d.ts.map +1 -0
  97. package/dist/providers/claude/plan-mode-pty-monitor.js +97 -0
  98. package/dist/providers/claude/plan-mode-pty-monitor.js.map +1 -0
  99. package/dist/providers/claude/strategy.d.ts.map +1 -1
  100. package/dist/providers/claude/strategy.js +6 -1
  101. package/dist/providers/claude/strategy.js.map +1 -1
  102. package/dist/providers/claude/tool-tracking.d.ts +1 -0
  103. package/dist/providers/claude/tool-tracking.d.ts.map +1 -1
  104. package/dist/providers/claude/tool-tracking.js +3 -0
  105. package/dist/providers/claude/tool-tracking.js.map +1 -1
  106. package/dist/providers/codex/plan-mode-activator.d.ts +23 -0
  107. package/dist/providers/codex/plan-mode-activator.d.ts.map +1 -0
  108. package/dist/providers/codex/plan-mode-activator.js +207 -0
  109. package/dist/providers/codex/plan-mode-activator.js.map +1 -0
  110. package/dist/providers/codex/session.d.ts +1 -0
  111. package/dist/providers/codex/session.d.ts.map +1 -1
  112. package/dist/providers/codex/session.js +35 -18
  113. package/dist/providers/codex/session.js.map +1 -1
  114. package/dist/providers/codex/strategy.d.ts +2 -1
  115. package/dist/providers/codex/strategy.d.ts.map +1 -1
  116. package/dist/providers/codex/strategy.js +17 -13
  117. package/dist/providers/codex/strategy.js.map +1 -1
  118. package/dist/providers/copilot/session.d.ts.map +1 -1
  119. package/dist/providers/copilot/session.js +11 -20
  120. package/dist/providers/copilot/session.js.map +1 -1
  121. package/dist/providers/types.d.ts +76 -0
  122. package/dist/providers/types.d.ts.map +1 -1
  123. package/dist/providers/types.js.map +1 -1
  124. package/dist/pty/spawn.d.ts.map +1 -1
  125. package/dist/pty/spawn.js +6 -1
  126. package/dist/pty/spawn.js.map +1 -1
  127. package/dist/pty/types.d.ts +7 -2
  128. package/dist/pty/types.d.ts.map +1 -1
  129. package/dist/resume-tui.d.ts +52 -0
  130. package/dist/resume-tui.d.ts.map +1 -0
  131. package/dist/resume-tui.js +344 -0
  132. package/dist/resume-tui.js.map +1 -0
  133. package/dist/session/flow-snapshot.d.ts +14 -0
  134. package/dist/session/flow-snapshot.d.ts.map +1 -0
  135. package/dist/session/flow-snapshot.js +28 -0
  136. package/dist/session/flow-snapshot.js.map +1 -0
  137. package/dist/session/list.d.ts +16 -0
  138. package/dist/session/list.d.ts.map +1 -0
  139. package/dist/session/list.js +89 -0
  140. package/dist/session/list.js.map +1 -0
  141. package/dist/session/locator.d.ts +15 -0
  142. package/dist/session/locator.d.ts.map +1 -1
  143. package/dist/session/locator.js +46 -27
  144. package/dist/session/locator.js.map +1 -1
  145. package/dist/session/lock.d.ts +26 -0
  146. package/dist/session/lock.d.ts.map +1 -0
  147. package/dist/session/lock.js +95 -0
  148. package/dist/session/lock.js.map +1 -0
  149. package/dist/session/manifest.d.ts +80 -0
  150. package/dist/session/manifest.d.ts.map +1 -0
  151. package/dist/session/manifest.js +2 -0
  152. package/dist/session/manifest.js.map +1 -0
  153. package/dist/session/persistence.d.ts +19 -0
  154. package/dist/session/persistence.d.ts.map +1 -0
  155. package/dist/session/persistence.js +68 -0
  156. package/dist/session/persistence.js.map +1 -0
  157. package/dist/session/process-start-time.d.ts +17 -0
  158. package/dist/session/process-start-time.d.ts.map +1 -0
  159. package/dist/session/process-start-time.js +99 -0
  160. package/dist/session/process-start-time.js.map +1 -0
  161. package/dist/session/restore.d.ts +31 -0
  162. package/dist/session/restore.d.ts.map +1 -0
  163. package/dist/session/restore.js +111 -0
  164. package/dist/session/restore.js.map +1 -0
  165. package/dist/session/resume.d.ts +5 -0
  166. package/dist/session/resume.d.ts.map +1 -0
  167. package/dist/session/resume.js +109 -0
  168. package/dist/session/resume.js.map +1 -0
  169. package/dist/session/session-store.d.ts +43 -0
  170. package/dist/session/session-store.d.ts.map +1 -0
  171. package/dist/session/session-store.js +134 -0
  172. package/dist/session/session-store.js.map +1 -0
  173. package/dist/startup-tui.d.ts +10 -11
  174. package/dist/startup-tui.d.ts.map +1 -1
  175. package/dist/startup-tui.js +25 -108
  176. package/dist/startup-tui.js.map +1 -1
  177. package/dist/status-bar.js +1 -26
  178. package/dist/status-bar.js.map +1 -1
  179. package/dist/terminal/host.d.ts +22 -9
  180. package/dist/terminal/host.d.ts.map +1 -1
  181. package/dist/terminal/host.js +67 -78
  182. package/dist/terminal/host.js.map +1 -1
  183. package/dist/terminal/input-router.d.ts +24 -103
  184. package/dist/terminal/input-router.d.ts.map +1 -1
  185. package/dist/terminal/input-router.js +63 -364
  186. package/dist/terminal/input-router.js.map +1 -1
  187. package/dist/terminal/key-event-source.d.ts +52 -0
  188. package/dist/terminal/key-event-source.d.ts.map +1 -0
  189. package/dist/terminal/key-event-source.js +31 -0
  190. package/dist/terminal/key-event-source.js.map +1 -0
  191. package/dist/terminal/key-to-bytes.d.ts +11 -0
  192. package/dist/terminal/key-to-bytes.d.ts.map +1 -0
  193. package/dist/terminal/key-to-bytes.js +81 -0
  194. package/dist/terminal/key-to-bytes.js.map +1 -0
  195. package/dist/terminal/koffi-loader.d.ts +14 -0
  196. package/dist/terminal/koffi-loader.d.ts.map +1 -1
  197. package/dist/terminal/koffi-loader.js.map +1 -1
  198. package/dist/terminal/render.d.ts +1 -2
  199. package/dist/terminal/render.d.ts.map +1 -1
  200. package/dist/terminal/render.js +1 -30
  201. package/dist/terminal/render.js.map +1 -1
  202. package/dist/terminal/stdin-byte-source.d.ts +27 -0
  203. package/dist/terminal/stdin-byte-source.d.ts.map +1 -0
  204. package/dist/terminal/stdin-byte-source.js +92 -0
  205. package/dist/terminal/stdin-byte-source.js.map +1 -0
  206. package/dist/terminal/win32-console-mode.d.ts.map +1 -1
  207. package/dist/terminal/win32-console-mode.js.map +1 -1
  208. package/dist/terminal/win32-console-source.d.ts +26 -0
  209. package/dist/terminal/win32-console-source.d.ts.map +1 -0
  210. package/dist/terminal/win32-console-source.js +275 -0
  211. package/dist/terminal/win32-console-source.js.map +1 -0
  212. package/dist/terminal/win32-key-translator.d.ts +26 -0
  213. package/dist/terminal/win32-key-translator.d.ts.map +1 -0
  214. package/dist/terminal/win32-key-translator.js +87 -0
  215. package/dist/terminal/win32-key-translator.js.map +1 -0
  216. package/dist/terminal-input.d.ts +10 -0
  217. package/dist/terminal-input.d.ts.map +1 -1
  218. package/dist/terminal-input.js +132 -113
  219. package/dist/terminal-input.js.map +1 -1
  220. package/dist/user/host-curate-prompt.d.ts +2 -1
  221. package/dist/user/host-curate-prompt.d.ts.map +1 -1
  222. package/dist/user/host-curate-prompt.js +13 -11
  223. package/dist/user/host-curate-prompt.js.map +1 -1
  224. package/dist/user/host-prompt.d.ts +4 -1
  225. package/dist/user/host-prompt.d.ts.map +1 -1
  226. package/dist/user/host-prompt.js +24 -6
  227. package/dist/user/host-prompt.js.map +1 -1
  228. package/dist/user/prompt.d.ts +7 -9
  229. package/dist/user/prompt.d.ts.map +1 -1
  230. package/dist/user/prompt.js +14 -23
  231. package/dist/user/prompt.js.map +1 -1
  232. package/package.json +1 -1
@@ -1,67 +1,30 @@
1
- import { DumpHotkeyDetector } from "../dump/hotkey.js";
1
+ import { isDumpHotkey } from "../dump/hotkey.js";
2
+ import { encodeKeysToBytes } from "./key-to-bytes.js";
2
3
  /**
3
4
  * Number of lines to scroll for a single mouse-wheel event. Small enough
4
5
  * to feel precise while still moving meaningfully on every notch.
5
6
  */
6
7
  export const WHEEL_LINES_PER_EVENT = 3;
7
- const ETX = 0x03; // Ctrl+C
8
- const ESC = 0x1b;
9
- const LBRACKET = 0x5b; // '['
10
- const LT = 0x3c; // '<'
11
- const TILDE = 0x7e; // '~'
12
- /** Maximum dwell for a buffered partial SGR mouse sequence before we drop it. */
13
- const SGR_MOUSE_PARTIAL_TIMEOUT_MS = 50;
14
8
  /**
15
- * Centralizes stdin ownership while the orchestration host is active.
9
+ * Event-based input router. Operates on `TerminalKey[]` produced by a
10
+ * `KeyEventSource`; the byte-level state machine is internal to
11
+ * `StdinByteSource`'s parser.
16
12
  *
17
- * Routing order on each chunk:
18
- *
19
- * 1. Dump hotkey detector (Ctrl+]) — strips dump bytes from forward.
20
- * The detector also reassembles split CSI sequences for kitty /
21
- * win32 dump variants, so when configured, downstream stages see
22
- * whole sequences for those paths.
13
+ * Routing order on each event batch:
14
+ * 1. Dump hotkey check (Ctrl+]) — strips matching events before they
15
+ * reach the parent UI or child.
23
16
  * 2. Active parent UI mode (if attached) — fully consumes by default.
24
- * Parent UI receives Ctrl+C, mouse, and nav keys first and may
25
- * handle them. Only when there is no parent UI, or it returns
26
- * `false`, does routing fall through to the host's own handlers.
27
- * 3. SGR mouse-wheel parsing — consumes `CSI < 64/65 ; … M` for
28
- * vertical wheel events and dispatches scroll callbacks. Non-wheel
29
- * SGR mouse events flow through unchanged. A small first-class
30
- * buffer reassembles SGR mouse sequences split across chunks so
31
- * the routing works regardless of whether the dump detector is
32
- * configured.
33
- * 4. Host shortcut routing on remaining bytes:
34
- * - Ctrl+C (0x03) → `onInterrupt()`
35
- * - PageUp (CSI 5~) → `onScrollPages(-1)`
36
- * - PageDown (CSI 6~) → `onScrollPages(+1)`
37
- * - Home (CSI 1~/H) → `onScrollToTop()`
38
- * - End (CSI 4~/F) → `onScrollToBottom()`
39
- * 5. Attached child PTY when `gateOpen` is true — `handle.write(forward)`.
40
- * 6. Otherwise the chunk is dropped.
17
+ * 3. Wheel events scrollback callbacks (consumed; never reach child).
18
+ * 4. Host shortcuts: Ctrl+C onInterrupt; page/home/end scrollback.
19
+ * 5. Remaining events child PTY when `gateOpen` is true, encoded via
20
+ * `encodeKeysToBytes`. Otherwise dropped.
41
21
  */
42
22
  export class InputRouter {
43
23
  options;
44
24
  parentUiMode;
45
25
  childHandle;
46
- dumpDetector;
47
- /** Buffered head of a split SGR mouse sequence (`ESC [ < … `). */
48
- sgrPartial = [];
49
- sgrPartialTimer;
50
26
  constructor(options = {}) {
51
27
  this.options = options;
52
- if (this.options.onDump) {
53
- const onDump = this.options.onDump;
54
- this.dumpDetector = new DumpHotkeyDetector(() => onDump(), (deferred) => {
55
- // Deferred flush — fires when DumpHotkeyDetector buffered an
56
- // ESC (or partial CSI) and the timeout expired without a final
57
- // byte arriving. Re-enter the routing pipeline so a bare ESC
58
- // reaches an active parent UI mode (HostBackedCuratePrompt
59
- // uses Esc to cancel comment editing). Only when there is no
60
- // parent UI and the child gate is open does the bytes reach
61
- // the child.
62
- this.routeDeferred(deferred);
63
- });
64
- }
65
28
  }
66
29
  attachChild(handle) {
67
30
  this.childHandle = handle;
@@ -79,346 +42,82 @@ export class InputRouter {
79
42
  return;
80
43
  this.parentUiMode = undefined;
81
44
  }
82
- /** Process a stdin chunk. Returns true when at least one byte was consumed. */
83
- handleChunk(chunk) {
84
- // Global parent shortcuts run FIRST so Ctrl+] reliably triggers a
85
- // dump regardless of which UI mode currently owns input. The detector
86
- // strips the hotkey bytes from the forward buffer; everything else
87
- // continues down the routing pipeline.
88
- let forward = chunk;
89
- if (this.dumpDetector) {
90
- forward = this.dumpDetector.process(chunk);
91
- }
92
- if (forward.length === 0)
93
- return true;
94
- // Parent UI gets first crack at every byte that isn't the dump
95
- // hotkey — including mouse events and nav keys. A host-backed
96
- // prompt that wants to own wheel input simply consumes the chunk.
97
- if (this.parentUiMode) {
98
- const consumed = this.parentUiMode.onInput(forward);
99
- // Default behaviour: parent UI swallows everything until detached.
100
- if (consumed !== false) {
101
- // The parent UI took ownership. Any partial SGR mouse sequence
102
- // we previously buffered no longer applies — clear the buffer.
103
- this.resetSgrPartial();
104
- return true;
45
+ /** Process a batch of `TerminalKey` events. */
46
+ handleEvents(events) {
47
+ if (events.length === 0)
48
+ return;
49
+ // Pre-filter: dump hotkey runs ahead of everything and is stripped.
50
+ const filtered = [];
51
+ for (const ev of events) {
52
+ if (isDumpHotkey(ev)) {
53
+ this.options.onDump?.();
54
+ continue;
105
55
  }
56
+ filtered.push(ev);
106
57
  }
107
- // Host owns the bytes. SGR mouse-wheel parsing comes BEFORE host
108
- // shortcuts so wheel events don't accidentally match nav keys.
109
- forward = this.consumeSgrMouseWheel(forward);
110
- if (forward.length === 0)
111
- return true;
112
- const afterShortcuts = this.consumeHostShortcuts(forward);
113
- if (afterShortcuts.length === 0)
114
- return true;
115
- return this.forwardToChild(afterShortcuts);
116
- }
117
- forwardToChild(buf) {
118
- const child = this.childHandle;
119
- if (!child || !child.gateOpen)
120
- return false;
121
- child.write(buf.toString());
122
- return true;
123
- }
124
- /**
125
- * Strip SGR mouse wheel events (`CSI < 64;…M` and `CSI < 65;…M`) from
126
- * the chunk, dispatching scrollback callbacks. Non-wheel SGR mouse
127
- * events (clicks, motion, releases) and other CSI sequences (Home,
128
- * PageUp, etc.) are left in the chunk so callers can still forward
129
- * them or run them through host shortcut routing.
130
- *
131
- * Sequences split across chunk boundaries are first-class. The buffer
132
- * holds any incomplete CSI prefix — bare ESC, ESC `[`, ESC `[ < …` —
133
- * and prepends it to the next chunk. This works even when the dump
134
- * detector is not configured (the detector reassembles split CSI for
135
- * its own purposes when it is configured, but mouse-wheel scrollback
136
- * MUST NOT depend on it). A 50 ms safety timer flushes a stale
137
- * partial through `consumeHostShortcuts` and the child gate so a
138
- * bare Esc keypress eventually reaches the child even when there is
139
- * no continuation, and so a stray ESC byte cannot permanently block
140
- * future input.
141
- */
142
- consumeSgrMouseWheel(buf) {
143
- // Prepend any buffered partial to this chunk before parsing.
144
- if (this.sgrPartial.length > 0) {
145
- const merged = Buffer.allocUnsafe(this.sgrPartial.length + buf.length);
146
- for (let k = 0; k < this.sgrPartial.length; k++)
147
- merged[k] = this.sgrPartial[k];
148
- buf.copy(merged, this.sgrPartial.length);
149
- buf = merged;
150
- this.resetSgrPartialTimer();
151
- this.sgrPartial = [];
58
+ if (filtered.length === 0)
59
+ return;
60
+ // Parent UI gets the remainder first.
61
+ if (this.parentUiMode) {
62
+ const consumed = this.parentUiMode.onEvents(filtered);
63
+ if (consumed !== false)
64
+ return;
152
65
  }
153
- if (buf.length === 0)
154
- return buf;
155
- const out = [];
156
- let i = 0;
157
- while (i < buf.length) {
158
- const b = buf[i];
159
- if (b !== ESC) {
160
- out.push(b);
161
- i++;
162
- continue;
163
- }
164
- // ESC byte. The chunk ends here, after `[`, or after `[ < …`
165
- // — buffer the partial in every case so a split mouse sequence
166
- // never leaks to the child as half-bytes.
167
- if (i + 1 >= buf.length) {
168
- // Bare ESC at end-of-chunk. Could be (a) the Esc key, (b) the
169
- // start of an Alt+key combo, or (c) the start of any CSI
170
- // including SGR mouse. Buffering all three for 50 ms costs a
171
- // small delay on the Esc key (matching the dump detector's
172
- // own delay) but is the price of not forwarding partial mouse
173
- // sequences to the child.
174
- this.savePartialSgr(buf.subarray(i));
175
- return Buffer.from(out);
176
- }
177
- if (buf[i + 1] !== LBRACKET) {
178
- // ESC + non-`[` — Alt+key or another ESC-prefixed combo. Emit
179
- // both bytes immediately so Alt+key combos are not delayed.
180
- out.push(b);
181
- i++;
182
- continue;
183
- }
184
- // We have ESC `[`. Find the CSI final byte in the range 0x40-0x7e.
185
- let j = i + 2;
186
- while (j < buf.length) {
187
- const t = buf[j];
188
- if (t >= 0x40 && t <= 0x7e)
189
- break;
190
- j++;
191
- }
192
- if (j >= buf.length) {
193
- // Unterminated CSI — buffer the partial for the next chunk to
194
- // complete. This covers all reviewer-flagged splits: ESC alone,
195
- // `ESC [`, `ESC [ <`, `ESC [ < 64 ;`, etc.
196
- this.savePartialSgr(buf.subarray(i));
197
- return Buffer.from(out);
198
- }
199
- const params = buf.subarray(i + 2, j).toString("ascii");
200
- const final = buf[j];
201
- // SGR mouse-wheel sequence: ESC `[ < cb ; cx ; cy M` where
202
- // cb=64 (wheel up) or cb=65 (wheel down). Anything else (clicks,
203
- // releases, non-mouse CSI) is passed through unchanged.
204
- if (params.startsWith("<") && final === 0x4d /* M */) {
205
- const cb = parseInt(params.slice(1).split(";")[0] ?? "", 10);
206
- if (cb === 64) {
66
+ // Host owns the batch — pull wheel events into scrollback, ETX into
67
+ // interrupt, page/home/end into scroll callbacks; forward whatever
68
+ // remains to the child via the encoder.
69
+ const forward = [];
70
+ for (const ev of filtered) {
71
+ if (ev.kind === "wheel") {
72
+ if (ev.direction === "up") {
207
73
  this.options.onScrollBackLines?.(WHEEL_LINES_PER_EVENT);
208
- i = j + 1;
209
- continue;
210
74
  }
211
- if (cb === 65) {
75
+ else {
212
76
  this.options.onScrollForwardLines?.(WHEEL_LINES_PER_EVENT);
213
- i = j + 1;
214
- continue;
215
77
  }
78
+ continue;
216
79
  }
217
- // Not a mouse wheel emit the entire CSI sequence intact.
218
- for (let k = i; k <= j; k++)
219
- out.push(buf[k]);
220
- i = j + 1;
221
- }
222
- return Buffer.from(out);
223
- }
224
- savePartialSgr(partial) {
225
- this.sgrPartial = Array.from(partial);
226
- if (this.sgrPartialTimer)
227
- clearTimeout(this.sgrPartialTimer);
228
- this.sgrPartialTimer = setTimeout(() => this.flushPartialSgr(), SGR_MOUSE_PARTIAL_TIMEOUT_MS);
229
- }
230
- /**
231
- * Stale-partial flush. Two distinct cases:
232
- *
233
- * - Bare `ESC` (1 byte): flush through host shortcuts and the child
234
- * gate. The user pressed Esc and there is no continuation; the
235
- * child must still receive the byte after the safety window
236
- * (matching the dump detector's bare-Esc deferred-flush).
237
- *
238
- * - Truncated CSI (`ESC [ …`, 2+ bytes): drop. The user pressed
239
- * Home/PageUp/wheel/etc. and the terminal failed to deliver the
240
- * rest within the window. Forwarding raw `ESC [ < 6 4 ;` would
241
- * inject random bytes into the child agent — much worse than
242
- * losing one stray nav event.
243
- */
244
- flushPartialSgr() {
245
- if (this.sgrPartial.length === 0) {
246
- this.sgrPartialTimer = undefined;
247
- return;
248
- }
249
- const buf = Buffer.from(this.sgrPartial);
250
- this.sgrPartial = [];
251
- this.sgrPartialTimer = undefined;
252
- if (buf.length === 1 && buf[0] === ESC) {
253
- const afterShortcuts = this.consumeHostShortcuts(buf);
254
- if (afterShortcuts.length > 0)
255
- this.forwardToChild(afterShortcuts);
256
- }
257
- // Else: drop the truncated CSI prefix.
258
- }
259
- resetSgrPartialTimer() {
260
- if (this.sgrPartialTimer) {
261
- clearTimeout(this.sgrPartialTimer);
262
- this.sgrPartialTimer = undefined;
263
- }
264
- }
265
- resetSgrPartial() {
266
- this.resetSgrPartialTimer();
267
- if (this.sgrPartial.length > 0) {
268
- this.sgrPartial = [];
269
- }
270
- }
271
- /**
272
- * Consume host scrollback / interrupt shortcuts from the chunk. Returns
273
- * the chunk with any consumed bytes removed.
274
- *
275
- * Recognized sequences (single-chunk only — split CSI across two
276
- * chunks falls through to the child unchanged, which is acceptable
277
- * because real terminals deliver these in one chunk):
278
- *
279
- * - 0x03 Ctrl+C → onInterrupt()
280
- * - ESC [ 5 ~ PageUp → onScrollPages(-1)
281
- * - ESC [ 6 ~ PageDown → onScrollPages(+1)
282
- * - ESC [ 1 ~ / ESC [ H Home → onScrollToTop()
283
- * - ESC [ 4 ~ / ESC [ F End → onScrollToBottom()
284
- *
285
- * Modifier-prefixed variants (e.g. `ESC [ 1;5 H` for Ctrl+Home) match
286
- * the same callback as their unmodified form.
287
- */
288
- consumeHostShortcuts(buf) {
289
- if (buf.length === 0)
290
- return buf;
291
- const out = [];
292
- let i = 0;
293
- while (i < buf.length) {
294
- const b = buf[i];
295
- if (b === ETX) {
80
+ if (ev.kind === "control" && ev.byte === 0x03) {
296
81
  if (this.options.onInterrupt) {
297
82
  this.options.onInterrupt();
298
- i++;
299
83
  continue;
300
84
  }
301
- // No interrupt handler — fall through to child.
302
- out.push(b);
303
- i++;
304
- continue;
305
85
  }
306
- if (b === ESC && i + 1 < buf.length && buf[i + 1] === LBRACKET) {
307
- // Find the CSI final byte.
308
- let j = i + 2;
309
- while (j < buf.length) {
310
- const t = buf[j];
311
- if (t >= 0x40 && t <= 0x7e)
312
- break;
313
- j++;
314
- }
315
- if (j >= buf.length) {
316
- // Unterminated — emit remainder unchanged.
317
- for (let k = i; k < buf.length; k++)
318
- out.push(buf[k]);
319
- return Buffer.from(out);
320
- }
321
- const params = buf.subarray(i + 2, j).toString("ascii");
322
- const final = buf[j];
323
- const handled = this.dispatchCsi(params, final);
324
- if (handled) {
325
- i = j + 1;
326
- continue;
327
- }
328
- // Not a host shortcut — pass through unchanged.
329
- for (let k = i; k <= j; k++)
330
- out.push(buf[k]);
331
- i = j + 1;
332
- continue;
333
- }
334
- out.push(b);
335
- i++;
336
- }
337
- return Buffer.from(out);
338
- }
339
- dispatchCsi(params, final) {
340
- // PageUp = ESC [ 5 ~ ; PageDown = ESC [ 6 ~ ; Home = ESC [ 1 ~ or H ;
341
- // End = ESC [ 4 ~ or F. Modifier params (e.g. "1;5") are accepted so
342
- // Ctrl/Shift+nav routes through the same scroll callback.
343
- if (final === TILDE) {
344
- const code = parseInt(params.split(";")[0] ?? "", 10);
345
- if (code === 5) {
346
- if (this.options.onScrollPages) {
347
- this.options.onScrollPages(-1);
348
- return true;
349
- }
350
- return false;
351
- }
352
- if (code === 6) {
86
+ if (ev.kind === "page") {
353
87
  if (this.options.onScrollPages) {
354
- this.options.onScrollPages(1);
355
- return true;
356
- }
357
- return false;
358
- }
359
- if (code === 1 || code === 7) {
360
- if (this.options.onScrollToTop) {
361
- this.options.onScrollToTop();
362
- return true;
363
- }
364
- return false;
365
- }
366
- if (code === 4 || code === 8) {
367
- if (this.options.onScrollToBottom) {
368
- this.options.onScrollToBottom();
369
- return true;
88
+ this.options.onScrollPages(ev.direction === "up" ? -1 : 1);
89
+ continue;
370
90
  }
371
- return false;
372
91
  }
373
- return false;
374
- }
375
- if (final === 0x48 /* H */) {
376
- if (this.options.onScrollToTop) {
92
+ if (ev.kind === "home" && this.options.onScrollToTop) {
377
93
  this.options.onScrollToTop();
378
- return true;
94
+ continue;
379
95
  }
380
- return false;
381
- }
382
- if (final === 0x46 /* F */) {
383
- if (this.options.onScrollToBottom) {
96
+ if (ev.kind === "end" && this.options.onScrollToBottom) {
384
97
  this.options.onScrollToBottom();
385
- return true;
98
+ continue;
386
99
  }
387
- return false;
100
+ forward.push(ev);
388
101
  }
389
- return false;
102
+ if (forward.length === 0)
103
+ return;
104
+ this.forwardToChild(forward);
390
105
  }
391
- /**
392
- * Route a deferred buffer (produced by `DumpHotkeyDetector` when a
393
- * pending escape sequence times out). The deferred bytes have already
394
- * been screened for the dump hotkey — they must NOT pass through the
395
- * detector again. They DO continue through the parent UI mode, the
396
- * SGR mouse parser, host shortcuts, and the child gate so a bare Esc
397
- * reaches host-backed prompts and a deferred mouse sequence is still
398
- * correctly classified.
399
- */
400
- routeDeferred(buf) {
106
+ forwardToChild(events) {
107
+ const child = this.childHandle;
108
+ if (!child || !child.gateOpen)
109
+ return;
110
+ const buf = encodeKeysToBytes(events);
401
111
  if (buf.length === 0)
402
- return false;
403
- if (this.parentUiMode) {
404
- const consumed = this.parentUiMode.onInput(buf);
405
- if (consumed !== false) {
406
- this.resetSgrPartial();
407
- return true;
408
- }
409
- }
410
- const afterMouse = this.consumeSgrMouseWheel(buf);
411
- if (afterMouse.length === 0)
412
- return true;
413
- const afterShortcuts = this.consumeHostShortcuts(afterMouse);
414
- if (afterShortcuts.length === 0)
415
- return true;
416
- return this.forwardToChild(afterShortcuts);
112
+ return;
113
+ // Forward the encoded Buffer verbatim — the PtyHandle adapter is
114
+ // responsible for handing it to node-pty without lossy decoding.
115
+ // Going through a latin1 string here would corrupt multibyte UTF-8
116
+ // printable chars (e.g. "中" → "中") because node-pty re-encodes
117
+ // the inbound string as UTF-8.
118
+ child.write(buf);
417
119
  }
418
120
  destroy() {
419
- this.dumpDetector?.destroy();
420
- this.dumpDetector = undefined;
421
- this.resetSgrPartial();
422
121
  this.childHandle = undefined;
423
122
  this.parentUiMode = undefined;
424
123
  }
@@ -1 +1 @@
1
- {"version":3,"file":"input-router.js","sourceRoot":"","sources":["../../src/terminal/input-router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"input-router.js","sourceRoot":"","sources":["../../src/terminal/input-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { TerminalKey } from "../terminal-input.js";
2
+ export interface KeyEventSourceOptions {
3
+ /** Override stdin. Default: `process.stdin`. */
4
+ stdin?: NodeJS.ReadStream;
5
+ }
6
+ /** Post-resize terminal size carried by a `KeyEventSource.onResize` callback. */
7
+ export interface ResizeSize {
8
+ columns: number;
9
+ rows: number;
10
+ }
11
+ /**
12
+ * Structured-event source for keyboard input. Replaces the per-consumer
13
+ * `process.stdin.on("data", …)` + `TerminalKeyParser` wiring with a
14
+ * single subscription surface.
15
+ *
16
+ * - Multiple subscribers may attach via `onEvents`; each event burst
17
+ * fans out to all of them.
18
+ * - `start()` / `stop()` are idempotent; the source owns raw-mode and
19
+ * VT-input setup on its injected stdin.
20
+ * - Deferred bare-Esc events surface through the same subscriber
21
+ * callback as regular events.
22
+ */
23
+ export interface KeyEventSource {
24
+ start(): void;
25
+ stop(): void;
26
+ /** Returns an idempotent unsubscribe function. */
27
+ onEvents(cb: (events: TerminalKey[]) => void): () => void;
28
+ /**
29
+ * Fires on a terminal/buffer resize, carrying the post-resize size when
30
+ * the source can determine it. On the Win32 FFI path this is the
31
+ * authoritative dimensions decoded from `WINDOW_BUFFER_SIZE_RECORD` —
32
+ * `stdout.columns`/`rows` are stale at that point because libuv never
33
+ * saw the record. Returns an idempotent unsubscribe.
34
+ */
35
+ onResize(cb: (size: ResizeSize) => void): () => void;
36
+ }
37
+ /**
38
+ * Build a `KeyEventSource` for the given (or default) stdin.
39
+ *
40
+ * On Windows, when koffi loads AND the caller did not inject a custom
41
+ * stdin, returns a `Win32ConsoleSource` that reads `CONIN$` directly via
42
+ * FFI — bypassing ConPTY's lossy byte translation. Otherwise (including
43
+ * koffi-load failure on Windows), returns a `StdinByteSource` that wraps
44
+ * `TerminalKeyParser` over the injected stdin for byte-identical
45
+ * behavior.
46
+ *
47
+ * The `stdin === process.stdin` gate guarantees that test mocks and
48
+ * embedded hosts with a custom stream always fall through to
49
+ * `StdinByteSource`.
50
+ */
51
+ export declare function createKeyEventSource(opts?: KeyEventSourceOptions): KeyEventSource;
52
+ //# sourceMappingURL=key-event-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-event-source.d.ts","sourceRoot":"","sources":["../../src/terminal/key-event-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIxD,MAAM,WAAW,qBAAqB;IACpC,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAC3B;AAED,iFAAiF;AACjF,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,kDAAkD;IAClD,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC1D;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACtD;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,GAAE,qBAA0B,GAC/B,cAAc,CAahB"}
@@ -0,0 +1,31 @@
1
+ import { StdinByteSource } from "./stdin-byte-source.js";
2
+ import { Win32ConsoleSource } from "./win32-console-source.js";
3
+ let warnedOnFallback = false;
4
+ /**
5
+ * Build a `KeyEventSource` for the given (or default) stdin.
6
+ *
7
+ * On Windows, when koffi loads AND the caller did not inject a custom
8
+ * stdin, returns a `Win32ConsoleSource` that reads `CONIN$` directly via
9
+ * FFI — bypassing ConPTY's lossy byte translation. Otherwise (including
10
+ * koffi-load failure on Windows), returns a `StdinByteSource` that wraps
11
+ * `TerminalKeyParser` over the injected stdin for byte-identical
12
+ * behavior.
13
+ *
14
+ * The `stdin === process.stdin` gate guarantees that test mocks and
15
+ * embedded hosts with a custom stream always fall through to
16
+ * `StdinByteSource`.
17
+ */
18
+ export function createKeyEventSource(opts = {}) {
19
+ const stdin = opts.stdin ?? process.stdin;
20
+ if (process.platform === "win32" && stdin === process.stdin) {
21
+ const native = Win32ConsoleSource.tryCreate();
22
+ if (native)
23
+ return native;
24
+ if (!warnedOnFallback) {
25
+ warnedOnFallback = true;
26
+ process.stderr.write("[poly-weaver] koffi unavailable; using stdin input path\n");
27
+ }
28
+ }
29
+ return new StdinByteSource(stdin);
30
+ }
31
+ //# sourceMappingURL=key-event-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-event-source.js","sourceRoot":"","sources":["../../src/terminal/key-event-source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAwC/D,IAAI,gBAAgB,GAAG,KAAK,CAAC;AAE7B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAA8B,EAAE;IAEhC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC;IAC1C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,EAAE,CAAC;QAC9C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,gBAAgB,GAAG,IAAI,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2DAA2D,CAC5D,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { TerminalKey } from "../terminal-input.js";
2
+ /**
3
+ * Encode `TerminalKey[]` back to VT bytes for child PTY forwarding.
4
+ *
5
+ * `raw` events carry pre-framed CSI / SS3 bytes and are written verbatim.
6
+ * Unmodified Tab/Esc/Enter/Backspace encode to a single ASCII byte so the
7
+ * child agent sees the same byte stream it would have received without
8
+ * the event-based migration.
9
+ */
10
+ export declare function encodeKeysToBytes(events: TerminalKey[]): Buffer;
11
+ //# sourceMappingURL=key-to-bytes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-to-bytes.d.ts","sourceRoot":"","sources":["../../src/terminal/key-to-bytes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAiBxD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAS/D"}