@viraatdas/rudder 3.1.3 → 3.1.8

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.
Binary file
@@ -0,0 +1,57 @@
1
+ export type PredictorOptions = {
2
+ /** Predict only once the smoothed round trip is at least this (ms). */
3
+ thresholdMs?: number;
4
+ /** A prediction not confirmed within this long is rolled back (ms). */
5
+ timeoutMs?: number;
6
+ /** After a rollback, stop predicting for this long (ms). */
7
+ cooldownMs?: number;
8
+ now?: () => number;
9
+ };
10
+ export declare class EchoPredictor {
11
+ private readonly model;
12
+ private readonly out;
13
+ private readonly thresholdMs;
14
+ private readonly timeoutMs;
15
+ private readonly cooldownMs;
16
+ private readonly now;
17
+ private predictions;
18
+ private pendingWrites;
19
+ private inSyncFrame;
20
+ private midEscape;
21
+ private cursorVisible;
22
+ private sawFrame;
23
+ private caret;
24
+ private hold;
25
+ private holdSince;
26
+ private suspendedUntil;
27
+ private srtt;
28
+ private timer;
29
+ rollbacks: number;
30
+ confirmed: number;
31
+ constructor(cols: number, rows: number, out: (text: string) => void, options?: PredictorOptions);
32
+ /** Feed a measured round trip (ms); predictions start above the threshold. */
33
+ noteRtt(ms: number): void;
34
+ get active(): boolean;
35
+ resize(cols: number, rows: number): void;
36
+ dispose(): void;
37
+ /** Bytes the cloud drew. Call after writing them to the real terminal. */
38
+ onServerData(data: Buffer | string): void;
39
+ /** Keystrokes the user typed (already sent to the cloud). */
40
+ onInput(data: Buffer | string): void;
41
+ private atBoundary;
42
+ private setHold;
43
+ private predictChar;
44
+ private predictBackspace;
45
+ /** Draw every pending prediction and park the cursor after the last one. */
46
+ private show;
47
+ private reconcile;
48
+ /** Repaint every predicted cell from the model and put the cursor back. */
49
+ private rollback;
50
+ private ensureTimer;
51
+ private cellChar;
52
+ private cellBlank;
53
+ /** SGR + character that redraws one cell exactly as the model has it. */
54
+ private cellPaint;
55
+ }
56
+ /** Whether a chunk stops inside an escape sequence (the next chunk finishes it). */
57
+ export declare function endsMidEscape(text: string): boolean;
@@ -0,0 +1,342 @@
1
+ // Predictive local echo for `rudder cloud` (the mosh trick).
2
+ //
3
+ // A keystroke to the cloud dashboard takes a round trip (~100ms from the US
4
+ // west coast to the machine in Virginia) before its echo is drawn. The
5
+ // dashboard always parks the real terminal cursor on the input caret (the task
6
+ // box, or the agent's composer), so the client can draw a typed character at
7
+ // the caret immediately and let the cloud's frame confirm it.
8
+ //
9
+ // The client keeps an exact model of the screen the cloud has drawn (xterm's
10
+ // headless terminal, fed only the cloud's bytes). Predictions are written to
11
+ // the real terminal BETWEEN cloud frames (never inside a synchronized-output
12
+ // frame or a half-received escape sequence), so they never tear a frame. A
13
+ // prediction is confirmed when the model shows the same character in that
14
+ // cell; one the cloud contradicts, or that is not echoed in time, is rolled
15
+ // back by repainting its cell from the model. Predictions only start once the
16
+ // measured round trip is worth hiding, and only on a visible caret over a
17
+ // blank cell (typing at the end of the input, the common case).
18
+ import { createRequire } from "node:module";
19
+ const require = createRequire(import.meta.url);
20
+ const { Terminal } = require("@xterm/headless");
21
+ const SYNC_BEGIN = "\x1b[?2026h";
22
+ const SYNC_END = "\x1b[?2026l";
23
+ const CURSOR_SHOW = "\x1b[?25h";
24
+ const CURSOR_HIDE = "\x1b[?25l";
25
+ export class EchoPredictor {
26
+ model;
27
+ out;
28
+ thresholdMs;
29
+ timeoutMs;
30
+ cooldownMs;
31
+ now;
32
+ predictions = [];
33
+ pendingWrites = 0;
34
+ inSyncFrame = false;
35
+ midEscape = false;
36
+ cursorVisible = true;
37
+ sawFrame = false;
38
+ // Where the caret was when the last complete cloud frame ended. Mid-frame the
39
+ // model's cursor is wherever the cloud happens to be drawing.
40
+ caret = null;
41
+ // A key we cannot predict (Enter, arrows, a mouse report) changes the screen
42
+ // in ways the model has not seen yet: hold until the cloud catches up.
43
+ hold = false;
44
+ holdSince = 0;
45
+ suspendedUntil = 0;
46
+ srtt = null;
47
+ timer = null;
48
+ rollbacks = 0;
49
+ confirmed = 0;
50
+ constructor(cols, rows, out, options = {}) {
51
+ this.model = new Terminal({ cols, rows, allowProposedApi: true, scrollback: 0 });
52
+ this.out = out;
53
+ this.thresholdMs = options.thresholdMs ?? 30;
54
+ this.timeoutMs = options.timeoutMs ?? 1200;
55
+ this.cooldownMs = options.cooldownMs ?? 1000;
56
+ this.now = options.now ?? (() => Date.now());
57
+ }
58
+ /** Feed a measured round trip (ms); predictions start above the threshold. */
59
+ noteRtt(ms) {
60
+ if (!Number.isFinite(ms) || ms < 0) {
61
+ return;
62
+ }
63
+ this.srtt = this.srtt === null ? ms : this.srtt * 0.8 + ms * 0.2;
64
+ }
65
+ get active() {
66
+ return this.srtt !== null && this.srtt >= this.thresholdMs;
67
+ }
68
+ resize(cols, rows) {
69
+ this.rollback();
70
+ this.model.resize(Math.max(1, cols), Math.max(1, rows));
71
+ }
72
+ dispose() {
73
+ if (process.env.RUDDER_PREDICT_DEBUG === "1") {
74
+ process.stderr.write(`\npredict: srtt=${this.srtt?.toFixed(0) ?? "?"}ms confirmed=${this.confirmed} rollbacks=${this.rollbacks}\n`);
75
+ }
76
+ if (this.timer) {
77
+ clearInterval(this.timer);
78
+ this.timer = null;
79
+ }
80
+ this.model.dispose();
81
+ }
82
+ /** Bytes the cloud drew. Call after writing them to the real terminal. */
83
+ onServerData(data) {
84
+ const text = typeof data === "string" ? data : data.toString("utf8");
85
+ const lastBegin = text.lastIndexOf(SYNC_BEGIN);
86
+ const lastEnd = text.lastIndexOf(SYNC_END);
87
+ if (lastBegin !== -1 || lastEnd !== -1) {
88
+ this.inSyncFrame = lastBegin > lastEnd;
89
+ if (lastEnd > lastBegin) {
90
+ this.sawFrame = true;
91
+ }
92
+ }
93
+ const lastShow = text.lastIndexOf(CURSOR_SHOW);
94
+ const lastHide = text.lastIndexOf(CURSOR_HIDE);
95
+ if (lastShow !== -1 || lastHide !== -1) {
96
+ this.cursorVisible = lastShow > lastHide;
97
+ }
98
+ this.midEscape = endsMidEscape(text);
99
+ this.pendingWrites += 1;
100
+ this.model.write(text, () => {
101
+ this.pendingWrites -= 1;
102
+ if (this.pendingWrites === 0) {
103
+ if (this.atBoundary()) {
104
+ const buffer = this.model.buffer.active;
105
+ this.caret = { row: buffer.cursorY, col: buffer.cursorX };
106
+ }
107
+ this.reconcile();
108
+ }
109
+ });
110
+ }
111
+ /** Keystrokes the user typed (already sent to the cloud). */
112
+ onInput(data) {
113
+ const bytes = typeof data === "string" ? Buffer.from(data, "utf8") : data;
114
+ if (!this.active) {
115
+ return;
116
+ }
117
+ for (const byte of bytes) {
118
+ if (byte >= 0x20 && byte <= 0x7e) {
119
+ if (!this.predictChar(String.fromCharCode(byte))) {
120
+ this.setHold();
121
+ return;
122
+ }
123
+ }
124
+ else if (byte === 0x7f || byte === 0x08) {
125
+ if (!this.predictBackspace()) {
126
+ this.setHold();
127
+ return;
128
+ }
129
+ }
130
+ else {
131
+ this.setHold();
132
+ return;
133
+ }
134
+ }
135
+ }
136
+ atBoundary() {
137
+ return this.pendingWrites === 0 && !this.inSyncFrame && !this.midEscape;
138
+ }
139
+ setHold() {
140
+ this.hold = true;
141
+ this.holdSince = this.now();
142
+ }
143
+ predictChar(ch) {
144
+ if (this.hold) {
145
+ // The key that set the hold has had time to come back only after about
146
+ // one round trip, and the model must have caught up with it.
147
+ const settle = (this.srtt ?? 0) * 1.5 + 50;
148
+ if (this.pendingWrites !== 0 || this.now() - this.holdSince < settle) {
149
+ return false;
150
+ }
151
+ this.hold = false;
152
+ }
153
+ if (!this.sawFrame || !this.cursorVisible || this.now() < this.suspendedUntil) {
154
+ return false;
155
+ }
156
+ let row;
157
+ let col;
158
+ const last = this.predictions[this.predictions.length - 1];
159
+ if (last) {
160
+ row = last.row;
161
+ col = last.col + 1;
162
+ }
163
+ else {
164
+ if (!this.caret) {
165
+ return false;
166
+ }
167
+ row = this.caret.row;
168
+ col = this.caret.col;
169
+ }
170
+ // Leave the last column alone (wrapping is the cloud's call), and only
171
+ // type over blank cells: typing at the end of the input.
172
+ if (col >= this.model.cols - 1 || !this.cellBlank(row, col)) {
173
+ return false;
174
+ }
175
+ const prediction = { row, col, ch, at: this.now(), shown: false };
176
+ this.predictions.push(prediction);
177
+ this.ensureTimer();
178
+ if (this.atBoundary()) {
179
+ this.show();
180
+ }
181
+ return true;
182
+ }
183
+ predictBackspace() {
184
+ const last = this.predictions.pop();
185
+ if (!last) {
186
+ // Deleting text the cloud already drew: let the cloud do it.
187
+ return false;
188
+ }
189
+ if (last.shown && this.atBoundary()) {
190
+ this.out(`\x1b[${last.row + 1};${last.col + 1}H${this.cellPaint(last.row, last.col)}\x1b[0m\x1b[${last.row + 1};${last.col + 1}H`);
191
+ }
192
+ return true;
193
+ }
194
+ /** Draw every pending prediction and park the cursor after the last one. */
195
+ show() {
196
+ if (this.predictions.length === 0) {
197
+ return;
198
+ }
199
+ let text = "\x1b[0m";
200
+ for (const prediction of this.predictions) {
201
+ text += `\x1b[${prediction.row + 1};${prediction.col + 1}H${prediction.ch}`;
202
+ prediction.shown = true;
203
+ }
204
+ this.out(text);
205
+ }
206
+ reconcile() {
207
+ if (this.pendingWrites !== 0) {
208
+ return;
209
+ }
210
+ if (this.predictions.length === 0) {
211
+ return;
212
+ }
213
+ // Confirm in order: the cloud echoes keystrokes in the order they were sent.
214
+ while (this.predictions.length > 0) {
215
+ const first = this.predictions[0];
216
+ if (this.cellChar(first.row, first.col) !== first.ch) {
217
+ break;
218
+ }
219
+ this.predictions.shift();
220
+ this.confirmed += 1;
221
+ }
222
+ if (this.predictions.length === 0) {
223
+ return;
224
+ }
225
+ const first = this.predictions[0];
226
+ if (!this.atBoundary() || !this.caret) {
227
+ // Mid-frame the cursor is wherever the cloud is drawing: judge at the end.
228
+ return;
229
+ }
230
+ // The cloud moved its caret past a prediction without drawing it, or onto
231
+ // another row: the key did something other than type.
232
+ const contradicted = this.caret.row !== first.row
233
+ || this.caret.col > first.col
234
+ || !this.cellBlank(first.row, first.col);
235
+ if (contradicted || this.now() - first.at > this.timeoutMs) {
236
+ this.rollback();
237
+ return;
238
+ }
239
+ if (this.atBoundary()) {
240
+ // The cloud's frame may have repainted these cells: draw them again.
241
+ this.show();
242
+ }
243
+ }
244
+ /** Repaint every predicted cell from the model and put the cursor back. */
245
+ rollback() {
246
+ if (this.predictions.length === 0) {
247
+ return;
248
+ }
249
+ const shown = this.predictions.filter((prediction) => prediction.shown);
250
+ this.predictions = [];
251
+ this.rollbacks += 1;
252
+ this.suspendedUntil = this.now() + this.cooldownMs;
253
+ if (shown.length === 0 || !this.atBoundary()) {
254
+ return;
255
+ }
256
+ let text = "";
257
+ for (const prediction of shown) {
258
+ text += `\x1b[${prediction.row + 1};${prediction.col + 1}H${this.cellPaint(prediction.row, prediction.col)}`;
259
+ }
260
+ const buffer = this.model.buffer.active;
261
+ text += `\x1b[0m\x1b[${buffer.cursorY + 1};${buffer.cursorX + 1}H`;
262
+ this.out(text);
263
+ }
264
+ ensureTimer() {
265
+ if (this.timer) {
266
+ return;
267
+ }
268
+ this.timer = setInterval(() => {
269
+ if (this.predictions.length === 0) {
270
+ if (this.timer) {
271
+ clearInterval(this.timer);
272
+ this.timer = null;
273
+ }
274
+ return;
275
+ }
276
+ if (this.pendingWrites === 0 && this.now() - this.predictions[0].at > this.timeoutMs) {
277
+ this.rollback();
278
+ }
279
+ }, 100);
280
+ this.timer.unref?.();
281
+ }
282
+ cellChar(row, col) {
283
+ return this.model.buffer.active.getLine(row)?.getCell(col)?.getChars() ?? "";
284
+ }
285
+ cellBlank(row, col) {
286
+ const chars = this.cellChar(row, col);
287
+ return chars === "" || chars === " ";
288
+ }
289
+ /** SGR + character that redraws one cell exactly as the model has it. */
290
+ cellPaint(row, col) {
291
+ const cell = this.model.buffer.active.getLine(row)?.getCell(col);
292
+ if (!cell) {
293
+ return "\x1b[0m ";
294
+ }
295
+ const codes = ["0"];
296
+ if (cell.isBold())
297
+ codes.push("1");
298
+ if (cell.isDim())
299
+ codes.push("2");
300
+ if (cell.isItalic())
301
+ codes.push("3");
302
+ if (cell.isUnderline())
303
+ codes.push("4");
304
+ if (cell.isInverse())
305
+ codes.push("7");
306
+ if (cell.isFgRGB()) {
307
+ const c = cell.getFgColor();
308
+ codes.push(`38;2;${(c >> 16) & 255};${(c >> 8) & 255};${c & 255}`);
309
+ }
310
+ else if (cell.isFgPalette()) {
311
+ codes.push(`38;5;${cell.getFgColor()}`);
312
+ }
313
+ if (cell.isBgRGB()) {
314
+ const c = cell.getBgColor();
315
+ codes.push(`48;2;${(c >> 16) & 255};${(c >> 8) & 255};${c & 255}`);
316
+ }
317
+ else if (cell.isBgPalette()) {
318
+ codes.push(`48;5;${cell.getBgColor()}`);
319
+ }
320
+ return `\x1b[${codes.join(";")}m${cell.getChars() || " "}`;
321
+ }
322
+ }
323
+ /** Whether a chunk stops inside an escape sequence (the next chunk finishes it). */
324
+ export function endsMidEscape(text) {
325
+ const tail = text.slice(-256);
326
+ const esc = tail.lastIndexOf("\x1b");
327
+ if (esc === -1) {
328
+ return false;
329
+ }
330
+ const rest = tail.slice(esc);
331
+ if (rest.length === 1) {
332
+ return true;
333
+ }
334
+ if (rest[1] === "[") {
335
+ return !/^\x1b\[[0-?]*[ -/]*[@-~]/.test(rest);
336
+ }
337
+ if (rest[1] === "]" || rest[1] === "P" || rest[1] === "_") {
338
+ return !/(\x07|\x1b\\)/.test(rest.slice(2));
339
+ }
340
+ return false;
341
+ }
342
+ //# sourceMappingURL=predict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"predict.js","sourceRoot":"","sources":["../src/predict.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viraatdas/rudder",
3
- "version": "3.1.3",
3
+ "version": "3.1.8",
4
4
  "description": "A TUI for managing coding agents: run Claude Code, Codex and opencode side by side, each in its own isolated jj workspace.",
5
5
  "keywords": [
6
6
  "tui",
@@ -64,6 +64,7 @@
64
64
  "typescript": "^5.8.3"
65
65
  },
66
66
  "dependencies": {
67
+ "@xterm/headless": "^6.0.0",
67
68
  "ws": "^8.18.0"
68
69
  }
69
70
  }