@integrity-labs/agt-cli 0.10.7 → 0.10.9

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/bin/agt.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  resolveChannels,
33
33
  serializeManifestForSlackCli,
34
34
  setActiveTeam
35
- } from "../chunk-VDUA5FEW.js";
35
+ } from "../chunk-PZG4XPJV.js";
36
36
 
37
37
  // src/bin/agt.ts
38
38
  import { join as join11 } from "path";
@@ -107,7 +107,7 @@ async function whoamiCommand() {
107
107
  jsonOutput({
108
108
  ok: true,
109
109
  api_key_prefix: apiKey.slice(0, 8) + "****",
110
- host: getHost() ?? null,
110
+ host: getHost(),
111
111
  host_id: exchange.hostId,
112
112
  team: exchange.teamSlug,
113
113
  team_id: exchange.teamId,
@@ -117,7 +117,7 @@ async function whoamiCommand() {
117
117
  }
118
118
  success("Authenticated via API key");
119
119
  info(`API Key: ${chalk3.bold(apiKey.slice(0, 8) + "****")}`);
120
- info(`Host: ${chalk3.bold(getHost() ?? "not set")}`);
120
+ info(`Host: ${chalk3.bold(getHost())}`);
121
121
  info(`Host ID: ${exchange.hostId}`);
122
122
  info(`Team: ${chalk3.bold(exchange.teamSlug ?? exchange.teamId)}`);
123
123
  info(`User: ${chalk3.bold(exchange.userEmail ?? "unknown")}`);
@@ -2053,8 +2053,160 @@ async function hostDecommissionCommand(hostName) {
2053
2053
  }
2054
2054
  }
2055
2055
 
2056
- // src/commands/manager.ts
2056
+ // src/commands/host-pair.ts
2057
+ import { spawn, spawnSync } from "child_process";
2057
2058
  import chalk14 from "chalk";
2059
+ async function hostPairCommand(name, opts) {
2060
+ const teamSlug = requireTeam();
2061
+ if (!teamSlug) return;
2062
+ const json = isJsonMode();
2063
+ const localPort = Number(opts.port ?? "54545");
2064
+ if (!Number.isInteger(localPort) || localPort < 1024 || localPort > 65535) {
2065
+ error("--port must be an integer between 1024 and 65535");
2066
+ process.exitCode = 1;
2067
+ return;
2068
+ }
2069
+ let host2;
2070
+ try {
2071
+ const data = await api.get(`/hosts/${encodeURIComponent(name)}`);
2072
+ host2 = data.host;
2073
+ } catch (err) {
2074
+ if (json) jsonOutput({ ok: false, error: err.message });
2075
+ else error(`Failed to look up host: ${err.message}`);
2076
+ process.exitCode = 1;
2077
+ return;
2078
+ }
2079
+ if (host2.provision_source !== "augmented-ec2") {
2080
+ const msg = `Host "${name}" is ${host2.provision_source ?? "self"}-provisioned, not an Augmented-managed EC2. agt host pair is only for EC2 hosts provisioned through the Augmented API.`;
2081
+ if (json) jsonOutput({ ok: false, error: msg });
2082
+ else error(msg);
2083
+ process.exitCode = 1;
2084
+ return;
2085
+ }
2086
+ if (!host2.ec2_instance_id) {
2087
+ const msg = `Host "${name}" has no EC2 instance ID yet. Provision it first with \`agt host provision\`.`;
2088
+ if (json) jsonOutput({ ok: false, error: msg });
2089
+ else error(msg);
2090
+ process.exitCode = 1;
2091
+ return;
2092
+ }
2093
+ const region = host2.ec2_region ?? process.env.AWS_REGION ?? "us-east-2";
2094
+ const instanceId = host2.ec2_instance_id;
2095
+ const preflightErr = preflightAws();
2096
+ if (preflightErr) {
2097
+ if (json) jsonOutput({ ok: false, error: preflightErr });
2098
+ else error(preflightErr);
2099
+ process.exitCode = 1;
2100
+ return;
2101
+ }
2102
+ if (json) {
2103
+ jsonOutput({
2104
+ ok: true,
2105
+ host: { name: host2.name, id: host2.id, instance_id: instanceId, region },
2106
+ port_forward: {
2107
+ command: "aws",
2108
+ args: [
2109
+ "ssm",
2110
+ "start-session",
2111
+ "--region",
2112
+ region,
2113
+ "--target",
2114
+ instanceId,
2115
+ "--document-name",
2116
+ "AWS-StartPortForwardingSession",
2117
+ "--parameters",
2118
+ JSON.stringify({ portNumber: [String(localPort)], localPortNumber: [String(localPort)] })
2119
+ ]
2120
+ },
2121
+ shell: {
2122
+ command: "aws",
2123
+ args: ["ssm", "start-session", "--region", region, "--target", instanceId]
2124
+ }
2125
+ });
2126
+ return;
2127
+ }
2128
+ info(`Pairing Claude Code on ${chalk14.bold(name)} (${instanceId}, ${region})`);
2129
+ info(`Local port ${chalk14.cyan(String(localPort))} will be forwarded to the host.`);
2130
+ console.log();
2131
+ console.log(chalk14.dim("In the shell that opens, run:"));
2132
+ console.log(` ${chalk14.cyan(`CLAUDE_CODE_OAUTH_PORT=${localPort} claude /login`)}`);
2133
+ console.log(chalk14.dim("Then click the printed URL on this machine. The OAuth callback"));
2134
+ console.log(chalk14.dim(`will reach Claude Code via the port-forward tunnel.`));
2135
+ console.log();
2136
+ console.log(chalk14.dim("Exit the shell (Ctrl+D) when Claude Code reports successful login."));
2137
+ console.log();
2138
+ const tunnel = spawn(
2139
+ "aws",
2140
+ [
2141
+ "ssm",
2142
+ "start-session",
2143
+ "--region",
2144
+ region,
2145
+ "--target",
2146
+ instanceId,
2147
+ "--document-name",
2148
+ "AWS-StartPortForwardingSession",
2149
+ "--parameters",
2150
+ JSON.stringify({ portNumber: [String(localPort)], localPortNumber: [String(localPort)] })
2151
+ ],
2152
+ { stdio: ["ignore", "pipe", "pipe"] }
2153
+ );
2154
+ tunnel.stderr?.on("data", (buf) => {
2155
+ const line = buf.toString().trim();
2156
+ if (line.startsWith("An error occurred")) {
2157
+ console.error(chalk14.red(`[tunnel] ${line}`));
2158
+ }
2159
+ });
2160
+ await new Promise((r) => setTimeout(r, 1500));
2161
+ if (tunnel.exitCode !== null) {
2162
+ error("Port-forward tunnel failed to start. Check AWS credentials and session-manager-plugin.");
2163
+ process.exitCode = 1;
2164
+ return;
2165
+ }
2166
+ if (opts.noShell) {
2167
+ console.log(chalk14.dim("--no-shell set; tunnel is running. Press Ctrl+C to exit."));
2168
+ await new Promise((resolve2) => {
2169
+ const onSignal = () => {
2170
+ terminate(tunnel);
2171
+ resolve2();
2172
+ };
2173
+ process.once("SIGINT", onSignal);
2174
+ process.once("SIGTERM", onSignal);
2175
+ });
2176
+ } else {
2177
+ await runInteractive("aws", ["ssm", "start-session", "--region", region, "--target", instanceId]);
2178
+ terminate(tunnel);
2179
+ }
2180
+ success("Pair session ended.");
2181
+ }
2182
+ function preflightAws() {
2183
+ const aws = spawnSync("aws", ["--version"], { stdio: "ignore" });
2184
+ if (aws.status !== 0) {
2185
+ return "AWS CLI not found. Install: https://aws.amazon.com/cli/";
2186
+ }
2187
+ const plugin2 = spawnSync("session-manager-plugin", [], { stdio: "ignore" });
2188
+ if (plugin2.error) {
2189
+ return "session-manager-plugin not found. Install: brew install --cask session-manager-plugin";
2190
+ }
2191
+ return null;
2192
+ }
2193
+ function runInteractive(cmd, args) {
2194
+ return new Promise((resolve2) => {
2195
+ const child = spawn(cmd, args, { stdio: "inherit" });
2196
+ child.on("exit", (code) => resolve2(code ?? 0));
2197
+ child.on("error", () => resolve2(1));
2198
+ });
2199
+ }
2200
+ function terminate(child) {
2201
+ if (child.exitCode !== null) return;
2202
+ try {
2203
+ child.kill("SIGTERM");
2204
+ } catch {
2205
+ }
2206
+ }
2207
+
2208
+ // src/commands/manager.ts
2209
+ import chalk15 from "chalk";
2058
2210
  import { join as join8 } from "path";
2059
2211
  import { homedir } from "os";
2060
2212
 
@@ -2172,16 +2324,6 @@ function getManagerStatus() {
2172
2324
  // src/commands/manager.ts
2173
2325
  function managerStartCommand(opts) {
2174
2326
  const json = isJsonMode();
2175
- if (!getHost()) {
2176
- const msg = "AGT_HOST is not set. Export it to point at the Augmented API (e.g. export AGT_HOST=https://your-api.example.com)";
2177
- if (json) {
2178
- jsonOutput({ ok: false, error: msg });
2179
- } else {
2180
- error(msg);
2181
- }
2182
- process.exitCode = 1;
2183
- return;
2184
- }
2185
2327
  const apiKey = getApiKey();
2186
2328
  if (!apiKey) {
2187
2329
  const msg = "AGT_API_KEY is not set. Export it with your host API key (tlk_...)";
@@ -2267,10 +2409,10 @@ function managerStatusCommand() {
2267
2409
  jsonOutput({ ok: true, running: true, ...status });
2268
2410
  return;
2269
2411
  }
2270
- console.log(chalk14.bold("\nManager Status\n"));
2412
+ console.log(chalk15.bold("\nManager Status\n"));
2271
2413
  info(`PID: ${status.pid}`);
2272
2414
  info(`Started: ${status.startedAt}`);
2273
- info(`Last poll: ${status.lastPollAt ?? chalk14.dim("none")}`);
2415
+ info(`Last poll: ${status.lastPollAt ?? chalk15.dim("none")}`);
2274
2416
  info(`Polls: ${status.pollCount}`);
2275
2417
  info(`Errors: ${status.errorCount}`);
2276
2418
  console.log();
@@ -2279,19 +2421,19 @@ function managerStatusCommand() {
2279
2421
  return;
2280
2422
  }
2281
2423
  const rows = status.agents.map((a) => {
2282
- let gwStatus = chalk14.dim("\u2014");
2424
+ let gwStatus = chalk15.dim("\u2014");
2283
2425
  if (a.gatewayRunning) {
2284
- gwStatus = chalk14.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
2426
+ gwStatus = chalk15.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
2285
2427
  } else if (a.gatewayPort) {
2286
- gwStatus = chalk14.red(`:${a.gatewayPort} (down)`);
2428
+ gwStatus = chalk15.red(`:${a.gatewayPort} (down)`);
2287
2429
  }
2288
2430
  return [
2289
2431
  a.codeName,
2290
- a.status === "active" ? chalk14.green(a.status) : a.status === "paused" ? chalk14.yellow(a.status) : chalk14.dim(a.status ?? "\u2014"),
2291
- a.charterVersion || chalk14.dim("\u2014"),
2432
+ a.status === "active" ? chalk15.green(a.status) : a.status === "paused" ? chalk15.yellow(a.status) : chalk15.dim(a.status ?? "\u2014"),
2433
+ a.charterVersion || chalk15.dim("\u2014"),
2292
2434
  gwStatus,
2293
- a.lastProvisionAt ? new Date(a.lastProvisionAt).toLocaleTimeString() : chalk14.dim("\u2014"),
2294
- a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() : chalk14.dim("\u2014")
2435
+ a.lastProvisionAt ? new Date(a.lastProvisionAt).toLocaleTimeString() : chalk15.dim("\u2014"),
2436
+ a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() : chalk15.dim("\u2014")
2295
2437
  ];
2296
2438
  });
2297
2439
  table(
@@ -2300,13 +2442,13 @@ function managerStatusCommand() {
2300
2442
  );
2301
2443
  const acpAgents = status.agents.filter((a) => a.acpSessions && a.acpSessions.length > 0);
2302
2444
  if (acpAgents.length > 0) {
2303
- console.log(chalk14.bold("\nACP Sessions\n"));
2445
+ console.log(chalk15.bold("\nACP Sessions\n"));
2304
2446
  const acpRows = acpAgents.flatMap(
2305
2447
  (a) => a.acpSessions.map((s) => [
2306
2448
  a.codeName,
2307
2449
  s.agentCommand,
2308
- s.sessionName ?? chalk14.dim("default"),
2309
- s.queueState === "running" ? chalk14.green(s.queueState) : s.queueState === "queued" ? chalk14.yellow(s.queueState) : chalk14.dim(s.queueState),
2450
+ s.sessionName ?? chalk15.dim("default"),
2451
+ s.queueState === "running" ? chalk15.green(s.queueState) : s.queueState === "queued" ? chalk15.yellow(s.queueState) : chalk15.dim(s.queueState),
2310
2452
  String(s.turnCount),
2311
2453
  new Date(s.startedAt).toLocaleTimeString()
2312
2454
  ])
@@ -2319,7 +2461,7 @@ function managerStatusCommand() {
2319
2461
  }
2320
2462
 
2321
2463
  // src/commands/agent.ts
2322
- import chalk15 from "chalk";
2464
+ import chalk16 from "chalk";
2323
2465
  import JSON52 from "json5";
2324
2466
  import { readFileSync as readFileSync3, existsSync as existsSync3 } from "fs";
2325
2467
  import { join as join9 } from "path";
@@ -2453,7 +2595,7 @@ async function agentShowCommand(codeName, opts) {
2453
2595
  return;
2454
2596
  }
2455
2597
  const displayName = apiAgent?.display_name ?? charter?.display_name ?? codeName;
2456
- console.log(chalk15.bold(`
2598
+ console.log(chalk16.bold(`
2457
2599
  Agent: ${codeName}`) + (displayName !== codeName ? ` (${displayName})` : "") + "\n");
2458
2600
  if (charter || apiAgent) {
2459
2601
  const agentId = apiAgent?.agent_id ?? charter?.agent_id;
@@ -2485,7 +2627,7 @@ Agent: ${codeName}`) + (displayName !== codeName ? ` (${displayName})` : "") + "
2485
2627
  info("No agent metadata available");
2486
2628
  }
2487
2629
  const filtered = opts.allChannels ? channelRows : channelRows.filter((c) => c.enabled);
2488
- console.log(chalk15.bold("\nChannels:"));
2630
+ console.log(chalk16.bold("\nChannels:"));
2489
2631
  if (filtered.length === 0) {
2490
2632
  info("(none enabled)");
2491
2633
  } else {
@@ -2501,7 +2643,7 @@ Agent: ${codeName}`) + (displayName !== codeName ? ` (${displayName})` : "") + "
2501
2643
  );
2502
2644
  }
2503
2645
  if (tools) {
2504
- console.log(chalk15.bold("\nTools:"));
2646
+ console.log(chalk16.bold("\nTools:"));
2505
2647
  if (tools.tools.length === 0) {
2506
2648
  info("(none configured)");
2507
2649
  } else {
@@ -2512,7 +2654,7 @@ Agent: ${codeName}`) + (displayName !== codeName ? ` (${displayName})` : "") + "
2512
2654
  }
2513
2655
  if (tools.global_controls) {
2514
2656
  const gc = tools.global_controls;
2515
- console.log(chalk15.bold("\nGlobal Controls:"));
2657
+ console.log(chalk16.bold("\nGlobal Controls:"));
2516
2658
  info(`Network: ${gc.default_network_policy === "deny" ? "deny-by-default" : "allow-by-default"}`);
2517
2659
  info(`Timeout: ${gc.default_timeout_ms}ms`);
2518
2660
  info(`Rate: ${gc.default_rate_limit_rpm} rpm`);
@@ -2528,7 +2670,7 @@ function formatTimestamp(iso) {
2528
2670
  }
2529
2671
 
2530
2672
  // src/commands/kanban-recurring.ts
2531
- import chalk16 from "chalk";
2673
+ import chalk17 from "chalk";
2532
2674
  import ora12 from "ora";
2533
2675
  async function resolveAgentId(codeName) {
2534
2676
  try {
@@ -2540,10 +2682,10 @@ async function resolveAgentId(codeName) {
2540
2682
  }
2541
2683
  }
2542
2684
  function priorityLabel(p) {
2543
- return p === 1 ? chalk16.red("HIGH") : p === 3 ? chalk16.dim("LOW") : chalk16.yellow("MED");
2685
+ return p === 1 ? chalk17.red("HIGH") : p === 3 ? chalk17.dim("LOW") : chalk17.yellow("MED");
2544
2686
  }
2545
2687
  function formatSpawnTime(isoDate, timezone) {
2546
- if (!isoDate) return chalk16.dim("\u2014");
2688
+ if (!isoDate) return chalk17.dim("\u2014");
2547
2689
  try {
2548
2690
  return new Intl.DateTimeFormat("en-AU", {
2549
2691
  dateStyle: "medium",
@@ -2608,8 +2750,8 @@ async function kanbanRecurringAddCommand(title, opts) {
2608
2750
  jsonOutput({ ok: true, template: data.template });
2609
2751
  return;
2610
2752
  }
2611
- success(`Recurring task created: ${chalk16.bold(title)}`);
2612
- info(`Schedule: ${chalk16.cyan(data.template.natural_language ?? data.template.expression ?? data.template.every_interval ?? "")}`);
2753
+ success(`Recurring task created: ${chalk17.bold(title)}`);
2754
+ info(`Schedule: ${chalk17.cyan(data.template.natural_language ?? data.template.expression ?? data.template.every_interval ?? "")}`);
2613
2755
  info(`Next spawn: ${formatSpawnTime(data.template.next_spawn_at, data.template.timezone)}`);
2614
2756
  info(`Timezone: ${data.template.timezone}`);
2615
2757
  } catch (err) {
@@ -2652,7 +2794,7 @@ async function kanbanRecurringListCommand(opts) {
2652
2794
  t.title,
2653
2795
  t.natural_language ?? t.expression ?? t.every_interval ?? "\u2014",
2654
2796
  priorityLabel(t.priority),
2655
- t.enabled ? chalk16.green("Active") : chalk16.dim("Disabled"),
2797
+ t.enabled ? chalk17.green("Active") : chalk17.dim("Disabled"),
2656
2798
  formatSpawnTime(t.next_spawn_at, t.timezone),
2657
2799
  String(t.spawn_count)
2658
2800
  ]);
@@ -2709,7 +2851,7 @@ async function kanbanRecurringDisableCommand(titleOrId, opts) {
2709
2851
  if (json) {
2710
2852
  jsonOutput({ ok: true, id: match.id, title: match.title, enabled: false });
2711
2853
  } else {
2712
- success(`Disabled: ${chalk16.bold(match.title)}`);
2854
+ success(`Disabled: ${chalk17.bold(match.title)}`);
2713
2855
  }
2714
2856
  } catch (err) {
2715
2857
  spinner.fail("Failed to disable recurring template");
@@ -2726,7 +2868,7 @@ async function kanbanRecurringDisableCommand(titleOrId, opts) {
2726
2868
  import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "fs";
2727
2869
  import { join as join10, dirname } from "path";
2728
2870
  import { homedir as homedir2 } from "os";
2729
- import chalk17 from "chalk";
2871
+ import chalk18 from "chalk";
2730
2872
  import ora13 from "ora";
2731
2873
  function detectShellProfile() {
2732
2874
  const shell = process.env["SHELL"] ?? "";
@@ -2779,7 +2921,7 @@ async function setupCommand(token) {
2779
2921
  if (!apiUrl) {
2780
2922
  apiUrl = "https://api.augmented.team";
2781
2923
  if (!json) {
2782
- info(`No AGT_HOST set \u2014 using default: ${chalk17.bold(apiUrl)}`);
2924
+ info(`No AGT_HOST set \u2014 using default: ${chalk18.bold(apiUrl)}`);
2783
2925
  }
2784
2926
  }
2785
2927
  const spinner = ora13({ text: "Exchanging provisioning token\u2026", isSilent: json });
@@ -2816,11 +2958,11 @@ async function setupCommand(token) {
2816
2958
  const exchange = await exchangeApiKey(setupResult.api_key);
2817
2959
  verifySpinner.succeed("Connection verified");
2818
2960
  if (!json) {
2819
- info(`Host: ${chalk17.bold(setupResult.host_name)}`);
2961
+ info(`Host: ${chalk18.bold(setupResult.host_name)}`);
2820
2962
  info(`Host ID: ${exchange.hostId}`);
2821
- info(`Team: ${chalk17.bold(exchange.teamSlug ?? setupResult.team_slug ?? "unknown")}`);
2963
+ info(`Team: ${chalk18.bold(exchange.teamSlug ?? setupResult.team_slug ?? "unknown")}`);
2822
2964
  if (exchange.userEmail) {
2823
- info(`User: ${chalk17.bold(exchange.userEmail)}`);
2965
+ info(`User: ${chalk18.bold(exchange.userEmail)}`);
2824
2966
  }
2825
2967
  }
2826
2968
  } catch (err) {
@@ -2859,7 +3001,7 @@ async function setupCommand(token) {
2859
3001
  writeFileSync5(profilePath, updated.endsWith("\n") ? updated : `${updated}
2860
3002
  `);
2861
3003
  if (!json) {
2862
- success(`Environment variables written to ${chalk17.bold(profilePath)}`);
3004
+ success(`Environment variables written to ${chalk18.bold(profilePath)}`);
2863
3005
  }
2864
3006
  const managerSpinner = ora13({ text: "Starting manager daemon\u2026", isSilent: json });
2865
3007
  managerSpinner.start();
@@ -2886,20 +3028,20 @@ async function setupCommand(token) {
2886
3028
  });
2887
3029
  } else {
2888
3030
  console.log();
2889
- console.log(chalk17.green.bold(" Setup complete!"));
3031
+ console.log(chalk18.green.bold(" Setup complete!"));
2890
3032
  console.log();
2891
3033
  if (setupResult.agents.length > 0) {
2892
- info(`Agents: ${setupResult.agents.map((a) => chalk17.cyan(a)).join(", ")}`);
3034
+ info(`Agents: ${setupResult.agents.map((a) => chalk18.cyan(a)).join(", ")}`);
2893
3035
  } else {
2894
3036
  info("No agents assigned yet. Assign agents in the dashboard or with: agt host assign");
2895
3037
  }
2896
3038
  console.log();
2897
- info(`Restart your shell or run: ${chalk17.bold(`source ${profilePath}`)}`);
3039
+ info(`Restart your shell or run: ${chalk18.bold(`source ${profilePath}`)}`);
2898
3040
  }
2899
3041
  }
2900
3042
 
2901
3043
  // src/commands/kanban.ts
2902
- import chalk18 from "chalk";
3044
+ import chalk19 from "chalk";
2903
3045
  import ora14 from "ora";
2904
3046
  async function resolveAgentId2(codeName) {
2905
3047
  try {
@@ -2910,14 +3052,14 @@ async function resolveAgentId2(codeName) {
2910
3052
  }
2911
3053
  }
2912
3054
  function priorityLabel2(p) {
2913
- return p === 1 ? chalk18.red("HIGH") : p === 3 ? chalk18.dim("LOW") : chalk18.yellow("MED");
3055
+ return p === 1 ? chalk19.red("HIGH") : p === 3 ? chalk19.dim("LOW") : chalk19.yellow("MED");
2914
3056
  }
2915
3057
  function statusLabel(s) {
2916
3058
  const map = {
2917
- in_progress: chalk18.blue("In Progress"),
2918
- today: chalk18.green("Today"),
2919
- backlog: chalk18.dim("Backlog"),
2920
- done: chalk18.gray("Done")
3059
+ in_progress: chalk19.blue("In Progress"),
3060
+ today: chalk19.green("Today"),
3061
+ backlog: chalk19.dim("Backlog"),
3062
+ done: chalk19.gray("Done")
2921
3063
  };
2922
3064
  return map[s] ?? s;
2923
3065
  }
@@ -2953,7 +3095,7 @@ async function kanbanListCommand(opts) {
2953
3095
  item.estimated_minutes ? `~${item.estimated_minutes}min` : "",
2954
3096
  item.id.slice(0, 8)
2955
3097
  ]);
2956
- console.log(chalk18.bold(`
3098
+ console.log(chalk19.bold(`
2957
3099
  Kanban: ${opts.agent}
2958
3100
  `));
2959
3101
  table(["Pri", "Status", "Title", "Est", "ID"], rows);
@@ -3193,7 +3335,7 @@ function getAcpAgent(name) {
3193
3335
  }
3194
3336
 
3195
3337
  // ../../packages/core/dist/acp/client.js
3196
- import { spawn } from "child_process";
3338
+ import { spawn as spawn2 } from "child_process";
3197
3339
  function resolveAgentCommand(agentName) {
3198
3340
  const adapter = getAcpAgent(agentName);
3199
3341
  if (adapter) {
@@ -3209,7 +3351,7 @@ function resolveAgentCommand(agentName) {
3209
3351
  }
3210
3352
  async function runAcpx(args, options = {}) {
3211
3353
  return new Promise((resolve2) => {
3212
- const child = spawn("acpx", args, {
3354
+ const child = spawn2("acpx", args, {
3213
3355
  cwd: options.cwd,
3214
3356
  stdio: ["pipe", "pipe", "pipe"],
3215
3357
  env: { ...process.env }
@@ -3409,9 +3551,9 @@ async function acpxCloseCommand(agent2, _opts, cmd) {
3409
3551
 
3410
3552
  // src/commands/update.ts
3411
3553
  import { execSync } from "child_process";
3412
- import chalk19 from "chalk";
3554
+ import chalk20 from "chalk";
3413
3555
  import ora15 from "ora";
3414
- var cliVersion = true ? "0.10.7" : "dev";
3556
+ var cliVersion = true ? "0.10.9" : "dev";
3415
3557
  async function fetchLatestVersion() {
3416
3558
  const host2 = getHost();
3417
3559
  if (!host2) return null;
@@ -3490,13 +3632,13 @@ async function updateCommand(opts = {}) {
3490
3632
  if (json) {
3491
3633
  jsonOutput({ ok: true, current: cliVersion, latest: versionInfo.latest, update_available: false });
3492
3634
  } else {
3493
- success(`You're on the latest version (${chalk19.bold(cliVersion)})`);
3635
+ success(`You're on the latest version (${chalk20.bold(cliVersion)})`);
3494
3636
  }
3495
3637
  return;
3496
3638
  }
3497
3639
  spinner.stop();
3498
3640
  if (!json) {
3499
- info(`Update available: ${chalk19.dim(cliVersion)} \u2192 ${chalk19.bold.green(versionInfo.latest)}`);
3641
+ info(`Update available: ${chalk20.dim(cliVersion)} \u2192 ${chalk20.bold.green(versionInfo.latest)}`);
3500
3642
  if (versionInfo.changelog_url) {
3501
3643
  info(`Changelog: ${versionInfo.changelog_url}`);
3502
3644
  }
@@ -3507,16 +3649,16 @@ async function updateCommand(opts = {}) {
3507
3649
  if (!json) {
3508
3650
  warn("Active processes detected:");
3509
3651
  if (managerPid) {
3510
- console.error(chalk19.yellow(` \u2022 Manager process running (PID ${managerPid})`));
3652
+ console.error(chalk20.yellow(` \u2022 Manager process running (PID ${managerPid})`));
3511
3653
  }
3512
3654
  if (tmuxSessions.length > 0) {
3513
- console.error(chalk19.yellow(` \u2022 ${tmuxSessions.length} active agent session(s): ${tmuxSessions.join(", ")}`));
3655
+ console.error(chalk20.yellow(` \u2022 ${tmuxSessions.length} active agent session(s): ${tmuxSessions.join(", ")}`));
3514
3656
  }
3515
3657
  console.error();
3516
3658
  warn("Updating while the manager is running will leave it on the old version until restarted.");
3517
3659
  warn("Active agent sessions will continue with stale MCP servers.");
3518
3660
  console.error();
3519
- info(`Run ${chalk19.bold("agt update --force")} to update anyway, then restart the manager.`);
3661
+ info(`Run ${chalk20.bold("agt update --force")} to update anyway, then restart the manager.`);
3520
3662
  } else {
3521
3663
  jsonOutput({
3522
3664
  ok: false,
@@ -3548,8 +3690,8 @@ async function updateCommand(opts = {}) {
3548
3690
  updated: true
3549
3691
  });
3550
3692
  } else {
3551
- success(`Updated to ${chalk19.bold(versionInfo.latest)}`);
3552
- info(`If you have a running manager, restart it: ${chalk19.bold("agt manager stop && agt manager start")}`);
3693
+ success(`Updated to ${chalk20.bold(versionInfo.latest)}`);
3694
+ info(`If you have a running manager, restart it: ${chalk20.bold("agt manager stop && agt manager start")}`);
3553
3695
  }
3554
3696
  } catch (err) {
3555
3697
  updateSpinner.fail("Update failed");
@@ -3575,8 +3717,8 @@ async function checkForUpdateOnStartup() {
3575
3717
  if (!versionInfo) return;
3576
3718
  if (isNewerVersion(cliVersion, versionInfo.latest)) {
3577
3719
  console.error(
3578
- chalk19.yellow(`
3579
- Update available: ${cliVersion} \u2192 ${versionInfo.latest}. Run ${chalk19.bold("agt update")} to install.`) + chalk19.dim("\n Note: Restart the manager after updating.\n")
3720
+ chalk20.yellow(`
3721
+ Update available: ${cliVersion} \u2192 ${versionInfo.latest}. Run ${chalk20.bold("agt update")} to install.`) + chalk20.dim("\n Note: Restart the manager after updating.\n")
3580
3722
  );
3581
3723
  }
3582
3724
  } catch {
@@ -3584,7 +3726,7 @@ async function checkForUpdateOnStartup() {
3584
3726
  }
3585
3727
 
3586
3728
  // src/commands/plugin.ts
3587
- import chalk20 from "chalk";
3729
+ import chalk21 from "chalk";
3588
3730
  import ora16 from "ora";
3589
3731
  async function pluginListCommand() {
3590
3732
  const json = isJsonMode();
@@ -3600,11 +3742,11 @@ async function pluginListCommand() {
3600
3742
  info("No plugins found for this team.");
3601
3743
  return;
3602
3744
  }
3603
- console.log(chalk20.bold("\nAvailable Plugins:\n"));
3745
+ console.log(chalk21.bold("\nAvailable Plugins:\n"));
3604
3746
  for (const p of data) {
3605
- const statusColor = p.status === "published" ? chalk20.green : p.status === "archived" ? chalk20.gray : chalk20.yellow;
3747
+ const statusColor = p.status === "published" ? chalk21.green : p.status === "archived" ? chalk21.gray : chalk21.yellow;
3606
3748
  console.log(
3607
- ` ${chalk20.bold(p.name)} ${chalk20.dim(`(${p.slug})`)} ${statusColor(p.status)} v${p.version} ${chalk20.dim(`${p.skills?.length ?? 0} skills, ${p.defined_scopes?.length ?? 0} scopes`)}`
3749
+ ` ${chalk21.bold(p.name)} ${chalk21.dim(`(${p.slug})`)} ${statusColor(p.status)} v${p.version} ${chalk21.dim(`${p.skills?.length ?? 0} skills, ${p.defined_scopes?.length ?? 0} scopes`)}`
3608
3750
  );
3609
3751
  }
3610
3752
  console.log();
@@ -3631,21 +3773,21 @@ async function pluginShowCommand(slug) {
3631
3773
  jsonOutput({ plugin: plugin2, scopes });
3632
3774
  return;
3633
3775
  }
3634
- console.log(chalk20.bold(`
3635
- ${plugin2.name}`), chalk20.dim(`(${plugin2.slug})`));
3636
- if (plugin2.description) console.log(chalk20.dim(plugin2.description));
3776
+ console.log(chalk21.bold(`
3777
+ ${plugin2.name}`), chalk21.dim(`(${plugin2.slug})`));
3778
+ if (plugin2.description) console.log(chalk21.dim(plugin2.description));
3637
3779
  console.log();
3638
3780
  console.log(` Status: ${plugin2.status} v${plugin2.version}`);
3639
3781
  console.log(` Category: ${plugin2.category}`);
3640
3782
  console.log(` Toolkits: ${plugin2.required_toolkits.join(", ") || "none"}`);
3641
3783
  console.log(` Skills: ${plugin2.skills?.length ?? 0}`);
3642
3784
  if (scopes.length > 0) {
3643
- console.log(chalk20.bold("\n Permission Scopes:\n"));
3785
+ console.log(chalk21.bold("\n Permission Scopes:\n"));
3644
3786
  for (const s of scopes) {
3645
- const roleColor = s.can_grant ? chalk20.green : chalk20.red;
3646
- const overrideTag = s.is_overridden ? chalk20.cyan(" [team override]") : "";
3787
+ const roleColor = s.can_grant ? chalk21.green : chalk21.red;
3788
+ const overrideTag = s.is_overridden ? chalk21.cyan(" [team override]") : "";
3647
3789
  console.log(
3648
- ` ${chalk20.bold(s.id)} ${s.name} min: ${roleColor(s.effective_min_role)}${overrideTag} ${s.can_grant ? chalk20.green("\u2713 grantable") : chalk20.red("\u2717 needs approval")}`
3790
+ ` ${chalk21.bold(s.id)} ${s.name} min: ${roleColor(s.effective_min_role)}${overrideTag} ${s.can_grant ? chalk21.green("\u2713 grantable") : chalk21.red("\u2717 needs approval")}`
3649
3791
  );
3650
3792
  }
3651
3793
  }
@@ -3696,7 +3838,7 @@ async function pluginInstallCommand(slug, options) {
3696
3838
  const needsApproval = err.body["needs_approval"];
3697
3839
  error("Some scopes exceed your role ceiling:");
3698
3840
  for (const s of needsApproval) {
3699
- console.log(chalk20.yellow(` - ${s}`));
3841
+ console.log(chalk21.yellow(` - ${s}`));
3700
3842
  }
3701
3843
  info("To request elevated scopes, use the web dashboard or contact your team admin.");
3702
3844
  process.exitCode = 1;
@@ -3750,10 +3892,10 @@ async function pluginRequestsCommand() {
3750
3892
  info("No pending scope requests.");
3751
3893
  return;
3752
3894
  }
3753
- console.log(chalk20.bold("\nPending Scope Requests:\n"));
3895
+ console.log(chalk21.bold("\nPending Scope Requests:\n"));
3754
3896
  for (const r of requests) {
3755
- console.log(` ${chalk20.bold(r.id)} scopes: ${r.requested_scopes.join(", ")}`);
3756
- if (r.reason) console.log(` reason: ${chalk20.dim(r.reason)}`);
3897
+ console.log(` ${chalk21.bold(r.id)} scopes: ${r.requested_scopes.join(", ")}`);
3898
+ if (r.reason) console.log(` reason: ${chalk21.dim(r.reason)}`);
3757
3899
  console.log(` status: ${r.status} requested: ${r.created_at}`);
3758
3900
  console.log();
3759
3901
  }
@@ -3810,7 +3952,7 @@ function handleError(err) {
3810
3952
  }
3811
3953
 
3812
3954
  // src/bin/agt.ts
3813
- var cliVersion2 = true ? "0.10.7" : "dev";
3955
+ var cliVersion2 = true ? "0.10.9" : "dev";
3814
3956
  var program = new Command();
3815
3957
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
3816
3958
  program.hook("preAction", (thisCommand) => {
@@ -3850,6 +3992,12 @@ host.command("unassign <host-name> <agent-code-names...>").description("Unassign
3850
3992
  host.command("agents [host-name]").description("List agents assigned to a host (omit name to auto-resolve from AGT_API_KEY)").action(hostAgentsCommand);
3851
3993
  host.command("rotate-key <host-name>").description("Rotate the API key for a host (revokes the old key)").action(hostRotateKeyCommand);
3852
3994
  host.command("decommission <host-name>").description("Decommission a host (revokes key, marks inactive)").action(hostDecommissionCommand);
3995
+ host.command("pair <host-name>").description("Start an SSM port-forward + shell to re-authenticate Claude Code on an EC2 host").option("--port <port>", "Local port to forward for the OAuth callback", "54545").option("--no-shell", "Start the tunnel only; do not open an interactive shell").action(
3996
+ (hostName, opts) => hostPairCommand(hostName, {
3997
+ port: opts.port,
3998
+ noShell: opts.shell === false
3999
+ })
4000
+ );
3853
4001
  var manager = program.command("manager").description("Host config sync daemon \u2014 keeps local agent files in sync with API");
3854
4002
  manager.command("start").description("Start the manager daemon (polls API for config changes and detects local drift)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files", join11(homedir3(), ".augmented")).action(managerStartCommand);
3855
4003
  manager.command("stop").description("Stop the running manager daemon").action(managerStopCommand);