@integrity-labs/agt-cli 0.28.95 → 0.28.97
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 +3 -3
- package/dist/{chunk-JYSWJMXU.js → chunk-5NQ652SP.js} +172 -2
- package/dist/chunk-5NQ652SP.js.map +1 -0
- package/dist/{chunk-QQYVNV5N.js → chunk-EN7ZKY4A.js} +2 -2
- package/dist/{claude-pair-runtime-DMC3ID2A.js → claude-pair-runtime-2ISKH4M2.js} +2 -2
- package/dist/lib/manager-worker.js +52 -8
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +122 -18
- package/dist/mcp/telegram-channel.js +104 -3
- package/dist/{persistent-session-X62FQ2TN.js → persistent-session-KAOPVQPC.js} +20 -2
- package/dist/{responsiveness-probe-PYEWQCIU.js → responsiveness-probe-OJPF6XDF.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-JYSWJMXU.js.map +0 -1
- /package/dist/{chunk-QQYVNV5N.js.map → chunk-EN7ZKY4A.js.map} +0 -0
- /package/dist/{claude-pair-runtime-DMC3ID2A.js.map → claude-pair-runtime-2ISKH4M2.js.map} +0 -0
- /package/dist/{persistent-session-X62FQ2TN.js.map → persistent-session-KAOPVQPC.js.map} +0 -0
- /package/dist/{responsiveness-probe-PYEWQCIU.js.map → responsiveness-probe-OJPF6XDF.js.map} +0 -0
package/dist/bin/agt.js
CHANGED
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
success,
|
|
38
38
|
table,
|
|
39
39
|
warn
|
|
40
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-EN7ZKY4A.js";
|
|
41
41
|
import {
|
|
42
42
|
CHANNEL_REGISTRY,
|
|
43
43
|
DEPLOYMENT_TEMPLATES,
|
|
@@ -4777,7 +4777,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
4777
4777
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
4778
4778
|
import chalk18 from "chalk";
|
|
4779
4779
|
import ora16 from "ora";
|
|
4780
|
-
var cliVersion = true ? "0.28.
|
|
4780
|
+
var cliVersion = true ? "0.28.97" : "dev";
|
|
4781
4781
|
async function fetchLatestVersion() {
|
|
4782
4782
|
const host2 = getHost();
|
|
4783
4783
|
if (!host2) return null;
|
|
@@ -5791,7 +5791,7 @@ function handleError(err) {
|
|
|
5791
5791
|
}
|
|
5792
5792
|
|
|
5793
5793
|
// src/bin/agt.ts
|
|
5794
|
-
var cliVersion2 = true ? "0.28.
|
|
5794
|
+
var cliVersion2 = true ? "0.28.97" : "dev";
|
|
5795
5795
|
var program = new Command();
|
|
5796
5796
|
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");
|
|
5797
5797
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -582,6 +582,150 @@ function resolveClaudeBinary() {
|
|
|
582
582
|
}
|
|
583
583
|
return "claude";
|
|
584
584
|
}
|
|
585
|
+
function isolationMode(codeName) {
|
|
586
|
+
if (process.env.AGT_ISOLATION !== "docker") return "none";
|
|
587
|
+
const allow = (process.env.AGT_ISOLATION_AGENTS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
588
|
+
if (allow.length > 0 && (!codeName || !allow.includes(codeName))) return "none";
|
|
589
|
+
return "docker";
|
|
590
|
+
}
|
|
591
|
+
var EGRESS_BASELINE_DOMAINS = [
|
|
592
|
+
".anthropic.com",
|
|
593
|
+
// claude API
|
|
594
|
+
"claude.ai",
|
|
595
|
+
// subscription auth
|
|
596
|
+
".augmented.team",
|
|
597
|
+
// the host/control-plane API
|
|
598
|
+
".slack.com",
|
|
599
|
+
// channels (incl. wss)
|
|
600
|
+
".composio.dev"
|
|
601
|
+
// composio MCP
|
|
602
|
+
];
|
|
603
|
+
function egressMode(codeName) {
|
|
604
|
+
if (process.env.AGT_EGRESS !== "allowlist") return "none";
|
|
605
|
+
if (isolationMode(codeName) !== "docker") return "none";
|
|
606
|
+
return "allowlist";
|
|
607
|
+
}
|
|
608
|
+
var VALID_EGRESS_DOMAIN = /^\.?([a-z0-9-]+\.)+[a-z0-9-]+$/;
|
|
609
|
+
function buildEgressAllowlist(toolsFrontmatter) {
|
|
610
|
+
const domains = new Set(EGRESS_BASELINE_DOMAINS);
|
|
611
|
+
for (const tool of toolsFrontmatter?.tools ?? []) {
|
|
612
|
+
for (const d of tool.network?.allowlist_domains ?? []) {
|
|
613
|
+
if (typeof d !== "string") continue;
|
|
614
|
+
const norm = d.trim().toLowerCase();
|
|
615
|
+
if (VALID_EGRESS_DOMAIN.test(norm)) domains.add(norm);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return [...domains].sort();
|
|
619
|
+
}
|
|
620
|
+
function egressAllowlistHostPath(codeName, homeDir) {
|
|
621
|
+
const home = homeDir ?? (process.env.HOME?.trim() || homedir2());
|
|
622
|
+
return join2(home, ".augmented", "_egress", `${codeName}.txt`);
|
|
623
|
+
}
|
|
624
|
+
function writeEgressAllowlist(codeName, domains, homeDir) {
|
|
625
|
+
const p = egressAllowlistHostPath(codeName, homeDir);
|
|
626
|
+
mkdirSync2(dirname(p), { recursive: true });
|
|
627
|
+
writeFileSync3(p, domains.join("\n") + "\n", { mode: 420 });
|
|
628
|
+
return p;
|
|
629
|
+
}
|
|
630
|
+
var EGRESS_DOCKER_TIMEOUT_MS = 1e4;
|
|
631
|
+
function isNoSuchContainer(err) {
|
|
632
|
+
const e = err;
|
|
633
|
+
const text = `${e?.stderr?.toString() ?? ""}${e?.message ?? ""}`;
|
|
634
|
+
return /no such container|is not running/i.test(text);
|
|
635
|
+
}
|
|
636
|
+
function reloadEgressSidecar(codeName) {
|
|
637
|
+
try {
|
|
638
|
+
execFileSync3("docker", ["kill", "--signal=HUP", `agt-squid-${codeName}`], {
|
|
639
|
+
stdio: "pipe",
|
|
640
|
+
timeout: EGRESS_DOCKER_TIMEOUT_MS
|
|
641
|
+
});
|
|
642
|
+
return true;
|
|
643
|
+
} catch (err) {
|
|
644
|
+
if (!isNoSuchContainer(err)) throw err;
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
function restartEgressSidecar(codeName) {
|
|
649
|
+
try {
|
|
650
|
+
execFileSync3("docker", ["restart", `agt-squid-${codeName}`], {
|
|
651
|
+
stdio: "pipe",
|
|
652
|
+
timeout: EGRESS_DOCKER_TIMEOUT_MS
|
|
653
|
+
});
|
|
654
|
+
return true;
|
|
655
|
+
} catch (err) {
|
|
656
|
+
if (!isNoSuchContainer(err)) throw err;
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function buildDockerRunCommand(args) {
|
|
661
|
+
const { codeName, agentId, wrapperPath, projectDir, homeDir, runId, passApiKey, egress } = args;
|
|
662
|
+
const q = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
|
|
663
|
+
const agentDir = join2(homeDir, ".augmented", codeName);
|
|
664
|
+
const agentIdDir = join2(homeDir, ".augmented", agentId);
|
|
665
|
+
const mcpDir = join2(homeDir, ".augmented", "_mcp");
|
|
666
|
+
const claudeHome = join2(homeDir, ".claude");
|
|
667
|
+
const claudeJson = join2(homeDir, ".claude.json");
|
|
668
|
+
const mounts = [
|
|
669
|
+
`-v ${q(`${agentDir}:${agentDir}`)}`,
|
|
670
|
+
`-v ${q(`${agentIdDir}:${agentIdDir}`)}`,
|
|
671
|
+
`-v ${q(`${mcpDir}:${mcpDir}:ro`)}`,
|
|
672
|
+
`-v ${q(`${claudeHome}:${claudeHome}`)}`,
|
|
673
|
+
`-v ${q(`${claudeJson}:${claudeJson}`)}`
|
|
674
|
+
];
|
|
675
|
+
const image = process.env.AGT_ISOLATION_IMAGE || "agt-runtime:latest";
|
|
676
|
+
const memory = process.env.AGT_ISOLATION_MEMORY || "512m";
|
|
677
|
+
const cpus = process.env.AGT_ISOLATION_CPUS || "1.0";
|
|
678
|
+
const pids = process.env.AGT_ISOLATION_PIDS || "512";
|
|
679
|
+
const envArgs = [`-e ${q(`HOME=${homeDir}`)}`];
|
|
680
|
+
if (passApiKey) envArgs.push("-e ANTHROPIC_API_KEY");
|
|
681
|
+
if (runId) envArgs.push(`-e ${q(`AGT_RUN_ID=${runId}`)}`);
|
|
682
|
+
const egressImage = process.env.AGT_EGRESS_IMAGE || "agt-squid:latest";
|
|
683
|
+
const internalNet = `agt-net-${codeName}`;
|
|
684
|
+
const squidName = `agt-squid-${codeName}`;
|
|
685
|
+
const networkArgs = [];
|
|
686
|
+
let egressSetup = "";
|
|
687
|
+
if (egress) {
|
|
688
|
+
networkArgs.push(`--network ${internalNet}`);
|
|
689
|
+
const proxyUrl = `http://${squidName}:3128`;
|
|
690
|
+
envArgs.push(`-e ${q(`HTTPS_PROXY=${proxyUrl}`)}`);
|
|
691
|
+
envArgs.push(`-e ${q(`HTTP_PROXY=${proxyUrl}`)}`);
|
|
692
|
+
envArgs.push(`-e ${q(`NO_PROXY=${squidName},localhost,127.0.0.1`)}`);
|
|
693
|
+
egressSetup = [
|
|
694
|
+
`docker rm -f ${squidName} agt-${codeName} >/dev/null 2>&1 || true`,
|
|
695
|
+
`docker network create agt-egress >/dev/null 2>&1 || true`,
|
|
696
|
+
// FAIL-CLOSED: a stale or hand-created `agt-net-<codeName>` that is NOT
|
|
697
|
+
// internal would give the agent a route off-net, bypassing the proxy.
|
|
698
|
+
// Don't trust create-if-absent - verify the Internal flag and rebuild the
|
|
699
|
+
// network when it's missing or wrong.
|
|
700
|
+
`{ [ "$(docker network inspect -f '{{.Internal}}' ${internalNet} 2>/dev/null)" = "true" ] || { docker network rm ${internalNet} >/dev/null 2>&1 || true; docker network create --internal ${internalNet} >/dev/null; }; }`,
|
|
701
|
+
// squid processes untrusted agent traffic - give it the same hardening as
|
|
702
|
+
// the agent container (drop all caps, block privilege escalation). squid
|
|
703
|
+
// binds 3128 (>1024) and needs no capabilities; verified it still boots.
|
|
704
|
+
`docker run -d --name ${squidName} --network ${internalNet} --restart unless-stopped --memory 128m --cap-drop ALL --security-opt no-new-privileges -v ${q(`${egress.allowlistHostPath}:/etc/squid/allowlist.txt:ro`)} ${q(egressImage)} >/dev/null`,
|
|
705
|
+
`docker network connect agt-egress ${squidName} >/dev/null 2>&1`
|
|
706
|
+
].join(" && ");
|
|
707
|
+
}
|
|
708
|
+
const runCmd = [
|
|
709
|
+
"exec docker run --rm -it",
|
|
710
|
+
`--name agt-${codeName}`,
|
|
711
|
+
`--memory ${memory}`,
|
|
712
|
+
`--cpus ${cpus}`,
|
|
713
|
+
`--pids-limit ${pids}`,
|
|
714
|
+
// Defence in depth (red-team 2026-06-16): drop all Linux capabilities and
|
|
715
|
+
// block privilege escalation. claude + node MCP servers need none - verified
|
|
716
|
+
// booting clean under these. The mount namespace is the primary boundary;
|
|
717
|
+
// these shrink what a container-escape CVE could reach if it ever landed.
|
|
718
|
+
"--cap-drop ALL",
|
|
719
|
+
"--security-opt no-new-privileges",
|
|
720
|
+
...networkArgs,
|
|
721
|
+
...mounts,
|
|
722
|
+
`-w ${q(projectDir)}`,
|
|
723
|
+
...envArgs,
|
|
724
|
+
q(image),
|
|
725
|
+
q(wrapperPath)
|
|
726
|
+
].join(" ");
|
|
727
|
+
return egress ? `${egressSetup} && ${runCmd}` : `docker rm -f agt-${codeName} >/dev/null 2>&1; ${runCmd}`;
|
|
728
|
+
}
|
|
585
729
|
function writePersistentClaudeWrapper(args) {
|
|
586
730
|
const { projectDir, claudeBin, initPrompt, claudeArgsJoined } = args;
|
|
587
731
|
const envIntegrationsPath = join2(projectDir, ".env.integrations");
|
|
@@ -840,7 +984,24 @@ function spawnSession(config, session) {
|
|
|
840
984
|
if (claudeAuthMode === "api_key" && config.anthropicApiKey) {
|
|
841
985
|
tmuxSessionEnvArgs.push("-e", `ANTHROPIC_API_KEY=${config.anthropicApiKey}`);
|
|
842
986
|
}
|
|
843
|
-
const
|
|
987
|
+
const sessionHomeDir = process.env.HOME?.trim() || homedir2();
|
|
988
|
+
let egress;
|
|
989
|
+
if (egressMode(codeName) === "allowlist") {
|
|
990
|
+
const allowlist = config.egressAllowlist ?? buildEgressAllowlist(null);
|
|
991
|
+
const allowlistHostPath = writeEgressAllowlist(codeName, allowlist, sessionHomeDir);
|
|
992
|
+
egress = { allowlistHostPath };
|
|
993
|
+
log(`[persistent-session] egress allowlist for '${codeName}': ${allowlist.length} domains (deny-by-default)`);
|
|
994
|
+
}
|
|
995
|
+
const claudeCmd = isolationMode(codeName) === "docker" ? buildDockerRunCommand({
|
|
996
|
+
codeName,
|
|
997
|
+
agentId: config.agentId,
|
|
998
|
+
wrapperPath,
|
|
999
|
+
projectDir,
|
|
1000
|
+
homeDir: sessionHomeDir,
|
|
1001
|
+
runId: config.runId ?? void 0,
|
|
1002
|
+
passApiKey: claudeAuthMode === "api_key" && !!config.anthropicApiKey,
|
|
1003
|
+
egress
|
|
1004
|
+
}) : JSON.stringify(wrapperPath);
|
|
844
1005
|
const tmuxEnv = {
|
|
845
1006
|
...process.env,
|
|
846
1007
|
// Treat empty-string as missing too — `HOME=""` makes ~ resolve
|
|
@@ -1369,6 +1530,15 @@ export {
|
|
|
1369
1530
|
takeWatchdogGiveUpCount,
|
|
1370
1531
|
creditWatchdogGiveUpCount,
|
|
1371
1532
|
resolveClaudeBinary,
|
|
1533
|
+
isolationMode,
|
|
1534
|
+
EGRESS_BASELINE_DOMAINS,
|
|
1535
|
+
egressMode,
|
|
1536
|
+
buildEgressAllowlist,
|
|
1537
|
+
egressAllowlistHostPath,
|
|
1538
|
+
writeEgressAllowlist,
|
|
1539
|
+
reloadEgressSidecar,
|
|
1540
|
+
restartEgressSidecar,
|
|
1541
|
+
buildDockerRunCommand,
|
|
1372
1542
|
writePersistentClaudeWrapper,
|
|
1373
1543
|
paneLogPath,
|
|
1374
1544
|
readPaneLogTail,
|
|
@@ -1395,4 +1565,4 @@ export {
|
|
|
1395
1565
|
stopAllSessionsAndWait,
|
|
1396
1566
|
getProjectDir
|
|
1397
1567
|
};
|
|
1398
|
-
//# sourceMappingURL=chunk-
|
|
1568
|
+
//# sourceMappingURL=chunk-5NQ652SP.js.map
|