@viraatdas/rudder 3.1.7 → 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.
- package/dist/cloud.js +37 -1
- package/dist/cloud.js.map +1 -1
- package/dist/predict.d.ts +57 -0
- package/dist/predict.js +342 -0
- package/dist/predict.js.map +1 -0
- package/package.json +2 -1
package/dist/cloud.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
import { EchoPredictor } from "./predict.js";
|
|
3
4
|
import fsp from "node:fs/promises";
|
|
4
5
|
import os from "node:os";
|
|
5
6
|
import path from "node:path";
|
|
@@ -2828,12 +2829,19 @@ async function runAttach(target, options) {
|
|
|
2828
2829
|
let result = "failed";
|
|
2829
2830
|
const splashAllowed = isInteractive && !options.json && !options.quietBanner;
|
|
2830
2831
|
const splash = splashAllowed ? new AttachSplash(stdout, target.label) : null;
|
|
2832
|
+
// Predictive local echo (src/predict.ts): typed characters appear at the
|
|
2833
|
+
// caret at once and the cloud's frame confirms them. RUDDER_PREDICT=0
|
|
2834
|
+
// turns it off; it only engages once the round trip is worth hiding.
|
|
2835
|
+
const predictor = isInteractive && process.env.RUDDER_PREDICT !== "0"
|
|
2836
|
+
? new EchoPredictor(stdout.columns ?? 120, stdout.rows ?? 32, (text) => stdout.write(text))
|
|
2837
|
+
: null;
|
|
2831
2838
|
const sendResize = () => {
|
|
2832
2839
|
if (socket.readyState !== WebSocket.OPEN) {
|
|
2833
2840
|
return;
|
|
2834
2841
|
}
|
|
2835
2842
|
const cols = stdout.columns ?? 120;
|
|
2836
2843
|
const rows = stdout.rows ?? 32;
|
|
2844
|
+
predictor?.resize(cols, rows);
|
|
2837
2845
|
socket.send(JSON.stringify({ type: "resize", cols, rows }));
|
|
2838
2846
|
};
|
|
2839
2847
|
let lastCtrlC = 0;
|
|
@@ -2911,6 +2919,7 @@ async function runAttach(target, options) {
|
|
|
2911
2919
|
lastCtrlC = now;
|
|
2912
2920
|
}
|
|
2913
2921
|
socket.send(buffer, { binary: true });
|
|
2922
|
+
predictor?.onInput(buffer);
|
|
2914
2923
|
};
|
|
2915
2924
|
const onResize = () => {
|
|
2916
2925
|
if (hasControl) {
|
|
@@ -2925,7 +2934,14 @@ async function runAttach(target, options) {
|
|
|
2925
2934
|
// as a dropped connection, which attachWithReconnect reopens.
|
|
2926
2935
|
let lastHeard = Date.now();
|
|
2927
2936
|
let lastTick = Date.now();
|
|
2928
|
-
|
|
2937
|
+
let pingSentAt = 0;
|
|
2938
|
+
socket.on("pong", () => {
|
|
2939
|
+
lastHeard = Date.now();
|
|
2940
|
+
if (pingSentAt) {
|
|
2941
|
+
predictor?.noteRtt(Date.now() - pingSentAt);
|
|
2942
|
+
pingSentAt = 0;
|
|
2943
|
+
}
|
|
2944
|
+
});
|
|
2929
2945
|
socket.on("message", () => { lastHeard = Date.now(); });
|
|
2930
2946
|
const liveness = setInterval(() => {
|
|
2931
2947
|
const now = Date.now();
|
|
@@ -2940,6 +2956,7 @@ async function runAttach(target, options) {
|
|
|
2940
2956
|
}
|
|
2941
2957
|
try {
|
|
2942
2958
|
socket.ping();
|
|
2959
|
+
pingSentAt = Date.now();
|
|
2943
2960
|
}
|
|
2944
2961
|
catch {
|
|
2945
2962
|
socket.terminate();
|
|
@@ -2952,6 +2969,7 @@ async function runAttach(target, options) {
|
|
|
2952
2969
|
}
|
|
2953
2970
|
cleaned = true;
|
|
2954
2971
|
clearInterval(liveness);
|
|
2972
|
+
predictor?.dispose();
|
|
2955
2973
|
stdin.off("data", onStdin);
|
|
2956
2974
|
stdout.off("resize", onResize);
|
|
2957
2975
|
process.off("SIGINT", onSigint);
|
|
@@ -3105,6 +3123,20 @@ async function runAttach(target, options) {
|
|
|
3105
3123
|
};
|
|
3106
3124
|
socket.on("open", () => {
|
|
3107
3125
|
opened = true;
|
|
3126
|
+
// Measure the round trip at once: predictive echo waits on it.
|
|
3127
|
+
try {
|
|
3128
|
+
socket.ping();
|
|
3129
|
+
pingSentAt = Date.now();
|
|
3130
|
+
}
|
|
3131
|
+
catch {
|
|
3132
|
+
// the liveness timer retries
|
|
3133
|
+
}
|
|
3134
|
+
if (probeMode) {
|
|
3135
|
+
// An idle dashboard sends nothing; a resize makes it repaint, which is
|
|
3136
|
+
// the first frame the probe waits for.
|
|
3137
|
+
socket.send(JSON.stringify({ type: "resize", cols: 119, rows: 32 }));
|
|
3138
|
+
setTimeout(() => socket.send(JSON.stringify({ type: "resize", cols: 120, rows: 32 })), 200);
|
|
3139
|
+
}
|
|
3108
3140
|
// Disable Nagle on the underlying TCP socket so single keystrokes don't
|
|
3109
3141
|
// sit in the send buffer waiting for piggyback ACKs (~40ms savings per
|
|
3110
3142
|
// keypress on the WAN).
|
|
@@ -3211,6 +3243,7 @@ async function runAttach(target, options) {
|
|
|
3211
3243
|
setTimeout(sendResize, 150);
|
|
3212
3244
|
}
|
|
3213
3245
|
stdout.write(data);
|
|
3246
|
+
predictor?.onServerData(data);
|
|
3214
3247
|
return;
|
|
3215
3248
|
}
|
|
3216
3249
|
const text = Buffer.isBuffer(data)
|
|
@@ -3673,6 +3706,9 @@ const LAPTOP_CONFIG_FILES = [
|
|
|
3673
3706
|
"~/.codex/config.toml",
|
|
3674
3707
|
"~/.codex/AGENTS.md",
|
|
3675
3708
|
"~/.codex/hooks.json",
|
|
3709
|
+
// Service logins agents use from scripts (Kalshi signs requests with this key).
|
|
3710
|
+
"~/.kalshi/config.json",
|
|
3711
|
+
"~/.kalshi/private_key.pem",
|
|
3676
3712
|
];
|
|
3677
3713
|
async function laptopConfigFiles() {
|
|
3678
3714
|
const names = [...LAPTOP_CONFIG_FILES, "~/.aws/config", "~/.aws/credentials"];
|