ragent-cli 1.11.5 → 1.11.7
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/index.js +83 -8
- package/dist/sbom.json +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "ragent-cli",
|
|
34
|
-
version: "1.11.
|
|
34
|
+
version: "1.11.7",
|
|
35
35
|
description: "CLI agent for rAgent Live \u2014 browser-first terminal control plane for AI coding agents",
|
|
36
36
|
main: "dist/index.js",
|
|
37
37
|
bin: {
|
|
@@ -2930,6 +2930,10 @@ var BACKPRESSURE_RESUME_CHECK_MS = 100;
|
|
|
2930
2930
|
var STOP_DEBOUNCE_MS = 2e3;
|
|
2931
2931
|
var MAX_CONCURRENT_STREAMS = 20;
|
|
2932
2932
|
var MAX_SESSION_BUFFER_BYTES = 64 * 1024;
|
|
2933
|
+
var ALT_SCREEN_MODE_RE = /\x1b\[\?(?=[0-9;]*(?:47|1047|1048|1049)(?:;|[hl]))[0-9;]*[hl]/g;
|
|
2934
|
+
function stripAlternateScreenModeSwitches(data) {
|
|
2935
|
+
return data.replace(ALT_SCREEN_MODE_RE, "");
|
|
2936
|
+
}
|
|
2933
2937
|
function parsePaneTarget(sessionId) {
|
|
2934
2938
|
if (!sessionId.startsWith("tmux:")) return null;
|
|
2935
2939
|
const rest = sessionId.slice("tmux:".length);
|
|
@@ -3286,7 +3290,7 @@ var SessionStreamer = class {
|
|
|
3286
3290
|
{ env: cleanEnv, timeout: 5e3, encoding: "utf-8" }
|
|
3287
3291
|
);
|
|
3288
3292
|
if (initial) {
|
|
3289
|
-
this.sendFn(sessionId, initial.replace(/\n/g, "\r\n").replace(/\r\n$/, ""));
|
|
3293
|
+
this.sendFn(sessionId, stripAlternateScreenModeSwitches(initial.replace(/\n/g, "\r\n").replace(/\r\n$/, "")));
|
|
3290
3294
|
}
|
|
3291
3295
|
} catch {
|
|
3292
3296
|
}
|
|
@@ -3379,13 +3383,13 @@ var SessionStreamer = class {
|
|
|
3379
3383
|
if (stream.initializing) {
|
|
3380
3384
|
stream.initBuffer.push(data);
|
|
3381
3385
|
} else {
|
|
3382
|
-
this.sendFn(sessionId, data);
|
|
3386
|
+
this.sendFn(sessionId, stripAlternateScreenModeSwitches(data));
|
|
3383
3387
|
}
|
|
3384
3388
|
});
|
|
3385
3389
|
catProc.on("exit", () => {
|
|
3386
3390
|
if (!stream.stopped) {
|
|
3387
3391
|
const remaining = stream.utf8Decoder.end();
|
|
3388
|
-
if (remaining) this.sendFn(sessionId, remaining);
|
|
3392
|
+
if (remaining) this.sendFn(sessionId, stripAlternateScreenModeSwitches(remaining));
|
|
3389
3393
|
this.cleanupStream(stream);
|
|
3390
3394
|
this.active.delete(sessionId);
|
|
3391
3395
|
this.pendingStops.delete(sessionId);
|
|
@@ -3424,7 +3428,7 @@ var SessionStreamer = class {
|
|
|
3424
3428
|
{ env: cleanEnv, timeout: 5e3, encoding: "utf-8" }
|
|
3425
3429
|
);
|
|
3426
3430
|
if (initial) {
|
|
3427
|
-
this.sendFn(sessionId, initial.replace(/\n/g, "\r\n").replace(/\r\n$/, ""));
|
|
3431
|
+
this.sendFn(sessionId, stripAlternateScreenModeSwitches(initial.replace(/\n/g, "\r\n").replace(/\r\n$/, "")));
|
|
3428
3432
|
}
|
|
3429
3433
|
} catch {
|
|
3430
3434
|
}
|
|
@@ -3782,6 +3786,10 @@ var SequenceTracker = class {
|
|
|
3782
3786
|
var import_node_child_process3 = require("child_process");
|
|
3783
3787
|
var pty2 = __toESM(require("node-pty"));
|
|
3784
3788
|
var log9 = createLogger("pty");
|
|
3789
|
+
var MIN_TMUX_COLS = 20;
|
|
3790
|
+
var MAX_TMUX_COLS = 500;
|
|
3791
|
+
var MIN_TMUX_ROWS = 5;
|
|
3792
|
+
var MAX_TMUX_ROWS = 200;
|
|
3785
3793
|
var ANSI_KEY_SEQUENCES = /* @__PURE__ */ new Map([
|
|
3786
3794
|
["\x1B[A", "Up"],
|
|
3787
3795
|
["\x1B[B", "Down"],
|
|
@@ -3881,6 +3889,13 @@ function execTmuxSendKeys(args) {
|
|
|
3881
3889
|
});
|
|
3882
3890
|
});
|
|
3883
3891
|
}
|
|
3892
|
+
function isValidTmuxSessionName(target) {
|
|
3893
|
+
const sessionName = target.split(":")[0].split(".")[0];
|
|
3894
|
+
return /^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$/.test(sessionName);
|
|
3895
|
+
}
|
|
3896
|
+
function clampDimension(value, min, max) {
|
|
3897
|
+
return Math.max(min, Math.min(max, Math.floor(value)));
|
|
3898
|
+
}
|
|
3884
3899
|
function isInteractiveShell(command) {
|
|
3885
3900
|
const trimmed = String(command).trim();
|
|
3886
3901
|
return ["bash", "sh", "zsh", "fish"].includes(trimmed);
|
|
@@ -3911,8 +3926,8 @@ async function sendInputToTmux(sessionId, data) {
|
|
|
3911
3926
|
if (!sessionId.startsWith("tmux:")) return;
|
|
3912
3927
|
const target = sessionId.slice("tmux:".length).trim();
|
|
3913
3928
|
if (!target) return;
|
|
3914
|
-
|
|
3915
|
-
|
|
3929
|
+
if (!isValidTmuxSessionName(target)) {
|
|
3930
|
+
const sessionName = target.split(":")[0].split(".")[0];
|
|
3916
3931
|
log9.warn("invalid tmux session name", { sessionName });
|
|
3917
3932
|
return;
|
|
3918
3933
|
}
|
|
@@ -3929,6 +3944,35 @@ async function sendInputToTmux(sessionId, data) {
|
|
|
3929
3944
|
log9.warn("failed to send input", { sessionId, error: message });
|
|
3930
3945
|
}
|
|
3931
3946
|
}
|
|
3947
|
+
async function resizeTmuxPaneBySessionId(sessionId, cols, rows) {
|
|
3948
|
+
if (!sessionId.startsWith("tmux:")) return false;
|
|
3949
|
+
const target = sessionId.slice("tmux:".length).trim();
|
|
3950
|
+
if (!target) return false;
|
|
3951
|
+
if (!isValidTmuxSessionName(target)) {
|
|
3952
|
+
const sessionName = target.split(":")[0].split(".")[0];
|
|
3953
|
+
log9.warn("invalid tmux session name", { sessionName });
|
|
3954
|
+
return false;
|
|
3955
|
+
}
|
|
3956
|
+
if (!Number.isFinite(cols) || !Number.isFinite(rows)) return false;
|
|
3957
|
+
const safeCols = clampDimension(cols, MIN_TMUX_COLS, MAX_TMUX_COLS);
|
|
3958
|
+
const safeRows = clampDimension(rows, MIN_TMUX_ROWS, MAX_TMUX_ROWS);
|
|
3959
|
+
return new Promise((resolve) => {
|
|
3960
|
+
(0, import_node_child_process3.execFile)(
|
|
3961
|
+
"tmux",
|
|
3962
|
+
["resize-pane", "-t", target, "-x", String(safeCols), "-y", String(safeRows)],
|
|
3963
|
+
{ timeout: 5e3 },
|
|
3964
|
+
(err) => {
|
|
3965
|
+
if (err) {
|
|
3966
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3967
|
+
log9.warn("failed to resize tmux pane", { sessionId, error: message });
|
|
3968
|
+
resolve(false);
|
|
3969
|
+
return;
|
|
3970
|
+
}
|
|
3971
|
+
resolve(true);
|
|
3972
|
+
}
|
|
3973
|
+
);
|
|
3974
|
+
});
|
|
3975
|
+
}
|
|
3932
3976
|
async function stopAllDetachedTmuxSessions() {
|
|
3933
3977
|
try {
|
|
3934
3978
|
const raw = await execAsync(
|
|
@@ -4952,6 +4996,7 @@ function isSafeWorkingDir(raw) {
|
|
|
4952
4996
|
|
|
4953
4997
|
// src/control-dispatcher.ts
|
|
4954
4998
|
var log13 = createLogger("control");
|
|
4999
|
+
var TMUX_RESYNC_DEBOUNCE_MS = 150;
|
|
4955
5000
|
function collectProcessTreePids(rootPid, visited = /* @__PURE__ */ new Set()) {
|
|
4956
5001
|
if (visited.has(rootPid)) return [];
|
|
4957
5002
|
visited.add(rootPid);
|
|
@@ -4993,6 +5038,7 @@ var ControlDispatcher = class {
|
|
|
4993
5038
|
transcriptWatcher;
|
|
4994
5039
|
options;
|
|
4995
5040
|
_approvalEnforcer = null;
|
|
5041
|
+
tmuxResizeState = /* @__PURE__ */ new Map();
|
|
4996
5042
|
/** Set to true when a reconnect was requested (restart-agent, disconnect). */
|
|
4997
5043
|
reconnectRequested = false;
|
|
4998
5044
|
/** Set to false to stop the agent. */
|
|
@@ -5246,10 +5292,39 @@ var ControlDispatcher = class {
|
|
|
5246
5292
|
this.streamer.writeInput(sessionId, data);
|
|
5247
5293
|
}
|
|
5248
5294
|
}
|
|
5249
|
-
/** Handle resize routing
|
|
5295
|
+
/** Handle resize routing. */
|
|
5250
5296
|
handleResize(cols, rows, sessionId) {
|
|
5251
5297
|
if (!sessionId || sessionId.startsWith("pty:")) {
|
|
5252
5298
|
this.shell.resize(cols, rows);
|
|
5299
|
+
} else if (sessionId.startsWith("tmux:")) {
|
|
5300
|
+
const previous = this.tmuxResizeState.get(sessionId);
|
|
5301
|
+
if (previous?.cols === cols && previous.rows === rows) return;
|
|
5302
|
+
if (previous?.timer) clearTimeout(previous.timer);
|
|
5303
|
+
const state = { cols, rows, timer: null };
|
|
5304
|
+
this.tmuxResizeState.set(sessionId, state);
|
|
5305
|
+
resizeTmuxPaneBySessionId(sessionId, cols, rows).then((resized) => {
|
|
5306
|
+
if (!resized) {
|
|
5307
|
+
if (this.tmuxResizeState.get(sessionId) === state) {
|
|
5308
|
+
this.tmuxResizeState.delete(sessionId);
|
|
5309
|
+
}
|
|
5310
|
+
return;
|
|
5311
|
+
}
|
|
5312
|
+
const current = this.tmuxResizeState.get(sessionId);
|
|
5313
|
+
if (current !== state) return;
|
|
5314
|
+
current.timer = setTimeout(() => {
|
|
5315
|
+
const latest = this.tmuxResizeState.get(sessionId);
|
|
5316
|
+
if (latest === current) {
|
|
5317
|
+
latest.timer = null;
|
|
5318
|
+
this.streamer.resyncStream(sessionId);
|
|
5319
|
+
}
|
|
5320
|
+
}, TMUX_RESYNC_DEBOUNCE_MS);
|
|
5321
|
+
}).catch((error) => {
|
|
5322
|
+
if (this.tmuxResizeState.get(sessionId) === state) {
|
|
5323
|
+
this.tmuxResizeState.delete(sessionId);
|
|
5324
|
+
}
|
|
5325
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5326
|
+
log13.warn("tmux resize failed", { sessionId, error: message });
|
|
5327
|
+
});
|
|
5253
5328
|
} else if (sessionId.startsWith("screen:") || sessionId.startsWith("zellij:")) {
|
|
5254
5329
|
this.streamer.resize(sessionId, cols, rows);
|
|
5255
5330
|
}
|
package/dist/sbom.json
CHANGED
|
@@ -1166,8 +1166,8 @@
|
|
|
1166
1166
|
{
|
|
1167
1167
|
"type": "library",
|
|
1168
1168
|
"name": "ragent-cli",
|
|
1169
|
-
"version": "1.11.
|
|
1170
|
-
"bom-ref": "ragent-live|ragent-cli@1.11.
|
|
1169
|
+
"version": "1.11.7",
|
|
1170
|
+
"bom-ref": "ragent-live|ragent-cli@1.11.7",
|
|
1171
1171
|
"author": "Intellimetrics",
|
|
1172
1172
|
"description": "CLI agent for rAgent Live — browser-first terminal control plane for AI coding agents",
|
|
1173
1173
|
"licenses": [
|
|
@@ -1178,7 +1178,7 @@
|
|
|
1178
1178
|
}
|
|
1179
1179
|
}
|
|
1180
1180
|
],
|
|
1181
|
-
"purl": "pkg:npm/ragent-cli@1.11.
|
|
1181
|
+
"purl": "pkg:npm/ragent-cli@1.11.7",
|
|
1182
1182
|
"externalReferences": [
|
|
1183
1183
|
{
|
|
1184
1184
|
"url": "https://github.com/chadlindell/ragent-live/issues",
|
|
@@ -1303,7 +1303,7 @@
|
|
|
1303
1303
|
"ragent-live|@emnapi/wasi-threads@1.2.1",
|
|
1304
1304
|
"ragent-live|@pkgjs/parseargs@0.11.0",
|
|
1305
1305
|
"ragent-live|@tybys/wasm-util@0.10.1",
|
|
1306
|
-
"ragent-live|ragent-cli@1.11.
|
|
1306
|
+
"ragent-live|ragent-cli@1.11.7"
|
|
1307
1307
|
]
|
|
1308
1308
|
},
|
|
1309
1309
|
{
|
|
@@ -1436,7 +1436,7 @@
|
|
|
1436
1436
|
]
|
|
1437
1437
|
},
|
|
1438
1438
|
{
|
|
1439
|
-
"ref": "ragent-live|ragent-cli@1.11.
|
|
1439
|
+
"ref": "ragent-live|ragent-cli@1.11.7",
|
|
1440
1440
|
"dependsOn": [
|
|
1441
1441
|
"ragent-live|@azure/web-pubsub-client@1.0.4",
|
|
1442
1442
|
"ragent-live|commander@14.0.3",
|