@integrity-labs/agt-cli 0.27.36 → 0.27.38
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 +157 -14
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-LASXZZS6.js → chunk-NX5MXIFQ.js} +1 -1
- package/dist/lib/manager-worker.js +36 -25
- package/dist/lib/manager-worker.js.map +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-LASXZZS6.js.map → chunk-NX5MXIFQ.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-NX5MXIFQ.js";
|
|
31
31
|
import {
|
|
32
32
|
CHANNEL_REGISTRY,
|
|
33
33
|
DEPLOYMENT_TEMPLATES,
|
|
@@ -56,8 +56,8 @@ import {
|
|
|
56
56
|
} from "../chunk-GVM2KJOA.js";
|
|
57
57
|
|
|
58
58
|
// src/bin/agt.ts
|
|
59
|
-
import { join as
|
|
60
|
-
import { homedir as
|
|
59
|
+
import { join as join17 } from "path";
|
|
60
|
+
import { homedir as homedir7 } 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: readdirSync4, statSync: statSync3 } = await import("fs");
|
|
555
|
+
const entries = readdirSync4(augmentedDir);
|
|
556
556
|
for (const entry of entries) {
|
|
557
557
|
const entryPath = join2(augmentedDir, entry);
|
|
558
|
-
if (
|
|
558
|
+
if (statSync3(entryPath).isDirectory()) {
|
|
559
559
|
dirs.push({ name: entry, dir: entryPath });
|
|
560
560
|
}
|
|
561
561
|
}
|
|
@@ -4658,7 +4658,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
4658
4658
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
4659
4659
|
import chalk18 from "chalk";
|
|
4660
4660
|
import ora16 from "ora";
|
|
4661
|
-
var cliVersion = true ? "0.27.
|
|
4661
|
+
var cliVersion = true ? "0.27.38" : "dev";
|
|
4662
4662
|
async function fetchLatestVersion() {
|
|
4663
4663
|
const host2 = getHost();
|
|
4664
4664
|
if (!host2) return null;
|
|
@@ -4889,6 +4889,147 @@ async function checkForUpdateOnStartup() {
|
|
|
4889
4889
|
}
|
|
4890
4890
|
}
|
|
4891
4891
|
|
|
4892
|
+
// src/commands/audit-subagents.ts
|
|
4893
|
+
import { homedir as homedir6 } from "os";
|
|
4894
|
+
import { join as join16 } from "path";
|
|
4895
|
+
|
|
4896
|
+
// src/lib/subagent-mcp-audit.ts
|
|
4897
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
4898
|
+
import { join as join15 } from "path";
|
|
4899
|
+
function parseFrontmatter(content) {
|
|
4900
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
4901
|
+
if (!match) return null;
|
|
4902
|
+
const out = {};
|
|
4903
|
+
const lines = match[1].split(/\r?\n/);
|
|
4904
|
+
for (let i = 0; i < lines.length; i++) {
|
|
4905
|
+
const line = lines[i];
|
|
4906
|
+
const m = line.match(/^(name|tools|background):\s*(.*)$/);
|
|
4907
|
+
if (!m) continue;
|
|
4908
|
+
const [, key, rawValue] = m;
|
|
4909
|
+
const trimmed = rawValue.trim();
|
|
4910
|
+
if (key === "tools" && trimmed === "") {
|
|
4911
|
+
const items = [];
|
|
4912
|
+
let j = i + 1;
|
|
4913
|
+
while (j < lines.length) {
|
|
4914
|
+
const nextRaw = lines[j];
|
|
4915
|
+
const itemMatch = nextRaw.match(/^(\s+)-\s*(.+?)\s*$/);
|
|
4916
|
+
if (!itemMatch) break;
|
|
4917
|
+
items.push(itemMatch[2].replace(/^['"](.*)['"]$/, "$1"));
|
|
4918
|
+
j++;
|
|
4919
|
+
}
|
|
4920
|
+
if (items.length > 0) {
|
|
4921
|
+
out.tools = items.join(", ");
|
|
4922
|
+
i = j - 1;
|
|
4923
|
+
continue;
|
|
4924
|
+
}
|
|
4925
|
+
}
|
|
4926
|
+
out[key] = trimmed;
|
|
4927
|
+
}
|
|
4928
|
+
return out;
|
|
4929
|
+
}
|
|
4930
|
+
function toolsExcludeMcp(tools) {
|
|
4931
|
+
if (tools.length === 0) return false;
|
|
4932
|
+
if (/\bmcp__/.test(tools)) return false;
|
|
4933
|
+
if (/\*/.test(tools)) return false;
|
|
4934
|
+
if (/\bAll tools\b/i.test(tools)) return false;
|
|
4935
|
+
return true;
|
|
4936
|
+
}
|
|
4937
|
+
function findSubagentFiles(dir, depth = 0) {
|
|
4938
|
+
if (depth > 6) return [];
|
|
4939
|
+
let entries;
|
|
4940
|
+
try {
|
|
4941
|
+
entries = readdirSync3(dir);
|
|
4942
|
+
} catch {
|
|
4943
|
+
return [];
|
|
4944
|
+
}
|
|
4945
|
+
const out = [];
|
|
4946
|
+
const isAgentsDir = dir.endsWith("/agents") || dir.endsWith("\\agents");
|
|
4947
|
+
for (const entry of entries) {
|
|
4948
|
+
const full = join15(dir, entry);
|
|
4949
|
+
let s;
|
|
4950
|
+
try {
|
|
4951
|
+
s = statSync2(full);
|
|
4952
|
+
} catch {
|
|
4953
|
+
continue;
|
|
4954
|
+
}
|
|
4955
|
+
if (s.isDirectory()) {
|
|
4956
|
+
out.push(...findSubagentFiles(full, depth + 1));
|
|
4957
|
+
} else if (s.isFile() && isAgentsDir && entry.endsWith(".md")) {
|
|
4958
|
+
out.push(full);
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
return out;
|
|
4962
|
+
}
|
|
4963
|
+
function auditSubagentMcpBindings(rootDirs) {
|
|
4964
|
+
const findings = [];
|
|
4965
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4966
|
+
for (const root of rootDirs) {
|
|
4967
|
+
for (const file of findSubagentFiles(root)) {
|
|
4968
|
+
if (seen.has(file)) continue;
|
|
4969
|
+
seen.add(file);
|
|
4970
|
+
let content;
|
|
4971
|
+
try {
|
|
4972
|
+
content = readFileSync9(file, "utf-8");
|
|
4973
|
+
} catch {
|
|
4974
|
+
continue;
|
|
4975
|
+
}
|
|
4976
|
+
const fm = parseFrontmatter(content);
|
|
4977
|
+
if (!fm || typeof fm.tools !== "string") continue;
|
|
4978
|
+
if (!toolsExcludeMcp(fm.tools)) continue;
|
|
4979
|
+
findings.push({
|
|
4980
|
+
file,
|
|
4981
|
+
name: fm.name ?? "<unknown>",
|
|
4982
|
+
tools: fm.tools,
|
|
4983
|
+
reason: "restrictive-tools-no-mcp"
|
|
4984
|
+
});
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
return findings;
|
|
4988
|
+
}
|
|
4989
|
+
function formatFinding(f) {
|
|
4990
|
+
return `[manager-worker] [subagent-mcp-audit] file=${f.file} name=${f.name} reason=${f.reason} tools=${JSON.stringify(f.tools)}`;
|
|
4991
|
+
}
|
|
4992
|
+
|
|
4993
|
+
// src/commands/audit-subagents.ts
|
|
4994
|
+
function defaultRoots() {
|
|
4995
|
+
const home = homedir6();
|
|
4996
|
+
return [
|
|
4997
|
+
join16(home, ".claude", "agents"),
|
|
4998
|
+
join16(home, ".claude", "plugins"),
|
|
4999
|
+
join16(process.cwd(), ".claude", "agents")
|
|
5000
|
+
];
|
|
5001
|
+
}
|
|
5002
|
+
async function auditSubagentsCommand(options = {}) {
|
|
5003
|
+
const roots = defaultRoots();
|
|
5004
|
+
const findings = auditSubagentMcpBindings(roots);
|
|
5005
|
+
if (options.json) {
|
|
5006
|
+
process.stdout.write(`${JSON.stringify({ findings, roots }, null, 2)}
|
|
5007
|
+
`);
|
|
5008
|
+
} else if (findings.length === 0) {
|
|
5009
|
+
process.stdout.write("No restrictive sub-agents found \u2014 every sub-agent under the scanned roots either inherits the parent toolset or explicitly includes mcp__* wildcards.\n");
|
|
5010
|
+
} else {
|
|
5011
|
+
process.stdout.write(`Found ${findings.length} sub-agent${findings.length === 1 ? "" : "s"} whose tools allowlist excludes mcp__*:
|
|
5012
|
+
|
|
5013
|
+
`);
|
|
5014
|
+
for (const f of findings) {
|
|
5015
|
+
process.stdout.write(` \u2022 ${f.name} (${f.file})
|
|
5016
|
+
`);
|
|
5017
|
+
process.stdout.write(` tools: ${f.tools}
|
|
5018
|
+
`);
|
|
5019
|
+
}
|
|
5020
|
+
process.stdout.write(
|
|
5021
|
+
"\nThese sub-agents will return \"No such tool available.\" for every mcp__* call when dispatched from a managed agent. If the parent needs to do MCP-tool work, dispatch the Augmented plugin's `augmented-worker` sub-agent instead \u2014 it omits `tools:` so it inherits the parent's full toolset including every MCP server. See ENG-5897.\n"
|
|
5022
|
+
);
|
|
5023
|
+
for (const f of findings) {
|
|
5024
|
+
process.stderr.write(`${formatFinding(f)}
|
|
5025
|
+
`);
|
|
5026
|
+
}
|
|
5027
|
+
}
|
|
5028
|
+
if (options.strict && findings.length > 0) {
|
|
5029
|
+
process.exit(2);
|
|
5030
|
+
}
|
|
5031
|
+
}
|
|
5032
|
+
|
|
4892
5033
|
// src/commands/integration.ts
|
|
4893
5034
|
import chalk19 from "chalk";
|
|
4894
5035
|
import ora17 from "ora";
|
|
@@ -5190,7 +5331,7 @@ function handleError(err) {
|
|
|
5190
5331
|
}
|
|
5191
5332
|
|
|
5192
5333
|
// src/bin/agt.ts
|
|
5193
|
-
var cliVersion2 = true ? "0.27.
|
|
5334
|
+
var cliVersion2 = true ? "0.27.38" : "dev";
|
|
5194
5335
|
var program = new Command();
|
|
5195
5336
|
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");
|
|
5196
5337
|
program.hook("preAction", (thisCommand) => {
|
|
@@ -5272,16 +5413,16 @@ host.command("pair <host-name>").description("Start an SSM port-forward + shell
|
|
|
5272
5413
|
})
|
|
5273
5414
|
);
|
|
5274
5415
|
var manager = program.command("manager").description("Host config sync daemon \u2014 keeps local agent files in sync with API");
|
|
5275
|
-
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",
|
|
5276
|
-
manager.command("stop").description("Stop the running manager daemon").option("--config-dir <dir>", "Config directory for agent files",
|
|
5277
|
-
manager.command("status").description("Show the current manager daemon status and discovered agents").option("--config-dir <dir>", "Config directory for agent files",
|
|
5278
|
-
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",
|
|
5279
|
-
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",
|
|
5416
|
+
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", join17(homedir7(), ".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);
|
|
5417
|
+
manager.command("stop").description("Stop the running manager daemon").option("--config-dir <dir>", "Config directory for agent files", join17(homedir7(), ".augmented")).action(managerStopCommand);
|
|
5418
|
+
manager.command("status").description("Show the current manager daemon status and discovered agents").option("--config-dir <dir>", "Config directory for agent files", join17(homedir7(), ".augmented")).action(managerStatusCommand);
|
|
5419
|
+
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", join17(homedir7(), ".augmented")).option("--no-tui", "Skip the TUI and stream the manager log to stdout instead (CI / scripts)").action(managerWatchCommand);
|
|
5420
|
+
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", join17(homedir7(), ".augmented")).action(managerInstallCommand);
|
|
5280
5421
|
manager.command("uninstall").description("Remove the OS-level supervisor (launchctl unload + delete plist on macOS). Idempotent.").action(managerUninstallCommand);
|
|
5281
5422
|
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);
|
|
5282
5423
|
manager.command("uninstall-system-unit").description("Remove the system-level systemd unit (Linux, root). Idempotent. (ENG-4706)").action(managerUninstallSystemUnitCommand);
|
|
5283
5424
|
var agent = program.command("agent").description("Inspect and manage agents");
|
|
5284
|
-
agent.command("show <code-name>").description("Display an agent's provisioned OpenClaw configuration").option("--config-dir <dir>", "Config directory",
|
|
5425
|
+
agent.command("show <code-name>").description("Display an agent's provisioned OpenClaw configuration").option("--config-dir <dir>", "Config directory", join17(homedir7(), ".augmented")).option("--all-channels", "Show all channels (including disabled)").action(agentShowCommand);
|
|
5285
5426
|
var kanban = program.command("kanban").description("Manage agent kanban boards");
|
|
5286
5427
|
kanban.command("list").description("List kanban board items for an agent").requiredOption("--agent <code-name>", "Agent code name").action(kanbanListCommand);
|
|
5287
5428
|
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);
|
|
@@ -5309,6 +5450,8 @@ integration.command("approve <request-id>").description("Approve a scope request
|
|
|
5309
5450
|
integration.command("deny <request-id>").description("Deny a scope request").option("--reason <text>", "Denial reason").action(integrationDenyCommand);
|
|
5310
5451
|
integration.command("enrol").description("Enrol an integration with an API key or webhook secret (no OAuth flow)").requiredOption("--def <code-name>", "Integration definition code_name (e.g. resend, xero)").requiredOption("--scope <org|team|agent>", "Install scope").option("--api-key <value>", "API key (sets auth_type=api_key)").option("--access-token <value>", "Bearer access token (sets auth_type=oauth2)").option("--webhook-secret <value>", "Webhook signing secret (sets auth_type=webhook)").option("--display-name <name>", "Override display name (defaults to the definition\u2019s display_name)").option("--agent <code-name>", "Agent code name (required for agent scope)").action(integrationEnrolCommand);
|
|
5311
5452
|
program.command("update").description("Check for and install CLI updates").option("--force", "Update even if manager or agent sessions are running").action(updateCommand);
|
|
5453
|
+
var audit = program.command("audit").description("Operator audits \u2014 sub-agent MCP bindings, etc.");
|
|
5454
|
+
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);
|
|
5312
5455
|
var skipUpdateCheck = process.argv.includes("--skip-update-check") || process.argv.includes("--json") || process.argv[2] === "update";
|
|
5313
5456
|
if (!skipUpdateCheck) {
|
|
5314
5457
|
checkForUpdateOnStartup().catch(() => {
|