zcode-acp-server 0.14.3 → 0.17.2
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 +109 -9
- package/README.zh-CN.md +91 -9
- package/dist/backend/index.d.ts +1 -0
- package/dist/backend/index.d.ts.map +1 -1
- package/dist/backend/index.js +1 -0
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/sandbox.d.ts +92 -23
- package/dist/backend/sandbox.d.ts.map +1 -1
- package/dist/backend/sandbox.js +265 -70
- package/dist/backend/sandbox.js.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/config/auto-compact.d.ts.map +1 -1
- package/dist/config/auto-compact.js +6 -4
- package/dist/config/auto-compact.js.map +1 -1
- package/dist/config/mcp-discovery.d.ts.map +1 -1
- package/dist/config/mcp-discovery.js +7 -5
- package/dist/config/mcp-discovery.js.map +1 -1
- package/dist/handlers/background-tasks.d.ts.map +1 -1
- package/dist/handlers/background-tasks.js +2 -2
- package/dist/handlers/background-tasks.js.map +1 -1
- package/dist/handlers/dispatch.d.ts.map +1 -1
- package/dist/handlers/dispatch.js +4 -4
- package/dist/handlers/dispatch.js.map +1 -1
- package/dist/handlers/replay.d.ts.map +1 -1
- package/dist/handlers/replay.js +11 -5
- package/dist/handlers/replay.js.map +1 -1
- package/dist/handlers/sandbox-allow.d.ts +71 -0
- package/dist/handlers/sandbox-allow.d.ts.map +1 -0
- package/dist/handlers/sandbox-allow.js +299 -0
- package/dist/handlers/sandbox-allow.js.map +1 -0
- package/dist/handlers/server-requests.d.ts.map +1 -1
- package/dist/handlers/server-requests.js +7 -5
- package/dist/handlers/server-requests.js.map +1 -1
- package/dist/handlers/session.d.ts +24 -1
- package/dist/handlers/session.d.ts.map +1 -1
- package/dist/handlers/session.js +231 -24
- package/dist/handlers/session.js.map +1 -1
- package/dist/handlers/slash.d.ts.map +1 -1
- package/dist/handlers/slash.js +15 -13
- package/dist/handlers/slash.js.map +1 -1
- package/dist/i18n.d.ts +113 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +224 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +114 -15
- package/dist/index.js.map +1 -1
- package/dist/interaction/adapter.d.ts.map +1 -1
- package/dist/interaction/adapter.js +10 -7
- package/dist/interaction/adapter.js.map +1 -1
- package/dist/remote/config.d.ts +7 -0
- package/dist/remote/config.d.ts.map +1 -1
- package/dist/remote/config.js +2 -0
- package/dist/remote/config.js.map +1 -1
- package/dist/remote/endpoint.d.ts.map +1 -1
- package/dist/remote/endpoint.js +66 -11
- package/dist/remote/endpoint.js.map +1 -1
- package/dist/remote/hub-server.d.ts +15 -0
- package/dist/remote/hub-server.d.ts.map +1 -1
- package/dist/remote/hub-server.js +205 -1
- package/dist/remote/hub-server.js.map +1 -1
- package/dist/repl/App.d.ts.map +1 -1
- package/dist/repl/App.js +22 -5
- package/dist/repl/App.js.map +1 -1
- package/dist/repl/model.d.ts +21 -0
- package/dist/repl/model.d.ts.map +1 -1
- package/dist/repl/model.js +34 -1
- package/dist/repl/model.js.map +1 -1
- package/dist/repl/run.d.ts.map +1 -1
- package/dist/repl/run.js +5 -0
- package/dist/repl/run.js.map +1 -1
- package/dist/server.d.ts +78 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +114 -3
- package/dist/server.js.map +1 -1
- package/dist/tasks-index.d.ts +27 -0
- package/dist/tasks-index.d.ts.map +1 -1
- package/dist/tasks-index.js +72 -3
- package/dist/tasks-index.js.map +1 -1
- package/docs/RELEASING.md +29 -0
- package/docs/REMOTE-CLIENTS.md +43 -0
- package/docs/TROUBLESHOOTING.md +9 -3
- package/package.json +13 -12
- package/dist/remote/session-liveness.d.ts +0 -19
- package/dist/remote/session-liveness.d.ts.map +0 -1
- package/dist/remote/session-liveness.js +0 -70
- package/dist/remote/session-liveness.js.map +0 -1
- package/dist/repl/mouse.d.ts +0 -49
- package/dist/repl/mouse.d.ts.map +0 -1
- package/dist/repl/mouse.js +0 -165
- package/dist/repl/mouse.js.map +0 -1
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Heartbeat-time session availability verification.
|
|
3
|
-
*
|
|
4
|
-
* A bridge can outlive a session's ownership: restarting a project window
|
|
5
|
-
* leaks the old bridge process (Zed keeps it alive), and the new bridge takes
|
|
6
|
-
* over the session via the durable alias store. The old bridge keeps
|
|
7
|
-
* advertising the session in every heartbeat while its own backend subprocess
|
|
8
|
-
* can no longer serve it — remote clients then see the same session twice,
|
|
9
|
-
* and the stale copy opens empty. Before each hub heartbeat we probe idle
|
|
10
|
-
* advertised sessions with a cheap `session/messages` RPC: an error or empty
|
|
11
|
-
* answer marks the summary unavailable (dropped from the discovery payload,
|
|
12
|
-
* and the backend-loaded stamp cleared so a later session/load re-runs the
|
|
13
|
-
* resume RPC instead of skipping it); a non-empty answer restores it.
|
|
14
|
-
* Freshly-active sessions and sessions with an in-flight turn are trusted
|
|
15
|
-
* without a probe.
|
|
16
|
-
*/
|
|
17
|
-
import type { ZcodeAcpServer } from "../server.js";
|
|
18
|
-
export declare function verifySessionAvailability(server: ZcodeAcpServer): Promise<void>;
|
|
19
|
-
//# sourceMappingURL=session-liveness.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-liveness.d.ts","sourceRoot":"","sources":["../../src/remote/session-liveness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQnD,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDrF"}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Heartbeat-time session availability verification.
|
|
3
|
-
*
|
|
4
|
-
* A bridge can outlive a session's ownership: restarting a project window
|
|
5
|
-
* leaks the old bridge process (Zed keeps it alive), and the new bridge takes
|
|
6
|
-
* over the session via the durable alias store. The old bridge keeps
|
|
7
|
-
* advertising the session in every heartbeat while its own backend subprocess
|
|
8
|
-
* can no longer serve it — remote clients then see the same session twice,
|
|
9
|
-
* and the stale copy opens empty. Before each hub heartbeat we probe idle
|
|
10
|
-
* advertised sessions with a cheap `session/messages` RPC: an error or empty
|
|
11
|
-
* answer marks the summary unavailable (dropped from the discovery payload,
|
|
12
|
-
* and the backend-loaded stamp cleared so a later session/load re-runs the
|
|
13
|
-
* resume RPC instead of skipping it); a non-empty answer restores it.
|
|
14
|
-
* Freshly-active sessions and sessions with an in-flight turn are trusted
|
|
15
|
-
* without a probe.
|
|
16
|
-
*/
|
|
17
|
-
import { log, warn } from "../utils.js";
|
|
18
|
-
/** Sessions touched within this window are trusted without a probe. */
|
|
19
|
-
const FRESH_MS = 60_000;
|
|
20
|
-
/** Per-probe cap — a hung backend must not stall the heartbeat loop. */
|
|
21
|
-
const PROBE_TIMEOUT_MS = 3000;
|
|
22
|
-
export async function verifySessionAvailability(server) {
|
|
23
|
-
const backend = server.backend;
|
|
24
|
-
if (!backend || backend.isDead)
|
|
25
|
-
return;
|
|
26
|
-
const busyZcodeSids = new Set([...server.pendingTurns.values()].map((t) => t.zcodeSid));
|
|
27
|
-
const now = Date.now();
|
|
28
|
-
for (const [acpSid, summary] of server.sessionSummaries.entries()) {
|
|
29
|
-
if (!summary.hasActivity)
|
|
30
|
-
continue;
|
|
31
|
-
// Fresh summaries are trusted; unavailable ones are re-probed so a session
|
|
32
|
-
// that becomes serveable again returns to the discovery list.
|
|
33
|
-
if (summary.unavailable !== true && now - summary.updatedAt < FRESH_MS)
|
|
34
|
-
continue;
|
|
35
|
-
const zcodeSid = server.resolveSid(acpSid);
|
|
36
|
-
if (!zcodeSid || busyZcodeSids.has(zcodeSid))
|
|
37
|
-
continue;
|
|
38
|
-
let serveable = false;
|
|
39
|
-
try {
|
|
40
|
-
const timer = new Promise((resolve) => {
|
|
41
|
-
const t = setTimeout(() => resolve(null), PROBE_TIMEOUT_MS);
|
|
42
|
-
t.unref();
|
|
43
|
-
});
|
|
44
|
-
const resp = await Promise.race([
|
|
45
|
-
backend.request(server.nextId(), "session/messages", { sessionId: zcodeSid }, PROBE_TIMEOUT_MS),
|
|
46
|
-
timer,
|
|
47
|
-
]);
|
|
48
|
-
const messages = (resp?.result ?? {}).messages ?? [];
|
|
49
|
-
serveable = resp !== null && !resp.error && messages.length > 0;
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
serveable = false;
|
|
53
|
-
}
|
|
54
|
-
if (serveable) {
|
|
55
|
-
if (summary.unavailable) {
|
|
56
|
-
summary.unavailable = false;
|
|
57
|
-
log(`remote: session ${acpSid.slice(0, 8)} serves messages again - restored to discovery`);
|
|
58
|
-
}
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (!summary.unavailable) {
|
|
62
|
-
summary.unavailable = true;
|
|
63
|
-
// The loaded-in-this-subprocess stamp went stale (another backend took
|
|
64
|
-
// the session over): a later session/load must re-run the resume RPC.
|
|
65
|
-
server.backendLoadedSessions.delete(acpSid);
|
|
66
|
-
warn(`remote: session ${acpSid.slice(0, 8)} not serveable by this backend - hidden from discovery`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=session-liveness.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-liveness.js","sourceRoot":"","sources":["../../src/remote/session-liveness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,uEAAuE;AACvE,MAAM,QAAQ,GAAG,MAAM,CAAC;AACxB,wEAAwE;AACxE,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,MAAsB;IACpE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM;QAAE,OAAO;IAEvC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,WAAW;YAAE,SAAS;QACnC,2EAA2E;QAC3E,8DAA8D;QAC9D,IAAI,OAAO,CAAC,WAAW,KAAK,IAAI,IAAI,GAAG,GAAG,OAAO,CAAC,SAAS,GAAG,QAAQ;YAAE,SAAS;QACjF,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,IAAI,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QAEvD,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAC1C,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAC;gBAC5D,CAAC,CAAC,KAAK,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAC9B,OAAO,CAAC,OAAO,CACb,MAAM,CAAC,MAAM,EAAE,EACf,kBAAkB,EAClB,EAAE,SAAS,EAAE,QAAQ,EAAE,EACvB,gBAAgB,CACjB;gBACD,KAAK;aACN,CAAC,CAAC;YACH,MAAM,QAAQ,GAAI,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAmC,CAAC,QAAQ,IAAI,EAAE,CAAC;YACxF,SAAS,GAAG,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QAClE,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC;gBAC5B,GAAG,CAAC,mBAAmB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,gDAAgD,CAAC,CAAC;YAC7F,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACzB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;YAC3B,uEAAuE;YACvE,sEAAsE;YACtE,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CACF,mBAAmB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,wDAAwD,CAC9F,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/repl/mouse.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mouse-wheel capture for the full-screen REPL (alternate-screen mode).
|
|
3
|
-
*
|
|
4
|
-
* Enabling xterm mouse reporting (?1000 press/release + ?1002 drag +
|
|
5
|
-
* ?1006 SGR encoding) re-routes the terminal's wheel from its own scrollback
|
|
6
|
-
* scroll to escape sequences delivered to us — `\x1b[<64;col;rowM` = wheel
|
|
7
|
-
* up, `\x1b[<65;…M` = wheel down. The terminal stops scrolling entirely,
|
|
8
|
-
* which is what prevents Warp from scrolling the alt-screen frame away
|
|
9
|
-
* (warp#9838); vim/tmux/htop scroll correctly inside Warp via this exact
|
|
10
|
-
* mechanism.
|
|
11
|
-
*
|
|
12
|
-
* Ink knows nothing about mouse sequences, so raw bytes must never reach it:
|
|
13
|
-
* this module owns the REAL process.stdin as its sole consumer, strips
|
|
14
|
-
* complete SGR mouse events out of the byte stream, forwards everything
|
|
15
|
-
* else into a fake stdin handed to ink via `render({stdin})`, and reports
|
|
16
|
-
* wheel notches through a callback.
|
|
17
|
-
*/
|
|
18
|
-
/** DECSET sequences arming SGR mouse reporting on the terminal. */
|
|
19
|
-
export declare const MOUSE_ENABLE = "\u001B[?1000h\u001B[?1002h\u001B[?1006h";
|
|
20
|
-
/** Matching resets — idempotent, safe to write more than once. */
|
|
21
|
-
export declare const MOUSE_DISABLE = "\u001B[?1000l\u001B[?1002l\u001B[?1006l";
|
|
22
|
-
export type WheelDirection = "up" | "down";
|
|
23
|
-
/**
|
|
24
|
-
* Incremental splitter: feed() raw stdin chunks, get back display-safe text
|
|
25
|
-
* with every mouse event removed, and receive wheel callbacks for events.
|
|
26
|
-
* Holds an incomplete trailing sequence until the rest arrives in a later
|
|
27
|
-
* chunk.
|
|
28
|
-
*/
|
|
29
|
-
export declare class MouseSequenceFilter {
|
|
30
|
-
private readonly onWheel;
|
|
31
|
-
private pending;
|
|
32
|
-
constructor(onWheel: (dir: WheelDirection) => void);
|
|
33
|
-
/** Feed one raw chunk; returns the passthrough text (may be empty). */
|
|
34
|
-
feed(chunk: string): string;
|
|
35
|
-
}
|
|
36
|
-
export interface FilteredStdin {
|
|
37
|
-
/** Ink-facing stream — pass to render({stdin}). */
|
|
38
|
-
stream: NodeJS.ReadStream;
|
|
39
|
-
/** Stop capturing and tear down listeners on the real stdin. */
|
|
40
|
-
dispose(): void;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Take over process.stdin, strip mouse events, expose the cleaned stream for
|
|
44
|
-
* ink. The fake stream forwards TTY identity and lifecycle calls (ink sets
|
|
45
|
-
* raw mode, ref/unrefs it, and consumes via 'readable'+read()); keyboard data
|
|
46
|
-
* flows through unchanged byte-for-byte.
|
|
47
|
-
*/
|
|
48
|
-
export declare function createFilteredStdin(onWheel: (dir: WheelDirection) => void): FilteredStdin;
|
|
49
|
-
//# sourceMappingURL=mouse.d.ts.map
|
package/dist/repl/mouse.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mouse.d.ts","sourceRoot":"","sources":["../../src/repl/mouse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,mEAAmE;AACnE,eAAO,MAAM,YAAY,4CAAsC,CAAC;AAEhE,kEAAkE;AAClE,eAAO,MAAM,aAAa,4CAAsC,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,CAAC;AAM3C;;;;;GAKG;AACH,qBAAa,mBAAmB;IAGlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,OAAO,CAAM;gBAEQ,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI;IAEnE,uEAAuE;IACvE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CA+B5B;AA4CD,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;IAC1B,gEAAgE;IAChE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,aAAa,CA0CzF"}
|
package/dist/repl/mouse.js
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mouse-wheel capture for the full-screen REPL (alternate-screen mode).
|
|
3
|
-
*
|
|
4
|
-
* Enabling xterm mouse reporting (?1000 press/release + ?1002 drag +
|
|
5
|
-
* ?1006 SGR encoding) re-routes the terminal's wheel from its own scrollback
|
|
6
|
-
* scroll to escape sequences delivered to us — `\x1b[<64;col;rowM` = wheel
|
|
7
|
-
* up, `\x1b[<65;…M` = wheel down. The terminal stops scrolling entirely,
|
|
8
|
-
* which is what prevents Warp from scrolling the alt-screen frame away
|
|
9
|
-
* (warp#9838); vim/tmux/htop scroll correctly inside Warp via this exact
|
|
10
|
-
* mechanism.
|
|
11
|
-
*
|
|
12
|
-
* Ink knows nothing about mouse sequences, so raw bytes must never reach it:
|
|
13
|
-
* this module owns the REAL process.stdin as its sole consumer, strips
|
|
14
|
-
* complete SGR mouse events out of the byte stream, forwards everything
|
|
15
|
-
* else into a fake stdin handed to ink via `render({stdin})`, and reports
|
|
16
|
-
* wheel notches through a callback.
|
|
17
|
-
*/
|
|
18
|
-
import { PassThrough } from "node:stream";
|
|
19
|
-
/** DECSET sequences arming SGR mouse reporting on the terminal. */
|
|
20
|
-
export const MOUSE_ENABLE = "\x1b[?1000h\x1b[?1002h\x1b[?1006h";
|
|
21
|
-
/** Matching resets — idempotent, safe to write more than once. */
|
|
22
|
-
export const MOUSE_DISABLE = "\x1b[?1000l\x1b[?1002l\x1b[?1006l";
|
|
23
|
-
/** Longest legitimate SGR mouse event is well under 32 bytes; beyond this a
|
|
24
|
-
* dangling `\x1b[<` prefix is garbage and gets flushed verbatim. */
|
|
25
|
-
const MAX_PENDING = 64;
|
|
26
|
-
/**
|
|
27
|
-
* Incremental splitter: feed() raw stdin chunks, get back display-safe text
|
|
28
|
-
* with every mouse event removed, and receive wheel callbacks for events.
|
|
29
|
-
* Holds an incomplete trailing sequence until the rest arrives in a later
|
|
30
|
-
* chunk.
|
|
31
|
-
*/
|
|
32
|
-
export class MouseSequenceFilter {
|
|
33
|
-
onWheel;
|
|
34
|
-
pending = "";
|
|
35
|
-
constructor(onWheel) {
|
|
36
|
-
this.onWheel = onWheel;
|
|
37
|
-
}
|
|
38
|
-
/** Feed one raw chunk; returns the passthrough text (may be empty). */
|
|
39
|
-
feed(chunk) {
|
|
40
|
-
let buf = this.pending + chunk;
|
|
41
|
-
if (!buf.includes("\x1b"))
|
|
42
|
-
return buf;
|
|
43
|
-
let out = "";
|
|
44
|
-
let i = 0;
|
|
45
|
-
while (i < buf.length) {
|
|
46
|
-
if (buf[i] !== "\x1b") {
|
|
47
|
-
out += buf[i];
|
|
48
|
-
i++;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
const match = scanMouseEvent(buf, i);
|
|
52
|
-
if (match === null) {
|
|
53
|
-
// Ran off the end mid-candidate: hold the tail for the next chunk.
|
|
54
|
-
this.pending = buf.slice(i);
|
|
55
|
-
if (this.pending.length > MAX_PENDING) {
|
|
56
|
-
out += this.pending; // pathological — flush verbatim instead of eating input
|
|
57
|
-
this.pending = "";
|
|
58
|
-
}
|
|
59
|
-
return out;
|
|
60
|
-
}
|
|
61
|
-
if (!match.passthrough) {
|
|
62
|
-
if (match.dir !== null)
|
|
63
|
-
this.onWheel(match.dir);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
out += "\x1b"; // lone ESC / non-mouse CSI: byte-identical passthrough
|
|
67
|
-
}
|
|
68
|
-
i += match.consumed;
|
|
69
|
-
}
|
|
70
|
-
this.pending = "";
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Match one SGR mouse event at `start` (which must be ESC):
|
|
76
|
-
* `\x1b[<button;column;row(M|m)` — M = press/drag, m = release. Returns null
|
|
77
|
-
* when the buffer ends mid-candidate; `{passthrough: true}` when what follows
|
|
78
|
-
* is not a mouse event (arrow keys, other CSI, plain text) — only the ESC
|
|
79
|
-
* itself is "consumed", the caller re-emits it verbatim.
|
|
80
|
-
*/
|
|
81
|
-
function scanMouseEvent(s, start) {
|
|
82
|
-
let i = start + 1;
|
|
83
|
-
if (i >= s.length)
|
|
84
|
-
return null; // can't tell yet — maybe "[…" next chunk
|
|
85
|
-
if (s.charCodeAt(i) !== 0x5b /* [ */)
|
|
86
|
-
return passthroughEsc();
|
|
87
|
-
i++;
|
|
88
|
-
if (i >= s.length)
|
|
89
|
-
return null; // "[<" possible
|
|
90
|
-
if (s.charCodeAt(i) !== 0x3c /* < */)
|
|
91
|
-
return passthroughEsc();
|
|
92
|
-
const paramsStart = i + 1;
|
|
93
|
-
let finalIdx = -1;
|
|
94
|
-
for (let k = paramsStart; k < s.length; k++) {
|
|
95
|
-
const ch = s[k];
|
|
96
|
-
if ((ch >= "0" && ch <= "9") || ch === ";")
|
|
97
|
-
continue;
|
|
98
|
-
if (ch === "M" || ch === "m") {
|
|
99
|
-
finalIdx = k;
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
return passthroughEsc(); // some other CSI-x sequence, not ours
|
|
103
|
-
}
|
|
104
|
-
if (finalIdx === -1)
|
|
105
|
-
return null; // still valid-looking but incomplete
|
|
106
|
-
const params = s.slice(paramsStart, finalIdx).split(";");
|
|
107
|
-
// Wheel buttons per xterm ctlseqs: 64 = wheel up, 65 = wheel down. Drag /
|
|
108
|
-
// motion / release codes arrive too once ?1002h is armed — drop silently.
|
|
109
|
-
const button = Number.parseInt(params[0] ?? "", 10);
|
|
110
|
-
const dir = button === 64 ? "up" : button === 65 ? "down" : null;
|
|
111
|
-
return { passthrough: false, dir, consumed: finalIdx + 1 - start };
|
|
112
|
-
}
|
|
113
|
-
function passthroughEsc() {
|
|
114
|
-
return { passthrough: true, consumed: 1 };
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Take over process.stdin, strip mouse events, expose the cleaned stream for
|
|
118
|
-
* ink. The fake stream forwards TTY identity and lifecycle calls (ink sets
|
|
119
|
-
* raw mode, ref/unrefs it, and consumes via 'readable'+read()); keyboard data
|
|
120
|
-
* flows through unchanged byte-for-byte.
|
|
121
|
-
*/
|
|
122
|
-
export function createFilteredStdin(onWheel) {
|
|
123
|
-
const real = process.stdin;
|
|
124
|
-
// Chunks are utf8 strings downstream of us; decoding here keeps CJK and
|
|
125
|
-
// escape bytes aligned across chunk boundaries.
|
|
126
|
-
real.setEncoding("utf8");
|
|
127
|
-
const filter = new MouseSequenceFilter(onWheel);
|
|
128
|
-
const fake = new PassThrough();
|
|
129
|
-
Object.defineProperty(fake, "isTTY", { value: real.isTTY });
|
|
130
|
-
const proxy = fake;
|
|
131
|
-
proxy.setRawMode = (mode) => {
|
|
132
|
-
try {
|
|
133
|
-
real.setRawMode(mode);
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
// non-TTY stdin (tests): ink skips raw mode via isTTY anyway
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
proxy.ref = () => {
|
|
140
|
-
real.ref();
|
|
141
|
-
};
|
|
142
|
-
proxy.unref = () => {
|
|
143
|
-
real.unref();
|
|
144
|
-
};
|
|
145
|
-
const onData = (chunk) => {
|
|
146
|
-
const clean = filter.feed(chunk);
|
|
147
|
-
if (clean.length > 0 && !fake.destroyed)
|
|
148
|
-
fake.write(clean);
|
|
149
|
-
};
|
|
150
|
-
const endFake = () => {
|
|
151
|
-
if (!fake.destroyed)
|
|
152
|
-
fake.end();
|
|
153
|
-
};
|
|
154
|
-
real.on("data", onData);
|
|
155
|
-
real.once("end", endFake);
|
|
156
|
-
return {
|
|
157
|
-
stream: fake,
|
|
158
|
-
dispose() {
|
|
159
|
-
real.off("data", onData);
|
|
160
|
-
real.off("end", endFake);
|
|
161
|
-
endFake();
|
|
162
|
-
},
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
//# sourceMappingURL=mouse.js.map
|
package/dist/repl/mouse.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mouse.js","sourceRoot":"","sources":["../../src/repl/mouse.ts"],"names":[],"mappings":"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"}
|