@integrity-labs/agt-cli 0.28.1176 → 0.28.1178

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.
Files changed (38) hide show
  1. package/dist/bin/agt.js +104 -417
  2. package/dist/bin/agt.js.map +1 -1
  3. package/dist/{chunk-H37WRW2E.js → chunk-3XURNDW5.js} +6 -5
  4. package/dist/chunk-3XURNDW5.js.map +1 -0
  5. package/dist/{chunk-UREYP4ML.js → chunk-DAIXT5DR.js} +435 -56
  6. package/dist/chunk-DAIXT5DR.js.map +1 -0
  7. package/dist/{manager-supervisor-KIFBGETA.js → chunk-H3JMPEH7.js} +176 -8
  8. package/dist/chunk-H3JMPEH7.js.map +1 -0
  9. package/dist/{chunk-47P33SZF.js → chunk-MHSZBN6M.js} +12 -2
  10. package/dist/chunk-MHSZBN6M.js.map +1 -0
  11. package/dist/{chunk-DJNCIWVG.js → chunk-MO5JQVBG.js} +2 -2
  12. package/dist/{chunk-NHUXO5H2.js → chunk-R2NQG77N.js} +2 -2
  13. package/dist/{claude-code-updater-H7RNX6M7.js → claude-code-updater-F2O3LAWX.js} +3 -3
  14. package/dist/{claude-pair-runtime-53JY6TQX.js → claude-pair-runtime-I6KVCUBG.js} +3 -3
  15. package/dist/lib/manager-worker.js +258 -20
  16. package/dist/lib/manager-worker.js.map +1 -1
  17. package/dist/manager-supervisor-TD7E6FPC.js +26 -0
  18. package/dist/mcp/direct-chat-channel.js +4 -0
  19. package/dist/mcp/index.js +21 -8
  20. package/dist/mcp/origami.js +4 -0
  21. package/dist/mcp/slack-channel.js +4 -0
  22. package/dist/mcp/telegram-channel.js +4 -0
  23. package/dist/{persistent-session-HVYGIS5C.js → persistent-session-7HP4KOED.js} +4 -4
  24. package/dist/persistent-session-7HP4KOED.js.map +1 -0
  25. package/dist/{responsiveness-probe-OGZ6ADVR.js → responsiveness-probe-EPG7NOKI.js} +4 -4
  26. package/dist/{session-auth-dead-2JJLKURE.js → session-auth-dead-IG3MKV2W.js} +3 -3
  27. package/package.json +1 -1
  28. package/dist/chunk-47P33SZF.js.map +0 -1
  29. package/dist/chunk-H37WRW2E.js.map +0 -1
  30. package/dist/chunk-UREYP4ML.js.map +0 -1
  31. package/dist/manager-supervisor-KIFBGETA.js.map +0 -1
  32. /package/dist/{chunk-DJNCIWVG.js.map → chunk-MO5JQVBG.js.map} +0 -0
  33. /package/dist/{chunk-NHUXO5H2.js.map → chunk-R2NQG77N.js.map} +0 -0
  34. /package/dist/{claude-code-updater-H7RNX6M7.js.map → claude-code-updater-F2O3LAWX.js.map} +0 -0
  35. /package/dist/{claude-pair-runtime-53JY6TQX.js.map → claude-pair-runtime-I6KVCUBG.js.map} +0 -0
  36. /package/dist/{persistent-session-HVYGIS5C.js.map → manager-supervisor-TD7E6FPC.js.map} +0 -0
  37. /package/dist/{responsiveness-probe-OGZ6ADVR.js.map → responsiveness-probe-EPG7NOKI.js.map} +0 -0
  38. /package/dist/{session-auth-dead-2JJLKURE.js.map → session-auth-dead-IG3MKV2W.js.map} +0 -0
@@ -16,11 +16,11 @@ import {
16
16
  parseEnvFileEntries,
17
17
  parseEnvIntegrations,
18
18
  shellQuote
19
- } from "./chunk-H37WRW2E.js";
19
+ } from "./chunk-3XURNDW5.js";
20
20
  import {
21
21
  readDailySessionPin,
22
22
  sessionTranscriptDir
23
- } from "./chunk-DJNCIWVG.js";
23
+ } from "./chunk-MO5JQVBG.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-47P33SZF.js";
94
+ } from "./chunk-MHSZBN6M.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.1176" : "dev";
8082
+ var agtCliVersion = true ? "0.28.1178" : "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/manager.ts
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 { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
12335
- import { join as join12 } from "path";
12336
- import { homedir as homedir8, userInfo } from "os";
12337
- import { spawn as spawn4 } from "child_process";
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/lib/output.ts
12536
- import chalk2 from "chalk";
12537
- import Table from "cli-table3";
12538
- function success(msg) {
12539
- console.log(chalk2.green(`\u2714 ${msg}`));
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 error(msg) {
12542
- console.error(chalk2.red(`\u2718 ${msg}`));
12633
+ function quoteForEtcEnvironment(value) {
12634
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r?\n/g, "\\n")}"`;
12543
12635
  }
12544
- function warn(msg) {
12545
- console.warn(chalk2.yellow(`\u26A0 ${msg}`));
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 info(msg) {
12548
- console.log(chalk2.cyan(`\u2139 ${msg}`));
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 table(headers, rows) {
12551
- const t = new Table({
12552
- head: headers.map((h) => chalk2.bold.cyan(h)),
12553
- style: { head: [], border: [] }
12554
- });
12555
- for (const row of rows) {
12556
- t.push(row);
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 = homedir8();
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 ?? join12(homedir8(), ".augmented");
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 ?? join12(homedir8(), ".augmented");
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 ?? join12(homedir8(), ".augmented");
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(chalk3.bold("\nManager Status\n"));
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 ?? chalk3.dim("none")}`);
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 = chalk3.dim("\u2014");
13128
+ let gwStatus = chalk4.dim("\u2014");
12755
13129
  if (a.gatewayRunning) {
12756
- gwStatus = chalk3.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
13130
+ gwStatus = chalk4.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
12757
13131
  } else if (a.gatewayPort) {
12758
- gwStatus = chalk3.red(`:${a.gatewayPort} (down)`);
13132
+ gwStatus = chalk4.red(`:${a.gatewayPort} (down)`);
12759
13133
  }
12760
13134
  return [
12761
13135
  a.codeName,
12762
- a.status === "active" ? chalk3.green(a.status) : a.status === "paused" ? chalk3.yellow(a.status) : chalk3.dim(a.status ?? "\u2014"),
12763
- a.charterVersion || chalk3.dim("\u2014"),
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() : chalk3.dim("\u2014"),
12766
- a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() : chalk3.dim("\u2014")
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(chalk3.bold("\nACP Sessions\n"));
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 ?? chalk3.dim("default"),
12781
- s.queueState === "running" ? chalk3.green(s.queueState) : s.queueState === "queued" ? chalk3.yellow(s.queueState) : chalk3.dim(s.queueState),
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 (!existsSync10(candidate)) continue;
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-KIFBGETA.js");
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 ?? join12(homedir8(), ".augmented");
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 = homedir8();
13223
+ const home = homedir9();
12850
13224
  const protectedRoots = ["Documents", "Downloads", "Desktop", "Movies", "Music", "Pictures"];
12851
- const offending = protectedRoots.map((r) => join12(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
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() || homedir8(),
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-KIFBGETA.js");
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-KIFBGETA.js");
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" : join12("/home", user, ".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-KIFBGETA.js");
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-UREYP4ML.js.map
13617
+ //# sourceMappingURL=chunk-DAIXT5DR.js.map