@openape/apes 1.11.0 → 1.13.0

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/cli.js CHANGED
@@ -77,7 +77,7 @@ import {
77
77
  import "./chunk-7OCVIDC7.js";
78
78
 
79
79
  // src/cli.ts
80
- import consola51 from "consola";
80
+ import consola49 from "consola";
81
81
 
82
82
  // src/ape-shell.ts
83
83
  import path from "path";
@@ -107,7 +107,7 @@ function rewriteApeShellArgs(argv, argv0) {
107
107
  }
108
108
 
109
109
  // src/cli.ts
110
- import { defineCommand as defineCommand61, runMain } from "citty";
110
+ import { defineCommand as defineCommand60, runMain } from "citty";
111
111
 
112
112
  // src/commands/auth/login.ts
113
113
  import { Buffer as Buffer2 } from "buffer";
@@ -393,7 +393,7 @@ async function loginWithPKCE(idp) {
393
393
  consola2.success(`Logged in as ${payload.email || payload.sub}`);
394
394
  }
395
395
  async function loginWithKey(idp, keyPath, agentEmail) {
396
- const { readFileSync: readFileSync14 } = await import("fs");
396
+ const { readFileSync: readFileSync15 } = await import("fs");
397
397
  const { sign: sign3 } = await import("crypto");
398
398
  const { loadEd25519PrivateKey: loadEd25519PrivateKey2 } = await import("./ssh-key-6X3YZXSD.js");
399
399
  const challengeUrl = await getAgentChallengeEndpoint(idp);
@@ -406,7 +406,7 @@ async function loginWithKey(idp, keyPath, agentEmail) {
406
406
  throw new CliError(`Challenge failed: ${await challengeResp.text()}`);
407
407
  }
408
408
  const { challenge } = await challengeResp.json();
409
- const keyContent = readFileSync14(keyPath, "utf-8");
409
+ const keyContent = readFileSync15(keyPath, "utf-8");
410
410
  const privateKey = loadEd25519PrivateKey2(keyContent);
411
411
  const signature = sign3(null, Buffer2.from(challenge), privateKey).toString("base64");
412
412
  const authenticateUrl = await getAgentAuthenticateEndpoint(idp);
@@ -2693,46 +2693,19 @@ function buildBridgeBlock(bridge) {
2693
2693
  return `
2694
2694
  mkdir -p "$HOME_DIR/Library/Application Support/openape/bridge" "$HOME_DIR/Library/Logs"
2695
2695
  cat > "$HOME_DIR/Library/Application Support/openape/bridge/.env" ${shHeredoc(bridge.envFile)}
2696
- cat > "$HOME_DIR/Library/Application Support/openape/bridge/start.sh" ${shHeredoc(bridge.startScript)}
2697
- chmod 755 "$HOME_DIR/Library/Application Support/openape/bridge/start.sh"
2698
2696
  chmod 600 "$HOME_DIR/Library/Application Support/openape/bridge/.env"
2699
-
2700
- # System-wide LaunchDaemon \u2014 root-owned, mode 644 (launchd refuses
2701
- # group/world-writable plists). UserName in the plist makes launchd run
2702
- # the binary as the agent, not root.
2703
- cat > ${shQuote(bridge.plistPath)} ${shHeredoc(bridge.plistContent)}
2704
- chown root:wheel ${shQuote(bridge.plistPath)}
2705
- chmod 644 ${shQuote(bridge.plistPath)}
2706
2697
  `;
2707
2698
  }
2708
- function buildBridgeBootstrapBlock(bridge, _name) {
2709
- if (!bridge) return "";
2710
- return `
2711
- launchctl bootout "system/${bridge.plistLabel}" 2>/dev/null || true
2712
- launchctl bootstrap system ${shQuote(bridge.plistPath)} || \\
2713
- echo "warn: bridge bootstrap into system domain failed; check ${bridge.plistPath}"
2714
- `;
2699
+ function buildBridgeBootstrapBlock(_bridge, _name) {
2700
+ return "";
2715
2701
  }
2716
- function buildTroopBlock(troop) {
2717
- if (!troop) return "";
2702
+ function buildTroopBlock(_troop) {
2718
2703
  return `
2719
- mkdir -p "$HOME_DIR/Library/LaunchAgents" "$HOME_DIR/Library/Logs" "$HOME_DIR/.openape/agent/tasks"
2720
- cat > ${shQuote(troop.plistPath)} ${shHeredoc(troop.plistContent)}
2721
- chown root:wheel ${shQuote(troop.plistPath)}
2722
- chmod 644 ${shQuote(troop.plistPath)}
2704
+ mkdir -p "$HOME_DIR/Library/Logs" "$HOME_DIR/.openape/agent/tasks"
2723
2705
  `;
2724
2706
  }
2725
- function buildTroopBootstrapBlock(troop, name) {
2726
- if (!troop) return "";
2727
- return `
2728
- # Bootstrap the troop sync launchd in the system domain. setup.sh runs
2729
- # as root via \`apes run --as root\`, so we have permission. Stale label
2730
- # is bootouted first to make re-spawn idempotent.
2731
- echo "==> Installing troop sync launchd as ${name}\u2026"
2732
- launchctl bootout "system/${troop.plistLabel}" 2>/dev/null || true
2733
- launchctl bootstrap system ${shQuote(troop.plistPath)} || \\
2734
- echo "warn: troop sync bootstrap failed; check ${troop.plistPath}"
2735
- `;
2707
+ function buildTroopBootstrapBlock(_troop, _name) {
2708
+ return "";
2736
2709
  }
2737
2710
  function buildDestroyTeardownScript(input) {
2738
2711
  const { name, homeDir, adminUser } = input;
@@ -4265,7 +4238,7 @@ var agentsCommand = defineCommand28({
4265
4238
  });
4266
4239
 
4267
4240
  // src/commands/nest/index.ts
4268
- import { defineCommand as defineCommand37 } from "citty";
4241
+ import { defineCommand as defineCommand36 } from "citty";
4269
4242
 
4270
4243
  // src/commands/nest/authorize.ts
4271
4244
  import { execFileSync as execFileSync8 } from "child_process";
@@ -4385,7 +4358,14 @@ var DEFAULT_ALLOW_PATTERNS = [
4385
4358
  // is the wrapper that gets unwrapped before grant creation. So the
4386
4359
  // YOLO target string is just `openape-chat-bridge`, not the full
4387
4360
  // wrapped invocation.
4388
- "openape-chat-bridge"
4361
+ "openape-chat-bridge",
4362
+ // Phase E: per-agent pm2 management. The Nest shells out
4363
+ // `apes run --as <agent> -- pm2 startOrReload /var/openape/nest/agents/<agent>/ecosystem.config.js`
4364
+ // and `apes run --as <agent> -- pm2 delete openape-bridge-<agent>`.
4365
+ // Inner-command (post-unwrap) targets:
4366
+ "pm2 startOrReload *",
4367
+ "pm2 delete openape-bridge-*",
4368
+ "pm2 jlist"
4389
4369
  ];
4390
4370
  var authorizeNestCommand = defineCommand30({
4391
4371
  meta: {
@@ -4434,147 +4414,107 @@ var authorizeNestCommand = defineCommand30({
4434
4414
  });
4435
4415
 
4436
4416
  // src/commands/nest/destroy.ts
4437
- import process2 from "process";
4438
4417
  import { defineCommand as defineCommand31 } from "citty";
4439
- import consola28 from "consola";
4440
-
4441
- // src/lib/nest-grant-flow.ts
4442
- import { hostname as hostname5 } from "os";
4443
4418
  import consola27 from "consola";
4444
- var NEST_AUDIENCE = "nest";
4445
- async function requestNestGrant(opts) {
4446
- const auth = loadAuth();
4447
- if (!auth) {
4448
- throw new CliError("Not logged in. Run `apes login` first.");
4449
- }
4450
- const idp = getIdpUrl(opts.idp) ?? void 0;
4451
- if (!idp) {
4452
- throw new CliError("No IdP URL resolved. Pass --idp or run `apes login` first.");
4453
- }
4454
- const grantsUrl = await getGrantsEndpoint(idp);
4455
- const targetHost = opts.targetHost ?? hostname5();
4456
- const approval = opts.approval ?? "always";
4457
- const reusableId = await findReusableNestGrant({
4458
- grantsUrl,
4459
- requester: auth.email,
4460
- command: opts.command,
4461
- targetHost
4462
- });
4463
- if (reusableId) {
4464
- const { authz_jwt: authz_jwt2 } = await apiFetch(`${grantsUrl}/${reusableId}/token`, {
4465
- method: "POST"
4466
- });
4467
- return authz_jwt2;
4468
- }
4469
- consola27.info(`Requesting nest grant: ${opts.command.join(" ")}`);
4470
- const grant = await apiFetch(grantsUrl, {
4471
- method: "POST",
4472
- body: {
4473
- requester: auth.email,
4474
- target_host: targetHost,
4475
- audience: NEST_AUDIENCE,
4476
- grant_type: approval,
4477
- command: opts.command,
4478
- reason: opts.reason ?? opts.command.join(" ")
4479
- }
4480
- });
4481
- let approved = grant.status === "approved";
4482
- const maxWait = 15 * 60 * 1e3;
4483
- const interval = 3e3;
4484
- const start = Date.now();
4485
- while (!approved && Date.now() - start < maxWait) {
4486
- const status = await apiFetch(`${grantsUrl}/${grant.id}`);
4487
- if (status.status === "approved") {
4488
- approved = true;
4489
- break;
4490
- }
4491
- if (status.status === "denied" || status.status === "revoked") {
4492
- throw new CliError(`Grant ${status.status}.`);
4493
- }
4494
- if (!approved) {
4495
- consola27.info(`Waiting for approval: ${idp}/grant-approval?grant_id=${grant.id}`);
4496
- await new Promise((r3) => setTimeout(r3, interval));
4419
+
4420
+ // src/lib/nest-intent.ts
4421
+ import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync10, statSync as statSync2, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
4422
+ import { homedir as homedir10 } from "os";
4423
+ import { join as join10 } from "path";
4424
+ import { randomUUID } from "crypto";
4425
+ var POLL_INTERVAL_MS = 200;
4426
+ var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
4427
+ function resolveIntentDir() {
4428
+ if (process.env.OPENAPE_NEST_INTENT_DIR) return process.env.OPENAPE_NEST_INTENT_DIR;
4429
+ if (existsSync12("/var/openape/nest/intents")) return "/var/openape/nest/intents";
4430
+ return join10(homedir10(), ".openape", "nest", "intents");
4431
+ }
4432
+ async function dispatchIntent(intent, opts = {}) {
4433
+ const id = randomUUID();
4434
+ const dir = resolveIntentDir();
4435
+ if (!existsSync12(dir)) {
4436
+ throw new CliError(`Nest intent dir does not exist: ${dir}
4437
+ Is the nest daemon running? Try \`ps aux | grep openape-nest\`.`);
4438
+ }
4439
+ const intentPath = join10(dir, `${id}.json`);
4440
+ const responsePath = join10(dir, `${id}.response`);
4441
+ const tmpPath = `${intentPath}.tmp`;
4442
+ writeFileSync6(tmpPath, `${JSON.stringify({ id, ...intent })}
4443
+ `, { mode: 432 });
4444
+ try {
4445
+ const fs = await import("fs");
4446
+ fs.renameSync(tmpPath, intentPath);
4447
+ } catch (err) {
4448
+ try {
4449
+ unlinkSync(tmpPath);
4450
+ } catch {
4497
4451
  }
4452
+ throw err;
4498
4453
  }
4499
- if (!approved) {
4500
- throw new CliError(
4501
- `Grant approval timed out after 15 min (still pending). Check your DDISA inbox at ${idp}/grant-approval?grant_id=${grant.id}.`
4502
- );
4454
+ const deadline = Date.now() + (opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
4455
+ while (Date.now() < deadline) {
4456
+ if (existsSync12(responsePath)) {
4457
+ let raw;
4458
+ try {
4459
+ const st = statSync2(responsePath);
4460
+ if (Date.now() - st.mtimeMs < 50) {
4461
+ await sleep(50);
4462
+ }
4463
+ raw = readFileSync10(responsePath, "utf8");
4464
+ } catch {
4465
+ await sleep(POLL_INTERVAL_MS);
4466
+ continue;
4467
+ }
4468
+ try {
4469
+ unlinkSync(responsePath);
4470
+ } catch {
4471
+ }
4472
+ let parsed;
4473
+ try {
4474
+ parsed = JSON.parse(raw);
4475
+ } catch (err) {
4476
+ throw new CliError(`malformed nest response: ${err instanceof Error ? err.message : String(err)}`);
4477
+ }
4478
+ if (!parsed.ok) {
4479
+ throw new CliError(`nest: ${parsed.error}`);
4480
+ }
4481
+ return parsed.result;
4482
+ }
4483
+ await sleep(POLL_INTERVAL_MS);
4503
4484
  }
4504
- const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, {
4505
- method: "POST"
4506
- });
4507
- return authz_jwt;
4508
- }
4509
- function nestBaseUrl(port) {
4510
- const p2 = port ?? Number(process.env.OPENAPE_NEST_PORT ?? 9091);
4511
- return `http://127.0.0.1:${p2}`;
4512
- }
4513
- async function findReusableNestGrant(opts) {
4514
4485
  try {
4515
- const grants = await apiFetch(
4516
- `${opts.grantsUrl}?requester=${encodeURIComponent(opts.requester)}&status=approved&limit=50`
4517
- );
4518
- const now = Math.floor(Date.now() / 1e3);
4519
- const match = grants.data.find((g) => {
4520
- const r3 = g.request;
4521
- if (r3.audience !== NEST_AUDIENCE) return false;
4522
- if (r3.target_host !== opts.targetHost) return false;
4523
- if (r3.grant_type === "once") return false;
4524
- if (r3.grant_type === "timed" && g.expires_at && g.expires_at <= now) return false;
4525
- const cmd = r3.command ?? [];
4526
- if (cmd.length !== opts.command.length) return false;
4527
- return cmd.every((c2, i) => c2 === opts.command[i]);
4528
- });
4529
- return match?.id ?? null;
4486
+ unlinkSync(intentPath);
4530
4487
  } catch {
4531
- return null;
4532
4488
  }
4489
+ throw new CliError(`nest intent timeout (${(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS) / 1e3}s) \u2014 Nest daemon may not be running or is stuck.`);
4490
+ }
4491
+ function sleep(ms) {
4492
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
4533
4493
  }
4534
4494
 
4535
4495
  // src/commands/nest/destroy.ts
4536
4496
  var destroyNestCommand = defineCommand31({
4537
4497
  meta: {
4538
4498
  name: "destroy",
4539
- description: "Tear down an agent on the local nest (removes macOS user, hard-deletes IdP record, drops bridge plist). Requires a DDISA `nest destroy <name>` grant."
4499
+ description: "Tear down an agent on the local nest. Drops an intent file the nest daemon picks up."
4540
4500
  },
4541
4501
  args: {
4542
- name: { type: "positional", required: true, description: "Agent name to destroy" },
4543
- port: { type: "string", description: "Override nest port (default: 9091)" }
4502
+ name: { type: "positional", required: true, description: "Agent name to destroy" }
4544
4503
  },
4545
4504
  async run({ args }) {
4546
4505
  const name = String(args.name);
4547
- const token = await requestNestGrant({ command: ["nest", "destroy", name] });
4548
- const base = nestBaseUrl(args.port ? Number(args.port) : void 0);
4549
- try {
4550
- const res = await fetch(`${base}/agents/${encodeURIComponent(name)}`, {
4551
- method: "DELETE",
4552
- headers: { Authorization: `Bearer ${token}` }
4553
- });
4554
- if (!res.ok) {
4555
- const text = await res.text().catch(() => "");
4556
- throw new CliError(`nest DELETE /agents/${name} failed: ${res.status} ${text}`);
4557
- }
4558
- } catch (err) {
4559
- const msg = err instanceof Error ? err.message : String(err);
4560
- if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
4561
- consola28.error(`Nest daemon is not running at ${base}`);
4562
- consola28.info(" Run: apes nest install");
4563
- process2.exit(2);
4564
- }
4565
- throw err;
4566
- }
4567
- consola28.success(`Destroyed ${name}`);
4506
+ await dispatchIntent({ action: "destroy", name });
4507
+ consola27.success(`Destroyed ${name}`);
4568
4508
  }
4569
4509
  });
4570
4510
 
4571
4511
  // src/commands/nest/install.ts
4572
4512
  import { execFileSync as execFileSync9 } from "child_process";
4573
- import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
4574
- import { homedir as homedir10, userInfo as userInfo2 } from "os";
4575
- import { dirname as dirname3, join as join10 } from "path";
4513
+ import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
4514
+ import { homedir as homedir11, userInfo as userInfo2 } from "os";
4515
+ import { dirname as dirname3, join as join11 } from "path";
4576
4516
  import { defineCommand as defineCommand32 } from "citty";
4577
- import consola29 from "consola";
4517
+ import consola28 from "consola";
4578
4518
 
4579
4519
  // src/commands/nest/apes-agents-adapter.ts
4580
4520
  var APES_AGENTS_ADAPTER_TOML = `schema = "openape-shapes/v1"
@@ -4641,13 +4581,13 @@ resource_chain = ["agents:name={name}", "allowlist:email={peer_email}"]
4641
4581
  // src/commands/nest/install.ts
4642
4582
  var PLIST_LABEL = "ai.openape.nest";
4643
4583
  function plistPath() {
4644
- return join10(homedir10(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
4584
+ return join11(homedir11(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
4645
4585
  }
4646
4586
  function escape2(s) {
4647
4587
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
4648
4588
  }
4649
4589
  function buildPlist(args) {
4650
- const logsDir = join10(args.userHome, "Library", "Logs");
4590
+ const logsDir = join11(args.userHome, "Library", "Logs");
4651
4591
  return `<?xml version="1.0" encoding="UTF-8"?>
4652
4592
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
4653
4593
  <plist version="1.0">
@@ -4682,40 +4622,40 @@ function buildPlist(args) {
4682
4622
  `;
4683
4623
  }
4684
4624
  function installAdapter2() {
4685
- const target = join10(homedir10(), ".openape", "shapes", "adapters", "apes-agents.toml");
4686
- mkdirSync4(dirname3(target), { recursive: true });
4625
+ const target = join11(homedir11(), ".openape", "shapes", "adapters", "apes-agents.toml");
4626
+ mkdirSync5(dirname3(target), { recursive: true });
4687
4627
  let existing = "";
4688
4628
  try {
4689
- existing = readFileSync10(target, "utf8");
4629
+ existing = readFileSync11(target, "utf8");
4690
4630
  } catch {
4691
4631
  }
4692
4632
  if (existing === APES_AGENTS_ADAPTER_TOML) return false;
4693
- writeFileSync6(target, APES_AGENTS_ADAPTER_TOML, { mode: 420 });
4694
- consola29.success(`Wrote shapes adapter ${target}`);
4633
+ writeFileSync7(target, APES_AGENTS_ADAPTER_TOML, { mode: 420 });
4634
+ consola28.success(`Wrote shapes adapter ${target}`);
4695
4635
  return true;
4696
4636
  }
4697
4637
  function writeBridgeModelDefault(model) {
4698
- const envDir = join10(homedir10(), "litellm");
4699
- const envFile = join10(envDir, ".env");
4700
- mkdirSync4(envDir, { recursive: true });
4638
+ const envDir = join11(homedir11(), "litellm");
4639
+ const envFile = join11(envDir, ".env");
4640
+ mkdirSync5(envDir, { recursive: true });
4701
4641
  let lines = [];
4702
- if (existsSync12(envFile)) {
4703
- lines = readFileSync10(envFile, "utf8").split("\n").filter((l) => !l.startsWith("APE_CHAT_BRIDGE_MODEL="));
4642
+ if (existsSync13(envFile)) {
4643
+ lines = readFileSync11(envFile, "utf8").split("\n").filter((l) => !l.startsWith("APE_CHAT_BRIDGE_MODEL="));
4704
4644
  }
4705
4645
  lines.push(`APE_CHAT_BRIDGE_MODEL=${model}`);
4706
4646
  while (lines.length > 0 && lines.at(-1).trim() === "") lines.pop();
4707
- writeFileSync6(envFile, `${lines.join("\n")}
4647
+ writeFileSync7(envFile, `${lines.join("\n")}
4708
4648
  `, { mode: 384 });
4709
4649
  }
4710
4650
  function findBinary(name) {
4711
4651
  for (const dir of [
4712
- join10(homedir10(), ".bun", "bin"),
4652
+ join11(homedir11(), ".bun", "bin"),
4713
4653
  "/opt/homebrew/bin",
4714
4654
  "/usr/local/bin",
4715
4655
  "/usr/bin"
4716
4656
  ]) {
4717
- const p2 = join10(dir, name);
4718
- if (existsSync12(p2)) return p2;
4657
+ const p2 = join11(dir, name);
4658
+ if (existsSync13(p2)) return p2;
4719
4659
  }
4720
4660
  throw new Error(`could not locate ${name} on PATH; install it first`);
4721
4661
  }
@@ -4735,35 +4675,35 @@ var installNestCommand = defineCommand32({
4735
4675
  }
4736
4676
  },
4737
4677
  async run({ args }) {
4738
- const homeDir = homedir10();
4678
+ const homeDir = homedir11();
4739
4679
  const port = Number(args.port ?? 9091);
4740
4680
  if (!Number.isInteger(port) || port < 1024 || port > 65535) {
4741
4681
  throw new Error(`invalid port ${port}`);
4742
4682
  }
4743
4683
  const nestBin = findBinary("openape-nest");
4744
4684
  const apesBin = findBinary("apes");
4745
- consola29.info(`Installing nest at ${plistPath()}`);
4746
- consola29.info(` nest binary: ${nestBin}`);
4747
- consola29.info(` apes binary: ${apesBin}`);
4748
- consola29.info(` HTTP port: ${port}`);
4685
+ consola28.info(`Installing nest at ${plistPath()}`);
4686
+ consola28.info(` nest binary: ${nestBin}`);
4687
+ consola28.info(` apes binary: ${apesBin}`);
4688
+ consola28.info(` HTTP port: ${port}`);
4749
4689
  if (typeof args["bridge-model"] === "string" && args["bridge-model"]) {
4750
4690
  writeBridgeModelDefault(args["bridge-model"]);
4751
- consola29.success(`Default bridge model set to ${args["bridge-model"]} (in ~/litellm/.env)`);
4691
+ consola28.success(`Default bridge model set to ${args["bridge-model"]} (in ~/litellm/.env)`);
4752
4692
  }
4753
4693
  installAdapter2();
4754
- mkdirSync4(join10(homeDir, "Library", "LaunchAgents"), { recursive: true });
4755
- mkdirSync4(NEST_DATA_DIR, { recursive: true });
4694
+ mkdirSync5(join11(homeDir, "Library", "LaunchAgents"), { recursive: true });
4695
+ mkdirSync5(NEST_DATA_DIR, { recursive: true });
4756
4696
  const desired = buildPlist({ nestBin, apesBin, userHome: homeDir, nestHome: NEST_DATA_DIR, port });
4757
4697
  let existing = "";
4758
4698
  try {
4759
- existing = readFileSync10(plistPath(), "utf8");
4699
+ existing = readFileSync11(plistPath(), "utf8");
4760
4700
  } catch {
4761
4701
  }
4762
4702
  if (existing !== desired) {
4763
- writeFileSync6(plistPath(), desired, { mode: 420 });
4764
- consola29.success("Wrote launchd plist");
4703
+ writeFileSync7(plistPath(), desired, { mode: 420 });
4704
+ consola28.success("Wrote launchd plist");
4765
4705
  } else {
4766
- consola29.info("plist already up to date");
4706
+ consola28.info("plist already up to date");
4767
4707
  }
4768
4708
  const uid = userInfo2().uid;
4769
4709
  try {
@@ -4771,208 +4711,116 @@ var installNestCommand = defineCommand32({
4771
4711
  } catch {
4772
4712
  }
4773
4713
  execFileSync9("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
4774
- consola29.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
4775
- consola29.info("");
4776
- consola29.info("Next steps for zero-prompt spawn \u2014 both one-time:");
4777
- consola29.info("");
4778
- consola29.info(" 1. apes nest enroll # register nest as DDISA agent (creates own auth.json)");
4779
- consola29.info(" 2. apes nest authorize # set YOLO-policy on the nest agent");
4780
- consola29.info("");
4781
- consola29.info("After that, every `POST http://127.0.0.1:9091/agents` runs without DDISA prompts.");
4714
+ consola28.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
4715
+ consola28.info("");
4716
+ consola28.info("Next steps for zero-prompt spawn \u2014 both one-time:");
4717
+ consola28.info("");
4718
+ consola28.info(" 1. apes nest enroll # register nest as DDISA agent (creates own auth.json)");
4719
+ consola28.info(" 2. apes nest authorize # set YOLO-policy on the nest agent");
4720
+ consola28.info("");
4721
+ consola28.info("After that, every `POST http://127.0.0.1:9091/agents` runs without DDISA prompts.");
4782
4722
  }
4783
4723
  });
4784
4724
 
4785
4725
  // src/commands/nest/list.ts
4786
- import process3 from "process";
4787
4726
  import { defineCommand as defineCommand33 } from "citty";
4788
- import consola30 from "consola";
4727
+ import consola29 from "consola";
4789
4728
  var listNestCommand = defineCommand33({
4790
4729
  meta: {
4791
4730
  name: "list",
4792
- description: "List agents registered with the local nest. Goes through DDISA grants \u2014 YOLO auto-approves under the standard nest policy."
4731
+ description: "List agents registered with the local nest. File-based intent."
4793
4732
  },
4794
4733
  args: {
4795
- port: { type: "string", description: "Override nest port (default: 9091)" },
4796
4734
  json: { type: "boolean", description: "JSON output for scripts" }
4797
4735
  },
4798
4736
  async run({ args }) {
4799
- const token = await requestNestGrant({ command: ["nest", "list"] });
4800
- const base = nestBaseUrl(args.port ? Number(args.port) : void 0);
4801
- let resp;
4802
- try {
4803
- const res = await fetch(`${base}/agents`, {
4804
- headers: { Authorization: `Bearer ${token}` }
4805
- });
4806
- if (!res.ok) {
4807
- const text = await res.text().catch(() => "");
4808
- throw new CliError(`nest GET /agents failed: ${res.status} ${text}`);
4809
- }
4810
- resp = await res.json();
4811
- } catch (err) {
4812
- const msg = err instanceof Error ? err.message : String(err);
4813
- if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
4814
- consola30.error(`Nest daemon is not running at ${base}`);
4815
- consola30.info(" Run: apes nest install");
4816
- process3.exit(2);
4817
- }
4818
- throw err;
4819
- }
4737
+ const result = await dispatchIntent({ action: "list" });
4820
4738
  if (args.json) {
4821
- console.log(JSON.stringify(resp, null, 2));
4739
+ console.log(JSON.stringify(result, null, 2));
4822
4740
  return;
4823
4741
  }
4824
- if (resp.agents.length === 0) {
4825
- consola30.info("(no agents registered with this nest)");
4742
+ if (result.agents.length === 0) {
4743
+ consola29.info("(no agents registered with this nest)");
4826
4744
  return;
4827
4745
  }
4828
- consola30.info(`${resp.agents.length} agent(s) registered with this nest:`);
4829
- for (const a of resp.agents) {
4746
+ consola29.info(`${result.agents.length} agent(s) registered with this nest:`);
4747
+ for (const a of result.agents) {
4830
4748
  const bridge = a.bridge ? " bridge=on" : "";
4831
- consola30.info(` ${a.name.padEnd(16)} uid=${String(a.uid).padEnd(5)} home=${a.home}${bridge}`);
4749
+ consola29.info(` ${a.name.padEnd(16)} uid=${String(a.uid).padEnd(5)} home=${a.home}${bridge}`);
4832
4750
  }
4833
4751
  }
4834
4752
  });
4835
4753
 
4836
4754
  // src/commands/nest/spawn.ts
4837
- import process4 from "process";
4838
4755
  import { defineCommand as defineCommand34 } from "citty";
4839
- import consola31 from "consola";
4756
+ import consola30 from "consola";
4840
4757
  var spawnNestCommand = defineCommand34({
4841
4758
  meta: {
4842
4759
  name: "spawn",
4843
- description: "Spawn a new agent on the local nest. Requires a DDISA `nest spawn <name>` grant \u2014 auto-approved by Patrick's policy on first use, reused on subsequent calls."
4760
+ description: "Spawn a new agent on the local nest. Drops an intent file the nest daemon picks up; UNIX permissions on the intents dir gate access."
4844
4761
  },
4845
4762
  args: {
4846
4763
  name: { type: "positional", required: true, description: "Agent name (lowercase, [a-z0-9-], max 24 chars)" },
4847
4764
  "no-bridge": { type: "boolean", description: "Skip installing the chat-bridge daemon (default: install it)" },
4848
4765
  "bridge-key": { type: "string", description: "Override LITELLM_API_KEY (default: read from ~/litellm/.env)" },
4849
4766
  "bridge-base-url": { type: "string", description: "Override LITELLM_BASE_URL (default: read from ~/litellm/.env)" },
4850
- "bridge-model": { type: "string", description: "Override APE_CHAT_BRIDGE_MODEL" },
4851
- "port": { type: "string", description: "Override nest port (default: 9091)" }
4767
+ "bridge-model": { type: "string", description: "Override APE_CHAT_BRIDGE_MODEL" }
4852
4768
  },
4853
4769
  async run({ args }) {
4854
4770
  const name = String(args.name);
4855
- const token = await requestNestGrant({ command: ["nest", "spawn"] });
4856
- const base = nestBaseUrl(args.port ? Number(args.port) : void 0);
4857
- const reqBody = {
4771
+ const intent = {
4772
+ action: "spawn",
4858
4773
  name,
4859
4774
  bridge: !args["no-bridge"]
4860
4775
  };
4861
- if (typeof args["bridge-key"] === "string") reqBody.bridgeKey = args["bridge-key"];
4862
- if (typeof args["bridge-base-url"] === "string") reqBody.bridgeBaseUrl = args["bridge-base-url"];
4863
- if (typeof args["bridge-model"] === "string") reqBody.bridgeModel = args["bridge-model"];
4864
- let resp;
4865
- try {
4866
- const res = await fetch(`${base}/agents`, {
4867
- method: "POST",
4868
- headers: {
4869
- "Authorization": `Bearer ${token}`,
4870
- "Content-Type": "application/json"
4871
- },
4872
- body: JSON.stringify(reqBody)
4873
- });
4874
- if (!res.ok) {
4875
- const text = await res.text().catch(() => "");
4876
- throw new CliError(`nest POST /agents failed: ${res.status} ${text}`);
4877
- }
4878
- resp = await res.json();
4879
- } catch (err) {
4880
- const msg = err instanceof Error ? err.message : String(err);
4881
- if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
4882
- consola31.error(`Nest daemon is not running at ${base}`);
4883
- consola31.info(" Run: apes nest install");
4884
- process4.exit(2);
4885
- }
4886
- throw err;
4887
- }
4888
- consola31.success(`Spawned ${resp.name} (uid=${resp.uid}, home=${resp.home})`);
4889
- }
4890
- });
4891
-
4892
- // src/commands/nest/status.ts
4893
- import process5 from "process";
4894
- import { defineCommand as defineCommand35 } from "citty";
4895
- import consola32 from "consola";
4896
- var statusNestCommand = defineCommand35({
4897
- meta: {
4898
- name: "status",
4899
- description: "Print health of the local nest-daemon (agents registered). Goes through DDISA grants."
4900
- },
4901
- args: {
4902
- port: { type: "string", description: "Override nest port (default: 9091)" },
4903
- json: { type: "boolean", description: "JSON output for scripts" }
4904
- },
4905
- async run({ args }) {
4906
- const token = await requestNestGrant({ command: ["nest", "status"] });
4907
- const base = nestBaseUrl(args.port ? Number(args.port) : void 0);
4908
- let status;
4909
- try {
4910
- const res = await fetch(`${base}/status`, {
4911
- headers: { Authorization: `Bearer ${token}` }
4912
- });
4913
- if (!res.ok) {
4914
- const text = await res.text().catch(() => "");
4915
- throw new CliError(`nest GET /status failed: ${res.status} ${text}`);
4916
- }
4917
- status = await res.json();
4918
- } catch (err) {
4919
- const msg = err instanceof Error ? err.message : String(err);
4920
- if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
4921
- consola32.error(`Nest daemon is not running at ${base}`);
4922
- consola32.info(" Run: apes nest install");
4923
- process5.exit(2);
4924
- }
4925
- throw err;
4926
- }
4927
- if (args.json) {
4928
- console.log(JSON.stringify(status, null, 2));
4929
- return;
4930
- }
4931
- consola32.info(`Nest at ${base} \u2014 ${status.agents} agent(s) registered`);
4776
+ if (typeof args["bridge-key"] === "string") intent.bridgeKey = args["bridge-key"];
4777
+ if (typeof args["bridge-base-url"] === "string") intent.bridgeBaseUrl = args["bridge-base-url"];
4778
+ if (typeof args["bridge-model"] === "string") intent.bridgeModel = args["bridge-model"];
4779
+ const result = await dispatchIntent(intent);
4780
+ consola30.success(`Spawned ${result.name} (uid=${result.uid}, home=${result.home})`);
4932
4781
  }
4933
4782
  });
4934
4783
 
4935
4784
  // src/commands/nest/uninstall.ts
4936
4785
  import { execFileSync as execFileSync10 } from "child_process";
4937
- import { existsSync as existsSync13, unlinkSync } from "fs";
4938
- import { homedir as homedir11, userInfo as userInfo3 } from "os";
4939
- import { join as join11 } from "path";
4940
- import { defineCommand as defineCommand36 } from "citty";
4941
- import consola33 from "consola";
4786
+ import { existsSync as existsSync14, unlinkSync as unlinkSync2 } from "fs";
4787
+ import { homedir as homedir12, userInfo as userInfo3 } from "os";
4788
+ import { join as join12 } from "path";
4789
+ import { defineCommand as defineCommand35 } from "citty";
4790
+ import consola31 from "consola";
4942
4791
  var PLIST_LABEL2 = "ai.openape.nest";
4943
- var uninstallNestCommand = defineCommand36({
4792
+ var uninstallNestCommand = defineCommand35({
4944
4793
  meta: {
4945
4794
  name: "uninstall",
4946
4795
  description: "Stop + remove the local nest-daemon (registry + agents preserved)"
4947
4796
  },
4948
4797
  async run() {
4949
4798
  const uid = userInfo3().uid;
4950
- const path2 = join11(homedir11(), "Library", "LaunchAgents", `${PLIST_LABEL2}.plist`);
4799
+ const path2 = join12(homedir12(), "Library", "LaunchAgents", `${PLIST_LABEL2}.plist`);
4951
4800
  try {
4952
4801
  execFileSync10("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
4953
- consola33.success("Nest daemon stopped");
4802
+ consola31.success("Nest daemon stopped");
4954
4803
  } catch {
4955
- consola33.info("Nest daemon was not loaded");
4804
+ consola31.info("Nest daemon was not loaded");
4956
4805
  }
4957
- if (existsSync13(path2)) {
4958
- unlinkSync(path2);
4959
- consola33.success(`Removed ${path2}`);
4806
+ if (existsSync14(path2)) {
4807
+ unlinkSync2(path2);
4808
+ consola31.success(`Removed ${path2}`);
4960
4809
  }
4961
- consola33.info("Registry at ~/.openape/nest/agents.json kept \u2014 re-run `apes nest install` to resume supervision.");
4810
+ consola31.info("Registry at ~/.openape/nest/agents.json kept \u2014 re-run `apes nest install` to resume supervision.");
4962
4811
  }
4963
4812
  });
4964
4813
 
4965
4814
  // src/commands/nest/index.ts
4966
- var nestCommand = defineCommand37({
4815
+ var nestCommand = defineCommand36({
4967
4816
  meta: {
4968
4817
  name: "nest",
4969
- description: "Manage the local Nest control-plane daemon. One-time setup: `install` (launchd) \u2192 `enroll` (own DDISA identity) \u2192 `authorize` (YOLO-policy). Day-to-day: `status` / `list` (read-only) and `spawn` / `destroy` (mutating) \u2014 every API call is gated by a DDISA grant audited at the IdP, YOLO-approved silently under the policy `apes nest authorize` sets up."
4818
+ description: "Manage the local Nest control-plane daemon. One-time setup: `install` \u2192 `enroll` \u2192 `authorize`. Day-to-day: `list` / `spawn` / `destroy`. As of Phase D the Nest is a long-running CLIENT \u2014 commands talk to it via filesystem intent files in $NEST_HOME/intents (mode 770, group _openape_nest) instead of HTTP."
4970
4819
  },
4971
4820
  subCommands: {
4972
4821
  install: installNestCommand,
4973
4822
  enroll: enrollNestCommand,
4974
4823
  authorize: authorizeNestCommand,
4975
- status: statusNestCommand,
4976
4824
  list: listNestCommand,
4977
4825
  spawn: spawnNestCommand,
4978
4826
  destroy: destroyNestCommand,
@@ -4981,12 +4829,12 @@ var nestCommand = defineCommand37({
4981
4829
  });
4982
4830
 
4983
4831
  // src/commands/yolo/index.ts
4984
- import { defineCommand as defineCommand41 } from "citty";
4832
+ import { defineCommand as defineCommand40 } from "citty";
4985
4833
 
4986
4834
  // src/commands/yolo/clear.ts
4987
- import { defineCommand as defineCommand38 } from "citty";
4988
- import consola34 from "consola";
4989
- var yoloClearCommand = defineCommand38({
4835
+ import { defineCommand as defineCommand37 } from "citty";
4836
+ import consola32 from "consola";
4837
+ var yoloClearCommand = defineCommand37({
4990
4838
  meta: {
4991
4839
  name: "clear",
4992
4840
  description: "Remove the YOLO-policy from a DDISA agent (subsequent grants need human approval)"
@@ -5015,15 +4863,15 @@ var yoloClearCommand = defineCommand38({
5015
4863
  const text = await res.text().catch(() => "");
5016
4864
  throw new CliError(`DELETE /yolo-policy failed (${res.status}): ${text}`);
5017
4865
  }
5018
- consola34.success(`YOLO-policy cleared on ${email}`);
4866
+ consola32.success(`YOLO-policy cleared on ${email}`);
5019
4867
  }
5020
4868
  });
5021
4869
 
5022
4870
  // src/commands/yolo/set.ts
5023
- import { defineCommand as defineCommand39 } from "citty";
5024
- import consola35 from "consola";
4871
+ import { defineCommand as defineCommand38 } from "citty";
4872
+ import consola33 from "consola";
5025
4873
  var VALID_MODES = ["allow-list", "deny-list"];
5026
- var yoloSetCommand = defineCommand39({
4874
+ var yoloSetCommand = defineCommand38({
5027
4875
  meta: {
5028
4876
  name: "set",
5029
4877
  description: "Write a YOLO-policy on a DDISA agent you own"
@@ -5071,12 +4919,12 @@ var yoloSetCommand = defineCommand39({
5071
4919
  const denyPatterns = parseList(args.deny);
5072
4920
  const denyRiskThreshold = args["deny-risk"] ?? null;
5073
4921
  const expiresAt = parseExpiresIn(args["expires-in"]);
5074
- consola35.info(`Setting YOLO-policy on ${email}`);
5075
- consola35.info(` mode: ${mode}`);
5076
- if (allowPatterns.length) consola35.info(` allow_patterns: ${allowPatterns.join(", ")}`);
5077
- if (denyPatterns.length) consola35.info(` deny_patterns: ${denyPatterns.join(", ")}`);
5078
- if (denyRiskThreshold) consola35.info(` deny_risk: ${denyRiskThreshold}`);
5079
- if (expiresAt) consola35.info(` expires_at: ${new Date(expiresAt * 1e3).toISOString()}`);
4922
+ consola33.info(`Setting YOLO-policy on ${email}`);
4923
+ consola33.info(` mode: ${mode}`);
4924
+ if (allowPatterns.length) consola33.info(` allow_patterns: ${allowPatterns.join(", ")}`);
4925
+ if (denyPatterns.length) consola33.info(` deny_patterns: ${denyPatterns.join(", ")}`);
4926
+ if (denyRiskThreshold) consola33.info(` deny_risk: ${denyRiskThreshold}`);
4927
+ if (expiresAt) consola33.info(` expires_at: ${new Date(expiresAt * 1e3).toISOString()}`);
5080
4928
  const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`;
5081
4929
  const res = await fetch(url, {
5082
4930
  method: "PUT",
@@ -5096,7 +4944,7 @@ var yoloSetCommand = defineCommand39({
5096
4944
  const text = await res.text().catch(() => "");
5097
4945
  throw new CliError(`PUT /yolo-policy failed (${res.status}): ${text}`);
5098
4946
  }
5099
- consola35.success(`YOLO-policy applied to ${email}`);
4947
+ consola33.success(`YOLO-policy applied to ${email}`);
5100
4948
  }
5101
4949
  });
5102
4950
  function parseList(s) {
@@ -5114,9 +4962,9 @@ function parseExpiresIn(s) {
5114
4962
  }
5115
4963
 
5116
4964
  // src/commands/yolo/show.ts
5117
- import { defineCommand as defineCommand40 } from "citty";
5118
- import consola36 from "consola";
5119
- var yoloShowCommand = defineCommand40({
4965
+ import { defineCommand as defineCommand39 } from "citty";
4966
+ import consola34 from "consola";
4967
+ var yoloShowCommand = defineCommand39({
5120
4968
  meta: {
5121
4969
  name: "show",
5122
4970
  description: "Print the YOLO-policy currently set on a DDISA agent"
@@ -5153,17 +5001,17 @@ var yoloShowCommand = defineCommand40({
5153
5001
  console.log(JSON.stringify(policy, null, 2));
5154
5002
  return;
5155
5003
  }
5156
- consola36.info(`YOLO-policy for ${email}`);
5157
- consola36.info(` mode: ${policy.mode}`);
5158
- consola36.info(` allow_patterns: ${policy.allowPatterns.length ? policy.allowPatterns.join(", ") : "(none)"}`);
5159
- consola36.info(` deny_patterns: ${policy.denyPatterns.length ? policy.denyPatterns.join(", ") : "(none)"}`);
5160
- consola36.info(` deny_risk: ${policy.denyRiskThreshold ?? "(none)"}`);
5161
- consola36.info(` expires_at: ${policy.expiresAt ? new Date(policy.expiresAt * 1e3).toISOString() : "(never)"}`);
5004
+ consola34.info(`YOLO-policy for ${email}`);
5005
+ consola34.info(` mode: ${policy.mode}`);
5006
+ consola34.info(` allow_patterns: ${policy.allowPatterns.length ? policy.allowPatterns.join(", ") : "(none)"}`);
5007
+ consola34.info(` deny_patterns: ${policy.denyPatterns.length ? policy.denyPatterns.join(", ") : "(none)"}`);
5008
+ consola34.info(` deny_risk: ${policy.denyRiskThreshold ?? "(none)"}`);
5009
+ consola34.info(` expires_at: ${policy.expiresAt ? new Date(policy.expiresAt * 1e3).toISOString() : "(never)"}`);
5162
5010
  }
5163
5011
  });
5164
5012
 
5165
5013
  // src/commands/yolo/index.ts
5166
- var yoloCommand = defineCommand41({
5014
+ var yoloCommand = defineCommand40({
5167
5015
  meta: {
5168
5016
  name: "yolo",
5169
5017
  description: "Manage YOLO-policies on DDISA agents you own \u2014 auto-approve grant patterns at the IdP layer (allow-list) or block dangerous ones outright (deny-list)."
@@ -5176,15 +5024,15 @@ var yoloCommand = defineCommand41({
5176
5024
  });
5177
5025
 
5178
5026
  // src/commands/adapter/index.ts
5179
- import { defineCommand as defineCommand42 } from "citty";
5180
- import consola37 from "consola";
5181
- var adapterCommand = defineCommand42({
5027
+ import { defineCommand as defineCommand41 } from "citty";
5028
+ import consola35 from "consola";
5029
+ var adapterCommand = defineCommand41({
5182
5030
  meta: {
5183
5031
  name: "adapter",
5184
5032
  description: "Manage CLI adapters"
5185
5033
  },
5186
5034
  subCommands: {
5187
- list: defineCommand42({
5035
+ list: defineCommand41({
5188
5036
  meta: {
5189
5037
  name: "list",
5190
5038
  description: "List available adapters"
@@ -5215,7 +5063,7 @@ var adapterCommand = defineCommand42({
5215
5063
  `);
5216
5064
  return;
5217
5065
  }
5218
- consola37.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
5066
+ consola35.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
5219
5067
  for (const a of index2.adapters) {
5220
5068
  const installed = isInstalled(a.id, false) ? " [installed]" : "";
5221
5069
  console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}${installed}`);
@@ -5237,7 +5085,7 @@ var adapterCommand = defineCommand42({
5237
5085
  return;
5238
5086
  }
5239
5087
  if (local.length === 0) {
5240
- consola37.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
5088
+ consola35.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
5241
5089
  return;
5242
5090
  }
5243
5091
  for (const a of local) {
@@ -5245,7 +5093,7 @@ var adapterCommand = defineCommand42({
5245
5093
  }
5246
5094
  }
5247
5095
  }),
5248
- install: defineCommand42({
5096
+ install: defineCommand41({
5249
5097
  meta: {
5250
5098
  name: "install",
5251
5099
  description: "Install an adapter from the registry"
@@ -5274,24 +5122,24 @@ var adapterCommand = defineCommand42({
5274
5122
  for (const id of ids) {
5275
5123
  const entry = findAdapter(index, id);
5276
5124
  if (!entry) {
5277
- consola37.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
5125
+ consola35.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
5278
5126
  continue;
5279
5127
  }
5280
5128
  const conflicts = findConflictingAdapters(entry.executable, id);
5281
5129
  if (conflicts.length > 0) {
5282
5130
  for (const c2 of conflicts) {
5283
- consola37.warn(`Conflicting adapter found: ${c2.path} (id: ${c2.adapterId}, executable: ${c2.executable})`);
5284
- consola37.warn(` Remove it with: apes adapter remove ${c2.adapterId}`);
5131
+ consola35.warn(`Conflicting adapter found: ${c2.path} (id: ${c2.adapterId}, executable: ${c2.executable})`);
5132
+ consola35.warn(` Remove it with: apes adapter remove ${c2.adapterId}`);
5285
5133
  }
5286
5134
  }
5287
5135
  const result = await installAdapter(entry, { local });
5288
5136
  const verb = result.updated ? "Updated" : "Installed";
5289
- consola37.success(`${verb} ${result.id} \u2192 ${result.path}`);
5290
- consola37.info(`Digest: ${result.digest}`);
5137
+ consola35.success(`${verb} ${result.id} \u2192 ${result.path}`);
5138
+ consola35.info(`Digest: ${result.digest}`);
5291
5139
  }
5292
5140
  }
5293
5141
  }),
5294
- remove: defineCommand42({
5142
+ remove: defineCommand41({
5295
5143
  meta: {
5296
5144
  name: "remove",
5297
5145
  description: "Remove an installed adapter"
@@ -5314,9 +5162,9 @@ var adapterCommand = defineCommand42({
5314
5162
  let failed = false;
5315
5163
  for (const id of ids) {
5316
5164
  if (removeAdapter(id, local)) {
5317
- consola37.success(`Removed adapter: ${id}`);
5165
+ consola35.success(`Removed adapter: ${id}`);
5318
5166
  } else {
5319
- consola37.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
5167
+ consola35.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
5320
5168
  failed = true;
5321
5169
  }
5322
5170
  }
@@ -5324,7 +5172,7 @@ var adapterCommand = defineCommand42({
5324
5172
  throw new CliError("Some adapters could not be removed");
5325
5173
  }
5326
5174
  }),
5327
- info: defineCommand42({
5175
+ info: defineCommand41({
5328
5176
  meta: {
5329
5177
  name: "info",
5330
5178
  description: "Show detailed adapter information"
@@ -5366,7 +5214,7 @@ var adapterCommand = defineCommand42({
5366
5214
  }
5367
5215
  }
5368
5216
  }),
5369
- search: defineCommand42({
5217
+ search: defineCommand41({
5370
5218
  meta: {
5371
5219
  name: "search",
5372
5220
  description: "Search adapters in the registry"
@@ -5398,7 +5246,7 @@ var adapterCommand = defineCommand42({
5398
5246
  return;
5399
5247
  }
5400
5248
  if (results.length === 0) {
5401
- consola37.info(`No adapters matching "${query}"`);
5249
+ consola35.info(`No adapters matching "${query}"`);
5402
5250
  return;
5403
5251
  }
5404
5252
  for (const a of results) {
@@ -5407,7 +5255,7 @@ var adapterCommand = defineCommand42({
5407
5255
  }
5408
5256
  }
5409
5257
  }),
5410
- update: defineCommand42({
5258
+ update: defineCommand41({
5411
5259
  meta: {
5412
5260
  name: "update",
5413
5261
  description: "Update installed adapters"
@@ -5433,33 +5281,33 @@ var adapterCommand = defineCommand42({
5433
5281
  const targetId = args.id ? String(args.id) : void 0;
5434
5282
  const targets = targetId ? [targetId] : index.adapters.map((a) => a.id).filter((id) => isInstalled(id, false));
5435
5283
  if (targets.length === 0) {
5436
- consola37.info("No adapters installed to update.");
5284
+ consola35.info("No adapters installed to update.");
5437
5285
  return;
5438
5286
  }
5439
5287
  for (const id of targets) {
5440
5288
  const entry = findAdapter(index, id);
5441
5289
  if (!entry) {
5442
- consola37.warn(`${id}: not found in registry, skipping`);
5290
+ consola35.warn(`${id}: not found in registry, skipping`);
5443
5291
  continue;
5444
5292
  }
5445
5293
  const localDigest = getInstalledDigest(id, false);
5446
5294
  if (localDigest === entry.digest) {
5447
- consola37.info(`${id}: already up to date`);
5295
+ consola35.info(`${id}: already up to date`);
5448
5296
  continue;
5449
5297
  }
5450
5298
  if (localDigest && !args.yes) {
5451
- consola37.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
5452
- consola37.info(` Old: ${localDigest}`);
5453
- consola37.info(` New: ${entry.digest}`);
5454
- consola37.info(" Use --yes to confirm");
5299
+ consola35.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
5300
+ consola35.info(` Old: ${localDigest}`);
5301
+ consola35.info(` New: ${entry.digest}`);
5302
+ consola35.info(" Use --yes to confirm");
5455
5303
  continue;
5456
5304
  }
5457
5305
  const result = await installAdapter(entry);
5458
- consola37.success(`Updated ${result.id} \u2192 ${result.path}`);
5306
+ consola35.success(`Updated ${result.id} \u2192 ${result.path}`);
5459
5307
  }
5460
5308
  }
5461
5309
  }),
5462
- verify: defineCommand42({
5310
+ verify: defineCommand41({
5463
5311
  meta: {
5464
5312
  name: "verify",
5465
5313
  description: "Verify installed adapter against registry digest"
@@ -5492,7 +5340,7 @@ var adapterCommand = defineCommand42({
5492
5340
  if (!localDigest)
5493
5341
  throw new Error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
5494
5342
  if (localDigest === entry.digest) {
5495
- consola37.success(`${id}: digest matches registry`);
5343
+ consola35.success(`${id}: digest matches registry`);
5496
5344
  } else {
5497
5345
  console.log(` Local: ${localDigest}`);
5498
5346
  console.log(` Registry: ${entry.digest}`);
@@ -5505,10 +5353,10 @@ var adapterCommand = defineCommand42({
5505
5353
 
5506
5354
  // src/commands/run.ts
5507
5355
  import { execFileSync as execFileSync11 } from "child_process";
5508
- import { hostname as hostname6 } from "os";
5356
+ import { hostname as hostname5 } from "os";
5509
5357
  import { basename } from "path";
5510
- import { defineCommand as defineCommand43 } from "citty";
5511
- import consola38 from "consola";
5358
+ import { defineCommand as defineCommand42 } from "citty";
5359
+ import consola36 from "consola";
5512
5360
  function shouldWaitForGrant(args) {
5513
5361
  return args.wait === true || process.env.APE_WAIT === "1";
5514
5362
  }
@@ -5545,7 +5393,7 @@ function printPendingGrantInfo(grant, idp) {
5545
5393
  const statusCmd = `apes grants status ${grant.id}`;
5546
5394
  const executeCmd = `apes grants run ${grant.id}`;
5547
5395
  if (mode === "human") {
5548
- consola38.success(`Grant ${grant.id} created \u2014 awaiting your approval`);
5396
+ consola36.success(`Grant ${grant.id} created \u2014 awaiting your approval`);
5549
5397
  console.log(` Approve in browser: ${approveUrl}`);
5550
5398
  console.log(` Check status: ${statusCmd}`);
5551
5399
  console.log(` Run after approval: ${executeCmd}`);
@@ -5555,7 +5403,7 @@ function printPendingGrantInfo(grant, idp) {
5555
5403
  return;
5556
5404
  }
5557
5405
  const maxMin = getPollMaxMinutes();
5558
- consola38.success(`Grant ${grant.id} created (pending approval)`);
5406
+ consola36.success(`Grant ${grant.id} created (pending approval)`);
5559
5407
  console.log(` Approve: ${approveUrl}`);
5560
5408
  console.log(` Status: ${statusCmd} [--json]`);
5561
5409
  console.log(` Execute: ${executeCmd} --wait`);
@@ -5577,7 +5425,7 @@ function printPendingGrantInfo(grant, idp) {
5577
5425
  console.log(' Tip: Approve as "timed" or "always" in the browser to let this');
5578
5426
  console.log(" grant be reused on subsequent invocations without re-approval.");
5579
5427
  }
5580
- var runCommand = defineCommand43({
5428
+ var runCommand = defineCommand42({
5581
5429
  meta: {
5582
5430
  name: "run",
5583
5431
  description: "Execute a grant-secured command"
@@ -5666,7 +5514,7 @@ async function runShellMode(command, args) {
5666
5514
  const adapterHandled = await tryAdapterModeFromShell(command, idp, args);
5667
5515
  if (adapterHandled) return;
5668
5516
  const grantsUrl = await getGrantsEndpoint(idp);
5669
- const targetHost = args.host || hostname6();
5517
+ const targetHost = args.host || hostname5();
5670
5518
  try {
5671
5519
  const grants = await apiFetch(
5672
5520
  `${grantsUrl}?requester=${encodeURIComponent(auth.email)}&status=approved&limit=20`
@@ -5680,7 +5528,7 @@ async function runShellMode(command, args) {
5680
5528
  }
5681
5529
  } catch {
5682
5530
  }
5683
- consola38.info(`Requesting ape-shell session grant on ${targetHost}`);
5531
+ consola36.info(`Requesting ape-shell session grant on ${targetHost}`);
5684
5532
  const grant = await apiFetch(grantsUrl, {
5685
5533
  method: "POST",
5686
5534
  body: {
@@ -5700,8 +5548,8 @@ async function runShellMode(command, args) {
5700
5548
  host: targetHost
5701
5549
  });
5702
5550
  if (shouldWaitForGrant(args)) {
5703
- consola38.info(`Grant requested: ${grant.id}`);
5704
- consola38.info("Waiting for approval...");
5551
+ consola36.info(`Grant requested: ${grant.id}`);
5552
+ consola36.info("Waiting for approval...");
5705
5553
  const maxWait = 3e5;
5706
5554
  const interval = 3e3;
5707
5555
  const start = Date.now();
@@ -5732,13 +5580,13 @@ async function tryAdapterModeFromShell(command, idp, args) {
5732
5580
  try {
5733
5581
  resolved = await resolveCommand(loaded, [normalizedExecutable, ...parsed.argv]);
5734
5582
  } catch (err) {
5735
- consola38.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
5583
+ consola36.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
5736
5584
  return false;
5737
5585
  }
5738
5586
  try {
5739
5587
  const existingGrantId = await findExistingGrant(resolved, idp);
5740
5588
  if (existingGrantId) {
5741
- consola38.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
5589
+ consola36.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
5742
5590
  const token = await fetchGrantToken(idp, existingGrantId);
5743
5591
  await verifyAndExecute(token, resolved, existingGrantId);
5744
5592
  return true;
@@ -5746,7 +5594,7 @@ async function tryAdapterModeFromShell(command, idp, args) {
5746
5594
  } catch {
5747
5595
  }
5748
5596
  const approval = args.approval ?? "once";
5749
- consola38.info(`Requesting grant for: ${resolved.detail.display}`);
5597
+ consola36.info(`Requesting grant for: ${resolved.detail.display}`);
5750
5598
  const grant = await createShapesGrant(resolved, {
5751
5599
  idp,
5752
5600
  approval,
@@ -5754,19 +5602,19 @@ async function tryAdapterModeFromShell(command, idp, args) {
5754
5602
  });
5755
5603
  if (grant.similar_grants?.similar_grants?.length) {
5756
5604
  const n2 = grant.similar_grants.similar_grants.length;
5757
- consola38.info("");
5758
- consola38.info(` Similar grant(s) found (${n2}). Your approver can extend an existing grant to cover this request.`);
5605
+ consola36.info("");
5606
+ consola36.info(` Similar grant(s) found (${n2}). Your approver can extend an existing grant to cover this request.`);
5759
5607
  }
5760
5608
  notifyGrantPending({
5761
5609
  grantId: grant.id,
5762
5610
  approveUrl: `${idp}/grant-approval?grant_id=${grant.id}`,
5763
5611
  command: resolved.detail?.display || parsed?.raw || "unknown",
5764
5612
  audience: resolved.adapter?.cli?.audience ?? "shapes",
5765
- host: args.host || hostname6()
5613
+ host: args.host || hostname5()
5766
5614
  });
5767
5615
  if (shouldWaitForGrant(args)) {
5768
- consola38.info(`Grant requested: ${grant.id}`);
5769
- consola38.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5616
+ consola36.info(`Grant requested: ${grant.id}`);
5617
+ consola36.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5770
5618
  const status = await waitForGrantStatus(idp, grant.id);
5771
5619
  if (status !== "approved")
5772
5620
  throw new CliError(`Grant ${status}`);
@@ -5840,7 +5688,7 @@ async function runAdapterMode(command, rawArgs, args) {
5840
5688
  try {
5841
5689
  const existingGrantId = await findExistingGrant(resolved, idp);
5842
5690
  if (existingGrantId) {
5843
- consola38.info(`Reusing existing grant: ${existingGrantId}`);
5691
+ consola36.info(`Reusing existing grant: ${existingGrantId}`);
5844
5692
  const token = await fetchGrantToken(idp, existingGrantId);
5845
5693
  await verifyAndExecute(token, resolved, existingGrantId);
5846
5694
  return;
@@ -5854,17 +5702,17 @@ async function runAdapterMode(command, rawArgs, args) {
5854
5702
  });
5855
5703
  if (grant.similar_grants?.similar_grants?.length) {
5856
5704
  const n2 = grant.similar_grants.similar_grants.length;
5857
- consola38.info("");
5858
- consola38.info(` Similar grant(s) found (${n2}). Your approver can extend an existing grant to cover this request.`);
5705
+ consola36.info("");
5706
+ consola36.info(` Similar grant(s) found (${n2}). Your approver can extend an existing grant to cover this request.`);
5859
5707
  if (grant.similar_grants.widened_details?.length) {
5860
5708
  const wider = grant.similar_grants.widened_details.map((d) => d.permission).join(", ");
5861
- consola38.info(` Broader scope: ${wider}`);
5709
+ consola36.info(` Broader scope: ${wider}`);
5862
5710
  }
5863
- consola38.info("");
5711
+ consola36.info("");
5864
5712
  }
5865
5713
  if (shouldWaitForGrant(args)) {
5866
- consola38.info(`Grant requested: ${grant.id}`);
5867
- consola38.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5714
+ consola36.info(`Grant requested: ${grant.id}`);
5715
+ consola36.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5868
5716
  const status = await waitForGrantStatus(idp, grant.id);
5869
5717
  if (status !== "approved")
5870
5718
  throw new Error(`Grant ${status}`);
@@ -5883,8 +5731,8 @@ async function runAudienceMode(audience, action, args) {
5883
5731
  const idp = getIdpUrl(args.idp);
5884
5732
  const grantsUrl = await getGrantsEndpoint(idp);
5885
5733
  const command = action.split(" ");
5886
- const targetHost = args.host || hostname6();
5887
- consola38.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
5734
+ const targetHost = args.host || hostname5();
5735
+ consola36.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
5888
5736
  const grant = await apiFetch(grantsUrl, {
5889
5737
  method: "POST",
5890
5738
  body: {
@@ -5901,9 +5749,9 @@ async function runAudienceMode(audience, action, args) {
5901
5749
  printPendingGrantInfo(grant, idp);
5902
5750
  throw new CliExit(getAsyncExitCode());
5903
5751
  }
5904
- consola38.success(`Grant requested: ${grant.id}`);
5905
- consola38.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5906
- consola38.info("Waiting for approval...");
5752
+ consola36.success(`Grant requested: ${grant.id}`);
5753
+ consola36.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5754
+ consola36.info("Waiting for approval...");
5907
5755
  const maxWait = 15 * 60 * 1e3;
5908
5756
  const interval = 3e3;
5909
5757
  const start = Date.now();
@@ -5911,7 +5759,7 @@ async function runAudienceMode(audience, action, args) {
5911
5759
  while (Date.now() - start < maxWait) {
5912
5760
  const status = await apiFetch(`${grantsUrl}/${grant.id}`);
5913
5761
  if (status.status === "approved") {
5914
- consola38.success("Grant approved!");
5762
+ consola36.success("Grant approved!");
5915
5763
  approved = true;
5916
5764
  break;
5917
5765
  }
@@ -5926,12 +5774,12 @@ async function runAudienceMode(audience, action, args) {
5926
5774
  `Grant approval timed out after ${minutes} min (still pending). Check your DDISA inbox at ${idp}/grant-approval?grant_id=${grant.id} \u2014 if approved later, re-run the same \`apes run\` command and it will reuse the grant.`
5927
5775
  );
5928
5776
  }
5929
- consola38.info("Fetching grant token...");
5777
+ consola36.info("Fetching grant token...");
5930
5778
  const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, {
5931
5779
  method: "POST"
5932
5780
  });
5933
5781
  if (audience === "escapes") {
5934
- consola38.info(`Executing: ${command.join(" ")}`);
5782
+ consola36.info(`Executing: ${command.join(" ")}`);
5935
5783
  try {
5936
5784
  const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
5937
5785
  execFileSync11(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
@@ -5949,8 +5797,8 @@ async function runAudienceMode(audience, action, args) {
5949
5797
 
5950
5798
  // src/commands/proxy.ts
5951
5799
  import { spawn as spawn2 } from "child_process";
5952
- import { defineCommand as defineCommand44 } from "citty";
5953
- import consola39 from "consola";
5800
+ import { defineCommand as defineCommand43 } from "citty";
5801
+ import consola37 from "consola";
5954
5802
 
5955
5803
  // src/proxy/config.ts
5956
5804
  function buildDefaultProxyConfigToml(opts) {
@@ -5984,10 +5832,10 @@ note = "VPC-internal hostname suffix"
5984
5832
 
5985
5833
  // src/proxy/local-proxy.ts
5986
5834
  import { spawn } from "child_process";
5987
- import { mkdtempSync as mkdtempSync3, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "fs";
5835
+ import { mkdtempSync as mkdtempSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "fs";
5988
5836
  import { createRequire } from "module";
5989
5837
  import { tmpdir as tmpdir3 } from "os";
5990
- import { dirname as dirname4, join as join12, resolve as resolve3 } from "path";
5838
+ import { dirname as dirname4, join as join13, resolve as resolve3 } from "path";
5991
5839
  var require2 = createRequire(import.meta.url);
5992
5840
  function findProxyBin() {
5993
5841
  const pkgPath = require2.resolve("@openape/proxy/package.json");
@@ -5999,9 +5847,9 @@ function findProxyBin() {
5999
5847
  return resolve3(dirname4(pkgPath), binRel);
6000
5848
  }
6001
5849
  async function startEphemeralProxy(configToml) {
6002
- const tmpDir = mkdtempSync3(join12(tmpdir3(), "openape-proxy-"));
6003
- const configPath = join12(tmpDir, "config.toml");
6004
- writeFileSync7(configPath, configToml, { mode: 384 });
5850
+ const tmpDir = mkdtempSync3(join13(tmpdir3(), "openape-proxy-"));
5851
+ const configPath = join13(tmpDir, "config.toml");
5852
+ writeFileSync8(configPath, configToml, { mode: 384 });
6005
5853
  const binPath = findProxyBin();
6006
5854
  const child = spawn(process.execPath, [binPath, "-c", configPath], {
6007
5855
  stdio: ["ignore", "pipe", "pipe"],
@@ -6093,10 +5941,10 @@ function resolveProxyConfigOptions() {
6093
5941
  77
6094
5942
  );
6095
5943
  }
6096
- consola39.info(`[apes proxy] IdP-mediated mode \u2014 agent=${auth.email}, idp=${auth.idp}`);
5944
+ consola37.info(`[apes proxy] IdP-mediated mode \u2014 agent=${auth.email}, idp=${auth.idp}`);
6097
5945
  return { agentEmail: auth.email, idpUrl: auth.idp, mediated: true };
6098
5946
  }
6099
- var proxyCommand = defineCommand44({
5947
+ var proxyCommand = defineCommand43({
6100
5948
  meta: {
6101
5949
  name: "proxy",
6102
5950
  description: "Run a command with HTTPS_PROXY routed through the OpenApe egress proxy."
@@ -6118,12 +5966,12 @@ var proxyCommand = defineCommand44({
6118
5966
  let close = null;
6119
5967
  if (reuseUrl) {
6120
5968
  proxyUrl = reuseUrl;
6121
- consola39.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`);
5969
+ consola37.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`);
6122
5970
  } else {
6123
5971
  const ephemeral = await startEphemeralProxy(buildDefaultProxyConfigToml(resolveProxyConfigOptions()));
6124
5972
  proxyUrl = ephemeral.url;
6125
5973
  close = ephemeral.close;
6126
- consola39.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`);
5974
+ consola37.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`);
6127
5975
  }
6128
5976
  const noProxy = process.env.NO_PROXY ?? process.env.no_proxy ?? "127.0.0.1,localhost";
6129
5977
  const childEnv = {
@@ -6155,7 +6003,7 @@ var proxyCommand = defineCommand44({
6155
6003
  else resolveExit(code ?? 0);
6156
6004
  });
6157
6005
  child.once("error", (err) => {
6158
- consola39.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message);
6006
+ consola37.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message);
6159
6007
  resolveExit(127);
6160
6008
  });
6161
6009
  });
@@ -6169,8 +6017,8 @@ function signalNumber(signal) {
6169
6017
  }
6170
6018
 
6171
6019
  // src/commands/explain.ts
6172
- import { defineCommand as defineCommand45 } from "citty";
6173
- var explainCommand = defineCommand45({
6020
+ import { defineCommand as defineCommand44 } from "citty";
6021
+ var explainCommand = defineCommand44({
6174
6022
  meta: {
6175
6023
  name: "explain",
6176
6024
  description: "Show what permission a command would need"
@@ -6208,9 +6056,9 @@ var explainCommand = defineCommand45({
6208
6056
  });
6209
6057
 
6210
6058
  // src/commands/config/get.ts
6211
- import { defineCommand as defineCommand46 } from "citty";
6212
- import consola40 from "consola";
6213
- var configGetCommand = defineCommand46({
6059
+ import { defineCommand as defineCommand45 } from "citty";
6060
+ import consola38 from "consola";
6061
+ var configGetCommand = defineCommand45({
6214
6062
  meta: {
6215
6063
  name: "get",
6216
6064
  description: "Get a configuration value"
@@ -6230,7 +6078,7 @@ var configGetCommand = defineCommand46({
6230
6078
  if (idp)
6231
6079
  console.log(idp);
6232
6080
  else
6233
- consola40.info("No IdP configured.");
6081
+ consola38.info("No IdP configured.");
6234
6082
  break;
6235
6083
  }
6236
6084
  case "email": {
@@ -6238,7 +6086,7 @@ var configGetCommand = defineCommand46({
6238
6086
  if (auth?.email)
6239
6087
  console.log(auth.email);
6240
6088
  else
6241
- consola40.info("Not logged in.");
6089
+ consola38.info("Not logged in.");
6242
6090
  break;
6243
6091
  }
6244
6092
  default: {
@@ -6251,7 +6099,7 @@ var configGetCommand = defineCommand46({
6251
6099
  if (sectionObj && field in sectionObj) {
6252
6100
  console.log(sectionObj[field]);
6253
6101
  } else {
6254
- consola40.info(`Key "${key}" not set.`);
6102
+ consola38.info(`Key "${key}" not set.`);
6255
6103
  }
6256
6104
  } else {
6257
6105
  throw new CliError(`Unknown key: "${key}". Use: idp, email, defaults.idp, defaults.approval, agent.key, agent.email`);
@@ -6262,9 +6110,9 @@ var configGetCommand = defineCommand46({
6262
6110
  });
6263
6111
 
6264
6112
  // src/commands/config/set.ts
6265
- import { defineCommand as defineCommand47 } from "citty";
6266
- import consola41 from "consola";
6267
- var configSetCommand = defineCommand47({
6113
+ import { defineCommand as defineCommand46 } from "citty";
6114
+ import consola39 from "consola";
6115
+ var configSetCommand = defineCommand46({
6268
6116
  meta: {
6269
6117
  name: "set",
6270
6118
  description: "Set a configuration value"
@@ -6300,12 +6148,12 @@ var configSetCommand = defineCommand47({
6300
6148
  throw new CliError(`Unknown section: "${section}". Use: defaults, agent`);
6301
6149
  }
6302
6150
  saveConfig(config);
6303
- consola41.success(`Set ${key} = ${value}`);
6151
+ consola39.success(`Set ${key} = ${value}`);
6304
6152
  }
6305
6153
  });
6306
6154
 
6307
6155
  // src/commands/fetch/index.ts
6308
- import { defineCommand as defineCommand48 } from "citty";
6156
+ import { defineCommand as defineCommand47 } from "citty";
6309
6157
  async function doRequest(method, url, body, contentType, raw, showHeaders) {
6310
6158
  const token = getAuthToken();
6311
6159
  if (!token) {
@@ -6341,13 +6189,13 @@ async function doRequest(method, url, body, contentType, raw, showHeaders) {
6341
6189
  throw new CliError(`HTTP ${response.status} ${response.statusText}`);
6342
6190
  }
6343
6191
  }
6344
- var fetchCommand = defineCommand48({
6192
+ var fetchCommand = defineCommand47({
6345
6193
  meta: {
6346
6194
  name: "fetch",
6347
6195
  description: "Make authenticated HTTP requests"
6348
6196
  },
6349
6197
  subCommands: {
6350
- get: defineCommand48({
6198
+ get: defineCommand47({
6351
6199
  meta: {
6352
6200
  name: "get",
6353
6201
  description: "GET request with auth token"
@@ -6373,7 +6221,7 @@ var fetchCommand = defineCommand48({
6373
6221
  await doRequest("GET", String(args.url), void 0, "application/json", Boolean(args.raw), Boolean(args.headers));
6374
6222
  }
6375
6223
  }),
6376
- post: defineCommand48({
6224
+ post: defineCommand47({
6377
6225
  meta: {
6378
6226
  name: "post",
6379
6227
  description: "POST request with auth token"
@@ -6412,8 +6260,8 @@ var fetchCommand = defineCommand48({
6412
6260
  });
6413
6261
 
6414
6262
  // src/commands/mcp/index.ts
6415
- import { defineCommand as defineCommand49 } from "citty";
6416
- var mcpCommand = defineCommand49({
6263
+ import { defineCommand as defineCommand48 } from "citty";
6264
+ var mcpCommand = defineCommand48({
6417
6265
  meta: {
6418
6266
  name: "mcp",
6419
6267
  description: "Start MCP server for AI agents"
@@ -6436,25 +6284,25 @@ var mcpCommand = defineCommand49({
6436
6284
  if (transport !== "stdio" && transport !== "sse") {
6437
6285
  throw new Error('Transport must be "stdio" or "sse"');
6438
6286
  }
6439
- const { startMcpServer } = await import("./server-F3ALNNYS.js");
6287
+ const { startMcpServer } = await import("./server-HYDAVEQI.js");
6440
6288
  await startMcpServer(transport, port);
6441
6289
  }
6442
6290
  });
6443
6291
 
6444
6292
  // src/commands/init/index.ts
6445
- import { existsSync as existsSync14, copyFileSync, writeFileSync as writeFileSync8 } from "fs";
6293
+ import { existsSync as existsSync15, copyFileSync, writeFileSync as writeFileSync9 } from "fs";
6446
6294
  import { randomBytes } from "crypto";
6447
6295
  import { execFileSync as execFileSync12 } from "child_process";
6448
- import { join as join13 } from "path";
6449
- import { defineCommand as defineCommand50 } from "citty";
6450
- import consola42 from "consola";
6296
+ import { join as join14 } from "path";
6297
+ import { defineCommand as defineCommand49 } from "citty";
6298
+ import consola40 from "consola";
6451
6299
  var DEFAULT_IDP_URL = "https://id.openape.at";
6452
6300
  async function downloadTemplate(repo, targetDir) {
6453
6301
  const { downloadTemplate: gigetDownload } = await import("giget");
6454
6302
  await gigetDownload(`gh:${repo}`, { dir: targetDir, force: false });
6455
6303
  }
6456
6304
  function installDeps(dir) {
6457
- const hasLockFile = (name) => existsSync14(join13(dir, name));
6305
+ const hasLockFile = (name) => existsSync15(join14(dir, name));
6458
6306
  if (hasLockFile("pnpm-lock.yaml")) {
6459
6307
  execFileSync12("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
6460
6308
  } else if (hasLockFile("bun.lockb")) {
@@ -6464,20 +6312,20 @@ function installDeps(dir) {
6464
6312
  }
6465
6313
  }
6466
6314
  async function promptChoice(message, choices) {
6467
- const result = await consola42.prompt(message, { type: "select", options: choices });
6315
+ const result = await consola40.prompt(message, { type: "select", options: choices });
6468
6316
  if (typeof result === "symbol") {
6469
6317
  throw new CliExit(0);
6470
6318
  }
6471
6319
  return result;
6472
6320
  }
6473
6321
  async function promptText(message, defaultValue) {
6474
- const result = await consola42.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
6322
+ const result = await consola40.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
6475
6323
  if (typeof result === "symbol") {
6476
6324
  throw new CliExit(0);
6477
6325
  }
6478
6326
  return result || defaultValue || "";
6479
6327
  }
6480
- var initCommand = defineCommand50({
6328
+ var initCommand = defineCommand49({
6481
6329
  meta: {
6482
6330
  name: "init",
6483
6331
  description: "Scaffold a new OpenApe project"
@@ -6519,23 +6367,23 @@ var initCommand = defineCommand50({
6519
6367
  });
6520
6368
  async function initSP(targetDir) {
6521
6369
  const dir = targetDir || "my-app";
6522
- if (existsSync14(join13(dir, "package.json"))) {
6370
+ if (existsSync15(join14(dir, "package.json"))) {
6523
6371
  throw new CliError(`Directory "${dir}" already contains a project.`);
6524
6372
  }
6525
- consola42.start("Scaffolding SP starter...");
6373
+ consola40.start("Scaffolding SP starter...");
6526
6374
  await downloadTemplate("openape-ai/openape-sp-starter", dir);
6527
- consola42.success("Scaffolded from openape-sp-starter");
6528
- consola42.start("Installing dependencies...");
6375
+ consola40.success("Scaffolded from openape-sp-starter");
6376
+ consola40.start("Installing dependencies...");
6529
6377
  installDeps(dir);
6530
- consola42.success("Dependencies installed");
6531
- const envExample = join13(dir, ".env.example");
6532
- const envFile = join13(dir, ".env");
6533
- if (existsSync14(envExample) && !existsSync14(envFile)) {
6378
+ consola40.success("Dependencies installed");
6379
+ const envExample = join14(dir, ".env.example");
6380
+ const envFile = join14(dir, ".env");
6381
+ if (existsSync15(envExample) && !existsSync15(envFile)) {
6534
6382
  copyFileSync(envExample, envFile);
6535
- consola42.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
6383
+ consola40.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
6536
6384
  }
6537
6385
  console.log("");
6538
- consola42.box([
6386
+ consola40.box([
6539
6387
  `cd ${dir}`,
6540
6388
  "npm run dev",
6541
6389
  "",
@@ -6544,7 +6392,7 @@ async function initSP(targetDir) {
6544
6392
  }
6545
6393
  async function initIdP(targetDir) {
6546
6394
  const dir = targetDir || "my-idp";
6547
- if (existsSync14(join13(dir, "package.json"))) {
6395
+ if (existsSync15(join14(dir, "package.json"))) {
6548
6396
  throw new CliError(`Directory "${dir}" already contains a project.`);
6549
6397
  }
6550
6398
  const domain = await promptText("Domain for the IdP", "localhost");
@@ -6554,15 +6402,15 @@ async function initIdP(targetDir) {
6554
6402
  "s3 (S3-compatible)"
6555
6403
  ]);
6556
6404
  const adminEmail = await promptText("Admin email");
6557
- consola42.start("Scaffolding IdP starter...");
6405
+ consola40.start("Scaffolding IdP starter...");
6558
6406
  await downloadTemplate("openape-ai/openape-idp-starter", dir);
6559
- consola42.success("Scaffolded from openape-idp-starter");
6560
- consola42.start("Installing dependencies...");
6407
+ consola40.success("Scaffolded from openape-idp-starter");
6408
+ consola40.start("Installing dependencies...");
6561
6409
  installDeps(dir);
6562
- consola42.success("Dependencies installed");
6410
+ consola40.success("Dependencies installed");
6563
6411
  const sessionSecret = randomBytes(32).toString("hex");
6564
6412
  const managementToken = randomBytes(32).toString("hex");
6565
- consola42.success("Secrets generated");
6413
+ consola40.success("Secrets generated");
6566
6414
  const isLocalhost = domain === "localhost";
6567
6415
  const origin = isLocalhost ? "http://localhost:3000" : `https://${domain}`;
6568
6416
  const envContent = [
@@ -6576,11 +6424,11 @@ async function initIdP(targetDir) {
6576
6424
  `NUXT_OPENAPE_RP_ID=${domain}`,
6577
6425
  `NUXT_OPENAPE_RP_ORIGIN=${origin}`
6578
6426
  ].join("\n");
6579
- writeFileSync8(join13(dir, ".env"), `${envContent}
6427
+ writeFileSync9(join14(dir, ".env"), `${envContent}
6580
6428
  `, { mode: 384 });
6581
- consola42.success(".env created");
6429
+ consola40.success(".env created");
6582
6430
  console.log("");
6583
- consola42.box([
6431
+ consola40.box([
6584
6432
  `cd ${dir}`,
6585
6433
  "npm run dev",
6586
6434
  "",
@@ -6597,11 +6445,11 @@ async function initIdP(targetDir) {
6597
6445
 
6598
6446
  // src/commands/enroll.ts
6599
6447
  import { Buffer as Buffer5 } from "buffer";
6600
- import { existsSync as existsSync15, readFileSync as readFileSync11 } from "fs";
6448
+ import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
6601
6449
  import { execFile as execFile2 } from "child_process";
6602
6450
  import { sign as sign2 } from "crypto";
6603
- import { defineCommand as defineCommand51 } from "citty";
6604
- import consola43 from "consola";
6451
+ import { defineCommand as defineCommand50 } from "citty";
6452
+ import consola41 from "consola";
6605
6453
  var DEFAULT_IDP_URL2 = "https://id.openape.at";
6606
6454
  var DEFAULT_KEY_PATH = "~/.ssh/id_ed25519";
6607
6455
  var POLL_INTERVAL = 3e3;
@@ -6613,7 +6461,7 @@ function openBrowser2(url) {
6613
6461
  }
6614
6462
  async function pollForEnrollment(idp, agentEmail, keyPath) {
6615
6463
  const resolvedKey = resolveKeyPath(keyPath);
6616
- const keyContent = readFileSync11(resolvedKey, "utf-8");
6464
+ const keyContent = readFileSync12(resolvedKey, "utf-8");
6617
6465
  const privateKey = loadEd25519PrivateKey(keyContent);
6618
6466
  const challengeUrl = await getAgentChallengeEndpoint(idp);
6619
6467
  const authenticateUrl = await getAgentAuthenticateEndpoint(idp);
@@ -6644,7 +6492,7 @@ async function pollForEnrollment(idp, agentEmail, keyPath) {
6644
6492
  }
6645
6493
  throw new Error("Enrollment timed out. Please check the browser and try again.");
6646
6494
  }
6647
- var enrollCommand = defineCommand51({
6495
+ var enrollCommand = defineCommand50({
6648
6496
  meta: {
6649
6497
  name: "enroll",
6650
6498
  description: "Enroll an agent with an Identity Provider"
@@ -6664,38 +6512,38 @@ var enrollCommand = defineCommand51({
6664
6512
  }
6665
6513
  },
6666
6514
  async run({ args }) {
6667
- const idp = args.idp || await consola43.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r3) => {
6515
+ const idp = args.idp || await consola41.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r3) => {
6668
6516
  if (typeof r3 === "symbol") throw new CliExit(0);
6669
6517
  return r3;
6670
6518
  }) || DEFAULT_IDP_URL2;
6671
- const agentName = args.name || await consola43.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r3) => {
6519
+ const agentName = args.name || await consola41.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r3) => {
6672
6520
  if (typeof r3 === "symbol") throw new CliExit(0);
6673
6521
  return r3;
6674
6522
  });
6675
6523
  if (!agentName) {
6676
6524
  throw new CliError("Agent name is required.");
6677
6525
  }
6678
- const keyPath = args.key || await consola43.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r3) => {
6526
+ const keyPath = args.key || await consola41.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r3) => {
6679
6527
  if (typeof r3 === "symbol") throw new CliExit(0);
6680
6528
  return r3;
6681
6529
  }) || DEFAULT_KEY_PATH;
6682
6530
  const resolvedKey = resolveKeyPath(keyPath);
6683
6531
  let publicKey;
6684
- if (existsSync15(resolvedKey)) {
6532
+ if (existsSync16(resolvedKey)) {
6685
6533
  publicKey = readPublicKey(resolvedKey);
6686
- consola43.success(`Using existing key ${keyPath}`);
6534
+ consola41.success(`Using existing key ${keyPath}`);
6687
6535
  } else {
6688
- consola43.start(`Generating Ed25519 key pair at ${keyPath}...`);
6536
+ consola41.start(`Generating Ed25519 key pair at ${keyPath}...`);
6689
6537
  publicKey = generateAndSaveKey(keyPath);
6690
- consola43.success(`Key pair generated at ${keyPath}`);
6538
+ consola41.success(`Key pair generated at ${keyPath}`);
6691
6539
  }
6692
6540
  const encodedKey = encodeURIComponent(publicKey);
6693
6541
  const enrollUrl = `${idp}/enroll?name=${encodeURIComponent(agentName)}&key=${encodedKey}`;
6694
- consola43.info("Opening browser for enrollment...");
6695
- consola43.info(`\u2192 ${idp}/enroll`);
6542
+ consola41.info("Opening browser for enrollment...");
6543
+ consola41.info(`\u2192 ${idp}/enroll`);
6696
6544
  openBrowser2(enrollUrl);
6697
6545
  console.log("");
6698
- const agentEmail = await consola43.prompt(
6546
+ const agentEmail = await consola41.prompt(
6699
6547
  "Agent email (shown in browser after enrollment)",
6700
6548
  { type: "text", placeholder: `agent+${agentName}@...` }
6701
6549
  ).then((r3) => {
@@ -6705,7 +6553,7 @@ var enrollCommand = defineCommand51({
6705
6553
  if (!agentEmail) {
6706
6554
  throw new CliError("Agent email is required to verify enrollment.");
6707
6555
  }
6708
- consola43.start("Verifying enrollment...");
6556
+ consola41.start("Verifying enrollment...");
6709
6557
  const { token, expiresIn } = await pollForEnrollment(idp, agentEmail, keyPath);
6710
6558
  saveAuth({
6711
6559
  idp,
@@ -6717,18 +6565,18 @@ var enrollCommand = defineCommand51({
6717
6565
  config.defaults = { ...config.defaults, idp };
6718
6566
  config.agent = { key: keyPath, email: agentEmail };
6719
6567
  saveConfig(config);
6720
- consola43.success(`Agent enrolled as ${agentEmail}`);
6721
- consola43.success("Config saved to ~/.config/apes/");
6568
+ consola41.success(`Agent enrolled as ${agentEmail}`);
6569
+ consola41.success("Config saved to ~/.config/apes/");
6722
6570
  console.log("");
6723
- consola43.info("Verify with: apes whoami");
6571
+ consola41.info("Verify with: apes whoami");
6724
6572
  }
6725
6573
  });
6726
6574
 
6727
6575
  // src/commands/register-user.ts
6728
- import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
6729
- import { defineCommand as defineCommand52 } from "citty";
6730
- import consola44 from "consola";
6731
- var registerUserCommand = defineCommand52({
6576
+ import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
6577
+ import { defineCommand as defineCommand51 } from "citty";
6578
+ import consola42 from "consola";
6579
+ var registerUserCommand = defineCommand51({
6732
6580
  meta: {
6733
6581
  name: "register-user",
6734
6582
  description: "Register a sub-user with SSH key"
@@ -6764,8 +6612,8 @@ var registerUserCommand = defineCommand52({
6764
6612
  throw new CliError("No IdP URL configured. Run `apes login` first.");
6765
6613
  }
6766
6614
  let publicKey = args.key;
6767
- if (existsSync16(args.key)) {
6768
- publicKey = readFileSync12(args.key, "utf-8").trim();
6615
+ if (existsSync17(args.key)) {
6616
+ publicKey = readFileSync13(args.key, "utf-8").trim();
6769
6617
  }
6770
6618
  if (!publicKey.startsWith("ssh-ed25519 ")) {
6771
6619
  throw new CliError("Public key must be in ssh-ed25519 format.");
@@ -6783,18 +6631,18 @@ var registerUserCommand = defineCommand52({
6783
6631
  ...userType ? { type: userType } : {}
6784
6632
  }
6785
6633
  });
6786
- consola44.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
6634
+ consola42.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
6787
6635
  }
6788
6636
  });
6789
6637
 
6790
6638
  // src/commands/utils/index.ts
6791
- import { defineCommand as defineCommand54 } from "citty";
6639
+ import { defineCommand as defineCommand53 } from "citty";
6792
6640
 
6793
6641
  // src/commands/utils/dig.ts
6794
- import { defineCommand as defineCommand53 } from "citty";
6795
- import consola45 from "consola";
6642
+ import { defineCommand as defineCommand52 } from "citty";
6643
+ import consola43 from "consola";
6796
6644
  import { resolveDDISA as resolveDDISA2 } from "@openape/core";
6797
- var digCommand = defineCommand53({
6645
+ var digCommand = defineCommand52({
6798
6646
  meta: {
6799
6647
  name: "dig",
6800
6648
  description: "Resolve DDISA IdP for a domain or email (admin/diag tool)"
@@ -6867,12 +6715,12 @@ var digCommand = defineCommand53({
6867
6715
  console.log(` domain: ${domain}`);
6868
6716
  console.log("");
6869
6717
  if (!result.ddisa.found) {
6870
- consola45.warn(`No DDISA record at _ddisa.${domain}`);
6718
+ consola43.warn(`No DDISA record at _ddisa.${domain}`);
6871
6719
  if (result.hint) console.log(`
6872
6720
  ${result.hint}`);
6873
6721
  throw new CliError(`No DDISA record found for ${domain}`);
6874
6722
  }
6875
- consola45.success(`_ddisa.${domain} \u2192 ${result.ddisa.idp}`);
6723
+ consola43.success(`_ddisa.${domain} \u2192 ${result.ddisa.idp}`);
6876
6724
  console.log(` Version: ${result.ddisa.version || "ddisa1"}`);
6877
6725
  console.log(` IdP URL: ${result.ddisa.idp}`);
6878
6726
  if (result.ddisa.mode) console.log(` Mode: ${result.ddisa.mode}`);
@@ -6882,13 +6730,13 @@ ${result.hint}`);
6882
6730
  return;
6883
6731
  }
6884
6732
  if (result.idpDiscovery.ok) {
6885
- consola45.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`);
6733
+ consola43.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`);
6886
6734
  if (result.idpDiscovery.issuer) console.log(` Issuer: ${result.idpDiscovery.issuer}`);
6887
6735
  if (result.idpDiscovery.ddisaVersion) console.log(` DDISA: v${result.idpDiscovery.ddisaVersion}`);
6888
6736
  if (result.idpDiscovery.authMethods?.length) console.log(` Auth: ${result.idpDiscovery.authMethods.join(", ")}`);
6889
6737
  if (result.idpDiscovery.grantTypes?.length) console.log(` Grants: ${result.idpDiscovery.grantTypes.join(", ")}`);
6890
6738
  } else {
6891
- consola45.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ""}`);
6739
+ consola43.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ""}`);
6892
6740
  if (result.hint) console.log(`
6893
6741
  ${result.hint}`);
6894
6742
  throw new CliError(`IdP at ${result.ddisa.idp} not reachable`);
@@ -6897,7 +6745,7 @@ ${result.hint}`);
6897
6745
  });
6898
6746
 
6899
6747
  // src/commands/utils/index.ts
6900
- var utilsCommand = defineCommand54({
6748
+ var utilsCommand = defineCommand53({
6901
6749
  meta: {
6902
6750
  name: "utils",
6903
6751
  description: "Admin/diagnostic utilities (dig, \u2026)"
@@ -6908,12 +6756,12 @@ var utilsCommand = defineCommand54({
6908
6756
  });
6909
6757
 
6910
6758
  // src/commands/sessions/index.ts
6911
- import { defineCommand as defineCommand57 } from "citty";
6759
+ import { defineCommand as defineCommand56 } from "citty";
6912
6760
 
6913
6761
  // src/commands/sessions/list.ts
6914
- import { defineCommand as defineCommand55 } from "citty";
6915
- import consola46 from "consola";
6916
- var sessionsListCommand = defineCommand55({
6762
+ import { defineCommand as defineCommand54 } from "citty";
6763
+ import consola44 from "consola";
6764
+ var sessionsListCommand = defineCommand54({
6917
6765
  meta: {
6918
6766
  name: "list",
6919
6767
  description: "List your active refresh-token families (one per logged-in device)."
@@ -6931,7 +6779,7 @@ var sessionsListCommand = defineCommand55({
6931
6779
  return;
6932
6780
  }
6933
6781
  if (result.data.length === 0) {
6934
- consola46.info("No active sessions.");
6782
+ consola44.info("No active sessions.");
6935
6783
  return;
6936
6784
  }
6937
6785
  for (const f of result.data) {
@@ -6943,9 +6791,9 @@ var sessionsListCommand = defineCommand55({
6943
6791
  });
6944
6792
 
6945
6793
  // src/commands/sessions/remove.ts
6946
- import { defineCommand as defineCommand56 } from "citty";
6947
- import consola47 from "consola";
6948
- var sessionsRemoveCommand = defineCommand56({
6794
+ import { defineCommand as defineCommand55 } from "citty";
6795
+ import consola45 from "consola";
6796
+ var sessionsRemoveCommand = defineCommand55({
6949
6797
  meta: {
6950
6798
  name: "remove",
6951
6799
  description: "Revoke one of your active refresh-token families by id."
@@ -6961,12 +6809,12 @@ var sessionsRemoveCommand = defineCommand56({
6961
6809
  const id = String(args.familyId).trim();
6962
6810
  if (!id) throw new CliError("familyId required");
6963
6811
  await apiFetch(`/api/me/sessions/${encodeURIComponent(id)}`, { method: "DELETE" });
6964
- consola47.success(`Session ${id} revoked. The device using it will need to \`apes login\` again on its next refresh.`);
6812
+ consola45.success(`Session ${id} revoked. The device using it will need to \`apes login\` again on its next refresh.`);
6965
6813
  }
6966
6814
  });
6967
6815
 
6968
6816
  // src/commands/sessions/index.ts
6969
- var sessionsCommand = defineCommand57({
6817
+ var sessionsCommand = defineCommand56({
6970
6818
  meta: {
6971
6819
  name: "sessions",
6972
6820
  description: "Manage your active refresh-token sessions across devices"
@@ -6978,10 +6826,10 @@ var sessionsCommand = defineCommand57({
6978
6826
  });
6979
6827
 
6980
6828
  // src/commands/dns-check.ts
6981
- import { defineCommand as defineCommand58 } from "citty";
6982
- import consola48 from "consola";
6829
+ import { defineCommand as defineCommand57 } from "citty";
6830
+ import consola46 from "consola";
6983
6831
  import { resolveDDISA as resolveDDISA3 } from "@openape/core";
6984
- var dnsCheckCommand = defineCommand58({
6832
+ var dnsCheckCommand = defineCommand57({
6985
6833
  meta: {
6986
6834
  name: "dns-check",
6987
6835
  description: "Validate DDISA DNS TXT records for a domain"
@@ -6995,7 +6843,7 @@ var dnsCheckCommand = defineCommand58({
6995
6843
  },
6996
6844
  async run({ args }) {
6997
6845
  const domain = args.domain;
6998
- consola48.start(`Checking _ddisa.${domain}...`);
6846
+ consola46.start(`Checking _ddisa.${domain}...`);
6999
6847
  try {
7000
6848
  const result = await resolveDDISA3(domain);
7001
6849
  if (!result) {
@@ -7004,7 +6852,7 @@ var dnsCheckCommand = defineCommand58({
7004
6852
  console.log(` _ddisa.${domain} TXT "v=ddisa1 idp=https://id.${domain}"`);
7005
6853
  throw new CliError(`No DDISA record found for ${domain}`);
7006
6854
  }
7007
- consola48.success(`_ddisa.${domain} \u2192 ${result.idp}`);
6855
+ consola46.success(`_ddisa.${domain} \u2192 ${result.idp}`);
7008
6856
  console.log("");
7009
6857
  console.log(` Version: ${result.version || "ddisa1"}`);
7010
6858
  console.log(` IdP URL: ${result.idp}`);
@@ -7013,14 +6861,14 @@ var dnsCheckCommand = defineCommand58({
7013
6861
  if (result.priority !== void 0)
7014
6862
  console.log(` Priority: ${result.priority}`);
7015
6863
  console.log("");
7016
- consola48.start(`Verifying IdP at ${result.idp}...`);
6864
+ consola46.start(`Verifying IdP at ${result.idp}...`);
7017
6865
  const discoResp = await fetch(`${result.idp}/.well-known/openid-configuration`);
7018
6866
  if (!discoResp.ok) {
7019
- consola48.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
6867
+ consola46.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
7020
6868
  return;
7021
6869
  }
7022
6870
  const disco = await discoResp.json();
7023
- consola48.success(`IdP is reachable`);
6871
+ consola46.success(`IdP is reachable`);
7024
6872
  console.log(` Issuer: ${disco.issuer}`);
7025
6873
  console.log(` DDISA: v${disco.ddisa_version || "?"}`);
7026
6874
  if (disco.ddisa_auth_methods_supported) {
@@ -7038,7 +6886,7 @@ var dnsCheckCommand = defineCommand58({
7038
6886
  // src/commands/health.ts
7039
6887
  import { exec } from "child_process";
7040
6888
  import { promisify } from "util";
7041
- import { defineCommand as defineCommand59 } from "citty";
6889
+ import { defineCommand as defineCommand58 } from "citty";
7042
6890
  var execAsync = promisify(exec);
7043
6891
  async function resolveApeShellPath() {
7044
6892
  try {
@@ -7074,7 +6922,7 @@ async function bestEffortGrantCount(idp) {
7074
6922
  }
7075
6923
  }
7076
6924
  async function runHealth(args) {
7077
- const version = true ? "1.11.0" : "0.0.0";
6925
+ const version = true ? "1.13.0" : "0.0.0";
7078
6926
  const auth = loadAuth();
7079
6927
  if (!auth) {
7080
6928
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -7137,7 +6985,7 @@ async function runHealth(args) {
7137
6985
  throw new CliError(`IdP ${auth.idp} unreachable: ${idpProbe.error}`, 1);
7138
6986
  }
7139
6987
  }
7140
- var healthCommand = defineCommand59({
6988
+ var healthCommand = defineCommand58({
7141
6989
  meta: {
7142
6990
  name: "health",
7143
6991
  description: "Report CLI diagnostic state (auth, IdP, grants, binaries)"
@@ -7155,8 +7003,8 @@ var healthCommand = defineCommand59({
7155
7003
  });
7156
7004
 
7157
7005
  // src/commands/workflows.ts
7158
- import { defineCommand as defineCommand60 } from "citty";
7159
- import consola49 from "consola";
7006
+ import { defineCommand as defineCommand59 } from "citty";
7007
+ import consola47 from "consola";
7160
7008
 
7161
7009
  // src/guides/index.ts
7162
7010
  var guides = [
@@ -7206,7 +7054,7 @@ var guides = [
7206
7054
  ];
7207
7055
 
7208
7056
  // src/commands/workflows.ts
7209
- var workflowsCommand = defineCommand60({
7057
+ var workflowsCommand = defineCommand59({
7210
7058
  meta: {
7211
7059
  name: "workflows",
7212
7060
  description: "Discover workflow guides"
@@ -7227,7 +7075,7 @@ var workflowsCommand = defineCommand60({
7227
7075
  if (args.id) {
7228
7076
  const guide = guides.find((g) => g.id === String(args.id));
7229
7077
  if (!guide) {
7230
- consola49.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
7078
+ consola47.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
7231
7079
  throw new CliError(`Guide not found: ${args.id}`);
7232
7080
  }
7233
7081
  if (args.json) {
@@ -7267,26 +7115,26 @@ var workflowsCommand = defineCommand60({
7267
7115
  });
7268
7116
 
7269
7117
  // src/version-check.ts
7270
- import { existsSync as existsSync17, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "fs";
7271
- import { homedir as homedir12 } from "os";
7272
- import { join as join14 } from "path";
7273
- import consola50 from "consola";
7118
+ import { existsSync as existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
7119
+ import { homedir as homedir13 } from "os";
7120
+ import { join as join15 } from "path";
7121
+ import consola48 from "consola";
7274
7122
  var PACKAGE_NAME = "@openape/apes";
7275
7123
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
7276
- var CACHE_FILE = join14(homedir12(), ".config", "apes", ".version-check.json");
7124
+ var CACHE_FILE = join15(homedir13(), ".config", "apes", ".version-check.json");
7277
7125
  function readCache() {
7278
- if (!existsSync17(CACHE_FILE)) return null;
7126
+ if (!existsSync18(CACHE_FILE)) return null;
7279
7127
  try {
7280
- return JSON.parse(readFileSync13(CACHE_FILE, "utf-8"));
7128
+ return JSON.parse(readFileSync14(CACHE_FILE, "utf-8"));
7281
7129
  } catch {
7282
7130
  return null;
7283
7131
  }
7284
7132
  }
7285
7133
  function writeCache(entry) {
7286
7134
  try {
7287
- const dir = join14(homedir12(), ".config", "apes");
7288
- if (!existsSync17(dir)) mkdirSync5(dir, { recursive: true, mode: 448 });
7289
- writeFileSync9(CACHE_FILE, JSON.stringify(entry), { mode: 384 });
7135
+ const dir = join15(homedir13(), ".config", "apes");
7136
+ if (!existsSync18(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
7137
+ writeFileSync10(CACHE_FILE, JSON.stringify(entry), { mode: 384 });
7290
7138
  } catch {
7291
7139
  }
7292
7140
  }
@@ -7315,7 +7163,7 @@ async function fetchLatestVersion() {
7315
7163
  }
7316
7164
  function warnIfBehind(currentVersion, latest) {
7317
7165
  if (compareSemver(currentVersion, latest) < 0) {
7318
- consola50.warn(
7166
+ consola48.warn(
7319
7167
  `apes ${currentVersion} is behind latest @openape/apes@${latest}. Run \`npm i -g @openape/apes@latest\` to update. (Suppress with APES_NO_UPDATE_CHECK=1.)`
7320
7168
  );
7321
7169
  }
@@ -7347,10 +7195,10 @@ if (shellRewrite) {
7347
7195
  if (shellRewrite.action === "rewrite") {
7348
7196
  process.argv = shellRewrite.argv;
7349
7197
  } else if (shellRewrite.action === "version") {
7350
- console.log(`ape-shell ${"1.11.0"} (OpenApe DDISA shell wrapper)`);
7198
+ console.log(`ape-shell ${"1.13.0"} (OpenApe DDISA shell wrapper)`);
7351
7199
  process.exit(0);
7352
7200
  } else if (shellRewrite.action === "help") {
7353
- console.log(`ape-shell ${"1.11.0"} \u2014 OpenApe DDISA shell wrapper`);
7201
+ console.log(`ape-shell ${"1.13.0"} \u2014 OpenApe DDISA shell wrapper`);
7354
7202
  console.log("");
7355
7203
  console.log("Usage:");
7356
7204
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -7374,7 +7222,7 @@ if (shellRewrite) {
7374
7222
  }
7375
7223
  }
7376
7224
  var debug = process.argv.includes("--debug");
7377
- var grantsCommand = defineCommand61({
7225
+ var grantsCommand = defineCommand60({
7378
7226
  meta: {
7379
7227
  name: "grants",
7380
7228
  description: "Grant management"
@@ -7395,7 +7243,7 @@ var grantsCommand = defineCommand61({
7395
7243
  "delegation-revoke": delegationRevokeCommand
7396
7244
  }
7397
7245
  });
7398
- var configCommand = defineCommand61({
7246
+ var configCommand = defineCommand60({
7399
7247
  meta: {
7400
7248
  name: "config",
7401
7249
  description: "Configuration management"
@@ -7405,10 +7253,10 @@ var configCommand = defineCommand61({
7405
7253
  set: configSetCommand
7406
7254
  }
7407
7255
  });
7408
- var main = defineCommand61({
7256
+ var main = defineCommand60({
7409
7257
  meta: {
7410
7258
  name: "apes",
7411
- version: "1.11.0",
7259
+ version: "1.13.0",
7412
7260
  description: "Unified CLI for OpenApe"
7413
7261
  },
7414
7262
  subCommands: {
@@ -7465,20 +7313,20 @@ async function maybeRefreshAuth() {
7465
7313
  }
7466
7314
  }
7467
7315
  await maybeRefreshAuth();
7468
- await maybeWarnStaleVersion("1.11.0").catch(() => {
7316
+ await maybeWarnStaleVersion("1.13.0").catch(() => {
7469
7317
  });
7470
7318
  runMain(main).catch((err) => {
7471
7319
  if (err instanceof CliExit) {
7472
7320
  process.exit(err.exitCode);
7473
7321
  }
7474
7322
  if (err instanceof CliError) {
7475
- consola51.error(err.message);
7323
+ consola49.error(err.message);
7476
7324
  process.exit(err.exitCode);
7477
7325
  }
7478
7326
  if (debug) {
7479
- consola51.error(err);
7327
+ consola49.error(err);
7480
7328
  } else {
7481
- consola51.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
7329
+ consola49.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
7482
7330
  }
7483
7331
  process.exit(1);
7484
7332
  });