@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 +231 -83
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-VDUA5FEW.js → chunk-PZG4XPJV.js} +5 -8
- package/dist/chunk-PZG4XPJV.js.map +1 -0
- package/dist/lib/manager-worker.js +192 -83
- package/dist/lib/manager-worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-VDUA5FEW.js.map +0 -1
package/dist/bin/agt.js
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
resolveChannels,
|
|
33
33
|
serializeManifestForSlackCli,
|
|
34
34
|
setActiveTeam
|
|
35
|
-
} from "../chunk-
|
|
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()
|
|
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()
|
|
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/
|
|
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(
|
|
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 ??
|
|
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 =
|
|
2424
|
+
let gwStatus = chalk15.dim("\u2014");
|
|
2283
2425
|
if (a.gatewayRunning) {
|
|
2284
|
-
gwStatus =
|
|
2426
|
+
gwStatus = chalk15.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
|
|
2285
2427
|
} else if (a.gatewayPort) {
|
|
2286
|
-
gwStatus =
|
|
2428
|
+
gwStatus = chalk15.red(`:${a.gatewayPort} (down)`);
|
|
2287
2429
|
}
|
|
2288
2430
|
return [
|
|
2289
2431
|
a.codeName,
|
|
2290
|
-
a.status === "active" ?
|
|
2291
|
-
a.charterVersion ||
|
|
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() :
|
|
2294
|
-
a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() :
|
|
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(
|
|
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 ??
|
|
2309
|
-
s.queueState === "running" ?
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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 ?
|
|
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
|
|
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: ${
|
|
2612
|
-
info(`Schedule: ${
|
|
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 ?
|
|
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: ${
|
|
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
|
|
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: ${
|
|
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: ${
|
|
2961
|
+
info(`Host: ${chalk18.bold(setupResult.host_name)}`);
|
|
2820
2962
|
info(`Host ID: ${exchange.hostId}`);
|
|
2821
|
-
info(`Team: ${
|
|
2963
|
+
info(`Team: ${chalk18.bold(exchange.teamSlug ?? setupResult.team_slug ?? "unknown")}`);
|
|
2822
2964
|
if (exchange.userEmail) {
|
|
2823
|
-
info(`User: ${
|
|
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 ${
|
|
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(
|
|
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) =>
|
|
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: ${
|
|
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
|
|
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 ?
|
|
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:
|
|
2918
|
-
today:
|
|
2919
|
-
backlog:
|
|
2920
|
-
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(
|
|
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 =
|
|
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
|
|
3554
|
+
import chalk20 from "chalk";
|
|
3413
3555
|
import ora15 from "ora";
|
|
3414
|
-
var cliVersion = true ? "0.10.
|
|
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 (${
|
|
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: ${
|
|
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(
|
|
3652
|
+
console.error(chalk20.yellow(` \u2022 Manager process running (PID ${managerPid})`));
|
|
3511
3653
|
}
|
|
3512
3654
|
if (tmuxSessions.length > 0) {
|
|
3513
|
-
console.error(
|
|
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 ${
|
|
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 ${
|
|
3552
|
-
info(`If you have a running manager, restart it: ${
|
|
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
|
-
|
|
3579
|
-
Update available: ${cliVersion} \u2192 ${versionInfo.latest}. Run ${
|
|
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
|
|
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(
|
|
3745
|
+
console.log(chalk21.bold("\nAvailable Plugins:\n"));
|
|
3604
3746
|
for (const p of data) {
|
|
3605
|
-
const statusColor = p.status === "published" ?
|
|
3747
|
+
const statusColor = p.status === "published" ? chalk21.green : p.status === "archived" ? chalk21.gray : chalk21.yellow;
|
|
3606
3748
|
console.log(
|
|
3607
|
-
` ${
|
|
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(
|
|
3635
|
-
${plugin2.name}`),
|
|
3636
|
-
if (plugin2.description) console.log(
|
|
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(
|
|
3785
|
+
console.log(chalk21.bold("\n Permission Scopes:\n"));
|
|
3644
3786
|
for (const s of scopes) {
|
|
3645
|
-
const roleColor = s.can_grant ?
|
|
3646
|
-
const overrideTag = s.is_overridden ?
|
|
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
|
-
` ${
|
|
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(
|
|
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(
|
|
3895
|
+
console.log(chalk21.bold("\nPending Scope Requests:\n"));
|
|
3754
3896
|
for (const r of requests) {
|
|
3755
|
-
console.log(` ${
|
|
3756
|
-
if (r.reason) console.log(` 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.
|
|
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);
|