@viraatdas/rudder 3.1.8 → 3.1.12
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/dist/attach-session.d.ts +91 -0
- package/dist/attach-session.js +290 -0
- package/dist/attach-session.js.map +1 -0
- package/dist/cloud.js +304 -224
- package/dist/cloud.js.map +1 -1
- package/dist/move-home.d.ts +2 -0
- package/dist/move-home.js +58 -4
- package/dist/move-home.js.map +1 -1
- package/dist/native/darwin-arm64/rudder-native +0 -0
- package/dist/native/darwin-x64/rudder-native +0 -0
- package/dist/native/linux-x64/rudder-native +0 -0
- package/dist/predict.d.ts +10 -0
- package/dist/predict.js +28 -1
- package/dist/predict.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { EchoPredictor } from "./predict.js";
|
|
2
|
+
export type SessionInput = {
|
|
3
|
+
on(event: "data", listener: (chunk: Buffer | string) => void): unknown;
|
|
4
|
+
off(event: "data", listener: (chunk: Buffer | string) => void): unknown;
|
|
5
|
+
resume(): unknown;
|
|
6
|
+
pause(): unknown;
|
|
7
|
+
setRawMode?(mode: boolean): unknown;
|
|
8
|
+
};
|
|
9
|
+
export type SessionOutput = {
|
|
10
|
+
columns?: number;
|
|
11
|
+
rows?: number;
|
|
12
|
+
write(text: string): unknown;
|
|
13
|
+
on(event: "resize", listener: () => void): unknown;
|
|
14
|
+
off(event: "resize", listener: () => void): unknown;
|
|
15
|
+
};
|
|
16
|
+
export type SessionOptions = {
|
|
17
|
+
interactive: boolean;
|
|
18
|
+
/** false keeps the screen model but never draws predicted keystrokes. */
|
|
19
|
+
predict?: boolean;
|
|
20
|
+
/** Where a non-interactive session reports a drop (stderr). */
|
|
21
|
+
log?: (text: string) => void;
|
|
22
|
+
now?: () => number;
|
|
23
|
+
};
|
|
24
|
+
export declare const KITTY_KEYBOARD_PUSH = "\u001B[>5u";
|
|
25
|
+
export declare const KITTY_KEYBOARD_POP = "\u001B[<u";
|
|
26
|
+
export declare function containsCtrlC(data: Buffer): boolean;
|
|
27
|
+
export declare class AttachSession {
|
|
28
|
+
/** Sent as `?client=`: the relay lets this terminal take its own place back. */
|
|
29
|
+
readonly clientId: `${string}-${string}-${string}-${string}-${string}`;
|
|
30
|
+
readonly interactive: boolean;
|
|
31
|
+
/** The cloud's screen as last drawn (and predictive echo on top of it). */
|
|
32
|
+
readonly predictor: EchoPredictor | null;
|
|
33
|
+
/** Connections that reached `open`. */
|
|
34
|
+
connections: number;
|
|
35
|
+
/** The cloud has drawn on this terminal: a reconnect resumes that picture. */
|
|
36
|
+
drewFrame: boolean;
|
|
37
|
+
hasLeft: boolean;
|
|
38
|
+
private readonly input;
|
|
39
|
+
private readonly output;
|
|
40
|
+
private readonly label;
|
|
41
|
+
private readonly log;
|
|
42
|
+
private readonly now;
|
|
43
|
+
private held;
|
|
44
|
+
private released;
|
|
45
|
+
private inGap;
|
|
46
|
+
private status;
|
|
47
|
+
private badge;
|
|
48
|
+
private queued;
|
|
49
|
+
private queuedBytes;
|
|
50
|
+
private lastCtrlC;
|
|
51
|
+
private leaveListeners;
|
|
52
|
+
constructor(label: string, input: SessionInput, output: SessionOutput, options: SessionOptions);
|
|
53
|
+
/** Take the terminal: alternate screen, raw keys, mouse and keyboard flags. */
|
|
54
|
+
hold(): void;
|
|
55
|
+
/** Give the terminal back exactly once, whatever state it is in. */
|
|
56
|
+
release(): void;
|
|
57
|
+
/**
|
|
58
|
+
* The link dropped and a reconnect follows. The screen stays as it was, a
|
|
59
|
+
* badge says what is happening, and keys are kept for the next connection.
|
|
60
|
+
*/
|
|
61
|
+
enterGap(): void;
|
|
62
|
+
/** A retry is about to start; the badge counts them once it is slow. */
|
|
63
|
+
noteAttempt(attempt: number): void;
|
|
64
|
+
/** A connection opened: it reads the keys from here on. */
|
|
65
|
+
exitGap(): void;
|
|
66
|
+
/** Keys typed while the link was down, in order, for the new connection. */
|
|
67
|
+
takeQueued(): Buffer | null;
|
|
68
|
+
/** Wait out a retry delay; true if the user left meanwhile. */
|
|
69
|
+
wait(ms: number): Promise<boolean>;
|
|
70
|
+
onLeave(listener: () => void): () => void;
|
|
71
|
+
/**
|
|
72
|
+
* Ctrl+C while nothing on the other end can take it: the first press says
|
|
73
|
+
* how to leave, a second within a few seconds leaves. True when leaving.
|
|
74
|
+
*/
|
|
75
|
+
ctrlCToLeave(): boolean;
|
|
76
|
+
leave(): void;
|
|
77
|
+
/** A lasting state worth a badge (worker away, read-only, reconnecting). */
|
|
78
|
+
showStatus(text: string): void;
|
|
79
|
+
/** The state is over: take the badge off and repaint what it covered. */
|
|
80
|
+
clearStatus(): void;
|
|
81
|
+
get statusText(): string | null;
|
|
82
|
+
/** The terminal changed size while connected: redraw the badge to fit. */
|
|
83
|
+
noteResize(): void;
|
|
84
|
+
private onGapInput;
|
|
85
|
+
private onGapResize;
|
|
86
|
+
private stopGapInput;
|
|
87
|
+
private closeOpenSequence;
|
|
88
|
+
private drawBadge;
|
|
89
|
+
private eraseBadge;
|
|
90
|
+
private setTitle;
|
|
91
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
// One `rudder cloud` terminal across reconnects (the mosh shape).
|
|
2
|
+
//
|
|
3
|
+
// A dropped link used to hand the terminal back: raw mode off, out of the
|
|
4
|
+
// alternate screen, "Lost the connection..." under the shell prompt, a wait of
|
|
5
|
+
// up to 15s, then the dashboard repainted into the main buffer on top of the
|
|
6
|
+
// scrollback. Laptops sleep and Wi-Fi changes, so that happened all the time.
|
|
7
|
+
//
|
|
8
|
+
// The session keeps the terminal through the gap instead: the cloud's last
|
|
9
|
+
// picture stays up with a small badge in the corner, what you type is kept and
|
|
10
|
+
// sent once the link is back, Ctrl+C twice leaves, and the reconnect paints
|
|
11
|
+
// over the old picture in place.
|
|
12
|
+
import { randomUUID } from "node:crypto";
|
|
13
|
+
import { EchoPredictor } from "./predict.js";
|
|
14
|
+
// The remote dashboard asks for DISAMBIGUATE_ESCAPE_CODES | REPORT_ALTERNATE_KEYS
|
|
15
|
+
// once, long before any attach; see runAttach in cloud.ts.
|
|
16
|
+
export const KITTY_KEYBOARD_PUSH = "\x1b[>5u";
|
|
17
|
+
export const KITTY_KEYBOARD_POP = "\x1b[<u";
|
|
18
|
+
const ALT_SCREEN_ON = "\x1b[?1049h";
|
|
19
|
+
const ALT_SCREEN_OFF = "\x1b[?1049l\x1b[?25h";
|
|
20
|
+
const MOUSE_ON = "\x1b[?1000h\x1b[?1002h\x1b[?1006h";
|
|
21
|
+
const MOUSE_OFF = "\x1b[?1006l\x1b[?1002l\x1b[?1000l";
|
|
22
|
+
const SYNC_BEGIN = "\x1b[?2026h";
|
|
23
|
+
const SYNC_END = "\x1b[?2026l";
|
|
24
|
+
// CAN aborts an escape sequence the cloud's last bytes left open, so an
|
|
25
|
+
// overlay is never read as the tail of one. Outside a sequence it is ignored.
|
|
26
|
+
const CANCEL = "\x18";
|
|
27
|
+
const LEAVE_WINDOW_MS = 3_000;
|
|
28
|
+
const QUEUE_LIMIT_BYTES = 64 * 1024;
|
|
29
|
+
export function containsCtrlC(data) {
|
|
30
|
+
return data.includes(0x03) || /\x1b\[99;5(?::[123])?u/.test(data.toString("latin1"));
|
|
31
|
+
}
|
|
32
|
+
export class AttachSession {
|
|
33
|
+
/** Sent as `?client=`: the relay lets this terminal take its own place back. */
|
|
34
|
+
clientId = randomUUID();
|
|
35
|
+
interactive;
|
|
36
|
+
/** The cloud's screen as last drawn (and predictive echo on top of it). */
|
|
37
|
+
predictor;
|
|
38
|
+
/** Connections that reached `open`. */
|
|
39
|
+
connections = 0;
|
|
40
|
+
/** The cloud has drawn on this terminal: a reconnect resumes that picture. */
|
|
41
|
+
drewFrame = false;
|
|
42
|
+
hasLeft = false;
|
|
43
|
+
input;
|
|
44
|
+
output;
|
|
45
|
+
label;
|
|
46
|
+
log;
|
|
47
|
+
now;
|
|
48
|
+
held = false;
|
|
49
|
+
released = false;
|
|
50
|
+
inGap = false;
|
|
51
|
+
status = null;
|
|
52
|
+
badge = null;
|
|
53
|
+
queued = [];
|
|
54
|
+
queuedBytes = 0;
|
|
55
|
+
lastCtrlC = 0;
|
|
56
|
+
leaveListeners = new Set();
|
|
57
|
+
constructor(label, input, output, options) {
|
|
58
|
+
this.label = label;
|
|
59
|
+
this.input = input;
|
|
60
|
+
this.output = output;
|
|
61
|
+
this.interactive = options.interactive;
|
|
62
|
+
this.log = options.log ?? ((text) => process.stderr.write(text));
|
|
63
|
+
this.now = options.now ?? (() => Date.now());
|
|
64
|
+
this.predictor = options.interactive
|
|
65
|
+
? new EchoPredictor(output.columns ?? 120, output.rows ?? 32, (text) => output.write(text), {
|
|
66
|
+
predict: options.predict ?? true,
|
|
67
|
+
})
|
|
68
|
+
: null;
|
|
69
|
+
}
|
|
70
|
+
/** Take the terminal: alternate screen, raw keys, mouse and keyboard flags. */
|
|
71
|
+
hold() {
|
|
72
|
+
if (!this.interactive || this.held || this.released) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.held = true;
|
|
76
|
+
this.output.write(ALT_SCREEN_ON);
|
|
77
|
+
try {
|
|
78
|
+
this.input.setRawMode?.(true);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// ignore
|
|
82
|
+
}
|
|
83
|
+
// The remote dashboard's own enable sequences arrive as output bytes,
|
|
84
|
+
// which the local terminal never treats as mode switches.
|
|
85
|
+
this.output.write(MOUSE_ON);
|
|
86
|
+
this.output.write(KITTY_KEYBOARD_PUSH);
|
|
87
|
+
}
|
|
88
|
+
/** Give the terminal back exactly once, whatever state it is in. */
|
|
89
|
+
release() {
|
|
90
|
+
if (this.released) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.released = true;
|
|
94
|
+
this.stopGapInput();
|
|
95
|
+
if (this.held) {
|
|
96
|
+
this.output.write(KITTY_KEYBOARD_POP);
|
|
97
|
+
this.output.write(MOUSE_OFF);
|
|
98
|
+
// Release the tab title so the shell prompt can rewrite it.
|
|
99
|
+
this.output.write("\x1b]0;\x07");
|
|
100
|
+
try {
|
|
101
|
+
this.input.setRawMode?.(false);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// ignore
|
|
105
|
+
}
|
|
106
|
+
this.output.write(ALT_SCREEN_OFF);
|
|
107
|
+
}
|
|
108
|
+
this.predictor?.dispose();
|
|
109
|
+
this.input.pause();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The link dropped and a reconnect follows. The screen stays as it was, a
|
|
113
|
+
* badge says what is happening, and keys are kept for the next connection.
|
|
114
|
+
*/
|
|
115
|
+
enterGap() {
|
|
116
|
+
if (this.released || this.inGap) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.inGap = true;
|
|
120
|
+
if (!this.interactive) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.closeOpenSequence();
|
|
124
|
+
this.setTitle(`Rudder cloud: ${this.label} · reconnecting`);
|
|
125
|
+
this.showStatus("Reconnecting · your agents keep running");
|
|
126
|
+
this.input.on("data", this.onGapInput);
|
|
127
|
+
this.output.on("resize", this.onGapResize);
|
|
128
|
+
this.input.resume();
|
|
129
|
+
}
|
|
130
|
+
/** A retry is about to start; the badge counts them once it is slow. */
|
|
131
|
+
noteAttempt(attempt) {
|
|
132
|
+
if (!this.interactive) {
|
|
133
|
+
this.log(`\nLost the connection to Rudder Cloud (laptop slept or the network dropped; your agents kept running). Reconnecting${attempt > 1 ? ` (try ${attempt})` : ""}...\n`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (attempt >= 4) {
|
|
137
|
+
this.showStatus(`Reconnecting (try ${attempt}) · Ctrl+C twice to leave`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** A connection opened: it reads the keys from here on. */
|
|
141
|
+
exitGap() {
|
|
142
|
+
if (!this.inGap) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.inGap = false;
|
|
146
|
+
this.stopGapInput();
|
|
147
|
+
if (this.interactive && this.held) {
|
|
148
|
+
this.setTitle(`Rudder cloud: ${this.label}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** Keys typed while the link was down, in order, for the new connection. */
|
|
152
|
+
takeQueued() {
|
|
153
|
+
if (this.queuedBytes === 0) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
const data = Buffer.concat(this.queued, this.queuedBytes);
|
|
157
|
+
this.queued = [];
|
|
158
|
+
this.queuedBytes = 0;
|
|
159
|
+
return data;
|
|
160
|
+
}
|
|
161
|
+
/** Wait out a retry delay; true if the user left meanwhile. */
|
|
162
|
+
wait(ms) {
|
|
163
|
+
if (this.hasLeft) {
|
|
164
|
+
return Promise.resolve(true);
|
|
165
|
+
}
|
|
166
|
+
return new Promise((resolve) => {
|
|
167
|
+
const timer = setTimeout(() => {
|
|
168
|
+
off();
|
|
169
|
+
resolve(false);
|
|
170
|
+
}, ms);
|
|
171
|
+
const off = this.onLeave(() => {
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
resolve(true);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
onLeave(listener) {
|
|
178
|
+
this.leaveListeners.add(listener);
|
|
179
|
+
return () => this.leaveListeners.delete(listener);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Ctrl+C while nothing on the other end can take it: the first press says
|
|
183
|
+
* how to leave, a second within a few seconds leaves. True when leaving.
|
|
184
|
+
*/
|
|
185
|
+
ctrlCToLeave() {
|
|
186
|
+
const now = this.now();
|
|
187
|
+
if (now - this.lastCtrlC < LEAVE_WINDOW_MS) {
|
|
188
|
+
this.leave();
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
this.lastCtrlC = now;
|
|
192
|
+
this.drawBadge("Press Ctrl+C again to leave");
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
leave() {
|
|
196
|
+
if (this.hasLeft) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.hasLeft = true;
|
|
200
|
+
for (const listener of [...this.leaveListeners]) {
|
|
201
|
+
listener();
|
|
202
|
+
}
|
|
203
|
+
this.leaveListeners.clear();
|
|
204
|
+
}
|
|
205
|
+
/** A lasting state worth a badge (worker away, read-only, reconnecting). */
|
|
206
|
+
showStatus(text) {
|
|
207
|
+
this.status = text;
|
|
208
|
+
this.drawBadge(text);
|
|
209
|
+
}
|
|
210
|
+
/** The state is over: take the badge off and repaint what it covered. */
|
|
211
|
+
clearStatus() {
|
|
212
|
+
this.status = null;
|
|
213
|
+
this.eraseBadge();
|
|
214
|
+
}
|
|
215
|
+
get statusText() {
|
|
216
|
+
return this.status;
|
|
217
|
+
}
|
|
218
|
+
/** The terminal changed size while connected: redraw the badge to fit. */
|
|
219
|
+
noteResize() {
|
|
220
|
+
this.badge = null;
|
|
221
|
+
if (this.status) {
|
|
222
|
+
this.drawBadge(this.status);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
onGapInput = (chunk) => {
|
|
226
|
+
const buffer = typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk;
|
|
227
|
+
if (containsCtrlC(buffer)) {
|
|
228
|
+
// Never queued: an interrupt replayed into the dashboard after the
|
|
229
|
+
// reconnect would land on whatever is running by then.
|
|
230
|
+
this.ctrlCToLeave();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const room = QUEUE_LIMIT_BYTES - this.queuedBytes;
|
|
234
|
+
if (room <= 0) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const kept = buffer.length <= room ? buffer : buffer.subarray(0, room);
|
|
238
|
+
this.queued.push(Buffer.from(kept));
|
|
239
|
+
this.queuedBytes += kept.length;
|
|
240
|
+
};
|
|
241
|
+
onGapResize = () => {
|
|
242
|
+
this.predictor?.resize(this.output.columns ?? 120, this.output.rows ?? 32);
|
|
243
|
+
this.noteResize();
|
|
244
|
+
};
|
|
245
|
+
stopGapInput() {
|
|
246
|
+
this.input.off("data", this.onGapInput);
|
|
247
|
+
this.output.off("resize", this.onGapResize);
|
|
248
|
+
}
|
|
249
|
+
// The cloud's last bytes may have stopped inside an escape sequence or a
|
|
250
|
+
// synchronized frame. End both on the terminal and in the model alike.
|
|
251
|
+
closeOpenSequence() {
|
|
252
|
+
if (!this.held) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const reset = `${CANCEL}${SYNC_END}`;
|
|
256
|
+
this.output.write(reset);
|
|
257
|
+
this.predictor?.onServerData(reset);
|
|
258
|
+
}
|
|
259
|
+
drawBadge(text) {
|
|
260
|
+
if (!this.interactive || !this.held || this.released) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const cols = this.output.columns ?? 80;
|
|
264
|
+
const available = Math.max(4, cols - 2);
|
|
265
|
+
let body = ` ⟳ ${text} `;
|
|
266
|
+
if ([...body].length > available) {
|
|
267
|
+
body = `${[...body].slice(0, available - 2).join("")}… `;
|
|
268
|
+
}
|
|
269
|
+
const width = [...body].length;
|
|
270
|
+
const col = Math.max(0, cols - width - 1);
|
|
271
|
+
let erase = "";
|
|
272
|
+
if (this.badge && this.predictor) {
|
|
273
|
+
erase = this.predictor.paintRegion(0, this.badge.col, this.badge.width);
|
|
274
|
+
}
|
|
275
|
+
this.badge = { col, width };
|
|
276
|
+
this.output.write(`${CANCEL}${SYNC_BEGIN}${erase}\x1b7\x1b[1;${col + 1}H\x1b[0;30;43m${body}\x1b[0m\x1b8${SYNC_END}`);
|
|
277
|
+
}
|
|
278
|
+
eraseBadge() {
|
|
279
|
+
const badge = this.badge;
|
|
280
|
+
this.badge = null;
|
|
281
|
+
if (!badge || !this.predictor || !this.held || this.released) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
this.output.write(`${CANCEL}${SYNC_BEGIN}${this.predictor.paintRegion(0, badge.col, badge.width)}${SYNC_END}`);
|
|
285
|
+
}
|
|
286
|
+
setTitle(title) {
|
|
287
|
+
this.output.write(`\x1b]0;${title}\x07`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=attach-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach-session.js","sourceRoot":"","sources":["../src/attach-session.ts"],"names":[],"mappings":"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"}
|