ragent-cli 1.7.3 → 1.8.0
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 +80 -11
- package/package.json +2 -2
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.
|
|
34
|
+
version: "1.8.0",
|
|
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: {
|
|
@@ -89,7 +89,7 @@ var require_package = __commonJS({
|
|
|
89
89
|
"@changesets/cli": "^2.29.8",
|
|
90
90
|
"@eslint/js": "^10.0.1",
|
|
91
91
|
"@types/figlet": "^1.7.0",
|
|
92
|
-
"@types/node": "^
|
|
92
|
+
"@types/node": "^20.17.0",
|
|
93
93
|
"@types/ws": "^8.5.13",
|
|
94
94
|
eslint: "^10.0.2",
|
|
95
95
|
tsup: "^8.4.0",
|
|
@@ -950,7 +950,7 @@ var SECRET_PATTERNS = [
|
|
|
950
950
|
/eyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g
|
|
951
951
|
// JWT
|
|
952
952
|
];
|
|
953
|
-
var redactionEnabled =
|
|
953
|
+
var redactionEnabled = true;
|
|
954
954
|
function setRedactionEnabled(enabled) {
|
|
955
955
|
redactionEnabled = enabled;
|
|
956
956
|
}
|
|
@@ -1045,6 +1045,7 @@ var import_node_os = require("os");
|
|
|
1045
1045
|
var import_node_string_decoder = require("string_decoder");
|
|
1046
1046
|
var pty = __toESM(require("node-pty"));
|
|
1047
1047
|
var STOP_DEBOUNCE_MS = 2e3;
|
|
1048
|
+
var MAX_CONCURRENT_STREAMS = 20;
|
|
1048
1049
|
var MAX_SESSION_BUFFER_BYTES = 64 * 1024;
|
|
1049
1050
|
function parsePaneTarget(sessionId) {
|
|
1050
1051
|
if (!sessionId.startsWith("tmux:")) return null;
|
|
@@ -1151,6 +1152,12 @@ var SessionStreamer = class {
|
|
|
1151
1152
|
if (this.active.has(sessionId)) {
|
|
1152
1153
|
return true;
|
|
1153
1154
|
}
|
|
1155
|
+
if (this.active.size >= MAX_CONCURRENT_STREAMS) {
|
|
1156
|
+
console.warn(
|
|
1157
|
+
`[rAgent] Stream limit reached (${MAX_CONCURRENT_STREAMS}). Rejecting: ${sessionId}`
|
|
1158
|
+
);
|
|
1159
|
+
return false;
|
|
1160
|
+
}
|
|
1154
1161
|
if (sessionId.startsWith("tmux:")) {
|
|
1155
1162
|
return this.startTmuxStream(sessionId);
|
|
1156
1163
|
}
|
|
@@ -2702,6 +2709,10 @@ var ControlDispatcher = class {
|
|
|
2702
2709
|
console.warn("[rAgent] Control message missing HMAC signature.");
|
|
2703
2710
|
return false;
|
|
2704
2711
|
}
|
|
2712
|
+
if (!/^[0-9a-f]{64}$/i.test(receivedHmac)) {
|
|
2713
|
+
console.warn("[rAgent] Control message has malformed HMAC signature.");
|
|
2714
|
+
return false;
|
|
2715
|
+
}
|
|
2705
2716
|
const { hmac: _, ...payloadWithoutHmac } = payload;
|
|
2706
2717
|
const canonical = JSON.stringify(payloadWithoutHmac, Object.keys(payloadWithoutHmac).sort());
|
|
2707
2718
|
const expected = crypto2.createHmac("sha256", sessionKey).update(canonical).digest("hex");
|
|
@@ -2718,7 +2729,9 @@ var ControlDispatcher = class {
|
|
|
2718
2729
|
"stop-session",
|
|
2719
2730
|
"stop-detached",
|
|
2720
2731
|
"disconnect",
|
|
2721
|
-
"kill-process"
|
|
2732
|
+
"kill-process",
|
|
2733
|
+
"start-agent",
|
|
2734
|
+
"provision"
|
|
2722
2735
|
]);
|
|
2723
2736
|
if (dangerousActions.has(action) && this.connection.sessionKey) {
|
|
2724
2737
|
if (!this.verifyMessageHmac(payload)) {
|
|
@@ -2798,6 +2811,9 @@ var ControlDispatcher = class {
|
|
|
2798
2811
|
case "start-agent":
|
|
2799
2812
|
await this.handleStartAgent(payload);
|
|
2800
2813
|
return;
|
|
2814
|
+
case "provision":
|
|
2815
|
+
await this.handleProvision(payload);
|
|
2816
|
+
return;
|
|
2801
2817
|
case "stream-session":
|
|
2802
2818
|
this.handleStreamSession(sessionId);
|
|
2803
2819
|
return;
|
|
@@ -2837,8 +2853,11 @@ var ControlDispatcher = class {
|
|
|
2837
2853
|
}
|
|
2838
2854
|
/** Handle provision request from dashboard. */
|
|
2839
2855
|
async handleProvision(payload) {
|
|
2840
|
-
const provReq = payload;
|
|
2841
|
-
if (!provReq
|
|
2856
|
+
const provReq = validateProvisionRequest(payload);
|
|
2857
|
+
if (!provReq) {
|
|
2858
|
+
console.warn("[rAgent] Rejecting provision request \u2014 malformed payload.");
|
|
2859
|
+
return;
|
|
2860
|
+
}
|
|
2842
2861
|
console.log(`[rAgent] Provision request: ${provReq.manifest.name} (${provReq.provisionId})`);
|
|
2843
2862
|
const sendProgress = (progress) => {
|
|
2844
2863
|
const ws = this.connection.activeSocket;
|
|
@@ -2980,6 +2999,56 @@ var ControlDispatcher = class {
|
|
|
2980
2999
|
}
|
|
2981
3000
|
}
|
|
2982
3001
|
};
|
|
3002
|
+
var VALID_INSTALL_METHODS = /* @__PURE__ */ new Set(["npm", "pip", "binary", "custom"]);
|
|
3003
|
+
var VALID_RUNTIMES = /* @__PURE__ */ new Set(["node", "python", "none"]);
|
|
3004
|
+
function validateProvisionRequest(payload) {
|
|
3005
|
+
if (typeof payload.provisionId !== "string" || !payload.provisionId) return null;
|
|
3006
|
+
if (typeof payload.sessionName !== "string" || !payload.sessionName) return null;
|
|
3007
|
+
if (typeof payload.command !== "string" || !payload.command) return null;
|
|
3008
|
+
const manifest = payload.manifest;
|
|
3009
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) return null;
|
|
3010
|
+
const m = manifest;
|
|
3011
|
+
if (typeof m.id !== "string" || !m.id) return null;
|
|
3012
|
+
if (typeof m.name !== "string" || !m.name) return null;
|
|
3013
|
+
if (typeof m.installMethod !== "string" || !VALID_INSTALL_METHODS.has(m.installMethod)) return null;
|
|
3014
|
+
if (typeof m.installCommand !== "string") return null;
|
|
3015
|
+
if (typeof m.checkCommand !== "string") return null;
|
|
3016
|
+
let prerequisites;
|
|
3017
|
+
if (m.prerequisites !== void 0 && m.prerequisites !== null) {
|
|
3018
|
+
if (typeof m.prerequisites !== "object" || Array.isArray(m.prerequisites)) return null;
|
|
3019
|
+
const p = m.prerequisites;
|
|
3020
|
+
if (typeof p.runtime !== "string" || !VALID_RUNTIMES.has(p.runtime)) return null;
|
|
3021
|
+
prerequisites = {
|
|
3022
|
+
runtime: p.runtime,
|
|
3023
|
+
minVersion: typeof p.minVersion === "string" ? p.minVersion : void 0
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
if (payload.workingDir !== void 0 && typeof payload.workingDir !== "string") return null;
|
|
3027
|
+
if (payload.envVars !== void 0 && (typeof payload.envVars !== "object" || payload.envVars === null || Array.isArray(payload.envVars))) return null;
|
|
3028
|
+
let validatedEnvVars;
|
|
3029
|
+
if (payload.envVars && typeof payload.envVars === "object") {
|
|
3030
|
+
const entries = Object.entries(payload.envVars);
|
|
3031
|
+
for (const [, v] of entries) {
|
|
3032
|
+
if (typeof v !== "string") return null;
|
|
3033
|
+
}
|
|
3034
|
+
validatedEnvVars = payload.envVars;
|
|
3035
|
+
}
|
|
3036
|
+
return {
|
|
3037
|
+
provisionId: payload.provisionId,
|
|
3038
|
+
sessionName: payload.sessionName,
|
|
3039
|
+
command: payload.command,
|
|
3040
|
+
workingDir: typeof payload.workingDir === "string" ? payload.workingDir : void 0,
|
|
3041
|
+
envVars: validatedEnvVars,
|
|
3042
|
+
manifest: {
|
|
3043
|
+
id: m.id,
|
|
3044
|
+
name: m.name,
|
|
3045
|
+
installMethod: m.installMethod,
|
|
3046
|
+
installCommand: m.installCommand,
|
|
3047
|
+
checkCommand: m.checkCommand,
|
|
3048
|
+
prerequisites
|
|
3049
|
+
}
|
|
3050
|
+
};
|
|
3051
|
+
}
|
|
2983
3052
|
|
|
2984
3053
|
// src/transcript-watcher.ts
|
|
2985
3054
|
var fs3 = __toESM(require("fs"));
|
|
@@ -3576,9 +3645,9 @@ async function runAgent(rawOptions) {
|
|
|
3576
3645
|
}
|
|
3577
3646
|
const lockPath = acquirePidLock(options.hostId);
|
|
3578
3647
|
const config = loadConfig();
|
|
3579
|
-
if (config.redaction?.enabled) {
|
|
3580
|
-
setRedactionEnabled(
|
|
3581
|
-
console.log("[rAgent] Secret redaction
|
|
3648
|
+
if (config.redaction?.enabled === false || rawOptions.redact === false) {
|
|
3649
|
+
setRedactionEnabled(false);
|
|
3650
|
+
console.log("[rAgent] Secret redaction disabled.");
|
|
3582
3651
|
}
|
|
3583
3652
|
console.log(`[rAgent] Connector started for ${options.hostName} (${options.hostId})`);
|
|
3584
3653
|
console.log(`[rAgent] Portal: ${options.portal}`);
|
|
@@ -3763,7 +3832,7 @@ async function runAgent(rawOptions) {
|
|
|
3763
3832
|
} else if (payload.type === "start-agent") {
|
|
3764
3833
|
await dispatcher.handleControlAction({ ...payload, action: "start-agent" });
|
|
3765
3834
|
} else if (payload.type === "provision") {
|
|
3766
|
-
await dispatcher.
|
|
3835
|
+
await dispatcher.handleControlAction({ ...payload, action: "provision" });
|
|
3767
3836
|
}
|
|
3768
3837
|
}
|
|
3769
3838
|
if (msg.type === "message" && msg.group === groups.registryGroup) {
|
|
@@ -3985,7 +4054,7 @@ function registerConnectCommand(program2) {
|
|
|
3985
4054
|
|
|
3986
4055
|
// src/commands/run.ts
|
|
3987
4056
|
function registerRunCommand(program2) {
|
|
3988
|
-
program2.command("run").description("Run connector for a connected machine").option("--portal <url>", "Portal base URL").option("--agent-token <token>", "Connector token").option("-i, --id <id>", "Machine ID").option("-n, --name <name>", "Machine name").option("-c, --command <command>", "CLI command to run").action(async (opts) => {
|
|
4057
|
+
program2.command("run").description("Run connector for a connected machine").option("--portal <url>", "Portal base URL").option("--agent-token <token>", "Connector token").option("-i, --id <id>", "Machine ID").option("-n, --name <name>", "Machine name").option("-c, --command <command>", "CLI command to run").option("--no-redact", "Disable secret redaction in terminal output").action(async (opts) => {
|
|
3989
4058
|
try {
|
|
3990
4059
|
printCommandArt("Run Connector", "streaming terminal session to portal");
|
|
3991
4060
|
await runAgent(opts);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ragent-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "CLI agent for rAgent Live — browser-first terminal control plane for AI coding agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@changesets/cli": "^2.29.8",
|
|
59
59
|
"@eslint/js": "^10.0.1",
|
|
60
60
|
"@types/figlet": "^1.7.0",
|
|
61
|
-
"@types/node": "^
|
|
61
|
+
"@types/node": "^20.17.0",
|
|
62
62
|
"@types/ws": "^8.5.13",
|
|
63
63
|
"eslint": "^10.0.2",
|
|
64
64
|
"tsup": "^8.4.0",
|