@clawrent/cli 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +150 -2
- package/dist/index.js.map +1 -1
- package/dist/lib.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
5
|
+
import { dirname, join as join3 } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
4
7
|
import { Command } from "commander";
|
|
5
8
|
|
|
6
9
|
// src/commands/auth.ts
|
|
@@ -687,6 +690,75 @@ function registerProviderCommands(program2) {
|
|
|
687
690
|
// src/serve/index.ts
|
|
688
691
|
import WebSocket3 from "ws";
|
|
689
692
|
|
|
693
|
+
// 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";
|
|
696
|
+
import { spawn } from "child_process";
|
|
697
|
+
function getPidFilePath() {
|
|
698
|
+
return join2(getConfigDir(), "serve.pid");
|
|
699
|
+
}
|
|
700
|
+
function getLogFilePath() {
|
|
701
|
+
return join2(getConfigDir(), "serve.log");
|
|
702
|
+
}
|
|
703
|
+
function readPid() {
|
|
704
|
+
try {
|
|
705
|
+
const content = readFileSync2(getPidFilePath(), "utf-8").trim();
|
|
706
|
+
const pid = parseInt(content, 10);
|
|
707
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
708
|
+
} catch {
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
function writePid(pid) {
|
|
713
|
+
const dir = getConfigDir();
|
|
714
|
+
if (!existsSync2(dir)) {
|
|
715
|
+
mkdirSync2(dir, { recursive: true });
|
|
716
|
+
}
|
|
717
|
+
writeFileSync2(getPidFilePath(), String(pid), "utf-8");
|
|
718
|
+
}
|
|
719
|
+
function removePidFile() {
|
|
720
|
+
try {
|
|
721
|
+
unlinkSync2(getPidFilePath());
|
|
722
|
+
} catch {
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function isProcessAlive(pid) {
|
|
726
|
+
try {
|
|
727
|
+
process.kill(pid, 0);
|
|
728
|
+
return true;
|
|
729
|
+
} catch {
|
|
730
|
+
return false;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
function isDaemonRunning() {
|
|
734
|
+
const pid = readPid();
|
|
735
|
+
if (pid === null) return { running: false, pid: null };
|
|
736
|
+
if (isProcessAlive(pid)) {
|
|
737
|
+
return { running: true, pid };
|
|
738
|
+
}
|
|
739
|
+
removePidFile();
|
|
740
|
+
return { running: false, pid: null };
|
|
741
|
+
}
|
|
742
|
+
function spawnDaemon(args) {
|
|
743
|
+
const logFile = getLogFilePath();
|
|
744
|
+
const dir = getConfigDir();
|
|
745
|
+
if (!existsSync2(dir)) {
|
|
746
|
+
mkdirSync2(dir, { recursive: true });
|
|
747
|
+
}
|
|
748
|
+
const logFd = openSync(logFile, "a");
|
|
749
|
+
const child = spawn(process.argv[0], [process.argv[1], ...args], {
|
|
750
|
+
detached: true,
|
|
751
|
+
stdio: ["ignore", logFd, logFd],
|
|
752
|
+
windowsHide: true
|
|
753
|
+
});
|
|
754
|
+
child.unref();
|
|
755
|
+
closeSync(logFd);
|
|
756
|
+
if (!child.pid) {
|
|
757
|
+
throw new Error("Failed to start daemon process");
|
|
758
|
+
}
|
|
759
|
+
return child.pid;
|
|
760
|
+
}
|
|
761
|
+
|
|
690
762
|
// src/serve/stdio-bridge.ts
|
|
691
763
|
import { createInterface as createInterface2 } from "readline";
|
|
692
764
|
var StdioBridge = class {
|
|
@@ -879,8 +951,24 @@ var pendingInstructions = /* @__PURE__ */ new Map();
|
|
|
879
951
|
var knownPendingSessions = /* @__PURE__ */ new Set();
|
|
880
952
|
var activeSessions = /* @__PURE__ */ new Set();
|
|
881
953
|
function registerServeCommand(program2) {
|
|
882
|
-
program2.command("serve").description("Start serve daemon - bridge WebSocket sessions to stdin/stdout").requiredOption("--agent-id <id>", "Agent ID to serve").option("--agent-token <token>", "Agent token for /ws/agent control channel").option("--auto-approve", "Automatically approve incoming sessions", false).option("--poll-interval <ms>", "Polling interval for pending sessions (ms)", "5000").action(async (opts) => {
|
|
954
|
+
program2.command("serve").description("Start serve daemon - bridge WebSocket sessions to stdin/stdout").requiredOption("--agent-id <id>", "Agent ID to serve").option("--agent-token <token>", "Agent token for /ws/agent control channel").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) => {
|
|
883
955
|
try {
|
|
956
|
+
if (opts.daemon) {
|
|
957
|
+
const { running, pid: existingPid } = isDaemonRunning();
|
|
958
|
+
if (running) {
|
|
959
|
+
printError(`Daemon already running (PID: ${existingPid}). Use 'clawrent stop' first.`);
|
|
960
|
+
process.exit(1);
|
|
961
|
+
}
|
|
962
|
+
const args = ["serve", "--agent-id", opts.agentId];
|
|
963
|
+
if (opts.agentToken) args.push("--agent-token", opts.agentToken);
|
|
964
|
+
if (opts.autoApprove) args.push("--auto-approve");
|
|
965
|
+
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()}`);
|
|
970
|
+
process.exit(0);
|
|
971
|
+
}
|
|
884
972
|
await runDaemon(opts);
|
|
885
973
|
} catch (err) {
|
|
886
974
|
printError(err instanceof Error ? err.message : String(err));
|
|
@@ -1152,9 +1240,67 @@ async function approveAndConnect(client, sessionManager, bridge, sessionId) {
|
|
|
1152
1240
|
}
|
|
1153
1241
|
}
|
|
1154
1242
|
|
|
1243
|
+
// src/commands/stop.ts
|
|
1244
|
+
function registerStopCommand(program2) {
|
|
1245
|
+
program2.command("stop").description("Stop the background serve daemon").action(async () => {
|
|
1246
|
+
const { running, pid } = isDaemonRunning();
|
|
1247
|
+
if (!running || pid === null) {
|
|
1248
|
+
printSuccess("No daemon is running.");
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
try {
|
|
1252
|
+
process.kill(pid, "SIGTERM");
|
|
1253
|
+
} catch (err) {
|
|
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;
|
|
1265
|
+
}
|
|
1266
|
+
const maxWait = 3e3;
|
|
1267
|
+
const interval = 200;
|
|
1268
|
+
let waited = 0;
|
|
1269
|
+
while (waited < maxWait) {
|
|
1270
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
1271
|
+
waited += interval;
|
|
1272
|
+
if (!isProcessAlive(pid)) {
|
|
1273
|
+
removePidFile();
|
|
1274
|
+
printSuccess(`Daemon stopped (PID: ${pid}).`);
|
|
1275
|
+
return;
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
try {
|
|
1279
|
+
process.kill(pid, "SIGKILL");
|
|
1280
|
+
} catch {
|
|
1281
|
+
}
|
|
1282
|
+
removePidFile();
|
|
1283
|
+
printSuccess(`Daemon stopped (PID: ${pid}).`);
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// src/commands/status.ts
|
|
1288
|
+
function registerStatusCommand(program2) {
|
|
1289
|
+
program2.command("status").description("Check if the serve daemon is running").action(() => {
|
|
1290
|
+
const { running, pid } = isDaemonRunning();
|
|
1291
|
+
if (running && pid !== null) {
|
|
1292
|
+
printJson({ status: "running", pid, logFile: getLogFilePath() });
|
|
1293
|
+
} else {
|
|
1294
|
+
printJson({ status: "stopped" });
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1155
1299
|
// src/index.ts
|
|
1300
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1301
|
+
var pkg = JSON.parse(readFileSync3(join3(__dirname, "..", "package.json"), "utf-8"));
|
|
1156
1302
|
var program = new Command();
|
|
1157
|
-
program.name("clawrent").description("ClawRent CLI - Agent capability rental platform").version(
|
|
1303
|
+
program.name("clawrent").description("ClawRent CLI - Agent capability rental platform").version(pkg.version);
|
|
1158
1304
|
registerAuthCommand(program);
|
|
1159
1305
|
registerBrowseCommand(program);
|
|
1160
1306
|
registerAgentCommand(program);
|
|
@@ -1167,5 +1313,7 @@ registerSendCommand(program);
|
|
|
1167
1313
|
registerHealthCommand(program);
|
|
1168
1314
|
registerProviderCommands(program);
|
|
1169
1315
|
registerServeCommand(program);
|
|
1316
|
+
registerStopCommand(program);
|
|
1317
|
+
registerStatusCommand(program);
|
|
1170
1318
|
program.parse();
|
|
1171
1319
|
//# sourceMappingURL=index.js.map
|
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/serve/stdio-bridge.ts","../src/serve/session-manager.ts","../src/serve/protocol.ts"],"sourcesContent":["import { 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\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('0.1.0');\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\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\nfunction 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 } from '../output.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}\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 .action(async (opts: ServeOptions) => {\r\n try {\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 { 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"],"mappings":"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","names":["program","program","program","program","program","program","program","program","program","program","program","WebSocket","createInterface","WebSocket","program","WebSocket"]}
|
|
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"]}
|
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\nfunction 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 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":[]}
|