@agent-commons/cli 0.2.3 → 0.3.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.
Files changed (2) hide show
  1. package/dist/bin.js +564 -48
  2. package/package.json +2 -2
package/dist/bin.js CHANGED
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/bin.ts
27
- var import_commander16 = require("commander");
27
+ var import_commander18 = require("commander");
28
28
  var import_path5 = require("path");
29
29
  var import_os4 = require("os");
30
30
  var import_child_process3 = require("child_process");
@@ -160,7 +160,7 @@ var sym = {
160
160
  bullet: import_chalk.default.dim("\u2022"),
161
161
  dot: import_chalk.default.dim("\xB7")
162
162
  };
163
- function banner(version = "0.2.3") {
163
+ function banner(version = "0.3.0") {
164
164
  const line = import_chalk.default.cyan(" \u2500".padEnd(2) + "\u2500".repeat(44));
165
165
  console.log("");
166
166
  console.log(line);
@@ -577,10 +577,11 @@ function agentsCommand() {
577
577
  agents.map((a) => ({
578
578
  ID: a.agentId.slice(0, 8) + "\u2026",
579
579
  Name: a.name,
580
+ Runtime: a.runtimeType ?? "native",
580
581
  Model: `${a.modelProvider}/${a.modelId}`,
581
582
  Created: relativeTime(a.createdAt)
582
583
  })),
583
- ["ID", "Name", "Model", "Created"]
584
+ ["ID", "Name", "Runtime", "Model", "Created"]
584
585
  );
585
586
  } catch (err) {
586
587
  spinner.stop();
@@ -600,8 +601,15 @@ function agentsCommand() {
600
601
  detail([
601
602
  ["Agent ID", c.id(agent.agentId)],
602
603
  ["Provider", `${agent.modelProvider} / ${agent.modelId}`],
604
+ ["Runtime", agent.runtimeType ?? "native"],
605
+ ["Runtime status", agent.runtimeStatus ?? "ready"],
603
606
  ["Instructions", agent.instructions?.slice(0, 80) ?? c.dim("(none)")],
604
- ["Tools", [...agent.commonTools ?? [], ...agent.externalTools ?? []].join(", ") || c.dim("(none)")],
607
+ [
608
+ "Tools",
609
+ [...agent.commonTools ?? [], ...agent.externalTools ?? []].join(
610
+ ", "
611
+ ) || c.dim("(none)")
612
+ ],
605
613
  ["Created", relativeTime(agent.createdAt)]
606
614
  ]);
607
615
  } catch (err) {
@@ -610,7 +618,18 @@ function agentsCommand() {
610
618
  process.exit(1);
611
619
  }
612
620
  });
613
- cmd.command("create").description("Create a new agent").requiredOption("--name <name>", "Agent name").option("--instructions <text>", "System instructions").option("--provider <provider>", "Model provider (openai|anthropic|google|groq|openrouter|xai|ollama|custom)", "openai").option("--model <id>", "Model ID", "gpt-5.4-mini").option("--model-api-key <key>", "Provider API key (BYOK)").option("--model-base-url <url>", "Base URL for custom or local OpenAI-compatible providers").option("--json", "Output as JSON").action(async (opts) => {
621
+ cmd.command("create").description("Create a new agent").requiredOption("--name <name>", "Agent name").option("--instructions <text>", "System instructions").option(
622
+ "--provider <provider>",
623
+ "Model provider (openai|anthropic|google|groq|openrouter|xai|ollama|custom)",
624
+ "openai"
625
+ ).option("--model <id>", "Model ID", "gpt-5.4-mini").option("--model-api-key <key>", "Provider API key (BYOK)").option(
626
+ "--model-base-url <url>",
627
+ "Base URL for custom or local OpenAI-compatible providers"
628
+ ).option(
629
+ "--runtime <runtime>",
630
+ "Agent runtime (native|openclaw|hermes|custom)",
631
+ "native"
632
+ ).option("--json", "Output as JSON").action(async (opts) => {
614
633
  const cfg = loadConfig();
615
634
  if (!cfg.initiator) {
616
635
  console.error(c.error("No initiator set. Run `agc login` first."));
@@ -618,6 +637,9 @@ function agentsCommand() {
618
637
  }
619
638
  const spinner = spin("Creating agent\u2026");
620
639
  try {
640
+ if (!["native", "openclaw", "hermes", "custom"].includes(opts.runtime)) {
641
+ throw new Error(`Unsupported runtime "${opts.runtime}"`);
642
+ }
621
643
  const client = makeClient();
622
644
  const res = await client.agents.create({
623
645
  name: opts.name,
@@ -626,7 +648,8 @@ function agentsCommand() {
626
648
  modelProvider: opts.provider,
627
649
  modelId: opts.model,
628
650
  modelApiKey: opts.modelApiKey,
629
- modelBaseUrl: opts.modelBaseUrl
651
+ modelBaseUrl: opts.modelBaseUrl,
652
+ runtimeType: opts.runtime
630
653
  });
631
654
  const agent = res?.data ?? res;
632
655
  spinner.stop();
@@ -636,15 +659,57 @@ ${sym.ok} Agent created`);
636
659
  detail([
637
660
  ["Agent ID", c.id(agent.agentId)],
638
661
  ["Name", agent.name],
639
- ["Model", `${agent.modelProvider}/${agent.modelId}`]
662
+ ["Model", `${agent.modelProvider}/${agent.modelId}`],
663
+ ["Runtime", agent.runtimeType ?? opts.runtime]
664
+ ]);
665
+ console.log(
666
+ c.dim("\n Tip: agc config set defaultAgentId " + agent.agentId)
667
+ );
668
+ } catch (err) {
669
+ spinner.stop();
670
+ printError(err);
671
+ process.exit(1);
672
+ }
673
+ });
674
+ const runtime = cmd.command("runtime").description("Manage an agent runtime");
675
+ runtime.command("status <agentId>").description("Show managed runtime status and capabilities").option("--json", "Output as JSON").action(async (agentId, opts) => {
676
+ const spinner = spin("Fetching runtime status\u2026");
677
+ try {
678
+ const result = await makeClient().agents.getRuntime(agentId);
679
+ spinner.stop();
680
+ if (opts.json) return jsonOut(result.data);
681
+ detail([
682
+ ["Runtime", result.data.runtimeType],
683
+ ["Status", result.data.status],
684
+ ["Managed", result.data.managed ? "yes" : "no"],
685
+ ["Computer", result.data.computer?.computerId ?? c.dim("(none)")]
640
686
  ]);
641
- console.log(c.dim("\n Tip: agc config set defaultAgentId " + agent.agentId));
642
687
  } catch (err) {
643
688
  spinner.stop();
644
689
  printError(err);
645
690
  process.exit(1);
646
691
  }
647
692
  });
693
+ for (const action of ["deploy", "restart", "sleep"]) {
694
+ runtime.command(`${action} <agentId>`).description(
695
+ `${action[0].toUpperCase()}${action.slice(1)} the managed agent runtime`
696
+ ).action(async (agentId) => {
697
+ const spinner = spin(
698
+ `${action[0].toUpperCase()}${action.slice(1)}ing runtime\u2026`
699
+ );
700
+ try {
701
+ const client = makeClient();
702
+ const result = action === "deploy" ? await client.agents.deployRuntime(agentId) : action === "restart" ? await client.agents.restartRuntime(agentId) : await client.agents.sleepRuntime(agentId);
703
+ spinner.stop();
704
+ console.log(`
705
+ ${sym.ok} Runtime ${result.data.status}`);
706
+ } catch (err) {
707
+ spinner.stop();
708
+ printError(err);
709
+ process.exit(1);
710
+ }
711
+ });
712
+ }
648
713
  const autonomy = cmd.command("autonomy").description("Manage agent heartbeat");
649
714
  autonomy.command("status").description("Show autonomy status for an agent").requiredOption("--agent <agentId>", "Agent ID").option("--json", "Output as JSON").action(async (opts) => {
650
715
  const client = makeClient();
@@ -660,8 +725,14 @@ ${c.bold("Heartbeat Status")}`);
660
725
  ["Enabled", s.enabled ? c.bold("yes") : "no"],
661
726
  ["Interval", s.intervalSec ? `${s.intervalSec}s` : "n/a"],
662
727
  ["Armed", s.isArmed ? c.bold("yes") : "no"],
663
- ["Last beat", s.lastBeatAt ? new Date(s.lastBeatAt).toLocaleString() : "never"],
664
- ["Next beat", s.nextBeatAt ? new Date(s.nextBeatAt).toLocaleString() : "n/a"]
728
+ [
729
+ "Last beat",
730
+ s.lastBeatAt ? new Date(s.lastBeatAt).toLocaleString() : "never"
731
+ ],
732
+ [
733
+ "Next beat",
734
+ s.nextBeatAt ? new Date(s.nextBeatAt).toLocaleString() : "n/a"
735
+ ]
665
736
  ]);
666
737
  } catch (err) {
667
738
  spinner.stop();
@@ -669,7 +740,11 @@ ${c.bold("Heartbeat Status")}`);
669
740
  process.exit(1);
670
741
  }
671
742
  });
672
- autonomy.command("enable").description("Enable heartbeat for an agent").requiredOption("--agent <agentId>", "Agent ID").option("--interval <seconds>", "Heartbeat interval in seconds (min 30)", "300").action(async (opts) => {
743
+ autonomy.command("enable").description("Enable heartbeat for an agent").requiredOption("--agent <agentId>", "Agent ID").option(
744
+ "--interval <seconds>",
745
+ "Heartbeat interval in seconds (min 30)",
746
+ "300"
747
+ ).action(async (opts) => {
673
748
  const client = makeClient();
674
749
  const spinner = spin("Enabling autonomy\u2026");
675
750
  try {
@@ -678,8 +753,10 @@ ${c.bold("Heartbeat Status")}`);
678
753
  intervalSec: parseInt(opts.interval, 10)
679
754
  });
680
755
  spinner.stop();
681
- console.log(`
682
- ${sym.ok} Autonomy enabled for agent ${c.id(opts.agent)}`);
756
+ console.log(
757
+ `
758
+ ${sym.ok} Autonomy enabled for agent ${c.id(opts.agent)}`
759
+ );
683
760
  console.log(c.dim(` Heartbeat every ${opts.interval}s`));
684
761
  } catch (err) {
685
762
  spinner.stop();
@@ -693,8 +770,10 @@ ${sym.ok} Autonomy enabled for agent ${c.id(opts.agent)}`);
693
770
  try {
694
771
  await client.agents.setAutonomy(opts.agent, { enabled: false });
695
772
  spinner.stop();
696
- console.log(`
697
- ${sym.ok} Autonomy disabled for agent ${c.id(opts.agent)}`);
773
+ console.log(
774
+ `
775
+ ${sym.ok} Autonomy disabled for agent ${c.id(opts.agent)}`
776
+ );
698
777
  } catch (err) {
699
778
  spinner.stop();
700
779
  printError(err);
@@ -707,8 +786,10 @@ ${sym.ok} Autonomy disabled for agent ${c.id(opts.agent)}`);
707
786
  try {
708
787
  await client.agents.triggerHeartbeat(opts.agent);
709
788
  spinner.stop();
710
- console.log(`
711
- ${sym.ok} Heartbeat triggered for agent ${c.id(opts.agent)}`);
789
+ console.log(
790
+ `
791
+ ${sym.ok} Heartbeat triggered for agent ${c.id(opts.agent)}`
792
+ );
712
793
  } catch (err) {
713
794
  spinner.stop();
714
795
  printError(err);
@@ -954,12 +1035,136 @@ ${sym.ok} ${c.label(toolName)}`);
954
1035
  return cmd;
955
1036
  }
956
1037
 
957
- // src/commands/workflow.ts
1038
+ // src/commands/connections.ts
958
1039
  var import_commander5 = require("commander");
1040
+ function connectionsCommand() {
1041
+ const cmd = new import_commander5.Command("connections").description(
1042
+ "Manage OAuth account connections (Google Workspace, GitHub, Slack, \u2026) that agents act with"
1043
+ );
1044
+ cmd.command("list", { isDefault: true }).description("List your connected accounts").option("--json", "Output as JSON").action(async (opts) => {
1045
+ const cfg = loadConfig();
1046
+ const spinner = spin("Fetching connections\u2026");
1047
+ try {
1048
+ const client = makeClient();
1049
+ const res = await client.oauth.listConnections(
1050
+ cfg.initiator ? { ownerId: cfg.initiator, ownerType: "user" } : void 0
1051
+ );
1052
+ const connections = res?.connections ?? [];
1053
+ spinner.stop();
1054
+ if (opts.json) return jsonOut(connections);
1055
+ section(`Connections (${connections.length})`);
1056
+ if (connections.length === 0) {
1057
+ console.log(c.dim(" No connected accounts. Run `agc connections connect <provider>`."));
1058
+ return;
1059
+ }
1060
+ table(
1061
+ connections.map((conn) => ({
1062
+ ID: (conn.connectionId ?? "").slice(0, 8) + "\u2026",
1063
+ Provider: conn.providerDisplayName || conn.providerKey || "",
1064
+ Account: conn.providerUserEmail || conn.providerUserName || "",
1065
+ Status: conn.status ?? "",
1066
+ Scopes: String((conn.scopes ?? []).length),
1067
+ Used: conn.lastUsedAt ? relativeTime(conn.lastUsedAt) : c.dim("never")
1068
+ })),
1069
+ ["ID", "Provider", "Account", "Status", "Scopes", "Used"]
1070
+ );
1071
+ } catch (err) {
1072
+ spinner.stop();
1073
+ printError(err);
1074
+ process.exit(1);
1075
+ }
1076
+ });
1077
+ cmd.command("providers").description("List OAuth providers available to connect").option("--json", "Output as JSON").action(async (opts) => {
1078
+ const spinner = spin("Fetching providers\u2026");
1079
+ try {
1080
+ const client = makeClient();
1081
+ const res = await client.oauth.listProviders();
1082
+ const providers = res?.providers ?? [];
1083
+ spinner.stop();
1084
+ if (opts.json) return jsonOut(providers);
1085
+ section(`Providers (${providers.length})`);
1086
+ table(
1087
+ providers.map((p) => ({
1088
+ Key: p.providerKey ?? "",
1089
+ Name: p.displayName ?? "",
1090
+ Active: p.isActive ? "yes" : "no"
1091
+ })),
1092
+ ["Key", "Name", "Active"]
1093
+ );
1094
+ } catch (err) {
1095
+ spinner.stop();
1096
+ printError(err);
1097
+ process.exit(1);
1098
+ }
1099
+ });
1100
+ cmd.command("connect <providerKey>").description("Connect an account: prints an authorization URL to open in your browser").option("--scopes <scopes>", "Space-separated OAuth scopes to request").option("--json", "Output as JSON").action(async (providerKey, opts) => {
1101
+ const cfg = loadConfig();
1102
+ if (!cfg.initiator) {
1103
+ console.error(c.error("No initiator set. Run `agc login` first."));
1104
+ process.exit(1);
1105
+ }
1106
+ const spinner = spin("Starting OAuth flow\u2026");
1107
+ try {
1108
+ const client = makeClient();
1109
+ const res = await client.oauth.connect({
1110
+ providerKey,
1111
+ ...opts.scopes ? { scopes: String(opts.scopes).split(/\s+/).filter(Boolean) } : {}
1112
+ });
1113
+ spinner.stop();
1114
+ if (opts.json) return jsonOut(res);
1115
+ console.log(`
1116
+ ${sym.ok} Open this URL in your browser to authorize:`);
1117
+ console.log(`
1118
+ ${c.id(res.authorizationUrl)}
1119
+ `);
1120
+ console.log(c.dim(" After approving, the connection appears in `agc connections list`."));
1121
+ } catch (err) {
1122
+ spinner.stop();
1123
+ printError(err);
1124
+ process.exit(1);
1125
+ }
1126
+ });
1127
+ cmd.command("test <connectionId>").description("Check that a connection is active and its token is valid").option("--json", "Output as JSON").action(async (connectionId, opts) => {
1128
+ const spinner = spin("Testing connection\u2026");
1129
+ try {
1130
+ const client = makeClient();
1131
+ const res = await client.oauth.test(connectionId);
1132
+ spinner.stop();
1133
+ if (opts.json) return jsonOut(res);
1134
+ detail([
1135
+ ["Status", res.status],
1136
+ ["Token valid", res.accessTokenValid ? "yes" : "no"],
1137
+ ["Account", res.providerUserEmail ?? c.dim("(unknown)")],
1138
+ ["Last error", res.error ?? c.dim("(none)")]
1139
+ ]);
1140
+ } catch (err) {
1141
+ spinner.stop();
1142
+ printError(err);
1143
+ process.exit(1);
1144
+ }
1145
+ });
1146
+ cmd.command("revoke <connectionId>").description("Revoke a connection and delete its stored tokens").action(async (connectionId) => {
1147
+ const spinner = spin("Revoking connection\u2026");
1148
+ try {
1149
+ const client = makeClient();
1150
+ await client.oauth.revoke(connectionId);
1151
+ spinner.stop();
1152
+ console.log(`${sym.ok} Connection revoked.`);
1153
+ } catch (err) {
1154
+ spinner.stop();
1155
+ printError(err);
1156
+ process.exit(1);
1157
+ }
1158
+ });
1159
+ return cmd;
1160
+ }
1161
+
1162
+ // src/commands/workflow.ts
1163
+ var import_commander6 = require("commander");
959
1164
  var import_fs4 = require("fs");
960
1165
  var import_sdk2 = require("@agent-commons/sdk");
961
1166
  function workflowCommand() {
962
- const cmd = new import_commander5.Command("workflow").description("Run and monitor workflows").alias("wf");
1167
+ const cmd = new import_commander6.Command("workflow").description("Run and monitor workflows").alias("wf");
963
1168
  async function createTemplateWorkflow(params) {
964
1169
  const client = makeClient();
965
1170
  const template = (0, import_sdk2.buildWorkflowTemplate)(params.templateName, params.ctx);
@@ -1357,9 +1562,9 @@ ${c.warn("\u23F8 Awaiting approval")} at node ${c.id(e.pausedAtNode ?? "")}`);
1357
1562
  }
