@cotal-ai/manager 0.9.1 → 0.10.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.
@@ -1,218 +0,0 @@
1
- import WebSocket from "ws";
2
- import { c } from "./ui.js";
3
- /**
4
- * The detach key — Ctrl-] (0x1d) by default, as in telnet/ssh escape conventions. `COTAL_DETACH_KEY`
5
- * rebinds it to another control key when Ctrl-] clashes with a keybinding inside the agent's TUI;
6
- * accepts `ctrl-<char>` or `^<char>` (e.g. `ctrl-b`, `^_`). Read at point of use, per the repo's
7
- * `COTAL_*` convention. An unparseable value — including a set-but-empty or whitespace-only one —
8
- * throws (named), never silently falling back; the caller turns that into a loud exit. Only an
9
- * unset var = the Ctrl-] default.
10
- */
11
- export function detachKey() {
12
- const spec = process.env.COTAL_DETACH_KEY;
13
- if (spec === undefined)
14
- return { byte: 0x1d, label: "Ctrl-]", overridden: false };
15
- const m = /^(?:ctrl-|\^)([a-z@[\\\]^_])$/i.exec(spec.trim());
16
- if (!m) {
17
- throw new Error(`invalid COTAL_DETACH_KEY "${spec}" — expected ctrl-<char> or ^<char> for a control key ` +
18
- `(a-z, or one of @ [ \\ ] ^ _), e.g. ctrl-b`);
19
- }
20
- const ch = m[1].toUpperCase();
21
- return { byte: ch.charCodeAt(0) & 0x1f, label: `Ctrl-${ch}`, overridden: true };
22
- }
23
- /**
24
- * Terminal modes a full-screen child (a fullscreen TUI: OpenCode, or Claude under `/tui fullscreen`)
25
- * commonly turns on but that we must undo locally on detach/exit: the agent keeps running after
26
- * Ctrl-], so it never restores OUR terminal. Without this, detaching from a mouse-tracking TUI leaves
27
- * the terminal reporting every cursor move as input (a stream of `ESC[<…M` escape codes), or its
28
- * focus in/out as `ESC[I`/`ESC[O`. Disables all mouse-report modes + focus reporting + bracketed
29
- * paste, resets the keypad/cursor-key modes, shows the cursor, and resets attributes. Leaving the
30
- * alternate screen is handled separately (ALT_LEAVE_SEQ), only when we actually entered it — see
31
- * cleanup().
32
- */
33
- const MOUSE_OFF = "\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1005l\x1b[?1006l\x1b[?1015l"; // all mouse tracking off
34
- const RESTORE = MOUSE_OFF +
35
- "\x1b[?1004l" + // focus reporting off
36
- "\x1b[?2004l" + // bracketed paste off
37
- "\x1b[?1l" + // application cursor keys off (DECCKM): a full-screen TUI enables it; left on, arrows emit ESC O A not ESC [ A
38
- "\x1b>" + // keypad → numeric (DECKPNM)
39
- "\x1b[?25h" + // show cursor
40
- "\x1b[0m"; // reset attributes
41
- // Leave the alternate screen on detach, but ONLY if the child put us there (altScreen). The attach
42
- // snapshot faithfully re-enters the child's alt-screen (`?1049h`) on our terminal; without a matching
43
- // leave we strand it in the alt buffer, which has no scrollback and — with xterm alt-scroll — turns
44
- // the wheel into ↑/↓ that walk shell history. Leaving the alt buffer IS the whole fix: alt-scroll
45
- // (`?1007`) only acts inside the alt buffer, so `?1049l` alone makes it inert. We deliberately don't
46
- // send `?1007l` — nothing on this path ever enabled it (unlike console.ts, which sets `?1007h` on
47
- // entry), so disabling it would clobber the operator's own alternate-scroll preference for later apps.
48
- const ALT_LEAVE_SEQ = "\x1b[?1049l"; // leave alt-screen — alt-scroll is inert once back in the main buffer
49
- // Wheel-scroll for full-screen children. A fullscreen TUI (OpenCode, or Claude under `/tui
50
- // fullscreen`) runs in the alternate screen — where the terminal's native scrollback is dead — and
51
- // scrolls its content itself off mouse reports. But it enables that mouse capture on ITS pty, and the
52
- // enable doesn't reliably survive the attach hop (backlog eviction / nested pty), so our terminal
53
- // never reports the wheel and scrolling dies. So while the child is in the alternate screen we enable
54
- // SGR mouse reporting on OUR terminal and translate each wheel tick into PageUp/PageDown — the
55
- // keystrokes a fullscreen TUI treats as "scroll the view" (OpenCode: `messages_page_up`/`_down`;
56
- // Claude's fullscreen binds PageUp/PageDown too). A child in the normal screen (inline Claude) keeps
57
- // altScreen=false, so this stays off and its native terminal-scrollback wheel is untouched.
58
- const MOUSE_ON = "\x1b[?1002h\x1b[?1006h"; // button+drag tracking, SGR encoding
59
- const PAGE_UP = "\x1b[5~";
60
- const PAGE_DOWN = "\x1b[6~";
61
- // Enter/leave the alternate screen: xterm `?1049`, plus the older `?1047`/`?47`.
62
- const ALT_ENTER = /\x1b\[\?(?:1049|1047|47)h/g;
63
- const ALT_LEAVE = /\x1b\[\?(?:1049|1047|47)l/g;
64
- // A complete SGR mouse report: `ESC [ < btn ; col ; row (M|m)`.
65
- const SGR_MOUSE = /^\x1b\[<(\d+);\d+;\d+[Mm]/;
66
- const lastIndexOfRe = (re, s) => {
67
- re.lastIndex = 0;
68
- let last = -1;
69
- for (let m = re.exec(s); m; m = re.exec(s))
70
- last = m.index;
71
- return last;
72
- };
73
- /**
74
- * Drive a manager's attach endpoint from the terminal: raw-mode stdin streams to
75
- * the PTY, PTY output streams to stdout, and SIGWINCH-style resizes are forwarded.
76
- * The detach key (Ctrl-] by default, {@link detachKey}) detaches without killing the agent.
77
- */
78
- export function attachClient(url) {
79
- // Resolve the detach key before connecting so a bad COTAL_DETACH_KEY fails loudly up front
80
- // (matching the manager's other fail-fast exits) instead of after an attach we'd only tear down.
81
- let detach;
82
- try {
83
- detach = detachKey();
84
- }
85
- catch (e) {
86
- console.error(c.red(`✗ ${e.message}`));
87
- process.exit(1);
88
- }
89
- return new Promise((resolve, reject) => {
90
- const ws = new WebSocket(url);
91
- const stdin = process.stdin;
92
- const wasRaw = stdin.isRaw ?? false;
93
- // A broken local pipe (terminal closed / SIGHUP) makes stdout writes async-error on a later
94
- // tick; with no listener that EPIPE/EIO becomes an uncaughtException — crashing on the per-frame
95
- // PTY write or the on-detach restore write. Register a no-op listener once here (not in cleanup,
96
- // so it outlives the async error tick) to turn it into a handled no-op.
97
- process.stdout.on("error", () => { });
98
- // Wheel-scroll state (see MOUSE_ON above): whether the child is in the alternate screen, and a
99
- // buffer for an SGR mouse report split across stdin reads.
100
- let altScreen = false;
101
- let mouseBuf = "";
102
- // Carry the tail of the previous output frame so an alt-screen escape split across ws frames
103
- // (e.g. `ESC[?10` then `49h`) is still detected; 16 bytes covers these private-mode sequences.
104
- // Acting only on state *change* below makes re-scanning the carried bytes idempotent.
105
- let scanTail = "";
106
- // Track the child's alt-screen transitions in its output so we can arm/disarm wheel translation.
107
- const trackAltScreen = (data) => {
108
- const s = scanTail + data.toString("latin1");
109
- scanTail = s.slice(-16);
110
- const enter = lastIndexOfRe(ALT_ENTER, s);
111
- const leave = lastIndexOfRe(ALT_LEAVE, s);
112
- if (enter === -1 && leave === -1)
113
- return;
114
- const nowAlt = enter > leave;
115
- if (nowAlt === altScreen)
116
- return;
117
- altScreen = nowAlt;
118
- if (altScreen) {
119
- if (process.stdout.isTTY)
120
- process.stdout.write(MOUSE_ON);
121
- }
122
- else {
123
- // Leaving alt-screen mid-session: undo the mouse modes WE enabled so the terminal stops
124
- // reporting the wheel/clicks and native scrollback works again — don't wait for detach.
125
- mouseBuf = "";
126
- if (process.stdout.isTTY)
127
- process.stdout.write(MOUSE_OFF);
128
- }
129
- };
130
- const sendResize = () => ws.send(`r:${process.stdout.columns ?? 80},${process.stdout.rows ?? 24}`);
131
- const onInput = (d) => {
132
- if (d.length === 1 && d[0] === detach.byte) {
133
- ws.close();
134
- return;
135
- }
136
- // Inline child: forward keystrokes raw (its wheel scrolls the local terminal, not the app).
137
- if (!altScreen) {
138
- ws.send(d);
139
- return;
140
- }
141
- // Full-screen child: rewrite wheel reports to PageUp/PageDown, pass everything else through.
142
- mouseBuf += d.toString("latin1");
143
- let out = "";
144
- for (;;) {
145
- const i = mouseBuf.indexOf("\x1b[<");
146
- if (i === -1) {
147
- // A report split right before `<` (`ESC[` now, `<…M` next) would slip through untranslated:
148
- // hold a trailing `ESC[` for the next read. Never hold a bare trailing `ESC` — that's the
149
- // Escape key and must forward at once (e.g. OpenCode's interrupt); the rarer `ESC`|`[<…`
150
- // split stays raw by design.
151
- const keep = mouseBuf.endsWith("\x1b[") ? 2 : 0;
152
- out += mouseBuf.slice(0, mouseBuf.length - keep);
153
- mouseBuf = mouseBuf.slice(mouseBuf.length - keep);
154
- break;
155
- }
156
- out += mouseBuf.slice(0, i);
157
- const rest = mouseBuf.slice(i);
158
- const m = SGR_MOUSE.exec(rest);
159
- if (!m) {
160
- // Hold only a still-valid partial report (`ESC[<` + digits/semicolons) for the next read;
161
- // anything else can't become an SGR mouse report, so pass it straight through.
162
- if (/^\x1b\[<[\d;]*$/.test(rest))
163
- mouseBuf = rest;
164
- else {
165
- out += rest;
166
- mouseBuf = "";
167
- }
168
- break;
169
- }
170
- const btn = Number(m[1]);
171
- if (btn & 0x40)
172
- out += btn & 1 ? PAGE_DOWN : PAGE_UP; // wheel: 64=up, 65=down
173
- else
174
- out += m[0]; // other mouse (click/drag): forward raw so the TUI still gets it
175
- mouseBuf = rest.slice(m[0].length);
176
- }
177
- if (out)
178
- ws.send(Buffer.from(out, "latin1"));
179
- };
180
- const cleanup = () => {
181
- stdin.off("data", onInput);
182
- process.stdout.off("resize", sendResize);
183
- // Undo terminal modes the (still-running) agent's TUI enabled — it won't restore us on detach.
184
- // If the child put us in its alternate screen (altScreen), leave it too so the terminal isn't
185
- // stranded in the alt buffer; an inline child (altScreen=false) keeps its scrollback.
186
- if (process.stdout.isTTY)
187
- process.stdout.write(RESTORE + (altScreen ? ALT_LEAVE_SEQ : ""));
188
- if (stdin.isTTY)
189
- stdin.setRawMode(wasRaw);
190
- stdin.pause();
191
- };
192
- ws.on("open", () => {
193
- // Make an override visible (the CLI's "attached to X — Ctrl-] to detach" hint still prints the
194
- // default label). Only on override, so the default case stays free of duplicate noise.
195
- if (detach.overridden)
196
- console.error(c.dim(`detach key: ${detach.label} (via COTAL_DETACH_KEY)`));
197
- if (stdin.isTTY)
198
- stdin.setRawMode(true);
199
- stdin.resume();
200
- sendResize();
201
- process.stdout.on("resize", sendResize);
202
- stdin.on("data", onInput);
203
- });
204
- ws.on("message", (data) => {
205
- trackAltScreen(data);
206
- process.stdout.write(data);
207
- });
208
- ws.on("close", () => {
209
- cleanup();
210
- resolve();
211
- });
212
- ws.on("error", (e) => {
213
- cleanup();
214
- reject(e);
215
- });
216
- });
217
- }
218
- //# sourceMappingURL=attach-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"attach-client.js","sourceRoot":"","sources":["../src/attach-client.ts"],"names":[],"mappings":"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"}