@integrity-labs/agt-cli 0.28.1177 → 0.28.1179
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 +104 -417
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-DJNCIWVG.js → chunk-2FHYCFZM.js} +2 -2
- package/dist/{chunk-H37WRW2E.js → chunk-GJD536LU.js} +9 -6
- package/dist/chunk-GJD536LU.js.map +1 -0
- package/dist/{manager-supervisor-KIFBGETA.js → chunk-H3JMPEH7.js} +176 -8
- package/dist/chunk-H3JMPEH7.js.map +1 -0
- package/dist/{chunk-NHUXO5H2.js → chunk-KDYZNWZW.js} +2 -2
- package/dist/{chunk-45UH24I2.js → chunk-O5P2OS36.js} +435 -56
- package/dist/chunk-O5P2OS36.js.map +1 -0
- package/dist/{chunk-47P33SZF.js → chunk-PINFVWGX.js} +120 -3
- package/dist/chunk-PINFVWGX.js.map +1 -0
- package/dist/{claude-code-updater-H7RNX6M7.js → claude-code-updater-LL7KVAU3.js} +3 -3
- package/dist/{claude-pair-runtime-53JY6TQX.js → claude-pair-runtime-R5MNSUM7.js} +3 -3
- package/dist/lib/manager-worker.js +636 -262
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/manager-supervisor-TD7E6FPC.js +26 -0
- package/dist/mcp/direct-chat-channel.js +18 -1
- package/dist/mcp/index.js +151 -63
- package/dist/mcp/origami.js +18 -1
- package/dist/mcp/slack-channel.js +18 -1
- package/dist/mcp/telegram-channel.js +18 -1
- package/dist/{persistent-session-HVYGIS5C.js → persistent-session-34QXCPJK.js} +4 -4
- package/dist/persistent-session-34QXCPJK.js.map +1 -0
- package/dist/{responsiveness-probe-OGZ6ADVR.js → responsiveness-probe-ZT6ITMYI.js} +4 -4
- package/dist/{session-auth-dead-2JJLKURE.js → session-auth-dead-KAHV2ES2.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-45UH24I2.js.map +0 -1
- package/dist/chunk-47P33SZF.js.map +0 -1
- package/dist/chunk-H37WRW2E.js.map +0 -1
- package/dist/manager-supervisor-KIFBGETA.js.map +0 -1
- /package/dist/{chunk-DJNCIWVG.js.map → chunk-2FHYCFZM.js.map} +0 -0
- /package/dist/{chunk-NHUXO5H2.js.map → chunk-KDYZNWZW.js.map} +0 -0
- /package/dist/{claude-code-updater-H7RNX6M7.js.map → claude-code-updater-LL7KVAU3.js.map} +0 -0
- /package/dist/{claude-pair-runtime-53JY6TQX.js.map → claude-pair-runtime-R5MNSUM7.js.map} +0 -0
- /package/dist/{persistent-session-HVYGIS5C.js.map → manager-supervisor-TD7E6FPC.js.map} +0 -0
- /package/dist/{responsiveness-probe-OGZ6ADVR.js.map → responsiveness-probe-ZT6ITMYI.js.map} +0 -0
- /package/dist/{session-auth-dead-2JJLKURE.js.map → session-auth-dead-KAHV2ES2.js.map} +0 -0
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
parseEnvFileEntries,
|
|
17
17
|
parseEnvIntegrations,
|
|
18
18
|
shellQuote
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-GJD536LU.js";
|
|
20
20
|
import {
|
|
21
21
|
readDailySessionPin,
|
|
22
22
|
sessionTranscriptDir
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-2FHYCFZM.js";
|
|
24
24
|
import {
|
|
25
25
|
classifyUnanswerablePane,
|
|
26
26
|
isConsumerTermsDialogVisible,
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
buildIntegrationsSection,
|
|
60
60
|
buildSlackThirdPartyBotsEnvValue,
|
|
61
61
|
coerceEnvValue,
|
|
62
|
+
deriveConsoleUrl,
|
|
62
63
|
formatLiteralSecretRejection,
|
|
63
64
|
generateClaudeMd,
|
|
64
65
|
getFlagDefinition,
|
|
@@ -90,7 +91,7 @@ import {
|
|
|
90
91
|
scanConfigForLiteralSecrets,
|
|
91
92
|
worseConnectivityOutcome,
|
|
92
93
|
wrapScheduledTaskPrompt
|
|
93
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-PINFVWGX.js";
|
|
94
95
|
import {
|
|
95
96
|
claudeJsonPathFor,
|
|
96
97
|
effectiveClaudeJsonPath,
|
|
@@ -8078,7 +8079,7 @@ function exchangeFailureKind(err) {
|
|
|
8078
8079
|
}
|
|
8079
8080
|
|
|
8080
8081
|
// src/lib/api-client.ts
|
|
8081
|
-
var agtCliVersion = true ? "0.28.
|
|
8082
|
+
var agtCliVersion = true ? "0.28.1179" : "dev";
|
|
8082
8083
|
var lastConfigHash = null;
|
|
8083
8084
|
function setConfigHash(hash) {
|
|
8084
8085
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -8255,6 +8256,49 @@ async function mintAgentKey(rawHostKey, agentId) {
|
|
|
8255
8256
|
}
|
|
8256
8257
|
return data.agent_key;
|
|
8257
8258
|
}
|
|
8259
|
+
async function mintRotatedHostKey(rawHostKey) {
|
|
8260
|
+
const res = await fetch(`${requireHost()}/host/rotate-key`, {
|
|
8261
|
+
method: "POST",
|
|
8262
|
+
headers: { "Content-Type": "application/json" },
|
|
8263
|
+
body: JSON.stringify({ host_key: rawHostKey }),
|
|
8264
|
+
// BOUNDED, because this await is now on the poll cycle's critical path
|
|
8265
|
+
// (CodeRabbit on #7114). The rotation moved onto the heartbeat handler,
|
|
8266
|
+
// which `pollCycleInner` awaits, so an unanswered mint blocks the Claude
|
|
8267
|
+
// Code updater, the responsiveness probe, the wedge and pane-fatal checks,
|
|
8268
|
+
// the /host/agents fetch and every per-agent `processAgent` for as long as
|
|
8269
|
+
// it hangs — and Node's built-in fetch waits 300s by default. The
|
|
8270
|
+
// 5-minute retry backoff would then re-arm the same stall. 10s matches the
|
|
8271
|
+
// other short calls in this process (`telegram-ingest.ts`). A timeout
|
|
8272
|
+
// surfaces as a thrown error, which `adoptRotatedHostKey` reports as
|
|
8273
|
+
// `error` and the manager retries after the backoff — but the retry only
|
|
8274
|
+
// succeeds if the SERVER never committed the mint. The abort cancels the
|
|
8275
|
+
// client, not the route: if the key was already inserted and recorded, the
|
|
8276
|
+
// retry hits the one-mint-per-request guard, gets 409, and the request
|
|
8277
|
+
// needs a `compromised` rotation (Obi Wan `9b564171021b` on #7114). A lost
|
|
8278
|
+
// response after the commit ends the same way. The runbook lists it.
|
|
8279
|
+
signal: AbortSignal.timeout(1e4)
|
|
8280
|
+
});
|
|
8281
|
+
if (res.status === 403) {
|
|
8282
|
+
return null;
|
|
8283
|
+
}
|
|
8284
|
+
if (res.status === 409) {
|
|
8285
|
+
const body = await res.json().catch(() => ({}));
|
|
8286
|
+
return { refused: String(body["error"] ?? "conflict") };
|
|
8287
|
+
}
|
|
8288
|
+
if (!res.ok) {
|
|
8289
|
+
const body = await res.json().catch(() => ({}));
|
|
8290
|
+
throw new Error(`Host key rotation mint failed (${res.status}): ${String(body["error"] ?? res.statusText)}`);
|
|
8291
|
+
}
|
|
8292
|
+
const data = await res.json();
|
|
8293
|
+
const prefix = data.key?.prefix;
|
|
8294
|
+
const rawKey = data.key?.raw_key;
|
|
8295
|
+
if (!prefix || !rawKey) return null;
|
|
8296
|
+
return { prefix, rawKey };
|
|
8297
|
+
}
|
|
8298
|
+
function adoptHostKeyInProcess(rawKey) {
|
|
8299
|
+
process.env["AGT_API_KEY"] = rawKey;
|
|
8300
|
+
forceNextExchange();
|
|
8301
|
+
}
|
|
8258
8302
|
async function resolveAuth() {
|
|
8259
8303
|
const apiKey = getApiKey();
|
|
8260
8304
|
if (!apiKey) {
|
|
@@ -12329,12 +12373,38 @@ function decidePin(opts) {
|
|
|
12329
12373
|
return { kind: "install", version: pinned };
|
|
12330
12374
|
}
|
|
12331
12375
|
|
|
12332
|
-
// src/commands/
|
|
12376
|
+
// src/commands/setup.ts
|
|
12377
|
+
import { existsSync as existsSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, accessSync, constants as fsConstants } from "fs";
|
|
12378
|
+
import { join as join12, dirname as dirname7 } from "path";
|
|
12379
|
+
import { homedir as homedir8 } from "os";
|
|
12333
12380
|
import chalk3 from "chalk";
|
|
12334
|
-
import
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
import
|
|
12381
|
+
import ora from "ora";
|
|
12382
|
+
|
|
12383
|
+
// src/lib/output.ts
|
|
12384
|
+
import chalk2 from "chalk";
|
|
12385
|
+
import Table from "cli-table3";
|
|
12386
|
+
function success(msg) {
|
|
12387
|
+
console.log(chalk2.green(`\u2714 ${msg}`));
|
|
12388
|
+
}
|
|
12389
|
+
function error(msg) {
|
|
12390
|
+
console.error(chalk2.red(`\u2718 ${msg}`));
|
|
12391
|
+
}
|
|
12392
|
+
function warn(msg) {
|
|
12393
|
+
console.warn(chalk2.yellow(`\u26A0 ${msg}`));
|
|
12394
|
+
}
|
|
12395
|
+
function info(msg) {
|
|
12396
|
+
console.log(chalk2.cyan(`\u2139 ${msg}`));
|
|
12397
|
+
}
|
|
12398
|
+
function table(headers, rows) {
|
|
12399
|
+
const t = new Table({
|
|
12400
|
+
head: headers.map((h) => chalk2.bold.cyan(h)),
|
|
12401
|
+
style: { head: [], border: [] }
|
|
12402
|
+
});
|
|
12403
|
+
for (const row of rows) {
|
|
12404
|
+
t.push(row);
|
|
12405
|
+
}
|
|
12406
|
+
console.log(t.toString());
|
|
12407
|
+
}
|
|
12338
12408
|
|
|
12339
12409
|
// src/lib/watchdog.ts
|
|
12340
12410
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, existsSync as existsSync9, mkdirSync as mkdirSync7, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync5 } from "fs";
|
|
@@ -12532,33 +12602,337 @@ function getManagerStatus(configDir = DEFAULT_CONFIG_DIR) {
|
|
|
12532
12602
|
return readStateFile(configDir);
|
|
12533
12603
|
}
|
|
12534
12604
|
|
|
12535
|
-
// src/
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12605
|
+
// src/commands/setup.ts
|
|
12606
|
+
function detectShellProfile() {
|
|
12607
|
+
const shell = process.env["SHELL"] ?? "";
|
|
12608
|
+
const home = homedir8();
|
|
12609
|
+
if (shell.includes("zsh")) {
|
|
12610
|
+
return join12(home, ".zshrc");
|
|
12611
|
+
}
|
|
12612
|
+
if (shell.includes("fish")) {
|
|
12613
|
+
const fishConfig = join12(home, ".config", "fish", "config.fish");
|
|
12614
|
+
return fishConfig;
|
|
12615
|
+
}
|
|
12616
|
+
const bashrc = join12(home, ".bashrc");
|
|
12617
|
+
if (existsSync10(bashrc)) return bashrc;
|
|
12618
|
+
return join12(home, ".bash_profile");
|
|
12619
|
+
}
|
|
12620
|
+
function maybeWriteSystemWideEnv(apiUrl, apiKey, consoleUrl) {
|
|
12621
|
+
const empty = { etcEnvironment: false, profileD: false, bashrc: false };
|
|
12622
|
+
if (process.platform === "win32") return empty;
|
|
12623
|
+
if (typeof process.getuid !== "function" || process.getuid() !== 0) return empty;
|
|
12624
|
+
return {
|
|
12625
|
+
etcEnvironment: writeEtcEnvironment(apiUrl, apiKey, consoleUrl),
|
|
12626
|
+
profileD: writeProfileDScript(apiUrl, apiKey, consoleUrl),
|
|
12627
|
+
// Run for its side-effect (wiring /etc/bashrc to source agt.sh) but
|
|
12628
|
+
// treat it as a supporting channel, not proof that env values were
|
|
12629
|
+
// persisted. Success reporting should reflect actual value writes.
|
|
12630
|
+
bashrc: ensureBashrcSourcesProfileD()
|
|
12631
|
+
};
|
|
12540
12632
|
}
|
|
12541
|
-
function
|
|
12542
|
-
|
|
12633
|
+
function quoteForEtcEnvironment(value) {
|
|
12634
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r?\n/g, "\\n")}"`;
|
|
12543
12635
|
}
|
|
12544
|
-
function
|
|
12545
|
-
|
|
12636
|
+
function parseEtcEnvironmentValue(text, key) {
|
|
12637
|
+
let found = null;
|
|
12638
|
+
for (const line of text.split(/\r?\n/)) {
|
|
12639
|
+
const m = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)$/.exec(line);
|
|
12640
|
+
if (!m || m[1] !== key) continue;
|
|
12641
|
+
const raw = m[2].trim();
|
|
12642
|
+
const quoted = /^"((?:[^"\\]|\\.)*)"$/.exec(raw);
|
|
12643
|
+
found = quoted ? quoted[1].replace(/\\(n|\\|")/g, (_, c) => c === "n" ? "\n" : c) : raw;
|
|
12644
|
+
}
|
|
12645
|
+
return found || null;
|
|
12546
12646
|
}
|
|
12547
|
-
function
|
|
12548
|
-
|
|
12647
|
+
function readEtcEnvironmentValue(key) {
|
|
12648
|
+
try {
|
|
12649
|
+
return parseEtcEnvironmentValue(readFileSync12("/etc/environment", "utf-8"), key);
|
|
12650
|
+
} catch {
|
|
12651
|
+
return null;
|
|
12652
|
+
}
|
|
12549
12653
|
}
|
|
12550
|
-
function
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
}
|
|
12555
|
-
|
|
12556
|
-
|
|
12654
|
+
function quoteForPosixShell(value) {
|
|
12655
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
12656
|
+
}
|
|
12657
|
+
function quoteForFishShell(value) {
|
|
12658
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, `\\'`)}'`;
|
|
12659
|
+
}
|
|
12660
|
+
function writeEtcEnvironment(apiUrl, apiKey, consoleUrl) {
|
|
12661
|
+
const envPath = "/etc/environment";
|
|
12662
|
+
if (!existsSync10(envPath)) return false;
|
|
12663
|
+
try {
|
|
12664
|
+
accessSync(envPath, fsConstants.W_OK);
|
|
12665
|
+
} catch {
|
|
12666
|
+
return false;
|
|
12667
|
+
}
|
|
12668
|
+
try {
|
|
12669
|
+
const current = readFileSync12(envPath, "utf-8");
|
|
12670
|
+
const stripped = current.split(/\r?\n/).filter((line) => !/^\s*(?:export\s+)?AGT_(?:HOST|API_KEY|CONSOLE_URL)=/.test(line)).join("\n");
|
|
12671
|
+
const base = stripped.endsWith("\n") || stripped.length === 0 ? stripped : `${stripped}
|
|
12672
|
+
`;
|
|
12673
|
+
const lines = [
|
|
12674
|
+
`AGT_HOST=${quoteForEtcEnvironment(apiUrl)}`,
|
|
12675
|
+
`AGT_API_KEY=${quoteForEtcEnvironment(apiKey)}`
|
|
12676
|
+
];
|
|
12677
|
+
if (consoleUrl) lines.push(`AGT_CONSOLE_URL=${quoteForEtcEnvironment(consoleUrl)}`);
|
|
12678
|
+
const appended = `${base}${lines.join("\n")}
|
|
12679
|
+
`;
|
|
12680
|
+
writeFileSync8(envPath, appended, { mode: 420 });
|
|
12681
|
+
return true;
|
|
12682
|
+
} catch {
|
|
12683
|
+
return false;
|
|
12684
|
+
}
|
|
12685
|
+
}
|
|
12686
|
+
function writeProfileDScript(apiUrl, apiKey, consoleUrl) {
|
|
12687
|
+
const profileD = "/etc/profile.d";
|
|
12688
|
+
if (!existsSync10(profileD)) return false;
|
|
12689
|
+
try {
|
|
12690
|
+
accessSync(profileD, fsConstants.W_OK);
|
|
12691
|
+
} catch {
|
|
12692
|
+
return false;
|
|
12693
|
+
}
|
|
12694
|
+
try {
|
|
12695
|
+
const scriptPath = `${profileD}/agt.sh`;
|
|
12696
|
+
const lines = [
|
|
12697
|
+
"# Augmented \u2014 auto-generated by `agt setup`. Do not edit.",
|
|
12698
|
+
`export AGT_HOST=${quoteForPosixShell(apiUrl)}`,
|
|
12699
|
+
`export AGT_API_KEY=${quoteForPosixShell(apiKey)}`
|
|
12700
|
+
];
|
|
12701
|
+
if (consoleUrl) lines.push(`export AGT_CONSOLE_URL=${quoteForPosixShell(consoleUrl)}`);
|
|
12702
|
+
lines.push("");
|
|
12703
|
+
writeFileSync8(scriptPath, lines.join("\n"), { mode: 420 });
|
|
12704
|
+
return true;
|
|
12705
|
+
} catch {
|
|
12706
|
+
return false;
|
|
12707
|
+
}
|
|
12708
|
+
}
|
|
12709
|
+
function ensureBashrcSourcesProfileD() {
|
|
12710
|
+
const bashrc = "/etc/bashrc";
|
|
12711
|
+
if (!existsSync10(bashrc)) return false;
|
|
12712
|
+
try {
|
|
12713
|
+
accessSync(bashrc, fsConstants.W_OK);
|
|
12714
|
+
} catch {
|
|
12715
|
+
return false;
|
|
12716
|
+
}
|
|
12717
|
+
try {
|
|
12718
|
+
const current = readFileSync12(bashrc, "utf-8");
|
|
12719
|
+
const marker = "# Augmented (agt) \u2014 source system-wide AGT env";
|
|
12720
|
+
if (current.includes(marker)) return true;
|
|
12721
|
+
const snippet = [
|
|
12722
|
+
"",
|
|
12723
|
+
marker,
|
|
12724
|
+
"if [ -r /etc/profile.d/agt.sh ]; then",
|
|
12725
|
+
" . /etc/profile.d/agt.sh",
|
|
12726
|
+
"fi",
|
|
12727
|
+
""
|
|
12728
|
+
].join("\n");
|
|
12729
|
+
writeFileSync8(bashrc, current + snippet);
|
|
12730
|
+
return true;
|
|
12731
|
+
} catch {
|
|
12732
|
+
return false;
|
|
12733
|
+
}
|
|
12734
|
+
}
|
|
12735
|
+
function buildExportLines(shell, apiUrl, apiKey, consoleUrl) {
|
|
12736
|
+
if (shell.includes("fish")) {
|
|
12737
|
+
const lines2 = [
|
|
12738
|
+
"",
|
|
12739
|
+
"# Augmented (agt) host configuration",
|
|
12740
|
+
`set -gx AGT_HOST ${quoteForFishShell(apiUrl)}`,
|
|
12741
|
+
`set -gx AGT_API_KEY ${quoteForFishShell(apiKey)}`
|
|
12742
|
+
];
|
|
12743
|
+
if (consoleUrl) lines2.push(`set -gx AGT_CONSOLE_URL ${quoteForFishShell(consoleUrl)}`);
|
|
12744
|
+
lines2.push("");
|
|
12745
|
+
return lines2.join("\n");
|
|
12746
|
+
}
|
|
12747
|
+
const lines = [
|
|
12748
|
+
"",
|
|
12749
|
+
"# Augmented (agt) host configuration",
|
|
12750
|
+
`export AGT_HOST=${quoteForPosixShell(apiUrl)}`,
|
|
12751
|
+
`export AGT_API_KEY=${quoteForPosixShell(apiKey)}`
|
|
12752
|
+
];
|
|
12753
|
+
if (consoleUrl) lines.push(`export AGT_CONSOLE_URL=${quoteForPosixShell(consoleUrl)}`);
|
|
12754
|
+
lines.push("");
|
|
12755
|
+
return lines.join("\n");
|
|
12756
|
+
}
|
|
12757
|
+
async function setupCommand(token, options = {}) {
|
|
12758
|
+
const json = isJsonMode();
|
|
12759
|
+
const shortTokenPattern = /^[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}$/i;
|
|
12760
|
+
const legacyTokenPattern = /^prov_[a-f0-9]{64}$/i;
|
|
12761
|
+
if (!token || !shortTokenPattern.test(token) && !legacyTokenPattern.test(token)) {
|
|
12762
|
+
if (json) {
|
|
12763
|
+
jsonOutput({ ok: false, error: "Invalid provisioning token. Expected format: XXXX-XXXX or prov_<64 hex>" });
|
|
12764
|
+
} else {
|
|
12765
|
+
error("Invalid provisioning token. Expected format: XXXX-XXXX or prov_<64 hex>");
|
|
12766
|
+
info("Get a provisioning token from the Augmented dashboard after creating a host.");
|
|
12767
|
+
}
|
|
12768
|
+
process.exitCode = 1;
|
|
12769
|
+
return;
|
|
12770
|
+
}
|
|
12771
|
+
const normalizedToken = shortTokenPattern.test(token) ? token.toUpperCase() : token.toLowerCase();
|
|
12772
|
+
const apiHostFlag = options.apiHost?.trim();
|
|
12773
|
+
const envHost = process.env["AGT_HOST"]?.trim();
|
|
12774
|
+
const apiUrl = apiHostFlag || envHost;
|
|
12775
|
+
if (!apiUrl) {
|
|
12776
|
+
const msg = "Cannot determine API host for token exchange. Pass --api-host <url> or set AGT_HOST before running `agt setup`.\n Production: --api-host https://api.augmented.team\n Non-prod stage: --api-host https://<stage>.api.staging.augmented.team\n Local development: --api-host http://api.agt.localhost:1355";
|
|
12777
|
+
if (json) {
|
|
12778
|
+
jsonOutput({ ok: false, error: msg });
|
|
12779
|
+
} else {
|
|
12780
|
+
error(msg);
|
|
12781
|
+
}
|
|
12782
|
+
process.exitCode = 1;
|
|
12783
|
+
return;
|
|
12784
|
+
}
|
|
12785
|
+
if (!json) {
|
|
12786
|
+
if (apiHostFlag) {
|
|
12787
|
+
info(`Exchanging token against ${chalk3.bold(apiUrl)} (from --api-host)`);
|
|
12788
|
+
} else {
|
|
12789
|
+
info(`Exchanging token against ${chalk3.bold(apiUrl)} (from AGT_HOST)`);
|
|
12790
|
+
}
|
|
12791
|
+
}
|
|
12792
|
+
const spinner = ora({ text: "Exchanging provisioning token\u2026", isSilent: json });
|
|
12793
|
+
spinner.start();
|
|
12794
|
+
let setupResult;
|
|
12795
|
+
try {
|
|
12796
|
+
const res = await fetch(`${apiUrl}/host/setup`, {
|
|
12797
|
+
method: "POST",
|
|
12798
|
+
headers: { "Content-Type": "application/json" },
|
|
12799
|
+
body: JSON.stringify({ token: normalizedToken })
|
|
12800
|
+
});
|
|
12801
|
+
if (!res.ok) {
|
|
12802
|
+
const body = await res.json().catch(() => ({}));
|
|
12803
|
+
throw new Error(body["error"] ?? `Setup failed: HTTP ${res.status}`);
|
|
12804
|
+
}
|
|
12805
|
+
setupResult = await res.json();
|
|
12806
|
+
spinner.succeed("Provisioning token accepted");
|
|
12807
|
+
} catch (err) {
|
|
12808
|
+
spinner.fail("Failed to exchange provisioning token");
|
|
12809
|
+
if (json) {
|
|
12810
|
+
jsonOutput({ ok: false, error: err.message });
|
|
12811
|
+
} else {
|
|
12812
|
+
error(err.message);
|
|
12813
|
+
}
|
|
12814
|
+
process.exitCode = 1;
|
|
12815
|
+
return;
|
|
12816
|
+
}
|
|
12817
|
+
const finalApiUrl = setupResult.api_url || apiUrl;
|
|
12818
|
+
process.env["AGT_HOST"] = finalApiUrl;
|
|
12819
|
+
process.env["AGT_API_KEY"] = setupResult.api_key;
|
|
12820
|
+
const verifySpinner = ora({ text: "Verifying connection\u2026", isSilent: json });
|
|
12821
|
+
verifySpinner.start();
|
|
12822
|
+
try {
|
|
12823
|
+
const exchange = await exchangeApiKey(setupResult.api_key);
|
|
12824
|
+
verifySpinner.succeed("Connection verified");
|
|
12825
|
+
if (!json) {
|
|
12826
|
+
info(`Host: ${chalk3.bold(setupResult.host_name)}`);
|
|
12827
|
+
info(`Host ID: ${exchange.hostId}`);
|
|
12828
|
+
info(`Team: ${chalk3.bold(exchange.teamSlug ?? setupResult.team_slug ?? "unknown")}`);
|
|
12829
|
+
if (exchange.userEmail) {
|
|
12830
|
+
info(`User: ${chalk3.bold(exchange.userEmail)}`);
|
|
12831
|
+
}
|
|
12832
|
+
}
|
|
12833
|
+
} catch (err) {
|
|
12834
|
+
verifySpinner.fail("Connection verification failed");
|
|
12835
|
+
if (json) {
|
|
12836
|
+
jsonOutput({ ok: false, error: err.message });
|
|
12837
|
+
} else {
|
|
12838
|
+
error(err.message);
|
|
12839
|
+
info("Connection could not be verified. No changes were written to your shell profile.");
|
|
12840
|
+
info("Check your network connection and try: agt whoami");
|
|
12841
|
+
}
|
|
12842
|
+
process.exitCode = 1;
|
|
12843
|
+
return;
|
|
12844
|
+
}
|
|
12845
|
+
const profilePath = detectShellProfile();
|
|
12846
|
+
const shell = process.env["SHELL"] ?? "bash";
|
|
12847
|
+
const consoleUrl = deriveConsoleUrl(finalApiUrl);
|
|
12848
|
+
if (consoleUrl) {
|
|
12849
|
+
process.env["AGT_CONSOLE_URL"] = consoleUrl;
|
|
12850
|
+
}
|
|
12851
|
+
if (!json && !consoleUrl) {
|
|
12852
|
+
warn(
|
|
12853
|
+
`Could not derive AGT_CONSOLE_URL from ${finalApiUrl} \u2014 scheduled-delivery deep links will be disabled until you set it manually.`
|
|
12854
|
+
);
|
|
12855
|
+
}
|
|
12856
|
+
const exportLines = buildExportLines(shell, finalApiUrl, setupResult.api_key, consoleUrl);
|
|
12857
|
+
const profileDir = dirname7(profilePath);
|
|
12858
|
+
if (!existsSync10(profileDir)) {
|
|
12859
|
+
mkdirSync8(profileDir, { recursive: true });
|
|
12860
|
+
}
|
|
12861
|
+
const marker = "# Augmented (agt) host configuration";
|
|
12862
|
+
const current = existsSync10(profilePath) ? readFileSync12(profilePath, "utf-8") : "";
|
|
12863
|
+
let updated;
|
|
12864
|
+
if (current.includes(marker)) {
|
|
12865
|
+
updated = current.replace(
|
|
12866
|
+
/\n?# Augmented \(agt\) host configuration\n(?:(?:export\s+AGT_\w+=.*|set\s+-gx\s+AGT_\w+\s+.*)\n)*\n?/,
|
|
12867
|
+
exportLines
|
|
12868
|
+
);
|
|
12869
|
+
if (!json) {
|
|
12870
|
+
info("Replacing existing Augmented config block in shell profile.");
|
|
12871
|
+
}
|
|
12872
|
+
} else {
|
|
12873
|
+
updated = current + exportLines;
|
|
12874
|
+
}
|
|
12875
|
+
writeFileSync8(profilePath, updated.endsWith("\n") ? updated : `${updated}
|
|
12876
|
+
`);
|
|
12877
|
+
if (!json) {
|
|
12878
|
+
success(`Environment variables written to ${chalk3.bold(profilePath)}`);
|
|
12879
|
+
}
|
|
12880
|
+
const sys = maybeWriteSystemWideEnv(finalApiUrl, setupResult.api_key, consoleUrl);
|
|
12881
|
+
const valueChannelsWritten = sys.etcEnvironment || sys.profileD;
|
|
12882
|
+
if (!json && valueChannelsWritten) {
|
|
12883
|
+
const channels = [
|
|
12884
|
+
sys.etcEnvironment ? "/etc/environment" : null,
|
|
12885
|
+
sys.profileD ? "/etc/profile.d/agt.sh" : null,
|
|
12886
|
+
sys.bashrc ? "/etc/bashrc" : null
|
|
12887
|
+
].filter(Boolean).join(" + ");
|
|
12888
|
+
success(`System-wide env updated: ${channels}`);
|
|
12889
|
+
}
|
|
12890
|
+
const managerSpinner = ora({ text: "Starting manager daemon\u2026", isSilent: json });
|
|
12891
|
+
managerSpinner.start();
|
|
12892
|
+
try {
|
|
12893
|
+
const configDir = join12(homedir8(), ".augmented");
|
|
12894
|
+
const { pid } = startWatchdog({ intervalMs: 1e4, configDir, detached: true });
|
|
12895
|
+
managerSpinner.succeed(`Manager started (PID ${pid})`);
|
|
12896
|
+
} catch (err) {
|
|
12897
|
+
managerSpinner.warn("Could not start manager daemon");
|
|
12898
|
+
if (!json) {
|
|
12899
|
+
warn(err.message);
|
|
12900
|
+
info("Start it manually with: agt manager start");
|
|
12901
|
+
}
|
|
12902
|
+
}
|
|
12903
|
+
const includeApiKey = process.env["AGT_SETUP_INCLUDE_API_KEY"] === "1";
|
|
12904
|
+
if (json) {
|
|
12905
|
+
jsonOutput({
|
|
12906
|
+
ok: true,
|
|
12907
|
+
host_name: setupResult.host_name,
|
|
12908
|
+
host_id: setupResult.host_id,
|
|
12909
|
+
team_slug: setupResult.team_slug,
|
|
12910
|
+
api_url: finalApiUrl,
|
|
12911
|
+
...includeApiKey ? { api_key: setupResult.api_key } : {},
|
|
12912
|
+
agents: setupResult.agents,
|
|
12913
|
+
profile: profilePath
|
|
12914
|
+
});
|
|
12915
|
+
process.exit(0);
|
|
12916
|
+
} else {
|
|
12917
|
+
console.log();
|
|
12918
|
+
console.log(chalk3.green.bold(" Setup complete!"));
|
|
12919
|
+
console.log();
|
|
12920
|
+
if (setupResult.agents.length > 0) {
|
|
12921
|
+
info(`Agents: ${setupResult.agents.map((a) => chalk3.cyan(a)).join(", ")}`);
|
|
12922
|
+
} else {
|
|
12923
|
+
info("No agents assigned yet. Assign agents in the dashboard or with: agt host assign");
|
|
12924
|
+
}
|
|
12925
|
+
console.log();
|
|
12926
|
+
info(`Restart your shell or run: ${chalk3.bold(`source ${profilePath}`)}`);
|
|
12557
12927
|
}
|
|
12558
|
-
console.log(t.toString());
|
|
12559
12928
|
}
|
|
12560
12929
|
|
|
12561
12930
|
// src/commands/manager.ts
|
|
12931
|
+
import chalk4 from "chalk";
|
|
12932
|
+
import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
|
|
12933
|
+
import { join as join13 } from "path";
|
|
12934
|
+
import { homedir as homedir9, userInfo } from "os";
|
|
12935
|
+
import { spawn as spawn4 } from "child_process";
|
|
12562
12936
|
function normalizePinInEnv(env) {
|
|
12563
12937
|
const normalized = normalizePinVersion(env.AGT_CLI_PIN_VERSION);
|
|
12564
12938
|
if (normalized) env.AGT_CLI_PIN_VERSION = normalized;
|
|
@@ -12567,7 +12941,7 @@ function normalizePinInEnv(env) {
|
|
|
12567
12941
|
function managerStartCommand(opts) {
|
|
12568
12942
|
const json = isJsonMode();
|
|
12569
12943
|
if (!process.env.HOME || !process.env.HOME.trim()) {
|
|
12570
|
-
const fallback =
|
|
12944
|
+
const fallback = homedir9();
|
|
12571
12945
|
process.env.HOME = fallback;
|
|
12572
12946
|
if (!json) {
|
|
12573
12947
|
info(`HOME was not set in the manager env \u2014 defaulting to ${fallback}.`);
|
|
@@ -12601,7 +12975,7 @@ function managerStartCommand(opts) {
|
|
|
12601
12975
|
process.exitCode = 1;
|
|
12602
12976
|
return;
|
|
12603
12977
|
}
|
|
12604
|
-
const configDir = opts.configDir ??
|
|
12978
|
+
const configDir = opts.configDir ?? join13(homedir9(), ".augmented");
|
|
12605
12979
|
if (opts.supervise) {
|
|
12606
12980
|
if (json) {
|
|
12607
12981
|
jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
|
|
@@ -12697,7 +13071,7 @@ function runSupervisorLoop(intervalSec, configDir) {
|
|
|
12697
13071
|
}
|
|
12698
13072
|
async function managerStopCommand(opts = {}) {
|
|
12699
13073
|
const json = isJsonMode();
|
|
12700
|
-
const configDir = opts.configDir ??
|
|
13074
|
+
const configDir = opts.configDir ?? join13(homedir9(), ".augmented");
|
|
12701
13075
|
try {
|
|
12702
13076
|
const result = await stopWatchdog(configDir);
|
|
12703
13077
|
if (!result.stopped && !result.pid) {
|
|
@@ -12725,7 +13099,7 @@ async function managerStopCommand(opts = {}) {
|
|
|
12725
13099
|
}
|
|
12726
13100
|
function managerStatusCommand(opts = {}) {
|
|
12727
13101
|
const json = isJsonMode();
|
|
12728
|
-
const configDir = opts.configDir ??
|
|
13102
|
+
const configDir = opts.configDir ?? join13(homedir9(), ".augmented");
|
|
12729
13103
|
const status = getManagerStatus(configDir);
|
|
12730
13104
|
if (!status) {
|
|
12731
13105
|
if (json) {
|
|
@@ -12739,10 +13113,10 @@ function managerStatusCommand(opts = {}) {
|
|
|
12739
13113
|
jsonOutput({ ok: true, running: true, ...status });
|
|
12740
13114
|
return;
|
|
12741
13115
|
}
|
|
12742
|
-
console.log(
|
|
13116
|
+
console.log(chalk4.bold("\nManager Status\n"));
|
|
12743
13117
|
info(`PID: ${status.pid}`);
|
|
12744
13118
|
info(`Started: ${status.startedAt}`);
|
|
12745
|
-
info(`Last poll: ${status.lastPollAt ??
|
|
13119
|
+
info(`Last poll: ${status.lastPollAt ?? chalk4.dim("none")}`);
|
|
12746
13120
|
info(`Polls: ${status.pollCount}`);
|
|
12747
13121
|
info(`Errors: ${status.errorCount}`);
|
|
12748
13122
|
console.log();
|
|
@@ -12751,19 +13125,19 @@ function managerStatusCommand(opts = {}) {
|
|
|
12751
13125
|
return;
|
|
12752
13126
|
}
|
|
12753
13127
|
const rows = status.agents.map((a) => {
|
|
12754
|
-
let gwStatus =
|
|
13128
|
+
let gwStatus = chalk4.dim("\u2014");
|
|
12755
13129
|
if (a.gatewayRunning) {
|
|
12756
|
-
gwStatus =
|
|
13130
|
+
gwStatus = chalk4.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
|
|
12757
13131
|
} else if (a.gatewayPort) {
|
|
12758
|
-
gwStatus =
|
|
13132
|
+
gwStatus = chalk4.red(`:${a.gatewayPort} (down)`);
|
|
12759
13133
|
}
|
|
12760
13134
|
return [
|
|
12761
13135
|
a.codeName,
|
|
12762
|
-
a.status === "active" ?
|
|
12763
|
-
a.charterVersion ||
|
|
13136
|
+
a.status === "active" ? chalk4.green(a.status) : a.status === "paused" ? chalk4.yellow(a.status) : chalk4.dim(a.status ?? "\u2014"),
|
|
13137
|
+
a.charterVersion || chalk4.dim("\u2014"),
|
|
12764
13138
|
gwStatus,
|
|
12765
|
-
a.lastProvisionAt ? new Date(a.lastProvisionAt).toLocaleTimeString() :
|
|
12766
|
-
a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() :
|
|
13139
|
+
a.lastProvisionAt ? new Date(a.lastProvisionAt).toLocaleTimeString() : chalk4.dim("\u2014"),
|
|
13140
|
+
a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() : chalk4.dim("\u2014")
|
|
12767
13141
|
];
|
|
12768
13142
|
});
|
|
12769
13143
|
table(
|
|
@@ -12772,13 +13146,13 @@ function managerStatusCommand(opts = {}) {
|
|
|
12772
13146
|
);
|
|
12773
13147
|
const acpAgents = status.agents.filter((a) => a.acpSessions && a.acpSessions.length > 0);
|
|
12774
13148
|
if (acpAgents.length > 0) {
|
|
12775
|
-
console.log(
|
|
13149
|
+
console.log(chalk4.bold("\nACP Sessions\n"));
|
|
12776
13150
|
const acpRows = acpAgents.flatMap(
|
|
12777
13151
|
(a) => a.acpSessions.map((s) => [
|
|
12778
13152
|
a.codeName,
|
|
12779
13153
|
s.agentCommand,
|
|
12780
|
-
s.sessionName ??
|
|
12781
|
-
s.queueState === "running" ?
|
|
13154
|
+
s.sessionName ?? chalk4.dim("default"),
|
|
13155
|
+
s.queueState === "running" ? chalk4.green(s.queueState) : s.queueState === "queued" ? chalk4.yellow(s.queueState) : chalk4.dim(s.queueState),
|
|
12782
13156
|
String(s.turnCount),
|
|
12783
13157
|
new Date(s.startedAt).toLocaleTimeString()
|
|
12784
13158
|
])
|
|
@@ -12815,7 +13189,7 @@ function resolveStableAgtBin(rawPath) {
|
|
|
12815
13189
|
if (!prefix || !formula) return rawPath;
|
|
12816
13190
|
const candidates = [`${prefix}/bin/${formula}`, `${prefix}/bin/agt`];
|
|
12817
13191
|
for (const candidate of candidates) {
|
|
12818
|
-
if (!
|
|
13192
|
+
if (!existsSync11(candidate)) continue;
|
|
12819
13193
|
try {
|
|
12820
13194
|
realpathSync2(candidate);
|
|
12821
13195
|
return candidate;
|
|
@@ -12826,7 +13200,7 @@ function resolveStableAgtBin(rawPath) {
|
|
|
12826
13200
|
}
|
|
12827
13201
|
async function managerInstallCommand(opts = {}) {
|
|
12828
13202
|
const json = isJsonMode();
|
|
12829
|
-
const { installSupervisor, supervisorStatus } = await import("./manager-supervisor-
|
|
13203
|
+
const { installSupervisor, supervisorStatus } = await import("./manager-supervisor-TD7E6FPC.js");
|
|
12830
13204
|
const intervalSec = parseInt(opts.interval ?? "10", 10);
|
|
12831
13205
|
if (isNaN(intervalSec) || intervalSec < 5) {
|
|
12832
13206
|
const msg = "Interval must be at least 5 seconds.";
|
|
@@ -12835,7 +13209,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
12835
13209
|
process.exitCode = 1;
|
|
12836
13210
|
return;
|
|
12837
13211
|
}
|
|
12838
|
-
const configDir = opts.configDir ??
|
|
13212
|
+
const configDir = opts.configDir ?? join13(homedir9(), ".augmented");
|
|
12839
13213
|
const rawAgtBin = process.argv[1];
|
|
12840
13214
|
if (!rawAgtBin) {
|
|
12841
13215
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -12846,9 +13220,9 @@ async function managerInstallCommand(opts = {}) {
|
|
|
12846
13220
|
}
|
|
12847
13221
|
const agtBin = resolveStableAgtBin(rawAgtBin);
|
|
12848
13222
|
if (process.platform === "darwin") {
|
|
12849
|
-
const home =
|
|
13223
|
+
const home = homedir9();
|
|
12850
13224
|
const protectedRoots = ["Documents", "Downloads", "Desktop", "Movies", "Music", "Pictures"];
|
|
12851
|
-
const offending = protectedRoots.map((r) =>
|
|
13225
|
+
const offending = protectedRoots.map((r) => join13(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
|
|
12852
13226
|
if (offending) {
|
|
12853
13227
|
const msg = `agt binary at ${agtBin} sits inside a macOS TCC-protected folder (${offending}). launchd-spawned processes cannot read files there and the manager would EPERM on startup. Either install agt globally (\`npm install -g @integrity-labs/agt-cli\`) or copy the dist outside protected folders before running this command.`;
|
|
12854
13228
|
if (json) jsonOutput({ ok: false, error: msg });
|
|
@@ -12861,7 +13235,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
12861
13235
|
AGT_HOST: getHost(),
|
|
12862
13236
|
// ?? alone wouldn't catch `HOME=""` from a stripped systemd env.
|
|
12863
13237
|
// Treat empty / whitespace-only as missing.
|
|
12864
|
-
HOME: process.env.HOME?.trim() ||
|
|
13238
|
+
HOME: process.env.HOME?.trim() || homedir9(),
|
|
12865
13239
|
USER: process.env.USER?.trim() || userInfo().username
|
|
12866
13240
|
};
|
|
12867
13241
|
const apiKey = getApiKey();
|
|
@@ -12888,7 +13262,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
12888
13262
|
}
|
|
12889
13263
|
async function managerUninstallCommand() {
|
|
12890
13264
|
const json = isJsonMode();
|
|
12891
|
-
const { uninstallSupervisor } = await import("./manager-supervisor-
|
|
13265
|
+
const { uninstallSupervisor } = await import("./manager-supervisor-TD7E6FPC.js");
|
|
12892
13266
|
const result = await uninstallSupervisor();
|
|
12893
13267
|
if (!result.ok) {
|
|
12894
13268
|
if (json) jsonOutput({ ok: false, error: result.error });
|
|
@@ -12904,7 +13278,7 @@ async function managerUninstallCommand() {
|
|
|
12904
13278
|
}
|
|
12905
13279
|
async function managerInstallSystemUnitCommand(opts = {}) {
|
|
12906
13280
|
const json = isJsonMode();
|
|
12907
|
-
const { installSystemUnit, systemUnitStatus } = await import("./manager-supervisor-
|
|
13281
|
+
const { installSystemUnit, systemUnitStatus } = await import("./manager-supervisor-TD7E6FPC.js");
|
|
12908
13282
|
const intervalSec = parseInt(opts.interval ?? "10", 10);
|
|
12909
13283
|
if (isNaN(intervalSec) || intervalSec < 5) {
|
|
12910
13284
|
const msg = "Interval must be at least 5 seconds.";
|
|
@@ -12914,7 +13288,7 @@ async function managerInstallSystemUnitCommand(opts = {}) {
|
|
|
12914
13288
|
return;
|
|
12915
13289
|
}
|
|
12916
13290
|
const user = opts.user ?? "root";
|
|
12917
|
-
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" :
|
|
13291
|
+
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join13("/home", user, ".augmented"));
|
|
12918
13292
|
const rawAgtBin = process.argv[1];
|
|
12919
13293
|
if (!rawAgtBin) {
|
|
12920
13294
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -12960,7 +13334,7 @@ async function managerInstallSystemUnitCommand(opts = {}) {
|
|
|
12960
13334
|
}
|
|
12961
13335
|
async function managerUninstallSystemUnitCommand() {
|
|
12962
13336
|
const json = isJsonMode();
|
|
12963
|
-
const { uninstallSystemUnit } = await import("./manager-supervisor-
|
|
13337
|
+
const { uninstallSystemUnit } = await import("./manager-supervisor-TD7E6FPC.js");
|
|
12964
13338
|
const result = await uninstallSystemUnit();
|
|
12965
13339
|
if (!result.ok) {
|
|
12966
13340
|
if (json) jsonOutput({ ok: false, error: result.error });
|
|
@@ -13168,6 +13542,8 @@ export {
|
|
|
13168
13542
|
getCachedClaudeAuthModeRaw,
|
|
13169
13543
|
exchangeApiKey,
|
|
13170
13544
|
mintAgentKey,
|
|
13545
|
+
mintRotatedHostKey,
|
|
13546
|
+
adoptHostKeyInProcess,
|
|
13171
13547
|
ApiError,
|
|
13172
13548
|
api,
|
|
13173
13549
|
getHostId,
|
|
@@ -13224,8 +13600,11 @@ export {
|
|
|
13224
13600
|
normalizePinVersion,
|
|
13225
13601
|
pinAllowsUrgent,
|
|
13226
13602
|
decidePin,
|
|
13603
|
+
readEtcEnvironmentValue,
|
|
13604
|
+
writeEtcEnvironment,
|
|
13605
|
+
writeProfileDScript,
|
|
13606
|
+
setupCommand,
|
|
13227
13607
|
getManagerPaths,
|
|
13228
|
-
startWatchdog,
|
|
13229
13608
|
managerStartCommand,
|
|
13230
13609
|
SUPERVISOR_RESTART_EXIT_CODE,
|
|
13231
13610
|
managerStopCommand,
|
|
@@ -13235,4 +13614,4 @@ export {
|
|
|
13235
13614
|
managerInstallSystemUnitCommand,
|
|
13236
13615
|
managerUninstallSystemUnitCommand
|
|
13237
13616
|
};
|
|
13238
|
-
//# sourceMappingURL=chunk-
|
|
13617
|
+
//# sourceMappingURL=chunk-O5P2OS36.js.map
|