1358
1563
 
1359
1564
  // src/commands/task.ts
1360
- var import_commander6 = require("commander");
1565
+ var import_commander7 = require("commander");
1361
1566
  function taskCommand() {
1362
- const cmd = new import_commander6.Command("task").description("Manage and execute tasks").alias("t");
1567
+ const cmd = new import_commander7.Command("task").description("Manage and execute tasks").alias("t");
1363
1568
  cmd.command("list").description("List tasks").option("--agent <agentId>", "Filter by agent ID").option("--session <sessionId>", "Filter by session ID").option("--json", "Output as JSON").action(async (opts) => {
1364
1569
  const cfg = loadConfig();
1365
1570
  const agentId = opts.agent ?? cfg.defaultAgentId;
@@ -1544,7 +1749,7 @@ ${sym.fail} ${c.error(event.message ?? event.type)}`);
1544
1749
  }
1545
1750
 
1546
1751
  // src/commands/run.ts
1547
- var import_commander7 = require("commander");
1752
+ var import_commander8 = require("commander");
1548
1753
  var readline3 = __toESM(require("readline"));
1549
1754
 
1550
1755
  // src/local-tools.ts
@@ -2177,7 +2382,7 @@ async function runLocalTool(call, cfg) {
2177
2382
 
2178
2383
  // src/commands/run.ts
2179
2384
  function runCommand() {
2180
- return new import_commander7.Command("run").description("Send a single prompt to an agent and stream the response").argument("<prompt>", "Prompt text to send").option("--agent <agentId>", "Agent ID").option("--session <sessionId>", "Resume an existing session by ID").option("--new-session", "Create a new session and print its ID for future use").option("--local", "Enable local file system access (with permission prompts)").option("-y, --yes", "Enable local file system access and auto-approve all operations").option("--no-stream", "Disable streaming (wait for full response)").option("--json", "Output raw event stream as JSON lines").action(async (prompt2, opts) => {
2385
+ return new import_commander8.Command("run").description("Send a single prompt to an agent and stream the response").argument("<prompt>", "Prompt text to send").option("--agent <agentId>", "Agent ID").option("--session <sessionId>", "Resume an existing session by ID").option("--new-session", "Create a new session and print its ID for future use").option("--computer", "Give the agent access to its persistent cloud computer").option("--local", "Enable local file system access (with permission prompts)").option("-y, --yes", "Enable local file system access and auto-approve all operations").option("--no-stream", "Disable streaming (wait for full response)").option("--json", "Output raw event stream as JSON lines").action(async (prompt2, opts) => {
2181
2386
  const cfg = loadConfig();
2182
2387
  const agentId = opts.agent ?? cfg.defaultAgentId;
2183
2388
  if (!agentId) {
@@ -2246,6 +2451,9 @@ function runCommand() {
2246
2451
  if (localEnabled) {
2247
2452
  rows.push(["Local tools", autoApprove ? c.warn("enabled (auto-approve on)") : c.success("enabled")]);
2248
2453
  }
2454
+ if (opts.computer) {
2455
+ rows.push(["Cloud computer", c.success("enabled") + c.dim(" (persistent, remote)")]);
2456
+ }
2249
2457
  if (rows.length) {
2250
2458
  detail(rows);
2251
2459
  console.log();
@@ -2256,6 +2464,7 @@ function runCommand() {
2256
2464
  sessionId,
2257
2465
  messages: [{ role: "user", content: prompt2 }],
2258
2466
  ...cfg.initiator && { initiatorId: cfg.initiator },
2467
+ ...opts.computer && { computerRequest: { enabled: true } },
2259
2468
  ...cliContext && { cliContext }
2260
2469
  };
2261
2470
  if (opts.noStream && !localEnabled) {
@@ -2355,7 +2564,7 @@ ${sym.fail} ${c.error(event.message ?? "Error")}`);
2355
2564
  }
2356
2565
 
2357
2566
  // src/commands/chat.ts
2358
- var import_commander8 = require("commander");
2567
+ var import_commander9 = require("commander");
2359
2568
  var readline4 = __toESM(require("readline"));
2360
2569
  var import_fs6 = require("fs");
2361
2570
  var import_path4 = require("path");
@@ -2399,7 +2608,7 @@ var LOCAL_TOOLS_DISCLAIMER = `
2399
2608
  ${c.dim("Session activity is logged to")} ${c.primary("~/.agc/sessions/")}
2400
2609
  `;
2401
2610
  function chatCommand() {
2402
- return new import_commander8.Command("chat").description("Start an interactive chat REPL with an agent").option("--agent <agentId>", "Agent ID (or set defaultAgentId in config)").option("--resume <sessionId>", "Resume an existing session by ID").option("--no-stream", "Disable token streaming (wait for full response)").option("--no-local", "Disable local file system access for the agent").action(async (opts) => {
2611
+ return new import_commander9.Command("chat").description("Start an interactive chat REPL with an agent").option("--agent <agentId>", "Agent ID (or set defaultAgentId in config)").option("--resume <sessionId>", "Resume an existing session by ID").option("--computer", "Give the agent access to its persistent cloud computer").option("--no-stream", "Disable token streaming (wait for full response)").option("--no-local", "Disable local file system access for the agent").action(async (opts) => {
2403
2612
  const localEnabled = opts.local !== false;
2404
2613
  const cfg = loadConfig();
2405
2614
  const agentId = opts.agent ?? cfg.defaultAgentId;
@@ -2481,6 +2690,7 @@ ${c.bold("Agent Commons Chat")}`);
2481
2690
  ["Session", c.id(sessionId) + (isResume ? c.dim(" (resumed)") : c.dim(" (new)"))]
2482
2691
  ];
2483
2692
  if (walletLine) headerRows.push(["Wallet", walletLine]);
2693
+ if (opts.computer) headerRows.push(["Cloud computer", c.success("enabled") + c.dim(" (persistent, remote)")]);
2484
2694
  if (localEnabled) headerRows.push(["Local tools", c.success("enabled") + c.dim(" (read, write, search, run)")]);
2485
2695
  detail(headerRows);
2486
2696
  let localToolsCfg = null;
@@ -2590,6 +2800,7 @@ ${content}
2590
2800
  agentId,
2591
2801
  sessionId,
2592
2802
  messages: [{ role: "user", content: userMessage }],
2803
+ ...opts.computer && { computerRequest: { enabled: true } },
2593
2804
  ...cliContext && { cliContext }
2594
2805
  };
2595
2806
  if (opts.noStream) {
@@ -2746,7 +2957,15 @@ ${sym.fail} ${c.error(event.message ?? "Stream error")}`);
2746
2957
  if (thinkingSpinner.isSpinning) thinkingSpinner.stop();
2747
2958
  process.stdout.write("\n");
2748
2959
  if (localToolsCfg && agentContent) {
2749
- await handleLocalToolLoop(agentContent, localToolsCfg, client, agentId, sessionId, appendSessionLog);
2960
+ await handleLocalToolLoop(
2961
+ agentContent,
2962
+ localToolsCfg,
2963
+ client,
2964
+ agentId,
2965
+ sessionId,
2966
+ appendSessionLog,
2967
+ !!opts.computer
2968
+ );
2750
2969
  }
2751
2970
  } catch (err) {
2752
2971
  process.stdout.write("\n");
@@ -2775,7 +2994,7 @@ Session preserved. Resume with: agc chat --resume ${sessionId}`));
2775
2994
  });
2776
2995
  }
2777
2996
  var MAX_TOOL_DEPTH = 10;
2778
- async function handleLocalToolLoop(agentText, cfg, client, agentId, sessionId, appendLog, depth = 0) {
2997
+ async function handleLocalToolLoop(agentText, cfg, client, agentId, sessionId, appendLog, computerEnabled = false, depth = 0) {
2779
2998
  if (depth >= MAX_TOOL_DEPTH) {
2780
2999
  console.log(c.dim(`
2781
3000
  [local] Max tool depth reached (${MAX_TOOL_DEPTH}). Stopping tool loop.
@@ -2822,7 +3041,8 @@ ${result}
2822
3041
  for await (const evt of client.agents.stream({
2823
3042
  agentId,
2824
3043
  sessionId,
2825
- messages: [{ role: "user", content: resultMsg }]
3044
+ messages: [{ role: "user", content: resultMsg }],
3045
+ ...computerEnabled && { computerRequest: { enabled: true } }
2826
3046
  })) {
2827
3047
  if (evt.type === "token") {
2828
3048
  const tok = evt.content ?? "";
@@ -2860,7 +3080,16 @@ ${sym.fail} ${c.error(evt.message ?? "Stream error")}`);
2860
3080
  console.error(`${sym.fail} ${c.error(err?.message ?? String(err))}`);
2861
3081
  return;
2862
3082
  }
2863
- await handleLocalToolLoop(followContent, cfg, client, agentId, sessionId, appendLog, depth + 1);
3083
+ await handleLocalToolLoop(
3084
+ followContent,
3085
+ cfg,
3086
+ client,
3087
+ agentId,
3088
+ sessionId,
3089
+ appendLog,
3090
+ computerEnabled,
3091
+ depth + 1
3092
+ );
2864
3093
  }
2865
3094
  function truncate(s, max) {
2866
3095
  const str = String(s ?? "");
@@ -2949,9 +3178,9 @@ function extractText(payload) {
2949
3178
  }
2950
3179
 
2951
3180
  // src/commands/mcp.ts
2952
- var import_commander9 = require("commander");
3181
+ var import_commander10 = require("commander");
2953
3182
  function mcpCommand() {
2954
- const cmd = new import_commander9.Command("mcp").description("Manage MCP (Model Context Protocol) servers");
3183
+ const cmd = new import_commander10.Command("mcp").description("Manage MCP (Model Context Protocol) servers");
2955
3184
  cmd.command("list").description("List MCP servers for the current initiator").option("--agent <agentId>", "List servers owned by an agent instead of the user").option("--json", "Output as JSON").action(async (opts) => {
2956
3185
  const cfg = loadConfig();
2957
3186
  if (!cfg.initiator && !opts.agent) {
@@ -3249,9 +3478,9 @@ ${sym.ok} MCP server registered`);
3249
3478
  }
3250
3479
 
3251
3480
  // src/commands/skills.ts
3252
- var import_commander10 = require("commander");
3481
+ var import_commander11 = require("commander");
3253
3482
  function skillsCommand() {
3254
- const cmd = new import_commander10.Command("skills").description("Discover and manage skills");
3483
+ const cmd = new import_commander11.Command("skills").description("Discover and manage skills");
3255
3484
  cmd.command("list").description("List available skills").option("--owner <id>", "Filter by owner ID").option("--platform", "Show platform-only skills").option("--json", "Output as JSON").action(async (opts) => {
3256
3485
  const spinner = spin("Fetching skills\u2026");
3257
3486
  try {
@@ -3502,9 +3731,9 @@ function skillsCommand() {
3502
3731
  }
3503
3732
 
3504
3733
  // src/commands/wallet.ts
3505
- var import_commander11 = require("commander");
3734
+ var import_commander12 = require("commander");
3506
3735
  function walletCommand() {
3507
- const cmd = new import_commander11.Command("wallet").description("Manage agent wallets");
3736
+ const cmd = new import_commander12.Command("wallet").description("Manage agent wallets");
3508
3737
  cmd.command("list").description("List all wallets for an agent").option("--agent <agentId>", "Agent ID (or use defaultAgentId from config)").option("--json", "Output as JSON").action(async (opts) => {
3509
3738
  const cfg = loadConfig();
3510
3739
  const agentId = opts.agent ?? cfg.defaultAgentId;
@@ -3734,9 +3963,9 @@ function chainName(chainId) {
3734
3963
  }
3735
3964
 
3736
3965
  // src/commands/models.ts
3737
- var import_commander12 = require("commander");
3966
+ var import_commander13 = require("commander");
3738
3967
  function modelsCommand() {
3739
- const cmd = new import_commander12.Command("models").description("List available LLM models");
3968
+ const cmd = new import_commander13.Command("models").description("List available LLM models");
3740
3969
  cmd.command("ls").description("List all available models grouped by provider").option("--provider <name>", "Filter by provider (openai, anthropic, google, mistral, groq, ollama)").option("--json", "Output as JSON").action(async (opts) => {
3741
3970
  const client = makeClient();
3742
3971
  const spinner = spin("Fetching models\u2026");
@@ -3779,9 +4008,9 @@ ${c.bold(provider.toUpperCase())}`);
3779
4008
  }
3780
4009
 
3781
4010
  // src/commands/memory.ts
3782
- var import_commander13 = require("commander");
4011
+ var import_commander14 = require("commander");
3783
4012
  function memoryCommand() {
3784
- const cmd = new import_commander13.Command("memory").description("View and manage agent memories");
4013
+ const cmd = new import_commander14.Command("memory").description("View and manage agent memories");
3785
4014
  cmd.command("list").description("List memories for an agent").option("--agent <agentId>", "Agent ID (defaults to configured agent)").option("--type <type>", "Filter by type: episodic | semantic | procedural").option("--limit <n>", "Max results", "50").option("--json", "Output as JSON").action(async (opts) => {
3786
4015
  const cfg = loadConfig();
3787
4016
  const agentId = opts.agent ?? cfg.defaultAgentId;
@@ -3921,9 +4150,9 @@ ${sym.ok} Memory ${c.id(memoryId)} deleted`);
3921
4150
  }
3922
4151
 
3923
4152
  // src/commands/usage.ts
3924
- var import_commander14 = require("commander");
4153
+ var import_commander15 = require("commander");
3925
4154
  function usageCommand() {
3926
- const cmd = new import_commander14.Command("usage").description("View token usage and cost by agent");
4155
+ const cmd = new import_commander15.Command("usage").description("View token usage and cost by agent");
3927
4156
  cmd.command("agents").description("Show usage summary for all your agents").option("--owner <address>", "Owner address (defaults to configured initiator)").option("--from <date>", "Start date (ISO, e.g. 2025-01-01)").option("--to <date>", "End date (ISO)").option("--json", "Output as JSON").action(async (opts) => {
3928
4157
  const cfg = loadConfig();
3929
4158
  const owner = opts.owner ?? cfg.initiator;
@@ -4015,7 +4244,7 @@ function usageCommand() {
4015
4244
  }
4016
4245
 
4017
4246
  // src/commands/logs.ts
4018
- var import_commander15 = require("commander");
4247
+ var import_commander16 = require("commander");
4019
4248
  var STATUS_COLOR = {
4020
4249
  success: (s) => c.bold(s),
4021
4250
  error: (s) => c.error(s),
@@ -4025,7 +4254,7 @@ function colorStatus(status) {
4025
4254
  return (STATUS_COLOR[status] ?? c.dim)(status);
4026
4255
  }
4027
4256
  function logsCommand() {
4028
- const cmd = new import_commander15.Command("logs").description("View agent activity logs");
4257
+ const cmd = new import_commander16.Command("logs").description("View agent activity logs");
4029
4258
  cmd.command("list").alias("ls").description("List recent log entries for an agent").option("--agent <agentId>", "Agent ID (defaults to configured agent)").option("--session <sessionId>", "Filter by session ID").option("--status <status>", "Filter: success | error | warning").option("--limit <n>", "Max entries to show", "50").option("--json", "Output as JSON").action(async (opts) => {
4030
4259
  const cfg = loadConfig();
4031
4260
  const agentId = opts.agent ?? cfg.defaultAgentId;
@@ -4099,6 +4328,288 @@ function logsCommand() {
4099
4328
  return cmd;
4100
4329
  }
4101
4330
 
4331
+ // src/commands/computer.ts
4332
+ var import_commander17 = require("commander");
4333
+ var RESOURCE_PROFILES = [
4334
+ "starter",
4335
+ "standard",
4336
+ "performance",
4337
+ "gpu"
4338
+ ];
4339
+ var RESOURCE_MODES = ["fixed", "elastic"];
4340
+ function resolveAgentId(opts) {
4341
+ const agentId = opts.agent ?? loadConfig().defaultAgentId;
4342
+ if (!agentId) {
4343
+ throw new Error(
4344
+ "Specify --agent <agentId> or set defaultAgentId with `agc config set defaultAgentId <id>`."
4345
+ );
4346
+ }
4347
+ return agentId;
4348
+ }
4349
+ function unwrap(response) {
4350
+ return response?.data ?? response;
4351
+ }
4352
+ function displayComputer(computer) {
4353
+ if (!computer) {
4354
+ section("Persistent cloud computer");
4355
+ detail([
4356
+ ["Status", statusBadge("disabled")],
4357
+ ["Persistence", "persistent"],
4358
+ ["Computer ID", c.dim("(not provisioned)")]
4359
+ ]);
4360
+ console.log(c.dim(" Enable it with: agc computer enable --agent <agentId>"));
4361
+ return;
4362
+ }
4363
+ const wire = computer;
4364
+ const resources = computer.resources ?? {};
4365
+ const gpu = resources.gpu ?? (wire.gpuCount ? { count: wire.gpuCount, type: wire.gpuType } : null);
4366
+ const cpu = resources.vcpu ?? wire.cpuRequest ?? wire.cpuLimit;
4367
+ const memory = resources.memoryGiB != null ? `${resources.memoryGiB} GiB` : wire.memoryRequest ?? wire.memoryLimit;
4368
+ const storage = resources.storageGiB != null ? `${resources.storageGiB} GiB` : wire.storageLimit;
4369
+ section("Persistent cloud computer");
4370
+ detail([
4371
+ ["Computer ID", computer.computerId ? c.id(computer.computerId) : c.dim("(not provisioned)")],
4372
+ ["Enabled", computer.enabled === false ? "no" : c.success("yes")],
4373
+ ["Status", statusBadge(computer.status ?? "disabled")],
4374
+ ["Desired state", computer.desiredState ?? c.dim("n/a")],
4375
+ ["Persistence", computer.persistence ?? wire.lifecycle ?? "persistent"],
4376
+ ["Profile", computer.resourceProfile ?? c.dim("n/a")],
4377
+ ["Mode", computer.resourceMode ?? c.dim("n/a")],
4378
+ ["CPU", cpu != null ? String(cpu) : c.dim("n/a")],
4379
+ ["Memory", memory != null ? String(memory) : c.dim("n/a")],
4380
+ ["Storage", storage != null ? String(storage) : c.dim("n/a")],
4381
+ ["GPU", gpu?.count ? `${gpu.count} \xD7 ${gpu.type ?? "provider default"}` : "none"],
4382
+ ["Region", computer.region ?? c.dim("automatic")],
4383
+ ["Workspace", computer.workspaceRoot ?? c.dim("not mounted")],
4384
+ ["Last activity", computer.lastActivityAt ? relativeTime(computer.lastActivityAt) : c.dim("never")],
4385
+ ["Error", computer.errorMessage ?? void 0]
4386
+ ]);
4387
+ }
4388
+ function parseNumber(value, name, options) {
4389
+ if (value === void 0) return void 0;
4390
+ const parsed = Number(value);
4391
+ const minimum = options?.allowZero ? 0 : Number.MIN_VALUE;
4392
+ if (!Number.isFinite(parsed) || parsed < minimum || options?.integer && !Number.isInteger(parsed)) {
4393
+ const qualifier = options?.integer ? "whole number" : "number";
4394
+ throw new Error(`${name} must be a ${options?.allowZero ? "non-negative" : "positive"} ${qualifier}.`);
4395
+ }
4396
+ return parsed;
4397
+ }
4398
+ async function changeEnabled(agentId, enabled, json) {
4399
+ const spinner = spin(`${enabled ? "Enabling" : "Disabling"} persistent cloud computer\u2026`);
4400
+ try {
4401
+ const response = await makeClient().agents.updateComputerConfig(agentId, { enabled });
4402
+ const config = unwrap(response);
4403
+ spinner.stop();
4404
+ if (json) return jsonOut(config);
4405
+ console.log(`
4406
+ ${sym.ok} Persistent cloud computer ${enabled ? "enabled" : "disabled"} for agent ${c.id(agentId)}`);
4407
+ if (enabled) {
4408
+ console.log(c.dim(` Wake it now with: agc computer wake --agent ${agentId}`));
4409
+ }
4410
+ } catch (error) {
4411
+ spinner.stop();
4412
+ printError(error);
4413
+ process.exitCode = 1;
4414
+ }
4415
+ }
4416
+ async function lifecycleAction(action, agentId, reason, json) {
4417
+ const verb = action === "wake" ? "Waking" : action === "sleep" ? "Sleeping" : "Restarting";
4418
+ const spinner = spin(`${verb} persistent cloud computer\u2026`);
4419
+ try {
4420
+ const client = makeClient();
4421
+ const response = action === "wake" ? await client.agents.wakeComputer(agentId, reason ? { reason } : void 0) : action === "sleep" ? await client.agents.sleepComputer(agentId, reason ? { reason } : void 0) : await client.agents.restartComputer(agentId, reason ? { reason } : void 0);
4422
+ const computer = unwrap(response);
4423
+ spinner.stop();
4424
+ if (json) return jsonOut(computer);
4425
+ console.log(`
4426
+ ${sym.ok} Persistent cloud computer ${action === "sleep" ? "is sleeping" : action === "wake" ? "is awake" : "restarted"}`);
4427
+ displayComputer(computer);
4428
+ } catch (error) {
4429
+ spinner.stop();
4430
+ printError(error);
4431
+ process.exitCode = 1;
4432
+ }
4433
+ }
4434
+ function addAgentOption(command) {
4435
+ return command.option("--agent <agentId>", "Agent ID (defaults to configured agent)");
4436
+ }
4437
+ function computerCommand() {
4438
+ const command = new import_commander17.Command("computer").description("Manage an agent's one persistent cloud computer");
4439
+ addAgentOption(command.command("status").description("Show persistent cloud computer status")).option("--json", "Output as JSON").action(async (opts) => {
4440
+ let agentId;
4441
+ try {
4442
+ agentId = resolveAgentId(opts);
4443
+ } catch (error) {
4444
+ printError(error);
4445
+ process.exitCode = 1;
4446
+ return;
4447
+ }
4448
+ const spinner = spin("Fetching persistent cloud computer\u2026");
4449
+ try {
4450
+ const computer = unwrap(await makeClient().agents.getComputer(agentId));
4451
+ spinner.stop();
4452
+ if (opts.json) return jsonOut(computer);
4453
+ displayComputer(computer);
4454
+ } catch (error) {
4455
+ spinner.stop();
4456
+ printError(error);
4457
+ process.exitCode = 1;
4458
+ }
4459
+ });
4460
+ addAgentOption(command.command("enable").description("Enable a persistent cloud computer for an agent")).option("--json", "Output as JSON").action(async (opts) => {
4461
+ try {
4462
+ await changeEnabled(resolveAgentId(opts), true, !!opts.json);
4463
+ } catch (error) {
4464
+ printError(error);
4465
+ process.exitCode = 1;
4466
+ }
4467
+ });
4468
+ addAgentOption(command.command("disable").description("Disable the agent cloud computer")).option("--json", "Output as JSON").action(async (opts) => {
4469
+ try {
4470
+ await changeEnabled(resolveAgentId(opts), false, !!opts.json);
4471
+ } catch (error) {
4472
+ printError(error);
4473
+ process.exitCode = 1;
4474
+ }
4475
+ });
4476
+ for (const action of ["wake", "sleep", "restart"]) {
4477
+ const descriptions = {
4478
+ wake: "Wake the persistent cloud computer",
4479
+ sleep: "Sleep compute while preserving the persistent workspace",
4480
+ restart: "Restart the runtime while preserving the persistent workspace"
4481
+ };
4482
+ addAgentOption(command.command(action).description(descriptions[action])).option("--reason <text>", `Reason for the ${action}`).option("--json", "Output as JSON").action(async (opts) => {
4483
+ try {
4484
+ await lifecycleAction(action, resolveAgentId(opts), opts.reason, !!opts.json);
4485
+ } catch (error) {
4486
+ printError(error);
4487
+ process.exitCode = 1;
4488
+ }
4489
+ });
4490
+ }
4491
+ addAgentOption(command.command("resize").description("Resize the persistent cloud computer")).option("--profile <profile>", `Resource profile: ${RESOURCE_PROFILES.join(" | ")}`).option("--mode <mode>", `Resource mode: ${RESOURCE_MODES.join(" | ")}`).option("--vcpu <count>", "Requested virtual CPU count").option("--cpu <count>", "Alias for --vcpu").option("--memory <gib>", "Requested memory in GiB").option("--storage <gib>", "Requested persistent storage in GiB").option("--gpu-type <type>", "GPU type, such as nvidia-h100").option("--gpu-count <count>", "GPU count (0 removes GPU allocation)").option("--json", "Output as JSON").action(async (opts) => {
4492
+ let agentId;
4493
+ let resize;
4494
+ try {
4495
+ agentId = resolveAgentId(opts);
4496
+ if (opts.profile && !RESOURCE_PROFILES.includes(opts.profile)) {
4497
+ throw new Error(`--profile must be one of: ${RESOURCE_PROFILES.join(", ")}.`);
4498
+ }
4499
+ if (opts.mode && !RESOURCE_MODES.includes(opts.mode)) {
4500
+ throw new Error(`--mode must be one of: ${RESOURCE_MODES.join(", ")}.`);
4501
+ }
4502
+ if (opts.vcpu !== void 0 && opts.cpu !== void 0) {
4503
+ throw new Error("Use either --vcpu or --cpu, not both.");
4504
+ }
4505
+ const vcpu = parseNumber(opts.vcpu ?? opts.cpu, "CPU");
4506
+ const memoryGiB = parseNumber(opts.memory, "Memory");
4507
+ const storageGiB = parseNumber(opts.storage, "Storage");
4508
+ const gpuCount = parseNumber(opts.gpuCount, "GPU count", { integer: true, allowZero: true });
4509
+ const resources = {
4510
+ ...vcpu !== void 0 && { vcpu },
4511
+ ...memoryGiB !== void 0 && { memoryGiB },
4512
+ ...storageGiB !== void 0 && { storageGiB },
4513
+ ...(gpuCount !== void 0 || opts.gpuType) && {
4514
+ gpu: { count: gpuCount ?? 1, ...opts.gpuType && { type: opts.gpuType } }
4515
+ }
4516
+ };
4517
+ resize = {
4518
+ ...opts.profile && { resourceProfile: opts.profile },
4519
+ ...opts.mode && { resourceMode: opts.mode },
4520
+ ...Object.keys(resources).length > 0 && { resources }
4521
+ };
4522
+ if (Object.keys(resize).length === 0) {
4523
+ throw new Error("Specify --profile, --mode, or at least one resource value.");
4524
+ }
4525
+ } catch (error) {
4526
+ printError(error);
4527
+ process.exitCode = 1;
4528
+ return;
4529
+ }
4530
+ const spinner = spin("Resizing persistent cloud computer\u2026");
4531
+ try {
4532
+ const computer = unwrap(await makeClient().agents.resizeComputer(agentId, resize));
4533
+ spinner.stop();
4534
+ if (opts.json) return jsonOut(computer);
4535
+ console.log(`
4536
+ ${sym.ok} Persistent cloud computer resize requested`);
4537
+ displayComputer(computer);
4538
+ } catch (error) {
4539
+ spinner.stop();
4540
+ printError(error);
4541
+ process.exitCode = 1;
4542
+ }
4543
+ });
4544
+ addAgentOption(
4545
+ command.command("exec").description("Run a command in the persistent cloud computer").argument("<command...>", "Command and arguments to run")
4546
+ ).option("--cwd <path>", "Working directory").option("--timeout <seconds>", "Command timeout in seconds", "120").option("--json", "Output as JSON").action(async (commandParts, opts) => {
4547
+ let agentId;
4548
+ let timeoutSeconds;
4549
+ try {
4550
+ agentId = resolveAgentId(opts);
4551
+ timeoutSeconds = parseNumber(opts.timeout, "Timeout");
4552
+ } catch (error) {
4553
+ printError(error);
4554
+ process.exitCode = 1;
4555
+ return;
4556
+ }
4557
+ const spinner = spin("Running command in persistent cloud computer\u2026");
4558
+ try {
4559
+ const result = unwrap(await makeClient().agents.execComputer(agentId, {
4560
+ command: commandParts.join(" "),
4561
+ ...opts.cwd && { cwd: opts.cwd },
4562
+ ...timeoutSeconds !== void 0 && { timeoutSeconds }
4563
+ }));
4564
+ spinner.stop();
4565
+ if (opts.json) return jsonOut(result);
4566
+ const stdout = result?.stdout ?? result?.output ?? result?.result ?? "";
4567
+ const stderr = result?.stderr ?? "";
4568
+ if (stdout) process.stdout.write(String(stdout).replace(/\n?$/, "\n"));
4569
+ if (stderr) process.stderr.write(c.error(String(stderr).replace(/\n?$/, "\n")));
4570
+ const exitCode = result?.exitCode ?? result?.exit_code;
4571
+ if (exitCode !== void 0 && exitCode !== 0) process.exitCode = Number(exitCode);
4572
+ } catch (error) {
4573
+ spinner.stop();
4574
+ printError(error);
4575
+ process.exitCode = 1;
4576
+ }
4577
+ });
4578
+ addAgentOption(command.command("events").description("List recent persistent cloud computer events")).option("--limit <count>", "Maximum events", "50").option("--json", "Output as JSON").action(async (opts) => {
4579
+ let agentId;
4580
+ let limit;
4581
+ try {
4582
+ agentId = resolveAgentId(opts);
4583
+ limit = parseNumber(opts.limit, "Limit", { integer: true });
4584
+ } catch (error) {
4585
+ printError(error);
4586
+ process.exitCode = 1;
4587
+ return;
4588
+ }
4589
+ const spinner = spin("Fetching persistent cloud computer events\u2026");
4590
+ try {
4591
+ const events = unwrap(await makeClient().agents.listComputerEvents(agentId, limit));
4592
+ spinner.stop();
4593
+ if (opts.json) return jsonOut(events);
4594
+ section(`Cloud computer events (${events.length})`);
4595
+ table(
4596
+ events.map((event) => ({
4597
+ Event: event.eventType ?? "",
4598
+ Summary: event.summary ?? "",
4599
+ Actor: event.actorType ?? "",
4600
+ When: event.createdAt ? relativeTime(event.createdAt) : ""
4601
+ })),
4602
+ ["Event", "Summary", "Actor", "When"]
4603
+ );
4604
+ } catch (error) {
4605
+ spinner.stop();
4606
+ printError(error);
4607
+ process.exitCode = 1;
4608
+ }
4609
+ });
4610
+ return command;
4611
+ }
4612
+
4102
4613
  // src/bin.ts
4103
4614
  var CONFIG_FILE3 = (0, import_path5.join)((0, import_os4.homedir)(), ".agc", "config.json");
4104
4615
  async function interactiveMenu() {
@@ -4120,6 +4631,7 @@ async function interactiveMenu() {
4120
4631
  const action = await select("What would you like to do?", [
4121
4632
  { label: "Chat with an agent", value: "chat", hint: "agc chat" },
4122
4633
  { label: "Run an agent (one-shot)", value: "run", hint: "agc run" },
4634
+ { label: "Manage an agent cloud computer", value: "computer", hint: "agc computer status" },
4123
4635
  { label: "View sessions", value: "sessions", hint: "agc sessions list" },
4124
4636
  { label: "Manage agents", value: "agents", hint: "agc agents list" },
4125
4637
  { label: "Tasks", value: "tasks", hint: "agc task list" },
@@ -4135,8 +4647,9 @@ async function interactiveMenu() {
4135
4647
  if (action === "exit") {
4136
4648
  process.exit(0);
4137
4649
  }
4138
- const agentId = cfg.defaultAgentId ?? await pickAgentInteractively(action);
4139
- if ((action === "chat" || action === "run") && !agentId) return;
4650
+ const needsAgent = action === "chat" || action === "run" || action === "computer";
4651
+ const agentId = needsAgent ? cfg.defaultAgentId ?? await pickAgentInteractively(action) : void 0;
4652
+ if (needsAgent && !agentId) return;
4140
4653
  if (action === "run") {
4141
4654
  const prompt2 = await askPrompt("Enter your prompt:");
4142
4655
  if (!prompt2) return;
@@ -4147,6 +4660,7 @@ async function interactiveMenu() {
4147
4660
  chat: ["chat", "--agent", agentId],
4148
4661
  run: [],
4149
4662
  // handled above
4663
+ computer: ["computer", "status", "--agent", agentId],
4150
4664
  sessions: ["sessions", "list"],
4151
4665
  agents: ["agents", "list"],
4152
4666
  tasks: ["task", "list"],
@@ -4212,7 +4726,7 @@ async function pickAgentInteractively(action) {
4212
4726
  }
4213
4727
  console.log();
4214
4728
  const agentId = await select(
4215
- `Choose an agent to ${action} with:`,
4729
+ action === "computer" ? "Choose the agent whose cloud computer you want to manage:" : `Choose an agent to ${action} with:`,
4216
4730
  agents.map((a) => ({
4217
4731
  label: a.name,
4218
4732
  value: a.agentId,
@@ -4231,8 +4745,8 @@ async function pickAgentInteractively(action) {
4231
4745
  }
4232
4746
  return agentId;
4233
4747
  }
4234
- var program = new import_commander16.Command();
4235
- program.name("agc").description("Agent Commons CLI \u2014 interact with the Agent Commons platform").version("0.2.3", "-v, --version").action(async () => {
4748
+ var program = new import_commander18.Command();
4749
+ program.name("agc").description("Agent Commons CLI \u2014 interact with the Agent Commons platform").version("0.3.0", "-v, --version").action(async () => {
4236
4750
  await interactiveMenu();
4237
4751
  });
4238
4752
  program.hook("preAction", async (_thisCommand, actionCommand) => {
@@ -4246,10 +4760,12 @@ program.addCommand(configCommand());
4246
4760
  program.addCommand(agentsCommand());
4247
4761
  program.addCommand(sessionsCommand());
4248
4762
  program.addCommand(toolsCommand());
4763
+ program.addCommand(connectionsCommand());
4249
4764
  program.addCommand(workflowCommand());
4250
4765
  program.addCommand(taskCommand());
4251
4766
  program.addCommand(runCommand());
4252
4767
  program.addCommand(chatCommand());
4768
+ program.addCommand(computerCommand());
4253
4769
  program.addCommand(mcpCommand());
4254
4770
  program.addCommand(skillsCommand());
4255
4771
  program.addCommand(walletCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-commons/cli",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Agent Commons CLI — chat, run, and manage agents from your terminal",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "commander": "^12.1.0",
17
17
  "ora": "^8.1.1",
18
18
  "pdf-parse": "^1.1.1",
19
- "@agent-commons/sdk": "0.2.3"
19
+ "@agent-commons/sdk": "0.4.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^22.10.2",