@clawrent/cli 0.2.2 → 0.4.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/LICENSE +15 -0
- package/dist/index.js +153 -50
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +43 -2
- package/dist/lib.js +43 -3
- package/dist/lib.js.map +1 -1
- package/package.json +3 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ClawRent
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/dist/index.js
CHANGED
|
@@ -100,6 +100,12 @@ var ApiClient = class {
|
|
|
100
100
|
return this.config.userId;
|
|
101
101
|
}
|
|
102
102
|
// --- Auth (no auth needed) ---
|
|
103
|
+
async sendVerification(email) {
|
|
104
|
+
return this.request("POST", "/api/auth/send-verification", { email }, false);
|
|
105
|
+
}
|
|
106
|
+
async registerUser(input) {
|
|
107
|
+
return this.request("POST", "/api/auth/register", input, false);
|
|
108
|
+
}
|
|
103
109
|
async login(email, password) {
|
|
104
110
|
return this.request("POST", "/api/auth/login", { email, password }, false);
|
|
105
111
|
}
|
|
@@ -163,7 +169,7 @@ var ApiClient = class {
|
|
|
163
169
|
const params = new URLSearchParams();
|
|
164
170
|
if (query?.page) params.set("page", String(query.page));
|
|
165
171
|
if (query?.limit) params.set("limit", String(query.limit));
|
|
166
|
-
if (query?.
|
|
172
|
+
if (query?.roles) params.set("roles", query.roles);
|
|
167
173
|
const qs = params.toString();
|
|
168
174
|
return this.request("GET", `/api/agents/my${qs ? `?${qs}` : ""}`);
|
|
169
175
|
}
|
|
@@ -171,9 +177,14 @@ var ApiClient = class {
|
|
|
171
177
|
async getMyAgent() {
|
|
172
178
|
return this.request("GET", "/api/agents/me/agent");
|
|
173
179
|
}
|
|
174
|
-
async
|
|
175
|
-
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/
|
|
180
|
+
async applyProvider(agentId, data) {
|
|
181
|
+
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/apply-provider`, data);
|
|
176
182
|
}
|
|
183
|
+
/** Publish agent — simplified apply-provider with defaults, submits for admin review */
|
|
184
|
+
async publishAgent(agentId, data) {
|
|
185
|
+
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/publish`, data ?? {});
|
|
186
|
+
}
|
|
187
|
+
/** Activate agent — verify admin-approved + WebSocket connected, then go online */
|
|
177
188
|
async activateAgent(agentId) {
|
|
178
189
|
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/activate`);
|
|
179
190
|
}
|
|
@@ -238,6 +249,35 @@ var ApiClient = class {
|
|
|
238
249
|
async health() {
|
|
239
250
|
return this.request("GET", "/api/health", void 0, false);
|
|
240
251
|
}
|
|
252
|
+
// --- Docs (MCP interface) ---
|
|
253
|
+
async getDocsTree() {
|
|
254
|
+
return this.request("GET", "/api/mcp/docs/tree", void 0, false);
|
|
255
|
+
}
|
|
256
|
+
async getDocByPath(path) {
|
|
257
|
+
return this.request("GET", `/api/mcp/docs/by-path/${encodeURI(path)}`, void 0, false);
|
|
258
|
+
}
|
|
259
|
+
async searchDocs(query) {
|
|
260
|
+
const params = new URLSearchParams({ q: query });
|
|
261
|
+
return this.request("GET", `/api/mcp/docs/search?${params.toString()}`, void 0, false);
|
|
262
|
+
}
|
|
263
|
+
async getDoc(id) {
|
|
264
|
+
return this.request("GET", `/api/mcp/docs/${encodeURIComponent(id)}`, void 0, false);
|
|
265
|
+
}
|
|
266
|
+
async createDoc(data) {
|
|
267
|
+
return this.request("POST", "/api/mcp/docs", data);
|
|
268
|
+
}
|
|
269
|
+
async updateDoc(id, data) {
|
|
270
|
+
return this.request("PATCH", `/api/mcp/docs/${encodeURIComponent(id)}`, data);
|
|
271
|
+
}
|
|
272
|
+
async deleteDoc(id) {
|
|
273
|
+
return this.request("DELETE", `/api/mcp/docs/${encodeURIComponent(id)}`);
|
|
274
|
+
}
|
|
275
|
+
async publishDoc(id) {
|
|
276
|
+
return this.request("POST", `/api/mcp/docs/${encodeURIComponent(id)}/publish`);
|
|
277
|
+
}
|
|
278
|
+
async unpublishDoc(id) {
|
|
279
|
+
return this.request("POST", `/api/mcp/docs/${encodeURIComponent(id)}/unpublish`);
|
|
280
|
+
}
|
|
241
281
|
// --- Private ---
|
|
242
282
|
async request(method, path, body, requireAuth = true) {
|
|
243
283
|
const url = `${this.config.apiUrl}${path}`;
|
|
@@ -281,28 +321,31 @@ function printSuccess(message) {
|
|
|
281
321
|
}
|
|
282
322
|
|
|
283
323
|
// src/commands/auth.ts
|
|
284
|
-
function deriveWsUrl(apiUrl) {
|
|
285
|
-
return apiUrl.replace(/^http/, "ws");
|
|
286
|
-
}
|
|
287
324
|
async function promptInput(prompt, hidden = false) {
|
|
288
|
-
const
|
|
325
|
+
const stdin = process.stdin;
|
|
326
|
+
if (!stdin.isTTY) {
|
|
327
|
+
const rl = createInterface({ input: stdin });
|
|
328
|
+
return new Promise((resolve) => {
|
|
329
|
+
rl.question("", (answer) => {
|
|
330
|
+
rl.close();
|
|
331
|
+
resolve(answer.trim());
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
289
335
|
return new Promise((resolve) => {
|
|
290
336
|
if (hidden) {
|
|
291
337
|
process.stderr.write(prompt);
|
|
292
|
-
const stdin = process.stdin;
|
|
293
338
|
const wasRaw = stdin.isRaw;
|
|
294
|
-
if (stdin.
|
|
339
|
+
if (stdin.setRawMode) stdin.setRawMode(true);
|
|
295
340
|
let input = "";
|
|
296
341
|
const onData = (ch) => {
|
|
297
342
|
const c = ch.toString("utf-8");
|
|
298
|
-
if (c === "\n" || c === "\r") {
|
|
343
|
+
if (c === "\n" || c === "\r" || c === "") {
|
|
299
344
|
stdin.removeListener("data", onData);
|
|
300
|
-
if (stdin.
|
|
345
|
+
if (stdin.setRawMode && wasRaw !== void 0) stdin.setRawMode(wasRaw);
|
|
301
346
|
process.stderr.write("\n");
|
|
302
|
-
rl.close();
|
|
303
347
|
resolve(input);
|
|
304
348
|
} else if (c === "") {
|
|
305
|
-
rl.close();
|
|
306
349
|
process.exit(1);
|
|
307
350
|
} else if (c === "\x7F" || c === "\b") {
|
|
308
351
|
input = input.slice(0, -1);
|
|
@@ -312,6 +355,7 @@ async function promptInput(prompt, hidden = false) {
|
|
|
312
355
|
};
|
|
313
356
|
stdin.on("data", onData);
|
|
314
357
|
} else {
|
|
358
|
+
const rl = createInterface({ input: stdin, output: process.stderr });
|
|
315
359
|
rl.question(prompt, (answer) => {
|
|
316
360
|
rl.close();
|
|
317
361
|
resolve(answer);
|
|
@@ -321,18 +365,72 @@ async function promptInput(prompt, hidden = false) {
|
|
|
321
365
|
}
|
|
322
366
|
function registerAuthCommand(program2) {
|
|
323
367
|
const auth = program2.command("auth").description("Authentication management");
|
|
324
|
-
auth.command("
|
|
368
|
+
auth.command("send-verification").description("Send email verification code (step 1 of registration)").requiredOption("-e, --email <email>", "Email address").action(async (opts) => {
|
|
369
|
+
try {
|
|
370
|
+
const currentConfig = loadConfig();
|
|
371
|
+
const client = new ApiClient(currentConfig);
|
|
372
|
+
const result = await client.sendVerification(opts.email);
|
|
373
|
+
printJson({ email: opts.email, sent: true, ...result });
|
|
374
|
+
} catch (err) {
|
|
375
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
376
|
+
process.exit(1);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
auth.command("register").description("Register a new ClawRent account").option("-e, --email <email>", "Email address").option("-n, --name <name>", "Display name").option("-p, --password <password>", "Password (min 8 chars). If omitted, prompts interactively.").option("-c, --code <code>", "6-digit verification code. If omitted, sends code first and prompts.").action(async (opts) => {
|
|
380
|
+
try {
|
|
381
|
+
const currentConfig = loadConfig();
|
|
382
|
+
const client = new ApiClient(currentConfig);
|
|
383
|
+
const email = opts.email ?? await promptInput("Email: ");
|
|
384
|
+
const name = opts.name ?? await promptInput("Display name: ");
|
|
385
|
+
const password = opts.password ?? await promptInput("Password (min 8 chars): ", true);
|
|
386
|
+
if (password.length < 8) {
|
|
387
|
+
printError("Password must be at least 8 characters");
|
|
388
|
+
process.exit(1);
|
|
389
|
+
}
|
|
390
|
+
let verificationCode;
|
|
391
|
+
if (opts.code) {
|
|
392
|
+
verificationCode = opts.code;
|
|
393
|
+
} else {
|
|
394
|
+
printSuccess("Sending verification code to your email...");
|
|
395
|
+
await client.sendVerification(email);
|
|
396
|
+
printSuccess("Verification code sent! Check your inbox.");
|
|
397
|
+
verificationCode = await promptInput("Verification code: ");
|
|
398
|
+
}
|
|
399
|
+
const result = await client.registerUser({
|
|
400
|
+
email,
|
|
401
|
+
password,
|
|
402
|
+
name,
|
|
403
|
+
verificationCode
|
|
404
|
+
});
|
|
405
|
+
saveConfig({
|
|
406
|
+
token: result.token,
|
|
407
|
+
apiKey: result.apiKey,
|
|
408
|
+
userId: result.user.id,
|
|
409
|
+
email: result.user.email,
|
|
410
|
+
name: result.user.name
|
|
411
|
+
});
|
|
412
|
+
printJson({
|
|
413
|
+
success: true,
|
|
414
|
+
user: result.user,
|
|
415
|
+
token: result.token,
|
|
416
|
+
apiKey: result.apiKey,
|
|
417
|
+
configSaved: getConfigPath()
|
|
418
|
+
});
|
|
419
|
+
} catch (err) {
|
|
420
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
421
|
+
process.exit(1);
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
auth.command("login").description("Login to ClawRent platform").option("-e, --email <email>", "Email address").option("-p, --password <password>", "Password").action(async (opts) => {
|
|
325
425
|
try {
|
|
326
426
|
const currentConfig = loadConfig();
|
|
327
|
-
const apiUrl = opts.apiUrl ?? currentConfig.apiUrl;
|
|
328
|
-
const wsUrl = deriveWsUrl(apiUrl);
|
|
329
427
|
const email = opts.email ?? await promptInput("Email: ");
|
|
330
428
|
const password = opts.password ?? await promptInput("Password: ", true);
|
|
331
429
|
if (!email || !password) {
|
|
332
430
|
printError("Email and password are required.");
|
|
333
431
|
process.exit(1);
|
|
334
432
|
}
|
|
335
|
-
const client = new ApiClient(
|
|
433
|
+
const client = new ApiClient(currentConfig);
|
|
336
434
|
const result = await client.login(email, password);
|
|
337
435
|
saveConfig({
|
|
338
436
|
token: result.token,
|
|
@@ -340,8 +438,12 @@ function registerAuthCommand(program2) {
|
|
|
340
438
|
email: result.user.email,
|
|
341
439
|
name: result.user.name
|
|
342
440
|
});
|
|
343
|
-
|
|
344
|
-
|
|
441
|
+
printJson({
|
|
442
|
+
success: true,
|
|
443
|
+
user: result.user,
|
|
444
|
+
token: result.token,
|
|
445
|
+
configSaved: getConfigPath()
|
|
446
|
+
});
|
|
345
447
|
} catch (err) {
|
|
346
448
|
printError(err instanceof Error ? err.message : String(err));
|
|
347
449
|
process.exit(1);
|
|
@@ -350,7 +452,7 @@ function registerAuthCommand(program2) {
|
|
|
350
452
|
auth.command("logout").description("Logout and clear saved credentials").action(() => {
|
|
351
453
|
try {
|
|
352
454
|
clearConfig();
|
|
353
|
-
|
|
455
|
+
printJson({ success: true, message: "Credentials cleared" });
|
|
354
456
|
} catch (err) {
|
|
355
457
|
printError(err instanceof Error ? err.message : String(err));
|
|
356
458
|
process.exit(1);
|
|
@@ -427,7 +529,7 @@ function registerBalanceCommand(program2) {
|
|
|
427
529
|
try {
|
|
428
530
|
const client = new ApiClient(loadConfig());
|
|
429
531
|
const result = await client.getBalance();
|
|
430
|
-
|
|
532
|
+
printJson(result);
|
|
431
533
|
} catch (err) {
|
|
432
534
|
printError(err instanceof Error ? err.message : String(err));
|
|
433
535
|
process.exit(1);
|
|
@@ -441,7 +543,7 @@ function registerTopupCommand(program2) {
|
|
|
441
543
|
try {
|
|
442
544
|
const client = new ApiClient(loadConfig());
|
|
443
545
|
const result = await client.topUp(amount);
|
|
444
|
-
|
|
546
|
+
printJson(result);
|
|
445
547
|
} catch (err) {
|
|
446
548
|
printError(err instanceof Error ? err.message : String(err));
|
|
447
549
|
process.exit(1);
|
|
@@ -505,7 +607,7 @@ function registerEndCommand(program2) {
|
|
|
505
607
|
// src/commands/send.ts
|
|
506
608
|
import WebSocket from "ws";
|
|
507
609
|
function registerSendCommand(program2) {
|
|
508
|
-
program2.command("send <sessionId>").description("Send a message to a session via WebSocket").requiredOption("--content <text>", "Message content").option("--type <messageType>", "Message type", "dialogue.message").option("--token <sessionToken>", "Session token (auto-fetched if not provided)").option("--wait <ms>", "Wait for response (milliseconds)").action(async (sessionId, opts) => {
|
|
610
|
+
program2.command("send <sessionId>").description("Send a message to a session via WebSocket").requiredOption("--content <text>", "Message content").option("--type <messageType>", "Message type", "dialogue.message").option("--token <sessionToken>", "Session token (auto-fetched if not provided)").option("--slot <index>", "Slot index for consumer role (default: 0)", "0").option("--wait <ms>", "Wait for response (milliseconds)").action(async (sessionId, opts) => {
|
|
509
611
|
try {
|
|
510
612
|
const config = loadConfig();
|
|
511
613
|
const client = new ApiClient(config);
|
|
@@ -522,7 +624,7 @@ function registerSendCommand(program2) {
|
|
|
522
624
|
printError("Could not determine session token. Use --token flag.");
|
|
523
625
|
process.exit(1);
|
|
524
626
|
}
|
|
525
|
-
const wsUrl = `${config.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=${role}`;
|
|
627
|
+
const wsUrl = `${config.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=${role}${role === "consumer" ? `&slotIndex=${opts.slot}` : ""}`;
|
|
526
628
|
await new Promise((resolve, reject) => {
|
|
527
629
|
const ws = new WebSocket(wsUrl);
|
|
528
630
|
let responded = false;
|
|
@@ -586,18 +688,12 @@ function registerSendCommand(program2) {
|
|
|
586
688
|
function registerProviderCommands(program2) {
|
|
587
689
|
const provider = program2.command("provider").description("Provider operations");
|
|
588
690
|
const agent = provider.command("agent").description("Manage your agents");
|
|
589
|
-
agent.command("create").description("Register a new agent").requiredOption("--name <name>", "Agent name").requiredOption("--slug <slug>", "Agent slug (URL-friendly)").requiredOption("--description <desc>", "Agent description (10-500 chars)").option("--long-description <text>", "Detailed description").option("--
|
|
691
|
+
agent.command("create").description("Register a new agent (consumer by default)").requiredOption("--name <name>", "Agent name").requiredOption("--slug <slug>", "Agent slug (URL-friendly)").requiredOption("--description <desc>", "Agent description (10-500 chars)").option("--long-description <text>", "Detailed description").option("--capabilities <json>", "Capabilities as JSON array").option("--permissions <json>", "Required permissions as JSON array").action(async (opts) => {
|
|
590
692
|
try {
|
|
591
693
|
const data = {
|
|
592
694
|
name: opts.name,
|
|
593
695
|
slug: opts.slug,
|
|
594
|
-
description: opts.description
|
|
595
|
-
pricingModel: opts.pricingModel,
|
|
596
|
-
priceAmount: opts.price,
|
|
597
|
-
currency: opts.currency,
|
|
598
|
-
hostingType: opts.hostingType,
|
|
599
|
-
approvalMode: opts.approvalMode,
|
|
600
|
-
maxConcurrentSessions: parseInt(opts.maxConcurrent, 10)
|
|
696
|
+
description: opts.description
|
|
601
697
|
};
|
|
602
698
|
if (opts.longDescription) data["longDescription"] = opts.longDescription;
|
|
603
699
|
if (opts.capabilities) {
|
|
@@ -608,6 +704,14 @@ function registerProviderCommands(program2) {
|
|
|
608
704
|
process.exit(1);
|
|
609
705
|
}
|
|
610
706
|
}
|
|
707
|
+
if (opts.permissions) {
|
|
708
|
+
try {
|
|
709
|
+
data["requiredPermissions"] = JSON.parse(opts.permissions);
|
|
710
|
+
} catch {
|
|
711
|
+
printError("Invalid JSON for --permissions");
|
|
712
|
+
process.exit(1);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
611
715
|
const client = new ApiClient(loadConfig());
|
|
612
716
|
const result = await client.registerAgent(data);
|
|
613
717
|
printJson(result);
|
|
@@ -616,11 +720,11 @@ function registerProviderCommands(program2) {
|
|
|
616
720
|
process.exit(1);
|
|
617
721
|
}
|
|
618
722
|
});
|
|
619
|
-
agent.command("list").description("List your agents").option("-
|
|
723
|
+
agent.command("list").description("List your agents").option("-r, --roles <roles>", "Filter by roles (consumer, both)").option("-p, --page <number>", "Page number", "1").option("-l, --limit <number>", "Results per page", "20").action(async (opts) => {
|
|
620
724
|
try {
|
|
621
725
|
const client = new ApiClient(loadConfig());
|
|
622
726
|
const result = await client.getMyAgents({
|
|
623
|
-
|
|
727
|
+
roles: opts.roles,
|
|
624
728
|
page: parseInt(opts.page, 10),
|
|
625
729
|
limit: parseInt(opts.limit, 10)
|
|
626
730
|
});
|
|
@@ -630,22 +734,19 @@ function registerProviderCommands(program2) {
|
|
|
630
734
|
process.exit(1);
|
|
631
735
|
}
|
|
632
736
|
});
|
|
633
|
-
agent.command("
|
|
737
|
+
agent.command("apply-provider <agentId>").description("Apply for provider role on an agent").option("--pricing-model <model>", "Pricing model (per_token/per_session/per_minute)", "per_session").option("--price <amount>", "Price amount", "1.00").option("--currency <cur>", "Currency (CNY/USD)", "CNY").option("--hosting-type <type>", "Hosting type (self_hosted/platform_hosted)", "self_hosted").option("--approval-mode <mode>", "Session approval mode (manual/auto)", "manual").option("--max-concurrent <n>", "Max concurrent sessions", "5").option("--max-slots <n>", "Max consumer slots per session", "1").action(async (agentId, opts) => {
|
|
634
738
|
try {
|
|
635
739
|
const client = new ApiClient(loadConfig());
|
|
636
|
-
const result = await client.
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
const client = new ApiClient(loadConfig());
|
|
647
|
-
const result = await client.activateAgent(agentId);
|
|
648
|
-
printSuccess("Agent activated successfully.");
|
|
740
|
+
const result = await client.applyProvider(agentId, {
|
|
741
|
+
pricingModel: opts.pricingModel,
|
|
742
|
+
priceAmount: opts.price,
|
|
743
|
+
currency: opts.currency,
|
|
744
|
+
hostingType: opts.hostingType,
|
|
745
|
+
approvalMode: opts.approvalMode,
|
|
746
|
+
maxConcurrentSessions: parseInt(opts.maxConcurrent, 10),
|
|
747
|
+
maxConsumerSlots: parseInt(opts.maxSlots, 10)
|
|
748
|
+
});
|
|
749
|
+
printSuccess("Provider application submitted.");
|
|
649
750
|
printJson(result);
|
|
650
751
|
} catch (err) {
|
|
651
752
|
printError(err instanceof Error ? err.message : String(err));
|
|
@@ -1148,14 +1249,16 @@ async function runDaemon(opts) {
|
|
|
1148
1249
|
sessionId: sid,
|
|
1149
1250
|
sessionToken,
|
|
1150
1251
|
taskDescription: payload["taskDescription"] ?? "",
|
|
1151
|
-
consumerUserId: payload["consumerUserId"] ?? ""
|
|
1252
|
+
consumerUserId: payload["consumerUserId"] ?? "",
|
|
1253
|
+
slotIndex: payload["slotIndex"] ?? 0
|
|
1152
1254
|
});
|
|
1153
1255
|
sessionManager.connect(sid, sessionToken);
|
|
1154
1256
|
} else {
|
|
1155
1257
|
bridge.writeNotification("session.pending", {
|
|
1156
1258
|
sessionId: sid,
|
|
1157
1259
|
taskDescription: payload["taskDescription"] ?? "",
|
|
1158
|
-
consumerUserId: payload["consumerUserId"] ?? ""
|
|
1260
|
+
consumerUserId: payload["consumerUserId"] ?? "",
|
|
1261
|
+
slotIndex: payload["slotIndex"] ?? 0
|
|
1159
1262
|
});
|
|
1160
1263
|
}
|
|
1161
1264
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/api-client.ts","../src/output.ts","../src/commands/browse.ts","../src/commands/agent.ts","../src/commands/sessions.ts","../src/commands/balance.ts","../src/commands/topup.ts","../src/commands/health.ts","../src/commands/rent.ts","../src/commands/end.ts","../src/commands/send.ts","../src/commands/provider/index.ts","../src/serve/index.ts","../src/daemon.ts","../src/serve/stdio-bridge.ts","../src/serve/session-manager.ts","../src/serve/protocol.ts","../src/commands/stop.ts","../src/commands/status.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\r\nimport { dirname, join } from 'node:path';\r\nimport { fileURLToPath } from 'node:url';\r\nimport { Command } from 'commander';\r\nimport { registerAuthCommand } from './commands/auth.js';\r\nimport { registerBrowseCommand } from './commands/browse.js';\r\nimport { registerAgentCommand } from './commands/agent.js';\r\nimport { registerSessionsCommand } from './commands/sessions.js';\r\nimport { registerBalanceCommand } from './commands/balance.js';\r\nimport { registerTopupCommand } from './commands/topup.js';\r\nimport { registerHealthCommand } from './commands/health.js';\r\nimport { registerRentCommand } from './commands/rent.js';\r\nimport { registerEndCommand } from './commands/end.js';\r\nimport { registerSendCommand } from './commands/send.js';\r\nimport { registerProviderCommands } from './commands/provider/index.js';\r\nimport { registerServeCommand } from './serve/index.js';\r\nimport { registerStopCommand } from './commands/stop.js';\r\nimport { registerStatusCommand } from './commands/status.js';\r\n\r\nconst __dirname = dirname(fileURLToPath(import.meta.url));\r\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('clawrent')\r\n .description('ClawRent CLI - Agent capability rental platform')\r\n .version(pkg.version);\r\n\r\n// Auth\r\nregisterAuthCommand(program);\r\n\r\n// Consumer commands\r\nregisterBrowseCommand(program);\r\nregisterAgentCommand(program);\r\nregisterSessionsCommand(program);\r\nregisterBalanceCommand(program);\r\nregisterTopupCommand(program);\r\nregisterRentCommand(program);\r\nregisterEndCommand(program);\r\nregisterSendCommand(program);\r\nregisterHealthCommand(program);\r\n\r\n// Provider commands\r\nregisterProviderCommands(program);\r\n\r\n// Serve daemon\r\nregisterServeCommand(program);\r\n\r\n// Daemon management\r\nregisterStopCommand(program);\r\nregisterStatusCommand(program);\r\n\r\nprogram.parse();\r\n","import { Command } from 'commander';\r\nimport { createInterface } from 'node:readline';\r\nimport { loadConfig, saveConfig, clearConfig, getConfigPath } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../output.js';\r\n\r\nfunction deriveWsUrl(apiUrl: string): string {\r\n return apiUrl.replace(/^http/, 'ws');\r\n}\r\n\r\nasync function promptInput(prompt: string, hidden: boolean = false): Promise<string> {\r\n const rl = createInterface({ input: process.stdin, output: process.stderr });\r\n\r\n return new Promise((resolve) => {\r\n if (hidden) {\r\n // For password: write prompt manually, mute output\r\n process.stderr.write(prompt);\r\n const stdin = process.stdin;\r\n const wasRaw = stdin.isRaw;\r\n if (stdin.isTTY) stdin.setRawMode(true);\r\n let input = '';\r\n const onData = (ch: Buffer) => {\r\n const c = ch.toString('utf-8');\r\n if (c === '\\n' || c === '\\r') {\r\n stdin.removeListener('data', onData);\r\n if (stdin.isTTY && wasRaw !== undefined) stdin.setRawMode(wasRaw);\r\n process.stderr.write('\\n');\r\n rl.close();\r\n resolve(input);\r\n } else if (c === '\\u0003') {\r\n // Ctrl+C\r\n rl.close();\r\n process.exit(1);\r\n } else if (c === '\\u007F' || c === '\\b') {\r\n // Backspace\r\n input = input.slice(0, -1);\r\n } else {\r\n input += c;\r\n }\r\n };\r\n stdin.on('data', onData);\r\n } else {\r\n rl.question(prompt, (answer) => {\r\n rl.close();\r\n resolve(answer);\r\n });\r\n }\r\n });\r\n}\r\n\r\nexport function registerAuthCommand(program: Command): void {\r\n const auth = program\r\n .command('auth')\r\n .description('Authentication management');\r\n\r\n auth\r\n .command('login')\r\n .description('Login to ClawRent platform')\r\n .option('-e, --email <email>', 'Email address')\r\n .option('-p, --password <password>', 'Password')\r\n .option('--api-url <url>', 'Platform API URL')\r\n .action(async (opts: { email?: string; password?: string; apiUrl?: string }) => {\r\n try {\r\n const currentConfig = loadConfig();\r\n const apiUrl = opts.apiUrl ?? currentConfig.apiUrl;\r\n const wsUrl = deriveWsUrl(apiUrl);\r\n\r\n const email = opts.email ?? await promptInput('Email: ');\r\n const password = opts.password ?? await promptInput('Password: ', true);\r\n\r\n if (!email || !password) {\r\n printError('Email and password are required.');\r\n process.exit(1);\r\n }\r\n\r\n const client = new ApiClient({ ...currentConfig, apiUrl, wsUrl });\r\n const result = await client.login(email, password);\r\n\r\n // Save credentials (do NOT save apiUrl/wsUrl — they come from defaults or env vars,\r\n // saving them would pin the config to a specific URL and break after default changes)\r\n saveConfig({\r\n token: result.token,\r\n userId: result.user.id,\r\n email: result.user.email,\r\n name: result.user.name,\r\n });\r\n\r\n printSuccess(`Logged in as ${result.user.name} (${result.user.email})`);\r\n printSuccess(`Config saved to ${getConfigPath()}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n auth\r\n .command('logout')\r\n .description('Logout and clear saved credentials')\r\n .action(() => {\r\n try {\r\n clearConfig();\r\n printSuccess('Logged out. Config cleared.');\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n auth\r\n .command('whoami')\r\n .description('Show current user info')\r\n .action(async () => {\r\n try {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n const me = await client.getMe();\r\n printJson(me);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\n\r\nexport interface ClawRentConfig {\r\n apiUrl: string;\r\n wsUrl: string;\r\n token?: string;\r\n apiKey?: string;\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: ClawRentConfig = {\r\n apiUrl: 'https://clawrent.cloud',\r\n wsUrl: 'wss://clawrent.cloud',\r\n};\r\n\r\nexport function getConfigDir(): string {\r\n return join(homedir(), '.clawrent');\r\n}\r\n\r\nfunction getConfigFilePath(): string {\r\n return join(getConfigDir(), 'config.json');\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return getConfigFilePath();\r\n}\r\n\r\nexport function loadConfig(): ClawRentConfig {\r\n let fileConfig: Partial<ClawRentConfig> = {};\r\n\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n const raw = readFileSync(configPath, 'utf-8');\r\n fileConfig = JSON.parse(raw) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Ignore corrupt config file\r\n }\r\n }\r\n\r\n // Migration: remove stale localhost URLs saved by older CLI versions.\r\n // These override the new production defaults and break remote connections.\r\n if (fileConfig.apiUrl?.includes('localhost') || fileConfig.wsUrl?.includes('localhost')) {\r\n delete fileConfig.apiUrl;\r\n delete fileConfig.wsUrl;\r\n // Persist the cleanup so it only runs once\r\n try {\r\n const cleaned = { ...fileConfig };\r\n writeFileSync(configPath, JSON.stringify(cleaned, null, 2), 'utf-8');\r\n } catch {\r\n // Non-fatal\r\n }\r\n }\r\n\r\n // Merge: defaults < file < env vars\r\n const config: ClawRentConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...fileConfig,\r\n };\r\n\r\n // Env vars always override\r\n const envApiUrl = process.env['CLAWRENT_API_URL'];\r\n const envWsUrl = process.env['CLAWRENT_WS_URL'];\r\n const envToken = process.env['CLAWRENT_TOKEN'];\r\n const envApiKey = process.env['CLAWRENT_API_KEY'];\r\n const envUserId = process.env['CLAWRENT_USER_ID'];\r\n\r\n if (envApiUrl) config.apiUrl = envApiUrl;\r\n if (envWsUrl) config.wsUrl = envWsUrl;\r\n if (envToken) config.token = envToken;\r\n if (envApiKey) config.apiKey = envApiKey;\r\n if (envUserId) config.userId = envUserId;\r\n\r\n return config;\r\n}\r\n\r\nexport function saveConfig(partial: Partial<ClawRentConfig>): void {\r\n const configDir = getConfigDir();\r\n if (!existsSync(configDir)) {\r\n mkdirSync(configDir, { recursive: true });\r\n }\r\n\r\n let existing: Partial<ClawRentConfig> = {};\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n existing = JSON.parse(readFileSync(configPath, 'utf-8')) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Overwrite corrupt file\r\n }\r\n }\r\n\r\n const merged = { ...existing, ...partial };\r\n writeFileSync(configPath, JSON.stringify(merged, null, 2), 'utf-8');\r\n}\r\n\r\nexport function clearConfig(): void {\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n unlinkSync(configPath);\r\n }\r\n}\r\n","import type { ClawRentConfig } from './config.js';\r\n\r\nexport class ApiClient {\r\n private config: ClawRentConfig;\r\n\r\n constructor(config: ClawRentConfig) {\r\n this.config = config;\r\n }\r\n\r\n get apiUrl(): string {\r\n return this.config.apiUrl;\r\n }\r\n\r\n get wsUrl(): string {\r\n return this.config.wsUrl;\r\n }\r\n\r\n get userId(): string | undefined {\r\n return this.config.userId;\r\n }\r\n\r\n // --- Auth (no auth needed) ---\r\n\r\n async login(email: string, password: string): Promise<{ user: { id: string; email: string; name: string; role: string }; token: string }> {\r\n return this.request('POST', '/api/auth/login', { email, password }, false);\r\n }\r\n\r\n async getMe(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/auth/me');\r\n }\r\n\r\n // --- Marketplace ---\r\n\r\n async browse(query?: { search?: string; category?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.search) params.set('search', query.search);\r\n if (query?.category) params.set('category', query.category);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/marketplace/browse${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getAgent(slug: string): Promise<unknown> {\r\n return this.request('GET', `/api/marketplace/agents/${encodeURIComponent(slug)}`);\r\n }\r\n\r\n // --- Sessions ---\r\n\r\n async rent(options: { agentId: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }): Promise<unknown> {\r\n return this.request('POST', '/api/sessions', {\r\n agentId: options.agentId,\r\n taskDescription: options.taskDescription,\r\n grantedPermissions: options.grantedPermissions ?? {},\r\n });\r\n }\r\n\r\n async getSessions(query?: { role?: string; status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.role) params.set('role', query.role);\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/sessions${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getSession(sessionId: string): Promise<Record<string, unknown>> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}`);\r\n }\r\n\r\n async getSessionMessages(sessionId: string): Promise<unknown> {\r\n return this.request('GET', `/api/sessions/${encodeURIComponent(sessionId)}/messages`);\r\n }\r\n\r\n async endSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/end`);\r\n }\r\n\r\n async approveSession(sessionId: string): Promise<unknown> {\r\n return this.request('POST', `/api/sessions/${encodeURIComponent(sessionId)}/approve`);\r\n }\r\n\r\n // --- Billing ---\r\n\r\n async getBalance(): Promise<{ balance: string }> {\r\n return this.request('GET', '/api/billing/wallet');\r\n }\r\n\r\n async topUp(amount: string): Promise<{ balance: string }> {\r\n return this.request('POST', '/api/billing/wallet/topup', { amount });\r\n }\r\n\r\n // --- Provider: Agents ---\r\n\r\n async registerAgent(data: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', '/api/agents', data);\r\n }\r\n\r\n async getMyAgents(query?: { page?: number; limit?: number; status?: string }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n if (query?.status) params.set('status', query.status);\r\n const qs = params.toString();\r\n return this.request('GET', `/api/agents/my${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */\r\n async getMyAgent(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/agents/me/agent');\r\n }\r\n\r\n async publishAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`);\r\n }\r\n\r\n async activateAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/activate`);\r\n }\r\n\r\n async setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown> {\r\n return this.request('PATCH', `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });\r\n }\r\n\r\n async generateAgentToken(agentId: string): Promise<{ agentId: string; token: string; createdAt: string; warning: string }> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n async revokeAgentToken(agentId: string): Promise<{ message: string }> {\r\n return this.request('DELETE', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n // --- Orders ---\r\n\r\n async createOrder(data: {\r\n items: Array<{ providerAgentId: string; consumerAgentId?: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }>;\r\n note?: string;\r\n fromCart?: boolean;\r\n }): Promise<unknown> {\r\n return this.request('POST', '/api/orders', data);\r\n }\r\n\r\n async getOrders(query?: { status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/orders${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getOrder(orderId: string): Promise<unknown> {\r\n return this.request('GET', `/api/orders/${encodeURIComponent(orderId)}`);\r\n }\r\n\r\n async cancelOrder(orderId: string): Promise<unknown> {\r\n return this.request('POST', `/api/orders/${encodeURIComponent(orderId)}/cancel`);\r\n }\r\n\r\n // --- Cart ---\r\n\r\n async getCart(): Promise<unknown> {\r\n return this.request('GET', '/api/cart');\r\n }\r\n\r\n async addToCart(data: { providerAgentId: string; taskDescription: string }): Promise<unknown> {\r\n return this.request('POST', '/api/cart', data);\r\n }\r\n\r\n async updateCartItem(itemId: string, data: { taskDescription: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/cart/${encodeURIComponent(itemId)}`, data);\r\n }\r\n\r\n async removeFromCart(itemId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/cart/${encodeURIComponent(itemId)}`);\r\n }\r\n\r\n async clearCart(): Promise<unknown> {\r\n return this.request('DELETE', '/api/cart');\r\n }\r\n\r\n // --- Favorites ---\r\n\r\n async listFavorites(query?: { page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/favorites${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async addFavorite(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n async removeFavorite(agentId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n // --- Health ---\r\n\r\n async health(): Promise<unknown> {\r\n return this.request('GET', '/api/health', undefined, false);\r\n }\r\n\r\n // --- Private ---\r\n\r\n private async request<T = any>(method: string, path: string, body?: unknown, requireAuth: boolean = true): Promise<T> {\r\n const url = `${this.config.apiUrl}${path}`;\r\n const headers: Record<string, string> = {};\r\n\r\n if (body !== undefined) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n if (requireAuth) {\r\n if (this.config.token) {\r\n headers['Authorization'] = `Bearer ${this.config.token}`;\r\n } else if (this.config.apiKey) {\r\n headers['x-api-key'] = this.config.apiKey;\r\n } else {\r\n throw new Error('Not authenticated. Run `clawrent auth login` first.');\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.json().catch(() => ({ message: response.statusText })) as Record<string, unknown>;\r\n throw new Error(`API error ${response.status}: ${errBody['message'] ?? JSON.stringify(errBody)}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n }\r\n}\r\n","export function printJson(data: unknown): void {\r\n process.stdout.write(JSON.stringify(data, null, 2) + '\\n');\r\n}\r\n\r\nexport function printError(message: string): void {\r\n process.stderr.write(`Error: ${message}\\n`);\r\n}\r\n\r\nexport function printSuccess(message: string): void {\r\n process.stdout.write(`${message}\\n`);\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerBrowseCommand(program: Command): void {\r\n program\r\n .command('browse')\r\n .description('Browse available agents on the marketplace')\r\n .option('-s, --search <query>', 'Search by name')\r\n .option('-c, --category <category>', 'Filter by category')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { search?: string; category?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.browse({\r\n search: opts.search,\r\n category: opts.category,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerAgentCommand(program: Command): void {\r\n program\r\n .command('agent <slug>')\r\n .description('Get agent details by slug')\r\n .action(async (slug: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getAgent(slug);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerSessionsCommand(program: Command): void {\r\n program\r\n .command('sessions')\r\n .description('List your sessions')\r\n .option('-r, --role <role>', 'Filter by role (consumer/provider)')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { role?: string; status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getSessions({\r\n role: opts.role,\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nexport function registerBalanceCommand(program: Command): void {\r\n program\r\n .command('balance')\r\n .description('Check wallet balance')\r\n .action(async () => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getBalance();\r\n printSuccess(`Balance: ${result.balance}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nexport function registerTopupCommand(program: Command): void {\r\n program\r\n .command('topup <amount>')\r\n .description('Top up wallet balance')\r\n .action(async (amount: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.topUp(amount);\r\n printSuccess(`New balance: ${result.balance}`);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerHealthCommand(program: Command): void {\r\n program\r\n .command('health')\r\n .description('Check platform health')\r\n .action(async () => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.health();\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerRentCommand(program: Command): void {\r\n program\r\n .command('rent')\r\n .description('Rent an agent (create a session)')\r\n .requiredOption('--agent-id <id>', 'Agent ID to rent')\r\n .requiredOption('--task <description>', 'Task description')\r\n .option('--permissions <json>', 'Granted permissions as JSON string', '{}')\r\n .action(async (opts: { agentId: string; task: string; permissions: string }) => {\r\n try {\r\n let grantedPermissions: Record<string, unknown> = {};\r\n try {\r\n grantedPermissions = JSON.parse(opts.permissions) as Record<string, unknown>;\r\n } catch {\r\n printError('Invalid JSON for --permissions');\r\n process.exit(1);\r\n }\r\n\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.rent({\r\n agentId: opts.agentId,\r\n taskDescription: opts.task,\r\n grantedPermissions,\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError } from '../output.js';\r\n\r\nexport function registerEndCommand(program: Command): void {\r\n program\r\n .command('end <sessionId>')\r\n .description('End a session')\r\n .action(async (sessionId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.endSession(sessionId);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport WebSocket from 'ws';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../output.js';\r\n\r\nexport function registerSendCommand(program: Command): void {\r\n program\r\n .command('send <sessionId>')\r\n .description('Send a message to a session via WebSocket')\r\n .requiredOption('--content <text>', 'Message content')\r\n .option('--type <messageType>', 'Message type', 'dialogue.message')\r\n .option('--token <sessionToken>', 'Session token (auto-fetched if not provided)')\r\n .option('--wait <ms>', 'Wait for response (milliseconds)')\r\n .action(async (sessionId: string, opts: { content: string; type: string; token?: string; wait?: string }) => {\r\n try {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n\r\n // Get session token if not provided\r\n let sessionToken = opts.token;\r\n let role = 'consumer';\r\n if (!sessionToken) {\r\n const session = await client.getSession(sessionId);\r\n sessionToken = session['sessionToken'] as string;\r\n // Determine role\r\n if (config.userId && session['providerUserId'] === config.userId) {\r\n role = 'provider';\r\n }\r\n }\r\n\r\n if (!sessionToken) {\r\n printError('Could not determine session token. Use --token flag.');\r\n process.exit(1);\r\n }\r\n\r\n const wsUrl = `${config.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=${role}`;\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const ws = new WebSocket(wsUrl);\r\n let responded = false;\r\n\r\n ws.on('open', () => {\r\n // Build full protocol envelope as required by ClawRentMessageSchema\r\n const message = {\r\n id: `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId,\r\n timestamp: Date.now(),\r\n sender: { role, agentId: config.userId ?? 'unknown' },\r\n type: opts.type,\r\n payload: { content: opts.content, dialogueType: 'message' },\r\n };\r\n ws.send(JSON.stringify(message));\r\n\r\n if (opts.wait) {\r\n // Wait for response\r\n setTimeout(() => {\r\n if (!responded) {\r\n ws.close(1000);\r\n printSuccess('Message sent (no response within timeout).');\r\n resolve();\r\n }\r\n }, parseInt(opts.wait, 10));\r\n } else {\r\n // Send and close\r\n setTimeout(() => {\r\n ws.close(1000);\r\n printSuccess('Message sent.');\r\n resolve();\r\n }, 500);\r\n }\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const data = JSON.parse(raw.toString());\r\n if (data.type !== 'system.heartbeat_ack' && data.type !== 'system.peer_connected') {\r\n responded = true;\r\n printJson(data);\r\n if (opts.wait) {\r\n ws.close(1000);\r\n resolve();\r\n }\r\n }\r\n } catch {\r\n // ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n reject(err);\r\n });\r\n\r\n ws.on('close', () => {\r\n if (!responded && opts.wait) {\r\n resolve();\r\n }\r\n });\r\n });\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { loadConfig } from '../../config.js';\r\nimport { ApiClient } from '../../api-client.js';\r\nimport { printJson, printError, printSuccess } from '../../output.js';\r\n\r\nexport function registerProviderCommands(program: Command): void {\r\n const provider = program\r\n .command('provider')\r\n .description('Provider operations');\r\n\r\n // --- Agent subcommands ---\r\n const agent = provider\r\n .command('agent')\r\n .description('Manage your agents');\r\n\r\n agent\r\n .command('create')\r\n .description('Register a new agent')\r\n .requiredOption('--name <name>', 'Agent name')\r\n .requiredOption('--slug <slug>', 'Agent slug (URL-friendly)')\r\n .requiredOption('--description <desc>', 'Agent description (10-500 chars)')\r\n .option('--long-description <text>', 'Detailed description')\r\n .option('--pricing-model <model>', 'Pricing model (per_token/per_session/per_minute)', 'per_session')\r\n .option('--price <amount>', 'Price amount', '1.00')\r\n .option('--currency <cur>', 'Currency (CNY/USD)', 'CNY')\r\n .option('--hosting-type <type>', 'Hosting type (self_hosted/platform_hosted)', 'self_hosted')\r\n .option('--approval-mode <mode>', 'Approval mode (manual/auto)', 'manual')\r\n .option('--max-concurrent <n>', 'Max concurrent sessions', '5')\r\n .option('--capabilities <json>', 'Capabilities as JSON array')\r\n .action(async (opts: {\r\n name: string; slug: string; description: string; longDescription?: string;\r\n pricingModel: string; price: string; currency: string; hostingType: string;\r\n approvalMode: string; maxConcurrent: string; capabilities?: string;\r\n }) => {\r\n try {\r\n const data: Record<string, unknown> = {\r\n name: opts.name,\r\n slug: opts.slug,\r\n description: opts.description,\r\n pricingModel: opts.pricingModel,\r\n priceAmount: opts.price,\r\n currency: opts.currency,\r\n hostingType: opts.hostingType,\r\n approvalMode: opts.approvalMode,\r\n maxConcurrentSessions: parseInt(opts.maxConcurrent, 10),\r\n };\r\n if (opts.longDescription) data['longDescription'] = opts.longDescription;\r\n if (opts.capabilities) {\r\n try {\r\n data['capabilities'] = JSON.parse(opts.capabilities);\r\n } catch {\r\n printError('Invalid JSON for --capabilities');\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.registerAgent(data);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('list')\r\n .description('List your agents')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getMyAgents({\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('publish <agentId>')\r\n .description('Publish an agent (draft -> pending_review)')\r\n .action(async (agentId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.publishAgent(agentId);\r\n printSuccess('Agent published successfully.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('activate <agentId>')\r\n .description('Activate an agent (pending_review -> active)')\r\n .action(async (agentId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.activateAgent(agentId);\r\n printSuccess('Agent activated successfully.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('status <agentId>')\r\n .description('Set agent online status')\r\n .requiredOption('--status <status>', 'Online status (online/offline/busy)')\r\n .action(async (agentId: string, opts: { status: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.setOnlineStatus(agentId, opts.status);\r\n printSuccess(`Agent status set to ${opts.status}.`);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n // --- Provider session commands ---\r\n provider\r\n .command('sessions')\r\n .description('List provider sessions')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getSessions({\r\n role: 'provider',\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n provider\r\n .command('approve <sessionId>')\r\n .description('Approve a pending session')\r\n .action(async (sessionId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.approveSession(sessionId);\r\n printSuccess('Session approved.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport WebSocket from 'ws';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printError, printSuccess } from '../output.js';\r\nimport { isDaemonRunning, spawnDaemon, writePid, getLogFilePath } from '../daemon.js';\r\nimport { StdioBridge } from './stdio-bridge.js';\r\nimport { SessionManager } from './session-manager.js';\r\nimport {\r\n createCorrelationId,\r\n isResponse,\r\n isRequest,\r\n type JsonRpcMessage,\r\n type ResultPayload,\r\n} from './protocol.js';\r\n\r\ninterface ServeOptions {\r\n agentToken: string;\r\n autoApprove: boolean;\r\n pollInterval: string;\r\n daemon: boolean;\r\n}\r\n\r\n/** Pending instruction tracking: correlationId -> sessionId */\r\nconst pendingInstructions = new Map<string, string>();\r\n\r\n/** Known session IDs we've already seen (to avoid duplicate polling notifications) */\r\nconst knownPendingSessions = new Set<string>();\r\nconst activeSessions = new Set<string>();\r\n\r\nexport function registerServeCommand(program: Command): void {\r\n program\r\n .command('serve')\r\n .description('Start serve daemon - bridge WebSocket sessions to stdin/stdout')\r\n .requiredOption('--agent-token <token>', 'Agent token (agt_clawrent_*) for authentication')\r\n .option('--auto-approve', 'Automatically approve incoming sessions', false)\r\n .option('--poll-interval <ms>', 'Polling interval for pending sessions (ms)', '5000')\r\n .option('-d, --daemon', 'Run in background as a daemon process', false)\r\n .action(async (opts: ServeOptions) => {\r\n try {\r\n if (opts.daemon) {\r\n // --- Daemon mode: resolve agentId first, then fork ---\r\n const config = loadConfig();\r\n // Override token for this request\r\n config.token = opts.agentToken;\r\n const client = new ApiClient(config);\r\n\r\n let agentId: string;\r\n try {\r\n const agent = await client.getMyAgent();\r\n agentId = agent['id'] as string;\r\n } catch {\r\n printError('Failed to resolve agent from token. Is the token valid?');\r\n process.exit(1);\r\n }\r\n\r\n const { running, pid: existingPid } = isDaemonRunning(agentId);\r\n if (running) {\r\n printError(`Daemon already running for agent ${agentId} (PID: ${existingPid}). Use 'clawrent stop --agent-id ${agentId}' first.`);\r\n process.exit(1);\r\n }\r\n\r\n // Rebuild args without --daemon / -d\r\n const args: string[] = ['serve', '--agent-token', opts.agentToken];\r\n if (opts.autoApprove) args.push('--auto-approve');\r\n if (opts.pollInterval !== '5000') args.push('--poll-interval', opts.pollInterval);\r\n\r\n const pid = spawnDaemon(agentId, args);\r\n writePid(agentId, pid);\r\n printSuccess(`Daemon started for agent ${agentId} (PID: ${pid})\\nLogs: ${getLogFilePath(agentId)}`);\r\n process.exit(0);\r\n }\r\n\r\n await runDaemon(opts);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n\r\nasync function runDaemon(opts: ServeOptions): Promise<void> {\r\n const config = loadConfig();\r\n // Override token for agentToken auth\r\n config.token = opts.agentToken;\r\n const client = new ApiClient(config);\r\n const bridge = new StdioBridge();\r\n const sessionManager = new SessionManager(config.wsUrl);\r\n const pollInterval = parseInt(opts.pollInterval, 10);\r\n let agentWs: WebSocket | null = null;\r\n let agentHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n // --- 1. Startup: resolve agent from token ---\r\n let agentId: string;\r\n let agentName: string;\r\n try {\r\n const agent = await client.getMyAgent();\r\n agentId = agent['id'] as string;\r\n agentName = (agent['name'] as string) ?? agentId;\r\n sessionManager.agentId = agentId;\r\n } catch {\r\n printError('Failed to resolve agent from token. Is the token valid?');\r\n process.exit(1);\r\n }\r\n\r\n // --- 2. Notify ready ---\r\n bridge.writeNotification('ready', {\r\n agentId,\r\n agentName,\r\n });\r\n\r\n // --- 3. Wire up session manager events ---\r\n sessionManager.on('session:connected', (sessionId: string) => {\r\n bridge.writeNotification('session.connected', { sessionId });\r\n });\r\n\r\n sessionManager.on('session:message', (sessionId: string, message: Record<string, unknown>) => {\r\n const type = message['type'] as string;\r\n\r\n if (type?.startsWith('instruction.')) {\r\n // Instruction from consumer -> forward as JSON-RPC request (expects response)\r\n const corrId = createCorrelationId();\r\n pendingInstructions.set(corrId, sessionId);\r\n\r\n bridge.writeRequest('instruction', corrId, {\r\n sessionId,\r\n messageId: (message['id'] as string) ?? corrId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n sender: message['sender'],\r\n });\r\n } else if (type?.startsWith('dialogue.')) {\r\n // Dialogue from consumer -> forward as notification\r\n const payload = (message['payload'] as Record<string, unknown>) ?? {};\r\n bridge.writeNotification('dialogue', {\r\n sessionId,\r\n content: payload['content'] ?? '',\r\n dialogueType: payload['dialogueType'] ?? 'message',\r\n });\r\n } else if (type?.startsWith('result.')) {\r\n // Result from consumer -> forward as notification\r\n bridge.writeNotification('result', {\r\n sessionId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n });\r\n } else if (type === 'system.session_ended' || type === 'system.peer_disconnected') {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.ended', {\r\n sessionId,\r\n reason: type,\r\n });\r\n } else if (type === 'system.peer_connected') {\r\n bridge.writeNotification('session.peer_connected', { sessionId });\r\n } else if (type !== 'system.heartbeat_ack') {\r\n // Forward unknown messages as-is\r\n bridge.writeNotification('message', { sessionId, ...message });\r\n }\r\n });\r\n\r\n sessionManager.on('session:disconnected', (sessionId: string, reason: string) => {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.disconnected', { sessionId, reason });\r\n });\r\n\r\n sessionManager.on('session:reconnecting', (sessionId: string, delay: number) => {\r\n bridge.writeNotification('session.reconnecting', { sessionId, delay });\r\n });\r\n\r\n sessionManager.on('session:error', (sessionId: string, err: Error) => {\r\n bridge.writeNotification('session.error', { sessionId, message: err.message });\r\n });\r\n\r\n // --- 4. Handle stdin messages from agent ---\r\n bridge.start((msg: JsonRpcMessage) => {\r\n if (isResponse(msg)) {\r\n // Agent is responding to an instruction we forwarded\r\n const sessionId = pendingInstructions.get(msg.id);\r\n if (sessionId && msg.result) {\r\n pendingInstructions.delete(msg.id);\r\n const result = msg.result as unknown as ResultPayload;\r\n sessionManager.send(sessionId, {\r\n type: result.type ?? 'result.success',\r\n payload: result.payload ?? result,\r\n });\r\n }\r\n } else if (isRequest(msg)) {\r\n // Agent is proactively sending something\r\n if (msg.method === 'send') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n if (params?.['sessionId']) {\r\n const sent = sessionManager.send(params['sessionId'] as string, {\r\n type: params['type'] ?? 'dialogue.message',\r\n payload: (params['payload'] as Record<string, unknown>) ?? { content: '' },\r\n });\r\n bridge.writeResponse(msg.id, { success: sent });\r\n }\r\n } else if (msg.method === 'approve') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n const sid = params?.['sessionId'] as string | undefined;\r\n if (sid) {\r\n approveAndConnect(client, sessionManager, bridge, sid).catch(() => {\r\n bridge.writeResponse(msg.id, { success: false, error: 'Failed to approve' });\r\n }).then(() => {\r\n bridge.writeResponse(msg.id, { success: true });\r\n });\r\n }\r\n }\r\n }\r\n // Notifications from agent are ignored for now\r\n });\r\n\r\n // --- 5. Agent control channel (/ws/agent) + fallback poll loop ---\r\n let pollTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n function connectAgentWs(token: string) {\r\n const wsBase = config.wsUrl ?? config.apiUrl.replace(/^http/, 'ws');\r\n const url = `${wsBase}/ws/agent?token=${token}`;\r\n agentWs = new WebSocket(url);\r\n\r\n agentWs.on('open', () => {\r\n bridge.writeNotification('agent.connected', { agentId });\r\n\r\n // Start heartbeat on agent channel\r\n agentHeartbeatTimer = setInterval(() => {\r\n if (agentWs && agentWs.readyState === WebSocket.OPEN) {\r\n agentWs.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, 25_000);\r\n\r\n // Stop polling when WS is connected\r\n if (pollTimer) {\r\n clearInterval(pollTimer);\r\n pollTimer = null;\r\n }\r\n });\r\n\r\n agentWs.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString());\r\n const type = message.type as string;\r\n\r\n if (type === 'session.new' || type === 'session.approved') {\r\n const payload = message.payload as Record<string, unknown>;\r\n const sid = payload['sessionId'] as string;\r\n const sessionToken = payload['sessionToken'] as string;\r\n\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) return;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove && type === 'session.new') {\r\n approveAndConnect(client, sessionManager, bridge, sid);\r\n } else if (type === 'session.approved' && sessionToken) {\r\n // Already approved, connect directly\r\n activeSessions.add(sid);\r\n bridge.writeNotification('session.new', {\r\n sessionId: sid,\r\n sessionToken,\r\n taskDescription: (payload['taskDescription'] as string) ?? '',\r\n consumerUserId: (payload['consumerUserId'] as string) ?? '',\r\n });\r\n sessionManager.connect(sid, sessionToken);\r\n } else {\r\n bridge.writeNotification('session.pending', {\r\n sessionId: sid,\r\n taskDescription: (payload['taskDescription'] as string) ?? '',\r\n consumerUserId: (payload['consumerUserId'] as string) ?? '',\r\n });\r\n }\r\n }\r\n // Ignore heartbeat_ack and other system messages\r\n } catch {\r\n // Ignore parse errors on agent channel\r\n }\r\n });\r\n\r\n agentWs.on('close', (code, reason) => {\r\n if (agentHeartbeatTimer) {\r\n clearInterval(agentHeartbeatTimer);\r\n agentHeartbeatTimer = null;\r\n }\r\n bridge.writeNotification('agent.disconnected', {\r\n agentId,\r\n code,\r\n reason: reason.toString(),\r\n });\r\n\r\n // Fall back to polling\r\n if (!pollTimer) {\r\n startPollLoop();\r\n }\r\n\r\n // Reconnect after 5s unless deliberately closed\r\n if (code !== 1000 && code !== 4009) {\r\n setTimeout(() => connectAgentWs(token), 5000);\r\n }\r\n });\r\n\r\n agentWs.on('error', () => {\r\n // Error will trigger close event\r\n });\r\n }\r\n\r\n function startPollLoop() {\r\n pollTimer = setInterval(async () => {\r\n try {\r\n const sessions = (await client.getSessions({\r\n role: 'provider',\r\n status: 'pending_approval',\r\n })) as { data: Array<Record<string, unknown>> };\r\n\r\n for (const session of sessions.data ?? []) {\r\n const sid = session['id'] as string;\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) continue;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove) {\r\n await approveAndConnect(client, sessionManager, bridge, sid);\r\n } else {\r\n bridge.writeNotification('session.pending', {\r\n sessionId: sid,\r\n taskDescription: session['taskDescription'] ?? '',\r\n consumerUserId: session['consumerUserId'] ?? '',\r\n });\r\n }\r\n }\r\n } catch {\r\n // Silently retry on next poll\r\n }\r\n }, pollInterval);\r\n }\r\n\r\n // Connect via /ws/agent with the token\r\n connectAgentWs(opts.agentToken);\r\n\r\n // --- 6. Graceful shutdown ---\r\n const shutdown = async () => {\r\n if (pollTimer) clearInterval(pollTimer);\r\n if (agentHeartbeatTimer) clearInterval(agentHeartbeatTimer);\r\n bridge.stop();\r\n\r\n // Close agent WS (this triggers server-side offline update)\r\n if (agentWs) {\r\n try { agentWs.close(1000, 'Shutting down'); } catch { /* ignore */ }\r\n agentWs = null;\r\n }\r\n\r\n sessionManager.disconnectAll();\r\n bridge.writeNotification('shutdown', { reason: 'signal' });\r\n\r\n // Give a moment for messages to flush\r\n setTimeout(() => process.exit(0), 500);\r\n };\r\n\r\n process.on('SIGINT', () => { void shutdown(); });\r\n process.on('SIGTERM', () => { void shutdown(); });\r\n}\r\n\r\nasync function approveAndConnect(\r\n client: ApiClient,\r\n sessionManager: SessionManager,\r\n bridge: StdioBridge,\r\n sessionId: string,\r\n): Promise<void> {\r\n try {\r\n const approved = (await client.approveSession(sessionId)) as Record<string, unknown>;\r\n const sessionToken = approved['sessionToken'] as string;\r\n const taskDescription = approved['taskDescription'] as string;\r\n\r\n activeSessions.add(sessionId);\r\n\r\n bridge.writeNotification('session.new', {\r\n sessionId,\r\n sessionToken,\r\n taskDescription: taskDescription ?? '',\r\n consumerUserId: (approved['consumerUserId'] as string) ?? '',\r\n });\r\n\r\n sessionManager.connect(sessionId, sessionToken);\r\n } catch (err: unknown) {\r\n bridge.writeNotification('session.approve_failed', {\r\n sessionId,\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, unlinkSync, openSync, closeSync, mkdirSync, existsSync, readdirSync } from 'node:fs';\r\nimport { join, basename } from 'node:path';\r\nimport { spawn } from 'node:child_process';\r\nimport { getConfigDir } from './config.js';\r\n\r\nexport function getPidFilePath(agentId: string): string {\r\n return join(getConfigDir(), `serve-${agentId}.pid`);\r\n}\r\n\r\nexport function getLogFilePath(agentId: string): string {\r\n return join(getConfigDir(), `serve-${agentId}.log`);\r\n}\r\n\r\nexport function readPid(agentId: string): number | null {\r\n try {\r\n const content = readFileSync(getPidFilePath(agentId), 'utf-8').trim();\r\n const pid = parseInt(content, 10);\r\n return Number.isFinite(pid) && pid > 0 ? pid : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function writePid(agentId: string, pid: number): void {\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n writeFileSync(getPidFilePath(agentId), String(pid), 'utf-8');\r\n}\r\n\r\nexport function removePidFile(agentId: string): void {\r\n try {\r\n unlinkSync(getPidFilePath(agentId));\r\n } catch {\r\n // Ignore ENOENT\r\n }\r\n}\r\n\r\nexport function isProcessAlive(pid: number): boolean {\r\n try {\r\n process.kill(pid, 0);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function isDaemonRunning(agentId: string): { running: boolean; pid: number | null } {\r\n const pid = readPid(agentId);\r\n if (pid === null) return { running: false, pid: null };\r\n\r\n if (isProcessAlive(pid)) {\r\n return { running: true, pid };\r\n }\r\n\r\n // Stale PID file — process is dead, clean up\r\n removePidFile(agentId);\r\n return { running: false, pid: null };\r\n}\r\n\r\n/** List all running daemons by scanning PID files in config dir */\r\nexport function listRunningDaemons(): Array<{ agentId: string; pid: number }> {\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) return [];\r\n\r\n const results: Array<{ agentId: string; pid: number }> = [];\r\n\r\n for (const file of readdirSync(dir)) {\r\n const match = /^serve-(.+)\\.pid$/.exec(basename(file));\r\n if (!match) continue;\r\n\r\n const agentId = match[1]!;\r\n const { running, pid } = isDaemonRunning(agentId);\r\n if (running && pid !== null) {\r\n results.push({ agentId, pid });\r\n }\r\n }\r\n\r\n return results;\r\n}\r\n\r\nexport function spawnDaemon(agentId: string, args: string[]): number {\r\n const logFile = getLogFilePath(agentId);\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n const logFd = openSync(logFile, 'a');\r\n\r\n const child = spawn(process.argv[0]!, [process.argv[1]!, ...args], {\r\n detached: true,\r\n stdio: ['ignore', logFd, logFd],\r\n windowsHide: true,\r\n });\r\n\r\n child.unref();\r\n closeSync(logFd);\r\n\r\n if (!child.pid) {\r\n throw new Error('Failed to start daemon process');\r\n }\r\n\r\n return child.pid;\r\n}\r\n","import { createInterface } from 'node:readline';\r\nimport type { JsonRpcMessage, JsonRpcResponse, JsonRpcRequest, JsonRpcNotification } from './protocol.js';\r\n\r\nexport type StdinMessageHandler = (msg: JsonRpcMessage) => void;\r\n\r\n/**\r\n * StdioBridge handles JSON Lines communication over stdin/stdout.\r\n * Each line is a JSON-RPC 2.0 message.\r\n */\r\nexport class StdioBridge {\r\n private handler: StdinMessageHandler | null = null;\r\n private rl: ReturnType<typeof createInterface> | null = null;\r\n\r\n /** Start reading from stdin */\r\n start(handler: StdinMessageHandler): void {\r\n this.handler = handler;\r\n this.rl = createInterface({ input: process.stdin, crlfDelay: Infinity });\r\n\r\n this.rl.on('line', (line) => {\r\n const trimmed = line.trim();\r\n if (!trimmed) return;\r\n\r\n try {\r\n const msg = JSON.parse(trimmed) as JsonRpcMessage;\r\n if (msg.jsonrpc !== '2.0') {\r\n this.writeError('Invalid JSON-RPC: missing jsonrpc field');\r\n return;\r\n }\r\n this.handler?.(msg);\r\n } catch {\r\n this.writeError(`Failed to parse JSON: ${trimmed.slice(0, 100)}`);\r\n }\r\n });\r\n\r\n this.rl.on('close', () => {\r\n // stdin closed — process will shut down\r\n });\r\n }\r\n\r\n /** Stop reading */\r\n stop(): void {\r\n this.rl?.close();\r\n this.rl = null;\r\n }\r\n\r\n /** Write a JSON-RPC message to stdout */\r\n write(msg: JsonRpcMessage): void {\r\n process.stdout.write(JSON.stringify(msg) + '\\n');\r\n }\r\n\r\n /** Write a notification */\r\n writeNotification(method: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcNotification = { jsonrpc: '2.0', method, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a request (expects response) */\r\n writeRequest(method: string, id: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcRequest = { jsonrpc: '2.0', method, id, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a response */\r\n writeResponse(id: string, result: Record<string, unknown>): void {\r\n const msg: JsonRpcResponse = { jsonrpc: '2.0', id, result };\r\n this.write(msg);\r\n }\r\n\r\n /** Write an error notification to stdout */\r\n private writeError(message: string): void {\r\n this.writeNotification('error', { message });\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n","// JSON-RPC 2.0 protocol types for clawrent serve stdin/stdout communication\r\n\r\n/** Base JSON-RPC message */\r\nexport interface JsonRpcBase {\r\n jsonrpc: '2.0';\r\n}\r\n\r\n/** JSON-RPC request (has method + id) */\r\nexport interface JsonRpcRequest extends JsonRpcBase {\r\n method: string;\r\n id: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC notification (has method, no id) */\r\nexport interface JsonRpcNotification extends JsonRpcBase {\r\n method: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC response (has id + result or error) */\r\nexport interface JsonRpcResponse extends JsonRpcBase {\r\n id: string;\r\n result?: Record<string, unknown>;\r\n error?: { code: number; message: string; data?: unknown };\r\n}\r\n\r\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcResponse;\r\n\r\n// --- Daemon -> Agent (stdout) methods ---\r\n\r\nexport interface ReadyParams {\r\n agentId: string;\r\n agentName: string;\r\n}\r\n\r\nexport interface SessionNewParams {\r\n sessionId: string;\r\n sessionToken: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n}\r\n\r\nexport interface SessionPendingParams {\r\n sessionId: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n}\r\n\r\nexport interface InstructionParams {\r\n sessionId: string;\r\n messageId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n sender?: Record<string, unknown>;\r\n}\r\n\r\nexport interface DialogueParams {\r\n sessionId: string;\r\n content: string;\r\n dialogueType: string;\r\n}\r\n\r\nexport interface SessionEndedParams {\r\n sessionId: string;\r\n reason: string;\r\n}\r\n\r\n// --- Agent -> Daemon (stdin) methods ---\r\n\r\nexport interface ResultPayload {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface SendParams {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface ApproveParams {\r\n sessionId: string;\r\n}\r\n\r\n// --- Helpers ---\r\n\r\nlet correlationCounter = 0;\r\n\r\nexport function createCorrelationId(): string {\r\n return `corr_${Date.now().toString(36)}_${(correlationCounter++).toString(36)}`;\r\n}\r\n\r\nexport function createNotification(method: string, params: Record<string, unknown>): JsonRpcNotification {\r\n return { jsonrpc: '2.0', method, params };\r\n}\r\n\r\nexport function createRequest(method: string, params: Record<string, unknown>, id?: string): JsonRpcRequest {\r\n return { jsonrpc: '2.0', method, id: id ?? createCorrelationId(), params };\r\n}\r\n\r\nexport function isResponse(msg: JsonRpcMessage): msg is JsonRpcResponse {\r\n return 'id' in msg && ('result' in msg || 'error' in msg) && !('method' in msg);\r\n}\r\n\r\nexport function isRequest(msg: JsonRpcMessage): msg is JsonRpcRequest {\r\n return 'method' in msg && 'id' in msg;\r\n}\r\n\r\nexport function isNotification(msg: JsonRpcMessage): msg is JsonRpcNotification {\r\n return 'method' in msg && !('id' in msg);\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, removePidFile, isProcessAlive, listRunningDaemons } from '../daemon.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nasync function stopOne(agentId: string): Promise<boolean> {\r\n const { running, pid } = isDaemonRunning(agentId);\r\n\r\n if (!running || pid === null) {\r\n return false;\r\n }\r\n\r\n try {\r\n process.kill(pid, 'SIGTERM');\r\n } catch (err: unknown) {\r\n const code = (err as NodeJS.ErrnoException).code;\r\n if (code === 'ESRCH') {\r\n removePidFile(agentId);\r\n return true;\r\n }\r\n if (code === 'EPERM') {\r\n printError(`Permission denied. Cannot stop daemon for agent ${agentId} (PID: ${pid}).`);\r\n return false;\r\n }\r\n throw err;\r\n }\r\n\r\n const maxWait = 3000;\r\n const interval = 200;\r\n let waited = 0;\r\n\r\n while (waited < maxWait) {\r\n await new Promise((r) => setTimeout(r, interval));\r\n waited += interval;\r\n if (!isProcessAlive(pid)) {\r\n removePidFile(agentId);\r\n printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);\r\n return true;\r\n }\r\n }\r\n\r\n try {\r\n process.kill(pid, 'SIGKILL');\r\n } catch {\r\n // May have exited between check and kill\r\n }\r\n\r\n removePidFile(agentId);\r\n printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);\r\n return true;\r\n}\r\n\r\nexport function registerStopCommand(program: Command): void {\r\n program\r\n .command('stop')\r\n .description('Stop background serve daemon(s)')\r\n .option('--agent-id <id>', 'Stop daemon for a specific agent')\r\n .option('--all', 'Stop all running daemons', false)\r\n .action(async (opts: { agentId?: string; all: boolean }) => {\r\n if (opts.agentId) {\r\n const stopped = await stopOne(opts.agentId);\r\n if (!stopped) {\r\n printSuccess(`No daemon running for agent ${opts.agentId}.`);\r\n }\r\n return;\r\n }\r\n\r\n // Default: stop all\r\n const daemons = listRunningDaemons();\r\n if (daemons.length === 0) {\r\n printSuccess('No daemons are running.');\r\n return;\r\n }\r\n\r\n for (const d of daemons) {\r\n await stopOne(d.agentId);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, getLogFilePath, listRunningDaemons } from '../daemon.js';\r\nimport { printJson } from '../output.js';\r\n\r\nexport function registerStatusCommand(program: Command): void {\r\n program\r\n .command('status')\r\n .description('Check running serve daemon(s)')\r\n .option('--agent-id <id>', 'Check daemon for a specific agent')\r\n .action((opts: { agentId?: string }) => {\r\n if (opts.agentId) {\r\n const { running, pid } = isDaemonRunning(opts.agentId);\r\n if (running && pid !== null) {\r\n printJson({ status: 'running', agentId: opts.agentId, pid, logFile: getLogFilePath(opts.agentId) });\r\n } else {\r\n printJson({ status: 'stopped', agentId: opts.agentId });\r\n }\r\n return;\r\n }\r\n\r\n // List all running daemons\r\n const daemons = listRunningDaemons();\r\n if (daemons.length === 0) {\r\n printJson({ daemons: [] });\r\n } else {\r\n printJson({\r\n daemons: daemons.map((d) => ({\r\n agentId: d.agentId,\r\n pid: d.pid,\r\n logFile: getLogFilePath(d.agentId),\r\n })),\r\n });\r\n }\r\n });\r\n}\r\n"],"mappings":"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","names":["readFileSync","join","program","program","program","program","program","program","program","program","program","program","program","WebSocket","readFileSync","writeFileSync","unlinkSync","mkdirSync","existsSync","join","join","readFileSync","existsSync","mkdirSync","writeFileSync","unlinkSync","createInterface","WebSocket","program","WebSocket","program","program","readFileSync","join"]}
|
|
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\n/**\r\n * Prompt for input. Works in both interactive (TTY) and non-interactive (piped) modes.\r\n * - TTY: shows the question, reads from terminal\r\n * - No-TTY: reads a single line from stdin (for agent piped input)\r\n */\r\nasync function promptInput(prompt: string, hidden: boolean = false): Promise<string> {\r\n const stdin = process.stdin;\r\n\r\n // Non-interactive: read a line from stdin pipe\r\n if (!stdin.isTTY) {\r\n const rl = createInterface({ input: stdin });\r\n return new Promise((resolve) => {\r\n rl.question('', (answer) => {\r\n rl.close();\r\n resolve(answer.trim());\r\n });\r\n });\r\n }\r\n\r\n // Interactive: show prompt\r\n return new Promise((resolve) => {\r\n if (hidden) {\r\n process.stderr.write(prompt);\r\n const wasRaw = stdin.isRaw;\r\n if (stdin.setRawMode) 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' || c === '\\u0004') {\r\n stdin.removeListener('data', onData);\r\n if (stdin.setRawMode && wasRaw !== undefined) stdin.setRawMode(wasRaw);\r\n process.stderr.write('\\n');\r\n resolve(input);\r\n } else if (c === '\\u0003') {\r\n process.exit(1);\r\n } else if (c === '\\u007F' || c === '\\b') {\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 const rl = createInterface({ input: stdin, output: process.stderr });\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('send-verification')\r\n .description('Send email verification code (step 1 of registration)')\r\n .requiredOption('-e, --email <email>', 'Email address')\r\n .action(async (opts: { email: string }) => {\r\n try {\r\n const currentConfig = loadConfig();\r\n const client = new ApiClient(currentConfig);\r\n const result = await client.sendVerification(opts.email);\r\n printJson({ email: opts.email, sent: true, ...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 auth\r\n .command('register')\r\n .description('Register a new ClawRent account')\r\n .option('-e, --email <email>', 'Email address')\r\n .option('-n, --name <name>', 'Display name')\r\n .option('-p, --password <password>', 'Password (min 8 chars). If omitted, prompts interactively.')\r\n .option('-c, --code <code>', '6-digit verification code. If omitted, sends code first and prompts.')\r\n .action(async (opts: { email?: string; name?: string; password?: string; code?: string }) => {\r\n try {\r\n const currentConfig = loadConfig();\r\n const client = new ApiClient(currentConfig);\r\n\r\n const email = opts.email ?? await promptInput('Email: ');\r\n const name = opts.name ?? await promptInput('Display name: ');\r\n const password = opts.password ?? await promptInput('Password (min 8 chars): ', true);\r\n\r\n if (password.length < 8) {\r\n printError('Password must be at least 8 characters');\r\n process.exit(1);\r\n }\r\n\r\n let verificationCode: string;\r\n\r\n if (opts.code) {\r\n verificationCode = opts.code;\r\n } else {\r\n // Interactive: send verification code first\r\n printSuccess('Sending verification code to your email...');\r\n await client.sendVerification(email);\r\n printSuccess('Verification code sent! Check your inbox.');\r\n verificationCode = await promptInput('Verification code: ');\r\n }\r\n\r\n const result = await client.registerUser({\r\n email,\r\n password,\r\n name,\r\n verificationCode,\r\n });\r\n\r\n // Save credentials (NO URLs per config separation principle)\r\n saveConfig({\r\n token: result.token,\r\n apiKey: result.apiKey,\r\n userId: result.user.id,\r\n email: result.user.email,\r\n name: result.user.name,\r\n });\r\n\r\n printJson({\r\n success: true,\r\n user: result.user,\r\n token: result.token,\r\n apiKey: result.apiKey,\r\n configSaved: getConfigPath(),\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 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 .action(async (opts: { email?: string; password?: string }) => {\r\n try {\r\n const currentConfig = loadConfig();\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);\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 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 printJson({\r\n success: true,\r\n user: result.user,\r\n token: result.token,\r\n configSaved: getConfigPath(),\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 auth\r\n .command('logout')\r\n .description('Logout and clear saved credentials')\r\n .action(() => {\r\n try {\r\n clearConfig();\r\n printJson({ success: true, message: 'Credentials 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 sendVerification(email: string): Promise<{ message: string }> {\r\n return this.request('POST', '/api/auth/send-verification', { email }, false);\r\n }\r\n\r\n async registerUser(input: {\r\n email: string;\r\n password: string;\r\n name: string;\r\n verificationCode: string;\r\n }): Promise<{ user: { id: string; email: string; name: string; role: string }; token: string; apiKey: string }> {\r\n return this.request('POST', '/api/auth/register', input, false);\r\n }\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; roles?: 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?.roles) params.set('roles', query.roles);\r\n const qs = params.toString();\r\n return this.request('GET', `/api/agents/my${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */\r\n async getMyAgent(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/agents/me/agent');\r\n }\r\n\r\n async applyProvider(agentId: string, data: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/apply-provider`, data);\r\n }\r\n\r\n /** Publish agent — simplified apply-provider with defaults, submits for admin review */\r\n async publishAgent(agentId: string, data?: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`, data ?? {});\r\n }\r\n\r\n /** Activate agent — verify admin-approved + WebSocket connected, then go online */\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 // --- Docs (MCP interface) ---\r\n\r\n async getDocsTree(): Promise<unknown> {\r\n return this.request('GET', '/api/mcp/docs/tree', undefined, false);\r\n }\r\n\r\n async getDocByPath(path: string): Promise<unknown> {\r\n return this.request('GET', `/api/mcp/docs/by-path/${encodeURI(path)}`, undefined, false);\r\n }\r\n\r\n async searchDocs(query: string): Promise<unknown> {\r\n const params = new URLSearchParams({ q: query });\r\n return this.request('GET', `/api/mcp/docs/search?${params.toString()}`, undefined, false);\r\n }\r\n\r\n async getDoc(id: string): Promise<unknown> {\r\n return this.request('GET', `/api/mcp/docs/${encodeURIComponent(id)}`, undefined, false);\r\n }\r\n\r\n async createDoc(data: { type: string; title: string; parentId?: string; content?: string; slug?: string; icon?: string }): Promise<unknown> {\r\n return this.request('POST', '/api/mcp/docs', data);\r\n }\r\n\r\n async updateDoc(id: string, data: { title?: string; content?: string; changeSummary?: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/mcp/docs/${encodeURIComponent(id)}`, data);\r\n }\r\n\r\n async deleteDoc(id: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/mcp/docs/${encodeURIComponent(id)}`);\r\n }\r\n\r\n async publishDoc(id: string): Promise<unknown> {\r\n return this.request('POST', `/api/mcp/docs/${encodeURIComponent(id)}/publish`);\r\n }\r\n\r\n async unpublishDoc(id: string): Promise<unknown> {\r\n return this.request('POST', `/api/mcp/docs/${encodeURIComponent(id)}/unpublish`);\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 { printJson, 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 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 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 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 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('--slot <index>', 'Slot index for consumer role (default: 0)', '0')\r\n .option('--wait <ms>', 'Wait for response (milliseconds)')\r\n .action(async (sessionId: string, opts: { content: string; type: string; token?: string; slot: 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}${role === 'consumer' ? `&slotIndex=${opts.slot}` : ''}`;\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 (consumer by default)')\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('--capabilities <json>', 'Capabilities as JSON array')\r\n .option('--permissions <json>', 'Required permissions as JSON array')\r\n .action(async (opts: {\r\n name: string; slug: string; description: string; longDescription?: string;\r\n capabilities?: string; permissions?: 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 };\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 if (opts.permissions) {\r\n try {\r\n data['requiredPermissions'] = JSON.parse(opts.permissions);\r\n } catch {\r\n printError('Invalid JSON for --permissions');\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('-r, --roles <roles>', 'Filter by roles (consumer, both)')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { roles?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getMyAgents({\r\n roles: opts.roles,\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('apply-provider <agentId>')\r\n .description('Apply for provider role on an agent')\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>', 'Session approval mode (manual/auto)', 'manual')\r\n .option('--max-concurrent <n>', 'Max concurrent sessions', '5')\r\n .option('--max-slots <n>', 'Max consumer slots per session', '1')\r\n .action(async (agentId: string, opts: {\r\n pricingModel: string; price: string; currency: string; hostingType: string;\r\n approvalMode: string; maxConcurrent: string; maxSlots: string;\r\n }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.applyProvider(agentId, {\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 maxConsumerSlots: parseInt(opts.maxSlots, 10),\r\n });\r\n printSuccess('Provider application submitted.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n agent\r\n .command('status <agentId>')\r\n .description('Set agent online status')\r\n .requiredOption('--status <status>', 'Online status (online/offline/busy)')\r\n .action(async (agentId: string, opts: { status: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.setOnlineStatus(agentId, opts.status);\r\n printSuccess(`Agent status set to ${opts.status}.`);\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n // --- Provider session commands ---\r\n provider\r\n .command('sessions')\r\n .description('List provider sessions')\r\n .option('-s, --status <status>', 'Filter by status')\r\n .option('-p, --page <number>', 'Page number', '1')\r\n .option('-l, --limit <number>', 'Results per page', '20')\r\n .action(async (opts: { status?: string; page: string; limit: string }) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.getSessions({\r\n role: 'provider',\r\n status: opts.status,\r\n page: parseInt(opts.page, 10),\r\n limit: parseInt(opts.limit, 10),\r\n });\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n\r\n provider\r\n .command('approve <sessionId>')\r\n .description('Approve a pending session')\r\n .action(async (sessionId: string) => {\r\n try {\r\n const client = new ApiClient(loadConfig());\r\n const result = await client.approveSession(sessionId);\r\n printSuccess('Session approved.');\r\n printJson(result);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport WebSocket from 'ws';\r\nimport { loadConfig } from '../config.js';\r\nimport { ApiClient } from '../api-client.js';\r\nimport { printError, printSuccess } from '../output.js';\r\nimport { isDaemonRunning, spawnDaemon, writePid, getLogFilePath } from '../daemon.js';\r\nimport { StdioBridge } from './stdio-bridge.js';\r\nimport { SessionManager } from './session-manager.js';\r\nimport {\r\n createCorrelationId,\r\n isResponse,\r\n isRequest,\r\n type JsonRpcMessage,\r\n type ResultPayload,\r\n} from './protocol.js';\r\n\r\ninterface ServeOptions {\r\n agentToken: string;\r\n autoApprove: boolean;\r\n pollInterval: string;\r\n daemon: boolean;\r\n}\r\n\r\n/** Pending instruction tracking: correlationId -> sessionId */\r\nconst pendingInstructions = new Map<string, string>();\r\n\r\n/** Known session IDs we've already seen (to avoid duplicate polling notifications) */\r\nconst knownPendingSessions = new Set<string>();\r\nconst activeSessions = new Set<string>();\r\n\r\nexport function registerServeCommand(program: Command): void {\r\n program\r\n .command('serve')\r\n .description('Start serve daemon - bridge WebSocket sessions to stdin/stdout')\r\n .requiredOption('--agent-token <token>', 'Agent token (agt_clawrent_*) for authentication')\r\n .option('--auto-approve', 'Automatically approve incoming sessions', false)\r\n .option('--poll-interval <ms>', 'Polling interval for pending sessions (ms)', '5000')\r\n .option('-d, --daemon', 'Run in background as a daemon process', false)\r\n .action(async (opts: ServeOptions) => {\r\n try {\r\n if (opts.daemon) {\r\n // --- Daemon mode: resolve agentId first, then fork ---\r\n const config = loadConfig();\r\n // Override token for this request\r\n config.token = opts.agentToken;\r\n const client = new ApiClient(config);\r\n\r\n let agentId: string;\r\n try {\r\n const agent = await client.getMyAgent();\r\n agentId = agent['id'] as string;\r\n } catch {\r\n printError('Failed to resolve agent from token. Is the token valid?');\r\n process.exit(1);\r\n }\r\n\r\n const { running, pid: existingPid } = isDaemonRunning(agentId);\r\n if (running) {\r\n printError(`Daemon already running for agent ${agentId} (PID: ${existingPid}). Use 'clawrent stop --agent-id ${agentId}' first.`);\r\n process.exit(1);\r\n }\r\n\r\n // Rebuild args without --daemon / -d\r\n const args: string[] = ['serve', '--agent-token', opts.agentToken];\r\n if (opts.autoApprove) args.push('--auto-approve');\r\n if (opts.pollInterval !== '5000') args.push('--poll-interval', opts.pollInterval);\r\n\r\n const pid = spawnDaemon(agentId, args);\r\n writePid(agentId, pid);\r\n printSuccess(`Daemon started for agent ${agentId} (PID: ${pid})\\nLogs: ${getLogFilePath(agentId)}`);\r\n process.exit(0);\r\n }\r\n\r\n await runDaemon(opts);\r\n } catch (err: unknown) {\r\n printError(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n\r\nasync function runDaemon(opts: ServeOptions): Promise<void> {\r\n const config = loadConfig();\r\n // Override token for agentToken auth\r\n config.token = opts.agentToken;\r\n const client = new ApiClient(config);\r\n const bridge = new StdioBridge();\r\n const sessionManager = new SessionManager(config.wsUrl);\r\n const pollInterval = parseInt(opts.pollInterval, 10);\r\n let agentWs: WebSocket | null = null;\r\n let agentHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n // --- 1. Startup: resolve agent from token ---\r\n let agentId: string;\r\n let agentName: string;\r\n try {\r\n const agent = await client.getMyAgent();\r\n agentId = agent['id'] as string;\r\n agentName = (agent['name'] as string) ?? agentId;\r\n sessionManager.agentId = agentId;\r\n } catch {\r\n printError('Failed to resolve agent from token. Is the token valid?');\r\n process.exit(1);\r\n }\r\n\r\n // --- 2. Notify ready ---\r\n bridge.writeNotification('ready', {\r\n agentId,\r\n agentName,\r\n });\r\n\r\n // --- 3. Wire up session manager events ---\r\n sessionManager.on('session:connected', (sessionId: string) => {\r\n bridge.writeNotification('session.connected', { sessionId });\r\n });\r\n\r\n sessionManager.on('session:message', (sessionId: string, message: Record<string, unknown>) => {\r\n const type = message['type'] as string;\r\n\r\n if (type?.startsWith('instruction.')) {\r\n // Instruction from consumer -> forward as JSON-RPC request (expects response)\r\n const corrId = createCorrelationId();\r\n pendingInstructions.set(corrId, sessionId);\r\n\r\n bridge.writeRequest('instruction', corrId, {\r\n sessionId,\r\n messageId: (message['id'] as string) ?? corrId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n sender: message['sender'],\r\n });\r\n } else if (type?.startsWith('dialogue.')) {\r\n // Dialogue from consumer -> forward as notification\r\n const payload = (message['payload'] as Record<string, unknown>) ?? {};\r\n bridge.writeNotification('dialogue', {\r\n sessionId,\r\n content: payload['content'] ?? '',\r\n dialogueType: payload['dialogueType'] ?? 'message',\r\n });\r\n } else if (type?.startsWith('result.')) {\r\n // Result from consumer -> forward as notification\r\n bridge.writeNotification('result', {\r\n sessionId,\r\n type,\r\n payload: (message['payload'] as Record<string, unknown>) ?? {},\r\n });\r\n } else if (type === 'system.session_ended' || type === 'system.peer_disconnected') {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.ended', {\r\n sessionId,\r\n reason: type,\r\n });\r\n } else if (type === 'system.peer_connected') {\r\n bridge.writeNotification('session.peer_connected', { sessionId });\r\n } else if (type !== 'system.heartbeat_ack') {\r\n // Forward unknown messages as-is\r\n bridge.writeNotification('message', { sessionId, ...message });\r\n }\r\n });\r\n\r\n sessionManager.on('session:disconnected', (sessionId: string, reason: string) => {\r\n activeSessions.delete(sessionId);\r\n bridge.writeNotification('session.disconnected', { sessionId, reason });\r\n });\r\n\r\n sessionManager.on('session:reconnecting', (sessionId: string, delay: number) => {\r\n bridge.writeNotification('session.reconnecting', { sessionId, delay });\r\n });\r\n\r\n sessionManager.on('session:error', (sessionId: string, err: Error) => {\r\n bridge.writeNotification('session.error', { sessionId, message: err.message });\r\n });\r\n\r\n // --- 4. Handle stdin messages from agent ---\r\n bridge.start((msg: JsonRpcMessage) => {\r\n if (isResponse(msg)) {\r\n // Agent is responding to an instruction we forwarded\r\n const sessionId = pendingInstructions.get(msg.id);\r\n if (sessionId && msg.result) {\r\n pendingInstructions.delete(msg.id);\r\n const result = msg.result as unknown as ResultPayload;\r\n sessionManager.send(sessionId, {\r\n type: result.type ?? 'result.success',\r\n payload: result.payload ?? result,\r\n });\r\n }\r\n } else if (isRequest(msg)) {\r\n // Agent is proactively sending something\r\n if (msg.method === 'send') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n if (params?.['sessionId']) {\r\n const sent = sessionManager.send(params['sessionId'] as string, {\r\n type: params['type'] ?? 'dialogue.message',\r\n payload: (params['payload'] as Record<string, unknown>) ?? { content: '' },\r\n });\r\n bridge.writeResponse(msg.id, { success: sent });\r\n }\r\n } else if (msg.method === 'approve') {\r\n const params = msg.params as Record<string, unknown> | undefined;\r\n const sid = params?.['sessionId'] as string | undefined;\r\n if (sid) {\r\n approveAndConnect(client, sessionManager, bridge, sid).catch(() => {\r\n bridge.writeResponse(msg.id, { success: false, error: 'Failed to approve' });\r\n }).then(() => {\r\n bridge.writeResponse(msg.id, { success: true });\r\n });\r\n }\r\n }\r\n }\r\n // Notifications from agent are ignored for now\r\n });\r\n\r\n // --- 5. Agent control channel (/ws/agent) + fallback poll loop ---\r\n let pollTimer: ReturnType<typeof setInterval> | null = null;\r\n\r\n function connectAgentWs(token: string) {\r\n const wsBase = config.wsUrl ?? config.apiUrl.replace(/^http/, 'ws');\r\n const url = `${wsBase}/ws/agent?token=${token}`;\r\n agentWs = new WebSocket(url);\r\n\r\n agentWs.on('open', () => {\r\n bridge.writeNotification('agent.connected', { agentId });\r\n\r\n // Start heartbeat on agent channel\r\n agentHeartbeatTimer = setInterval(() => {\r\n if (agentWs && agentWs.readyState === WebSocket.OPEN) {\r\n agentWs.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, 25_000);\r\n\r\n // Stop polling when WS is connected\r\n if (pollTimer) {\r\n clearInterval(pollTimer);\r\n pollTimer = null;\r\n }\r\n });\r\n\r\n agentWs.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString());\r\n const type = message.type as string;\r\n\r\n if (type === 'session.new' || type === 'session.approved') {\r\n const payload = message.payload as Record<string, unknown>;\r\n const sid = payload['sessionId'] as string;\r\n const sessionToken = payload['sessionToken'] as string;\r\n\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) return;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove && type === 'session.new') {\r\n approveAndConnect(client, sessionManager, bridge, sid);\r\n } else if (type === 'session.approved' && sessionToken) {\r\n // Already approved, connect directly\r\n activeSessions.add(sid);\r\n bridge.writeNotification('session.new', {\r\n sessionId: sid,\r\n sessionToken,\r\n taskDescription: (payload['taskDescription'] as string) ?? '',\r\n consumerUserId: (payload['consumerUserId'] as string) ?? '',\r\n slotIndex: (payload['slotIndex'] as number) ?? 0,\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 slotIndex: (payload['slotIndex'] as number) ?? 0,\r\n });\r\n }\r\n }\r\n // Ignore heartbeat_ack and other system messages\r\n } catch {\r\n // Ignore parse errors on agent channel\r\n }\r\n });\r\n\r\n agentWs.on('close', (code, reason) => {\r\n if (agentHeartbeatTimer) {\r\n clearInterval(agentHeartbeatTimer);\r\n agentHeartbeatTimer = null;\r\n }\r\n bridge.writeNotification('agent.disconnected', {\r\n agentId,\r\n code,\r\n reason: reason.toString(),\r\n });\r\n\r\n // Fall back to polling\r\n if (!pollTimer) {\r\n startPollLoop();\r\n }\r\n\r\n // Reconnect after 5s unless deliberately closed\r\n if (code !== 1000 && code !== 4009) {\r\n setTimeout(() => connectAgentWs(token), 5000);\r\n }\r\n });\r\n\r\n agentWs.on('error', () => {\r\n // Error will trigger close event\r\n });\r\n }\r\n\r\n function startPollLoop() {\r\n pollTimer = setInterval(async () => {\r\n try {\r\n const sessions = (await client.getSessions({\r\n role: 'provider',\r\n status: 'pending_approval',\r\n })) as { data: Array<Record<string, unknown>> };\r\n\r\n for (const session of sessions.data ?? []) {\r\n const sid = session['id'] as string;\r\n if (knownPendingSessions.has(sid) || activeSessions.has(sid)) continue;\r\n knownPendingSessions.add(sid);\r\n\r\n if (opts.autoApprove) {\r\n await approveAndConnect(client, sessionManager, bridge, sid);\r\n } else {\r\n bridge.writeNotification('session.pending', {\r\n sessionId: sid,\r\n taskDescription: session['taskDescription'] ?? '',\r\n consumerUserId: session['consumerUserId'] ?? '',\r\n });\r\n }\r\n }\r\n } catch {\r\n // Silently retry on next poll\r\n }\r\n }, pollInterval);\r\n }\r\n\r\n // Connect via /ws/agent with the token\r\n connectAgentWs(opts.agentToken);\r\n\r\n // --- 6. Graceful shutdown ---\r\n const shutdown = async () => {\r\n if (pollTimer) clearInterval(pollTimer);\r\n if (agentHeartbeatTimer) clearInterval(agentHeartbeatTimer);\r\n bridge.stop();\r\n\r\n // Close agent WS (this triggers server-side offline update)\r\n if (agentWs) {\r\n try { agentWs.close(1000, 'Shutting down'); } catch { /* ignore */ }\r\n agentWs = null;\r\n }\r\n\r\n sessionManager.disconnectAll();\r\n bridge.writeNotification('shutdown', { reason: 'signal' });\r\n\r\n // Give a moment for messages to flush\r\n setTimeout(() => process.exit(0), 500);\r\n };\r\n\r\n process.on('SIGINT', () => { void shutdown(); });\r\n process.on('SIGTERM', () => { void shutdown(); });\r\n}\r\n\r\nasync function approveAndConnect(\r\n client: ApiClient,\r\n sessionManager: SessionManager,\r\n bridge: StdioBridge,\r\n sessionId: string,\r\n): Promise<void> {\r\n try {\r\n const approved = (await client.approveSession(sessionId)) as Record<string, unknown>;\r\n const sessionToken = approved['sessionToken'] as string;\r\n const taskDescription = approved['taskDescription'] as string;\r\n\r\n activeSessions.add(sessionId);\r\n\r\n bridge.writeNotification('session.new', {\r\n sessionId,\r\n sessionToken,\r\n taskDescription: taskDescription ?? '',\r\n consumerUserId: (approved['consumerUserId'] as string) ?? '',\r\n });\r\n\r\n sessionManager.connect(sessionId, sessionToken);\r\n } catch (err: unknown) {\r\n bridge.writeNotification('session.approve_failed', {\r\n sessionId,\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, unlinkSync, openSync, closeSync, mkdirSync, existsSync, readdirSync } from 'node:fs';\r\nimport { join, basename } from 'node:path';\r\nimport { spawn } from 'node:child_process';\r\nimport { getConfigDir } from './config.js';\r\n\r\nexport function getPidFilePath(agentId: string): string {\r\n return join(getConfigDir(), `serve-${agentId}.pid`);\r\n}\r\n\r\nexport function getLogFilePath(agentId: string): string {\r\n return join(getConfigDir(), `serve-${agentId}.log`);\r\n}\r\n\r\nexport function readPid(agentId: string): number | null {\r\n try {\r\n const content = readFileSync(getPidFilePath(agentId), 'utf-8').trim();\r\n const pid = parseInt(content, 10);\r\n return Number.isFinite(pid) && pid > 0 ? pid : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function writePid(agentId: string, pid: number): void {\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n writeFileSync(getPidFilePath(agentId), String(pid), 'utf-8');\r\n}\r\n\r\nexport function removePidFile(agentId: string): void {\r\n try {\r\n unlinkSync(getPidFilePath(agentId));\r\n } catch {\r\n // Ignore ENOENT\r\n }\r\n}\r\n\r\nexport function isProcessAlive(pid: number): boolean {\r\n try {\r\n process.kill(pid, 0);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function isDaemonRunning(agentId: string): { running: boolean; pid: number | null } {\r\n const pid = readPid(agentId);\r\n if (pid === null) return { running: false, pid: null };\r\n\r\n if (isProcessAlive(pid)) {\r\n return { running: true, pid };\r\n }\r\n\r\n // Stale PID file — process is dead, clean up\r\n removePidFile(agentId);\r\n return { running: false, pid: null };\r\n}\r\n\r\n/** List all running daemons by scanning PID files in config dir */\r\nexport function listRunningDaemons(): Array<{ agentId: string; pid: number }> {\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) return [];\r\n\r\n const results: Array<{ agentId: string; pid: number }> = [];\r\n\r\n for (const file of readdirSync(dir)) {\r\n const match = /^serve-(.+)\\.pid$/.exec(basename(file));\r\n if (!match) continue;\r\n\r\n const agentId = match[1]!;\r\n const { running, pid } = isDaemonRunning(agentId);\r\n if (running && pid !== null) {\r\n results.push({ agentId, pid });\r\n }\r\n }\r\n\r\n return results;\r\n}\r\n\r\nexport function spawnDaemon(agentId: string, args: string[]): number {\r\n const logFile = getLogFilePath(agentId);\r\n const dir = getConfigDir();\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n const logFd = openSync(logFile, 'a');\r\n\r\n const child = spawn(process.argv[0]!, [process.argv[1]!, ...args], {\r\n detached: true,\r\n stdio: ['ignore', logFd, logFd],\r\n windowsHide: true,\r\n });\r\n\r\n child.unref();\r\n closeSync(logFd);\r\n\r\n if (!child.pid) {\r\n throw new Error('Failed to start daemon process');\r\n }\r\n\r\n return child.pid;\r\n}\r\n","import { createInterface } from 'node:readline';\r\nimport type { JsonRpcMessage, JsonRpcResponse, JsonRpcRequest, JsonRpcNotification } from './protocol.js';\r\n\r\nexport type StdinMessageHandler = (msg: JsonRpcMessage) => void;\r\n\r\n/**\r\n * StdioBridge handles JSON Lines communication over stdin/stdout.\r\n * Each line is a JSON-RPC 2.0 message.\r\n */\r\nexport class StdioBridge {\r\n private handler: StdinMessageHandler | null = null;\r\n private rl: ReturnType<typeof createInterface> | null = null;\r\n\r\n /** Start reading from stdin */\r\n start(handler: StdinMessageHandler): void {\r\n this.handler = handler;\r\n this.rl = createInterface({ input: process.stdin, crlfDelay: Infinity });\r\n\r\n this.rl.on('line', (line) => {\r\n const trimmed = line.trim();\r\n if (!trimmed) return;\r\n\r\n try {\r\n const msg = JSON.parse(trimmed) as JsonRpcMessage;\r\n if (msg.jsonrpc !== '2.0') {\r\n this.writeError('Invalid JSON-RPC: missing jsonrpc field');\r\n return;\r\n }\r\n this.handler?.(msg);\r\n } catch {\r\n this.writeError(`Failed to parse JSON: ${trimmed.slice(0, 100)}`);\r\n }\r\n });\r\n\r\n this.rl.on('close', () => {\r\n // stdin closed — process will shut down\r\n });\r\n }\r\n\r\n /** Stop reading */\r\n stop(): void {\r\n this.rl?.close();\r\n this.rl = null;\r\n }\r\n\r\n /** Write a JSON-RPC message to stdout */\r\n write(msg: JsonRpcMessage): void {\r\n process.stdout.write(JSON.stringify(msg) + '\\n');\r\n }\r\n\r\n /** Write a notification */\r\n writeNotification(method: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcNotification = { jsonrpc: '2.0', method, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a request (expects response) */\r\n writeRequest(method: string, id: string, params: Record<string, unknown>): void {\r\n const msg: JsonRpcRequest = { jsonrpc: '2.0', method, id, params };\r\n this.write(msg);\r\n }\r\n\r\n /** Write a response */\r\n writeResponse(id: string, result: Record<string, unknown>): void {\r\n const msg: JsonRpcResponse = { jsonrpc: '2.0', id, result };\r\n this.write(msg);\r\n }\r\n\r\n /** Write an error notification to stdout */\r\n private writeError(message: string): void {\r\n this.writeNotification('error', { message });\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n","// JSON-RPC 2.0 protocol types for clawrent serve stdin/stdout communication\r\n\r\n/** Base JSON-RPC message */\r\nexport interface JsonRpcBase {\r\n jsonrpc: '2.0';\r\n}\r\n\r\n/** JSON-RPC request (has method + id) */\r\nexport interface JsonRpcRequest extends JsonRpcBase {\r\n method: string;\r\n id: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC notification (has method, no id) */\r\nexport interface JsonRpcNotification extends JsonRpcBase {\r\n method: string;\r\n params?: Record<string, unknown>;\r\n}\r\n\r\n/** JSON-RPC response (has id + result or error) */\r\nexport interface JsonRpcResponse extends JsonRpcBase {\r\n id: string;\r\n result?: Record<string, unknown>;\r\n error?: { code: number; message: string; data?: unknown };\r\n}\r\n\r\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcResponse;\r\n\r\n// --- Daemon -> Agent (stdout) methods ---\r\n\r\nexport interface ReadyParams {\r\n agentId: string;\r\n agentName: string;\r\n}\r\n\r\nexport interface SessionNewParams {\r\n sessionId: string;\r\n sessionToken: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n slotIndex?: number;\r\n}\r\n\r\nexport interface SessionPendingParams {\r\n sessionId: string;\r\n taskDescription: string;\r\n consumerUserId: string;\r\n slotIndex?: number;\r\n}\r\n\r\nexport interface InstructionParams {\r\n sessionId: string;\r\n messageId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n sender?: Record<string, unknown>;\r\n}\r\n\r\nexport interface DialogueParams {\r\n sessionId: string;\r\n content: string;\r\n dialogueType: string;\r\n}\r\n\r\nexport interface SessionEndedParams {\r\n sessionId: string;\r\n reason: string;\r\n}\r\n\r\n// --- Agent -> Daemon (stdin) methods ---\r\n\r\nexport interface ResultPayload {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface SendParams {\r\n sessionId: string;\r\n type: string;\r\n payload: Record<string, unknown>;\r\n}\r\n\r\nexport interface ApproveParams {\r\n sessionId: string;\r\n}\r\n\r\n// --- Helpers ---\r\n\r\nlet correlationCounter = 0;\r\n\r\nexport function createCorrelationId(): string {\r\n return `corr_${Date.now().toString(36)}_${(correlationCounter++).toString(36)}`;\r\n}\r\n\r\nexport function createNotification(method: string, params: Record<string, unknown>): JsonRpcNotification {\r\n return { jsonrpc: '2.0', method, params };\r\n}\r\n\r\nexport function createRequest(method: string, params: Record<string, unknown>, id?: string): JsonRpcRequest {\r\n return { jsonrpc: '2.0', method, id: id ?? createCorrelationId(), params };\r\n}\r\n\r\nexport function isResponse(msg: JsonRpcMessage): msg is JsonRpcResponse {\r\n return 'id' in msg && ('result' in msg || 'error' in msg) && !('method' in msg);\r\n}\r\n\r\nexport function isRequest(msg: JsonRpcMessage): msg is JsonRpcRequest {\r\n return 'method' in msg && 'id' in msg;\r\n}\r\n\r\nexport function isNotification(msg: JsonRpcMessage): msg is JsonRpcNotification {\r\n return 'method' in msg && !('id' in msg);\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, removePidFile, isProcessAlive, listRunningDaemons } from '../daemon.js';\r\nimport { printSuccess, printError } from '../output.js';\r\n\r\nasync function stopOne(agentId: string): Promise<boolean> {\r\n const { running, pid } = isDaemonRunning(agentId);\r\n\r\n if (!running || pid === null) {\r\n return false;\r\n }\r\n\r\n try {\r\n process.kill(pid, 'SIGTERM');\r\n } catch (err: unknown) {\r\n const code = (err as NodeJS.ErrnoException).code;\r\n if (code === 'ESRCH') {\r\n removePidFile(agentId);\r\n return true;\r\n }\r\n if (code === 'EPERM') {\r\n printError(`Permission denied. Cannot stop daemon for agent ${agentId} (PID: ${pid}).`);\r\n return false;\r\n }\r\n throw err;\r\n }\r\n\r\n const maxWait = 3000;\r\n const interval = 200;\r\n let waited = 0;\r\n\r\n while (waited < maxWait) {\r\n await new Promise((r) => setTimeout(r, interval));\r\n waited += interval;\r\n if (!isProcessAlive(pid)) {\r\n removePidFile(agentId);\r\n printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);\r\n return true;\r\n }\r\n }\r\n\r\n try {\r\n process.kill(pid, 'SIGKILL');\r\n } catch {\r\n // May have exited between check and kill\r\n }\r\n\r\n removePidFile(agentId);\r\n printSuccess(`Daemon stopped for agent ${agentId} (PID: ${pid}).`);\r\n return true;\r\n}\r\n\r\nexport function registerStopCommand(program: Command): void {\r\n program\r\n .command('stop')\r\n .description('Stop background serve daemon(s)')\r\n .option('--agent-id <id>', 'Stop daemon for a specific agent')\r\n .option('--all', 'Stop all running daemons', false)\r\n .action(async (opts: { agentId?: string; all: boolean }) => {\r\n if (opts.agentId) {\r\n const stopped = await stopOne(opts.agentId);\r\n if (!stopped) {\r\n printSuccess(`No daemon running for agent ${opts.agentId}.`);\r\n }\r\n return;\r\n }\r\n\r\n // Default: stop all\r\n const daemons = listRunningDaemons();\r\n if (daemons.length === 0) {\r\n printSuccess('No daemons are running.');\r\n return;\r\n }\r\n\r\n for (const d of daemons) {\r\n await stopOne(d.agentId);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { isDaemonRunning, getLogFilePath, listRunningDaemons } from '../daemon.js';\r\nimport { printJson } from '../output.js';\r\n\r\nexport function registerStatusCommand(program: Command): void {\r\n program\r\n .command('status')\r\n .description('Check running serve daemon(s)')\r\n .option('--agent-id <id>', 'Check daemon for a specific agent')\r\n .action((opts: { agentId?: string }) => {\r\n if (opts.agentId) {\r\n const { running, pid } = isDaemonRunning(opts.agentId);\r\n if (running && pid !== null) {\r\n printJson({ status: 'running', agentId: opts.agentId, pid, logFile: getLogFilePath(opts.agentId) });\r\n } else {\r\n printJson({ status: 'stopped', agentId: opts.agentId });\r\n }\r\n return;\r\n }\r\n\r\n // List all running daemons\r\n const daemons = listRunningDaemons();\r\n if (daemons.length === 0) {\r\n printJson({ daemons: [] });\r\n } else {\r\n printJson({\r\n daemons: daemons.map((d) => ({\r\n agentId: d.agentId,\r\n pid: d.pid,\r\n logFile: getLogFilePath(d.agentId),\r\n })),\r\n });\r\n }\r\n });\r\n}\r\n"],"mappings":"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","names":["readFileSync","join","program","program","program","program","program","program","program","program","program","program","program","WebSocket","readFileSync","writeFileSync","unlinkSync","mkdirSync","existsSync","join","join","readFileSync","existsSync","mkdirSync","writeFileSync","unlinkSync","createInterface","WebSocket","program","WebSocket","program","program","readFileSync","join"]}
|
package/dist/lib.d.ts
CHANGED
|
@@ -21,6 +21,24 @@ declare class ApiClient {
|
|
|
21
21
|
get apiUrl(): string;
|
|
22
22
|
get wsUrl(): string;
|
|
23
23
|
get userId(): string | undefined;
|
|
24
|
+
sendVerification(email: string): Promise<{
|
|
25
|
+
message: string;
|
|
26
|
+
}>;
|
|
27
|
+
registerUser(input: {
|
|
28
|
+
email: string;
|
|
29
|
+
password: string;
|
|
30
|
+
name: string;
|
|
31
|
+
verificationCode: string;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
user: {
|
|
34
|
+
id: string;
|
|
35
|
+
email: string;
|
|
36
|
+
name: string;
|
|
37
|
+
role: string;
|
|
38
|
+
};
|
|
39
|
+
token: string;
|
|
40
|
+
apiKey: string;
|
|
41
|
+
}>;
|
|
24
42
|
login(email: string, password: string): Promise<{
|
|
25
43
|
user: {
|
|
26
44
|
id: string;
|
|
@@ -63,11 +81,14 @@ declare class ApiClient {
|
|
|
63
81
|
getMyAgents(query?: {
|
|
64
82
|
page?: number;
|
|
65
83
|
limit?: number;
|
|
66
|
-
|
|
84
|
+
roles?: string;
|
|
67
85
|
}): Promise<unknown>;
|
|
68
86
|
/** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */
|
|
69
87
|
getMyAgent(): Promise<Record<string, unknown>>;
|
|
70
|
-
|
|
88
|
+
applyProvider(agentId: string, data: Record<string, unknown>): Promise<unknown>;
|
|
89
|
+
/** Publish agent — simplified apply-provider with defaults, submits for admin review */
|
|
90
|
+
publishAgent(agentId: string, data?: Record<string, unknown>): Promise<unknown>;
|
|
91
|
+
/** Activate agent — verify admin-approved + WebSocket connected, then go online */
|
|
71
92
|
activateAgent(agentId: string): Promise<unknown>;
|
|
72
93
|
setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown>;
|
|
73
94
|
generateAgentToken(agentId: string): Promise<{
|
|
@@ -113,6 +134,26 @@ declare class ApiClient {
|
|
|
113
134
|
addFavorite(agentId: string): Promise<unknown>;
|
|
114
135
|
removeFavorite(agentId: string): Promise<unknown>;
|
|
115
136
|
health(): Promise<unknown>;
|
|
137
|
+
getDocsTree(): Promise<unknown>;
|
|
138
|
+
getDocByPath(path: string): Promise<unknown>;
|
|
139
|
+
searchDocs(query: string): Promise<unknown>;
|
|
140
|
+
getDoc(id: string): Promise<unknown>;
|
|
141
|
+
createDoc(data: {
|
|
142
|
+
type: string;
|
|
143
|
+
title: string;
|
|
144
|
+
parentId?: string;
|
|
145
|
+
content?: string;
|
|
146
|
+
slug?: string;
|
|
147
|
+
icon?: string;
|
|
148
|
+
}): Promise<unknown>;
|
|
149
|
+
updateDoc(id: string, data: {
|
|
150
|
+
title?: string;
|
|
151
|
+
content?: string;
|
|
152
|
+
changeSummary?: string;
|
|
153
|
+
}): Promise<unknown>;
|
|
154
|
+
deleteDoc(id: string): Promise<unknown>;
|
|
155
|
+
publishDoc(id: string): Promise<unknown>;
|
|
156
|
+
unpublishDoc(id: string): Promise<unknown>;
|
|
116
157
|
private request;
|
|
117
158
|
}
|
|
118
159
|
|
package/dist/lib.js
CHANGED
|
@@ -14,6 +14,12 @@ var ApiClient = class {
|
|
|
14
14
|
return this.config.userId;
|
|
15
15
|
}
|
|
16
16
|
// --- Auth (no auth needed) ---
|
|
17
|
+
async sendVerification(email) {
|
|
18
|
+
return this.request("POST", "/api/auth/send-verification", { email }, false);
|
|
19
|
+
}
|
|
20
|
+
async registerUser(input) {
|
|
21
|
+
return this.request("POST", "/api/auth/register", input, false);
|
|
22
|
+
}
|
|
17
23
|
async login(email, password) {
|
|
18
24
|
return this.request("POST", "/api/auth/login", { email, password }, false);
|
|
19
25
|
}
|
|
@@ -77,7 +83,7 @@ var ApiClient = class {
|
|
|
77
83
|
const params = new URLSearchParams();
|
|
78
84
|
if (query?.page) params.set("page", String(query.page));
|
|
79
85
|
if (query?.limit) params.set("limit", String(query.limit));
|
|
80
|
-
if (query?.
|
|
86
|
+
if (query?.roles) params.set("roles", query.roles);
|
|
81
87
|
const qs = params.toString();
|
|
82
88
|
return this.request("GET", `/api/agents/my${qs ? `?${qs}` : ""}`);
|
|
83
89
|
}
|
|
@@ -85,9 +91,14 @@ var ApiClient = class {
|
|
|
85
91
|
async getMyAgent() {
|
|
86
92
|
return this.request("GET", "/api/agents/me/agent");
|
|
87
93
|
}
|
|
88
|
-
async
|
|
89
|
-
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/
|
|
94
|
+
async applyProvider(agentId, data) {
|
|
95
|
+
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/apply-provider`, data);
|
|
96
|
+
}
|
|
97
|
+
/** Publish agent — simplified apply-provider with defaults, submits for admin review */
|
|
98
|
+
async publishAgent(agentId, data) {
|
|
99
|
+
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/publish`, data ?? {});
|
|
90
100
|
}
|
|
101
|
+
/** Activate agent — verify admin-approved + WebSocket connected, then go online */
|
|
91
102
|
async activateAgent(agentId) {
|
|
92
103
|
return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/activate`);
|
|
93
104
|
}
|
|
@@ -152,6 +163,35 @@ var ApiClient = class {
|
|
|
152
163
|
async health() {
|
|
153
164
|
return this.request("GET", "/api/health", void 0, false);
|
|
154
165
|
}
|
|
166
|
+
// --- Docs (MCP interface) ---
|
|
167
|
+
async getDocsTree() {
|
|
168
|
+
return this.request("GET", "/api/mcp/docs/tree", void 0, false);
|
|
169
|
+
}
|
|
170
|
+
async getDocByPath(path) {
|
|
171
|
+
return this.request("GET", `/api/mcp/docs/by-path/${encodeURI(path)}`, void 0, false);
|
|
172
|
+
}
|
|
173
|
+
async searchDocs(query) {
|
|
174
|
+
const params = new URLSearchParams({ q: query });
|
|
175
|
+
return this.request("GET", `/api/mcp/docs/search?${params.toString()}`, void 0, false);
|
|
176
|
+
}
|
|
177
|
+
async getDoc(id) {
|
|
178
|
+
return this.request("GET", `/api/mcp/docs/${encodeURIComponent(id)}`, void 0, false);
|
|
179
|
+
}
|
|
180
|
+
async createDoc(data) {
|
|
181
|
+
return this.request("POST", "/api/mcp/docs", data);
|
|
182
|
+
}
|
|
183
|
+
async updateDoc(id, data) {
|
|
184
|
+
return this.request("PATCH", `/api/mcp/docs/${encodeURIComponent(id)}`, data);
|
|
185
|
+
}
|
|
186
|
+
async deleteDoc(id) {
|
|
187
|
+
return this.request("DELETE", `/api/mcp/docs/${encodeURIComponent(id)}`);
|
|
188
|
+
}
|
|
189
|
+
async publishDoc(id) {
|
|
190
|
+
return this.request("POST", `/api/mcp/docs/${encodeURIComponent(id)}/publish`);
|
|
191
|
+
}
|
|
192
|
+
async unpublishDoc(id) {
|
|
193
|
+
return this.request("POST", `/api/mcp/docs/${encodeURIComponent(id)}/unpublish`);
|
|
194
|
+
}
|
|
155
195
|
// --- Private ---
|
|
156
196
|
async request(method, path, body, requireAuth = true) {
|
|
157
197
|
const url = `${this.config.apiUrl}${path}`;
|
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 /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */\r\n async getMyAgent(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/agents/me/agent');\r\n }\r\n\r\n async publishAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`);\r\n }\r\n\r\n async activateAgent(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/activate`);\r\n }\r\n\r\n async setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown> {\r\n return this.request('PATCH', `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });\r\n }\r\n\r\n async generateAgentToken(agentId: string): Promise<{ agentId: string; token: string; createdAt: string; warning: string }> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n async revokeAgentToken(agentId: string): Promise<{ message: string }> {\r\n return this.request('DELETE', `/api/agents/${encodeURIComponent(agentId)}/token`);\r\n }\r\n\r\n // --- Orders ---\r\n\r\n async createOrder(data: {\r\n items: Array<{ providerAgentId: string; consumerAgentId?: string; taskDescription: string; grantedPermissions?: Record<string, unknown> }>;\r\n note?: string;\r\n fromCart?: boolean;\r\n }): Promise<unknown> {\r\n return this.request('POST', '/api/orders', data);\r\n }\r\n\r\n async getOrders(query?: { status?: string; page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.status) params.set('status', query.status);\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/orders${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async getOrder(orderId: string): Promise<unknown> {\r\n return this.request('GET', `/api/orders/${encodeURIComponent(orderId)}`);\r\n }\r\n\r\n async cancelOrder(orderId: string): Promise<unknown> {\r\n return this.request('POST', `/api/orders/${encodeURIComponent(orderId)}/cancel`);\r\n }\r\n\r\n // --- Cart ---\r\n\r\n async getCart(): Promise<unknown> {\r\n return this.request('GET', '/api/cart');\r\n }\r\n\r\n async addToCart(data: { providerAgentId: string; taskDescription: string }): Promise<unknown> {\r\n return this.request('POST', '/api/cart', data);\r\n }\r\n\r\n async updateCartItem(itemId: string, data: { taskDescription: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/cart/${encodeURIComponent(itemId)}`, data);\r\n }\r\n\r\n async removeFromCart(itemId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/cart/${encodeURIComponent(itemId)}`);\r\n }\r\n\r\n async clearCart(): Promise<unknown> {\r\n return this.request('DELETE', '/api/cart');\r\n }\r\n\r\n // --- Favorites ---\r\n\r\n async listFavorites(query?: { page?: number; limit?: number }): Promise<unknown> {\r\n const params = new URLSearchParams();\r\n if (query?.page) params.set('page', String(query.page));\r\n if (query?.limit) params.set('limit', String(query.limit));\r\n const qs = params.toString();\r\n return this.request('GET', `/api/favorites${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n async addFavorite(agentId: string): Promise<unknown> {\r\n return this.request('POST', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n async removeFavorite(agentId: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/favorites/${encodeURIComponent(agentId)}`);\r\n }\r\n\r\n // --- Health ---\r\n\r\n async health(): Promise<unknown> {\r\n return this.request('GET', '/api/health', undefined, false);\r\n }\r\n\r\n // --- Private ---\r\n\r\n private async request<T = any>(method: string, path: string, body?: unknown, requireAuth: boolean = true): Promise<T> {\r\n const url = `${this.config.apiUrl}${path}`;\r\n const headers: Record<string, string> = {};\r\n\r\n if (body !== undefined) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n if (requireAuth) {\r\n if (this.config.token) {\r\n headers['Authorization'] = `Bearer ${this.config.token}`;\r\n } else if (this.config.apiKey) {\r\n headers['x-api-key'] = this.config.apiKey;\r\n } else {\r\n throw new Error('Not authenticated. Run `clawrent auth login` first.');\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.json().catch(() => ({ message: response.statusText })) as Record<string, unknown>;\r\n throw new Error(`API error ${response.status}: ${errBody['message'] ?? JSON.stringify(errBody)}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\n\r\nexport interface ClawRentConfig {\r\n apiUrl: string;\r\n wsUrl: string;\r\n token?: string;\r\n apiKey?: string;\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: ClawRentConfig = {\r\n apiUrl: 'https://clawrent.cloud',\r\n wsUrl: 'wss://clawrent.cloud',\r\n};\r\n\r\nexport function getConfigDir(): string {\r\n return join(homedir(), '.clawrent');\r\n}\r\n\r\nfunction getConfigFilePath(): string {\r\n return join(getConfigDir(), 'config.json');\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return getConfigFilePath();\r\n}\r\n\r\nexport function loadConfig(): ClawRentConfig {\r\n let fileConfig: Partial<ClawRentConfig> = {};\r\n\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n const raw = readFileSync(configPath, 'utf-8');\r\n fileConfig = JSON.parse(raw) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Ignore corrupt config file\r\n }\r\n }\r\n\r\n // Migration: remove stale localhost URLs saved by older CLI versions.\r\n // These override the new production defaults and break remote connections.\r\n if (fileConfig.apiUrl?.includes('localhost') || fileConfig.wsUrl?.includes('localhost')) {\r\n delete fileConfig.apiUrl;\r\n delete fileConfig.wsUrl;\r\n // Persist the cleanup so it only runs once\r\n try {\r\n const cleaned = { ...fileConfig };\r\n writeFileSync(configPath, JSON.stringify(cleaned, null, 2), 'utf-8');\r\n } catch {\r\n // Non-fatal\r\n }\r\n }\r\n\r\n // Merge: defaults < file < env vars\r\n const config: ClawRentConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...fileConfig,\r\n };\r\n\r\n // Env vars always override\r\n const envApiUrl = process.env['CLAWRENT_API_URL'];\r\n const envWsUrl = process.env['CLAWRENT_WS_URL'];\r\n const envToken = process.env['CLAWRENT_TOKEN'];\r\n const envApiKey = process.env['CLAWRENT_API_KEY'];\r\n const envUserId = process.env['CLAWRENT_USER_ID'];\r\n\r\n if (envApiUrl) config.apiUrl = envApiUrl;\r\n if (envWsUrl) config.wsUrl = envWsUrl;\r\n if (envToken) config.token = envToken;\r\n if (envApiKey) config.apiKey = envApiKey;\r\n if (envUserId) config.userId = envUserId;\r\n\r\n return config;\r\n}\r\n\r\nexport function saveConfig(partial: Partial<ClawRentConfig>): void {\r\n const configDir = getConfigDir();\r\n if (!existsSync(configDir)) {\r\n mkdirSync(configDir, { recursive: true });\r\n }\r\n\r\n let existing: Partial<ClawRentConfig> = {};\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n existing = JSON.parse(readFileSync(configPath, 'utf-8')) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Overwrite corrupt file\r\n }\r\n }\r\n\r\n const merged = { ...existing, ...partial };\r\n writeFileSync(configPath, JSON.stringify(merged, null, 2), 'utf-8');\r\n}\r\n\r\nexport function clearConfig(): void {\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n unlinkSync(configPath);\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
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 sendVerification(email: string): Promise<{ message: string }> {\r\n return this.request('POST', '/api/auth/send-verification', { email }, false);\r\n }\r\n\r\n async registerUser(input: {\r\n email: string;\r\n password: string;\r\n name: string;\r\n verificationCode: string;\r\n }): Promise<{ user: { id: string; email: string; name: string; role: string }; token: string; apiKey: string }> {\r\n return this.request('POST', '/api/auth/register', input, false);\r\n }\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; roles?: 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?.roles) params.set('roles', query.roles);\r\n const qs = params.toString();\r\n return this.request('GET', `/api/agents/my${qs ? `?${qs}` : ''}`);\r\n }\r\n\r\n /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */\r\n async getMyAgent(): Promise<Record<string, unknown>> {\r\n return this.request('GET', '/api/agents/me/agent');\r\n }\r\n\r\n async applyProvider(agentId: string, data: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/apply-provider`, data);\r\n }\r\n\r\n /** Publish agent — simplified apply-provider with defaults, submits for admin review */\r\n async publishAgent(agentId: string, data?: Record<string, unknown>): Promise<unknown> {\r\n return this.request('POST', `/api/agents/${encodeURIComponent(agentId)}/publish`, data ?? {});\r\n }\r\n\r\n /** Activate agent — verify admin-approved + WebSocket connected, then go online */\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 // --- Docs (MCP interface) ---\r\n\r\n async getDocsTree(): Promise<unknown> {\r\n return this.request('GET', '/api/mcp/docs/tree', undefined, false);\r\n }\r\n\r\n async getDocByPath(path: string): Promise<unknown> {\r\n return this.request('GET', `/api/mcp/docs/by-path/${encodeURI(path)}`, undefined, false);\r\n }\r\n\r\n async searchDocs(query: string): Promise<unknown> {\r\n const params = new URLSearchParams({ q: query });\r\n return this.request('GET', `/api/mcp/docs/search?${params.toString()}`, undefined, false);\r\n }\r\n\r\n async getDoc(id: string): Promise<unknown> {\r\n return this.request('GET', `/api/mcp/docs/${encodeURIComponent(id)}`, undefined, false);\r\n }\r\n\r\n async createDoc(data: { type: string; title: string; parentId?: string; content?: string; slug?: string; icon?: string }): Promise<unknown> {\r\n return this.request('POST', '/api/mcp/docs', data);\r\n }\r\n\r\n async updateDoc(id: string, data: { title?: string; content?: string; changeSummary?: string }): Promise<unknown> {\r\n return this.request('PATCH', `/api/mcp/docs/${encodeURIComponent(id)}`, data);\r\n }\r\n\r\n async deleteDoc(id: string): Promise<unknown> {\r\n return this.request('DELETE', `/api/mcp/docs/${encodeURIComponent(id)}`);\r\n }\r\n\r\n async publishDoc(id: string): Promise<unknown> {\r\n return this.request('POST', `/api/mcp/docs/${encodeURIComponent(id)}/publish`);\r\n }\r\n\r\n async unpublishDoc(id: string): Promise<unknown> {\r\n return this.request('POST', `/api/mcp/docs/${encodeURIComponent(id)}/unpublish`);\r\n }\r\n\r\n // --- Private ---\r\n\r\n private async request<T = any>(method: string, path: string, body?: unknown, requireAuth: boolean = true): Promise<T> {\r\n const url = `${this.config.apiUrl}${path}`;\r\n const headers: Record<string, string> = {};\r\n\r\n if (body !== undefined) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n if (requireAuth) {\r\n if (this.config.token) {\r\n headers['Authorization'] = `Bearer ${this.config.token}`;\r\n } else if (this.config.apiKey) {\r\n headers['x-api-key'] = this.config.apiKey;\r\n } else {\r\n throw new Error('Not authenticated. Run `clawrent auth login` first.');\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.json().catch(() => ({ message: response.statusText })) as Record<string, unknown>;\r\n throw new Error(`API error ${response.status}: ${errBody['message'] ?? JSON.stringify(errBody)}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n }\r\n}\r\n","import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\r\nimport { join } from 'node:path';\r\nimport { homedir } from 'node:os';\r\n\r\nexport interface ClawRentConfig {\r\n apiUrl: string;\r\n wsUrl: string;\r\n token?: string;\r\n apiKey?: string;\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: ClawRentConfig = {\r\n apiUrl: 'https://clawrent.cloud',\r\n wsUrl: 'wss://clawrent.cloud',\r\n};\r\n\r\nexport function getConfigDir(): string {\r\n return join(homedir(), '.clawrent');\r\n}\r\n\r\nfunction getConfigFilePath(): string {\r\n return join(getConfigDir(), 'config.json');\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return getConfigFilePath();\r\n}\r\n\r\nexport function loadConfig(): ClawRentConfig {\r\n let fileConfig: Partial<ClawRentConfig> = {};\r\n\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n const raw = readFileSync(configPath, 'utf-8');\r\n fileConfig = JSON.parse(raw) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Ignore corrupt config file\r\n }\r\n }\r\n\r\n // Migration: remove stale localhost URLs saved by older CLI versions.\r\n // These override the new production defaults and break remote connections.\r\n if (fileConfig.apiUrl?.includes('localhost') || fileConfig.wsUrl?.includes('localhost')) {\r\n delete fileConfig.apiUrl;\r\n delete fileConfig.wsUrl;\r\n // Persist the cleanup so it only runs once\r\n try {\r\n const cleaned = { ...fileConfig };\r\n writeFileSync(configPath, JSON.stringify(cleaned, null, 2), 'utf-8');\r\n } catch {\r\n // Non-fatal\r\n }\r\n }\r\n\r\n // Merge: defaults < file < env vars\r\n const config: ClawRentConfig = {\r\n ...DEFAULT_CONFIG,\r\n ...fileConfig,\r\n };\r\n\r\n // Env vars always override\r\n const envApiUrl = process.env['CLAWRENT_API_URL'];\r\n const envWsUrl = process.env['CLAWRENT_WS_URL'];\r\n const envToken = process.env['CLAWRENT_TOKEN'];\r\n const envApiKey = process.env['CLAWRENT_API_KEY'];\r\n const envUserId = process.env['CLAWRENT_USER_ID'];\r\n\r\n if (envApiUrl) config.apiUrl = envApiUrl;\r\n if (envWsUrl) config.wsUrl = envWsUrl;\r\n if (envToken) config.token = envToken;\r\n if (envApiKey) config.apiKey = envApiKey;\r\n if (envUserId) config.userId = envUserId;\r\n\r\n return config;\r\n}\r\n\r\nexport function saveConfig(partial: Partial<ClawRentConfig>): void {\r\n const configDir = getConfigDir();\r\n if (!existsSync(configDir)) {\r\n mkdirSync(configDir, { recursive: true });\r\n }\r\n\r\n let existing: Partial<ClawRentConfig> = {};\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n try {\r\n existing = JSON.parse(readFileSync(configPath, 'utf-8')) as Partial<ClawRentConfig>;\r\n } catch {\r\n // Overwrite corrupt file\r\n }\r\n }\r\n\r\n const merged = { ...existing, ...partial };\r\n writeFileSync(configPath, JSON.stringify(merged, null, 2), 'utf-8');\r\n}\r\n\r\nexport function clearConfig(): void {\r\n const configPath = getConfigFilePath();\r\n if (existsSync(configPath)) {\r\n unlinkSync(configPath);\r\n }\r\n}\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\n\r\nexport interface SessionConnection {\r\n sessionId: string;\r\n sessionToken: string;\r\n ws: WebSocket;\r\n heartbeatTimer: ReturnType<typeof setInterval> | null;\r\n reconnectAttempts: number;\r\n}\r\n\r\n/**\r\n * SessionManager manages multiple concurrent WebSocket connections,\r\n * one per active session.\r\n */\r\nexport class SessionManager extends EventEmitter {\r\n private sessions = new Map<string, SessionConnection>();\r\n private wsUrl: string;\r\n private heartbeatInterval: number;\r\n private maxReconnectDelay: number;\r\n public agentId?: string;\r\n\r\n constructor(wsUrl: string, heartbeatInterval = 25_000, maxReconnectDelay = 30_000) {\r\n super();\r\n this.wsUrl = wsUrl;\r\n this.heartbeatInterval = heartbeatInterval;\r\n this.maxReconnectDelay = maxReconnectDelay;\r\n }\r\n\r\n /** Connect to a session via WebSocket as provider */\r\n connect(sessionId: string, sessionToken: string): void {\r\n if (this.sessions.has(sessionId)) {\r\n return; // Already connected\r\n }\r\n\r\n const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;\r\n const ws = new WebSocket(url);\r\n\r\n const conn: SessionConnection = {\r\n sessionId,\r\n sessionToken,\r\n ws,\r\n heartbeatTimer: null,\r\n reconnectAttempts: 0,\r\n };\r\n\r\n this.sessions.set(sessionId, conn);\r\n\r\n ws.on('open', () => {\r\n conn.reconnectAttempts = 0;\r\n conn.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, this.heartbeatInterval);\r\n\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const message = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n // Skip heartbeat acks\r\n if (message['type'] === 'system.heartbeat_ack') return;\r\n\r\n this.emit('session:message', sessionId, message);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code, reason) => {\r\n this.clearHeartbeat(conn);\r\n\r\n if (code !== 1000) {\r\n // Abnormal close — try reconnect\r\n const delay = Math.min(\r\n 1000 * Math.pow(2, conn.reconnectAttempts),\r\n this.maxReconnectDelay,\r\n );\r\n conn.reconnectAttempts++;\r\n\r\n this.emit('session:reconnecting', sessionId, delay);\r\n\r\n setTimeout(() => {\r\n this.sessions.delete(sessionId);\r\n this.connect(sessionId, sessionToken);\r\n }, delay);\r\n } else {\r\n this.sessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId, reason.toString());\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n\r\n /** Send a message to a specific session, auto-wrapping with protocol envelope */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn || conn.ws.readyState !== WebSocket.OPEN) {\r\n return false;\r\n }\r\n // Ensure full ClawRentMessage envelope\r\n const envelope = {\r\n id: message['id'] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\r\n sessionId: message['sessionId'] ?? sessionId,\r\n timestamp: message['timestamp'] ?? Date.now(),\r\n sender: message['sender'] ?? { role: 'provider', agentId: this.agentId ?? 'unknown' },\r\n type: message['type'] ?? 'result.success',\r\n payload: message['payload'] ?? {},\r\n };\r\n conn.ws.send(JSON.stringify(envelope));\r\n return true;\r\n }\r\n\r\n /** Disconnect a specific session */\r\n disconnect(sessionId: string): void {\r\n const conn = this.sessions.get(sessionId);\r\n if (!conn) return;\r\n\r\n this.clearHeartbeat(conn);\r\n if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {\r\n conn.ws.close(1000, 'Provider disconnecting');\r\n }\r\n this.sessions.delete(sessionId);\r\n }\r\n\r\n /** Disconnect all sessions */\r\n disconnectAll(): void {\r\n for (const sessionId of this.sessions.keys()) {\r\n this.disconnect(sessionId);\r\n }\r\n }\r\n\r\n /** Get active session count */\r\n get activeCount(): number {\r\n return this.sessions.size;\r\n }\r\n\r\n /** Check if a session is connected */\r\n isConnected(sessionId: string): boolean {\r\n const conn = this.sessions.get(sessionId);\r\n return conn?.ws.readyState === WebSocket.OPEN;\r\n }\r\n\r\n private clearHeartbeat(conn: SessionConnection): void {\r\n if (conn.heartbeatTimer) {\r\n clearInterval(conn.heartbeatTimer);\r\n conn.heartbeatTimer = null;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clawrent/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/lib.js",
|
|
6
6
|
"types": "./dist/lib.d.ts",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"commander": "^13.0.0",
|
|
24
24
|
"ws": "^8.18.0",
|
|
25
|
-
"@clawrent/
|
|
26
|
-
"@clawrent/
|
|
25
|
+
"@clawrent/protocol": "0.2.0",
|
|
26
|
+
"@clawrent/shared-types": "0.2.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^22.0.0",
|