@clawrent/cli 0.2.0 → 0.2.2
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 +139 -97
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +2 -0
- package/dist/lib.js +4 -0
- package/dist/lib.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -167,6 +167,10 @@ var ApiClient = class {
|
|
|
167
167
|
const qs = params.toString();
|
|
168
168
|
return this.request("GET", `/api/agents/my${qs ? `?${qs}` : ""}`);
|
|
169
169
|
}
|
|
170
|
+
/** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */
|
|
171
|
+
async getMyAgent() {
|
|
172
|
+
return this.request("GET", "/api/agents/me/agent");
|
|
173
|
+
}
|
|
170
174
|
async publishAgent(agentId) {
|
|
171
175
|
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/publish`);
|
|
172
176
|
}
|
|
@@ -691,34 +695,34 @@ function registerProviderCommands(program2) {
|
|
|
691
695
|
import WebSocket3 from "ws";
|
|
692
696
|
|
|
693
697
|
// src/daemon.ts
|
|
694
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, openSync, closeSync, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
|
|
695
|
-
import { join as join2 } from "path";
|
|
698
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, openSync, closeSync, mkdirSync as mkdirSync2, existsSync as existsSync2, readdirSync } from "fs";
|
|
699
|
+
import { join as join2, basename } from "path";
|
|
696
700
|
import { spawn } from "child_process";
|
|
697
|
-
function getPidFilePath() {
|
|
698
|
-
return join2(getConfigDir(),
|
|
701
|
+
function getPidFilePath(agentId) {
|
|
702
|
+
return join2(getConfigDir(), `serve-${agentId}.pid`);
|
|
699
703
|
}
|
|
700
|
-
function getLogFilePath() {
|
|
701
|
-
return join2(getConfigDir(),
|
|
704
|
+
function getLogFilePath(agentId) {
|
|
705
|
+
return join2(getConfigDir(), `serve-${agentId}.log`);
|
|
702
706
|
}
|
|
703
|
-
function readPid() {
|
|
707
|
+
function readPid(agentId) {
|
|
704
708
|
try {
|
|
705
|
-
const content = readFileSync2(getPidFilePath(), "utf-8").trim();
|
|
709
|
+
const content = readFileSync2(getPidFilePath(agentId), "utf-8").trim();
|
|
706
710
|
const pid = parseInt(content, 10);
|
|
707
711
|
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
708
712
|
} catch {
|
|
709
713
|
return null;
|
|
710
714
|
}
|
|
711
715
|
}
|
|
712
|
-
function writePid(pid) {
|
|
716
|
+
function writePid(agentId, pid) {
|
|
713
717
|
const dir = getConfigDir();
|
|
714
718
|
if (!existsSync2(dir)) {
|
|
715
719
|
mkdirSync2(dir, { recursive: true });
|
|
716
720
|
}
|
|
717
|
-
writeFileSync2(getPidFilePath(), String(pid), "utf-8");
|
|
721
|
+
writeFileSync2(getPidFilePath(agentId), String(pid), "utf-8");
|
|
718
722
|
}
|
|
719
|
-
function removePidFile() {
|
|
723
|
+
function removePidFile(agentId) {
|
|
720
724
|
try {
|
|
721
|
-
unlinkSync2(getPidFilePath());
|
|
725
|
+
unlinkSync2(getPidFilePath(agentId));
|
|
722
726
|
} catch {
|
|
723
727
|
}
|
|
724
728
|
}
|
|
@@ -730,17 +734,32 @@ function isProcessAlive(pid) {
|
|
|
730
734
|
return false;
|
|
731
735
|
}
|
|
732
736
|
}
|
|
733
|
-
function isDaemonRunning() {
|
|
734
|
-
const pid = readPid();
|
|
737
|
+
function isDaemonRunning(agentId) {
|
|
738
|
+
const pid = readPid(agentId);
|
|
735
739
|
if (pid === null) return { running: false, pid: null };
|
|
736
740
|
if (isProcessAlive(pid)) {
|
|
737
741
|
return { running: true, pid };
|
|
738
742
|
}
|
|
739
|
-
removePidFile();
|
|
743
|
+
removePidFile(agentId);
|
|
740
744
|
return { running: false, pid: null };
|
|
741
745
|
}
|
|
742
|
-
function
|
|
743
|
-
const
|
|
746
|
+
function listRunningDaemons() {
|
|
747
|
+
const dir = getConfigDir();
|
|
748
|
+
if (!existsSync2(dir)) return [];
|
|
749
|
+
const results = [];
|
|
750
|
+
for (const file of readdirSync(dir)) {
|
|
751
|
+
const match = /^serve-(.+)\.pid$/.exec(basename(file));
|
|
752
|
+
if (!match) continue;
|
|
753
|
+
const agentId = match[1];
|
|
754
|
+
const { running, pid } = isDaemonRunning(agentId);
|
|
755
|
+
if (running && pid !== null) {
|
|
756
|
+
results.push({ agentId, pid });
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
return results;
|
|
760
|
+
}
|
|
761
|
+
function spawnDaemon(agentId, args) {
|
|
762
|
+
const logFile = getLogFilePath(agentId);
|
|
744
763
|
const dir = getConfigDir();
|
|
745
764
|
if (!existsSync2(dir)) {
|
|
746
765
|
mkdirSync2(dir, { recursive: true });
|
|
@@ -951,22 +970,32 @@ var pendingInstructions = /* @__PURE__ */ new Map();
|
|
|
951
970
|
var knownPendingSessions = /* @__PURE__ */ new Set();
|
|
952
971
|
var activeSessions = /* @__PURE__ */ new Set();
|
|
953
972
|
function registerServeCommand(program2) {
|
|
954
|
-
program2.command("serve").description("Start serve daemon - bridge WebSocket sessions to stdin/stdout").requiredOption("--agent-
|
|
973
|
+
program2.command("serve").description("Start serve daemon - bridge WebSocket sessions to stdin/stdout").requiredOption("--agent-token <token>", "Agent token (agt_clawrent_*) for authentication").option("--auto-approve", "Automatically approve incoming sessions", false).option("--poll-interval <ms>", "Polling interval for pending sessions (ms)", "5000").option("-d, --daemon", "Run in background as a daemon process", false).action(async (opts) => {
|
|
955
974
|
try {
|
|
956
975
|
if (opts.daemon) {
|
|
957
|
-
const
|
|
976
|
+
const config = loadConfig();
|
|
977
|
+
config.token = opts.agentToken;
|
|
978
|
+
const client = new ApiClient(config);
|
|
979
|
+
let agentId;
|
|
980
|
+
try {
|
|
981
|
+
const agent = await client.getMyAgent();
|
|
982
|
+
agentId = agent["id"];
|
|
983
|
+
} catch {
|
|
984
|
+
printError("Failed to resolve agent from token. Is the token valid?");
|
|
985
|
+
process.exit(1);
|
|
986
|
+
}
|
|
987
|
+
const { running, pid: existingPid } = isDaemonRunning(agentId);
|
|
958
988
|
if (running) {
|
|
959
|
-
printError(`Daemon already running (PID: ${existingPid}). Use 'clawrent stop' first.`);
|
|
989
|
+
printError(`Daemon already running for agent ${agentId} (PID: ${existingPid}). Use 'clawrent stop --agent-id ${agentId}' first.`);
|
|
960
990
|
process.exit(1);
|
|
961
991
|
}
|
|
962
|
-
const args = ["serve", "--agent-
|
|
963
|
-
if (opts.agentToken) args.push("--agent-token", opts.agentToken);
|
|
992
|
+
const args = ["serve", "--agent-token", opts.agentToken];
|
|
964
993
|
if (opts.autoApprove) args.push("--auto-approve");
|
|
965
994
|
if (opts.pollInterval !== "5000") args.push("--poll-interval", opts.pollInterval);
|
|
966
|
-
const pid = spawnDaemon(args);
|
|
967
|
-
writePid(pid);
|
|
968
|
-
printSuccess(`Daemon started (PID: ${pid})
|
|
969
|
-
Logs: ${getLogFilePath()}`);
|
|
995
|
+
const pid = spawnDaemon(agentId, args);
|
|
996
|
+
writePid(agentId, pid);
|
|
997
|
+
printSuccess(`Daemon started for agent ${agentId} (PID: ${pid})
|
|
998
|
+
Logs: ${getLogFilePath(agentId)}`);
|
|
970
999
|
process.exit(0);
|
|
971
1000
|
}
|
|
972
1001
|
await runDaemon(opts);
|
|
@@ -978,34 +1007,26 @@ Logs: ${getLogFilePath()}`);
|
|
|
978
1007
|
}
|
|
979
1008
|
async function runDaemon(opts) {
|
|
980
1009
|
const config = loadConfig();
|
|
1010
|
+
config.token = opts.agentToken;
|
|
981
1011
|
const client = new ApiClient(config);
|
|
982
1012
|
const bridge = new StdioBridge();
|
|
983
1013
|
const sessionManager = new SessionManager(config.wsUrl);
|
|
984
|
-
sessionManager.agentId = opts.agentId;
|
|
985
1014
|
const pollInterval = parseInt(opts.pollInterval, 10);
|
|
986
1015
|
let agentWs = null;
|
|
987
1016
|
let agentHeartbeatTimer = null;
|
|
988
|
-
let
|
|
1017
|
+
let agentId;
|
|
1018
|
+
let agentName;
|
|
989
1019
|
try {
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
if (!opts.agentToken) {
|
|
995
|
-
const status = agent["status"];
|
|
996
|
-
if (status === "draft") {
|
|
997
|
-
await client.publishAgent(opts.agentId);
|
|
998
|
-
await client.activateAgent(opts.agentId);
|
|
999
|
-
} else if (status === "pending_review") {
|
|
1000
|
-
await client.activateAgent(opts.agentId);
|
|
1001
|
-
}
|
|
1002
|
-
await client.setOnlineStatus(opts.agentId, "online");
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1020
|
+
const agent = await client.getMyAgent();
|
|
1021
|
+
agentId = agent["id"];
|
|
1022
|
+
agentName = agent["name"] ?? agentId;
|
|
1023
|
+
sessionManager.agentId = agentId;
|
|
1005
1024
|
} catch {
|
|
1025
|
+
printError("Failed to resolve agent from token. Is the token valid?");
|
|
1026
|
+
process.exit(1);
|
|
1006
1027
|
}
|
|
1007
1028
|
bridge.writeNotification("ready", {
|
|
1008
|
-
agentId
|
|
1029
|
+
agentId,
|
|
1009
1030
|
agentName
|
|
1010
1031
|
});
|
|
1011
1032
|
sessionManager.on("session:connected", (sessionId) => {
|
|
@@ -1098,7 +1119,7 @@ async function runDaemon(opts) {
|
|
|
1098
1119
|
const url = `${wsBase}/ws/agent?token=${token}`;
|
|
1099
1120
|
agentWs = new WebSocket3(url);
|
|
1100
1121
|
agentWs.on("open", () => {
|
|
1101
|
-
bridge.writeNotification("agent.connected", { agentId
|
|
1122
|
+
bridge.writeNotification("agent.connected", { agentId });
|
|
1102
1123
|
agentHeartbeatTimer = setInterval(() => {
|
|
1103
1124
|
if (agentWs && agentWs.readyState === WebSocket3.OPEN) {
|
|
1104
1125
|
agentWs.send(JSON.stringify({ type: "system.heartbeat", payload: {} }));
|
|
@@ -1147,7 +1168,7 @@ async function runDaemon(opts) {
|
|
|
1147
1168
|
agentHeartbeatTimer = null;
|
|
1148
1169
|
}
|
|
1149
1170
|
bridge.writeNotification("agent.disconnected", {
|
|
1150
|
-
agentId
|
|
1171
|
+
agentId,
|
|
1151
1172
|
code,
|
|
1152
1173
|
reason: reason.toString()
|
|
1153
1174
|
});
|
|
@@ -1186,11 +1207,7 @@ async function runDaemon(opts) {
|
|
|
1186
1207
|
}
|
|
1187
1208
|
}, pollInterval);
|
|
1188
1209
|
}
|
|
1189
|
-
|
|
1190
|
-
connectAgentWs(opts.agentToken);
|
|
1191
|
-
} else {
|
|
1192
|
-
startPollLoop();
|
|
1193
|
-
}
|
|
1210
|
+
connectAgentWs(opts.agentToken);
|
|
1194
1211
|
const shutdown = async () => {
|
|
1195
1212
|
if (pollTimer) clearInterval(pollTimer);
|
|
1196
1213
|
if (agentHeartbeatTimer) clearInterval(agentHeartbeatTimer);
|
|
@@ -1202,12 +1219,6 @@ async function runDaemon(opts) {
|
|
|
1202
1219
|
}
|
|
1203
1220
|
agentWs = null;
|
|
1204
1221
|
}
|
|
1205
|
-
if (!opts.agentToken) {
|
|
1206
|
-
try {
|
|
1207
|
-
await client.setOnlineStatus(opts.agentId, "offline");
|
|
1208
|
-
} catch {
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
1222
|
sessionManager.disconnectAll();
|
|
1212
1223
|
bridge.writeNotification("shutdown", { reason: "signal" });
|
|
1213
1224
|
setTimeout(() => process.exit(0), 500);
|
|
@@ -1241,57 +1252,88 @@ async function approveAndConnect(client, sessionManager, bridge, sessionId) {
|
|
|
1241
1252
|
}
|
|
1242
1253
|
|
|
1243
1254
|
// src/commands/stop.ts
|
|
1244
|
-
function
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1255
|
+
async function stopOne(agentId) {
|
|
1256
|
+
const { running, pid } = isDaemonRunning(agentId);
|
|
1257
|
+
if (!running || pid === null) {
|
|
1258
|
+
return false;
|
|
1259
|
+
}
|
|
1260
|
+
try {
|
|
1261
|
+
process.kill(pid, "SIGTERM");
|
|
1262
|
+
} catch (err) {
|
|
1263
|
+
const code = err.code;
|
|
1264
|
+
if (code === "ESRCH") {
|
|
1265
|
+
removePidFile(agentId);
|
|
1266
|
+
return true;
|
|
1250
1267
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
const code = err.code;
|
|
1255
|
-
if (code === "ESRCH") {
|
|
1256
|
-
removePidFile();
|
|
1257
|
-
printSuccess("Daemon already stopped.");
|
|
1258
|
-
return;
|
|
1259
|
-
}
|
|
1260
|
-
if (code === "EPERM") {
|
|
1261
|
-
printError(`Permission denied. Cannot stop daemon (PID: ${pid}).`);
|
|
1262
|
-
process.exit(1);
|
|
1263
|
-
}
|
|
1264
|
-
throw err;
|
|
1268
|
+
if (code === "EPERM") {
|
|
1269
|
+
printError(`Permission denied. Cannot stop daemon for agent ${agentId} (PID: ${pid}).`);
|
|
1270
|
+
return false;
|
|
1265
1271
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1272
|
+
throw err;
|
|
1273
|
+
}
|
|
1274
|
+
const maxWait = 3e3;
|
|
1275
|
+
const interval = 200;
|
|
1276
|
+
let waited = 0;
|
|
1277
|
+
while (waited < maxWait) {
|
|
1278
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
1279
|
+
waited += interval;
|
|
1280
|
+
if (!isProcessAlive(pid)) {
|
|
1281
|
+
removePidFile(agentId);
|
|
1282
|
+
printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);
|
|
1283
|
+
return true;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
try {
|
|
1287
|
+
process.kill(pid, "SIGKILL");
|
|
1288
|
+
} catch {
|
|
1289
|
+
}
|
|
1290
|
+
removePidFile(agentId);
|
|
1291
|
+
printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);
|
|
1292
|
+
return true;
|
|
1293
|
+
}
|
|
1294
|
+
function registerStopCommand(program2) {
|
|
1295
|
+
program2.command("stop").description("Stop background serve daemon(s)").option("--agent-id <id>", "Stop daemon for a specific agent").option("--all", "Stop all running daemons", false).action(async (opts) => {
|
|
1296
|
+
if (opts.agentId) {
|
|
1297
|
+
const stopped = await stopOne(opts.agentId);
|
|
1298
|
+
if (!stopped) {
|
|
1299
|
+
printSuccess(`No daemon running for agent ${opts.agentId}.`);
|
|
1276
1300
|
}
|
|
1301
|
+
return;
|
|
1277
1302
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1303
|
+
const daemons = listRunningDaemons();
|
|
1304
|
+
if (daemons.length === 0) {
|
|
1305
|
+
printSuccess("No daemons are running.");
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
for (const d of daemons) {
|
|
1309
|
+
await stopOne(d.agentId);
|
|
1281
1310
|
}
|
|
1282
|
-
removePidFile();
|
|
1283
|
-
printSuccess(`Daemon stopped (PID: ${pid}).`);
|
|
1284
1311
|
});
|
|
1285
1312
|
}
|
|
1286
1313
|
|
|
1287
1314
|
// src/commands/status.ts
|
|
1288
1315
|
function registerStatusCommand(program2) {
|
|
1289
|
-
program2.command("status").description("Check
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1316
|
+
program2.command("status").description("Check running serve daemon(s)").option("--agent-id <id>", "Check daemon for a specific agent").action((opts) => {
|
|
1317
|
+
if (opts.agentId) {
|
|
1318
|
+
const { running, pid } = isDaemonRunning(opts.agentId);
|
|
1319
|
+
if (running && pid !== null) {
|
|
1320
|
+
printJson({ status: "running", agentId: opts.agentId, pid, logFile: getLogFilePath(opts.agentId) });
|
|
1321
|
+
} else {
|
|
1322
|
+
printJson({ status: "stopped", agentId: opts.agentId });
|
|
1323
|
+
}
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
const daemons = listRunningDaemons();
|
|
1327
|
+
if (daemons.length === 0) {
|
|
1328
|
+
printJson({ daemons: [] });
|
|
1293
1329
|
} else {
|
|
1294
|
-
printJson({
|
|
1330
|
+
printJson({
|
|
1331
|
+
daemons: daemons.map((d) => ({
|
|
1332
|
+
agentId: d.agentId,
|
|
1333
|
+
pid: d.pid,
|
|
1334
|
+
logFile: getLogFilePath(d.agentId)
|
|
1335
|
+
}))
|
|
1336
|
+
});
|
|
1295
1337
|
}
|
|
1296
1338
|
});
|
|
1297
1339
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/api-client.ts","../src/output.ts","../src/commands/browse.ts","../src/commands/agent.ts","../src/commands/sessions.ts","../src/commands/balance.ts","../src/commands/topup.ts","../src/commands/health.ts","../src/commands/rent.ts","../src/commands/end.ts","../src/commands/send.ts","../src/commands/provider/index.ts","../src/serve/index.ts","../src/daemon.ts","../src/serve/stdio-bridge.ts","../src/serve/session-manager.ts","../src/serve/protocol.ts","../src/commands/stop.ts","../src/commands/status.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\r\nimport { dirname, join } from 'node:path';\r\nimport { fileURLToPath } from 'node:url';\r\nimport { Command } from 'commander';\r\nimport { registerAuthCommand } from './commands/auth.js';\r\nimport { registerBrowseCommand } from './commands/browse.js';\r\nimport { registerAgentCommand } from './commands/agent.js';\r\nimport { registerSessionsCommand } from './commands/sessions.js';\r\nimport { registerBalanceCommand } from './commands/balance.js';\r\nimport { registerTopupCommand } from './commands/topup.js';\r\nimport { registerHealthCommand } from './commands/health.js';\r\nimport { registerRentCommand } from './commands/rent.js';\r\nimport { registerEndCommand } from './commands/end.js';\r\nimport { registerSendCommand } from './commands/send.js';\r\nimport { registerProviderCommands } from './commands/provider/index.js';\r\nimport { registerServeCommand } from './serve/index.js';\r\nimport { registerStopCommand } from './commands/stop.js';\r\nimport { registerStatusCommand } from './commands/status.js';\r\n\r\nconst __dirname = dirname(fileURLToPath(import.meta.url));\r\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('clawrent')\r\n .description('ClawRent CLI - Agent capability rental platform')\r\n .version(pkg.version);\r\n\r\n// Auth\r\nregisterAuthCommand(program);\r\n\r\n// Consumer commands\r\nregisterBrowseCommand(program);\r\nregisterAgentCommand(program);\r\nregisterSessionsCommand(program);\r\nregisterBalanceCommand(program);\r\nregisterTopupCommand(program);\r\nregisterRentCommand(program);\r\nregisterEndCommand(program);\r\nregisterSendCommand(program);\r\nregisterHealthCommand(program);\r\n\r\n// Provider commands\r\nregisterProviderCommands(program);\r\n\r\n// Serve daemon\r\nregisterServeCommand(program);\r\n\r\n// Daemon management\r\nregisterStopCommand(program);\r\nregisterStatusCommand(program);\r\n\r\nprogram.parse();\r\n","import { Command } from 'commander';\r\nimport { createInterface } from 'node:readline';\r\nimport { loadConfig, saveConfig, clearConfig, getConfigPath } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../output.js';\r\n\r\nfunction deriveWsUrl(apiUrl: string): string {\r\n return apiUrl.replace(/^http/, 'ws');\r\n}\r\n\r\nasync function promptInput(prompt: string, hidden: boolean = false): Promise<string> {\r\n const rl = createInterface({ input: process.stdin, output: process.stderr });\r\n\r\n return new Promise((resolve) => {\r\n if (hidden) {\r\n // For password: write prompt manually, mute output\r\n process.stderr.write(prompt);\r\n const stdin = process.stdin;\r\n const wasRaw = stdin.isRaw;\r\n if (stdin.isTTY) stdin.setRawMode(true);\r\n let input = '';\r\n const onData = (ch: Buffer) => {\r\n const c = ch.toString('utf-8');\r\n if (c === '\\n' || c === '\\r') {\r\n stdin.removeListener('data', onData);\r\n if (stdin.isTTY && wasRaw !== undefined) stdin.setRawMode(wasRaw);\r\n process.stderr.write('\\n');\r\n rl.close();\r\n resolve(input);\r\n } else if (c === '\\u0003') {\r\n // Ctrl+C\r\n rl.close();\r\n process.exit(1);\r\n } else if (c === '\\u007F' || c === '\\b') {\r\n // Backspace\r\n input = input.slice(0, -1);\r\n } else {\r\n input += c;\r\n }\r\n };\r\n stdin.on('data', onData);\r\n } else {\r\n rl.question(prompt, (answer) => {\r\n rl.close();\r\n resolve(answer);\r\n });\r\n }\r\n });\r\n}\r\n\r\nexport function registerAuthCommand(program: Command): void {\r\n const auth = program\r\n .command('auth')\r\n .description('Authentication management');\r\n\r\n auth\r\n .command('login')\r\n .description('Login to ClawRent platform')\r\n .option('-e, --email <email>', 'Email address')\r\n .option('-p, --password <password>', 'Password')\r\n .option('--api-url <url>', 'Platform API URL')\r\n .action(async (opts: { email?: string; password?: string; apiUrl?: string }) => {\r\n try {\r\n const currentConfig = loadConfig();\r\n const apiUrl = opts.apiUrl ?? currentConfig.apiUrl;\r\n const wsUrl = deriveWsUrl(apiUrl);\r\n\r\n const email = opts.email ?? await promptInput('Email: ');\r\n const password = opts.password ?? await promptInput('Password: ', true);\r\n\r\n if (!email || !password) {\r\n printError('Email and password are required.');\r\n process.exit(1);\r\n }\r\n\r\n const client = new ApiClient({ ...currentConfig, apiUrl, wsUrl });\r\n const result = await client.login(email, password);\r\n\r\n // Save credentials (do NOT save apiUrl/wsUrl — they come from defaults or env vars,\r\n // saving them would pin the config to a specific URL and break after default changes)\r\n saveConfig({\r\n token: result.token,\r\n userId: result.user.id,\r\n email: result.user.email,\r\n name: result.user.name,\r\n });\r\n\r\n printSuccess(`Logged in as ${result.user.name} (${result.user.email})`);\r\n printSuccess(`Config saved to ${getConfigPath()}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n auth\r\n .command('logout')\r\n .description('Logout and clear saved credentials')\r\n .action(() => {\r\n try {\r\n clearConfig();\r\n printSuccess('Logged out. Config cleared.');\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n auth\r\n .command('whoami')\r\n .description('Show current user info')\r\n .action(async () => {\r\n try {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n const me = await client.getMe();\r\n printJson(me);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\n\r\nexport interface ClawRentConfig {\r\n apiUrl: string;\r\n wsUrl: string;\r\n token?: string;\r\n apiKey?: string;\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: ClawRentConfig = {\r\n apiUrl: 'https://clawrent.cloud',\r\n wsUrl: 'wss://clawrent.cloud',\r\n};\r\n\r\nexport function getConfigDir(): string {\r\n return join(homedir(), '.clawrent');\r\n}\r\n\r\nfunction getConfigFilePath(): string {\r\n return join(getConfigDir(), 'config.json');\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return getConfigFilePath();\r\n}\r\n\r\nexport function loadConfig(): ClawRentConfig {\r\n let fileConfig: Partial<ClawRentConfig> = {};\r\n\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n const raw = readFileSync(configPath, 'utf-8');\r\n fileConfig = JSON.parse(raw) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Ignore corrupt config file\r\n }\r\n }\r\n\r\n // Migration: remove stale localhost URLs saved by older CLI versions.\r\n // These override the new production defaults and break remote connections.\r\n if (fileConfig.apiUrl?.includes('localhost') || fileConfig.wsUrl?.includes('localhost')) {\r\n delete fileConfig.apiUrl;\r\n delete fileConfig.wsUrl;\r\n // Persist the cleanup so it only runs once\r\n try {\r\n const cleaned = { ...fileConfig };\r\n writeFileSync(configPath, JSON.stringify(cleaned, null, 2), 'utf-8');\r\n } catch {\r\n // Non-fatal\r\n }\r\n }\r\n\r\n // Merge: defaults < file < env vars\r\n const config: ClawRentConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...fileConfig,\r\n };\r\n\r\n // Env vars always override\r\n const envApiUrl = process.env['CLAWRENT_API_URL'];\r\n const envWsUrl = process.env['CLAWRENT_WS_URL'];\r\n const envToken = process.env['CLAWRENT_TOKEN'];\r\n const envApiKey = process.env['CLAWRENT_API_KEY'];\r\n const envUserId = process.env['CLAWRENT_USER_ID'];\r\n\r\n if (envApiUrl) config.apiUrl = envApiUrl;\r\n if (envWsUrl) config.wsUrl = envWsUrl;\r\n if (envToken) config.token = envToken;\r\n if (envApiKey) config.apiKey = envApiKey;\r\n if (envUserId) config.userId = envUserId;\r\n\r\n return config;\r\n}\r\n\r\nexport function saveConfig(partial: Partial<ClawRentConfig>): void {\r\n const configDir = getConfigDir();\r\n if (!existsSync(configDir)) {\r\n mkdirSync(configDir, { recursive: true });\r\n }\r\n\r\n let existing: Partial<ClawRentConfig> = {};\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n existing = JSON.parse(readFileSync(configPath, 'utf-8')) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Overwrite corrupt file\r\n }\r\n }\r\n\r\n const merged = { ...existing, ...partial };\r\n writeFileSync(configPath, JSON.stringify(merged, null, 2), 'utf-8');\r\n}\r\n\r\nexport function clearConfig(): void {\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n unlinkSync(configPath);\r\n }\r\n}\r\n","import type { ClawRentConfig } from './config.js';\r\n\r\nexport class ApiClient {\r\n private config: ClawRentConfig;\r\n\r\n constructor(config: ClawRentConfig) {\r\n this.config = config;\r\n }\r\n\r\n get apiUrl(): string {\r\n return this.config.apiUrl;\r\n }\r\n\r\n get wsUrl(): string {\r\n return this.config.wsUrl;\r\n }\r\n\r\n get userId(): string | undefined {\r\n return this.config.userId;\r\n }\r\n\r\n // --- Auth (no auth needed) ---\r\n\r\n async login(email: string, password: string): Promise<{ user: { id: string; email: string; name: string; role: string }; token: string }> {\r\n return this.request('POST', '/api/auth/login', { email, password }, false);\r\n }\r\n\r\n async getMe(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/auth/me');\r\n }\r\n\r\n // --- Marketplace ---\r\n\r\n async browse(query?: { search?: string; category?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.search) params.set('search', query.search);\r\n if (query?.category) params.set('category', query.category);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/marketplace/browse${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getAgent(slug: string): Promise<unknown> {\r\n return this.request('GET', `/api/marketplace/agents/${encodeURIComponent(slug)}`);\r\n }\r\n\r\n // --- Sessions ---\r\n\r\n async rent(options: { agentId: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }): Promise<unknown> {\r\n return this.request('POST', '/api/sessions', {\r\n agentId: options.agentId,\r\n taskDescription: options.taskDescription,\r\n grantedPermissions: options.grantedPermissions ?? {},\r\n });\r\n }\r\n\r\n async getSessions(query?: { role?: string; status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.role) params.set('role', query.role);\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/sessions${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getSession(sessionId: string): Promise<Record<string, unknown>> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}`);\r\n }\r\n\r\n async getSessionMessages(sessionId: string): Promise<unknown> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}/messages`);\r\n }\r\n\r\n async endSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/end`);\r\n }\r\n\r\n async approveSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/approve`);\r\n }\r\n\r\n // --- Billing ---\r\n\r\n async getBalance(): Promise<{ balance: string }> {\r\n return this.request('GET', '/api/billing/wallet');\r\n }\r\n\r\n async topUp(amount: string): Promise<{ balance: string }> {\r\n return this.request('POST', '/api/billing/wallet/topup', { amount });\r\n }\r\n\r\n // --- Provider: Agents ---\r\n\r\n async registerAgent(data: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', '/api/agents', data);\r\n }\r\n\r\n async getMyAgents(query?: { page?: number; limit?: number; status?: string }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n if (query?.status) params.set('status', query.status);\r\n const qs = params.toString();\r\n return this.request('GET', `/api/agents/my${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async publishAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`);\r\n }\r\n\r\n async activateAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/activate`);\r\n }\r\n\r\n async setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown> {\r\n return this.request('PATCH', `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });\r\n }\r\n\r\n async generateAgentToken(agentId: string): Promise<{ agentId: string; token: string; createdAt: string; warning: string }> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n async revokeAgentToken(agentId: string): Promise<{ message: string }> {\r\n return this.request('DELETE', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n // --- Orders ---\r\n\r\n async createOrder(data: {\r\n items: Array<{ providerAgentId: string; consumerAgentId?: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }>;\r\n note?: string;\r\n fromCart?: boolean;\r\n }): Promise<unknown> {\r\n return this.request('POST', '/api/orders', data);\r\n }\r\n\r\n async getOrders(query?: { status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/orders${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getOrder(orderId: string): Promise<unknown> {\r\n return this.request('GET', `/api/orders/${encodeURIComponent(orderId)}`);\r\n }\r\n\r\n async cancelOrder(orderId: string): Promise<unknown> {\r\n return this.request('POST', `/api/orders/${encodeURIComponent(orderId)}/cancel`);\r\n }\r\n\r\n // --- Cart ---\r\n\r\n async getCart(): Promise<unknown> {\r\n return this.request('GET', '/api/cart');\r\n }\r\n\r\n async addToCart(data: { providerAgentId: string; taskDescription: string }): Promise<unknown> {\r\n return this.request('POST', '/api/cart', data);\r\n }\r\n\r\n async updateCartItem(itemId: string, data: { taskDescription: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/cart/${encodeURIComponent(itemId)}`, data);\r\n }\r\n\r\n async removeFromCart(itemId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/cart/${encodeURIComponent(itemId)}`);\r\n }\r\n\r\n async clearCart(): Promise<unknown> {\r\n return this.request('DELETE', '/api/cart');\r\n }\r\n\r\n // --- Favorites ---\r\n\r\n async listFavorites(query?: { page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/favorites${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async addFavorite(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n async removeFavorite(agentId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n // --- Health ---\r\n\r\n async health(): Promise<unknown> {\r\n return this.request('GET', '/api/health', undefined, false);\r\n }\r\n\r\n // --- Private ---\r\n\r\n private async request<T = any>(method: string, path: string, body?: unknown, requireAuth: boolean = true): Promise<T> {\r\n const url = `${this.config.apiUrl}${path}`;\r\n const headers: Record<string, string> = {};\r\n\r\n if (body !== undefined) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n if (requireAuth) {\r\n if (this.config.token) {\r\n headers['Authorization'] = `Bearer ${this.config.token}`;\r\n } else if (this.config.apiKey) {\r\n headers['x-api-key'] = this.config.apiKey;\r\n } else {\r\n throw new Error('Not authenticated. Run `clawrent auth login` first.');\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.json().catch(() => ({ message: response.statusText })) as Record<string, unknown>;\r\n throw new Error(`API error ${response.status}: ${errBody['message'] ?? JSON.stringify(errBody)}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n }\r\n}\r\n","export function printJson(data: unknown): void {\r\n process.stdout.write(JSON.stringify(data, null, 2) + '\\n');\r\n}\r\n\r\nexport function printError(message: string): void {\r\n process.stderr.write(`Error: ${message}\\n`);\r\n}\r\n\r\nexport function printSuccess(message: string): void {\r\n process.stdout.write(`${message}\\n`);\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerBrowseCommand(program: Command): void {\r\n program\r\n .command('browse')\r\n .description('Browse available agents on the marketplace')\r\n .option('-s, --search <query>', 'Search by name')\r\n .option('-c, --category <category>', 'Filter by category')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { search?: string; category?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.browse({\r\n search: opts.search,\r\n category: opts.category,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerAgentCommand(program: Command): void {\r\n program\r\n .command('agent <slug>')\r\n .description('Get agent details by slug')\r\n .action(async (slug: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getAgent(slug);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerSessionsCommand(program: Command): void {\r\n program\r\n .command('sessions')\r\n .description('List your sessions')\r\n .option('-r, --role <role>', 'Filter by role (consumer/provider)')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { role?: string; status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getSessions({\r\n role: opts.role,\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nexport function registerBalanceCommand(program: Command): void {\r\n program\r\n .command('balance')\r\n .description('Check wallet balance')\r\n .action(async () => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getBalance();\r\n printSuccess(`Balance: ${result.balance}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nexport function registerTopupCommand(program: Command): void {\r\n program\r\n .command('topup <amount>')\r\n .description('Top up wallet balance')\r\n .action(async (amount: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.topUp(amount);\r\n printSuccess(`New balance: ${result.balance}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerHealthCommand(program: Command): void {\r\n program\r\n .command('health')\r\n .description('Check platform health')\r\n .action(async () => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.health();\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerRentCommand(program: Command): void {\r\n program\r\n .command('rent')\r\n .description('Rent an agent (create a session)')\r\n .requiredOption('--agent-id <id>', 'Agent ID to rent')\r\n .requiredOption('--task <description>', 'Task description')\r\n .option('--permissions <json>', 'Granted permissions as JSON string', '{}')\r\n .action(async (opts: { agentId: string; task: string; permissions: string }) => {\r\n try {\r\n let grantedPermissions: Record<string, unknown> = {};\r\n try {\r\n grantedPermissions = JSON.parse(opts.permissions) as Record<string, unknown>;\r\n } catch {\r\n printError('Invalid JSON for --permissions');\r\n process.exit(1);\r\n }\r\n\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.rent({\r\n agentId: opts.agentId,\r\n taskDescription: opts.task,\r\n grantedPermissions,\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerEndCommand(program: Command): void {\r\n program\r\n .command('end <sessionId>')\r\n .description('End a session')\r\n .action(async (sessionId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.endSession(sessionId);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport WebSocket from 'ws';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../output.js';\r\n\r\nexport function registerSendCommand(program: Command): void {\r\n program\r\n .command('send <sessionId>')\r\n .description('Send a message to a session via WebSocket')\r\n .requiredOption('--content <text>', 'Message content')\r\n .option('--type <messageType>', 'Message type', 'dialogue.message')\r\n .option('--token <sessionToken>', 'Session token (auto-fetched if not provided)')\r\n .option('--wait <ms>', 'Wait for response (milliseconds)')\r\n .action(async (sessionId: string, opts: { content: string; type: string; token?: string; wait?: string }) => {\r\n try {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n\r\n // Get session token if not provided\r\n let sessionToken = opts.token;\r\n let role = 'consumer';\r\n if (!sessionToken) {\r\n const session = await client.getSession(sessionId);\r\n sessionToken = session['sessionToken'] as string;\r\n // Determine role\r\n if (config.userId && session['providerUserId'] === config.userId) {\r\n role = 'provider';\r\n }\r\n }\r\n\r\n if (!sessionToken) {\r\n printError('Could not determine session token. Use --token flag.');\r\n process.exit(1);\r\n }\r\n\r\n const wsUrl = `${config.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=${role}`;\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const ws = new WebSocket(wsUrl);\r\n let responded = false;\r\n\r\n ws.on('open', () => {\r\n // Build full protocol envelope as required by ClawRentMessageSchema\r\n const message = {\r\n id: `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId,\r\n timestamp: Date.now(),\r\n sender: { role, agentId: config.userId ?? 'unknown' },\r\n type: opts.type,\r\n payload: { content: opts.content, dialogueType: 'message' },\r\n };\r\n ws.send(JSON.stringify(message));\r\n\r\n if (opts.wait) {\r\n // Wait for response\r\n setTimeout(() => {\r\n if (!responded) {\r\n ws.close(1000);\r\n printSuccess('Message sent (no response within timeout).');\r\n resolve();\r\n }\r\n }, parseInt(opts.wait, 10));\r\n } else {\r\n // Send and close\r\n setTimeout(() => {\r\n ws.close(1000);\r\n printSuccess('Message sent.');\r\n resolve();\r\n }, 500);\r\n }\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const data = JSON.parse(raw.toString());\r\n if (data.type !== 'system.heartbeat_ack' && data.type !== 'system.peer_connected') {\r\n responded = true;\r\n printJson(data);\r\n if (opts.wait) {\r\n ws.close(1000);\r\n resolve();\r\n }\r\n }\r\n } catch {\r\n // ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n reject(err);\r\n });\r\n\r\n ws.on('close', () => {\r\n if (!responded && opts.wait) {\r\n resolve();\r\n }\r\n });\r\n });\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../../config.js';\r\nimport { ApiClient } from '../../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../../output.js';\r\n\r\nexport function registerProviderCommands(program: Command): void {\r\n const provider = program\r\n .command('provider')\r\n .description('Provider operations');\r\n\r\n // --- Agent subcommands ---\r\n const agent = provider\r\n .command('agent')\r\n .description('Manage your agents');\r\n\r\n agent\r\n .command('create')\r\n .description('Register a new agent')\r\n .requiredOption('--name <name>', 'Agent name')\r\n .requiredOption('--slug <slug>', 'Agent slug (URL-friendly)')\r\n .requiredOption('--description <desc>', 'Agent description (10-500 chars)')\r\n .option('--long-description <text>', 'Detailed description')\r\n .option('--pricing-model <model>', 'Pricing model (per_token/per_session/per_minute)', 'per_session')\r\n .option('--price <amount>', 'Price amount', '1.00')\r\n .option('--currency <cur>', 'Currency (CNY/USD)', 'CNY')\r\n .option('--hosting-type <type>', 'Hosting type (self_hosted/platform_hosted)', 'self_hosted')\r\n .option('--approval-mode <mode>', 'Approval mode (manual/auto)', 'manual')\r\n .option('--max-concurrent <n>', 'Max concurrent sessions', '5')\r\n .option('--capabilities <json>', 'Capabilities as JSON array')\r\n .action(async (opts: {\r\n name: string; slug: string; description: string; longDescription?: string;\r\n pricingModel: string; price: string; currency: string; hostingType: string;\r\n approvalMode: string; maxConcurrent: string; capabilities?: string;\r\n }) => {\r\n try {\r\n const data: Record<string, unknown> = {\r\n name: opts.name,\r\n slug: opts.slug,\r\n description: opts.description,\r\n pricingModel: opts.pricingModel,\r\n priceAmount: opts.price,\r\n currency: opts.currency,\r\n hostingType: opts.hostingType,\r\n approvalMode: opts.approvalMode,\r\n maxConcurrentSessions: parseInt(opts.maxConcurrent, 10),\r\n };\r\n if (opts.longDescription) data['longDescription'] = opts.longDescription;\r\n if (opts.capabilities) {\r\n try {\r\n data['capabilities'] = JSON.parse(opts.capabilities);\r\n } catch {\r\n printError('Invalid JSON for --capabilities');\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.registerAgent(data);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('list')\r\n .description('List your agents')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getMyAgents({\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('publish <agentId>')\r\n .description('Publish an agent (draft -> pending_review)')\r\n .action(async (agentId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.publishAgent(agentId);\r\n printSuccess('Agent published successfully.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('activate <agentId>')\r\n .description('Activate an agent (pending_review -> active)')\r\n .action(async (agentId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.activateAgent(agentId);\r\n printSuccess('Agent activated successfully.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('status <agentId>')\r\n .description('Set agent online status')\r\n .requiredOption('--status <status>', 'Online status (online/offline/busy)')\r\n .action(async (agentId: string, opts: { status: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.setOnlineStatus(agentId, opts.status);\r\n printSuccess(`Agent status set to ${opts.status}.`);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n // --- Provider session commands ---\r\n provider\r\n .command('sessions')\r\n .description('List provider sessions')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getSessions({\r\n role: 'provider',\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n provider\r\n .command('approve <sessionId>')\r\n .description('Approve a pending session')\r\n .action(async (sessionId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.approveSession(sessionId);\r\n printSuccess('Session approved.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport WebSocket from 'ws';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printError, printSuccess } from '../output.js';\r\nimport { isDaemonRunning, spawnDaemon, writePid, getLogFilePath } from '../daemon.js';\r\nimport { StdioBridge } from './stdio-bridge.js';\r\nimport { SessionManager } from './session-manager.js';\r\nimport {\r\n createCorrelationId,\r\n isResponse,\r\n isRequest,\r\n type JsonRpcMessage,\r\n type ResultPayload,\r\n} from './protocol.js';\r\n\r\ninterface ServeOptions {\r\n agentId: string;\r\n agentToken?: string;\r\n autoApprove: boolean;\r\n pollInterval: string;\r\n daemon: boolean;\r\n}\r\n\r\n/** Pending instruction tracking: correlationId -> sessionId */\r\nconst pendingInstructions = new Map<string, string>();\r\n\r\n/** Known session IDs we've already seen (to avoid duplicate polling notifications) */\r\nconst knownPendingSessions = new Set<string>();\r\nconst activeSessions = new Set<string>();\r\n\r\nexport function registerServeCommand(program: Command): void {\r\n program\r\n .command('serve')\r\n .description('Start serve daemon - bridge WebSocket sessions to stdin/stdout')\r\n .requiredOption('--agent-id <id>', 'Agent ID to serve')\r\n .option('--agent-token <token>', 'Agent token for /ws/agent control channel')\r\n .option('--auto-approve', 'Automatically approve incoming sessions', false)\r\n .option('--poll-interval <ms>', 'Polling interval for pending sessions (ms)', '5000')\r\n .option('-d, --daemon', 'Run in background as a daemon process', false)\r\n .action(async (opts: ServeOptions) => {\r\n try {\r\n if (opts.daemon) {\r\n // --- Daemon mode: fork and exit ---\r\n const { running, pid: existingPid } = isDaemonRunning();\r\n if (running) {\r\n printError(`Daemon already running (PID: ${existingPid}). Use 'clawrent stop' first.`);\r\n process.exit(1);\r\n }\r\n\r\n // Rebuild args without --daemon / -d\r\n const args: string[] = ['serve', '--agent-id', opts.agentId];\r\n if (opts.agentToken) args.push('--agent-token', opts.agentToken);\r\n if (opts.autoApprove) args.push('--auto-approve');\r\n if (opts.pollInterval !== '5000') args.push('--poll-interval', opts.pollInterval);\r\n\r\n const pid = spawnDaemon(args);\r\n writePid(pid);\r\n printSuccess(`Daemon started (PID: ${pid})\\nLogs: ${getLogFilePath()}`);\r\n process.exit(0);\r\n }\r\n\r\n await runDaemon(opts);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n\r\nasync function runDaemon(opts: ServeOptions): Promise<void> {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n const bridge = new StdioBridge();\r\n const sessionManager = new SessionManager(config.wsUrl);\r\n sessionManager.agentId = opts.agentId;\r\n const pollInterval = parseInt(opts.pollInterval, 10);\r\n let agentWs: WebSocket | null = null;\r\n let agentHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n // --- 1. Startup: validate auth + resolve agent ---\r\n let agentName = opts.agentId;\r\n try {\r\n const agents = (await client.getMyAgents()) as { data: Array<Record<string, unknown>> };\r\n const agent = agents.data.find((a) => a['id'] === opts.agentId);\r\n if (agent) {\r\n agentName = (agent['name'] as string) ?? opts.agentId;\r\n\r\n // Auto-activate if needed (skip if no token yet — activation requires WS first)\r\n if (!opts.agentToken) {\r\n const status = agent['status'] as string;\r\n if (status === 'draft') {\r\n await client.publishAgent(opts.agentId);\r\n await client.activateAgent(opts.agentId);\r\n } else if (status === 'pending_review') {\r\n await client.activateAgent(opts.agentId);\r\n }\r\n // Set online via REST (legacy fallback)\r\n await client.setOnlineStatus(opts.agentId, 'online');\r\n }\r\n }\r\n } catch {\r\n // Continue anyway — the poll loop will surface errors\r\n }\r\n\r\n // --- 2. Notify ready ---\r\n bridge.writeNotification('ready', {\r\n agentId: opts.agentId,\r\n agentName,\r\n });\r\n\r\n // --- 3. Wire up session manager events ---\r\n sessionManager.on('session:connected', (sessionId: string) => {\r\n bridge.writeNotification('session.connected', { sessionId });\r\n });\r\n\r\n sessionManager.on('session:message', (sessionId: string, message: Record<string, unknown>) => {\r\n const type = message['type'] as string;\r\n\r\n if (type?.startsWith('instruction.')) {\r\n // Instruction from consumer -> forward as JSON-RPC request (expects response)\r\n const corrId = createCorrelationId();\r\n pendingInstructions.set(corrId, sessionId);\r\n\r\n bridge.writeRequest('instruction', corrId, {\r\n sessionId,\r\n messageId: (message['id'] as string) ?? corrId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n sender: message['sender'],\r\n });\r\n } else if (type?.startsWith('dialogue.')) {\r\n // Dialogue from consumer -> forward as notification\r\n const payload = (message['payload'] as Record<string, unknown>) ?? {};\r\n bridge.writeNotification('dialogue', {\r\n sessionId,\r\n content: payload['content'] ?? '',\r\n dialogueType: payload['dialogueType'] ?? 'message',\r\n });\r\n } else if (type?.startsWith('result.')) {\r\n // Result from consumer -> forward as notification\r\n bridge.writeNotification('result', {\r\n sessionId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n });\r\n } else if (type === 'system.session_ended' || type === 'system.peer_disconnected') {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.ended', {\r\n sessionId,\r\n reason: type,\r\n });\r\n } else if (type === 'system.peer_connected') {\r\n bridge.writeNotification('session.peer_connected', { sessionId });\r\n } else if (type !== 'system.heartbeat_ack') {\r\n // Forward unknown messages as-is\r\n bridge.writeNotification('message', { sessionId, ...message });\r\n }\r\n });\r\n\r\n sessionManager.on('session:disconnected', (sessionId: string, reason: string) => {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.disconnected', { sessionId, reason });\r\n });\r\n\r\n sessionManager.on('session:reconnecting', (sessionId: string, delay: number) => {\r\n bridge.writeNotification('session.reconnecting', { sessionId, delay });\r\n });\r\n\r\n sessionManager.on('session:error', (sessionId: string, err: Error) => {\r\n bridge.writeNotification('session.error', { sessionId, message: err.message });\r\n });\r\n\r\n // --- 4. Handle stdin messages from agent ---\r\n bridge.start((msg: JsonRpcMessage) => {\r\n if (isResponse(msg)) {\r\n // Agent is responding to an instruction we forwarded\r\n const sessionId = pendingInstructions.get(msg.id);\r\n if (sessionId && msg.result) {\r\n pendingInstructions.delete(msg.id);\r\n const result = msg.result as unknown as ResultPayload;\r\n sessionManager.send(sessionId, {\r\n type: result.type ?? 'result.success',\r\n payload: result.payload ?? result,\r\n });\r\n }\r\n } else if (isRequest(msg)) {\r\n // Agent is proactively sending something\r\n if (msg.method === 'send') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n if (params?.['sessionId']) {\r\n const sent = sessionManager.send(params['sessionId'] as string, {\r\n type: params['type'] ?? 'dialogue.message',\r\n payload: (params['payload'] as Record<string, unknown>) ?? { content: '' },\r\n });\r\n bridge.writeResponse(msg.id, { success: sent });\r\n }\r\n } else if (msg.method === 'approve') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n const sid = params?.['sessionId'] as string | undefined;\r\n if (sid) {\r\n approveAndConnect(client, sessionManager, bridge, sid).catch(() => {\r\n bridge.writeResponse(msg.id, { success: false, error: 'Failed to approve' });\r\n }).then(() => {\r\n bridge.writeResponse(msg.id, { success: true });\r\n });\r\n }\r\n }\r\n }\r\n // Notifications from agent are ignored for now\r\n });\r\n\r\n // --- 5. Agent control channel (/ws/agent) + fallback poll loop ---\r\n let pollTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n function connectAgentWs(token: string) {\r\n const wsBase = config.wsUrl ?? config.apiUrl.replace(/^http/, 'ws');\r\n const url = `${wsBase}/ws/agent?token=${token}`;\r\n agentWs = new WebSocket(url);\r\n\r\n agentWs.on('open', () => {\r\n bridge.writeNotification('agent.connected', { agentId: opts.agentId });\r\n\r\n // Start heartbeat on agent channel\r\n agentHeartbeatTimer = setInterval(() => {\r\n if (agentWs && agentWs.readyState === WebSocket.OPEN) {\r\n agentWs.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, 25_000);\r\n\r\n // Stop polling when WS is connected\r\n if (pollTimer) {\r\n clearInterval(pollTimer);\r\n pollTimer = null;\r\n }\r\n });\r\n\r\n agentWs.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString());\r\n const type = message.type as string;\r\n\r\n if (type === 'session.new' || type === 'session.approved') {\r\n const payload = message.payload as Record<string, unknown>;\r\n const sid = payload['sessionId'] as string;\r\n const sessionToken = payload['sessionToken'] as string;\r\n\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) return;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove && type === 'session.new') {\r\n approveAndConnect(client, sessionManager, bridge, sid);\r\n } else if (type === 'session.approved' && sessionToken) {\r\n // Already approved, connect directly\r\n activeSessions.add(sid);\r\n bridge.writeNotification('session.new', {\r\n sessionId: sid,\r\n sessionToken,\r\n taskDescription: (payload['taskDescription'] as string) ?? '',\r\n consumerUserId: (payload['consumerUserId'] as string) ?? '',\r\n });\r\n sessionManager.connect(sid, sessionToken);\r\n } else {\r\n bridge.writeNotification('session.pending', {\r\n sessionId: sid,\r\n taskDescription: (payload['taskDescription'] as string) ?? '',\r\n consumerUserId: (payload['consumerUserId'] as string) ?? '',\r\n });\r\n }\r\n }\r\n // Ignore heartbeat_ack and other system messages\r\n } catch {\r\n // Ignore parse errors on agent channel\r\n }\r\n });\r\n\r\n agentWs.on('close', (code, reason) => {\r\n if (agentHeartbeatTimer) {\r\n clearInterval(agentHeartbeatTimer);\r\n agentHeartbeatTimer = null;\r\n }\r\n bridge.writeNotification('agent.disconnected', {\r\n agentId: opts.agentId,\r\n code,\r\n reason: reason.toString(),\r\n });\r\n\r\n // Fall back to polling\r\n if (!pollTimer) {\r\n startPollLoop();\r\n }\r\n\r\n // Reconnect after 5s unless deliberately closed\r\n if (code !== 1000 && code !== 4009) {\r\n setTimeout(() => connectAgentWs(token), 5000);\r\n }\r\n });\r\n\r\n agentWs.on('error', () => {\r\n // Error will trigger close event\r\n });\r\n }\r\n\r\n function startPollLoop() {\r\n pollTimer = setInterval(async () => {\r\n try {\r\n const sessions = (await client.getSessions({\r\n role: 'provider',\r\n status: 'pending_approval',\r\n })) as { data: Array<Record<string, unknown>> };\r\n\r\n for (const session of sessions.data ?? []) {\r\n const sid = session['id'] as string;\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) continue;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove) {\r\n await approveAndConnect(client, sessionManager, bridge, sid);\r\n } else {\r\n bridge.writeNotification('session.pending', {\r\n sessionId: sid,\r\n taskDescription: session['taskDescription'] ?? '',\r\n consumerUserId: session['consumerUserId'] ?? '',\r\n });\r\n }\r\n }\r\n } catch {\r\n // Silently retry on next poll\r\n }\r\n }, pollInterval);\r\n }\r\n\r\n // Connect via /ws/agent if token provided, otherwise fallback to polling\r\n if (opts.agentToken) {\r\n connectAgentWs(opts.agentToken);\r\n } else {\r\n startPollLoop();\r\n }\r\n\r\n // --- 6. Graceful shutdown ---\r\n const shutdown = async () => {\r\n if (pollTimer) clearInterval(pollTimer);\r\n if (agentHeartbeatTimer) clearInterval(agentHeartbeatTimer);\r\n bridge.stop();\r\n\r\n // Close agent WS (this triggers server-side offline update)\r\n if (agentWs) {\r\n try { agentWs.close(1000, 'Shutting down'); } catch { /* ignore */ }\r\n agentWs = null;\r\n }\r\n\r\n // Fallback: set offline via REST if no agent WS was used\r\n if (!opts.agentToken) {\r\n try {\r\n await client.setOnlineStatus(opts.agentId, 'offline');\r\n } catch {\r\n // Best effort\r\n }\r\n }\r\n\r\n sessionManager.disconnectAll();\r\n bridge.writeNotification('shutdown', { reason: 'signal' });\r\n\r\n // Give a moment for messages to flush\r\n setTimeout(() => process.exit(0), 500);\r\n };\r\n\r\n process.on('SIGINT', () => { void shutdown(); });\r\n process.on('SIGTERM', () => { void shutdown(); });\r\n}\r\n\r\nasync function approveAndConnect(\r\n client: ApiClient,\r\n sessionManager: SessionManager,\r\n bridge: StdioBridge,\r\n sessionId: string,\r\n): Promise<void> {\r\n try {\r\n const approved = (await client.approveSession(sessionId)) as Record<string, unknown>;\r\n const sessionToken = approved['sessionToken'] as string;\r\n const taskDescription = approved['taskDescription'] as string;\r\n\r\n activeSessions.add(sessionId);\r\n\r\n bridge.writeNotification('session.new', {\r\n sessionId,\r\n sessionToken,\r\n taskDescription: taskDescription ?? '',\r\n consumerUserId: (approved['consumerUserId'] as string) ?? '',\r\n });\r\n\r\n sessionManager.connect(sessionId, sessionToken);\r\n } catch (err: unknown) {\r\n bridge.writeNotification('session.approve_failed', {\r\n sessionId,\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, unlinkSync, openSync, closeSync, mkdirSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { spawn } from 'node:child_process';\r\nimport { getConfigDir } from './config.js';\r\n\r\nexport function getPidFilePath(): string {\r\n return join(getConfigDir(), 'serve.pid');\r\n}\r\n\r\nexport function getLogFilePath(): string {\r\n return join(getConfigDir(), 'serve.log');\r\n}\r\n\r\nexport function readPid(): number | null {\r\n try {\r\n const content = readFileSync(getPidFilePath(), 'utf-8').trim();\r\n const pid = parseInt(content, 10);\r\n return Number.isFinite(pid) && pid > 0 ? pid : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function writePid(pid: number): void {\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n writeFileSync(getPidFilePath(), String(pid), 'utf-8');\r\n}\r\n\r\nexport function removePidFile(): void {\r\n try {\r\n unlinkSync(getPidFilePath());\r\n } catch {\r\n // Ignore ENOENT\r\n }\r\n}\r\n\r\nexport function isProcessAlive(pid: number): boolean {\r\n try {\r\n process.kill(pid, 0);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function isDaemonRunning(): { running: boolean; pid: number | null } {\r\n const pid = readPid();\r\n if (pid === null) return { running: false, pid: null };\r\n\r\n if (isProcessAlive(pid)) {\r\n return { running: true, pid };\r\n }\r\n\r\n // Stale PID file — process is dead, clean up\r\n removePidFile();\r\n return { running: false, pid: null };\r\n}\r\n\r\nexport function spawnDaemon(args: string[]): number {\r\n const logFile = getLogFilePath();\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n const logFd = openSync(logFile, 'a');\r\n\r\n const child = spawn(process.argv[0]!, [process.argv[1]!, ...args], {\r\n detached: true,\r\n stdio: ['ignore', logFd, logFd],\r\n windowsHide: true,\r\n });\r\n\r\n child.unref();\r\n closeSync(logFd);\r\n\r\n if (!child.pid) {\r\n throw new Error('Failed to start daemon process');\r\n }\r\n\r\n return child.pid;\r\n}\r\n","import { createInterface } from 'node:readline';\r\nimport type { JsonRpcMessage, JsonRpcResponse, JsonRpcRequest, JsonRpcNotification } from './protocol.js';\r\n\r\nexport type StdinMessageHandler = (msg: JsonRpcMessage) => void;\r\n\r\n/**\r\n * StdioBridge handles JSON Lines communication over stdin/stdout.\r\n * Each line is a JSON-RPC 2.0 message.\r\n */\r\nexport class StdioBridge {\r\n private handler: StdinMessageHandler | null = null;\r\n private rl: ReturnType<typeof createInterface> | null = null;\r\n\r\n /** Start reading from stdin */\r\n start(handler: StdinMessageHandler): void {\r\n this.handler = handler;\r\n this.rl = createInterface({ input: process.stdin, crlfDelay: Infinity });\r\n\r\n this.rl.on('line', (line) => {\r\n const trimmed = line.trim();\r\n if (!trimmed) return;\r\n\r\n try {\r\n const msg = JSON.parse(trimmed) as JsonRpcMessage;\r\n if (msg.jsonrpc !== '2.0') {\r\n this.writeError('Invalid JSON-RPC: missing jsonrpc field');\r\n return;\r\n }\r\n this.handler?.(msg);\r\n } catch {\r\n this.writeError(`Failed to parse JSON: ${trimmed.slice(0, 100)}`);\r\n }\r\n });\r\n\r\n this.rl.on('close', () => {\r\n // stdin closed — process will shut down\r\n });\r\n }\r\n\r\n /** Stop reading */\r\n stop(): void {\r\n this.rl?.close();\r\n this.rl = null;\r\n }\r\n\r\n /** Write a JSON-RPC message to stdout */\r\n write(msg: JsonRpcMessage): void {\r\n process.stdout.write(JSON.stringify(msg) + '\\n');\r\n }\r\n\r\n /** Write a notification */\r\n writeNotification(method: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcNotification = { jsonrpc: '2.0', method, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a request (expects response) */\r\n writeRequest(method: string, id: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcRequest = { jsonrpc: '2.0', method, id, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a response */\r\n writeResponse(id: string, result: Record<string, unknown>): void {\r\n const msg: JsonRpcResponse = { jsonrpc: '2.0', id, result };\r\n this.write(msg);\r\n }\r\n\r\n /** Write an error notification to stdout */\r\n private writeError(message: string): void {\r\n this.writeNotification('error', { message });\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n","// JSON-RPC 2.0 protocol types for clawrent serve stdin/stdout communication\r\n\r\n/** Base JSON-RPC message */\r\nexport interface JsonRpcBase {\r\n jsonrpc: '2.0';\r\n}\r\n\r\n/** JSON-RPC request (has method + id) */\r\nexport interface JsonRpcRequest extends JsonRpcBase {\r\n method: string;\r\n id: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC notification (has method, no id) */\r\nexport interface JsonRpcNotification extends JsonRpcBase {\r\n method: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC response (has id + result or error) */\r\nexport interface JsonRpcResponse extends JsonRpcBase {\r\n id: string;\r\n result?: Record<string, unknown>;\r\n error?: { code: number; message: string; data?: unknown };\r\n}\r\n\r\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcResponse;\r\n\r\n// --- Daemon -> Agent (stdout) methods ---\r\n\r\nexport interface ReadyParams {\r\n agentId: string;\r\n agentName: string;\r\n}\r\n\r\nexport interface SessionNewParams {\r\n sessionId: string;\r\n sessionToken: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n}\r\n\r\nexport interface SessionPendingParams {\r\n sessionId: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n}\r\n\r\nexport interface InstructionParams {\r\n sessionId: string;\r\n messageId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n sender?: Record<string, unknown>;\r\n}\r\n\r\nexport interface DialogueParams {\r\n sessionId: string;\r\n content: string;\r\n dialogueType: string;\r\n}\r\n\r\nexport interface SessionEndedParams {\r\n sessionId: string;\r\n reason: string;\r\n}\r\n\r\n// --- Agent -> Daemon (stdin) methods ---\r\n\r\nexport interface ResultPayload {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface SendParams {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface ApproveParams {\r\n sessionId: string;\r\n}\r\n\r\n// --- Helpers ---\r\n\r\nlet correlationCounter = 0;\r\n\r\nexport function createCorrelationId(): string {\r\n return `corr_${Date.now().toString(36)}_${(correlationCounter++).toString(36)}`;\r\n}\r\n\r\nexport function createNotification(method: string, params: Record<string, unknown>): JsonRpcNotification {\r\n return { jsonrpc: '2.0', method, params };\r\n}\r\n\r\nexport function createRequest(method: string, params: Record<string, unknown>, id?: string): JsonRpcRequest {\r\n return { jsonrpc: '2.0', method, id: id ?? createCorrelationId(), params };\r\n}\r\n\r\nexport function isResponse(msg: JsonRpcMessage): msg is JsonRpcResponse {\r\n return 'id' in msg && ('result' in msg || 'error' in msg) && !('method' in msg);\r\n}\r\n\r\nexport function isRequest(msg: JsonRpcMessage): msg is JsonRpcRequest {\r\n return 'method' in msg && 'id' in msg;\r\n}\r\n\r\nexport function isNotification(msg: JsonRpcMessage): msg is JsonRpcNotification {\r\n return 'method' in msg && !('id' in msg);\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, removePidFile, isProcessAlive } from '../daemon.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nexport function registerStopCommand(program: Command): void {\r\n program\r\n .command('stop')\r\n .description('Stop the background serve daemon')\r\n .action(async () => {\r\n const { running, pid } = isDaemonRunning();\r\n\r\n if (!running || pid === null) {\r\n printSuccess('No daemon is running.');\r\n return;\r\n }\r\n\r\n // Send SIGTERM to trigger graceful shutdown\r\n try {\r\n process.kill(pid, 'SIGTERM');\r\n } catch (err: unknown) {\r\n const code = (err as NodeJS.ErrnoException).code;\r\n if (code === 'ESRCH') {\r\n // Already dead\r\n removePidFile();\r\n printSuccess('Daemon already stopped.');\r\n return;\r\n }\r\n if (code === 'EPERM') {\r\n printError(`Permission denied. Cannot stop daemon (PID: ${pid}).`);\r\n process.exit(1);\r\n }\r\n throw err;\r\n }\r\n\r\n // Poll for process to exit (up to 3 seconds)\r\n const maxWait = 3000;\r\n const interval = 200;\r\n let waited = 0;\r\n\r\n while (waited < maxWait) {\r\n await new Promise((r) => setTimeout(r, interval));\r\n waited += interval;\r\n if (!isProcessAlive(pid)) {\r\n removePidFile();\r\n printSuccess(`Daemon stopped (PID: ${pid}).`);\r\n return;\r\n }\r\n }\r\n\r\n // Force kill if still alive\r\n try {\r\n process.kill(pid, 'SIGKILL');\r\n } catch {\r\n // Ignore — may have exited between check and kill\r\n }\r\n\r\n removePidFile();\r\n printSuccess(`Daemon stopped (PID: ${pid}).`);\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, getLogFilePath } from '../daemon.js';\r\nimport { printJson } from '../output.js';\r\n\r\nexport function registerStatusCommand(program: Command): void {\r\n program\r\n .command('status')\r\n .description('Check if the serve daemon is running')\r\n .action(() => {\r\n const { running, pid } = isDaemonRunning();\r\n\r\n if (running && pid !== null) {\r\n printJson({ status: 'running', pid, logFile: getLogFilePath() });\r\n } else {\r\n printJson({ status: 'stopped' });\r\n }\r\n });\r\n}\r\n"],"mappings":"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","names":["readFileSync","join","program","program","program","program","program","program","program","program","program","program","program","WebSocket","readFileSync","writeFileSync","unlinkSync","mkdirSync","existsSync","join","join","readFileSync","existsSync","mkdirSync","writeFileSync","unlinkSync","createInterface","WebSocket","program","WebSocket","program","program","readFileSync","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/api-client.ts","../src/output.ts","../src/commands/browse.ts","../src/commands/agent.ts","../src/commands/sessions.ts","../src/commands/balance.ts","../src/commands/topup.ts","../src/commands/health.ts","../src/commands/rent.ts","../src/commands/end.ts","../src/commands/send.ts","../src/commands/provider/index.ts","../src/serve/index.ts","../src/daemon.ts","../src/serve/stdio-bridge.ts","../src/serve/session-manager.ts","../src/serve/protocol.ts","../src/commands/stop.ts","../src/commands/status.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\r\nimport { dirname, join } from 'node:path';\r\nimport { fileURLToPath } from 'node:url';\r\nimport { Command } from 'commander';\r\nimport { registerAuthCommand } from './commands/auth.js';\r\nimport { registerBrowseCommand } from './commands/browse.js';\r\nimport { registerAgentCommand } from './commands/agent.js';\r\nimport { registerSessionsCommand } from './commands/sessions.js';\r\nimport { registerBalanceCommand } from './commands/balance.js';\r\nimport { registerTopupCommand } from './commands/topup.js';\r\nimport { registerHealthCommand } from './commands/health.js';\r\nimport { registerRentCommand } from './commands/rent.js';\r\nimport { registerEndCommand } from './commands/end.js';\r\nimport { registerSendCommand } from './commands/send.js';\r\nimport { registerProviderCommands } from './commands/provider/index.js';\r\nimport { registerServeCommand } from './serve/index.js';\r\nimport { registerStopCommand } from './commands/stop.js';\r\nimport { registerStatusCommand } from './commands/status.js';\r\n\r\nconst __dirname = dirname(fileURLToPath(import.meta.url));\r\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('clawrent')\r\n .description('ClawRent CLI - Agent capability rental platform')\r\n .version(pkg.version);\r\n\r\n// Auth\r\nregisterAuthCommand(program);\r\n\r\n// Consumer commands\r\nregisterBrowseCommand(program);\r\nregisterAgentCommand(program);\r\nregisterSessionsCommand(program);\r\nregisterBalanceCommand(program);\r\nregisterTopupCommand(program);\r\nregisterRentCommand(program);\r\nregisterEndCommand(program);\r\nregisterSendCommand(program);\r\nregisterHealthCommand(program);\r\n\r\n// Provider commands\r\nregisterProviderCommands(program);\r\n\r\n// Serve daemon\r\nregisterServeCommand(program);\r\n\r\n// Daemon management\r\nregisterStopCommand(program);\r\nregisterStatusCommand(program);\r\n\r\nprogram.parse();\r\n","import { Command } from 'commander';\r\nimport { createInterface } from 'node:readline';\r\nimport { loadConfig, saveConfig, clearConfig, getConfigPath } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../output.js';\r\n\r\nfunction deriveWsUrl(apiUrl: string): string {\r\n return apiUrl.replace(/^http/, 'ws');\r\n}\r\n\r\nasync function promptInput(prompt: string, hidden: boolean = false): Promise<string> {\r\n const rl = createInterface({ input: process.stdin, output: process.stderr });\r\n\r\n return new Promise((resolve) => {\r\n if (hidden) {\r\n // For password: write prompt manually, mute output\r\n process.stderr.write(prompt);\r\n const stdin = process.stdin;\r\n const wasRaw = stdin.isRaw;\r\n if (stdin.isTTY) stdin.setRawMode(true);\r\n let input = '';\r\n const onData = (ch: Buffer) => {\r\n const c = ch.toString('utf-8');\r\n if (c === '\\n' || c === '\\r') {\r\n stdin.removeListener('data', onData);\r\n if (stdin.isTTY && wasRaw !== undefined) stdin.setRawMode(wasRaw);\r\n process.stderr.write('\\n');\r\n rl.close();\r\n resolve(input);\r\n } else if (c === '\\u0003') {\r\n // Ctrl+C\r\n rl.close();\r\n process.exit(1);\r\n } else if (c === '\\u007F' || c === '\\b') {\r\n // Backspace\r\n input = input.slice(0, -1);\r\n } else {\r\n input += c;\r\n }\r\n };\r\n stdin.on('data', onData);\r\n } else {\r\n rl.question(prompt, (answer) => {\r\n rl.close();\r\n resolve(answer);\r\n });\r\n }\r\n });\r\n}\r\n\r\nexport function registerAuthCommand(program: Command): void {\r\n const auth = program\r\n .command('auth')\r\n .description('Authentication management');\r\n\r\n auth\r\n .command('login')\r\n .description('Login to ClawRent platform')\r\n .option('-e, --email <email>', 'Email address')\r\n .option('-p, --password <password>', 'Password')\r\n .option('--api-url <url>', 'Platform API URL')\r\n .action(async (opts: { email?: string; password?: string; apiUrl?: string }) => {\r\n try {\r\n const currentConfig = loadConfig();\r\n const apiUrl = opts.apiUrl ?? currentConfig.apiUrl;\r\n const wsUrl = deriveWsUrl(apiUrl);\r\n\r\n const email = opts.email ?? await promptInput('Email: ');\r\n const password = opts.password ?? await promptInput('Password: ', true);\r\n\r\n if (!email || !password) {\r\n printError('Email and password are required.');\r\n process.exit(1);\r\n }\r\n\r\n const client = new ApiClient({ ...currentConfig, apiUrl, wsUrl });\r\n const result = await client.login(email, password);\r\n\r\n // Save credentials (do NOT save apiUrl/wsUrl — they come from defaults or env vars,\r\n // saving them would pin the config to a specific URL and break after default changes)\r\n saveConfig({\r\n token: result.token,\r\n userId: result.user.id,\r\n email: result.user.email,\r\n name: result.user.name,\r\n });\r\n\r\n printSuccess(`Logged in as ${result.user.name} (${result.user.email})`);\r\n printSuccess(`Config saved to ${getConfigPath()}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n auth\r\n .command('logout')\r\n .description('Logout and clear saved credentials')\r\n .action(() => {\r\n try {\r\n clearConfig();\r\n printSuccess('Logged out. Config cleared.');\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n auth\r\n .command('whoami')\r\n .description('Show current user info')\r\n .action(async () => {\r\n try {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n const me = await client.getMe();\r\n printJson(me);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\n\r\nexport interface ClawRentConfig {\r\n apiUrl: string;\r\n wsUrl: string;\r\n token?: string;\r\n apiKey?: string;\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: ClawRentConfig = {\r\n apiUrl: 'https://clawrent.cloud',\r\n wsUrl: 'wss://clawrent.cloud',\r\n};\r\n\r\nexport function getConfigDir(): string {\r\n return join(homedir(), '.clawrent');\r\n}\r\n\r\nfunction getConfigFilePath(): string {\r\n return join(getConfigDir(), 'config.json');\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return getConfigFilePath();\r\n}\r\n\r\nexport function loadConfig(): ClawRentConfig {\r\n let fileConfig: Partial<ClawRentConfig> = {};\r\n\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n const raw = readFileSync(configPath, 'utf-8');\r\n fileConfig = JSON.parse(raw) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Ignore corrupt config file\r\n }\r\n }\r\n\r\n // Migration: remove stale localhost URLs saved by older CLI versions.\r\n // These override the new production defaults and break remote connections.\r\n if (fileConfig.apiUrl?.includes('localhost') || fileConfig.wsUrl?.includes('localhost')) {\r\n delete fileConfig.apiUrl;\r\n delete fileConfig.wsUrl;\r\n // Persist the cleanup so it only runs once\r\n try {\r\n const cleaned = { ...fileConfig };\r\n writeFileSync(configPath, JSON.stringify(cleaned, null, 2), 'utf-8');\r\n } catch {\r\n // Non-fatal\r\n }\r\n }\r\n\r\n // Merge: defaults < file < env vars\r\n const config: ClawRentConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...fileConfig,\r\n };\r\n\r\n // Env vars always override\r\n const envApiUrl = process.env['CLAWRENT_API_URL'];\r\n const envWsUrl = process.env['CLAWRENT_WS_URL'];\r\n const envToken = process.env['CLAWRENT_TOKEN'];\r\n const envApiKey = process.env['CLAWRENT_API_KEY'];\r\n const envUserId = process.env['CLAWRENT_USER_ID'];\r\n\r\n if (envApiUrl) config.apiUrl = envApiUrl;\r\n if (envWsUrl) config.wsUrl = envWsUrl;\r\n if (envToken) config.token = envToken;\r\n if (envApiKey) config.apiKey = envApiKey;\r\n if (envUserId) config.userId = envUserId;\r\n\r\n return config;\r\n}\r\n\r\nexport function saveConfig(partial: Partial<ClawRentConfig>): void {\r\n const configDir = getConfigDir();\r\n if (!existsSync(configDir)) {\r\n mkdirSync(configDir, { recursive: true });\r\n }\r\n\r\n let existing: Partial<ClawRentConfig> = {};\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n existing = JSON.parse(readFileSync(configPath, 'utf-8')) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Overwrite corrupt file\r\n }\r\n }\r\n\r\n const merged = { ...existing, ...partial };\r\n writeFileSync(configPath, JSON.stringify(merged, null, 2), 'utf-8');\r\n}\r\n\r\nexport function clearConfig(): void {\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n unlinkSync(configPath);\r\n }\r\n}\r\n","import type { ClawRentConfig } from './config.js';\r\n\r\nexport class ApiClient {\r\n private config: ClawRentConfig;\r\n\r\n constructor(config: ClawRentConfig) {\r\n this.config = config;\r\n }\r\n\r\n get apiUrl(): string {\r\n return this.config.apiUrl;\r\n }\r\n\r\n get wsUrl(): string {\r\n return this.config.wsUrl;\r\n }\r\n\r\n get userId(): string | undefined {\r\n return this.config.userId;\r\n }\r\n\r\n // --- Auth (no auth needed) ---\r\n\r\n async login(email: string, password: string): Promise<{ user: { id: string; email: string; name: string; role: string }; token: string }> {\r\n return this.request('POST', '/api/auth/login', { email, password }, false);\r\n }\r\n\r\n async getMe(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/auth/me');\r\n }\r\n\r\n // --- Marketplace ---\r\n\r\n async browse(query?: { search?: string; category?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.search) params.set('search', query.search);\r\n if (query?.category) params.set('category', query.category);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/marketplace/browse${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getAgent(slug: string): Promise<unknown> {\r\n return this.request('GET', `/api/marketplace/agents/${encodeURIComponent(slug)}`);\r\n }\r\n\r\n // --- Sessions ---\r\n\r\n async rent(options: { agentId: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }): Promise<unknown> {\r\n return this.request('POST', '/api/sessions', {\r\n agentId: options.agentId,\r\n taskDescription: options.taskDescription,\r\n grantedPermissions: options.grantedPermissions ?? {},\r\n });\r\n }\r\n\r\n async getSessions(query?: { role?: string; status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.role) params.set('role', query.role);\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/sessions${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getSession(sessionId: string): Promise<Record<string, unknown>> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}`);\r\n }\r\n\r\n async getSessionMessages(sessionId: string): Promise<unknown> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}/messages`);\r\n }\r\n\r\n async endSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/end`);\r\n }\r\n\r\n async approveSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/approve`);\r\n }\r\n\r\n // --- Billing ---\r\n\r\n async getBalance(): Promise<{ balance: string }> {\r\n return this.request('GET', '/api/billing/wallet');\r\n }\r\n\r\n async topUp(amount: string): Promise<{ balance: string }> {\r\n return this.request('POST', '/api/billing/wallet/topup', { amount });\r\n }\r\n\r\n // --- Provider: Agents ---\r\n\r\n async registerAgent(data: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', '/api/agents', data);\r\n }\r\n\r\n async getMyAgents(query?: { page?: number; limit?: number; status?: string }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n if (query?.status) params.set('status', query.status);\r\n const qs = params.toString();\r\n return this.request('GET', `/api/agents/my${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */\r\n async getMyAgent(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/agents/me/agent');\r\n }\r\n\r\n async publishAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`);\r\n }\r\n\r\n async activateAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/activate`);\r\n }\r\n\r\n async setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown> {\r\n return this.request('PATCH', `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });\r\n }\r\n\r\n async generateAgentToken(agentId: string): Promise<{ agentId: string; token: string; createdAt: string; warning: string }> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n async revokeAgentToken(agentId: string): Promise<{ message: string }> {\r\n return this.request('DELETE', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n // --- Orders ---\r\n\r\n async createOrder(data: {\r\n items: Array<{ providerAgentId: string; consumerAgentId?: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }>;\r\n note?: string;\r\n fromCart?: boolean;\r\n }): Promise<unknown> {\r\n return this.request('POST', '/api/orders', data);\r\n }\r\n\r\n async getOrders(query?: { status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/orders${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getOrder(orderId: string): Promise<unknown> {\r\n return this.request('GET', `/api/orders/${encodeURIComponent(orderId)}`);\r\n }\r\n\r\n async cancelOrder(orderId: string): Promise<unknown> {\r\n return this.request('POST', `/api/orders/${encodeURIComponent(orderId)}/cancel`);\r\n }\r\n\r\n // --- Cart ---\r\n\r\n async getCart(): Promise<unknown> {\r\n return this.request('GET', '/api/cart');\r\n }\r\n\r\n async addToCart(data: { providerAgentId: string; taskDescription: string }): Promise<unknown> {\r\n return this.request('POST', '/api/cart', data);\r\n }\r\n\r\n async updateCartItem(itemId: string, data: { taskDescription: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/cart/${encodeURIComponent(itemId)}`, data);\r\n }\r\n\r\n async removeFromCart(itemId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/cart/${encodeURIComponent(itemId)}`);\r\n }\r\n\r\n async clearCart(): Promise<unknown> {\r\n return this.request('DELETE', '/api/cart');\r\n }\r\n\r\n // --- Favorites ---\r\n\r\n async listFavorites(query?: { page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/favorites${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async addFavorite(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n async removeFavorite(agentId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n // --- Health ---\r\n\r\n async health(): Promise<unknown> {\r\n return this.request('GET', '/api/health', undefined, false);\r\n }\r\n\r\n // --- Private ---\r\n\r\n private async request<T = any>(method: string, path: string, body?: unknown, requireAuth: boolean = true): Promise<T> {\r\n const url = `${this.config.apiUrl}${path}`;\r\n const headers: Record<string, string> = {};\r\n\r\n if (body !== undefined) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n if (requireAuth) {\r\n if (this.config.token) {\r\n headers['Authorization'] = `Bearer ${this.config.token}`;\r\n } else if (this.config.apiKey) {\r\n headers['x-api-key'] = this.config.apiKey;\r\n } else {\r\n throw new Error('Not authenticated. Run `clawrent auth login` first.');\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.json().catch(() => ({ message: response.statusText })) as Record<string, unknown>;\r\n throw new Error(`API error ${response.status}: ${errBody['message'] ?? JSON.stringify(errBody)}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n }\r\n}\r\n","export function printJson(data: unknown): void {\r\n process.stdout.write(JSON.stringify(data, null, 2) + '\\n');\r\n}\r\n\r\nexport function printError(message: string): void {\r\n process.stderr.write(`Error: ${message}\\n`);\r\n}\r\n\r\nexport function printSuccess(message: string): void {\r\n process.stdout.write(`${message}\\n`);\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerBrowseCommand(program: Command): void {\r\n program\r\n .command('browse')\r\n .description('Browse available agents on the marketplace')\r\n .option('-s, --search <query>', 'Search by name')\r\n .option('-c, --category <category>', 'Filter by category')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { search?: string; category?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.browse({\r\n search: opts.search,\r\n category: opts.category,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerAgentCommand(program: Command): void {\r\n program\r\n .command('agent <slug>')\r\n .description('Get agent details by slug')\r\n .action(async (slug: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getAgent(slug);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerSessionsCommand(program: Command): void {\r\n program\r\n .command('sessions')\r\n .description('List your sessions')\r\n .option('-r, --role <role>', 'Filter by role (consumer/provider)')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { role?: string; status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getSessions({\r\n role: opts.role,\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nexport function registerBalanceCommand(program: Command): void {\r\n program\r\n .command('balance')\r\n .description('Check wallet balance')\r\n .action(async () => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getBalance();\r\n printSuccess(`Balance: ${result.balance}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nexport function registerTopupCommand(program: Command): void {\r\n program\r\n .command('topup <amount>')\r\n .description('Top up wallet balance')\r\n .action(async (amount: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.topUp(amount);\r\n printSuccess(`New balance: ${result.balance}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerHealthCommand(program: Command): void {\r\n program\r\n .command('health')\r\n .description('Check platform health')\r\n .action(async () => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.health();\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerRentCommand(program: Command): void {\r\n program\r\n .command('rent')\r\n .description('Rent an agent (create a session)')\r\n .requiredOption('--agent-id <id>', 'Agent ID to rent')\r\n .requiredOption('--task <description>', 'Task description')\r\n .option('--permissions <json>', 'Granted permissions as JSON string', '{}')\r\n .action(async (opts: { agentId: string; task: string; permissions: string }) => {\r\n try {\r\n let grantedPermissions: Record<string, unknown> = {};\r\n try {\r\n grantedPermissions = JSON.parse(opts.permissions) as Record<string, unknown>;\r\n } catch {\r\n printError('Invalid JSON for --permissions');\r\n process.exit(1);\r\n }\r\n\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.rent({\r\n agentId: opts.agentId,\r\n taskDescription: opts.task,\r\n grantedPermissions,\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerEndCommand(program: Command): void {\r\n program\r\n .command('end <sessionId>')\r\n .description('End a session')\r\n .action(async (sessionId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.endSession(sessionId);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport WebSocket from 'ws';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../output.js';\r\n\r\nexport function registerSendCommand(program: Command): void {\r\n program\r\n .command('send <sessionId>')\r\n .description('Send a message to a session via WebSocket')\r\n .requiredOption('--content <text>', 'Message content')\r\n .option('--type <messageType>', 'Message type', 'dialogue.message')\r\n .option('--token <sessionToken>', 'Session token (auto-fetched if not provided)')\r\n .option('--wait <ms>', 'Wait for response (milliseconds)')\r\n .action(async (sessionId: string, opts: { content: string; type: string; token?: string; wait?: string }) => {\r\n try {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n\r\n // Get session token if not provided\r\n let sessionToken = opts.token;\r\n let role = 'consumer';\r\n if (!sessionToken) {\r\n const session = await client.getSession(sessionId);\r\n sessionToken = session['sessionToken'] as string;\r\n // Determine role\r\n if (config.userId && session['providerUserId'] === config.userId) {\r\n role = 'provider';\r\n }\r\n }\r\n\r\n if (!sessionToken) {\r\n printError('Could not determine session token. Use --token flag.');\r\n process.exit(1);\r\n }\r\n\r\n const wsUrl = `${config.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=${role}`;\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const ws = new WebSocket(wsUrl);\r\n let responded = false;\r\n\r\n ws.on('open', () => {\r\n // Build full protocol envelope as required by ClawRentMessageSchema\r\n const message = {\r\n id: `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId,\r\n timestamp: Date.now(),\r\n sender: { role, agentId: config.userId ?? 'unknown' },\r\n type: opts.type,\r\n payload: { content: opts.content, dialogueType: 'message' },\r\n };\r\n ws.send(JSON.stringify(message));\r\n\r\n if (opts.wait) {\r\n // Wait for response\r\n setTimeout(() => {\r\n if (!responded) {\r\n ws.close(1000);\r\n printSuccess('Message sent (no response within timeout).');\r\n resolve();\r\n }\r\n }, parseInt(opts.wait, 10));\r\n } else {\r\n // Send and close\r\n setTimeout(() => {\r\n ws.close(1000);\r\n printSuccess('Message sent.');\r\n resolve();\r\n }, 500);\r\n }\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const data = JSON.parse(raw.toString());\r\n if (data.type !== 'system.heartbeat_ack' && data.type !== 'system.peer_connected') {\r\n responded = true;\r\n printJson(data);\r\n if (opts.wait) {\r\n ws.close(1000);\r\n resolve();\r\n }\r\n }\r\n } catch {\r\n // ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n reject(err);\r\n });\r\n\r\n ws.on('close', () => {\r\n if (!responded && opts.wait) {\r\n resolve();\r\n }\r\n });\r\n });\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../../config.js';\r\nimport { ApiClient } from '../../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../../output.js';\r\n\r\nexport function registerProviderCommands(program: Command): void {\r\n const provider = program\r\n .command('provider')\r\n .description('Provider operations');\r\n\r\n // --- Agent subcommands ---\r\n const agent = provider\r\n .command('agent')\r\n .description('Manage your agents');\r\n\r\n agent\r\n .command('create')\r\n .description('Register a new agent')\r\n .requiredOption('--name <name>', 'Agent name')\r\n .requiredOption('--slug <slug>', 'Agent slug (URL-friendly)')\r\n .requiredOption('--description <desc>', 'Agent description (10-500 chars)')\r\n .option('--long-description <text>', 'Detailed description')\r\n .option('--pricing-model <model>', 'Pricing model (per_token/per_session/per_minute)', 'per_session')\r\n .option('--price <amount>', 'Price amount', '1.00')\r\n .option('--currency <cur>', 'Currency (CNY/USD)', 'CNY')\r\n .option('--hosting-type <type>', 'Hosting type (self_hosted/platform_hosted)', 'self_hosted')\r\n .option('--approval-mode <mode>', 'Approval mode (manual/auto)', 'manual')\r\n .option('--max-concurrent <n>', 'Max concurrent sessions', '5')\r\n .option('--capabilities <json>', 'Capabilities as JSON array')\r\n .action(async (opts: {\r\n name: string; slug: string; description: string; longDescription?: string;\r\n pricingModel: string; price: string; currency: string; hostingType: string;\r\n approvalMode: string; maxConcurrent: string; capabilities?: string;\r\n }) => {\r\n try {\r\n const data: Record<string, unknown> = {\r\n name: opts.name,\r\n slug: opts.slug,\r\n description: opts.description,\r\n pricingModel: opts.pricingModel,\r\n priceAmount: opts.price,\r\n currency: opts.currency,\r\n hostingType: opts.hostingType,\r\n approvalMode: opts.approvalMode,\r\n maxConcurrentSessions: parseInt(opts.maxConcurrent, 10),\r\n };\r\n if (opts.longDescription) data['longDescription'] = opts.longDescription;\r\n if (opts.capabilities) {\r\n try {\r\n data['capabilities'] = JSON.parse(opts.capabilities);\r\n } catch {\r\n printError('Invalid JSON for --capabilities');\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.registerAgent(data);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('list')\r\n .description('List your agents')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getMyAgents({\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('publish <agentId>')\r\n .description('Publish an agent (draft -> pending_review)')\r\n .action(async (agentId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.publishAgent(agentId);\r\n printSuccess('Agent published successfully.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('activate <agentId>')\r\n .description('Activate an agent (pending_review -> active)')\r\n .action(async (agentId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.activateAgent(agentId);\r\n printSuccess('Agent activated successfully.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('status <agentId>')\r\n .description('Set agent online status')\r\n .requiredOption('--status <status>', 'Online status (online/offline/busy)')\r\n .action(async (agentId: string, opts: { status: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.setOnlineStatus(agentId, opts.status);\r\n printSuccess(`Agent status set to ${opts.status}.`);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n // --- Provider session commands ---\r\n provider\r\n .command('sessions')\r\n .description('List provider sessions')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getSessions({\r\n role: 'provider',\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n provider\r\n .command('approve <sessionId>')\r\n .description('Approve a pending session')\r\n .action(async (sessionId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.approveSession(sessionId);\r\n printSuccess('Session approved.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport WebSocket from 'ws';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printError, printSuccess } from '../output.js';\r\nimport { isDaemonRunning, spawnDaemon, writePid, getLogFilePath } from '../daemon.js';\r\nimport { StdioBridge } from './stdio-bridge.js';\r\nimport { SessionManager } from './session-manager.js';\r\nimport {\r\n createCorrelationId,\r\n isResponse,\r\n isRequest,\r\n type JsonRpcMessage,\r\n type ResultPayload,\r\n} from './protocol.js';\r\n\r\ninterface ServeOptions {\r\n agentToken: string;\r\n autoApprove: boolean;\r\n pollInterval: string;\r\n daemon: boolean;\r\n}\r\n\r\n/** Pending instruction tracking: correlationId -> sessionId */\r\nconst pendingInstructions = new Map<string, string>();\r\n\r\n/** Known session IDs we've already seen (to avoid duplicate polling notifications) */\r\nconst knownPendingSessions = new Set<string>();\r\nconst activeSessions = new Set<string>();\r\n\r\nexport function registerServeCommand(program: Command): void {\r\n program\r\n .command('serve')\r\n .description('Start serve daemon - bridge WebSocket sessions to stdin/stdout')\r\n .requiredOption('--agent-token <token>', 'Agent token (agt_clawrent_*) for authentication')\r\n .option('--auto-approve', 'Automatically approve incoming sessions', false)\r\n .option('--poll-interval <ms>', 'Polling interval for pending sessions (ms)', '5000')\r\n .option('-d, --daemon', 'Run in background as a daemon process', false)\r\n .action(async (opts: ServeOptions) => {\r\n try {\r\n if (opts.daemon) {\r\n // --- Daemon mode: resolve agentId first, then fork ---\r\n const config = loadConfig();\r\n // Override token for this request\r\n config.token = opts.agentToken;\r\n const client = new ApiClient(config);\r\n\r\n let agentId: string;\r\n try {\r\n const agent = await client.getMyAgent();\r\n agentId = agent['id'] as string;\r\n } catch {\r\n printError('Failed to resolve agent from token. Is the token valid?');\r\n process.exit(1);\r\n }\r\n\r\n const { running, pid: existingPid } = isDaemonRunning(agentId);\r\n if (running) {\r\n printError(`Daemon already running for agent ${agentId} (PID: ${existingPid}). Use 'clawrent stop --agent-id ${agentId}' first.`);\r\n process.exit(1);\r\n }\r\n\r\n // Rebuild args without --daemon / -d\r\n const args: string[] = ['serve', '--agent-token', opts.agentToken];\r\n if (opts.autoApprove) args.push('--auto-approve');\r\n if (opts.pollInterval !== '5000') args.push('--poll-interval', opts.pollInterval);\r\n\r\n const pid = spawnDaemon(agentId, args);\r\n writePid(agentId, pid);\r\n printSuccess(`Daemon started for agent ${agentId} (PID: ${pid})\\nLogs: ${getLogFilePath(agentId)}`);\r\n process.exit(0);\r\n }\r\n\r\n await runDaemon(opts);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n\r\nasync function runDaemon(opts: ServeOptions): Promise<void> {\r\n const config = loadConfig();\r\n // Override token for agentToken auth\r\n config.token = opts.agentToken;\r\n const client = new ApiClient(config);\r\n const bridge = new StdioBridge();\r\n const sessionManager = new SessionManager(config.wsUrl);\r\n const pollInterval = parseInt(opts.pollInterval, 10);\r\n let agentWs: WebSocket | null = null;\r\n let agentHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n // --- 1. Startup: resolve agent from token ---\r\n let agentId: string;\r\n let agentName: string;\r\n try {\r\n const agent = await client.getMyAgent();\r\n agentId = agent['id'] as string;\r\n agentName = (agent['name'] as string) ?? agentId;\r\n sessionManager.agentId = agentId;\r\n } catch {\r\n printError('Failed to resolve agent from token. Is the token valid?');\r\n process.exit(1);\r\n }\r\n\r\n // --- 2. Notify ready ---\r\n bridge.writeNotification('ready', {\r\n agentId,\r\n agentName,\r\n });\r\n\r\n // --- 3. Wire up session manager events ---\r\n sessionManager.on('session:connected', (sessionId: string) => {\r\n bridge.writeNotification('session.connected', { sessionId });\r\n });\r\n\r\n sessionManager.on('session:message', (sessionId: string, message: Record<string, unknown>) => {\r\n const type = message['type'] as string;\r\n\r\n if (type?.startsWith('instruction.')) {\r\n // Instruction from consumer -> forward as JSON-RPC request (expects response)\r\n const corrId = createCorrelationId();\r\n pendingInstructions.set(corrId, sessionId);\r\n\r\n bridge.writeRequest('instruction', corrId, {\r\n sessionId,\r\n messageId: (message['id'] as string) ?? corrId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n sender: message['sender'],\r\n });\r\n } else if (type?.startsWith('dialogue.')) {\r\n // Dialogue from consumer -> forward as notification\r\n const payload = (message['payload'] as Record<string, unknown>) ?? {};\r\n bridge.writeNotification('dialogue', {\r\n sessionId,\r\n content: payload['content'] ?? '',\r\n dialogueType: payload['dialogueType'] ?? 'message',\r\n });\r\n } else if (type?.startsWith('result.')) {\r\n // Result from consumer -> forward as notification\r\n bridge.writeNotification('result', {\r\n sessionId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n });\r\n } else if (type === 'system.session_ended' || type === 'system.peer_disconnected') {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.ended', {\r\n sessionId,\r\n reason: type,\r\n });\r\n } else if (type === 'system.peer_connected') {\r\n bridge.writeNotification('session.peer_connected', { sessionId });\r\n } else if (type !== 'system.heartbeat_ack') {\r\n // Forward unknown messages as-is\r\n bridge.writeNotification('message', { sessionId, ...message });\r\n }\r\n });\r\n\r\n sessionManager.on('session:disconnected', (sessionId: string, reason: string) => {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.disconnected', { sessionId, reason });\r\n });\r\n\r\n sessionManager.on('session:reconnecting', (sessionId: string, delay: number) => {\r\n bridge.writeNotification('session.reconnecting', { sessionId, delay });\r\n });\r\n\r\n sessionManager.on('session:error', (sessionId: string, err: Error) => {\r\n bridge.writeNotification('session.error', { sessionId, message: err.message });\r\n });\r\n\r\n // --- 4. Handle stdin messages from agent ---\r\n bridge.start((msg: JsonRpcMessage) => {\r\n if (isResponse(msg)) {\r\n // Agent is responding to an instruction we forwarded\r\n const sessionId = pendingInstructions.get(msg.id);\r\n if (sessionId && msg.result) {\r\n pendingInstructions.delete(msg.id);\r\n const result = msg.result as unknown as ResultPayload;\r\n sessionManager.send(sessionId, {\r\n type: result.type ?? 'result.success',\r\n payload: result.payload ?? result,\r\n });\r\n }\r\n } else if (isRequest(msg)) {\r\n // Agent is proactively sending something\r\n if (msg.method === 'send') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n if (params?.['sessionId']) {\r\n const sent = sessionManager.send(params['sessionId'] as string, {\r\n type: params['type'] ?? 'dialogue.message',\r\n payload: (params['payload'] as Record<string, unknown>) ?? { content: '' },\r\n });\r\n bridge.writeResponse(msg.id, { success: sent });\r\n }\r\n } else if (msg.method === 'approve') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n const sid = params?.['sessionId'] as string | undefined;\r\n if (sid) {\r\n approveAndConnect(client, sessionManager, bridge, sid).catch(() => {\r\n bridge.writeResponse(msg.id, { success: false, error: 'Failed to approve' });\r\n }).then(() => {\r\n bridge.writeResponse(msg.id, { success: true });\r\n });\r\n }\r\n }\r\n }\r\n // Notifications from agent are ignored for now\r\n });\r\n\r\n // --- 5. Agent control channel (/ws/agent) + fallback poll loop ---\r\n let pollTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n function connectAgentWs(token: string) {\r\n const wsBase = config.wsUrl ?? config.apiUrl.replace(/^http/, 'ws');\r\n const url = `${wsBase}/ws/agent?token=${token}`;\r\n agentWs = new WebSocket(url);\r\n\r\n agentWs.on('open', () => {\r\n bridge.writeNotification('agent.connected', { agentId });\r\n\r\n // Start heartbeat on agent channel\r\n agentHeartbeatTimer = setInterval(() => {\r\n if (agentWs && agentWs.readyState === WebSocket.OPEN) {\r\n agentWs.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, 25_000);\r\n\r\n // Stop polling when WS is connected\r\n if (pollTimer) {\r\n clearInterval(pollTimer);\r\n pollTimer = null;\r\n }\r\n });\r\n\r\n agentWs.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString());\r\n const type = message.type as string;\r\n\r\n if (type === 'session.new' || type === 'session.approved') {\r\n const payload = message.payload as Record<string, unknown>;\r\n const sid = payload['sessionId'] as string;\r\n const sessionToken = payload['sessionToken'] as string;\r\n\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) return;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove && type === 'session.new') {\r\n approveAndConnect(client, sessionManager, bridge, sid);\r\n } else if (type === 'session.approved' && sessionToken) {\r\n // Already approved, connect directly\r\n activeSessions.add(sid);\r\n bridge.writeNotification('session.new', {\r\n sessionId: sid,\r\n sessionToken,\r\n taskDescription: (payload['taskDescription'] as string) ?? '',\r\n consumerUserId: (payload['consumerUserId'] as string) ?? '',\r\n });\r\n sessionManager.connect(sid, sessionToken);\r\n } else {\r\n bridge.writeNotification('session.pending', {\r\n sessionId: sid,\r\n taskDescription: (payload['taskDescription'] as string) ?? '',\r\n consumerUserId: (payload['consumerUserId'] as string) ?? '',\r\n });\r\n }\r\n }\r\n // Ignore heartbeat_ack and other system messages\r\n } catch {\r\n // Ignore parse errors on agent channel\r\n }\r\n });\r\n\r\n agentWs.on('close', (code, reason) => {\r\n if (agentHeartbeatTimer) {\r\n clearInterval(agentHeartbeatTimer);\r\n agentHeartbeatTimer = null;\r\n }\r\n bridge.writeNotification('agent.disconnected', {\r\n agentId,\r\n code,\r\n reason: reason.toString(),\r\n });\r\n\r\n // Fall back to polling\r\n if (!pollTimer) {\r\n startPollLoop();\r\n }\r\n\r\n // Reconnect after 5s unless deliberately closed\r\n if (code !== 1000 && code !== 4009) {\r\n setTimeout(() => connectAgentWs(token), 5000);\r\n }\r\n });\r\n\r\n agentWs.on('error', () => {\r\n // Error will trigger close event\r\n });\r\n }\r\n\r\n function startPollLoop() {\r\n pollTimer = setInterval(async () => {\r\n try {\r\n const sessions = (await client.getSessions({\r\n role: 'provider',\r\n status: 'pending_approval',\r\n })) as { data: Array<Record<string, unknown>> };\r\n\r\n for (const session of sessions.data ?? []) {\r\n const sid = session['id'] as string;\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) continue;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove) {\r\n await approveAndConnect(client, sessionManager, bridge, sid);\r\n } else {\r\n bridge.writeNotification('session.pending', {\r\n sessionId: sid,\r\n taskDescription: session['taskDescription'] ?? '',\r\n consumerUserId: session['consumerUserId'] ?? '',\r\n });\r\n }\r\n }\r\n } catch {\r\n // Silently retry on next poll\r\n }\r\n }, pollInterval);\r\n }\r\n\r\n // Connect via /ws/agent with the token\r\n connectAgentWs(opts.agentToken);\r\n\r\n // --- 6. Graceful shutdown ---\r\n const shutdown = async () => {\r\n if (pollTimer) clearInterval(pollTimer);\r\n if (agentHeartbeatTimer) clearInterval(agentHeartbeatTimer);\r\n bridge.stop();\r\n\r\n // Close agent WS (this triggers server-side offline update)\r\n if (agentWs) {\r\n try { agentWs.close(1000, 'Shutting down'); } catch { /* ignore */ }\r\n agentWs = null;\r\n }\r\n\r\n sessionManager.disconnectAll();\r\n bridge.writeNotification('shutdown', { reason: 'signal' });\r\n\r\n // Give a moment for messages to flush\r\n setTimeout(() => process.exit(0), 500);\r\n };\r\n\r\n process.on('SIGINT', () => { void shutdown(); });\r\n process.on('SIGTERM', () => { void shutdown(); });\r\n}\r\n\r\nasync function approveAndConnect(\r\n client: ApiClient,\r\n sessionManager: SessionManager,\r\n bridge: StdioBridge,\r\n sessionId: string,\r\n): Promise<void> {\r\n try {\r\n const approved = (await client.approveSession(sessionId)) as Record<string, unknown>;\r\n const sessionToken = approved['sessionToken'] as string;\r\n const taskDescription = approved['taskDescription'] as string;\r\n\r\n activeSessions.add(sessionId);\r\n\r\n bridge.writeNotification('session.new', {\r\n sessionId,\r\n sessionToken,\r\n taskDescription: taskDescription ?? '',\r\n consumerUserId: (approved['consumerUserId'] as string) ?? '',\r\n });\r\n\r\n sessionManager.connect(sessionId, sessionToken);\r\n } catch (err: unknown) {\r\n bridge.writeNotification('session.approve_failed', {\r\n sessionId,\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, unlinkSync, openSync, closeSync, mkdirSync, existsSync, readdirSync } from 'node:fs';\r\nimport { join, basename } from 'node:path';\r\nimport { spawn } from 'node:child_process';\r\nimport { getConfigDir } from './config.js';\r\n\r\nexport function getPidFilePath(agentId: string): string {\r\n return join(getConfigDir(), `serve-${agentId}.pid`);\r\n}\r\n\r\nexport function getLogFilePath(agentId: string): string {\r\n return join(getConfigDir(), `serve-${agentId}.log`);\r\n}\r\n\r\nexport function readPid(agentId: string): number | null {\r\n try {\r\n const content = readFileSync(getPidFilePath(agentId), 'utf-8').trim();\r\n const pid = parseInt(content, 10);\r\n return Number.isFinite(pid) && pid > 0 ? pid : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function writePid(agentId: string, pid: number): void {\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n writeFileSync(getPidFilePath(agentId), String(pid), 'utf-8');\r\n}\r\n\r\nexport function removePidFile(agentId: string): void {\r\n try {\r\n unlinkSync(getPidFilePath(agentId));\r\n } catch {\r\n // Ignore ENOENT\r\n }\r\n}\r\n\r\nexport function isProcessAlive(pid: number): boolean {\r\n try {\r\n process.kill(pid, 0);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function isDaemonRunning(agentId: string): { running: boolean; pid: number | null } {\r\n const pid = readPid(agentId);\r\n if (pid === null) return { running: false, pid: null };\r\n\r\n if (isProcessAlive(pid)) {\r\n return { running: true, pid };\r\n }\r\n\r\n // Stale PID file — process is dead, clean up\r\n removePidFile(agentId);\r\n return { running: false, pid: null };\r\n}\r\n\r\n/** List all running daemons by scanning PID files in config dir */\r\nexport function listRunningDaemons(): Array<{ agentId: string; pid: number }> {\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) return [];\r\n\r\n const results: Array<{ agentId: string; pid: number }> = [];\r\n\r\n for (const file of readdirSync(dir)) {\r\n const match = /^serve-(.+)\\.pid$/.exec(basename(file));\r\n if (!match) continue;\r\n\r\n const agentId = match[1]!;\r\n const { running, pid } = isDaemonRunning(agentId);\r\n if (running && pid !== null) {\r\n results.push({ agentId, pid });\r\n }\r\n }\r\n\r\n return results;\r\n}\r\n\r\nexport function spawnDaemon(agentId: string, args: string[]): number {\r\n const logFile = getLogFilePath(agentId);\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n const logFd = openSync(logFile, 'a');\r\n\r\n const child = spawn(process.argv[0]!, [process.argv[1]!, ...args], {\r\n detached: true,\r\n stdio: ['ignore', logFd, logFd],\r\n windowsHide: true,\r\n });\r\n\r\n child.unref();\r\n closeSync(logFd);\r\n\r\n if (!child.pid) {\r\n throw new Error('Failed to start daemon process');\r\n }\r\n\r\n return child.pid;\r\n}\r\n","import { createInterface } from 'node:readline';\r\nimport type { JsonRpcMessage, JsonRpcResponse, JsonRpcRequest, JsonRpcNotification } from './protocol.js';\r\n\r\nexport type StdinMessageHandler = (msg: JsonRpcMessage) => void;\r\n\r\n/**\r\n * StdioBridge handles JSON Lines communication over stdin/stdout.\r\n * Each line is a JSON-RPC 2.0 message.\r\n */\r\nexport class StdioBridge {\r\n private handler: StdinMessageHandler | null = null;\r\n private rl: ReturnType<typeof createInterface> | null = null;\r\n\r\n /** Start reading from stdin */\r\n start(handler: StdinMessageHandler): void {\r\n this.handler = handler;\r\n this.rl = createInterface({ input: process.stdin, crlfDelay: Infinity });\r\n\r\n this.rl.on('line', (line) => {\r\n const trimmed = line.trim();\r\n if (!trimmed) return;\r\n\r\n try {\r\n const msg = JSON.parse(trimmed) as JsonRpcMessage;\r\n if (msg.jsonrpc !== '2.0') {\r\n this.writeError('Invalid JSON-RPC: missing jsonrpc field');\r\n return;\r\n }\r\n this.handler?.(msg);\r\n } catch {\r\n this.writeError(`Failed to parse JSON: ${trimmed.slice(0, 100)}`);\r\n }\r\n });\r\n\r\n this.rl.on('close', () => {\r\n // stdin closed — process will shut down\r\n });\r\n }\r\n\r\n /** Stop reading */\r\n stop(): void {\r\n this.rl?.close();\r\n this.rl = null;\r\n }\r\n\r\n /** Write a JSON-RPC message to stdout */\r\n write(msg: JsonRpcMessage): void {\r\n process.stdout.write(JSON.stringify(msg) + '\\n');\r\n }\r\n\r\n /** Write a notification */\r\n writeNotification(method: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcNotification = { jsonrpc: '2.0', method, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a request (expects response) */\r\n writeRequest(method: string, id: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcRequest = { jsonrpc: '2.0', method, id, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a response */\r\n writeResponse(id: string, result: Record<string, unknown>): void {\r\n const msg: JsonRpcResponse = { jsonrpc: '2.0', id, result };\r\n this.write(msg);\r\n }\r\n\r\n /** Write an error notification to stdout */\r\n private writeError(message: string): void {\r\n this.writeNotification('error', { message });\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n","// JSON-RPC 2.0 protocol types for clawrent serve stdin/stdout communication\r\n\r\n/** Base JSON-RPC message */\r\nexport interface JsonRpcBase {\r\n jsonrpc: '2.0';\r\n}\r\n\r\n/** JSON-RPC request (has method + id) */\r\nexport interface JsonRpcRequest extends JsonRpcBase {\r\n method: string;\r\n id: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC notification (has method, no id) */\r\nexport interface JsonRpcNotification extends JsonRpcBase {\r\n method: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC response (has id + result or error) */\r\nexport interface JsonRpcResponse extends JsonRpcBase {\r\n id: string;\r\n result?: Record<string, unknown>;\r\n error?: { code: number; message: string; data?: unknown };\r\n}\r\n\r\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcResponse;\r\n\r\n// --- Daemon -> Agent (stdout) methods ---\r\n\r\nexport interface ReadyParams {\r\n agentId: string;\r\n agentName: string;\r\n}\r\n\r\nexport interface SessionNewParams {\r\n sessionId: string;\r\n sessionToken: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n}\r\n\r\nexport interface SessionPendingParams {\r\n sessionId: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n}\r\n\r\nexport interface InstructionParams {\r\n sessionId: string;\r\n messageId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n sender?: Record<string, unknown>;\r\n}\r\n\r\nexport interface DialogueParams {\r\n sessionId: string;\r\n content: string;\r\n dialogueType: string;\r\n}\r\n\r\nexport interface SessionEndedParams {\r\n sessionId: string;\r\n reason: string;\r\n}\r\n\r\n// --- Agent -> Daemon (stdin) methods ---\r\n\r\nexport interface ResultPayload {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface SendParams {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface ApproveParams {\r\n sessionId: string;\r\n}\r\n\r\n// --- Helpers ---\r\n\r\nlet correlationCounter = 0;\r\n\r\nexport function createCorrelationId(): string {\r\n return `corr_${Date.now().toString(36)}_${(correlationCounter++).toString(36)}`;\r\n}\r\n\r\nexport function createNotification(method: string, params: Record<string, unknown>): JsonRpcNotification {\r\n return { jsonrpc: '2.0', method, params };\r\n}\r\n\r\nexport function createRequest(method: string, params: Record<string, unknown>, id?: string): JsonRpcRequest {\r\n return { jsonrpc: '2.0', method, id: id ?? createCorrelationId(), params };\r\n}\r\n\r\nexport function isResponse(msg: JsonRpcMessage): msg is JsonRpcResponse {\r\n return 'id' in msg && ('result' in msg || 'error' in msg) && !('method' in msg);\r\n}\r\n\r\nexport function isRequest(msg: JsonRpcMessage): msg is JsonRpcRequest {\r\n return 'method' in msg && 'id' in msg;\r\n}\r\n\r\nexport function isNotification(msg: JsonRpcMessage): msg is JsonRpcNotification {\r\n return 'method' in msg && !('id' in msg);\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, removePidFile, isProcessAlive, listRunningDaemons } from '../daemon.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nasync function stopOne(agentId: string): Promise<boolean> {\r\n const { running, pid } = isDaemonRunning(agentId);\r\n\r\n if (!running || pid === null) {\r\n return false;\r\n }\r\n\r\n try {\r\n process.kill(pid, 'SIGTERM');\r\n } catch (err: unknown) {\r\n const code = (err as NodeJS.ErrnoException).code;\r\n if (code === 'ESRCH') {\r\n removePidFile(agentId);\r\n return true;\r\n }\r\n if (code === 'EPERM') {\r\n printError(`Permission denied. Cannot stop daemon for agent ${agentId} (PID: ${pid}).`);\r\n return false;\r\n }\r\n throw err;\r\n }\r\n\r\n const maxWait = 3000;\r\n const interval = 200;\r\n let waited = 0;\r\n\r\n while (waited < maxWait) {\r\n await new Promise((r) => setTimeout(r, interval));\r\n waited += interval;\r\n if (!isProcessAlive(pid)) {\r\n removePidFile(agentId);\r\n printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);\r\n return true;\r\n }\r\n }\r\n\r\n try {\r\n process.kill(pid, 'SIGKILL');\r\n } catch {\r\n // May have exited between check and kill\r\n }\r\n\r\n removePidFile(agentId);\r\n printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);\r\n return true;\r\n}\r\n\r\nexport function registerStopCommand(program: Command): void {\r\n program\r\n .command('stop')\r\n .description('Stop background serve daemon(s)')\r\n .option('--agent-id <id>', 'Stop daemon for a specific agent')\r\n .option('--all', 'Stop all running daemons', false)\r\n .action(async (opts: { agentId?: string; all: boolean }) => {\r\n if (opts.agentId) {\r\n const stopped = await stopOne(opts.agentId);\r\n if (!stopped) {\r\n printSuccess(`No daemon running for agent ${opts.agentId}.`);\r\n }\r\n return;\r\n }\r\n\r\n // Default: stop all\r\n const daemons = listRunningDaemons();\r\n if (daemons.length === 0) {\r\n printSuccess('No daemons are running.');\r\n return;\r\n }\r\n\r\n for (const d of daemons) {\r\n await stopOne(d.agentId);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, getLogFilePath, listRunningDaemons } from '../daemon.js';\r\nimport { printJson } from '../output.js';\r\n\r\nexport function registerStatusCommand(program: Command): void {\r\n program\r\n .command('status')\r\n .description('Check running serve daemon(s)')\r\n .option('--agent-id <id>', 'Check daemon for a specific agent')\r\n .action((opts: { agentId?: string }) => {\r\n if (opts.agentId) {\r\n const { running, pid } = isDaemonRunning(opts.agentId);\r\n if (running && pid !== null) {\r\n printJson({ status: 'running', agentId: opts.agentId, pid, logFile: getLogFilePath(opts.agentId) });\r\n } else {\r\n printJson({ status: 'stopped', agentId: opts.agentId });\r\n }\r\n return;\r\n }\r\n\r\n // List all running daemons\r\n const daemons = listRunningDaemons();\r\n if (daemons.length === 0) {\r\n printJson({ daemons: [] });\r\n } else {\r\n printJson({\r\n daemons: daemons.map((d) => ({\r\n agentId: d.agentId,\r\n pid: d.pid,\r\n logFile: getLogFilePath(d.agentId),\r\n })),\r\n });\r\n }\r\n });\r\n}\r\n"],"mappings":"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","names":["readFileSync","join","program","program","program","program","program","program","program","program","program","program","program","WebSocket","readFileSync","writeFileSync","unlinkSync","mkdirSync","existsSync","join","join","readFileSync","existsSync","mkdirSync","writeFileSync","unlinkSync","createInterface","WebSocket","program","WebSocket","program","program","readFileSync","join"]}
|
package/dist/lib.d.ts
CHANGED
|
@@ -65,6 +65,8 @@ declare class ApiClient {
|
|
|
65
65
|
limit?: number;
|
|
66
66
|
status?: string;
|
|
67
67
|
}): Promise<unknown>;
|
|
68
|
+
/** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */
|
|
69
|
+
getMyAgent(): Promise<Record<string, unknown>>;
|
|
68
70
|
publishAgent(agentId: string): Promise<unknown>;
|
|
69
71
|
activateAgent(agentId: string): Promise<unknown>;
|
|
70
72
|
setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown>;
|
package/dist/lib.js
CHANGED
|
@@ -81,6 +81,10 @@ var ApiClient = class {
|
|
|
81
81
|
const qs = params.toString();
|
|
82
82
|
return this.request("GET", `/api/agents/my${qs ? `?${qs}` : ""}`);
|
|
83
83
|
}
|
|
84
|
+
/** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */
|
|
85
|
+
async getMyAgent() {
|
|
86
|
+
return this.request("GET", "/api/agents/me/agent");
|
|
87
|
+
}
|
|
84
88
|
async publishAgent(agentId) {
|
|
85
89
|
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/publish`);
|
|
86
90
|
}
|
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api-client.ts","../src/config.ts","../src/serve/session-manager.ts"],"sourcesContent":["import type { ClawRentConfig } from './config.js';\r\n\r\nexport class ApiClient {\r\n private config: ClawRentConfig;\r\n\r\n constructor(config: ClawRentConfig) {\r\n this.config = config;\r\n }\r\n\r\n get apiUrl(): string {\r\n return this.config.apiUrl;\r\n }\r\n\r\n get wsUrl(): string {\r\n return this.config.wsUrl;\r\n }\r\n\r\n get userId(): string | undefined {\r\n return this.config.userId;\r\n }\r\n\r\n // --- Auth (no auth needed) ---\r\n\r\n async login(email: string, password: string): Promise<{ user: { id: string; email: string; name: string; role: string }; token: string }> {\r\n return this.request('POST', '/api/auth/login', { email, password }, false);\r\n }\r\n\r\n async getMe(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/auth/me');\r\n }\r\n\r\n // --- Marketplace ---\r\n\r\n async browse(query?: { search?: string; category?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.search) params.set('search', query.search);\r\n if (query?.category) params.set('category', query.category);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/marketplace/browse${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getAgent(slug: string): Promise<unknown> {\r\n return this.request('GET', `/api/marketplace/agents/${encodeURIComponent(slug)}`);\r\n }\r\n\r\n // --- Sessions ---\r\n\r\n async rent(options: { agentId: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }): Promise<unknown> {\r\n return this.request('POST', '/api/sessions', {\r\n agentId: options.agentId,\r\n taskDescription: options.taskDescription,\r\n grantedPermissions: options.grantedPermissions ?? {},\r\n });\r\n }\r\n\r\n async getSessions(query?: { role?: string; status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.role) params.set('role', query.role);\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/sessions${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getSession(sessionId: string): Promise<Record<string, unknown>> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}`);\r\n }\r\n\r\n async getSessionMessages(sessionId: string): Promise<unknown> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}/messages`);\r\n }\r\n\r\n async endSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/end`);\r\n }\r\n\r\n async approveSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/approve`);\r\n }\r\n\r\n // --- Billing ---\r\n\r\n async getBalance(): Promise<{ balance: string }> {\r\n return this.request('GET', '/api/billing/wallet');\r\n }\r\n\r\n async topUp(amount: string): Promise<{ balance: string }> {\r\n return this.request('POST', '/api/billing/wallet/topup', { amount });\r\n }\r\n\r\n // --- Provider: Agents ---\r\n\r\n async registerAgent(data: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', '/api/agents', data);\r\n }\r\n\r\n async getMyAgents(query?: { page?: number; limit?: number; status?: string }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n if (query?.status) params.set('status', query.status);\r\n const qs = params.toString();\r\n return this.request('GET', `/api/agents/my${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async publishAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`);\r\n }\r\n\r\n async activateAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/activate`);\r\n }\r\n\r\n async setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown> {\r\n return this.request('PATCH', `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });\r\n }\r\n\r\n async generateAgentToken(agentId: string): Promise<{ agentId: string; token: string; createdAt: string; warning: string }> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n async revokeAgentToken(agentId: string): Promise<{ message: string }> {\r\n return this.request('DELETE', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n // --- Orders ---\r\n\r\n async createOrder(data: {\r\n items: Array<{ providerAgentId: string; consumerAgentId?: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }>;\r\n note?: string;\r\n fromCart?: boolean;\r\n }): Promise<unknown> {\r\n return this.request('POST', '/api/orders', data);\r\n }\r\n\r\n async getOrders(query?: { status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/orders${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getOrder(orderId: string): Promise<unknown> {\r\n return this.request('GET', `/api/orders/${encodeURIComponent(orderId)}`);\r\n }\r\n\r\n async cancelOrder(orderId: string): Promise<unknown> {\r\n return this.request('POST', `/api/orders/${encodeURIComponent(orderId)}/cancel`);\r\n }\r\n\r\n // --- Cart ---\r\n\r\n async getCart(): Promise<unknown> {\r\n return this.request('GET', '/api/cart');\r\n }\r\n\r\n async addToCart(data: { providerAgentId: string; taskDescription: string }): Promise<unknown> {\r\n return this.request('POST', '/api/cart', data);\r\n }\r\n\r\n async updateCartItem(itemId: string, data: { taskDescription: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/cart/${encodeURIComponent(itemId)}`, data);\r\n }\r\n\r\n async removeFromCart(itemId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/cart/${encodeURIComponent(itemId)}`);\r\n }\r\n\r\n async clearCart(): Promise<unknown> {\r\n return this.request('DELETE', '/api/cart');\r\n }\r\n\r\n // --- Favorites ---\r\n\r\n async listFavorites(query?: { page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/favorites${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async addFavorite(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n async removeFavorite(agentId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n // --- Health ---\r\n\r\n async health(): Promise<unknown> {\r\n return this.request('GET', '/api/health', undefined, false);\r\n }\r\n\r\n // --- Private ---\r\n\r\n private async request<T = any>(method: string, path: string, body?: unknown, requireAuth: boolean = true): Promise<T> {\r\n const url = `${this.config.apiUrl}${path}`;\r\n const headers: Record<string, string> = {};\r\n\r\n if (body !== undefined) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n if (requireAuth) {\r\n if (this.config.token) {\r\n headers['Authorization'] = `Bearer ${this.config.token}`;\r\n } else if (this.config.apiKey) {\r\n headers['x-api-key'] = this.config.apiKey;\r\n } else {\r\n throw new Error('Not authenticated. Run `clawrent auth login` first.');\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.json().catch(() => ({ message: response.statusText })) as Record<string, unknown>;\r\n throw new Error(`API error ${response.status}: ${errBody['message'] ?? JSON.stringify(errBody)}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\n\r\nexport interface ClawRentConfig {\r\n apiUrl: string;\r\n wsUrl: string;\r\n token?: string;\r\n apiKey?: string;\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: ClawRentConfig = {\r\n apiUrl: 'https://clawrent.cloud',\r\n wsUrl: 'wss://clawrent.cloud',\r\n};\r\n\r\nexport function getConfigDir(): string {\r\n return join(homedir(), '.clawrent');\r\n}\r\n\r\nfunction getConfigFilePath(): string {\r\n return join(getConfigDir(), 'config.json');\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return getConfigFilePath();\r\n}\r\n\r\nexport function loadConfig(): ClawRentConfig {\r\n let fileConfig: Partial<ClawRentConfig> = {};\r\n\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n const raw = readFileSync(configPath, 'utf-8');\r\n fileConfig = JSON.parse(raw) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Ignore corrupt config file\r\n }\r\n }\r\n\r\n // Migration: remove stale localhost URLs saved by older CLI versions.\r\n // These override the new production defaults and break remote connections.\r\n if (fileConfig.apiUrl?.includes('localhost') || fileConfig.wsUrl?.includes('localhost')) {\r\n delete fileConfig.apiUrl;\r\n delete fileConfig.wsUrl;\r\n // Persist the cleanup so it only runs once\r\n try {\r\n const cleaned = { ...fileConfig };\r\n writeFileSync(configPath, JSON.stringify(cleaned, null, 2), 'utf-8');\r\n } catch {\r\n // Non-fatal\r\n }\r\n }\r\n\r\n // Merge: defaults < file < env vars\r\n const config: ClawRentConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...fileConfig,\r\n };\r\n\r\n // Env vars always override\r\n const envApiUrl = process.env['CLAWRENT_API_URL'];\r\n const envWsUrl = process.env['CLAWRENT_WS_URL'];\r\n const envToken = process.env['CLAWRENT_TOKEN'];\r\n const envApiKey = process.env['CLAWRENT_API_KEY'];\r\n const envUserId = process.env['CLAWRENT_USER_ID'];\r\n\r\n if (envApiUrl) config.apiUrl = envApiUrl;\r\n if (envWsUrl) config.wsUrl = envWsUrl;\r\n if (envToken) config.token = envToken;\r\n if (envApiKey) config.apiKey = envApiKey;\r\n if (envUserId) config.userId = envUserId;\r\n\r\n return config;\r\n}\r\n\r\nexport function saveConfig(partial: Partial<ClawRentConfig>): void {\r\n const configDir = getConfigDir();\r\n if (!existsSync(configDir)) {\r\n mkdirSync(configDir, { recursive: true });\r\n }\r\n\r\n let existing: Partial<ClawRentConfig> = {};\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n existing = JSON.parse(readFileSync(configPath, 'utf-8')) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Overwrite corrupt file\r\n }\r\n }\r\n\r\n const merged = { ...existing, ...partial };\r\n writeFileSync(configPath, JSON.stringify(merged, null, 2), 'utf-8');\r\n}\r\n\r\nexport function clearConfig(): void {\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n unlinkSync(configPath);\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/api-client.ts","../src/config.ts","../src/serve/session-manager.ts"],"sourcesContent":["import type { ClawRentConfig } from './config.js';\r\n\r\nexport class ApiClient {\r\n private config: ClawRentConfig;\r\n\r\n constructor(config: ClawRentConfig) {\r\n this.config = config;\r\n }\r\n\r\n get apiUrl(): string {\r\n return this.config.apiUrl;\r\n }\r\n\r\n get wsUrl(): string {\r\n return this.config.wsUrl;\r\n }\r\n\r\n get userId(): string | undefined {\r\n return this.config.userId;\r\n }\r\n\r\n // --- Auth (no auth needed) ---\r\n\r\n async login(email: string, password: string): Promise<{ user: { id: string; email: string; name: string; role: string }; token: string }> {\r\n return this.request('POST', '/api/auth/login', { email, password }, false);\r\n }\r\n\r\n async getMe(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/auth/me');\r\n }\r\n\r\n // --- Marketplace ---\r\n\r\n async browse(query?: { search?: string; category?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.search) params.set('search', query.search);\r\n if (query?.category) params.set('category', query.category);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/marketplace/browse${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getAgent(slug: string): Promise<unknown> {\r\n return this.request('GET', `/api/marketplace/agents/${encodeURIComponent(slug)}`);\r\n }\r\n\r\n // --- Sessions ---\r\n\r\n async rent(options: { agentId: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }): Promise<unknown> {\r\n return this.request('POST', '/api/sessions', {\r\n agentId: options.agentId,\r\n taskDescription: options.taskDescription,\r\n grantedPermissions: options.grantedPermissions ?? {},\r\n });\r\n }\r\n\r\n async getSessions(query?: { role?: string; status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.role) params.set('role', query.role);\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/sessions${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getSession(sessionId: string): Promise<Record<string, unknown>> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}`);\r\n }\r\n\r\n async getSessionMessages(sessionId: string): Promise<unknown> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}/messages`);\r\n }\r\n\r\n async endSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/end`);\r\n }\r\n\r\n async approveSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/approve`);\r\n }\r\n\r\n // --- Billing ---\r\n\r\n async getBalance(): Promise<{ balance: string }> {\r\n return this.request('GET', '/api/billing/wallet');\r\n }\r\n\r\n async topUp(amount: string): Promise<{ balance: string }> {\r\n return this.request('POST', '/api/billing/wallet/topup', { amount });\r\n }\r\n\r\n // --- Provider: Agents ---\r\n\r\n async registerAgent(data: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', '/api/agents', data);\r\n }\r\n\r\n async getMyAgents(query?: { page?: number; limit?: number; status?: string }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n if (query?.status) params.set('status', query.status);\r\n const qs = params.toString();\r\n return this.request('GET', `/api/agents/my${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */\r\n async getMyAgent(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/agents/me/agent');\r\n }\r\n\r\n async publishAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`);\r\n }\r\n\r\n async activateAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/activate`);\r\n }\r\n\r\n async setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown> {\r\n return this.request('PATCH', `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });\r\n }\r\n\r\n async generateAgentToken(agentId: string): Promise<{ agentId: string; token: string; createdAt: string; warning: string }> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n async revokeAgentToken(agentId: string): Promise<{ message: string }> {\r\n return this.request('DELETE', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n // --- Orders ---\r\n\r\n async createOrder(data: {\r\n items: Array<{ providerAgentId: string; consumerAgentId?: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }>;\r\n note?: string;\r\n fromCart?: boolean;\r\n }): Promise<unknown> {\r\n return this.request('POST', '/api/orders', data);\r\n }\r\n\r\n async getOrders(query?: { status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/orders${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getOrder(orderId: string): Promise<unknown> {\r\n return this.request('GET', `/api/orders/${encodeURIComponent(orderId)}`);\r\n }\r\n\r\n async cancelOrder(orderId: string): Promise<unknown> {\r\n return this.request('POST', `/api/orders/${encodeURIComponent(orderId)}/cancel`);\r\n }\r\n\r\n // --- Cart ---\r\n\r\n async getCart(): Promise<unknown> {\r\n return this.request('GET', '/api/cart');\r\n }\r\n\r\n async addToCart(data: { providerAgentId: string; taskDescription: string }): Promise<unknown> {\r\n return this.request('POST', '/api/cart', data);\r\n }\r\n\r\n async updateCartItem(itemId: string, data: { taskDescription: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/cart/${encodeURIComponent(itemId)}`, data);\r\n }\r\n\r\n async removeFromCart(itemId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/cart/${encodeURIComponent(itemId)}`);\r\n }\r\n\r\n async clearCart(): Promise<unknown> {\r\n return this.request('DELETE', '/api/cart');\r\n }\r\n\r\n // --- Favorites ---\r\n\r\n async listFavorites(query?: { page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/favorites${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async addFavorite(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n async removeFavorite(agentId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n // --- Health ---\r\n\r\n async health(): Promise<unknown> {\r\n return this.request('GET', '/api/health', undefined, false);\r\n }\r\n\r\n // --- Private ---\r\n\r\n private async request<T = any>(method: string, path: string, body?: unknown, requireAuth: boolean = true): Promise<T> {\r\n const url = `${this.config.apiUrl}${path}`;\r\n const headers: Record<string, string> = {};\r\n\r\n if (body !== undefined) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n if (requireAuth) {\r\n if (this.config.token) {\r\n headers['Authorization'] = `Bearer ${this.config.token}`;\r\n } else if (this.config.apiKey) {\r\n headers['x-api-key'] = this.config.apiKey;\r\n } else {\r\n throw new Error('Not authenticated. Run `clawrent auth login` first.');\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.json().catch(() => ({ message: response.statusText })) as Record<string, unknown>;\r\n throw new Error(`API error ${response.status}: ${errBody['message'] ?? JSON.stringify(errBody)}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\n\r\nexport interface ClawRentConfig {\r\n apiUrl: string;\r\n wsUrl: string;\r\n token?: string;\r\n apiKey?: string;\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: ClawRentConfig = {\r\n apiUrl: 'https://clawrent.cloud',\r\n wsUrl: 'wss://clawrent.cloud',\r\n};\r\n\r\nexport function getConfigDir(): string {\r\n return join(homedir(), '.clawrent');\r\n}\r\n\r\nfunction getConfigFilePath(): string {\r\n return join(getConfigDir(), 'config.json');\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return getConfigFilePath();\r\n}\r\n\r\nexport function loadConfig(): ClawRentConfig {\r\n let fileConfig: Partial<ClawRentConfig> = {};\r\n\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n const raw = readFileSync(configPath, 'utf-8');\r\n fileConfig = JSON.parse(raw) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Ignore corrupt config file\r\n }\r\n }\r\n\r\n // Migration: remove stale localhost URLs saved by older CLI versions.\r\n // These override the new production defaults and break remote connections.\r\n if (fileConfig.apiUrl?.includes('localhost') || fileConfig.wsUrl?.includes('localhost')) {\r\n delete fileConfig.apiUrl;\r\n delete fileConfig.wsUrl;\r\n // Persist the cleanup so it only runs once\r\n try {\r\n const cleaned = { ...fileConfig };\r\n writeFileSync(configPath, JSON.stringify(cleaned, null, 2), 'utf-8');\r\n } catch {\r\n // Non-fatal\r\n }\r\n }\r\n\r\n // Merge: defaults < file < env vars\r\n const config: ClawRentConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...fileConfig,\r\n };\r\n\r\n // Env vars always override\r\n const envApiUrl = process.env['CLAWRENT_API_URL'];\r\n const envWsUrl = process.env['CLAWRENT_WS_URL'];\r\n const envToken = process.env['CLAWRENT_TOKEN'];\r\n const envApiKey = process.env['CLAWRENT_API_KEY'];\r\n const envUserId = process.env['CLAWRENT_USER_ID'];\r\n\r\n if (envApiUrl) config.apiUrl = envApiUrl;\r\n if (envWsUrl) config.wsUrl = envWsUrl;\r\n if (envToken) config.token = envToken;\r\n if (envApiKey) config.apiKey = envApiKey;\r\n if (envUserId) config.userId = envUserId;\r\n\r\n return config;\r\n}\r\n\r\nexport function saveConfig(partial: Partial<ClawRentConfig>): void {\r\n const configDir = getConfigDir();\r\n if (!existsSync(configDir)) {\r\n mkdirSync(configDir, { recursive: true });\r\n }\r\n\r\n let existing: Partial<ClawRentConfig> = {};\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n existing = JSON.parse(readFileSync(configPath, 'utf-8')) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Overwrite corrupt file\r\n }\r\n }\r\n\r\n const merged = { ...existing, ...partial };\r\n writeFileSync(configPath, JSON.stringify(merged, null, 2), 'utf-8');\r\n}\r\n\r\nexport function clearConfig(): void {\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n unlinkSync(configPath);\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clawrent/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/lib.js",
|
|
6
6
|
"types": "./dist/lib.d.ts",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"commander": "^13.0.0",
|
|
24
24
|
"ws": "^8.18.0",
|
|
25
|
-
"@clawrent/
|
|
26
|
-
"@clawrent/
|
|
25
|
+
"@clawrent/shared-types": "0.1.0",
|
|
26
|
+
"@clawrent/protocol": "0.1.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^22.0.0",
|