@openape/apes 1.6.0 → 1.7.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
@@ -63,7 +63,7 @@ import {
63
63
  } from "./chunk-OBF7IMQ2.js";
64
64
 
65
65
  // src/cli.ts
66
- import consola44 from "consola";
66
+ import consola47 from "consola";
67
67
 
68
68
  // src/ape-shell.ts
69
69
  import path from "path";
@@ -93,7 +93,7 @@ function rewriteApeShellArgs(argv, argv0) {
93
93
  }
94
94
 
95
95
  // src/cli.ts
96
- import { defineCommand as defineCommand54, runMain } from "citty";
96
+ import { defineCommand as defineCommand58, runMain } from "citty";
97
97
 
98
98
  // src/commands/auth/login.ts
99
99
  import { Buffer as Buffer2 } from "buffer";
@@ -3921,6 +3921,7 @@ var agentsCommand = defineCommand28({
3921
3921
  import { defineCommand as defineCommand34 } from "citty";
3922
3922
 
3923
3923
  // src/commands/nest/authorize.ts
3924
+ import { execFileSync as execFileSync9 } from "child_process";
3924
3925
  import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
3925
3926
  import { join as join9 } from "path";
3926
3927
  import { defineCommand as defineCommand30 } from "citty";
@@ -4009,10 +4010,17 @@ var enrollNestCommand = defineCommand29({
4009
4010
 
4010
4011
  // src/commands/nest/authorize.ts
4011
4012
  var DEFAULT_ALLOW_PATTERNS = [
4012
- // Agent lifecycle ops the nest issues against `apes run --as root`
4013
+ // Outer spawn-grant what the nest's HTTP handler invokes.
4013
4014
  "apes agents spawn *",
4014
4015
  "apes agents destroy *",
4015
4016
  "apes agents sync",
4017
+ // Inner setup.sh-grant — `apes agents spawn` itself shells out to
4018
+ // `apes run --as root --wait -- bash <tempdir>/setup.sh` to do the
4019
+ // dscl/launchctl/heredoc-write work. Path looks like
4020
+ // `bash /var/folders/.../apes-spawn-<name>-XXXX/setup.sh`. The narrow
4021
+ // glob below limits the auto-approval to that exact lifecycle path
4022
+ // — `bash *` would be unsafe.
4023
+ "bash *apes-spawn-*setup.sh",
4016
4024
  // Bridge invocation the supervisor uses to keep agent processes
4017
4025
  // running. Pattern is intentionally precise — not a generic
4018
4026
  // `apes run --as *` wildcard — so a compromised nest can't pivot
@@ -4022,77 +4030,51 @@ var DEFAULT_ALLOW_PATTERNS = [
4022
4030
  var authorizeNestCommand = defineCommand30({
4023
4031
  meta: {
4024
4032
  name: "authorize",
4025
- description: "Set the YOLO-policy that lets the local nest spawn/destroy without per-call DDISA prompts"
4033
+ description: "Set the YOLO-policy that lets the local nest spawn/destroy without per-call DDISA prompts (wraps `apes yolo set`)"
4026
4034
  },
4027
4035
  args: {
4028
4036
  "allow": {
4029
4037
  type: "string",
4030
4038
  description: "Override allow_patterns (comma-separated globs). Default: nest-managed agent lifecycle."
4031
4039
  },
4032
- "mode": {
4033
- type: "string",
4034
- description: "Policy mode (allow-list | deny-list). Default: allow-list \u2014 auto-approve only matched patterns."
4035
- },
4036
4040
  "expires-in": {
4037
4041
  type: "string",
4038
4042
  description: "Optional duration like 30d, 6h. Omit for no expiry."
4039
4043
  }
4040
4044
  },
4041
4045
  async run({ args }) {
4042
- const ownerAuth = loadAuth();
4043
- if (!ownerAuth?.email || !ownerAuth.access_token) {
4044
- throw new CliError("Run `apes login <email>` first \u2014 only the nest's owner can set its YOLO-policy.");
4045
- }
4046
4046
  const nestAuthPath = join9(NEST_DATA_DIR, ".config", "apes", "auth.json");
4047
4047
  if (!existsSync11(nestAuthPath)) {
4048
4048
  throw new CliError("Nest not enrolled. Run `apes nest enroll` first.");
4049
4049
  }
4050
4050
  const nestAuth = JSON.parse(readFileSync10(nestAuthPath, "utf8"));
4051
4051
  if (!nestAuth.email) throw new CliError(`${nestAuthPath} has no email`);
4052
- const idp = getIdpUrl();
4053
- if (!idp) throw new CliError("No IdP configured.");
4054
- const allowPatterns = typeof args.allow === "string" && args.allow ? args.allow.split(",").map((s) => s.trim()).filter(Boolean) : DEFAULT_ALLOW_PATTERNS;
4055
- const mode = args.mode ?? "allow-list";
4056
- const expiresAt = parseExpiresIn(args["expires-in"]);
4057
- consola26.info(`Setting YOLO-policy on ${nestAuth.email}`);
4058
- consola26.info(` mode: ${mode}`);
4059
- consola26.info(` allow_patterns:`);
4060
- for (const p of allowPatterns) consola26.info(` - ${p}`);
4061
- if (expiresAt) consola26.info(` expires_at: ${new Date(expiresAt * 1e3).toISOString()}`);
4062
- const url = `${idp}/api/users/${encodeURIComponent(nestAuth.email)}/yolo-policy`;
4063
- const res = await fetch(url, {
4064
- method: "PUT",
4065
- headers: {
4066
- "Authorization": `Bearer ${ownerAuth.access_token}`,
4067
- "Content-Type": "application/json"
4068
- },
4069
- body: JSON.stringify({
4070
- mode,
4071
- allowPatterns,
4072
- denyPatterns: [],
4073
- expiresAt: expiresAt ?? null
4074
- })
4075
- });
4076
- if (!res.ok) {
4077
- const text = await res.text().catch(() => "");
4078
- throw new CliError(`PUT /yolo-policy failed (${res.status}): ${text}`);
4052
+ const allow = args.allow ?? DEFAULT_ALLOW_PATTERNS.join(",");
4053
+ consola26.info(`Configuring YOLO-policy on ${nestAuth.email} via \`apes yolo set\`\u2026`);
4054
+ const cmdArgs = [
4055
+ "yolo",
4056
+ "set",
4057
+ nestAuth.email,
4058
+ "--mode",
4059
+ "allow-list",
4060
+ "--allow",
4061
+ allow
4062
+ ];
4063
+ if (typeof args["expires-in"] === "string" && args["expires-in"]) {
4064
+ cmdArgs.push("--expires-in", args["expires-in"]);
4065
+ }
4066
+ try {
4067
+ execFileSync9("apes", cmdArgs, { stdio: "inherit" });
4068
+ } catch (err) {
4069
+ throw new CliError(err instanceof Error ? err.message : String(err));
4079
4070
  }
4080
- consola26.success("YOLO-policy applied. Nest-driven agent lifecycle is now zero-prompt.");
4071
+ consola26.success("Nest-driven agent lifecycle is now zero-prompt.");
4081
4072
  consola26.info("Test: apes agents spawn <name> via the nest API \u2192 no DDISA prompt.");
4082
4073
  }
4083
4074
  });
4084
- function parseExpiresIn(s) {
4085
- if (!s) return null;
4086
- const m = s.match(/^(\d+)([hdw])$/);
4087
- if (!m) throw new CliError(`Invalid --expires-in "${s}" \u2014 expected forms like 30d, 6h, 2w`);
4088
- const n = Number(m[1]);
4089
- const unit = m[2];
4090
- const seconds = unit === "h" ? 3600 : unit === "d" ? 86400 : 7 * 86400;
4091
- return Math.floor(Date.now() / 1e3) + n * seconds;
4092
- }
4093
4075
 
4094
4076
  // src/commands/nest/install.ts
4095
- import { execFileSync as execFileSync9 } from "child_process";
4077
+ import { execFileSync as execFileSync10 } from "child_process";
4096
4078
  import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
4097
4079
  import { homedir as homedir11, userInfo as userInfo2 } from "os";
4098
4080
  import { dirname as dirname3, join as join10 } from "path";
@@ -4269,10 +4251,10 @@ var installNestCommand = defineCommand31({
4269
4251
  }
4270
4252
  const uid = userInfo2().uid;
4271
4253
  try {
4272
- execFileSync9("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL}`], { stdio: "ignore" });
4254
+ execFileSync10("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL}`], { stdio: "ignore" });
4273
4255
  } catch {
4274
4256
  }
4275
- execFileSync9("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
4257
+ execFileSync10("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
4276
4258
  consola27.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
4277
4259
  consola27.info("");
4278
4260
  consola27.info("Next steps for zero-prompt spawn \u2014 both one-time:");
@@ -4339,7 +4321,7 @@ function humanDuration(sec) {
4339
4321
  }
4340
4322
 
4341
4323
  // src/commands/nest/uninstall.ts
4342
- import { execFileSync as execFileSync10 } from "child_process";
4324
+ import { execFileSync as execFileSync11 } from "child_process";
4343
4325
  import { existsSync as existsSync13, unlinkSync } from "fs";
4344
4326
  import { homedir as homedir12, userInfo as userInfo3 } from "os";
4345
4327
  import { join as join11 } from "path";
@@ -4355,7 +4337,7 @@ var uninstallNestCommand = defineCommand33({
4355
4337
  const uid = userInfo3().uid;
4356
4338
  const path2 = join11(homedir12(), "Library", "LaunchAgents", `${PLIST_LABEL2}.plist`);
4357
4339
  try {
4358
- execFileSync10("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
4340
+ execFileSync11("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
4359
4341
  consola29.success("Nest daemon stopped");
4360
4342
  } catch {
4361
4343
  consola29.info("Nest daemon was not loaded");
@@ -4383,16 +4365,211 @@ var nestCommand = defineCommand34({
4383
4365
  }
4384
4366
  });
4385
4367
 
4386
- // src/commands/adapter/index.ts
4368
+ // src/commands/yolo/index.ts
4369
+ import { defineCommand as defineCommand38 } from "citty";
4370
+
4371
+ // src/commands/yolo/clear.ts
4387
4372
  import { defineCommand as defineCommand35 } from "citty";
4388
4373
  import consola30 from "consola";
4389
- var adapterCommand = defineCommand35({
4374
+ var yoloClearCommand = defineCommand35({
4375
+ meta: {
4376
+ name: "clear",
4377
+ description: "Remove the YOLO-policy from a DDISA agent (subsequent grants need human approval)"
4378
+ },
4379
+ args: {
4380
+ email: {
4381
+ type: "positional",
4382
+ description: "Target agent email",
4383
+ required: true
4384
+ }
4385
+ },
4386
+ async run({ args }) {
4387
+ const ownerAuth = loadAuth();
4388
+ if (!ownerAuth?.access_token) {
4389
+ throw new CliError("Run `apes login <email>` first.");
4390
+ }
4391
+ const idp = getIdpUrl();
4392
+ if (!idp) throw new CliError("No IdP configured.");
4393
+ const email = args.email;
4394
+ const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`;
4395
+ const res = await fetch(url, {
4396
+ method: "DELETE",
4397
+ headers: { Authorization: `Bearer ${ownerAuth.access_token}` }
4398
+ });
4399
+ if (!res.ok && res.status !== 404) {
4400
+ const text = await res.text().catch(() => "");
4401
+ throw new CliError(`DELETE /yolo-policy failed (${res.status}): ${text}`);
4402
+ }
4403
+ consola30.success(`YOLO-policy cleared on ${email}`);
4404
+ }
4405
+ });
4406
+
4407
+ // src/commands/yolo/set.ts
4408
+ import { defineCommand as defineCommand36 } from "citty";
4409
+ import consola31 from "consola";
4410
+ var VALID_MODES = ["allow-list", "deny-list"];
4411
+ var yoloSetCommand = defineCommand36({
4412
+ meta: {
4413
+ name: "set",
4414
+ description: "Write a YOLO-policy on a DDISA agent you own"
4415
+ },
4416
+ args: {
4417
+ "email": {
4418
+ type: "positional",
4419
+ description: "Target agent email (e.g. nest-mac-cb6bf26a+patrick+example_com@id.openape.ai)",
4420
+ required: true
4421
+ },
4422
+ "mode": {
4423
+ type: "string",
4424
+ description: "Policy mode (allow-list | deny-list)"
4425
+ },
4426
+ "allow": {
4427
+ type: "string",
4428
+ description: 'Allow patterns \u2014 comma-separated bash globs (e.g. "apes agents spawn *,apes agents sync")'
4429
+ },
4430
+ "deny": {
4431
+ type: "string",
4432
+ description: "Deny patterns \u2014 comma-separated bash globs"
4433
+ },
4434
+ "deny-risk": {
4435
+ type: "string",
4436
+ description: "Deny grants at this risk level or above (low|medium|high|critical)"
4437
+ },
4438
+ "expires-in": {
4439
+ type: "string",
4440
+ description: "Optional expiry like 30d, 6h, 2w. Omit for no expiry."
4441
+ }
4442
+ },
4443
+ async run({ args }) {
4444
+ const ownerAuth = loadAuth();
4445
+ if (!ownerAuth?.access_token) {
4446
+ throw new CliError("Run `apes login <email>` first.");
4447
+ }
4448
+ const idp = getIdpUrl();
4449
+ if (!idp) throw new CliError("No IdP configured.");
4450
+ const email = args.email;
4451
+ const mode = args.mode ?? "allow-list";
4452
+ if (!VALID_MODES.includes(mode)) {
4453
+ throw new CliError(`mode must be one of: ${VALID_MODES.join(", ")}`);
4454
+ }
4455
+ const allowPatterns = parseList(args.allow);
4456
+ const denyPatterns = parseList(args.deny);
4457
+ const denyRiskThreshold = args["deny-risk"] ?? null;
4458
+ const expiresAt = parseExpiresIn(args["expires-in"]);
4459
+ consola31.info(`Setting YOLO-policy on ${email}`);
4460
+ consola31.info(` mode: ${mode}`);
4461
+ if (allowPatterns.length) consola31.info(` allow_patterns: ${allowPatterns.join(", ")}`);
4462
+ if (denyPatterns.length) consola31.info(` deny_patterns: ${denyPatterns.join(", ")}`);
4463
+ if (denyRiskThreshold) consola31.info(` deny_risk: ${denyRiskThreshold}`);
4464
+ if (expiresAt) consola31.info(` expires_at: ${new Date(expiresAt * 1e3).toISOString()}`);
4465
+ const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`;
4466
+ const res = await fetch(url, {
4467
+ method: "PUT",
4468
+ headers: {
4469
+ "Authorization": `Bearer ${ownerAuth.access_token}`,
4470
+ "Content-Type": "application/json"
4471
+ },
4472
+ body: JSON.stringify({
4473
+ mode,
4474
+ allowPatterns,
4475
+ denyPatterns,
4476
+ denyRiskThreshold,
4477
+ expiresAt: expiresAt ?? null
4478
+ })
4479
+ });
4480
+ if (!res.ok) {
4481
+ const text = await res.text().catch(() => "");
4482
+ throw new CliError(`PUT /yolo-policy failed (${res.status}): ${text}`);
4483
+ }
4484
+ consola31.success(`YOLO-policy applied to ${email}`);
4485
+ }
4486
+ });
4487
+ function parseList(s) {
4488
+ if (!s) return [];
4489
+ return s.split(",").map((p) => p.trim()).filter(Boolean);
4490
+ }
4491
+ function parseExpiresIn(s) {
4492
+ if (!s) return null;
4493
+ const m = s.match(/^(\d+)([hdw])$/);
4494
+ if (!m) throw new CliError(`Invalid --expires-in "${s}" \u2014 expected forms like 30d, 6h, 2w`);
4495
+ const n = Number(m[1]);
4496
+ const unit = m[2];
4497
+ const seconds = unit === "h" ? 3600 : unit === "d" ? 86400 : 7 * 86400;
4498
+ return Math.floor(Date.now() / 1e3) + n * seconds;
4499
+ }
4500
+
4501
+ // src/commands/yolo/show.ts
4502
+ import { defineCommand as defineCommand37 } from "citty";
4503
+ import consola32 from "consola";
4504
+ var yoloShowCommand = defineCommand37({
4505
+ meta: {
4506
+ name: "show",
4507
+ description: "Print the YOLO-policy currently set on a DDISA agent"
4508
+ },
4509
+ args: {
4510
+ email: {
4511
+ type: "positional",
4512
+ description: "Target agent email",
4513
+ required: true
4514
+ },
4515
+ json: {
4516
+ type: "boolean",
4517
+ description: "JSON output for scripts"
4518
+ }
4519
+ },
4520
+ async run({ args }) {
4521
+ const ownerAuth = loadAuth();
4522
+ if (!ownerAuth?.access_token) {
4523
+ throw new CliError("Run `apes login <email>` first.");
4524
+ }
4525
+ const idp = getIdpUrl();
4526
+ if (!idp) throw new CliError("No IdP configured.");
4527
+ const email = args.email;
4528
+ const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`;
4529
+ const res = await fetch(url, {
4530
+ headers: { Authorization: `Bearer ${ownerAuth.access_token}` }
4531
+ });
4532
+ if (!res.ok) {
4533
+ const text = await res.text().catch(() => "");
4534
+ throw new CliError(`GET /yolo-policy failed (${res.status}): ${text}`);
4535
+ }
4536
+ const policy = await res.json();
4537
+ if (args.json) {
4538
+ console.log(JSON.stringify(policy, null, 2));
4539
+ return;
4540
+ }
4541
+ consola32.info(`YOLO-policy for ${email}`);
4542
+ consola32.info(` mode: ${policy.mode}`);
4543
+ consola32.info(` allow_patterns: ${policy.allowPatterns.length ? policy.allowPatterns.join(", ") : "(none)"}`);
4544
+ consola32.info(` deny_patterns: ${policy.denyPatterns.length ? policy.denyPatterns.join(", ") : "(none)"}`);
4545
+ consola32.info(` deny_risk: ${policy.denyRiskThreshold ?? "(none)"}`);
4546
+ consola32.info(` expires_at: ${policy.expiresAt ? new Date(policy.expiresAt * 1e3).toISOString() : "(never)"}`);
4547
+ }
4548
+ });
4549
+
4550
+ // src/commands/yolo/index.ts
4551
+ var yoloCommand = defineCommand38({
4552
+ meta: {
4553
+ name: "yolo",
4554
+ 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)."
4555
+ },
4556
+ subCommands: {
4557
+ set: yoloSetCommand,
4558
+ show: yoloShowCommand,
4559
+ clear: yoloClearCommand
4560
+ }
4561
+ });
4562
+
4563
+ // src/commands/adapter/index.ts
4564
+ import { defineCommand as defineCommand39 } from "citty";
4565
+ import consola33 from "consola";
4566
+ var adapterCommand = defineCommand39({
4390
4567
  meta: {
4391
4568
  name: "adapter",
4392
4569
  description: "Manage CLI adapters"
4393
4570
  },
4394
4571
  subCommands: {
4395
- list: defineCommand35({
4572
+ list: defineCommand39({
4396
4573
  meta: {
4397
4574
  name: "list",
4398
4575
  description: "List available adapters"
@@ -4423,7 +4600,7 @@ var adapterCommand = defineCommand35({
4423
4600
  `);
4424
4601
  return;
4425
4602
  }
4426
- consola30.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
4603
+ consola33.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
4427
4604
  for (const a of index2.adapters) {
4428
4605
  const installed = isInstalled(a.id, false) ? " [installed]" : "";
4429
4606
  console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}${installed}`);
@@ -4445,7 +4622,7 @@ var adapterCommand = defineCommand35({
4445
4622
  return;
4446
4623
  }
4447
4624
  if (local.length === 0) {
4448
- consola30.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
4625
+ consola33.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
4449
4626
  return;
4450
4627
  }
4451
4628
  for (const a of local) {
@@ -4453,7 +4630,7 @@ var adapterCommand = defineCommand35({
4453
4630
  }
4454
4631
  }
4455
4632
  }),
4456
- install: defineCommand35({
4633
+ install: defineCommand39({
4457
4634
  meta: {
4458
4635
  name: "install",
4459
4636
  description: "Install an adapter from the registry"
@@ -4482,24 +4659,24 @@ var adapterCommand = defineCommand35({
4482
4659
  for (const id of ids) {
4483
4660
  const entry = findAdapter(index, id);
4484
4661
  if (!entry) {
4485
- consola30.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
4662
+ consola33.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
4486
4663
  continue;
4487
4664
  }
4488
4665
  const conflicts = findConflictingAdapters(entry.executable, id);
4489
4666
  if (conflicts.length > 0) {
4490
4667
  for (const c of conflicts) {
4491
- consola30.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`);
4492
- consola30.warn(` Remove it with: apes adapter remove ${c.adapterId}`);
4668
+ consola33.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`);
4669
+ consola33.warn(` Remove it with: apes adapter remove ${c.adapterId}`);
4493
4670
  }
4494
4671
  }
4495
4672
  const result = await installAdapter(entry, { local });
4496
4673
  const verb = result.updated ? "Updated" : "Installed";
4497
- consola30.success(`${verb} ${result.id} \u2192 ${result.path}`);
4498
- consola30.info(`Digest: ${result.digest}`);
4674
+ consola33.success(`${verb} ${result.id} \u2192 ${result.path}`);
4675
+ consola33.info(`Digest: ${result.digest}`);
4499
4676
  }
4500
4677
  }
4501
4678
  }),
4502
- remove: defineCommand35({
4679
+ remove: defineCommand39({
4503
4680
  meta: {
4504
4681
  name: "remove",
4505
4682
  description: "Remove an installed adapter"
@@ -4522,9 +4699,9 @@ var adapterCommand = defineCommand35({
4522
4699
  let failed = false;
4523
4700
  for (const id of ids) {
4524
4701
  if (removeAdapter(id, local)) {
4525
- consola30.success(`Removed adapter: ${id}`);
4702
+ consola33.success(`Removed adapter: ${id}`);
4526
4703
  } else {
4527
- consola30.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
4704
+ consola33.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
4528
4705
  failed = true;
4529
4706
  }
4530
4707
  }
@@ -4532,7 +4709,7 @@ var adapterCommand = defineCommand35({
4532
4709
  throw new CliError("Some adapters could not be removed");
4533
4710
  }
4534
4711
  }),
4535
- info: defineCommand35({
4712
+ info: defineCommand39({
4536
4713
  meta: {
4537
4714
  name: "info",
4538
4715
  description: "Show detailed adapter information"
@@ -4574,7 +4751,7 @@ var adapterCommand = defineCommand35({
4574
4751
  }
4575
4752
  }
4576
4753
  }),
4577
- search: defineCommand35({
4754
+ search: defineCommand39({
4578
4755
  meta: {
4579
4756
  name: "search",
4580
4757
  description: "Search adapters in the registry"
@@ -4606,7 +4783,7 @@ var adapterCommand = defineCommand35({
4606
4783
  return;
4607
4784
  }
4608
4785
  if (results.length === 0) {
4609
- consola30.info(`No adapters matching "${query}"`);
4786
+ consola33.info(`No adapters matching "${query}"`);
4610
4787
  return;
4611
4788
  }
4612
4789
  for (const a of results) {
@@ -4615,7 +4792,7 @@ var adapterCommand = defineCommand35({
4615
4792
  }
4616
4793
  }
4617
4794
  }),
4618
- update: defineCommand35({
4795
+ update: defineCommand39({
4619
4796
  meta: {
4620
4797
  name: "update",
4621
4798
  description: "Update installed adapters"
@@ -4641,33 +4818,33 @@ var adapterCommand = defineCommand35({
4641
4818
  const targetId = args.id ? String(args.id) : void 0;
4642
4819
  const targets = targetId ? [targetId] : index.adapters.map((a) => a.id).filter((id) => isInstalled(id, false));
4643
4820
  if (targets.length === 0) {
4644
- consola30.info("No adapters installed to update.");
4821
+ consola33.info("No adapters installed to update.");
4645
4822
  return;
4646
4823
  }
4647
4824
  for (const id of targets) {
4648
4825
  const entry = findAdapter(index, id);
4649
4826
  if (!entry) {
4650
- consola30.warn(`${id}: not found in registry, skipping`);
4827
+ consola33.warn(`${id}: not found in registry, skipping`);
4651
4828
  continue;
4652
4829
  }
4653
4830
  const localDigest = getInstalledDigest(id, false);
4654
4831
  if (localDigest === entry.digest) {
4655
- consola30.info(`${id}: already up to date`);
4832
+ consola33.info(`${id}: already up to date`);
4656
4833
  continue;
4657
4834
  }
4658
4835
  if (localDigest && !args.yes) {
4659
- consola30.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
4660
- consola30.info(` Old: ${localDigest}`);
4661
- consola30.info(` New: ${entry.digest}`);
4662
- consola30.info(" Use --yes to confirm");
4836
+ consola33.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
4837
+ consola33.info(` Old: ${localDigest}`);
4838
+ consola33.info(` New: ${entry.digest}`);
4839
+ consola33.info(" Use --yes to confirm");
4663
4840
  continue;
4664
4841
  }
4665
4842
  const result = await installAdapter(entry);
4666
- consola30.success(`Updated ${result.id} \u2192 ${result.path}`);
4843
+ consola33.success(`Updated ${result.id} \u2192 ${result.path}`);
4667
4844
  }
4668
4845
  }
4669
4846
  }),
4670
- verify: defineCommand35({
4847
+ verify: defineCommand39({
4671
4848
  meta: {
4672
4849
  name: "verify",
4673
4850
  description: "Verify installed adapter against registry digest"
@@ -4700,7 +4877,7 @@ var adapterCommand = defineCommand35({
4700
4877
  if (!localDigest)
4701
4878
  throw new Error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
4702
4879
  if (localDigest === entry.digest) {
4703
- consola30.success(`${id}: digest matches registry`);
4880
+ consola33.success(`${id}: digest matches registry`);
4704
4881
  } else {
4705
4882
  console.log(` Local: ${localDigest}`);
4706
4883
  console.log(` Registry: ${entry.digest}`);
@@ -4712,11 +4889,11 @@ var adapterCommand = defineCommand35({
4712
4889
  });
4713
4890
 
4714
4891
  // src/commands/run.ts
4715
- import { execFileSync as execFileSync11 } from "child_process";
4892
+ import { execFileSync as execFileSync12 } from "child_process";
4716
4893
  import { hostname as hostname5 } from "os";
4717
4894
  import { basename } from "path";
4718
- import { defineCommand as defineCommand36 } from "citty";
4719
- import consola31 from "consola";
4895
+ import { defineCommand as defineCommand40 } from "citty";
4896
+ import consola34 from "consola";
4720
4897
  function shouldWaitForGrant(args) {
4721
4898
  return args.wait === true || process.env.APE_WAIT === "1";
4722
4899
  }
@@ -4753,7 +4930,7 @@ function printPendingGrantInfo(grant, idp) {
4753
4930
  const statusCmd = `apes grants status ${grant.id}`;
4754
4931
  const executeCmd = `apes grants run ${grant.id}`;
4755
4932
  if (mode === "human") {
4756
- consola31.success(`Grant ${grant.id} created \u2014 awaiting your approval`);
4933
+ consola34.success(`Grant ${grant.id} created \u2014 awaiting your approval`);
4757
4934
  console.log(` Approve in browser: ${approveUrl}`);
4758
4935
  console.log(` Check status: ${statusCmd}`);
4759
4936
  console.log(` Run after approval: ${executeCmd}`);
@@ -4763,7 +4940,7 @@ function printPendingGrantInfo(grant, idp) {
4763
4940
  return;
4764
4941
  }
4765
4942
  const maxMin = getPollMaxMinutes();
4766
- consola31.success(`Grant ${grant.id} created (pending approval)`);
4943
+ consola34.success(`Grant ${grant.id} created (pending approval)`);
4767
4944
  console.log(` Approve: ${approveUrl}`);
4768
4945
  console.log(` Status: ${statusCmd} [--json]`);
4769
4946
  console.log(` Execute: ${executeCmd} --wait`);
@@ -4785,7 +4962,7 @@ function printPendingGrantInfo(grant, idp) {
4785
4962
  console.log(' Tip: Approve as "timed" or "always" in the browser to let this');
4786
4963
  console.log(" grant be reused on subsequent invocations without re-approval.");
4787
4964
  }
4788
- var runCommand = defineCommand36({
4965
+ var runCommand = defineCommand40({
4789
4966
  meta: {
4790
4967
  name: "run",
4791
4968
  description: "Execute a grant-secured command"
@@ -4888,7 +5065,7 @@ async function runShellMode(command, args) {
4888
5065
  }
4889
5066
  } catch {
4890
5067
  }
4891
- consola31.info(`Requesting ape-shell session grant on ${targetHost}`);
5068
+ consola34.info(`Requesting ape-shell session grant on ${targetHost}`);
4892
5069
  const grant = await apiFetch(grantsUrl, {
4893
5070
  method: "POST",
4894
5071
  body: {
@@ -4908,8 +5085,8 @@ async function runShellMode(command, args) {
4908
5085
  host: targetHost
4909
5086
  });
4910
5087
  if (shouldWaitForGrant(args)) {
4911
- consola31.info(`Grant requested: ${grant.id}`);
4912
- consola31.info("Waiting for approval...");
5088
+ consola34.info(`Grant requested: ${grant.id}`);
5089
+ consola34.info("Waiting for approval...");
4913
5090
  const maxWait = 3e5;
4914
5091
  const interval = 3e3;
4915
5092
  const start = Date.now();
@@ -4940,13 +5117,13 @@ async function tryAdapterModeFromShell(command, idp, args) {
4940
5117
  try {
4941
5118
  resolved = await resolveCommand(loaded, [normalizedExecutable, ...parsed.argv]);
4942
5119
  } catch (err) {
4943
- consola31.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
5120
+ consola34.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
4944
5121
  return false;
4945
5122
  }
4946
5123
  try {
4947
5124
  const existingGrantId = await findExistingGrant(resolved, idp);
4948
5125
  if (existingGrantId) {
4949
- consola31.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
5126
+ consola34.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
4950
5127
  const token = await fetchGrantToken(idp, existingGrantId);
4951
5128
  await verifyAndExecute(token, resolved, existingGrantId);
4952
5129
  return true;
@@ -4954,7 +5131,7 @@ async function tryAdapterModeFromShell(command, idp, args) {
4954
5131
  } catch {
4955
5132
  }
4956
5133
  const approval = args.approval ?? "once";
4957
- consola31.info(`Requesting grant for: ${resolved.detail.display}`);
5134
+ consola34.info(`Requesting grant for: ${resolved.detail.display}`);
4958
5135
  const grant = await createShapesGrant(resolved, {
4959
5136
  idp,
4960
5137
  approval,
@@ -4962,8 +5139,8 @@ async function tryAdapterModeFromShell(command, idp, args) {
4962
5139
  });
4963
5140
  if (grant.similar_grants?.similar_grants?.length) {
4964
5141
  const n = grant.similar_grants.similar_grants.length;
4965
- consola31.info("");
4966
- consola31.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
5142
+ consola34.info("");
5143
+ consola34.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
4967
5144
  }
4968
5145
  notifyGrantPending({
4969
5146
  grantId: grant.id,
@@ -4973,8 +5150,8 @@ async function tryAdapterModeFromShell(command, idp, args) {
4973
5150
  host: args.host || hostname5()
4974
5151
  });
4975
5152
  if (shouldWaitForGrant(args)) {
4976
- consola31.info(`Grant requested: ${grant.id}`);
4977
- consola31.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5153
+ consola34.info(`Grant requested: ${grant.id}`);
5154
+ consola34.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
4978
5155
  const status = await waitForGrantStatus(idp, grant.id);
4979
5156
  if (status !== "approved")
4980
5157
  throw new CliError(`Grant ${status}`);
@@ -4990,7 +5167,7 @@ function execShellCommand(command) {
4990
5167
  throw new CliError("No command to execute");
4991
5168
  try {
4992
5169
  const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
4993
- execFileSync11(command[0], command.slice(1), {
5170
+ execFileSync12(command[0], command.slice(1), {
4994
5171
  stdio: "inherit",
4995
5172
  env: inheritedEnv
4996
5173
  });
@@ -5048,7 +5225,7 @@ async function runAdapterMode(command, rawArgs, args) {
5048
5225
  try {
5049
5226
  const existingGrantId = await findExistingGrant(resolved, idp);
5050
5227
  if (existingGrantId) {
5051
- consola31.info(`Reusing existing grant: ${existingGrantId}`);
5228
+ consola34.info(`Reusing existing grant: ${existingGrantId}`);
5052
5229
  const token = await fetchGrantToken(idp, existingGrantId);
5053
5230
  await verifyAndExecute(token, resolved, existingGrantId);
5054
5231
  return;
@@ -5062,17 +5239,17 @@ async function runAdapterMode(command, rawArgs, args) {
5062
5239
  });
5063
5240
  if (grant.similar_grants?.similar_grants?.length) {
5064
5241
  const n = grant.similar_grants.similar_grants.length;
5065
- consola31.info("");
5066
- consola31.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
5242
+ consola34.info("");
5243
+ consola34.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
5067
5244
  if (grant.similar_grants.widened_details?.length) {
5068
5245
  const wider = grant.similar_grants.widened_details.map((d) => d.permission).join(", ");
5069
- consola31.info(` Broader scope: ${wider}`);
5246
+ consola34.info(` Broader scope: ${wider}`);
5070
5247
  }
5071
- consola31.info("");
5248
+ consola34.info("");
5072
5249
  }
5073
5250
  if (shouldWaitForGrant(args)) {
5074
- consola31.info(`Grant requested: ${grant.id}`);
5075
- consola31.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5251
+ consola34.info(`Grant requested: ${grant.id}`);
5252
+ consola34.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5076
5253
  const status = await waitForGrantStatus(idp, grant.id);
5077
5254
  if (status !== "approved")
5078
5255
  throw new Error(`Grant ${status}`);
@@ -5092,7 +5269,7 @@ async function runAudienceMode(audience, action, args) {
5092
5269
  const grantsUrl = await getGrantsEndpoint(idp);
5093
5270
  const command = action.split(" ");
5094
5271
  const targetHost = args.host || hostname5();
5095
- consola31.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
5272
+ consola34.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
5096
5273
  const grant = await apiFetch(grantsUrl, {
5097
5274
  method: "POST",
5098
5275
  body: {
@@ -5109,9 +5286,9 @@ async function runAudienceMode(audience, action, args) {
5109
5286
  printPendingGrantInfo(grant, idp);
5110
5287
  throw new CliExit(getAsyncExitCode());
5111
5288
  }
5112
- consola31.success(`Grant requested: ${grant.id}`);
5113
- consola31.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5114
- consola31.info("Waiting for approval...");
5289
+ consola34.success(`Grant requested: ${grant.id}`);
5290
+ consola34.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
5291
+ consola34.info("Waiting for approval...");
5115
5292
  const maxWait = 15 * 60 * 1e3;
5116
5293
  const interval = 3e3;
5117
5294
  const start = Date.now();
@@ -5119,7 +5296,7 @@ async function runAudienceMode(audience, action, args) {
5119
5296
  while (Date.now() - start < maxWait) {
5120
5297
  const status = await apiFetch(`${grantsUrl}/${grant.id}`);
5121
5298
  if (status.status === "approved") {
5122
- consola31.success("Grant approved!");
5299
+ consola34.success("Grant approved!");
5123
5300
  approved = true;
5124
5301
  break;
5125
5302
  }
@@ -5134,15 +5311,15 @@ async function runAudienceMode(audience, action, args) {
5134
5311
  `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.`
5135
5312
  );
5136
5313
  }
5137
- consola31.info("Fetching grant token...");
5314
+ consola34.info("Fetching grant token...");
5138
5315
  const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, {
5139
5316
  method: "POST"
5140
5317
  });
5141
5318
  if (audience === "escapes") {
5142
- consola31.info(`Executing: ${command.join(" ")}`);
5319
+ consola34.info(`Executing: ${command.join(" ")}`);
5143
5320
  try {
5144
5321
  const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
5145
- execFileSync11(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
5322
+ execFileSync12(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
5146
5323
  stdio: "inherit",
5147
5324
  env: inheritedEnv
5148
5325
  });
@@ -5157,8 +5334,8 @@ async function runAudienceMode(audience, action, args) {
5157
5334
 
5158
5335
  // src/commands/proxy.ts
5159
5336
  import { spawn as spawn2 } from "child_process";
5160
- import { defineCommand as defineCommand37 } from "citty";
5161
- import consola32 from "consola";
5337
+ import { defineCommand as defineCommand41 } from "citty";
5338
+ import consola35 from "consola";
5162
5339
 
5163
5340
  // src/proxy/config.ts
5164
5341
  function buildDefaultProxyConfigToml(opts) {
@@ -5301,10 +5478,10 @@ function resolveProxyConfigOptions() {
5301
5478
  77
5302
5479
  );
5303
5480
  }
5304
- consola32.info(`[apes proxy] IdP-mediated mode \u2014 agent=${auth.email}, idp=${auth.idp}`);
5481
+ consola35.info(`[apes proxy] IdP-mediated mode \u2014 agent=${auth.email}, idp=${auth.idp}`);
5305
5482
  return { agentEmail: auth.email, idpUrl: auth.idp, mediated: true };
5306
5483
  }
5307
- var proxyCommand = defineCommand37({
5484
+ var proxyCommand = defineCommand41({
5308
5485
  meta: {
5309
5486
  name: "proxy",
5310
5487
  description: "Run a command with HTTPS_PROXY routed through the OpenApe egress proxy."
@@ -5326,12 +5503,12 @@ var proxyCommand = defineCommand37({
5326
5503
  let close = null;
5327
5504
  if (reuseUrl) {
5328
5505
  proxyUrl = reuseUrl;
5329
- consola32.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`);
5506
+ consola35.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`);
5330
5507
  } else {
5331
5508
  const ephemeral = await startEphemeralProxy(buildDefaultProxyConfigToml(resolveProxyConfigOptions()));
5332
5509
  proxyUrl = ephemeral.url;
5333
5510
  close = ephemeral.close;
5334
- consola32.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`);
5511
+ consola35.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`);
5335
5512
  }
5336
5513
  const noProxy = process.env.NO_PROXY ?? process.env.no_proxy ?? "127.0.0.1,localhost";
5337
5514
  const childEnv = {
@@ -5363,7 +5540,7 @@ var proxyCommand = defineCommand37({
5363
5540
  else resolveExit(code ?? 0);
5364
5541
  });
5365
5542
  child.once("error", (err) => {
5366
- consola32.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message);
5543
+ consola35.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message);
5367
5544
  resolveExit(127);
5368
5545
  });
5369
5546
  });
@@ -5377,8 +5554,8 @@ function signalNumber(signal) {
5377
5554
  }
5378
5555
 
5379
5556
  // src/commands/explain.ts
5380
- import { defineCommand as defineCommand38 } from "citty";
5381
- var explainCommand = defineCommand38({
5557
+ import { defineCommand as defineCommand42 } from "citty";
5558
+ var explainCommand = defineCommand42({
5382
5559
  meta: {
5383
5560
  name: "explain",
5384
5561
  description: "Show what permission a command would need"
@@ -5416,9 +5593,9 @@ var explainCommand = defineCommand38({
5416
5593
  });
5417
5594
 
5418
5595
  // src/commands/config/get.ts
5419
- import { defineCommand as defineCommand39 } from "citty";
5420
- import consola33 from "consola";
5421
- var configGetCommand = defineCommand39({
5596
+ import { defineCommand as defineCommand43 } from "citty";
5597
+ import consola36 from "consola";
5598
+ var configGetCommand = defineCommand43({
5422
5599
  meta: {
5423
5600
  name: "get",
5424
5601
  description: "Get a configuration value"
@@ -5438,7 +5615,7 @@ var configGetCommand = defineCommand39({
5438
5615
  if (idp)
5439
5616
  console.log(idp);
5440
5617
  else
5441
- consola33.info("No IdP configured.");
5618
+ consola36.info("No IdP configured.");
5442
5619
  break;
5443
5620
  }
5444
5621
  case "email": {
@@ -5446,7 +5623,7 @@ var configGetCommand = defineCommand39({
5446
5623
  if (auth?.email)
5447
5624
  console.log(auth.email);
5448
5625
  else
5449
- consola33.info("Not logged in.");
5626
+ consola36.info("Not logged in.");
5450
5627
  break;
5451
5628
  }
5452
5629
  default: {
@@ -5459,7 +5636,7 @@ var configGetCommand = defineCommand39({
5459
5636
  if (sectionObj && field in sectionObj) {
5460
5637
  console.log(sectionObj[field]);
5461
5638
  } else {
5462
- consola33.info(`Key "${key}" not set.`);
5639
+ consola36.info(`Key "${key}" not set.`);
5463
5640
  }
5464
5641
  } else {
5465
5642
  throw new CliError(`Unknown key: "${key}". Use: idp, email, defaults.idp, defaults.approval, agent.key, agent.email`);
@@ -5470,9 +5647,9 @@ var configGetCommand = defineCommand39({
5470
5647
  });
5471
5648
 
5472
5649
  // src/commands/config/set.ts
5473
- import { defineCommand as defineCommand40 } from "citty";
5474
- import consola34 from "consola";
5475
- var configSetCommand = defineCommand40({
5650
+ import { defineCommand as defineCommand44 } from "citty";
5651
+ import consola37 from "consola";
5652
+ var configSetCommand = defineCommand44({
5476
5653
  meta: {
5477
5654
  name: "set",
5478
5655
  description: "Set a configuration value"
@@ -5508,12 +5685,12 @@ var configSetCommand = defineCommand40({
5508
5685
  throw new CliError(`Unknown section: "${section}". Use: defaults, agent`);
5509
5686
  }
5510
5687
  saveConfig(config);
5511
- consola34.success(`Set ${key} = ${value}`);
5688
+ consola37.success(`Set ${key} = ${value}`);
5512
5689
  }
5513
5690
  });
5514
5691
 
5515
5692
  // src/commands/fetch/index.ts
5516
- import { defineCommand as defineCommand41 } from "citty";
5693
+ import { defineCommand as defineCommand45 } from "citty";
5517
5694
  async function doRequest(method, url, body, contentType, raw, showHeaders) {
5518
5695
  const token = getAuthToken();
5519
5696
  if (!token) {
@@ -5549,13 +5726,13 @@ async function doRequest(method, url, body, contentType, raw, showHeaders) {
5549
5726
  throw new CliError(`HTTP ${response.status} ${response.statusText}`);
5550
5727
  }
5551
5728
  }
5552
- var fetchCommand = defineCommand41({
5729
+ var fetchCommand = defineCommand45({
5553
5730
  meta: {
5554
5731
  name: "fetch",
5555
5732
  description: "Make authenticated HTTP requests"
5556
5733
  },
5557
5734
  subCommands: {
5558
- get: defineCommand41({
5735
+ get: defineCommand45({
5559
5736
  meta: {
5560
5737
  name: "get",
5561
5738
  description: "GET request with auth token"
@@ -5581,7 +5758,7 @@ var fetchCommand = defineCommand41({
5581
5758
  await doRequest("GET", String(args.url), void 0, "application/json", Boolean(args.raw), Boolean(args.headers));
5582
5759
  }
5583
5760
  }),
5584
- post: defineCommand41({
5761
+ post: defineCommand45({
5585
5762
  meta: {
5586
5763
  name: "post",
5587
5764
  description: "POST request with auth token"
@@ -5620,8 +5797,8 @@ var fetchCommand = defineCommand41({
5620
5797
  });
5621
5798
 
5622
5799
  // src/commands/mcp/index.ts
5623
- import { defineCommand as defineCommand42 } from "citty";
5624
- var mcpCommand = defineCommand42({
5800
+ import { defineCommand as defineCommand46 } from "citty";
5801
+ var mcpCommand = defineCommand46({
5625
5802
  meta: {
5626
5803
  name: "mcp",
5627
5804
  description: "Start MCP server for AI agents"
@@ -5644,7 +5821,7 @@ var mcpCommand = defineCommand42({
5644
5821
  if (transport !== "stdio" && transport !== "sse") {
5645
5822
  throw new Error('Transport must be "stdio" or "sse"');
5646
5823
  }
5647
- const { startMcpServer } = await import("./server-PHANS7PS.js");
5824
+ const { startMcpServer } = await import("./server-BSBIEKFK.js");
5648
5825
  await startMcpServer(transport, port);
5649
5826
  }
5650
5827
  });
@@ -5652,10 +5829,10 @@ var mcpCommand = defineCommand42({
5652
5829
  // src/commands/init/index.ts
5653
5830
  import { existsSync as existsSync14, copyFileSync, writeFileSync as writeFileSync9 } from "fs";
5654
5831
  import { randomBytes } from "crypto";
5655
- import { execFileSync as execFileSync12 } from "child_process";
5832
+ import { execFileSync as execFileSync13 } from "child_process";
5656
5833
  import { join as join13 } from "path";
5657
- import { defineCommand as defineCommand43 } from "citty";
5658
- import consola35 from "consola";
5834
+ import { defineCommand as defineCommand47 } from "citty";
5835
+ import consola38 from "consola";
5659
5836
  var DEFAULT_IDP_URL = "https://id.openape.at";
5660
5837
  async function downloadTemplate(repo, targetDir) {
5661
5838
  const { downloadTemplate: gigetDownload } = await import("giget");
@@ -5664,28 +5841,28 @@ async function downloadTemplate(repo, targetDir) {
5664
5841
  function installDeps(dir) {
5665
5842
  const hasLockFile = (name) => existsSync14(join13(dir, name));
5666
5843
  if (hasLockFile("pnpm-lock.yaml")) {
5667
- execFileSync12("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
5844
+ execFileSync13("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
5668
5845
  } else if (hasLockFile("bun.lockb")) {
5669
- execFileSync12("bun", ["install"], { cwd: dir, stdio: "inherit" });
5846
+ execFileSync13("bun", ["install"], { cwd: dir, stdio: "inherit" });
5670
5847
  } else {
5671
- execFileSync12("npm", ["install"], { cwd: dir, stdio: "inherit" });
5848
+ execFileSync13("npm", ["install"], { cwd: dir, stdio: "inherit" });
5672
5849
  }
5673
5850
  }
5674
5851
  async function promptChoice(message, choices) {
5675
- const result = await consola35.prompt(message, { type: "select", options: choices });
5852
+ const result = await consola38.prompt(message, { type: "select", options: choices });
5676
5853
  if (typeof result === "symbol") {
5677
5854
  throw new CliExit(0);
5678
5855
  }
5679
5856
  return result;
5680
5857
  }
5681
5858
  async function promptText(message, defaultValue) {
5682
- const result = await consola35.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
5859
+ const result = await consola38.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
5683
5860
  if (typeof result === "symbol") {
5684
5861
  throw new CliExit(0);
5685
5862
  }
5686
5863
  return result || defaultValue || "";
5687
5864
  }
5688
- var initCommand = defineCommand43({
5865
+ var initCommand = defineCommand47({
5689
5866
  meta: {
5690
5867
  name: "init",
5691
5868
  description: "Scaffold a new OpenApe project"
@@ -5730,20 +5907,20 @@ async function initSP(targetDir) {
5730
5907
  if (existsSync14(join13(dir, "package.json"))) {
5731
5908
  throw new CliError(`Directory "${dir}" already contains a project.`);
5732
5909
  }
5733
- consola35.start("Scaffolding SP starter...");
5910
+ consola38.start("Scaffolding SP starter...");
5734
5911
  await downloadTemplate("openape-ai/openape-sp-starter", dir);
5735
- consola35.success("Scaffolded from openape-sp-starter");
5736
- consola35.start("Installing dependencies...");
5912
+ consola38.success("Scaffolded from openape-sp-starter");
5913
+ consola38.start("Installing dependencies...");
5737
5914
  installDeps(dir);
5738
- consola35.success("Dependencies installed");
5915
+ consola38.success("Dependencies installed");
5739
5916
  const envExample = join13(dir, ".env.example");
5740
5917
  const envFile = join13(dir, ".env");
5741
5918
  if (existsSync14(envExample) && !existsSync14(envFile)) {
5742
5919
  copyFileSync(envExample, envFile);
5743
- consola35.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
5920
+ consola38.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
5744
5921
  }
5745
5922
  console.log("");
5746
- consola35.box([
5923
+ consola38.box([
5747
5924
  `cd ${dir}`,
5748
5925
  "npm run dev",
5749
5926
  "",
@@ -5762,15 +5939,15 @@ async function initIdP(targetDir) {
5762
5939
  "s3 (S3-compatible)"
5763
5940
  ]);
5764
5941
  const adminEmail = await promptText("Admin email");
5765
- consola35.start("Scaffolding IdP starter...");
5942
+ consola38.start("Scaffolding IdP starter...");
5766
5943
  await downloadTemplate("openape-ai/openape-idp-starter", dir);
5767
- consola35.success("Scaffolded from openape-idp-starter");
5768
- consola35.start("Installing dependencies...");
5944
+ consola38.success("Scaffolded from openape-idp-starter");
5945
+ consola38.start("Installing dependencies...");
5769
5946
  installDeps(dir);
5770
- consola35.success("Dependencies installed");
5947
+ consola38.success("Dependencies installed");
5771
5948
  const sessionSecret = randomBytes(32).toString("hex");
5772
5949
  const managementToken = randomBytes(32).toString("hex");
5773
- consola35.success("Secrets generated");
5950
+ consola38.success("Secrets generated");
5774
5951
  const isLocalhost = domain === "localhost";
5775
5952
  const origin = isLocalhost ? "http://localhost:3000" : `https://${domain}`;
5776
5953
  const envContent = [
@@ -5786,9 +5963,9 @@ async function initIdP(targetDir) {
5786
5963
  ].join("\n");
5787
5964
  writeFileSync9(join13(dir, ".env"), `${envContent}
5788
5965
  `, { mode: 384 });
5789
- consola35.success(".env created");
5966
+ consola38.success(".env created");
5790
5967
  console.log("");
5791
- consola35.box([
5968
+ consola38.box([
5792
5969
  `cd ${dir}`,
5793
5970
  "npm run dev",
5794
5971
  "",
@@ -5808,8 +5985,8 @@ import { Buffer as Buffer5 } from "buffer";
5808
5985
  import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
5809
5986
  import { execFile as execFile2 } from "child_process";
5810
5987
  import { sign as sign2 } from "crypto";
5811
- import { defineCommand as defineCommand44 } from "citty";
5812
- import consola36 from "consola";
5988
+ import { defineCommand as defineCommand48 } from "citty";
5989
+ import consola39 from "consola";
5813
5990
  var DEFAULT_IDP_URL2 = "https://id.openape.at";
5814
5991
  var DEFAULT_KEY_PATH = "~/.ssh/id_ed25519";
5815
5992
  var POLL_INTERVAL = 3e3;
@@ -5852,7 +6029,7 @@ async function pollForEnrollment(idp, agentEmail, keyPath) {
5852
6029
  }
5853
6030
  throw new Error("Enrollment timed out. Please check the browser and try again.");
5854
6031
  }
5855
- var enrollCommand = defineCommand44({
6032
+ var enrollCommand = defineCommand48({
5856
6033
  meta: {
5857
6034
  name: "enroll",
5858
6035
  description: "Enroll an agent with an Identity Provider"
@@ -5872,18 +6049,18 @@ var enrollCommand = defineCommand44({
5872
6049
  }
5873
6050
  },
5874
6051
  async run({ args }) {
5875
- const idp = args.idp || await consola36.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r) => {
6052
+ const idp = args.idp || await consola39.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r) => {
5876
6053
  if (typeof r === "symbol") throw new CliExit(0);
5877
6054
  return r;
5878
6055
  }) || DEFAULT_IDP_URL2;
5879
- const agentName = args.name || await consola36.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r) => {
6056
+ const agentName = args.name || await consola39.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r) => {
5880
6057
  if (typeof r === "symbol") throw new CliExit(0);
5881
6058
  return r;
5882
6059
  });
5883
6060
  if (!agentName) {
5884
6061
  throw new CliError("Agent name is required.");
5885
6062
  }
5886
- const keyPath = args.key || await consola36.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => {
6063
+ const keyPath = args.key || await consola39.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => {
5887
6064
  if (typeof r === "symbol") throw new CliExit(0);
5888
6065
  return r;
5889
6066
  }) || DEFAULT_KEY_PATH;
@@ -5891,19 +6068,19 @@ var enrollCommand = defineCommand44({
5891
6068
  let publicKey;
5892
6069
  if (existsSync15(resolvedKey)) {
5893
6070
  publicKey = readPublicKey(resolvedKey);
5894
- consola36.success(`Using existing key ${keyPath}`);
6071
+ consola39.success(`Using existing key ${keyPath}`);
5895
6072
  } else {
5896
- consola36.start(`Generating Ed25519 key pair at ${keyPath}...`);
6073
+ consola39.start(`Generating Ed25519 key pair at ${keyPath}...`);
5897
6074
  publicKey = generateAndSaveKey(keyPath);
5898
- consola36.success(`Key pair generated at ${keyPath}`);
6075
+ consola39.success(`Key pair generated at ${keyPath}`);
5899
6076
  }
5900
6077
  const encodedKey = encodeURIComponent(publicKey);
5901
6078
  const enrollUrl = `${idp}/enroll?name=${encodeURIComponent(agentName)}&key=${encodedKey}`;
5902
- consola36.info("Opening browser for enrollment...");
5903
- consola36.info(`\u2192 ${idp}/enroll`);
6079
+ consola39.info("Opening browser for enrollment...");
6080
+ consola39.info(`\u2192 ${idp}/enroll`);
5904
6081
  openBrowser2(enrollUrl);
5905
6082
  console.log("");
5906
- const agentEmail = await consola36.prompt(
6083
+ const agentEmail = await consola39.prompt(
5907
6084
  "Agent email (shown in browser after enrollment)",
5908
6085
  { type: "text", placeholder: `agent+${agentName}@...` }
5909
6086
  ).then((r) => {
@@ -5913,7 +6090,7 @@ var enrollCommand = defineCommand44({
5913
6090
  if (!agentEmail) {
5914
6091
  throw new CliError("Agent email is required to verify enrollment.");
5915
6092
  }
5916
- consola36.start("Verifying enrollment...");
6093
+ consola39.start("Verifying enrollment...");
5917
6094
  const { token, expiresIn } = await pollForEnrollment(idp, agentEmail, keyPath);
5918
6095
  saveAuth({
5919
6096
  idp,
@@ -5925,18 +6102,18 @@ var enrollCommand = defineCommand44({
5925
6102
  config.defaults = { ...config.defaults, idp };
5926
6103
  config.agent = { key: keyPath, email: agentEmail };
5927
6104
  saveConfig(config);
5928
- consola36.success(`Agent enrolled as ${agentEmail}`);
5929
- consola36.success("Config saved to ~/.config/apes/");
6105
+ consola39.success(`Agent enrolled as ${agentEmail}`);
6106
+ consola39.success("Config saved to ~/.config/apes/");
5930
6107
  console.log("");
5931
- consola36.info("Verify with: apes whoami");
6108
+ consola39.info("Verify with: apes whoami");
5932
6109
  }
5933
6110
  });
5934
6111
 
5935
6112
  // src/commands/register-user.ts
5936
6113
  import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
5937
- import { defineCommand as defineCommand45 } from "citty";
5938
- import consola37 from "consola";
5939
- var registerUserCommand = defineCommand45({
6114
+ import { defineCommand as defineCommand49 } from "citty";
6115
+ import consola40 from "consola";
6116
+ var registerUserCommand = defineCommand49({
5940
6117
  meta: {
5941
6118
  name: "register-user",
5942
6119
  description: "Register a sub-user with SSH key"
@@ -5991,18 +6168,18 @@ var registerUserCommand = defineCommand45({
5991
6168
  ...userType ? { type: userType } : {}
5992
6169
  }
5993
6170
  });
5994
- consola37.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
6171
+ consola40.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
5995
6172
  }
5996
6173
  });
5997
6174
 
5998
6175
  // src/commands/utils/index.ts
5999
- import { defineCommand as defineCommand47 } from "citty";
6176
+ import { defineCommand as defineCommand51 } from "citty";
6000
6177
 
6001
6178
  // src/commands/utils/dig.ts
6002
- import { defineCommand as defineCommand46 } from "citty";
6003
- import consola38 from "consola";
6179
+ import { defineCommand as defineCommand50 } from "citty";
6180
+ import consola41 from "consola";
6004
6181
  import { resolveDDISA as resolveDDISA2 } from "@openape/core";
6005
- var digCommand = defineCommand46({
6182
+ var digCommand = defineCommand50({
6006
6183
  meta: {
6007
6184
  name: "dig",
6008
6185
  description: "Resolve DDISA IdP for a domain or email (admin/diag tool)"
@@ -6075,12 +6252,12 @@ var digCommand = defineCommand46({
6075
6252
  console.log(` domain: ${domain}`);
6076
6253
  console.log("");
6077
6254
  if (!result.ddisa.found) {
6078
- consola38.warn(`No DDISA record at _ddisa.${domain}`);
6255
+ consola41.warn(`No DDISA record at _ddisa.${domain}`);
6079
6256
  if (result.hint) console.log(`
6080
6257
  ${result.hint}`);
6081
6258
  throw new CliError(`No DDISA record found for ${domain}`);
6082
6259
  }
6083
- consola38.success(`_ddisa.${domain} \u2192 ${result.ddisa.idp}`);
6260
+ consola41.success(`_ddisa.${domain} \u2192 ${result.ddisa.idp}`);
6084
6261
  console.log(` Version: ${result.ddisa.version || "ddisa1"}`);
6085
6262
  console.log(` IdP URL: ${result.ddisa.idp}`);
6086
6263
  if (result.ddisa.mode) console.log(` Mode: ${result.ddisa.mode}`);
@@ -6090,13 +6267,13 @@ ${result.hint}`);
6090
6267
  return;
6091
6268
  }
6092
6269
  if (result.idpDiscovery.ok) {
6093
- consola38.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`);
6270
+ consola41.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`);
6094
6271
  if (result.idpDiscovery.issuer) console.log(` Issuer: ${result.idpDiscovery.issuer}`);
6095
6272
  if (result.idpDiscovery.ddisaVersion) console.log(` DDISA: v${result.idpDiscovery.ddisaVersion}`);
6096
6273
  if (result.idpDiscovery.authMethods?.length) console.log(` Auth: ${result.idpDiscovery.authMethods.join(", ")}`);
6097
6274
  if (result.idpDiscovery.grantTypes?.length) console.log(` Grants: ${result.idpDiscovery.grantTypes.join(", ")}`);
6098
6275
  } else {
6099
- consola38.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ""}`);
6276
+ consola41.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ""}`);
6100
6277
  if (result.hint) console.log(`
6101
6278
  ${result.hint}`);
6102
6279
  throw new CliError(`IdP at ${result.ddisa.idp} not reachable`);
@@ -6105,7 +6282,7 @@ ${result.hint}`);
6105
6282
  });
6106
6283
 
6107
6284
  // src/commands/utils/index.ts
6108
- var utilsCommand = defineCommand47({
6285
+ var utilsCommand = defineCommand51({
6109
6286
  meta: {
6110
6287
  name: "utils",
6111
6288
  description: "Admin/diagnostic utilities (dig, \u2026)"
@@ -6116,12 +6293,12 @@ var utilsCommand = defineCommand47({
6116
6293
  });
6117
6294
 
6118
6295
  // src/commands/sessions/index.ts
6119
- import { defineCommand as defineCommand50 } from "citty";
6296
+ import { defineCommand as defineCommand54 } from "citty";
6120
6297
 
6121
6298
  // src/commands/sessions/list.ts
6122
- import { defineCommand as defineCommand48 } from "citty";
6123
- import consola39 from "consola";
6124
- var sessionsListCommand = defineCommand48({
6299
+ import { defineCommand as defineCommand52 } from "citty";
6300
+ import consola42 from "consola";
6301
+ var sessionsListCommand = defineCommand52({
6125
6302
  meta: {
6126
6303
  name: "list",
6127
6304
  description: "List your active refresh-token families (one per logged-in device)."
@@ -6139,7 +6316,7 @@ var sessionsListCommand = defineCommand48({
6139
6316
  return;
6140
6317
  }
6141
6318
  if (result.data.length === 0) {
6142
- consola39.info("No active sessions.");
6319
+ consola42.info("No active sessions.");
6143
6320
  return;
6144
6321
  }
6145
6322
  for (const f of result.data) {
@@ -6151,9 +6328,9 @@ var sessionsListCommand = defineCommand48({
6151
6328
  });
6152
6329
 
6153
6330
  // src/commands/sessions/remove.ts
6154
- import { defineCommand as defineCommand49 } from "citty";
6155
- import consola40 from "consola";
6156
- var sessionsRemoveCommand = defineCommand49({
6331
+ import { defineCommand as defineCommand53 } from "citty";
6332
+ import consola43 from "consola";
6333
+ var sessionsRemoveCommand = defineCommand53({
6157
6334
  meta: {
6158
6335
  name: "remove",
6159
6336
  description: "Revoke one of your active refresh-token families by id."
@@ -6169,12 +6346,12 @@ var sessionsRemoveCommand = defineCommand49({
6169
6346
  const id = String(args.familyId).trim();
6170
6347
  if (!id) throw new CliError("familyId required");
6171
6348
  await apiFetch(`/api/me/sessions/${encodeURIComponent(id)}`, { method: "DELETE" });
6172
- consola40.success(`Session ${id} revoked. The device using it will need to \`apes login\` again on its next refresh.`);
6349
+ consola43.success(`Session ${id} revoked. The device using it will need to \`apes login\` again on its next refresh.`);
6173
6350
  }
6174
6351
  });
6175
6352
 
6176
6353
  // src/commands/sessions/index.ts
6177
- var sessionsCommand = defineCommand50({
6354
+ var sessionsCommand = defineCommand54({
6178
6355
  meta: {
6179
6356
  name: "sessions",
6180
6357
  description: "Manage your active refresh-token sessions across devices"
@@ -6186,10 +6363,10 @@ var sessionsCommand = defineCommand50({
6186
6363
  });
6187
6364
 
6188
6365
  // src/commands/dns-check.ts
6189
- import { defineCommand as defineCommand51 } from "citty";
6190
- import consola41 from "consola";
6366
+ import { defineCommand as defineCommand55 } from "citty";
6367
+ import consola44 from "consola";
6191
6368
  import { resolveDDISA as resolveDDISA3 } from "@openape/core";
6192
- var dnsCheckCommand = defineCommand51({
6369
+ var dnsCheckCommand = defineCommand55({
6193
6370
  meta: {
6194
6371
  name: "dns-check",
6195
6372
  description: "Validate DDISA DNS TXT records for a domain"
@@ -6203,7 +6380,7 @@ var dnsCheckCommand = defineCommand51({
6203
6380
  },
6204
6381
  async run({ args }) {
6205
6382
  const domain = args.domain;
6206
- consola41.start(`Checking _ddisa.${domain}...`);
6383
+ consola44.start(`Checking _ddisa.${domain}...`);
6207
6384
  try {
6208
6385
  const result = await resolveDDISA3(domain);
6209
6386
  if (!result) {
@@ -6212,7 +6389,7 @@ var dnsCheckCommand = defineCommand51({
6212
6389
  console.log(` _ddisa.${domain} TXT "v=ddisa1 idp=https://id.${domain}"`);
6213
6390
  throw new CliError(`No DDISA record found for ${domain}`);
6214
6391
  }
6215
- consola41.success(`_ddisa.${domain} \u2192 ${result.idp}`);
6392
+ consola44.success(`_ddisa.${domain} \u2192 ${result.idp}`);
6216
6393
  console.log("");
6217
6394
  console.log(` Version: ${result.version || "ddisa1"}`);
6218
6395
  console.log(` IdP URL: ${result.idp}`);
@@ -6221,14 +6398,14 @@ var dnsCheckCommand = defineCommand51({
6221
6398
  if (result.priority !== void 0)
6222
6399
  console.log(` Priority: ${result.priority}`);
6223
6400
  console.log("");
6224
- consola41.start(`Verifying IdP at ${result.idp}...`);
6401
+ consola44.start(`Verifying IdP at ${result.idp}...`);
6225
6402
  const discoResp = await fetch(`${result.idp}/.well-known/openid-configuration`);
6226
6403
  if (!discoResp.ok) {
6227
- consola41.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
6404
+ consola44.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
6228
6405
  return;
6229
6406
  }
6230
6407
  const disco = await discoResp.json();
6231
- consola41.success(`IdP is reachable`);
6408
+ consola44.success(`IdP is reachable`);
6232
6409
  console.log(` Issuer: ${disco.issuer}`);
6233
6410
  console.log(` DDISA: v${disco.ddisa_version || "?"}`);
6234
6411
  if (disco.ddisa_auth_methods_supported) {
@@ -6246,7 +6423,7 @@ var dnsCheckCommand = defineCommand51({
6246
6423
  // src/commands/health.ts
6247
6424
  import { exec } from "child_process";
6248
6425
  import { promisify } from "util";
6249
- import { defineCommand as defineCommand52 } from "citty";
6426
+ import { defineCommand as defineCommand56 } from "citty";
6250
6427
  var execAsync = promisify(exec);
6251
6428
  async function resolveApeShellPath() {
6252
6429
  try {
@@ -6282,7 +6459,7 @@ async function bestEffortGrantCount(idp) {
6282
6459
  }
6283
6460
  }
6284
6461
  async function runHealth(args) {
6285
- const version = true ? "1.6.0" : "0.0.0";
6462
+ const version = true ? "1.7.0" : "0.0.0";
6286
6463
  const auth = loadAuth();
6287
6464
  if (!auth) {
6288
6465
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -6345,7 +6522,7 @@ async function runHealth(args) {
6345
6522
  throw new CliError(`IdP ${auth.idp} unreachable: ${idpProbe.error}`, 1);
6346
6523
  }
6347
6524
  }
6348
- var healthCommand = defineCommand52({
6525
+ var healthCommand = defineCommand56({
6349
6526
  meta: {
6350
6527
  name: "health",
6351
6528
  description: "Report CLI diagnostic state (auth, IdP, grants, binaries)"
@@ -6363,8 +6540,8 @@ var healthCommand = defineCommand52({
6363
6540
  });
6364
6541
 
6365
6542
  // src/commands/workflows.ts
6366
- import { defineCommand as defineCommand53 } from "citty";
6367
- import consola42 from "consola";
6543
+ import { defineCommand as defineCommand57 } from "citty";
6544
+ import consola45 from "consola";
6368
6545
 
6369
6546
  // src/guides/index.ts
6370
6547
  var guides = [
@@ -6414,7 +6591,7 @@ var guides = [
6414
6591
  ];
6415
6592
 
6416
6593
  // src/commands/workflows.ts
6417
- var workflowsCommand = defineCommand53({
6594
+ var workflowsCommand = defineCommand57({
6418
6595
  meta: {
6419
6596
  name: "workflows",
6420
6597
  description: "Discover workflow guides"
@@ -6435,7 +6612,7 @@ var workflowsCommand = defineCommand53({
6435
6612
  if (args.id) {
6436
6613
  const guide = guides.find((g) => g.id === String(args.id));
6437
6614
  if (!guide) {
6438
- consola42.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
6615
+ consola45.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
6439
6616
  throw new CliError(`Guide not found: ${args.id}`);
6440
6617
  }
6441
6618
  if (args.json) {
@@ -6478,7 +6655,7 @@ var workflowsCommand = defineCommand53({
6478
6655
  import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
6479
6656
  import { homedir as homedir13 } from "os";
6480
6657
  import { join as join14 } from "path";
6481
- import consola43 from "consola";
6658
+ import consola46 from "consola";
6482
6659
  var PACKAGE_NAME = "@openape/apes";
6483
6660
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
6484
6661
  var CACHE_FILE = join14(homedir13(), ".config", "apes", ".version-check.json");
@@ -6523,7 +6700,7 @@ async function fetchLatestVersion() {
6523
6700
  }
6524
6701
  function warnIfBehind(currentVersion, latest) {
6525
6702
  if (compareSemver(currentVersion, latest) < 0) {
6526
- consola43.warn(
6703
+ consola46.warn(
6527
6704
  `apes ${currentVersion} is behind latest @openape/apes@${latest}. Run \`npm i -g @openape/apes@latest\` to update. (Suppress with APES_NO_UPDATE_CHECK=1.)`
6528
6705
  );
6529
6706
  }
@@ -6555,10 +6732,10 @@ if (shellRewrite) {
6555
6732
  if (shellRewrite.action === "rewrite") {
6556
6733
  process.argv = shellRewrite.argv;
6557
6734
  } else if (shellRewrite.action === "version") {
6558
- console.log(`ape-shell ${"1.6.0"} (OpenApe DDISA shell wrapper)`);
6735
+ console.log(`ape-shell ${"1.7.0"} (OpenApe DDISA shell wrapper)`);
6559
6736
  process.exit(0);
6560
6737
  } else if (shellRewrite.action === "help") {
6561
- console.log(`ape-shell ${"1.6.0"} \u2014 OpenApe DDISA shell wrapper`);
6738
+ console.log(`ape-shell ${"1.7.0"} \u2014 OpenApe DDISA shell wrapper`);
6562
6739
  console.log("");
6563
6740
  console.log("Usage:");
6564
6741
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -6582,7 +6759,7 @@ if (shellRewrite) {
6582
6759
  }
6583
6760
  }
6584
6761
  var debug = process.argv.includes("--debug");
6585
- var grantsCommand = defineCommand54({
6762
+ var grantsCommand = defineCommand58({
6586
6763
  meta: {
6587
6764
  name: "grants",
6588
6765
  description: "Grant management"
@@ -6603,7 +6780,7 @@ var grantsCommand = defineCommand54({
6603
6780
  "delegation-revoke": delegationRevokeCommand
6604
6781
  }
6605
6782
  });
6606
- var configCommand = defineCommand54({
6783
+ var configCommand = defineCommand58({
6607
6784
  meta: {
6608
6785
  name: "config",
6609
6786
  description: "Configuration management"
@@ -6613,10 +6790,10 @@ var configCommand = defineCommand54({
6613
6790
  set: configSetCommand
6614
6791
  }
6615
6792
  });
6616
- var main = defineCommand54({
6793
+ var main = defineCommand58({
6617
6794
  meta: {
6618
6795
  name: "apes",
6619
- version: "1.6.0",
6796
+ version: "1.7.0",
6620
6797
  description: "Unified CLI for OpenApe"
6621
6798
  },
6622
6799
  subCommands: {
@@ -6633,6 +6810,7 @@ var main = defineCommand54({
6633
6810
  grants: grantsCommand,
6634
6811
  agents: agentsCommand,
6635
6812
  nest: nestCommand,
6813
+ yolo: yoloCommand,
6636
6814
  admin: adminCommand,
6637
6815
  run: runCommand,
6638
6816
  proxy: proxyCommand,
@@ -6672,20 +6850,20 @@ async function maybeRefreshAuth() {
6672
6850
  }
6673
6851
  }
6674
6852
  await maybeRefreshAuth();
6675
- await maybeWarnStaleVersion("1.6.0").catch(() => {
6853
+ await maybeWarnStaleVersion("1.7.0").catch(() => {
6676
6854
  });
6677
6855
  runMain(main).catch((err) => {
6678
6856
  if (err instanceof CliExit) {
6679
6857
  process.exit(err.exitCode);
6680
6858
  }
6681
6859
  if (err instanceof CliError) {
6682
- consola44.error(err.message);
6860
+ consola47.error(err.message);
6683
6861
  process.exit(err.exitCode);
6684
6862
  }
6685
6863
  if (debug) {
6686
- consola44.error(err);
6864
+ consola47.error(err);
6687
6865
  } else {
6688
- consola44.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
6866
+ consola47.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
6689
6867
  }
6690
6868
  process.exit(1);
6691
6869
  });