@clawrent/cli 0.3.0 → 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/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
  }
@@ -174,6 +180,14 @@ var ApiClient = class {
174
180
  async applyProvider(agentId, data) {
175
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 */
188
+ async activateAgent(agentId) {
189
+ return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/activate`);
190
+ }
177
191
  async setOnlineStatus(agentId, onlineStatus) {
178
192
  return this.request("PATCH", `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });
179
193
  }
@@ -235,6 +249,35 @@ var ApiClient = class {
235
249
  async health() {
236
250
  return this.request("GET", "/api/health", void 0, false);
237
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
+ }
238
281
  // --- Private ---
239
282
  async request(method, path, body, requireAuth = true) {
240
283
  const url = `${this.config.apiUrl}${path}`;
@@ -278,28 +321,31 @@ function printSuccess(message) {
278
321
  }
279
322
 
280
323
  // src/commands/auth.ts
281
- function deriveWsUrl(apiUrl) {
282
- return apiUrl.replace(/^http/, "ws");
283
- }
284
324
  async function promptInput(prompt, hidden = false) {
285
- const rl = createInterface({ input: process.stdin, output: process.stderr });
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
+ }
286
335
  return new Promise((resolve) => {
287
336
  if (hidden) {
288
337
  process.stderr.write(prompt);
289
- const stdin = process.stdin;
290
338
  const wasRaw = stdin.isRaw;
291
- if (stdin.isTTY) stdin.setRawMode(true);
339
+ if (stdin.setRawMode) stdin.setRawMode(true);
292
340
  let input = "";
293
341
  const onData = (ch) => {
294
342
  const c = ch.toString("utf-8");
295
- if (c === "\n" || c === "\r") {
343
+ if (c === "\n" || c === "\r" || c === "") {
296
344
  stdin.removeListener("data", onData);
297
- if (stdin.isTTY && wasRaw !== void 0) stdin.setRawMode(wasRaw);
345
+ if (stdin.setRawMode && wasRaw !== void 0) stdin.setRawMode(wasRaw);
298
346
  process.stderr.write("\n");
299
- rl.close();
300
347
  resolve(input);
301
348
  } else if (c === "") {
302
- rl.close();
303
349
  process.exit(1);
304
350
  } else if (c === "\x7F" || c === "\b") {
305
351
  input = input.slice(0, -1);
@@ -309,6 +355,7 @@ async function promptInput(prompt, hidden = false) {
309
355
  };
310
356
  stdin.on("data", onData);
311
357
  } else {
358
+ const rl = createInterface({ input: stdin, output: process.stderr });
312
359
  rl.question(prompt, (answer) => {
313
360
  rl.close();
314
361
  resolve(answer);
@@ -318,18 +365,72 @@ async function promptInput(prompt, hidden = false) {
318
365
  }
319
366
  function registerAuthCommand(program2) {
320
367
  const auth = program2.command("auth").description("Authentication management");
321
- auth.command("login").description("Login to ClawRent platform").option("-e, --email <email>", "Email address").option("-p, --password <password>", "Password").option("--api-url <url>", "Platform API URL").action(async (opts) => {
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) => {
322
425
  try {
323
426
  const currentConfig = loadConfig();
324
- const apiUrl = opts.apiUrl ?? currentConfig.apiUrl;
325
- const wsUrl = deriveWsUrl(apiUrl);
326
427
  const email = opts.email ?? await promptInput("Email: ");
327
428
  const password = opts.password ?? await promptInput("Password: ", true);
328
429
  if (!email || !password) {
329
430
  printError("Email and password are required.");
330
431
  process.exit(1);
331
432
  }
332
- const client = new ApiClient({ ...currentConfig, apiUrl, wsUrl });
433
+ const client = new ApiClient(currentConfig);
333
434
  const result = await client.login(email, password);
334
435
  saveConfig({
335
436
  token: result.token,
@@ -337,8 +438,12 @@ function registerAuthCommand(program2) {
337
438
  email: result.user.email,
338
439
  name: result.user.name
339
440
  });
340
- printSuccess(`Logged in as ${result.user.name} (${result.user.email})`);
341
- printSuccess(`Config saved to ${getConfigPath()}`);
441
+ printJson({
442
+ success: true,
443
+ user: result.user,
444
+ token: result.token,
445
+ configSaved: getConfigPath()
446
+ });
342
447
  } catch (err) {
343
448
  printError(err instanceof Error ? err.message : String(err));
344
449
  process.exit(1);
@@ -347,7 +452,7 @@ function registerAuthCommand(program2) {
347
452
  auth.command("logout").description("Logout and clear saved credentials").action(() => {
348
453
  try {
349
454
  clearConfig();
350
- printSuccess("Logged out. Config cleared.");
455
+ printJson({ success: true, message: "Credentials cleared" });
351
456
  } catch (err) {
352
457
  printError(err instanceof Error ? err.message : String(err));
353
458
  process.exit(1);
@@ -424,7 +529,7 @@ function registerBalanceCommand(program2) {
424
529
  try {
425
530
  const client = new ApiClient(loadConfig());
426
531
  const result = await client.getBalance();
427
- printSuccess(`Balance: ${result.balance}`);
532
+ printJson(result);
428
533
  } catch (err) {
429
534
  printError(err instanceof Error ? err.message : String(err));
430
535
  process.exit(1);
@@ -438,7 +543,7 @@ function registerTopupCommand(program2) {
438
543
  try {
439
544
  const client = new ApiClient(loadConfig());
440
545
  const result = await client.topUp(amount);
441
- printSuccess(`New balance: ${result.balance}`);
546
+ printJson(result);
442
547
  } catch (err) {
443
548
  printError(err instanceof Error ? err.message : String(err));
444
549
  process.exit(1);
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; 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 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('--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"]}
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;
@@ -68,6 +86,10 @@ declare class ApiClient {
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 */
92
+ activateAgent(agentId: string): Promise<unknown>;
71
93
  setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown>;
72
94
  generateAgentToken(agentId: string): Promise<{
73
95
  agentId: string;
@@ -112,6 +134,26 @@ declare class ApiClient {
112
134
  addFavorite(agentId: string): Promise<unknown>;
113
135
  removeFavorite(agentId: string): Promise<unknown>;
114
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>;
115
157
  private request;
116
158
  }
117
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
  }
@@ -88,6 +94,14 @@ var ApiClient = class {
88
94
  async applyProvider(agentId, data) {
89
95
  return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/apply-provider`, data);
90
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 ?? {});
100
+ }
101
+ /** Activate agent — verify admin-approved + WebSocket connected, then go online */
102
+ async activateAgent(agentId) {
103
+ return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/activate`);
104
+ }
91
105
  async setOnlineStatus(agentId, onlineStatus) {
92
106
  return this.request("PATCH", `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });
93
107
  }
@@ -149,6 +163,35 @@ var ApiClient = class {
149
163
  async health() {
150
164
  return this.request("GET", "/api/health", void 0, false);
151
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
+ }
152
195
  // --- Private ---
153
196
  async request(method, path, body, requireAuth = true) {
154
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; 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 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":";AAEO,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EAER,YAAY,QAAwB;AAClC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,SAA6B;AAC/B,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA,EAIA,MAAM,iBAAiB,OAA6C;AAClE,WAAO,KAAK,QAAQ,QAAQ,+BAA+B,EAAE,MAAM,GAAG,KAAK;AAAA,EAC7E;AAAA,EAEA,MAAM,aAAa,OAK6F;AAC9G,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,OAAO,KAAK;AAAA,EAChE;AAAA,EAEA,MAAM,MAAM,OAAe,UAA+G;AACxI,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,EAAE,OAAO,SAAS,GAAG,KAAK;AAAA,EAC3E;AAAA,EAEA,MAAM,QAA0C;AAC9C,WAAO,KAAK,QAAQ,OAAO,cAAc;AAAA,EAC3C;AAAA;AAAA,EAIA,MAAM,OAAO,OAAiG;AAC5G,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,OAAO,OAAQ,QAAO,IAAI,UAAU,MAAM,MAAM;AACpD,QAAI,OAAO,SAAU,QAAO,IAAI,YAAY,MAAM,QAAQ;AAC1D,QAAI,OAAO,KAAM,QAAO,IAAI,QAAQ,OAAO,MAAM,IAAI,CAAC;AACtD,QAAI,OAAO,MAAO,QAAO,IAAI,SAAS,OAAO,MAAM,KAAK,CAAC;AACzD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,QAAQ,OAAO,0BAA0B,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EAC3E;AAAA,EAEA,MAAM,SAAS,MAAgC;AAC7C,WAAO,KAAK,QAAQ,OAAO,2BAA2B,mBAAmB,IAAI,CAAC,EAAE;AAAA,EAClF;AAAA;AAAA,EAIA,MAAM,KAAK,SAAuH;AAChI,WAAO,KAAK,QAAQ,QAAQ,iBAAiB;AAAA,MAC3C,SAAS,QAAQ;AAAA,MACjB,iBAAiB,QAAQ;AAAA,MACzB,oBAAoB,QAAQ,sBAAsB,CAAC;AAAA,IACrD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,OAA6F;AAC7G,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,IAAI;AAC9C,QAAI,OAAO,OAAQ,QAAO,IAAI,UAAU,MAAM,MAAM;AACpD,QAAI,OAAO,KAAM,QAAO,IAAI,QAAQ,OAAO,MAAM,IAAI,CAAC;AACtD,QAAI,OAAO,MAAO,QAAO,IAAI,SAAS,OAAO,MAAM,KAAK,CAAC;AACzD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,QAAQ,OAAO,gBAAgB,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EACjE;AAAA,EAEA,MAAM,WAAW,WAAqD;AACpE,WAAO,KAAK,QAAQ,OAAO,iBAAiB,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAC7E;AAAA,EAEA,MAAM,mBAAmB,WAAqC;AAC5D,WAAO,KAAK,QAAQ,OAAO,iBAAiB,mBAAmB,SAAS,CAAC,WAAW;AAAA,EACtF;AAAA,EAEA,MAAM,WAAW,WAAqC;AACpD,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,mBAAmB,SAAS,CAAC,MAAM;AAAA,EAClF;AAAA,EAEA,MAAM,eAAe,WAAqC;AACxD,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,mBAAmB,SAAS,CAAC,UAAU;AAAA,EACtF;AAAA;AAAA,EAIA,MAAM,aAA2C;AAC/C,WAAO,KAAK,QAAQ,OAAO,qBAAqB;AAAA,EAClD;AAAA,EAEA,MAAM,MAAM,QAA8C;AACxD,WAAO,KAAK,QAAQ,QAAQ,6BAA6B,EAAE,OAAO,CAAC;AAAA,EACrE;AAAA;AAAA,EAIA,MAAM,cAAc,MAAiD;AACnE,WAAO,KAAK,QAAQ,QAAQ,eAAe,IAAI;AAAA,EACjD;AAAA,EAEA,MAAM,YAAY,OAA6E;AAC7F,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,OAAO,KAAM,QAAO,IAAI,QAAQ,OAAO,MAAM,IAAI,CAAC;AACtD,QAAI,OAAO,MAAO,QAAO,IAAI,SAAS,OAAO,MAAM,KAAK,CAAC;AACzD,QAAI,OAAO,MAAO,QAAO,IAAI,SAAS,MAAM,KAAK;AACjD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,QAAQ,OAAO,iBAAiB,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,aAA+C;AACnD,WAAO,KAAK,QAAQ,OAAO,sBAAsB;AAAA,EACnD;AAAA,EAEA,MAAM,cAAc,SAAiB,MAAiD;AACpF,WAAO,KAAK,QAAQ,QAAQ,eAAe,mBAAmB,OAAO,CAAC,mBAAmB,IAAI;AAAA,EAC/F;AAAA;AAAA,EAGA,MAAM,aAAa,SAAiB,MAAkD;AACpF,WAAO,KAAK,QAAQ,QAAQ,eAAe,mBAAmB,OAAO,CAAC,YAAY,QAAQ,CAAC,CAAC;AAAA,EAC9F;AAAA;AAAA,EAGA,MAAM,cAAc,SAAmC;AACrD,WAAO,KAAK,QAAQ,QAAQ,eAAe,mBAAmB,OAAO,CAAC,WAAW;AAAA,EACnF;AAAA,EAEA,MAAM,gBAAgB,SAAiB,cAAwC;AAC7E,WAAO,KAAK,QAAQ,SAAS,eAAe,mBAAmB,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC;AAAA,EACpG;AAAA,EAEA,MAAM,mBAAmB,SAAkG;AACzH,WAAO,KAAK,QAAQ,QAAQ,eAAe,mBAAmB,OAAO,CAAC,QAAQ;AAAA,EAChF;AAAA,EAEA,MAAM,iBAAiB,SAA+C;AACpE,WAAO,KAAK,QAAQ,UAAU,eAAe,mBAAmB,OAAO,CAAC,QAAQ;AAAA,EAClF;AAAA;AAAA,EAIA,MAAM,YAAY,MAIG;AACnB,WAAO,KAAK,QAAQ,QAAQ,eAAe,IAAI;AAAA,EACjD;AAAA,EAEA,MAAM,UAAU,OAA8E;AAC5F,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,OAAO,OAAQ,QAAO,IAAI,UAAU,MAAM,MAAM;AACpD,QAAI,OAAO,KAAM,QAAO,IAAI,QAAQ,OAAO,MAAM,IAAI,CAAC;AACtD,QAAI,OAAO,MAAO,QAAO,IAAI,SAAS,OAAO,MAAM,KAAK,CAAC;AACzD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,QAAQ,OAAO,cAAc,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EAC/D;AAAA,EAEA,MAAM,SAAS,SAAmC;AAChD,WAAO,KAAK,QAAQ,OAAO,eAAe,mBAAmB,OAAO,CAAC,EAAE;AAAA,EACzE;AAAA,EAEA,MAAM,YAAY,SAAmC;AACnD,WAAO,KAAK,QAAQ,QAAQ,eAAe,mBAAmB,OAAO,CAAC,SAAS;AAAA,EACjF;AAAA;AAAA,EAIA,MAAM,UAA4B;AAChC,WAAO,KAAK,QAAQ,OAAO,WAAW;AAAA,EACxC;AAAA,EAEA,MAAM,UAAU,MAA8E;AAC5F,WAAO,KAAK,QAAQ,QAAQ,aAAa,IAAI;AAAA,EAC/C;AAAA,EAEA,MAAM,eAAe,QAAgB,MAAqD;AACxF,WAAO,KAAK,QAAQ,SAAS,aAAa,mBAAmB,MAAM,CAAC,IAAI,IAAI;AAAA,EAC9E;AAAA,EAEA,MAAM,eAAe,QAAkC;AACrD,WAAO,KAAK,QAAQ,UAAU,aAAa,mBAAmB,MAAM,CAAC,EAAE;AAAA,EACzE;AAAA,EAEA,MAAM,YAA8B;AAClC,WAAO,KAAK,QAAQ,UAAU,WAAW;AAAA,EAC3C;AAAA;AAAA,EAIA,MAAM,cAAc,OAA6D;AAC/E,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,OAAO,KAAM,QAAO,IAAI,QAAQ,OAAO,MAAM,IAAI,CAAC;AACtD,QAAI,OAAO,MAAO,QAAO,IAAI,SAAS,OAAO,MAAM,KAAK,CAAC;AACzD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,QAAQ,OAAO,iBAAiB,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EAClE;AAAA,EAEA,MAAM,YAAY,SAAmC;AACnD,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,mBAAmB,OAAO,CAAC,EAAE;AAAA,EAC7E;AAAA,EAEA,MAAM,eAAe,SAAmC;AACtD,WAAO,KAAK,QAAQ,UAAU,kBAAkB,mBAAmB,OAAO,CAAC,EAAE;AAAA,EAC/E;AAAA;AAAA,EAIA,MAAM,SAA2B;AAC/B,WAAO,KAAK,QAAQ,OAAO,eAAe,QAAW,KAAK;AAAA,EAC5D;AAAA;AAAA,EAIA,MAAM,cAAgC;AACpC,WAAO,KAAK,QAAQ,OAAO,sBAAsB,QAAW,KAAK;AAAA,EACnE;AAAA,EAEA,MAAM,aAAa,MAAgC;AACjD,WAAO,KAAK,QAAQ,OAAO,yBAAyB,UAAU,IAAI,CAAC,IAAI,QAAW,KAAK;AAAA,EACzF;AAAA,EAEA,MAAM,WAAW,OAAiC;AAChD,UAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAC/C,WAAO,KAAK,QAAQ,OAAO,wBAAwB,OAAO,SAAS,CAAC,IAAI,QAAW,KAAK;AAAA,EAC1F;AAAA,EAEA,MAAM,OAAO,IAA8B;AACzC,WAAO,KAAK,QAAQ,OAAO,iBAAiB,mBAAmB,EAAE,CAAC,IAAI,QAAW,KAAK;AAAA,EACxF;AAAA,EAEA,MAAM,UAAU,MAA4H;AAC1I,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,IAAI;AAAA,EACnD;AAAA,EAEA,MAAM,UAAU,IAAY,MAAsF;AAChH,WAAO,KAAK,QAAQ,SAAS,iBAAiB,mBAAmB,EAAE,CAAC,IAAI,IAAI;AAAA,EAC9E;AAAA,EAEA,MAAM,UAAU,IAA8B;AAC5C,WAAO,KAAK,QAAQ,UAAU,iBAAiB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACzE;AAAA,EAEA,MAAM,WAAW,IAA8B;AAC7C,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,mBAAmB,EAAE,CAAC,UAAU;AAAA,EAC/E;AAAA,EAEA,MAAM,aAAa,IAA8B;AAC/C,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,mBAAmB,EAAE,CAAC,YAAY;AAAA,EACjF;AAAA;AAAA,EAIA,MAAc,QAAiB,QAAgB,MAAc,MAAgB,cAAuB,MAAkB;AACpH,UAAM,MAAM,GAAG,KAAK,OAAO,MAAM,GAAG,IAAI;AACxC,UAAM,UAAkC,CAAC;AAEzC,QAAI,SAAS,QAAW;AACtB,cAAQ,cAAc,IAAI;AAAA,IAC5B;AAEA,QAAI,aAAa;AACf,UAAI,KAAK,OAAO,OAAO;AACrB,gBAAQ,eAAe,IAAI,UAAU,KAAK,OAAO,KAAK;AAAA,MACxD,WAAW,KAAK,OAAO,QAAQ;AAC7B,gBAAQ,WAAW,IAAI,KAAK,OAAO;AAAA,MACrC,OAAO;AACL,cAAM,IAAI,MAAM,qDAAqD;AAAA,MACvE;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC;AAAA,MACA;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,UAAU,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,EAAE,SAAS,SAAS,WAAW,EAAE;AACpF,YAAM,IAAI,MAAM,aAAa,SAAS,MAAM,KAAK,QAAQ,SAAS,KAAK,KAAK,UAAU,OAAO,CAAC,EAAE;AAAA,IAClG;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AACF;;;ACzSA,SAAS,cAAc,eAAe,WAAW,YAAY,kBAAkB;AAC/E,SAAS,YAAY;AACrB,SAAS,eAAe;AAYxB,IAAM,iBAAiC;AAAA,EACrC,QAAQ;AAAA,EACR,OAAO;AACT;AAEO,SAAS,eAAuB;AACrC,SAAO,KAAK,QAAQ,GAAG,WAAW;AACpC;AAEA,SAAS,oBAA4B;AACnC,SAAO,KAAK,aAAa,GAAG,aAAa;AAC3C;AAEO,SAAS,gBAAwB;AACtC,SAAO,kBAAkB;AAC3B;AAEO,SAAS,aAA6B;AAC3C,MAAI,aAAsC,CAAC;AAE3C,QAAM,aAAa,kBAAkB;AACrC,MAAI,WAAW,UAAU,GAAG;AAC1B,QAAI;AACF,YAAM,MAAM,aAAa,YAAY,OAAO;AAC5C,mBAAa,KAAK,MAAM,GAAG;AAAA,IAC7B,QAAQ;AAAA,IAER;AAAA,EACF;AAIA,MAAI,WAAW,QAAQ,SAAS,WAAW,KAAK,WAAW,OAAO,SAAS,WAAW,GAAG;AACvF,WAAO,WAAW;AAClB,WAAO,WAAW;AAElB,QAAI;AACF,YAAM,UAAU,EAAE,GAAG,WAAW;AAChC,oBAAc,YAAY,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,OAAO;AAAA,IACrE,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,QAAM,SAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAGA,QAAM,YAAY,QAAQ,IAAI,kBAAkB;AAChD,QAAM,WAAW,QAAQ,IAAI,iBAAiB;AAC9C,QAAM,WAAW,QAAQ,IAAI,gBAAgB;AAC7C,QAAM,YAAY,QAAQ,IAAI,kBAAkB;AAChD,QAAM,YAAY,QAAQ,IAAI,kBAAkB;AAEhD,MAAI,UAAW,QAAO,SAAS;AAC/B,MAAI,SAAU,QAAO,QAAQ;AAC7B,MAAI,SAAU,QAAO,QAAQ;AAC7B,MAAI,UAAW,QAAO,SAAS;AAC/B,MAAI,UAAW,QAAO,SAAS;AAE/B,SAAO;AACT;AAEO,SAAS,WAAW,SAAwC;AACjE,QAAM,YAAY,aAAa;AAC/B,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,cAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAC1C;AAEA,MAAI,WAAoC,CAAC;AACzC,QAAM,aAAa,kBAAkB;AACrC,MAAI,WAAW,UAAU,GAAG;AAC1B,QAAI;AACF,iBAAW,KAAK,MAAM,aAAa,YAAY,OAAO,CAAC;AAAA,IACzD,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,SAAS,EAAE,GAAG,UAAU,GAAG,QAAQ;AACzC,gBAAc,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,OAAO;AACpE;AAEO,SAAS,cAAoB;AAClC,QAAM,aAAa,kBAAkB;AACrC,MAAI,WAAW,UAAU,GAAG;AAC1B,eAAW,UAAU;AAAA,EACvB;AACF;;;ACzGA,SAAS,oBAAoB;AAC7B,OAAO,eAAe;AAcf,IAAM,iBAAN,cAA6B,aAAa;AAAA,EACvC,WAAW,oBAAI,IAA+B;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACD;AAAA,EAEP,YAAY,OAAe,oBAAoB,MAAQ,oBAAoB,KAAQ;AACjF,UAAM;AACN,SAAK,QAAQ;AACb,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA,EAGA,QAAQ,WAAmB,cAA4B;AACrD,QAAI,KAAK,SAAS,IAAI,SAAS,GAAG;AAChC;AAAA,IACF;AAEA,UAAM,MAAM,GAAG,KAAK,KAAK,yBAAyB,SAAS,UAAU,YAAY;AACjF,UAAM,KAAK,IAAI,UAAU,GAAG;AAE5B,UAAM,OAA0B;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,IACrB;AAEA,SAAK,SAAS,IAAI,WAAW,IAAI;AAEjC,OAAG,GAAG,QAAQ,MAAM;AAClB,WAAK,oBAAoB;AACzB,WAAK,iBAAiB,YAAY,MAAM;AACtC,YAAI,GAAG,eAAe,UAAU,MAAM;AACpC,aAAG,KAAK,KAAK,UAAU,EAAE,MAAM,oBAAoB,SAAS,CAAC,EAAE,CAAC,CAAC;AAAA,QACnE;AAAA,MACF,GAAG,KAAK,iBAAiB;AAEzB,WAAK,KAAK,qBAAqB,SAAS;AAAA,IAC1C,CAAC;AAED,OAAG,GAAG,WAAW,CAAC,QAAQ;AACxB,UAAI;AACF,cAAM,UAAU,KAAK,MAAM,IAAI,SAAS,CAAC;AAEzC,YAAI,QAAQ,MAAM,MAAM,uBAAwB;AAEhD,aAAK,KAAK,mBAAmB,WAAW,OAAO;AAAA,MACjD,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAED,OAAG,GAAG,SAAS,CAAC,MAAM,WAAW;AAC/B,WAAK,eAAe,IAAI;AAExB,UAAI,SAAS,KAAM;AAEjB,cAAM,QAAQ,KAAK;AAAA,UACjB,MAAO,KAAK,IAAI,GAAG,KAAK,iBAAiB;AAAA,UACzC,KAAK;AAAA,QACP;AACA,aAAK;AAEL,aAAK,KAAK,wBAAwB,WAAW,KAAK;AAElD,mBAAW,MAAM;AACf,eAAK,SAAS,OAAO,SAAS;AAC9B,eAAK,QAAQ,WAAW,YAAY;AAAA,QACtC,GAAG,KAAK;AAAA,MACV,OAAO;AACL,aAAK,SAAS,OAAO,SAAS;AAC9B,aAAK,KAAK,wBAAwB,WAAW,OAAO,SAAS,CAAC;AAAA,MAChE;AAAA,IACF,CAAC;AAED,OAAG,GAAG,SAAS,CAAC,QAAQ;AACtB,WAAK,KAAK,iBAAiB,WAAW,GAAG;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,KAAK,WAAmB,SAA2C;AACjE,UAAM,OAAO,KAAK,SAAS,IAAI,SAAS;AACxC,QAAI,CAAC,QAAQ,KAAK,GAAG,eAAe,UAAU,MAAM;AAClD,aAAO;AAAA,IACT;AAEA,UAAM,WAAW;AAAA,MACf,IAAI,QAAQ,IAAI,KAAK,OAAO,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,MAC7F,WAAW,QAAQ,WAAW,KAAK;AAAA,MACnC,WAAW,QAAQ,WAAW,KAAK,KAAK,IAAI;AAAA,MAC5C,QAAQ,QAAQ,QAAQ,KAAK,EAAE,MAAM,YAAY,SAAS,KAAK,WAAW,UAAU;AAAA,MACpF,MAAM,QAAQ,MAAM,KAAK;AAAA,MACzB,SAAS,QAAQ,SAAS,KAAK,CAAC;AAAA,IAClC;AACA,SAAK,GAAG,KAAK,KAAK,UAAU,QAAQ,CAAC;AACrC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,WAAyB;AAClC,UAAM,OAAO,KAAK,SAAS,IAAI,SAAS;AACxC,QAAI,CAAC,KAAM;AAEX,SAAK,eAAe,IAAI;AACxB,QAAI,KAAK,GAAG,eAAe,UAAU,QAAQ,KAAK,GAAG,eAAe,UAAU,YAAY;AACxF,WAAK,GAAG,MAAM,KAAM,wBAAwB;AAAA,IAC9C;AACA,SAAK,SAAS,OAAO,SAAS;AAAA,EAChC;AAAA;AAAA,EAGA,gBAAsB;AACpB,eAAW,aAAa,KAAK,SAAS,KAAK,GAAG;AAC5C,WAAK,WAAW,SAAS;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,cAAsB;AACxB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA,EAGA,YAAY,WAA4B;AACtC,UAAM,OAAO,KAAK,SAAS,IAAI,SAAS;AACxC,WAAO,MAAM,GAAG,eAAe,UAAU;AAAA,EAC3C;AAAA,EAEQ,eAAe,MAA+B;AACpD,QAAI,KAAK,gBAAgB;AACvB,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawrent/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "main": "./dist/lib.js",
6
6
  "types": "./dist/lib.d.ts",