@integrity-labs/agt-cli 0.27.65 → 0.27.67
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 +186 -15
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-CF3SEPE3.js → chunk-DA3KY3D2.js} +107 -23
- package/dist/chunk-DA3KY3D2.js.map +1 -0
- package/dist/{chunk-UMFTYZO7.js → chunk-EYWW624B.js} +250 -163
- package/dist/chunk-EYWW624B.js.map +1 -0
- package/dist/{chunk-PM3CC2SJ.js → chunk-KPD5KJY7.js} +80 -1
- package/dist/chunk-KPD5KJY7.js.map +1 -0
- package/dist/{claude-pair-runtime-R7PGK4LT.js → claude-pair-runtime-6GSA5KRH.js} +2 -2
- package/dist/lib/manager-worker.js +30 -9
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-BN3PGV3A.js → persistent-session-2WJIWIMQ.js} +3 -3
- package/dist/{responsiveness-probe-QR6VWUKX.js → responsiveness-probe-RAWYP7LQ.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-CF3SEPE3.js.map +0 -1
- package/dist/chunk-PM3CC2SJ.js.map +0 -1
- package/dist/chunk-UMFTYZO7.js.map +0 -1
- /package/dist/{claude-pair-runtime-R7PGK4LT.js.map → claude-pair-runtime-6GSA5KRH.js.map} +0 -0
- /package/dist/{persistent-session-BN3PGV3A.js.map → persistent-session-2WJIWIMQ.js.map} +0 -0
- /package/dist/{responsiveness-probe-QR6VWUKX.js.map → responsiveness-probe-RAWYP7LQ.js.map} +0 -0
package/dist/bin/agt.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
success,
|
|
28
28
|
table,
|
|
29
29
|
warn
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-EYWW624B.js";
|
|
31
31
|
import {
|
|
32
32
|
CHANNEL_REGISTRY,
|
|
33
33
|
DEPLOYMENT_TEMPLATES,
|
|
@@ -53,11 +53,11 @@ import {
|
|
|
53
53
|
renderTemplate,
|
|
54
54
|
resolveChannels,
|
|
55
55
|
serializeManifestForSlackCli
|
|
56
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-KPD5KJY7.js";
|
|
57
57
|
|
|
58
58
|
// src/bin/agt.ts
|
|
59
|
-
import { join as
|
|
60
|
-
import { homedir as
|
|
59
|
+
import { join as join20 } from "path";
|
|
60
|
+
import { homedir as homedir9 } from "os";
|
|
61
61
|
import { Command } from "commander";
|
|
62
62
|
|
|
63
63
|
// src/commands/whoami.ts
|
|
@@ -551,11 +551,11 @@ async function lintCommand(path) {
|
|
|
551
551
|
process.exitCode = 1;
|
|
552
552
|
return;
|
|
553
553
|
}
|
|
554
|
-
const { readdirSync:
|
|
555
|
-
const entries =
|
|
554
|
+
const { readdirSync: readdirSync7, statSync: statSync5 } = await import("fs");
|
|
555
|
+
const entries = readdirSync7(augmentedDir);
|
|
556
556
|
for (const entry of entries) {
|
|
557
557
|
const entryPath = join2(augmentedDir, entry);
|
|
558
|
-
if (
|
|
558
|
+
if (statSync5(entryPath).isDirectory()) {
|
|
559
559
|
dirs.push({ name: entry, dir: entryPath });
|
|
560
560
|
}
|
|
561
561
|
}
|
|
@@ -4929,7 +4929,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
4929
4929
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
4930
4930
|
import chalk18 from "chalk";
|
|
4931
4931
|
import ora16 from "ora";
|
|
4932
|
-
var cliVersion = true ? "0.27.
|
|
4932
|
+
var cliVersion = true ? "0.27.67" : "dev";
|
|
4933
4933
|
async function fetchLatestVersion() {
|
|
4934
4934
|
const host2 = getHost();
|
|
4935
4935
|
if (!host2) return null;
|
|
@@ -5406,6 +5406,176 @@ async function auditMcpRenderCommand(options = {}) {
|
|
|
5406
5406
|
}
|
|
5407
5407
|
}
|
|
5408
5408
|
|
|
5409
|
+
// src/commands/audit-secrets.ts
|
|
5410
|
+
import { homedir as homedir8 } from "os";
|
|
5411
|
+
import { join as join19 } from "path";
|
|
5412
|
+
|
|
5413
|
+
// src/lib/secret-leak-audit.ts
|
|
5414
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
5415
|
+
import { join as join18 } from "path";
|
|
5416
|
+
|
|
5417
|
+
// ../../packages/core/dist/provisioning/mcp-secret-lint.js
|
|
5418
|
+
var LITERAL_SECRET_PATTERNS = [
|
|
5419
|
+
// Slack bot token — `xoxb-<workspace>-<...>`
|
|
5420
|
+
{ name: "slack_bot_token", re: /^xoxb-/ },
|
|
5421
|
+
// Slack app-level token (Socket Mode) — `xapp-<...>`
|
|
5422
|
+
{ name: "slack_app_token", re: /^xapp-/ },
|
|
5423
|
+
// AGT host API key — `tlk_<...>` (see claudecode-plugin-augmented README).
|
|
5424
|
+
{ name: "agt_host_api_key", re: /^tlk_/ },
|
|
5425
|
+
// Composio / generic api-key prefix — `ak_<...>`
|
|
5426
|
+
{ name: "composio_api_key", re: /^ak_/ },
|
|
5427
|
+
// Telegram bot token — `<10-digit bot id>:AAE<...>` (BotFather format).
|
|
5428
|
+
{ name: "telegram_bot_token", re: /^\d{10}:AAE/ },
|
|
5429
|
+
// ENG-5901 extension beyond the original AC's five patterns: a literal
|
|
5430
|
+
// JWT (`eyJ...`) is the shape of a leaked AGT_API_KEY, which the
|
|
5431
|
+
// value-prefix patterns above would otherwise miss. Header values often
|
|
5432
|
+
// carry it behind `Bearer ` (or a copy-pasted `Authorization: Bearer `),
|
|
5433
|
+
// so those prefixes are optionally consumed (CodeRabbit #1731).
|
|
5434
|
+
// Templates (`Bearer ${AGT_API_KEY}`) and concrete non-secret values
|
|
5435
|
+
// (UUIDs, hosts) never put `eyJ` after the prefix, so this stays
|
|
5436
|
+
// false-positive-safe inside .mcp.json.
|
|
5437
|
+
{ name: "jwt_agt_api_key", re: /^(?:authorization:\s*)?(?:bearer\s+)?eyJ[A-Za-z0-9_-]+\./i }
|
|
5438
|
+
];
|
|
5439
|
+
|
|
5440
|
+
// src/lib/secret-leak-audit.ts
|
|
5441
|
+
var SECRET_KEY_NAME_RE = /TOKEN|KEY|SECRET|BEARER|PASSWORD/i;
|
|
5442
|
+
function isTemplated(value) {
|
|
5443
|
+
return value.includes("${");
|
|
5444
|
+
}
|
|
5445
|
+
function matchesKnownSecretShape(value) {
|
|
5446
|
+
return LITERAL_SECRET_PATTERNS.some(({ re }) => re.test(value));
|
|
5447
|
+
}
|
|
5448
|
+
function isWorldReadable(mode) {
|
|
5449
|
+
return (mode & 63) !== 0;
|
|
5450
|
+
}
|
|
5451
|
+
function octal(mode) {
|
|
5452
|
+
return `0${(mode & 511).toString(8)}`;
|
|
5453
|
+
}
|
|
5454
|
+
function scanMcpFile(file, agent2, findings) {
|
|
5455
|
+
let mode = null;
|
|
5456
|
+
try {
|
|
5457
|
+
mode = statSync4(file).mode;
|
|
5458
|
+
} catch {
|
|
5459
|
+
return;
|
|
5460
|
+
}
|
|
5461
|
+
if (mode !== null && isWorldReadable(mode)) {
|
|
5462
|
+
findings.push({ kind: "world-readable-secret-file", file, agent: agent2, mode: octal(mode) });
|
|
5463
|
+
}
|
|
5464
|
+
let parsed;
|
|
5465
|
+
try {
|
|
5466
|
+
parsed = JSON.parse(readFileSync11(file, "utf-8"));
|
|
5467
|
+
} catch {
|
|
5468
|
+
return;
|
|
5469
|
+
}
|
|
5470
|
+
const servers = parsed?.mcpServers;
|
|
5471
|
+
if (typeof servers !== "object" || servers === null) return;
|
|
5472
|
+
for (const [server, raw] of Object.entries(servers)) {
|
|
5473
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
5474
|
+
const entry = raw;
|
|
5475
|
+
const blocks = [
|
|
5476
|
+
[entry.env, "env"],
|
|
5477
|
+
[entry.headers, "header"]
|
|
5478
|
+
];
|
|
5479
|
+
for (const [block, location] of blocks) {
|
|
5480
|
+
if (!block) continue;
|
|
5481
|
+
for (const [field, value] of Object.entries(block)) {
|
|
5482
|
+
if (typeof value !== "string" || value.length === 0) continue;
|
|
5483
|
+
if (isTemplated(value)) continue;
|
|
5484
|
+
if (!SECRET_KEY_NAME_RE.test(field) && !matchesKnownSecretShape(value)) continue;
|
|
5485
|
+
findings.push({ kind: "literal-secret-in-mcp", file, agent: agent2, server, field, location });
|
|
5486
|
+
}
|
|
5487
|
+
}
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5490
|
+
function scanEnvIntegrations(file, agent2, findings) {
|
|
5491
|
+
let mode;
|
|
5492
|
+
try {
|
|
5493
|
+
mode = statSync4(file).mode;
|
|
5494
|
+
} catch {
|
|
5495
|
+
return;
|
|
5496
|
+
}
|
|
5497
|
+
if (isWorldReadable(mode)) {
|
|
5498
|
+
findings.push({ kind: "world-readable-secret-file", file, agent: agent2, mode: octal(mode) });
|
|
5499
|
+
}
|
|
5500
|
+
}
|
|
5501
|
+
function auditSecretLeaks(augmentedRoot) {
|
|
5502
|
+
const findings = [];
|
|
5503
|
+
let agents;
|
|
5504
|
+
try {
|
|
5505
|
+
agents = readdirSync6(augmentedRoot);
|
|
5506
|
+
} catch {
|
|
5507
|
+
return findings;
|
|
5508
|
+
}
|
|
5509
|
+
for (const agent2 of agents) {
|
|
5510
|
+
const agentDir = join18(augmentedRoot, agent2);
|
|
5511
|
+
try {
|
|
5512
|
+
if (!statSync4(agentDir).isDirectory()) continue;
|
|
5513
|
+
} catch {
|
|
5514
|
+
continue;
|
|
5515
|
+
}
|
|
5516
|
+
scanMcpFile(join18(agentDir, "provision", ".mcp.json"), agent2, findings);
|
|
5517
|
+
scanMcpFile(join18(agentDir, "project", ".mcp.json"), agent2, findings);
|
|
5518
|
+
scanEnvIntegrations(join18(agentDir, ".env.integrations"), agent2, findings);
|
|
5519
|
+
}
|
|
5520
|
+
return findings;
|
|
5521
|
+
}
|
|
5522
|
+
function formatSecretFinding(f) {
|
|
5523
|
+
const parts = [
|
|
5524
|
+
"[audit-secrets]",
|
|
5525
|
+
`kind=${f.kind}`,
|
|
5526
|
+
`agent=${f.agent}`,
|
|
5527
|
+
`file=${f.file}`
|
|
5528
|
+
];
|
|
5529
|
+
if (f.server) parts.push(`server=${f.server}`);
|
|
5530
|
+
if (f.field) parts.push(`field=${f.field}`);
|
|
5531
|
+
if (f.location) parts.push(`location=${f.location}`);
|
|
5532
|
+
if (f.mode) parts.push(`mode=${f.mode}`);
|
|
5533
|
+
return parts.join(" ");
|
|
5534
|
+
}
|
|
5535
|
+
|
|
5536
|
+
// src/commands/audit-secrets.ts
|
|
5537
|
+
function describe(f) {
|
|
5538
|
+
if (f.kind === "literal-secret-in-mcp") {
|
|
5539
|
+
return `literal secret in ${f.location} field '${f.field}' of server '${f.server}'`;
|
|
5540
|
+
}
|
|
5541
|
+
return `secret file is mode ${f.mode} (expected 0600)`;
|
|
5542
|
+
}
|
|
5543
|
+
async function auditSecretsCommand(options = {}) {
|
|
5544
|
+
const root = options.root ?? join19(homedir8(), ".augmented");
|
|
5545
|
+
const findings = auditSecretLeaks(root);
|
|
5546
|
+
if (options.json) {
|
|
5547
|
+
process.stdout.write(`${JSON.stringify({ findings, root }, null, 2)}
|
|
5548
|
+
`);
|
|
5549
|
+
} else if (findings.length === 0) {
|
|
5550
|
+
process.stdout.write(
|
|
5551
|
+
`No literal secrets or world-readable secret files found under ${root}.
|
|
5552
|
+
`
|
|
5553
|
+
);
|
|
5554
|
+
} else {
|
|
5555
|
+
process.stdout.write(
|
|
5556
|
+
`Found ${findings.length} secret-handling issue${findings.length === 1 ? "" : "s"} under ${root}:
|
|
5557
|
+
|
|
5558
|
+
`
|
|
5559
|
+
);
|
|
5560
|
+
for (const f of findings) {
|
|
5561
|
+
process.stdout.write(` \u2022 [${f.agent}] ${describe(f)}
|
|
5562
|
+
`);
|
|
5563
|
+
process.stdout.write(` ${f.file}
|
|
5564
|
+
`);
|
|
5565
|
+
}
|
|
5566
|
+
process.stdout.write(
|
|
5567
|
+
"\nLiteral secrets in .mcp.json should be `${VAR}` placeholders with the raw value in .env.integrations (mode 0600). See docs/operator/credential-migration-eng5898.md.\n"
|
|
5568
|
+
);
|
|
5569
|
+
for (const f of findings) {
|
|
5570
|
+
process.stderr.write(`${formatSecretFinding(f)}
|
|
5571
|
+
`);
|
|
5572
|
+
}
|
|
5573
|
+
}
|
|
5574
|
+
if (options.strict && findings.length > 0) {
|
|
5575
|
+
process.exit(2);
|
|
5576
|
+
}
|
|
5577
|
+
}
|
|
5578
|
+
|
|
5409
5579
|
// src/commands/integration.ts
|
|
5410
5580
|
import chalk19 from "chalk";
|
|
5411
5581
|
import ora17 from "ora";
|
|
@@ -5707,7 +5877,7 @@ function handleError(err) {
|
|
|
5707
5877
|
}
|
|
5708
5878
|
|
|
5709
5879
|
// src/bin/agt.ts
|
|
5710
|
-
var cliVersion2 = true ? "0.27.
|
|
5880
|
+
var cliVersion2 = true ? "0.27.67" : "dev";
|
|
5711
5881
|
var program = new Command();
|
|
5712
5882
|
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");
|
|
5713
5883
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -5800,16 +5970,16 @@ host.command("pair <host-name>").description("Start an SSM port-forward + shell
|
|
|
5800
5970
|
})
|
|
5801
5971
|
);
|
|
5802
5972
|
var manager = program.command("manager").description("Host config sync daemon \u2014 keeps local agent files in sync with API");
|
|
5803
|
-
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",
|
|
5804
|
-
manager.command("stop").description("Stop the running manager daemon").option("--config-dir <dir>", "Config directory for agent files",
|
|
5805
|
-
manager.command("status").description("Show the current manager daemon status and discovered agents").option("--config-dir <dir>", "Config directory for agent files",
|
|
5806
|
-
manager.command("watch").description("Live TUI dashboard \u2014 per-agent boxes, drill-in, log tail. Read-only (ENG-4555).").option("--config-dir <dir>", "Config directory for agent files",
|
|
5807
|
-
manager.command("install").description("Install OS-level supervisor (launchd LaunchAgent on macOS) so the manager auto-restarts after crash, reboot, or self-update (ENG-4593)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files",
|
|
5973
|
+
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", join20(homedir9(), ".augmented")).option("--supervise", "Wrap the manager in a respawn-on-clean-exit loop so auto-upgrades can restart it transparently (ENG-4488)", false).action(managerStartCommand);
|
|
5974
|
+
manager.command("stop").description("Stop the running manager daemon").option("--config-dir <dir>", "Config directory for agent files", join20(homedir9(), ".augmented")).action(managerStopCommand);
|
|
5975
|
+
manager.command("status").description("Show the current manager daemon status and discovered agents").option("--config-dir <dir>", "Config directory for agent files", join20(homedir9(), ".augmented")).action(managerStatusCommand);
|
|
5976
|
+
manager.command("watch").description("Live TUI dashboard \u2014 per-agent boxes, drill-in, log tail. Read-only (ENG-4555).").option("--config-dir <dir>", "Config directory for agent files", join20(homedir9(), ".augmented")).option("--no-tui", "Skip the TUI and stream the manager log to stdout instead (CI / scripts)").action(managerWatchCommand);
|
|
5977
|
+
manager.command("install").description("Install OS-level supervisor (launchd LaunchAgent on macOS) so the manager auto-restarts after crash, reboot, or self-update (ENG-4593)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files", join20(homedir9(), ".augmented")).action(managerInstallCommand);
|
|
5808
5978
|
manager.command("uninstall").description("Remove the OS-level supervisor (launchctl unload + delete plist on macOS). Idempotent.").action(managerUninstallCommand);
|
|
5809
5979
|
manager.command("install-system-unit").description("Install a system-level systemd unit (Linux, root) so the manager auto-starts on every boot. For headless EC2 hosts \u2014 survives reboot without `loginctl enable-linger`. (ENG-4706)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files (defaults to /root/.augmented or /home/<user>/.augmented)").option("--user <name>", "Unix user the manager runs as", "root").action(managerInstallSystemUnitCommand);
|
|
5810
5980
|
manager.command("uninstall-system-unit").description("Remove the system-level systemd unit (Linux, root). Idempotent. (ENG-4706)").action(managerUninstallSystemUnitCommand);
|
|
5811
5981
|
var agent = program.command("agent").description("Inspect and manage agents");
|
|
5812
|
-
agent.command("show <code-name>").description("Display an agent's provisioned OpenClaw configuration").option("--config-dir <dir>", "Config directory",
|
|
5982
|
+
agent.command("show <code-name>").description("Display an agent's provisioned OpenClaw configuration").option("--config-dir <dir>", "Config directory", join20(homedir9(), ".augmented")).option("--all-channels", "Show all channels (including disabled)").action(agentShowCommand);
|
|
5813
5983
|
var kanban = program.command("kanban").description("Manage agent kanban boards");
|
|
5814
5984
|
kanban.command("list").description("List kanban board items for an agent").requiredOption("--agent <code-name>", "Agent code name").action(kanbanListCommand);
|
|
5815
5985
|
kanban.command("add <title>").description("Add a new item to an agent kanban board").requiredOption("--agent <code-name>", "Agent code name").option("--priority <1|2|3>", "Priority: 1=high, 2=medium, 3=low", "2").option("--status <status>", "Initial status: backlog | todo | in_progress", "todo").option("--description <text>", "Item description").option("--estimate <minutes>", "Estimated time in minutes").option("--deliverable <text>", "Expected output/deliverable").action(kanbanAddCommand);
|
|
@@ -5840,6 +6010,7 @@ program.command("update").description("Check for and install CLI updates").optio
|
|
|
5840
6010
|
var audit = program.command("audit").description("Operator audits \u2014 sub-agent MCP bindings, etc.");
|
|
5841
6011
|
audit.command("subagents").description("Find sub-agents whose tools allowlist would block mcp__* calls on dispatch (ENG-5897)").option("--strict", "Exit with code 2 if any findings (suitable for CI gating)").option("--json", "Emit findings as JSON to stdout").action(auditSubagentsCommand);
|
|
5842
6012
|
audit.command("mcp-render").description("Find managed agents whose subagent .md tools allowlist is stale vs .mcp.json (ENG-5922)").option("--strict", "Exit with code 2 if any findings (suitable for CI gating)").option("--json", "Emit findings as JSON to stdout").action(auditMcpRenderCommand);
|
|
6013
|
+
audit.command("secrets").description("Find literal secrets in .mcp.json and world-readable secret files (ENG-5901)").option("--strict", "Exit with code 2 if any findings (suitable for CI gating)").option("--json", "Emit findings as JSON to stdout").action(auditSecretsCommand);
|
|
5843
6014
|
var skipUpdateCheck = process.argv.includes("--skip-update-check") || process.argv.includes("--json") || process.argv[2] === "update";
|
|
5844
6015
|
if (!skipUpdateCheck) {
|
|
5845
6016
|
checkForUpdateOnStartup().catch(() => {
|