ragent-cli 1.11.8 → 1.11.9
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 +61 -17
- 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.9",
|
|
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: {
|
|
@@ -2934,6 +2934,24 @@ var ALT_SCREEN_MODE_RE = /\x1b\[\?(?=[0-9;]*(?:47|1047|1048|1049)(?:;|[hl]))[0-9
|
|
|
2934
2934
|
function stripAlternateScreenModeSwitches(data) {
|
|
2935
2935
|
return data.replace(ALT_SCREEN_MODE_RE, "");
|
|
2936
2936
|
}
|
|
2937
|
+
var AlternateScreenModeStripper = class {
|
|
2938
|
+
pending = "";
|
|
2939
|
+
write(data) {
|
|
2940
|
+
const combined = this.pending + data;
|
|
2941
|
+
this.pending = "";
|
|
2942
|
+
const match = combined.match(/\x1b(?:\[(?:\?(?:[0-9;]*)?)?)?$/);
|
|
2943
|
+
if (!match || match.index === void 0) {
|
|
2944
|
+
return stripAlternateScreenModeSwitches(combined);
|
|
2945
|
+
}
|
|
2946
|
+
this.pending = combined.slice(match.index);
|
|
2947
|
+
return stripAlternateScreenModeSwitches(combined.slice(0, match.index));
|
|
2948
|
+
}
|
|
2949
|
+
end() {
|
|
2950
|
+
const pending = this.pending;
|
|
2951
|
+
this.pending = "";
|
|
2952
|
+
return stripAlternateScreenModeSwitches(pending);
|
|
2953
|
+
}
|
|
2954
|
+
};
|
|
2937
2955
|
function parsePaneTarget(sessionId) {
|
|
2938
2956
|
if (!sessionId.startsWith("tmux:")) return null;
|
|
2939
2957
|
const rest = sessionId.slice("tmux:".length);
|
|
@@ -3172,6 +3190,11 @@ var SessionStreamer = class {
|
|
|
3172
3190
|
isStreaming(sessionId) {
|
|
3173
3191
|
return this.active.has(sessionId);
|
|
3174
3192
|
}
|
|
3193
|
+
hasViewer(sessionId, viewerId) {
|
|
3194
|
+
const viewerKey = viewerId?.trim() || "";
|
|
3195
|
+
if (!viewerKey) return false;
|
|
3196
|
+
return this.active.get(sessionId)?.viewerIds.has(viewerKey) ?? false;
|
|
3197
|
+
}
|
|
3175
3198
|
/**
|
|
3176
3199
|
* Stop all active streams immediately (no debounce).
|
|
3177
3200
|
*/
|
|
@@ -3253,11 +3276,19 @@ var SessionStreamer = class {
|
|
|
3253
3276
|
* Used when a viewer missed the initial burst (e.g. joinGroup race)
|
|
3254
3277
|
* or reconnected ("Retry stream"). Does NOT restart pipe-pane.
|
|
3255
3278
|
*/
|
|
3256
|
-
resyncStream(sessionId) {
|
|
3279
|
+
resyncStream(sessionId, viewerId) {
|
|
3257
3280
|
const stream = this.active.get(sessionId);
|
|
3258
3281
|
if (!stream || stream.stopped || stream.streamType !== "tmux-pipe") return false;
|
|
3259
3282
|
const { paneTarget, cleanEnv } = stream;
|
|
3260
3283
|
if (!paneTarget || !cleanEnv) return false;
|
|
3284
|
+
const targetViewerId = viewerId?.trim() || void 0;
|
|
3285
|
+
const send = (data) => {
|
|
3286
|
+
if (targetViewerId) {
|
|
3287
|
+
this.sendFn(sessionId, data, targetViewerId);
|
|
3288
|
+
} else {
|
|
3289
|
+
this.sendFn(sessionId, data);
|
|
3290
|
+
}
|
|
3291
|
+
};
|
|
3261
3292
|
stream.initializing = true;
|
|
3262
3293
|
try {
|
|
3263
3294
|
let alternateScreen = false;
|
|
@@ -3277,11 +3308,11 @@ var SessionStreamer = class {
|
|
|
3277
3308
|
{ env: cleanEnv, timeout: 1e4, encoding: "utf-8" }
|
|
3278
3309
|
);
|
|
3279
3310
|
if (scrollback && scrollback.length > 0) {
|
|
3280
|
-
|
|
3311
|
+
send(scrollback.replace(/\n/g, "\r\n"));
|
|
3281
3312
|
}
|
|
3282
3313
|
} catch {
|
|
3283
3314
|
}
|
|
3284
|
-
|
|
3315
|
+
send("\x1B[?1049l\x1B[0m\x1B[2J\x1B[H");
|
|
3285
3316
|
try {
|
|
3286
3317
|
const captureArgs = alternateScreen ? ["capture-pane", "-a", "-t", paneTarget, "-p", "-e"] : ["capture-pane", "-t", paneTarget, "-p", "-e"];
|
|
3287
3318
|
const initial = (0, import_node_child_process2.execFileSync)(
|
|
@@ -3290,7 +3321,7 @@ var SessionStreamer = class {
|
|
|
3290
3321
|
{ env: cleanEnv, timeout: 5e3, encoding: "utf-8" }
|
|
3291
3322
|
);
|
|
3292
3323
|
if (initial) {
|
|
3293
|
-
|
|
3324
|
+
send(stripAlternateScreenModeSwitches(initial.replace(/\n/g, "\r\n").replace(/\r\n$/, "")));
|
|
3294
3325
|
}
|
|
3295
3326
|
} catch {
|
|
3296
3327
|
}
|
|
@@ -3305,7 +3336,7 @@ var SessionStreamer = class {
|
|
|
3305
3336
|
const x = parseInt(parts[0], 10);
|
|
3306
3337
|
const y = parseInt(parts[1], 10);
|
|
3307
3338
|
if (!isNaN(x) && !isNaN(y)) {
|
|
3308
|
-
|
|
3339
|
+
send(`\x1B[${y + 1};${x + 1}H`);
|
|
3309
3340
|
}
|
|
3310
3341
|
}
|
|
3311
3342
|
} catch {
|
|
@@ -3359,7 +3390,8 @@ var SessionStreamer = class {
|
|
|
3359
3390
|
cleanEnv,
|
|
3360
3391
|
ptyProc: null,
|
|
3361
3392
|
straceProc: null,
|
|
3362
|
-
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8")
|
|
3393
|
+
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8"),
|
|
3394
|
+
altScreenStripper: new AlternateScreenModeStripper()
|
|
3363
3395
|
};
|
|
3364
3396
|
this.active.set(sessionId, stream);
|
|
3365
3397
|
try {
|
|
@@ -3383,13 +3415,19 @@ var SessionStreamer = class {
|
|
|
3383
3415
|
if (stream.initializing) {
|
|
3384
3416
|
stream.initBuffer.push(data);
|
|
3385
3417
|
} else {
|
|
3386
|
-
|
|
3418
|
+
const filtered = stream.altScreenStripper.write(data);
|
|
3419
|
+
if (filtered) this.sendFn(sessionId, filtered);
|
|
3387
3420
|
}
|
|
3388
3421
|
});
|
|
3389
3422
|
catProc.on("exit", () => {
|
|
3390
3423
|
if (!stream.stopped) {
|
|
3391
3424
|
const remaining = stream.utf8Decoder.end();
|
|
3392
|
-
if (remaining)
|
|
3425
|
+
if (remaining) {
|
|
3426
|
+
const filtered = stream.altScreenStripper.write(remaining);
|
|
3427
|
+
if (filtered) this.sendFn(sessionId, filtered);
|
|
3428
|
+
}
|
|
3429
|
+
const pending = stream.altScreenStripper.end();
|
|
3430
|
+
if (pending) this.sendFn(sessionId, pending);
|
|
3393
3431
|
this.cleanupStream(stream);
|
|
3394
3432
|
this.active.delete(sessionId);
|
|
3395
3433
|
this.pendingStops.delete(sessionId);
|
|
@@ -3485,7 +3523,8 @@ var SessionStreamer = class {
|
|
|
3485
3523
|
initBuffer: [],
|
|
3486
3524
|
ptyProc: proc,
|
|
3487
3525
|
straceProc: null,
|
|
3488
|
-
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8")
|
|
3526
|
+
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8"),
|
|
3527
|
+
altScreenStripper: new AlternateScreenModeStripper()
|
|
3489
3528
|
};
|
|
3490
3529
|
this.active.set(sessionId, stream);
|
|
3491
3530
|
proc.onData((data) => {
|
|
@@ -3538,7 +3577,8 @@ var SessionStreamer = class {
|
|
|
3538
3577
|
initBuffer: [],
|
|
3539
3578
|
ptyProc: proc,
|
|
3540
3579
|
straceProc: null,
|
|
3541
|
-
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8")
|
|
3580
|
+
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8"),
|
|
3581
|
+
altScreenStripper: new AlternateScreenModeStripper()
|
|
3542
3582
|
};
|
|
3543
3583
|
this.active.set(sessionId, stream);
|
|
3544
3584
|
proc.onData((data) => {
|
|
@@ -3603,7 +3643,8 @@ var SessionStreamer = class {
|
|
|
3603
3643
|
initBuffer: [],
|
|
3604
3644
|
ptyProc: null,
|
|
3605
3645
|
straceProc,
|
|
3606
|
-
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8")
|
|
3646
|
+
utf8Decoder: new import_node_string_decoder.StringDecoder("utf8"),
|
|
3647
|
+
altScreenStripper: new AlternateScreenModeStripper()
|
|
3607
3648
|
};
|
|
3608
3649
|
this.active.set(sessionId, stream);
|
|
3609
3650
|
const writeRegex = /^write\(([12]),\s*"((?:[^"\\]|\\.)*)"/;
|
|
@@ -5558,13 +5599,15 @@ var ControlDispatcher = class {
|
|
|
5558
5599
|
if (!sessionId) return;
|
|
5559
5600
|
const ws = this.connection.activeSocket;
|
|
5560
5601
|
const group = this.connection.activeGroups.privateGroup;
|
|
5602
|
+
const viewerKey = viewerId?.trim() || "";
|
|
5561
5603
|
if (sessionId.startsWith("tmux:") || sessionId.startsWith("screen:") || sessionId.startsWith("zellij:") || sessionId.startsWith("process:")) {
|
|
5562
5604
|
const alreadyStreaming = this.streamer.isStreaming(sessionId);
|
|
5605
|
+
const viewerAlreadyAttached = alreadyStreaming && this.streamer.hasViewer(sessionId, viewerKey);
|
|
5563
5606
|
const started = this.streamer.startStream(sessionId, viewerId ?? void 0);
|
|
5564
5607
|
if (ws && ws.readyState === import_ws4.default.OPEN && group) {
|
|
5565
5608
|
if (started) {
|
|
5566
|
-
if (alreadyStreaming) {
|
|
5567
|
-
this.streamer.resyncStream(sessionId);
|
|
5609
|
+
if (alreadyStreaming && !viewerAlreadyAttached) {
|
|
5610
|
+
this.streamer.resyncStream(sessionId, viewerKey);
|
|
5568
5611
|
}
|
|
5569
5612
|
const dims = this.queryPaneDimensions(sessionId);
|
|
5570
5613
|
sendToGroup(ws, group, { type: "stream-started", sessionId, ...dims });
|
|
@@ -6033,7 +6076,7 @@ async function runAgent(rawOptions) {
|
|
|
6033
6076
|
const outputBuffer = new OutputBuffer();
|
|
6034
6077
|
const ptySessionId = `pty:${options.hostId}`;
|
|
6035
6078
|
const sessionStreamer = new SessionStreamer(
|
|
6036
|
-
(sessionId, data) => {
|
|
6079
|
+
(sessionId, data, viewerId) => {
|
|
6037
6080
|
conn.requestInventorySync();
|
|
6038
6081
|
if (!conn.isReady()) {
|
|
6039
6082
|
sessionStreamer.bufferOutput(sessionId, data);
|
|
@@ -6041,11 +6084,12 @@ async function runAgent(rawOptions) {
|
|
|
6041
6084
|
}
|
|
6042
6085
|
const redactedData = redactStreamingChunk(sessionId, data);
|
|
6043
6086
|
for (const chunk of splitTransportChunks(redactedData)) {
|
|
6087
|
+
const outputPayload = viewerId ? { type: "output", sessionId, viewerId } : { type: "output", sessionId };
|
|
6044
6088
|
if (conn.sessionKey) {
|
|
6045
6089
|
const { enc, iv, seq } = encryptPayload(chunk, conn.sessionKey, conn.txSeq.next());
|
|
6046
|
-
sendToGroup(conn.activeSocket, conn.activeGroups.privateGroup, {
|
|
6090
|
+
sendToGroup(conn.activeSocket, conn.activeGroups.privateGroup, { ...outputPayload, enc, iv, seq });
|
|
6047
6091
|
} else {
|
|
6048
|
-
sendToGroup(conn.activeSocket, conn.activeGroups.privateGroup, {
|
|
6092
|
+
sendToGroup(conn.activeSocket, conn.activeGroups.privateGroup, { ...outputPayload, data: chunk });
|
|
6049
6093
|
}
|
|
6050
6094
|
}
|
|
6051
6095
|
},
|
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.9",
|
|
1170
|
+
"bom-ref": "ragent-live|ragent-cli@1.11.9",
|
|
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.9",
|
|
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.9"
|
|
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.9",
|
|
1440
1440
|
"dependsOn": [
|
|
1441
1441
|
"ragent-live|@azure/web-pubsub-client@1.0.4",
|
|
1442
1442
|
"ragent-live|commander@14.0.3",
|