@openape/apes 1.4.0 → 1.5.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 consola42 from "consola";
66
+ import consola43 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 defineCommand52, runMain } from "citty";
96
+ import { defineCommand as defineCommand53, runMain } from "citty";
97
97
 
98
98
  // src/commands/auth/login.ts
99
99
  import { Buffer as Buffer2 } from "buffer";
@@ -3918,15 +3918,135 @@ var agentsCommand = defineCommand28({
3918
3918
  });
3919
3919
 
3920
3920
  // src/commands/nest/index.ts
3921
- import { defineCommand as defineCommand32 } from "citty";
3921
+ import { defineCommand as defineCommand33 } from "citty";
3922
3922
 
3923
- // src/commands/nest/install.ts
3923
+ // src/commands/nest/authorize.ts
3924
3924
  import { execFileSync as execFileSync9 } from "child_process";
3925
- import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
3926
- import { homedir as homedir10, userInfo as userInfo2 } from "os";
3927
- import { join as join8 } from "path";
3928
3925
  import { defineCommand as defineCommand29 } from "citty";
3929
3926
  import consola25 from "consola";
3927
+ var authorizeNestCommand = defineCommand29({
3928
+ meta: {
3929
+ name: "authorize",
3930
+ description: "Request the always-capability-grant the nest needs for zero-prompt spawn/destroy"
3931
+ },
3932
+ args: {
3933
+ "reason": {
3934
+ type: "string",
3935
+ description: "Reason shown in the DDISA approval UI"
3936
+ },
3937
+ "wait": {
3938
+ type: "boolean",
3939
+ description: "Block until the grant is approved (default: print URL + exit 0)"
3940
+ }
3941
+ },
3942
+ async run({ args }) {
3943
+ const reason = args.reason ?? "nest-managed agent lifecycle (spawn / destroy / sync) \u2014 approve as Always";
3944
+ consola25.info("Requesting capability-grant for `apes-agents` (selector name=* covers all agent names)...");
3945
+ consola25.info("");
3946
+ consola25.info("When the IdP approval page opens, choose **Always** so the nest can re-use the grant on every spawn.");
3947
+ consola25.info("");
3948
+ const cmdArgs = [
3949
+ "grants",
3950
+ "request-capability",
3951
+ "apes-agents",
3952
+ "--resource",
3953
+ "agents:*",
3954
+ "--selector",
3955
+ "name=*",
3956
+ "--action",
3957
+ "create",
3958
+ "--action",
3959
+ "delete",
3960
+ "--action",
3961
+ "edit",
3962
+ "--action",
3963
+ "list",
3964
+ "--approval=always",
3965
+ "--reason",
3966
+ reason,
3967
+ "--run-as",
3968
+ "root"
3969
+ ];
3970
+ if (args.wait) cmdArgs.push("--wait");
3971
+ try {
3972
+ execFileSync9("apes", cmdArgs, { stdio: "inherit" });
3973
+ } catch (err) {
3974
+ throw new Error(err instanceof Error ? err.message : String(err));
3975
+ }
3976
+ }
3977
+ });
3978
+
3979
+ // src/commands/nest/install.ts
3980
+ import { execFileSync as execFileSync10 } from "child_process";
3981
+ import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
3982
+ import { homedir as homedir10, userInfo as userInfo2 } from "os";
3983
+ import { dirname as dirname3, join as join8 } from "path";
3984
+ import { defineCommand as defineCommand30 } from "citty";
3985
+ import consola26 from "consola";
3986
+
3987
+ // src/commands/nest/apes-agents-adapter.ts
3988
+ var APES_AGENTS_ADAPTER_TOML = `schema = "openape-shapes/v1"
3989
+
3990
+ # Adapter for the \`apes agents\` subtree \u2014 written by \`apes nest install\`.
3991
+ # A capability-grant with selector \`name=*\` covers any agent name
3992
+ # (selectorValueMatches treats '*' as a glob), letting the nest spawn
3993
+ # and destroy without per-agent DDISA prompts.
3994
+
3995
+ [cli]
3996
+ id = "apes-agents"
3997
+ executable = "apes"
3998
+ audience = "shapes"
3999
+ version = "1"
4000
+
4001
+ # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
4002
+ # AGENT LIFECYCLE \u2014 spawn / destroy / sync
4003
+ # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
4004
+
4005
+ [[operation]]
4006
+ id = "agents.spawn"
4007
+ command = ["agents", "spawn"]
4008
+ positionals = ["name"]
4009
+ display = "Spawn agent {name}"
4010
+ action = "create"
4011
+ risk = "high"
4012
+ resource_chain = ["agents:name={name}"]
4013
+
4014
+ [[operation]]
4015
+ id = "agents.destroy"
4016
+ command = ["agents", "destroy"]
4017
+ positionals = ["name"]
4018
+ display = "Destroy agent {name}"
4019
+ action = "delete"
4020
+ risk = "critical"
4021
+ resource_chain = ["agents:name={name}"]
4022
+
4023
+ [[operation]]
4024
+ id = "agents.sync"
4025
+ command = ["agents", "sync"]
4026
+ display = "Sync agent state with troop"
4027
+ action = "edit"
4028
+ risk = "low"
4029
+ resource_chain = ["agents:*"]
4030
+
4031
+ [[operation]]
4032
+ id = "agents.list"
4033
+ command = ["agents", "list"]
4034
+ display = "List agents"
4035
+ action = "list"
4036
+ risk = "low"
4037
+ resource_chain = ["agents:*"]
4038
+
4039
+ [[operation]]
4040
+ id = "agents.allow"
4041
+ command = ["agents", "allow"]
4042
+ positionals = ["name", "peer_email"]
4043
+ display = "Allow agent {name} to accept contact requests from {peer_email}"
4044
+ action = "edit"
4045
+ risk = "medium"
4046
+ resource_chain = ["agents:name={name}", "allowlist:email={peer_email}"]
4047
+ `;
4048
+
4049
+ // src/commands/nest/install.ts
3930
4050
  var PLIST_LABEL = "ai.openape.nest";
3931
4051
  function plistPath() {
3932
4052
  return join8(homedir10(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
@@ -3969,6 +4089,19 @@ function buildPlist(args) {
3969
4089
  </plist>
3970
4090
  `;
3971
4091
  }
4092
+ function installAdapter2() {
4093
+ const target = join8(homedir10(), ".openape", "shapes", "adapters", "apes-agents.toml");
4094
+ mkdirSync4(dirname3(target), { recursive: true });
4095
+ let existing = "";
4096
+ try {
4097
+ existing = readFileSync10(target, "utf8");
4098
+ } catch {
4099
+ }
4100
+ if (existing === APES_AGENTS_ADAPTER_TOML) return false;
4101
+ writeFileSync6(target, APES_AGENTS_ADAPTER_TOML, { mode: 420 });
4102
+ consola26.success(`Wrote shapes adapter ${target}`);
4103
+ return true;
4104
+ }
3972
4105
  function findBinary(name) {
3973
4106
  for (const dir of [
3974
4107
  join8(homedir10(), ".bun", "bin"),
@@ -3981,7 +4114,7 @@ function findBinary(name) {
3981
4114
  }
3982
4115
  throw new Error(`could not locate ${name} on PATH; install it first`);
3983
4116
  }
3984
- var installNestCommand = defineCommand29({
4117
+ var installNestCommand = defineCommand30({
3985
4118
  meta: {
3986
4119
  name: "install",
3987
4120
  description: "Install + start the local nest-daemon (idempotent \u2014 re-running just restarts)"
@@ -4000,10 +4133,11 @@ var installNestCommand = defineCommand29({
4000
4133
  }
4001
4134
  const nestBin = findBinary("openape-nest");
4002
4135
  const apesBin = findBinary("apes");
4003
- consola25.info(`Installing nest at ${plistPath()}`);
4004
- consola25.info(` nest binary: ${nestBin}`);
4005
- consola25.info(` apes binary: ${apesBin}`);
4006
- consola25.info(` HTTP port: ${port}`);
4136
+ consola26.info(`Installing nest at ${plistPath()}`);
4137
+ consola26.info(` nest binary: ${nestBin}`);
4138
+ consola26.info(` apes binary: ${apesBin}`);
4139
+ consola26.info(` HTTP port: ${port}`);
4140
+ installAdapter2();
4007
4141
  mkdirSync4(join8(homeDir, "Library", "LaunchAgents"), { recursive: true });
4008
4142
  const desired = buildPlist({ nestBin, apesBin, homeDir, port });
4009
4143
  let existing = "";
@@ -4013,35 +4147,33 @@ var installNestCommand = defineCommand29({
4013
4147
  }
4014
4148
  if (existing !== desired) {
4015
4149
  writeFileSync6(plistPath(), desired, { mode: 420 });
4016
- consola25.success("Wrote launchd plist");
4150
+ consola26.success("Wrote launchd plist");
4017
4151
  } else {
4018
- consola25.info("plist already up to date");
4152
+ consola26.info("plist already up to date");
4019
4153
  }
4020
4154
  const uid = userInfo2().uid;
4021
4155
  try {
4022
- execFileSync9("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL}`], { stdio: "ignore" });
4156
+ execFileSync10("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL}`], { stdio: "ignore" });
4023
4157
  } catch {
4024
4158
  }
4025
- execFileSync9("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
4026
- consola25.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
4027
- consola25.info("");
4028
- consola25.info("Next: approve the always-grant for nest-managed spawn/destroy.");
4029
- consola25.info('Run this once and choose "Always" when the IdP UI prompts:');
4030
- consola25.info("");
4031
- consola25.info(' apes run --as root --approval=always --reason "nest-managed agent spawn" \\');
4032
- consola25.info(" -- apes agents spawn _grant_pattern_seed_");
4033
- consola25.info("");
4034
- consola25.info('(The seed-spawn will fail because "_grant_pattern_seed_" is not a valid');
4035
- consola25.info("agent name \u2014 that's expected. The grant just needs to be approved-as-always.)");
4159
+ execFileSync10("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
4160
+ consola26.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
4161
+ consola26.info("");
4162
+ consola26.info("Next: request the capability-grant that lets the nest spawn/destroy any agent without per-call approval:");
4163
+ consola26.info("");
4164
+ consola26.info(" apes nest authorize");
4165
+ consola26.info("");
4166
+ consola26.info("That requests an `apes-agents` capability-grant covering all agent names (selector glob `name=*`)");
4167
+ consola26.info("from your DDISA inbox; approve it once as `always` and the nest API runs silently from then on.");
4036
4168
  }
4037
4169
  });
4038
4170
 
4039
4171
  // src/commands/nest/status.ts
4040
4172
  import process2 from "process";
4041
- import { defineCommand as defineCommand30 } from "citty";
4042
- import consola26 from "consola";
4173
+ import { defineCommand as defineCommand31 } from "citty";
4174
+ import consola27 from "consola";
4043
4175
  var DEFAULT_PORT = 9091;
4044
- var statusNestCommand = defineCommand30({
4176
+ var statusNestCommand = defineCommand31({
4045
4177
  meta: {
4046
4178
  name: "status",
4047
4179
  description: "Print state of the local nest-daemon (agents registered, processes supervised)"
@@ -4061,8 +4193,8 @@ var statusNestCommand = defineCommand30({
4061
4193
  } catch (err) {
4062
4194
  const msg = err instanceof Error ? err.message : String(err);
4063
4195
  if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
4064
- consola26.error(`Nest daemon is not running at http://127.0.0.1:${port}`);
4065
- consola26.info(" Run: apes nest install");
4196
+ consola27.error(`Nest daemon is not running at http://127.0.0.1:${port}`);
4197
+ consola27.info(" Run: apes nest install");
4066
4198
  process2.exit(2);
4067
4199
  }
4068
4200
  throw err;
@@ -4071,15 +4203,15 @@ var statusNestCommand = defineCommand30({
4071
4203
  console.log(JSON.stringify(status, null, 2));
4072
4204
  return;
4073
4205
  }
4074
- consola26.info(`Nest at http://127.0.0.1:${port} \u2014 ${status.agents} agent(s) registered, ${status.processes.length} supervised`);
4206
+ consola27.info(`Nest at http://127.0.0.1:${port} \u2014 ${status.agents} agent(s) registered, ${status.processes.length} supervised`);
4075
4207
  if (status.processes.length === 0) {
4076
- consola26.info(" (no processes running)");
4208
+ consola27.info(" (no processes running)");
4077
4209
  return;
4078
4210
  }
4079
4211
  for (const p of status.processes) {
4080
4212
  const uptime = humanDuration(p.uptimeSec);
4081
4213
  const crashTag = p.consecutiveCrashes > 0 ? ` \u26A0 ${p.consecutiveCrashes} crash(es)` : "";
4082
- consola26.info(` ${p.name.padEnd(16)} pid=${String(p.pid).padEnd(6)} up=${uptime}${crashTag}`);
4214
+ consola27.info(` ${p.name.padEnd(16)} pid=${String(p.pid).padEnd(6)} up=${uptime}${crashTag}`);
4083
4215
  }
4084
4216
  }
4085
4217
  });
@@ -4091,14 +4223,14 @@ function humanDuration(sec) {
4091
4223
  }
4092
4224
 
4093
4225
  // src/commands/nest/uninstall.ts
4094
- import { execFileSync as execFileSync10 } from "child_process";
4226
+ import { execFileSync as execFileSync11 } from "child_process";
4095
4227
  import { existsSync as existsSync11, unlinkSync } from "fs";
4096
4228
  import { homedir as homedir11, userInfo as userInfo3 } from "os";
4097
4229
  import { join as join9 } from "path";
4098
- import { defineCommand as defineCommand31 } from "citty";
4099
- import consola27 from "consola";
4230
+ import { defineCommand as defineCommand32 } from "citty";
4231
+ import consola28 from "consola";
4100
4232
  var PLIST_LABEL2 = "ai.openape.nest";
4101
- var uninstallNestCommand = defineCommand31({
4233
+ var uninstallNestCommand = defineCommand32({
4102
4234
  meta: {
4103
4235
  name: "uninstall",
4104
4236
  description: "Stop + remove the local nest-daemon (registry + agents preserved)"
@@ -4107,42 +4239,43 @@ var uninstallNestCommand = defineCommand31({
4107
4239
  const uid = userInfo3().uid;
4108
4240
  const path2 = join9(homedir11(), "Library", "LaunchAgents", `${PLIST_LABEL2}.plist`);
4109
4241
  try {
4110
- execFileSync10("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
4111
- consola27.success("Nest daemon stopped");
4242
+ execFileSync11("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
4243
+ consola28.success("Nest daemon stopped");
4112
4244
  } catch {
4113
- consola27.info("Nest daemon was not loaded");
4245
+ consola28.info("Nest daemon was not loaded");
4114
4246
  }
4115
4247
  if (existsSync11(path2)) {
4116
4248
  unlinkSync(path2);
4117
- consola27.success(`Removed ${path2}`);
4249
+ consola28.success(`Removed ${path2}`);
4118
4250
  }
4119
- consola27.info("Registry at ~/.openape/nest/agents.json kept \u2014 re-run `apes nest install` to resume supervision.");
4251
+ consola28.info("Registry at ~/.openape/nest/agents.json kept \u2014 re-run `apes nest install` to resume supervision.");
4120
4252
  }
4121
4253
  });
4122
4254
 
4123
4255
  // src/commands/nest/index.ts
4124
- var nestCommand = defineCommand32({
4256
+ var nestCommand = defineCommand33({
4125
4257
  meta: {
4126
4258
  name: "nest",
4127
- description: "Manage the local Nest control-plane daemon (install, status, uninstall). The Nest hosts agents on this computer \u2014 once installed, `apes agents spawn` is fast (no per-spawn DDISA approvals) and per-agent launchd plists are replaced by a single supervised process tree."
4259
+ description: "Manage the local Nest control-plane daemon (install, authorize, status, uninstall). The Nest hosts agents on this computer \u2014 once installed + authorized, `apes agents spawn` is fast (no per-spawn DDISA approvals) and per-agent launchd plists are replaced by a single supervised process tree."
4128
4260
  },
4129
4261
  subCommands: {
4130
4262
  install: installNestCommand,
4263
+ authorize: authorizeNestCommand,
4131
4264
  status: statusNestCommand,
4132
4265
  uninstall: uninstallNestCommand
4133
4266
  }
4134
4267
  });
4135
4268
 
4136
4269
  // src/commands/adapter/index.ts
4137
- import { defineCommand as defineCommand33 } from "citty";
4138
- import consola28 from "consola";
4139
- var adapterCommand = defineCommand33({
4270
+ import { defineCommand as defineCommand34 } from "citty";
4271
+ import consola29 from "consola";
4272
+ var adapterCommand = defineCommand34({
4140
4273
  meta: {
4141
4274
  name: "adapter",
4142
4275
  description: "Manage CLI adapters"
4143
4276
  },
4144
4277
  subCommands: {
4145
- list: defineCommand33({
4278
+ list: defineCommand34({
4146
4279
  meta: {
4147
4280
  name: "list",
4148
4281
  description: "List available adapters"
@@ -4173,7 +4306,7 @@ var adapterCommand = defineCommand33({
4173
4306
  `);
4174
4307
  return;
4175
4308
  }
4176
- consola28.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
4309
+ consola29.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
4177
4310
  for (const a of index2.adapters) {
4178
4311
  const installed = isInstalled(a.id, false) ? " [installed]" : "";
4179
4312
  console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}${installed}`);
@@ -4195,7 +4328,7 @@ var adapterCommand = defineCommand33({
4195
4328
  return;
4196
4329
  }
4197
4330
  if (local.length === 0) {
4198
- consola28.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
4331
+ consola29.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
4199
4332
  return;
4200
4333
  }
4201
4334
  for (const a of local) {
@@ -4203,7 +4336,7 @@ var adapterCommand = defineCommand33({
4203
4336
  }
4204
4337
  }
4205
4338
  }),
4206
- install: defineCommand33({
4339
+ install: defineCommand34({
4207
4340
  meta: {
4208
4341
  name: "install",
4209
4342
  description: "Install an adapter from the registry"
@@ -4232,24 +4365,24 @@ var adapterCommand = defineCommand33({
4232
4365
  for (const id of ids) {
4233
4366
  const entry = findAdapter(index, id);
4234
4367
  if (!entry) {
4235
- consola28.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
4368
+ consola29.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
4236
4369
  continue;
4237
4370
  }
4238
4371
  const conflicts = findConflictingAdapters(entry.executable, id);
4239
4372
  if (conflicts.length > 0) {
4240
4373
  for (const c of conflicts) {
4241
- consola28.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`);
4242
- consola28.warn(` Remove it with: apes adapter remove ${c.adapterId}`);
4374
+ consola29.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`);
4375
+ consola29.warn(` Remove it with: apes adapter remove ${c.adapterId}`);
4243
4376
  }
4244
4377
  }
4245
4378
  const result = await installAdapter(entry, { local });
4246
4379
  const verb = result.updated ? "Updated" : "Installed";
4247
- consola28.success(`${verb} ${result.id} \u2192 ${result.path}`);
4248
- consola28.info(`Digest: ${result.digest}`);
4380
+ consola29.success(`${verb} ${result.id} \u2192 ${result.path}`);
4381
+ consola29.info(`Digest: ${result.digest}`);
4249
4382
  }
4250
4383
  }
4251
4384
  }),
4252
- remove: defineCommand33({
4385
+ remove: defineCommand34({
4253
4386
  meta: {
4254
4387
  name: "remove",
4255
4388
  description: "Remove an installed adapter"
@@ -4272,9 +4405,9 @@ var adapterCommand = defineCommand33({
4272
4405
  let failed = false;
4273
4406
  for (const id of ids) {
4274
4407
  if (removeAdapter(id, local)) {
4275
- consola28.success(`Removed adapter: ${id}`);
4408
+ consola29.success(`Removed adapter: ${id}`);
4276
4409
  } else {
4277
- consola28.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
4410
+ consola29.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
4278
4411
  failed = true;
4279
4412
  }
4280
4413
  }
@@ -4282,7 +4415,7 @@ var adapterCommand = defineCommand33({
4282
4415
  throw new CliError("Some adapters could not be removed");
4283
4416
  }
4284
4417
  }),
4285
- info: defineCommand33({
4418
+ info: defineCommand34({
4286
4419
  meta: {
4287
4420
  name: "info",
4288
4421
  description: "Show detailed adapter information"
@@ -4324,7 +4457,7 @@ var adapterCommand = defineCommand33({
4324
4457
  }
4325
4458
  }
4326
4459
  }),
4327
- search: defineCommand33({
4460
+ search: defineCommand34({
4328
4461
  meta: {
4329
4462
  name: "search",
4330
4463
  description: "Search adapters in the registry"
@@ -4356,7 +4489,7 @@ var adapterCommand = defineCommand33({
4356
4489
  return;
4357
4490
  }
4358
4491
  if (results.length === 0) {
4359
- consola28.info(`No adapters matching "${query}"`);
4492
+ consola29.info(`No adapters matching "${query}"`);
4360
4493
  return;
4361
4494
  }
4362
4495
  for (const a of results) {
@@ -4365,7 +4498,7 @@ var adapterCommand = defineCommand33({
4365
4498
  }
4366
4499
  }
4367
4500
  }),
4368
- update: defineCommand33({
4501
+ update: defineCommand34({
4369
4502
  meta: {
4370
4503
  name: "update",
4371
4504
  description: "Update installed adapters"
@@ -4391,33 +4524,33 @@ var adapterCommand = defineCommand33({
4391
4524
  const targetId = args.id ? String(args.id) : void 0;
4392
4525
  const targets = targetId ? [targetId] : index.adapters.map((a) => a.id).filter((id) => isInstalled(id, false));
4393
4526
  if (targets.length === 0) {
4394
- consola28.info("No adapters installed to update.");
4527
+ consola29.info("No adapters installed to update.");
4395
4528
  return;
4396
4529
  }
4397
4530
  for (const id of targets) {
4398
4531
  const entry = findAdapter(index, id);
4399
4532
  if (!entry) {
4400
- consola28.warn(`${id}: not found in registry, skipping`);
4533
+ consola29.warn(`${id}: not found in registry, skipping`);
4401
4534
  continue;
4402
4535
  }
4403
4536
  const localDigest = getInstalledDigest(id, false);
4404
4537
  if (localDigest === entry.digest) {
4405
- consola28.info(`${id}: already up to date`);
4538
+ consola29.info(`${id}: already up to date`);
4406
4539
  continue;
4407
4540
  }
4408
4541
  if (localDigest && !args.yes) {
4409
- consola28.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
4410
- consola28.info(` Old: ${localDigest}`);
4411
- consola28.info(` New: ${entry.digest}`);
4412
- consola28.info(" Use --yes to confirm");
4542
+ consola29.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
4543
+ consola29.info(` Old: ${localDigest}`);
4544
+ consola29.info(` New: ${entry.digest}`);
4545
+ consola29.info(" Use --yes to confirm");
4413
4546
  continue;
4414
4547
  }
4415
4548
  const result = await installAdapter(entry);
4416
- consola28.success(`Updated ${result.id} \u2192 ${result.path}`);
4549
+ consola29.success(`Updated ${result.id} \u2192 ${result.path}`);
4417
4550
  }
4418
4551
  }
4419
4552
  }),
4420
- verify: defineCommand33({
4553
+ verify: defineCommand34({
4421
4554
  meta: {
4422
4555
  name: "verify",
4423
4556
  description: "Verify installed adapter against registry digest"
@@ -4450,7 +4583,7 @@ var adapterCommand = defineCommand33({
4450
4583
  if (!localDigest)
4451
4584
  throw new Error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
4452
4585
  if (localDigest === entry.digest) {
4453
- consola28.success(`${id}: digest matches registry`);
4586
+ consola29.success(`${id}: digest matches registry`);
4454
4587
  } else {
4455
4588
  console.log(` Local: ${localDigest}`);
4456
4589
  console.log(` Registry: ${entry.digest}`);
@@ -4462,11 +4595,11 @@ var adapterCommand = defineCommand33({
4462
4595
  });
4463
4596
 
4464
4597
  // src/commands/run.ts
4465
- import { execFileSync as execFileSync11 } from "child_process";
4598
+ import { execFileSync as execFileSync12 } from "child_process";
4466
4599
  import { hostname as hostname4 } from "os";
4467
4600
  import { basename } from "path";
4468
- import { defineCommand as defineCommand34 } from "citty";
4469
- import consola29 from "consola";
4601
+ import { defineCommand as defineCommand35 } from "citty";
4602
+ import consola30 from "consola";
4470
4603
  function shouldWaitForGrant(args) {
4471
4604
  return args.wait === true || process.env.APE_WAIT === "1";
4472
4605
  }
@@ -4503,7 +4636,7 @@ function printPendingGrantInfo(grant, idp) {
4503
4636
  const statusCmd = `apes grants status ${grant.id}`;
4504
4637
  const executeCmd = `apes grants run ${grant.id}`;
4505
4638
  if (mode === "human") {
4506
- consola29.success(`Grant ${grant.id} created \u2014 awaiting your approval`);
4639
+ consola30.success(`Grant ${grant.id} created \u2014 awaiting your approval`);
4507
4640
  console.log(` Approve in browser: ${approveUrl}`);
4508
4641
  console.log(` Check status: ${statusCmd}`);
4509
4642
  console.log(` Run after approval: ${executeCmd}`);
@@ -4513,7 +4646,7 @@ function printPendingGrantInfo(grant, idp) {
4513
4646
  return;
4514
4647
  }
4515
4648
  const maxMin = getPollMaxMinutes();
4516
- consola29.success(`Grant ${grant.id} created (pending approval)`);
4649
+ consola30.success(`Grant ${grant.id} created (pending approval)`);
4517
4650
  console.log(` Approve: ${approveUrl}`);
4518
4651
  console.log(` Status: ${statusCmd} [--json]`);
4519
4652
  console.log(` Execute: ${executeCmd} --wait`);
@@ -4535,7 +4668,7 @@ function printPendingGrantInfo(grant, idp) {
4535
4668
  console.log(' Tip: Approve as "timed" or "always" in the browser to let this');
4536
4669
  console.log(" grant be reused on subsequent invocations without re-approval.");
4537
4670
  }
4538
- var runCommand = defineCommand34({
4671
+ var runCommand = defineCommand35({
4539
4672
  meta: {
4540
4673
  name: "run",
4541
4674
  description: "Execute a grant-secured command"
@@ -4638,7 +4771,7 @@ async function runShellMode(command, args) {
4638
4771
  }
4639
4772
  } catch {
4640
4773
  }
4641
- consola29.info(`Requesting ape-shell session grant on ${targetHost}`);
4774
+ consola30.info(`Requesting ape-shell session grant on ${targetHost}`);
4642
4775
  const grant = await apiFetch(grantsUrl, {
4643
4776
  method: "POST",
4644
4777
  body: {
@@ -4658,8 +4791,8 @@ async function runShellMode(command, args) {
4658
4791
  host: targetHost
4659
4792
  });
4660
4793
  if (shouldWaitForGrant(args)) {
4661
- consola29.info(`Grant requested: ${grant.id}`);
4662
- consola29.info("Waiting for approval...");
4794
+ consola30.info(`Grant requested: ${grant.id}`);
4795
+ consola30.info("Waiting for approval...");
4663
4796
  const maxWait = 3e5;
4664
4797
  const interval = 3e3;
4665
4798
  const start = Date.now();
@@ -4690,13 +4823,13 @@ async function tryAdapterModeFromShell(command, idp, args) {
4690
4823
  try {
4691
4824
  resolved = await resolveCommand(loaded, [normalizedExecutable, ...parsed.argv]);
4692
4825
  } catch (err) {
4693
- consola29.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
4826
+ consola30.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
4694
4827
  return false;
4695
4828
  }
4696
4829
  try {
4697
4830
  const existingGrantId = await findExistingGrant(resolved, idp);
4698
4831
  if (existingGrantId) {
4699
- consola29.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
4832
+ consola30.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
4700
4833
  const token = await fetchGrantToken(idp, existingGrantId);
4701
4834
  await verifyAndExecute(token, resolved, existingGrantId);
4702
4835
  return true;
@@ -4704,7 +4837,7 @@ async function tryAdapterModeFromShell(command, idp, args) {
4704
4837
  } catch {
4705
4838
  }
4706
4839
  const approval = args.approval ?? "once";
4707
- consola29.info(`Requesting grant for: ${resolved.detail.display}`);
4840
+ consola30.info(`Requesting grant for: ${resolved.detail.display}`);
4708
4841
  const grant = await createShapesGrant(resolved, {
4709
4842
  idp,
4710
4843
  approval,
@@ -4712,8 +4845,8 @@ async function tryAdapterModeFromShell(command, idp, args) {
4712
4845
  });
4713
4846
  if (grant.similar_grants?.similar_grants?.length) {
4714
4847
  const n = grant.similar_grants.similar_grants.length;
4715
- consola29.info("");
4716
- consola29.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
4848
+ consola30.info("");
4849
+ consola30.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
4717
4850
  }
4718
4851
  notifyGrantPending({
4719
4852
  grantId: grant.id,
@@ -4723,8 +4856,8 @@ async function tryAdapterModeFromShell(command, idp, args) {
4723
4856
  host: args.host || hostname4()
4724
4857
  });
4725
4858
  if (shouldWaitForGrant(args)) {
4726
- consola29.info(`Grant requested: ${grant.id}`);
4727
- consola29.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
4859
+ consola30.info(`Grant requested: ${grant.id}`);
4860
+ consola30.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
4728
4861
  const status = await waitForGrantStatus(idp, grant.id);
4729
4862
  if (status !== "approved")
4730
4863
  throw new CliError(`Grant ${status}`);
@@ -4740,7 +4873,7 @@ function execShellCommand(command) {
4740
4873
  throw new CliError("No command to execute");
4741
4874
  try {
4742
4875
  const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
4743
- execFileSync11(command[0], command.slice(1), {
4876
+ execFileSync12(command[0], command.slice(1), {
4744
4877
  stdio: "inherit",
4745
4878
  env: inheritedEnv
4746
4879
  });
@@ -4798,7 +4931,7 @@ async function runAdapterMode(command, rawArgs, args) {
4798
4931
  try {
4799
4932
  const existingGrantId = await findExistingGrant(resolved, idp);
4800
4933
  if (existingGrantId) {
4801
- consola29.info(`Reusing existing grant: ${existingGrantId}`);
4934
+ consola30.info(`Reusing existing grant: ${existingGrantId}`);
4802
4935
  const token = await fetchGrantToken(idp, existingGrantId);
4803
4936
  await verifyAndExecute(token, resolved, existingGrantId);
4804
4937
  return;
@@ -4812,17 +4945,17 @@ async function runAdapterMode(command, rawArgs, args) {
4812
4945
  });
4813
4946
  if (grant.similar_grants?.similar_grants?.length) {
4814
4947
  const n = grant.similar_grants.similar_grants.length;
4815
- consola29.info("");
4816
- consola29.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
4948
+ consola30.info("");
4949
+ consola30.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
4817
4950
  if (grant.similar_grants.widened_details?.length) {
4818
4951
  const wider = grant.similar_grants.widened_details.map((d) => d.permission).join(", ");
4819
- consola29.info(` Broader scope: ${wider}`);
4952
+ consola30.info(` Broader scope: ${wider}`);
4820
4953
  }
4821
- consola29.info("");
4954
+ consola30.info("");
4822
4955
  }
4823
4956
  if (shouldWaitForGrant(args)) {
4824
- consola29.info(`Grant requested: ${grant.id}`);
4825
- consola29.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
4957
+ consola30.info(`Grant requested: ${grant.id}`);
4958
+ consola30.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
4826
4959
  const status = await waitForGrantStatus(idp, grant.id);
4827
4960
  if (status !== "approved")
4828
4961
  throw new Error(`Grant ${status}`);
@@ -4842,7 +4975,7 @@ async function runAudienceMode(audience, action, args) {
4842
4975
  const grantsUrl = await getGrantsEndpoint(idp);
4843
4976
  const command = action.split(" ");
4844
4977
  const targetHost = args.host || hostname4();
4845
- consola29.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
4978
+ consola30.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
4846
4979
  const grant = await apiFetch(grantsUrl, {
4847
4980
  method: "POST",
4848
4981
  body: {
@@ -4859,9 +4992,9 @@ async function runAudienceMode(audience, action, args) {
4859
4992
  printPendingGrantInfo(grant, idp);
4860
4993
  throw new CliExit(getAsyncExitCode());
4861
4994
  }
4862
- consola29.success(`Grant requested: ${grant.id}`);
4863
- consola29.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
4864
- consola29.info("Waiting for approval...");
4995
+ consola30.success(`Grant requested: ${grant.id}`);
4996
+ consola30.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
4997
+ consola30.info("Waiting for approval...");
4865
4998
  const maxWait = 15 * 60 * 1e3;
4866
4999
  const interval = 3e3;
4867
5000
  const start = Date.now();
@@ -4869,7 +5002,7 @@ async function runAudienceMode(audience, action, args) {
4869
5002
  while (Date.now() - start < maxWait) {
4870
5003
  const status = await apiFetch(`${grantsUrl}/${grant.id}`);
4871
5004
  if (status.status === "approved") {
4872
- consola29.success("Grant approved!");
5005
+ consola30.success("Grant approved!");
4873
5006
  approved = true;
4874
5007
  break;
4875
5008
  }
@@ -4884,15 +5017,15 @@ async function runAudienceMode(audience, action, args) {
4884
5017
  `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.`
4885
5018
  );
4886
5019
  }
4887
- consola29.info("Fetching grant token...");
5020
+ consola30.info("Fetching grant token...");
4888
5021
  const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, {
4889
5022
  method: "POST"
4890
5023
  });
4891
5024
  if (audience === "escapes") {
4892
- consola29.info(`Executing: ${command.join(" ")}`);
5025
+ consola30.info(`Executing: ${command.join(" ")}`);
4893
5026
  try {
4894
5027
  const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
4895
- execFileSync11(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
5028
+ execFileSync12(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
4896
5029
  stdio: "inherit",
4897
5030
  env: inheritedEnv
4898
5031
  });
@@ -4907,8 +5040,8 @@ async function runAudienceMode(audience, action, args) {
4907
5040
 
4908
5041
  // src/commands/proxy.ts
4909
5042
  import { spawn as spawn2 } from "child_process";
4910
- import { defineCommand as defineCommand35 } from "citty";
4911
- import consola30 from "consola";
5043
+ import { defineCommand as defineCommand36 } from "citty";
5044
+ import consola31 from "consola";
4912
5045
 
4913
5046
  // src/proxy/config.ts
4914
5047
  function buildDefaultProxyConfigToml(opts) {
@@ -4945,7 +5078,7 @@ import { spawn } from "child_process";
4945
5078
  import { mkdtempSync as mkdtempSync3, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "fs";
4946
5079
  import { createRequire } from "module";
4947
5080
  import { tmpdir as tmpdir3 } from "os";
4948
- import { dirname as dirname3, join as join10, resolve as resolve4 } from "path";
5081
+ import { dirname as dirname4, join as join10, resolve as resolve4 } from "path";
4949
5082
  var require2 = createRequire(import.meta.url);
4950
5083
  function findProxyBin() {
4951
5084
  const pkgPath = require2.resolve("@openape/proxy/package.json");
@@ -4954,7 +5087,7 @@ function findProxyBin() {
4954
5087
  if (!binRel) {
4955
5088
  throw new Error("@openape/proxy is missing the openape-proxy bin entry");
4956
5089
  }
4957
- return resolve4(dirname3(pkgPath), binRel);
5090
+ return resolve4(dirname4(pkgPath), binRel);
4958
5091
  }
4959
5092
  async function startEphemeralProxy(configToml) {
4960
5093
  const tmpDir = mkdtempSync3(join10(tmpdir3(), "openape-proxy-"));
@@ -5051,10 +5184,10 @@ function resolveProxyConfigOptions() {
5051
5184
  77
5052
5185
  );
5053
5186
  }
5054
- consola30.info(`[apes proxy] IdP-mediated mode \u2014 agent=${auth.email}, idp=${auth.idp}`);
5187
+ consola31.info(`[apes proxy] IdP-mediated mode \u2014 agent=${auth.email}, idp=${auth.idp}`);
5055
5188
  return { agentEmail: auth.email, idpUrl: auth.idp, mediated: true };
5056
5189
  }
5057
- var proxyCommand = defineCommand35({
5190
+ var proxyCommand = defineCommand36({
5058
5191
  meta: {
5059
5192
  name: "proxy",
5060
5193
  description: "Run a command with HTTPS_PROXY routed through the OpenApe egress proxy."
@@ -5076,12 +5209,12 @@ var proxyCommand = defineCommand35({
5076
5209
  let close = null;
5077
5210
  if (reuseUrl) {
5078
5211
  proxyUrl = reuseUrl;
5079
- consola30.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`);
5212
+ consola31.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`);
5080
5213
  } else {
5081
5214
  const ephemeral = await startEphemeralProxy(buildDefaultProxyConfigToml(resolveProxyConfigOptions()));
5082
5215
  proxyUrl = ephemeral.url;
5083
5216
  close = ephemeral.close;
5084
- consola30.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`);
5217
+ consola31.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`);
5085
5218
  }
5086
5219
  const noProxy = process.env.NO_PROXY ?? process.env.no_proxy ?? "127.0.0.1,localhost";
5087
5220
  const childEnv = {
@@ -5113,7 +5246,7 @@ var proxyCommand = defineCommand35({
5113
5246
  else resolveExit(code ?? 0);
5114
5247
  });
5115
5248
  child.once("error", (err) => {
5116
- consola30.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message);
5249
+ consola31.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message);
5117
5250
  resolveExit(127);
5118
5251
  });
5119
5252
  });
@@ -5127,8 +5260,8 @@ function signalNumber(signal) {
5127
5260
  }
5128
5261
 
5129
5262
  // src/commands/explain.ts
5130
- import { defineCommand as defineCommand36 } from "citty";
5131
- var explainCommand = defineCommand36({
5263
+ import { defineCommand as defineCommand37 } from "citty";
5264
+ var explainCommand = defineCommand37({
5132
5265
  meta: {
5133
5266
  name: "explain",
5134
5267
  description: "Show what permission a command would need"
@@ -5166,9 +5299,9 @@ var explainCommand = defineCommand36({
5166
5299
  });
5167
5300
 
5168
5301
  // src/commands/config/get.ts
5169
- import { defineCommand as defineCommand37 } from "citty";
5170
- import consola31 from "consola";
5171
- var configGetCommand = defineCommand37({
5302
+ import { defineCommand as defineCommand38 } from "citty";
5303
+ import consola32 from "consola";
5304
+ var configGetCommand = defineCommand38({
5172
5305
  meta: {
5173
5306
  name: "get",
5174
5307
  description: "Get a configuration value"
@@ -5188,7 +5321,7 @@ var configGetCommand = defineCommand37({
5188
5321
  if (idp)
5189
5322
  console.log(idp);
5190
5323
  else
5191
- consola31.info("No IdP configured.");
5324
+ consola32.info("No IdP configured.");
5192
5325
  break;
5193
5326
  }
5194
5327
  case "email": {
@@ -5196,7 +5329,7 @@ var configGetCommand = defineCommand37({
5196
5329
  if (auth?.email)
5197
5330
  console.log(auth.email);
5198
5331
  else
5199
- consola31.info("Not logged in.");
5332
+ consola32.info("Not logged in.");
5200
5333
  break;
5201
5334
  }
5202
5335
  default: {
@@ -5209,7 +5342,7 @@ var configGetCommand = defineCommand37({
5209
5342
  if (sectionObj && field in sectionObj) {
5210
5343
  console.log(sectionObj[field]);
5211
5344
  } else {
5212
- consola31.info(`Key "${key}" not set.`);
5345
+ consola32.info(`Key "${key}" not set.`);
5213
5346
  }
5214
5347
  } else {
5215
5348
  throw new CliError(`Unknown key: "${key}". Use: idp, email, defaults.idp, defaults.approval, agent.key, agent.email`);
@@ -5220,9 +5353,9 @@ var configGetCommand = defineCommand37({
5220
5353
  });
5221
5354
 
5222
5355
  // src/commands/config/set.ts
5223
- import { defineCommand as defineCommand38 } from "citty";
5224
- import consola32 from "consola";
5225
- var configSetCommand = defineCommand38({
5356
+ import { defineCommand as defineCommand39 } from "citty";
5357
+ import consola33 from "consola";
5358
+ var configSetCommand = defineCommand39({
5226
5359
  meta: {
5227
5360
  name: "set",
5228
5361
  description: "Set a configuration value"
@@ -5258,12 +5391,12 @@ var configSetCommand = defineCommand38({
5258
5391
  throw new CliError(`Unknown section: "${section}". Use: defaults, agent`);
5259
5392
  }
5260
5393
  saveConfig(config);
5261
- consola32.success(`Set ${key} = ${value}`);
5394
+ consola33.success(`Set ${key} = ${value}`);
5262
5395
  }
5263
5396
  });
5264
5397
 
5265
5398
  // src/commands/fetch/index.ts
5266
- import { defineCommand as defineCommand39 } from "citty";
5399
+ import { defineCommand as defineCommand40 } from "citty";
5267
5400
  async function doRequest(method, url, body, contentType, raw, showHeaders) {
5268
5401
  const token = getAuthToken();
5269
5402
  if (!token) {
@@ -5299,13 +5432,13 @@ async function doRequest(method, url, body, contentType, raw, showHeaders) {
5299
5432
  throw new CliError(`HTTP ${response.status} ${response.statusText}`);
5300
5433
  }
5301
5434
  }
5302
- var fetchCommand = defineCommand39({
5435
+ var fetchCommand = defineCommand40({
5303
5436
  meta: {
5304
5437
  name: "fetch",
5305
5438
  description: "Make authenticated HTTP requests"
5306
5439
  },
5307
5440
  subCommands: {
5308
- get: defineCommand39({
5441
+ get: defineCommand40({
5309
5442
  meta: {
5310
5443
  name: "get",
5311
5444
  description: "GET request with auth token"
@@ -5331,7 +5464,7 @@ var fetchCommand = defineCommand39({
5331
5464
  await doRequest("GET", String(args.url), void 0, "application/json", Boolean(args.raw), Boolean(args.headers));
5332
5465
  }
5333
5466
  }),
5334
- post: defineCommand39({
5467
+ post: defineCommand40({
5335
5468
  meta: {
5336
5469
  name: "post",
5337
5470
  description: "POST request with auth token"
@@ -5370,8 +5503,8 @@ var fetchCommand = defineCommand39({
5370
5503
  });
5371
5504
 
5372
5505
  // src/commands/mcp/index.ts
5373
- import { defineCommand as defineCommand40 } from "citty";
5374
- var mcpCommand = defineCommand40({
5506
+ import { defineCommand as defineCommand41 } from "citty";
5507
+ var mcpCommand = defineCommand41({
5375
5508
  meta: {
5376
5509
  name: "mcp",
5377
5510
  description: "Start MCP server for AI agents"
@@ -5394,7 +5527,7 @@ var mcpCommand = defineCommand40({
5394
5527
  if (transport !== "stdio" && transport !== "sse") {
5395
5528
  throw new Error('Transport must be "stdio" or "sse"');
5396
5529
  }
5397
- const { startMcpServer } = await import("./server-A56K7VDD.js");
5530
+ const { startMcpServer } = await import("./server-AK2JBMJD.js");
5398
5531
  await startMcpServer(transport, port);
5399
5532
  }
5400
5533
  });
@@ -5402,10 +5535,10 @@ var mcpCommand = defineCommand40({
5402
5535
  // src/commands/init/index.ts
5403
5536
  import { existsSync as existsSync12, copyFileSync, writeFileSync as writeFileSync8 } from "fs";
5404
5537
  import { randomBytes } from "crypto";
5405
- import { execFileSync as execFileSync12 } from "child_process";
5538
+ import { execFileSync as execFileSync13 } from "child_process";
5406
5539
  import { join as join11 } from "path";
5407
- import { defineCommand as defineCommand41 } from "citty";
5408
- import consola33 from "consola";
5540
+ import { defineCommand as defineCommand42 } from "citty";
5541
+ import consola34 from "consola";
5409
5542
  var DEFAULT_IDP_URL = "https://id.openape.at";
5410
5543
  async function downloadTemplate(repo, targetDir) {
5411
5544
  const { downloadTemplate: gigetDownload } = await import("giget");
@@ -5414,28 +5547,28 @@ async function downloadTemplate(repo, targetDir) {
5414
5547
  function installDeps(dir) {
5415
5548
  const hasLockFile = (name) => existsSync12(join11(dir, name));
5416
5549
  if (hasLockFile("pnpm-lock.yaml")) {
5417
- execFileSync12("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
5550
+ execFileSync13("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
5418
5551
  } else if (hasLockFile("bun.lockb")) {
5419
- execFileSync12("bun", ["install"], { cwd: dir, stdio: "inherit" });
5552
+ execFileSync13("bun", ["install"], { cwd: dir, stdio: "inherit" });
5420
5553
  } else {
5421
- execFileSync12("npm", ["install"], { cwd: dir, stdio: "inherit" });
5554
+ execFileSync13("npm", ["install"], { cwd: dir, stdio: "inherit" });
5422
5555
  }
5423
5556
  }
5424
5557
  async function promptChoice(message, choices) {
5425
- const result = await consola33.prompt(message, { type: "select", options: choices });
5558
+ const result = await consola34.prompt(message, { type: "select", options: choices });
5426
5559
  if (typeof result === "symbol") {
5427
5560
  throw new CliExit(0);
5428
5561
  }
5429
5562
  return result;
5430
5563
  }
5431
5564
  async function promptText(message, defaultValue) {
5432
- const result = await consola33.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
5565
+ const result = await consola34.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
5433
5566
  if (typeof result === "symbol") {
5434
5567
  throw new CliExit(0);
5435
5568
  }
5436
5569
  return result || defaultValue || "";
5437
5570
  }
5438
- var initCommand = defineCommand41({
5571
+ var initCommand = defineCommand42({
5439
5572
  meta: {
5440
5573
  name: "init",
5441
5574
  description: "Scaffold a new OpenApe project"
@@ -5480,20 +5613,20 @@ async function initSP(targetDir) {
5480
5613
  if (existsSync12(join11(dir, "package.json"))) {
5481
5614
  throw new CliError(`Directory "${dir}" already contains a project.`);
5482
5615
  }
5483
- consola33.start("Scaffolding SP starter...");
5616
+ consola34.start("Scaffolding SP starter...");
5484
5617
  await downloadTemplate("openape-ai/openape-sp-starter", dir);
5485
- consola33.success("Scaffolded from openape-sp-starter");
5486
- consola33.start("Installing dependencies...");
5618
+ consola34.success("Scaffolded from openape-sp-starter");
5619
+ consola34.start("Installing dependencies...");
5487
5620
  installDeps(dir);
5488
- consola33.success("Dependencies installed");
5621
+ consola34.success("Dependencies installed");
5489
5622
  const envExample = join11(dir, ".env.example");
5490
5623
  const envFile = join11(dir, ".env");
5491
5624
  if (existsSync12(envExample) && !existsSync12(envFile)) {
5492
5625
  copyFileSync(envExample, envFile);
5493
- consola33.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
5626
+ consola34.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
5494
5627
  }
5495
5628
  console.log("");
5496
- consola33.box([
5629
+ consola34.box([
5497
5630
  `cd ${dir}`,
5498
5631
  "npm run dev",
5499
5632
  "",
@@ -5512,15 +5645,15 @@ async function initIdP(targetDir) {
5512
5645
  "s3 (S3-compatible)"
5513
5646
  ]);
5514
5647
  const adminEmail = await promptText("Admin email");
5515
- consola33.start("Scaffolding IdP starter...");
5648
+ consola34.start("Scaffolding IdP starter...");
5516
5649
  await downloadTemplate("openape-ai/openape-idp-starter", dir);
5517
- consola33.success("Scaffolded from openape-idp-starter");
5518
- consola33.start("Installing dependencies...");
5650
+ consola34.success("Scaffolded from openape-idp-starter");
5651
+ consola34.start("Installing dependencies...");
5519
5652
  installDeps(dir);
5520
- consola33.success("Dependencies installed");
5653
+ consola34.success("Dependencies installed");
5521
5654
  const sessionSecret = randomBytes(32).toString("hex");
5522
5655
  const managementToken = randomBytes(32).toString("hex");
5523
- consola33.success("Secrets generated");
5656
+ consola34.success("Secrets generated");
5524
5657
  const isLocalhost = domain === "localhost";
5525
5658
  const origin = isLocalhost ? "http://localhost:3000" : `https://${domain}`;
5526
5659
  const envContent = [
@@ -5536,9 +5669,9 @@ async function initIdP(targetDir) {
5536
5669
  ].join("\n");
5537
5670
  writeFileSync8(join11(dir, ".env"), `${envContent}
5538
5671
  `, { mode: 384 });
5539
- consola33.success(".env created");
5672
+ consola34.success(".env created");
5540
5673
  console.log("");
5541
- consola33.box([
5674
+ consola34.box([
5542
5675
  `cd ${dir}`,
5543
5676
  "npm run dev",
5544
5677
  "",
@@ -5558,8 +5691,8 @@ import { Buffer as Buffer5 } from "buffer";
5558
5691
  import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
5559
5692
  import { execFile as execFile2 } from "child_process";
5560
5693
  import { sign as sign2 } from "crypto";
5561
- import { defineCommand as defineCommand42 } from "citty";
5562
- import consola34 from "consola";
5694
+ import { defineCommand as defineCommand43 } from "citty";
5695
+ import consola35 from "consola";
5563
5696
  var DEFAULT_IDP_URL2 = "https://id.openape.at";
5564
5697
  var DEFAULT_KEY_PATH = "~/.ssh/id_ed25519";
5565
5698
  var POLL_INTERVAL = 3e3;
@@ -5602,7 +5735,7 @@ async function pollForEnrollment(idp, agentEmail, keyPath) {
5602
5735
  }
5603
5736
  throw new Error("Enrollment timed out. Please check the browser and try again.");
5604
5737
  }
5605
- var enrollCommand = defineCommand42({
5738
+ var enrollCommand = defineCommand43({
5606
5739
  meta: {
5607
5740
  name: "enroll",
5608
5741
  description: "Enroll an agent with an Identity Provider"
@@ -5622,18 +5755,18 @@ var enrollCommand = defineCommand42({
5622
5755
  }
5623
5756
  },
5624
5757
  async run({ args }) {
5625
- const idp = args.idp || await consola34.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r) => {
5758
+ const idp = args.idp || await consola35.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r) => {
5626
5759
  if (typeof r === "symbol") throw new CliExit(0);
5627
5760
  return r;
5628
5761
  }) || DEFAULT_IDP_URL2;
5629
- const agentName = args.name || await consola34.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r) => {
5762
+ const agentName = args.name || await consola35.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r) => {
5630
5763
  if (typeof r === "symbol") throw new CliExit(0);
5631
5764
  return r;
5632
5765
  });
5633
5766
  if (!agentName) {
5634
5767
  throw new CliError("Agent name is required.");
5635
5768
  }
5636
- const keyPath = args.key || await consola34.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => {
5769
+ const keyPath = args.key || await consola35.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => {
5637
5770
  if (typeof r === "symbol") throw new CliExit(0);
5638
5771
  return r;
5639
5772
  }) || DEFAULT_KEY_PATH;
@@ -5641,19 +5774,19 @@ var enrollCommand = defineCommand42({
5641
5774
  let publicKey;
5642
5775
  if (existsSync13(resolvedKey)) {
5643
5776
  publicKey = readPublicKey(resolvedKey);
5644
- consola34.success(`Using existing key ${keyPath}`);
5777
+ consola35.success(`Using existing key ${keyPath}`);
5645
5778
  } else {
5646
- consola34.start(`Generating Ed25519 key pair at ${keyPath}...`);
5779
+ consola35.start(`Generating Ed25519 key pair at ${keyPath}...`);
5647
5780
  publicKey = generateAndSaveKey(keyPath);
5648
- consola34.success(`Key pair generated at ${keyPath}`);
5781
+ consola35.success(`Key pair generated at ${keyPath}`);
5649
5782
  }
5650
5783
  const encodedKey = encodeURIComponent(publicKey);
5651
5784
  const enrollUrl = `${idp}/enroll?name=${encodeURIComponent(agentName)}&key=${encodedKey}`;
5652
- consola34.info("Opening browser for enrollment...");
5653
- consola34.info(`\u2192 ${idp}/enroll`);
5785
+ consola35.info("Opening browser for enrollment...");
5786
+ consola35.info(`\u2192 ${idp}/enroll`);
5654
5787
  openBrowser2(enrollUrl);
5655
5788
  console.log("");
5656
- const agentEmail = await consola34.prompt(
5789
+ const agentEmail = await consola35.prompt(
5657
5790
  "Agent email (shown in browser after enrollment)",
5658
5791
  { type: "text", placeholder: `agent+${agentName}@...` }
5659
5792
  ).then((r) => {
@@ -5663,7 +5796,7 @@ var enrollCommand = defineCommand42({
5663
5796
  if (!agentEmail) {
5664
5797
  throw new CliError("Agent email is required to verify enrollment.");
5665
5798
  }
5666
- consola34.start("Verifying enrollment...");
5799
+ consola35.start("Verifying enrollment...");
5667
5800
  const { token, expiresIn } = await pollForEnrollment(idp, agentEmail, keyPath);
5668
5801
  saveAuth({
5669
5802
  idp,
@@ -5675,18 +5808,18 @@ var enrollCommand = defineCommand42({
5675
5808
  config.defaults = { ...config.defaults, idp };
5676
5809
  config.agent = { key: keyPath, email: agentEmail };
5677
5810
  saveConfig(config);
5678
- consola34.success(`Agent enrolled as ${agentEmail}`);
5679
- consola34.success("Config saved to ~/.config/apes/");
5811
+ consola35.success(`Agent enrolled as ${agentEmail}`);
5812
+ consola35.success("Config saved to ~/.config/apes/");
5680
5813
  console.log("");
5681
- consola34.info("Verify with: apes whoami");
5814
+ consola35.info("Verify with: apes whoami");
5682
5815
  }
5683
5816
  });
5684
5817
 
5685
5818
  // src/commands/register-user.ts
5686
5819
  import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
5687
- import { defineCommand as defineCommand43 } from "citty";
5688
- import consola35 from "consola";
5689
- var registerUserCommand = defineCommand43({
5820
+ import { defineCommand as defineCommand44 } from "citty";
5821
+ import consola36 from "consola";
5822
+ var registerUserCommand = defineCommand44({
5690
5823
  meta: {
5691
5824
  name: "register-user",
5692
5825
  description: "Register a sub-user with SSH key"
@@ -5741,18 +5874,18 @@ var registerUserCommand = defineCommand43({
5741
5874
  ...userType ? { type: userType } : {}
5742
5875
  }
5743
5876
  });
5744
- consola35.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
5877
+ consola36.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
5745
5878
  }
5746
5879
  });
5747
5880
 
5748
5881
  // src/commands/utils/index.ts
5749
- import { defineCommand as defineCommand45 } from "citty";
5882
+ import { defineCommand as defineCommand46 } from "citty";
5750
5883
 
5751
5884
  // src/commands/utils/dig.ts
5752
- import { defineCommand as defineCommand44 } from "citty";
5753
- import consola36 from "consola";
5885
+ import { defineCommand as defineCommand45 } from "citty";
5886
+ import consola37 from "consola";
5754
5887
  import { resolveDDISA as resolveDDISA2 } from "@openape/core";
5755
- var digCommand = defineCommand44({
5888
+ var digCommand = defineCommand45({
5756
5889
  meta: {
5757
5890
  name: "dig",
5758
5891
  description: "Resolve DDISA IdP for a domain or email (admin/diag tool)"
@@ -5825,12 +5958,12 @@ var digCommand = defineCommand44({
5825
5958
  console.log(` domain: ${domain}`);
5826
5959
  console.log("");
5827
5960
  if (!result.ddisa.found) {
5828
- consola36.warn(`No DDISA record at _ddisa.${domain}`);
5961
+ consola37.warn(`No DDISA record at _ddisa.${domain}`);
5829
5962
  if (result.hint) console.log(`
5830
5963
  ${result.hint}`);
5831
5964
  throw new CliError(`No DDISA record found for ${domain}`);
5832
5965
  }
5833
- consola36.success(`_ddisa.${domain} \u2192 ${result.ddisa.idp}`);
5966
+ consola37.success(`_ddisa.${domain} \u2192 ${result.ddisa.idp}`);
5834
5967
  console.log(` Version: ${result.ddisa.version || "ddisa1"}`);
5835
5968
  console.log(` IdP URL: ${result.ddisa.idp}`);
5836
5969
  if (result.ddisa.mode) console.log(` Mode: ${result.ddisa.mode}`);
@@ -5840,13 +5973,13 @@ ${result.hint}`);
5840
5973
  return;
5841
5974
  }
5842
5975
  if (result.idpDiscovery.ok) {
5843
- consola36.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`);
5976
+ consola37.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`);
5844
5977
  if (result.idpDiscovery.issuer) console.log(` Issuer: ${result.idpDiscovery.issuer}`);
5845
5978
  if (result.idpDiscovery.ddisaVersion) console.log(` DDISA: v${result.idpDiscovery.ddisaVersion}`);
5846
5979
  if (result.idpDiscovery.authMethods?.length) console.log(` Auth: ${result.idpDiscovery.authMethods.join(", ")}`);
5847
5980
  if (result.idpDiscovery.grantTypes?.length) console.log(` Grants: ${result.idpDiscovery.grantTypes.join(", ")}`);
5848
5981
  } else {
5849
- consola36.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ""}`);
5982
+ consola37.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ""}`);
5850
5983
  if (result.hint) console.log(`
5851
5984
  ${result.hint}`);
5852
5985
  throw new CliError(`IdP at ${result.ddisa.idp} not reachable`);
@@ -5855,7 +5988,7 @@ ${result.hint}`);
5855
5988
  });
5856
5989
 
5857
5990
  // src/commands/utils/index.ts
5858
- var utilsCommand = defineCommand45({
5991
+ var utilsCommand = defineCommand46({
5859
5992
  meta: {
5860
5993
  name: "utils",
5861
5994
  description: "Admin/diagnostic utilities (dig, \u2026)"
@@ -5866,12 +5999,12 @@ var utilsCommand = defineCommand45({
5866
5999
  });
5867
6000
 
5868
6001
  // src/commands/sessions/index.ts
5869
- import { defineCommand as defineCommand48 } from "citty";
6002
+ import { defineCommand as defineCommand49 } from "citty";
5870
6003
 
5871
6004
  // src/commands/sessions/list.ts
5872
- import { defineCommand as defineCommand46 } from "citty";
5873
- import consola37 from "consola";
5874
- var sessionsListCommand = defineCommand46({
6005
+ import { defineCommand as defineCommand47 } from "citty";
6006
+ import consola38 from "consola";
6007
+ var sessionsListCommand = defineCommand47({
5875
6008
  meta: {
5876
6009
  name: "list",
5877
6010
  description: "List your active refresh-token families (one per logged-in device)."
@@ -5889,7 +6022,7 @@ var sessionsListCommand = defineCommand46({
5889
6022
  return;
5890
6023
  }
5891
6024
  if (result.data.length === 0) {
5892
- consola37.info("No active sessions.");
6025
+ consola38.info("No active sessions.");
5893
6026
  return;
5894
6027
  }
5895
6028
  for (const f of result.data) {
@@ -5901,9 +6034,9 @@ var sessionsListCommand = defineCommand46({
5901
6034
  });
5902
6035
 
5903
6036
  // src/commands/sessions/remove.ts
5904
- import { defineCommand as defineCommand47 } from "citty";
5905
- import consola38 from "consola";
5906
- var sessionsRemoveCommand = defineCommand47({
6037
+ import { defineCommand as defineCommand48 } from "citty";
6038
+ import consola39 from "consola";
6039
+ var sessionsRemoveCommand = defineCommand48({
5907
6040
  meta: {
5908
6041
  name: "remove",
5909
6042
  description: "Revoke one of your active refresh-token families by id."
@@ -5919,12 +6052,12 @@ var sessionsRemoveCommand = defineCommand47({
5919
6052
  const id = String(args.familyId).trim();
5920
6053
  if (!id) throw new CliError("familyId required");
5921
6054
  await apiFetch(`/api/me/sessions/${encodeURIComponent(id)}`, { method: "DELETE" });
5922
- consola38.success(`Session ${id} revoked. The device using it will need to \`apes login\` again on its next refresh.`);
6055
+ consola39.success(`Session ${id} revoked. The device using it will need to \`apes login\` again on its next refresh.`);
5923
6056
  }
5924
6057
  });
5925
6058
 
5926
6059
  // src/commands/sessions/index.ts
5927
- var sessionsCommand = defineCommand48({
6060
+ var sessionsCommand = defineCommand49({
5928
6061
  meta: {
5929
6062
  name: "sessions",
5930
6063
  description: "Manage your active refresh-token sessions across devices"
@@ -5936,10 +6069,10 @@ var sessionsCommand = defineCommand48({
5936
6069
  });
5937
6070
 
5938
6071
  // src/commands/dns-check.ts
5939
- import { defineCommand as defineCommand49 } from "citty";
5940
- import consola39 from "consola";
6072
+ import { defineCommand as defineCommand50 } from "citty";
6073
+ import consola40 from "consola";
5941
6074
  import { resolveDDISA as resolveDDISA3 } from "@openape/core";
5942
- var dnsCheckCommand = defineCommand49({
6075
+ var dnsCheckCommand = defineCommand50({
5943
6076
  meta: {
5944
6077
  name: "dns-check",
5945
6078
  description: "Validate DDISA DNS TXT records for a domain"
@@ -5953,7 +6086,7 @@ var dnsCheckCommand = defineCommand49({
5953
6086
  },
5954
6087
  async run({ args }) {
5955
6088
  const domain = args.domain;
5956
- consola39.start(`Checking _ddisa.${domain}...`);
6089
+ consola40.start(`Checking _ddisa.${domain}...`);
5957
6090
  try {
5958
6091
  const result = await resolveDDISA3(domain);
5959
6092
  if (!result) {
@@ -5962,7 +6095,7 @@ var dnsCheckCommand = defineCommand49({
5962
6095
  console.log(` _ddisa.${domain} TXT "v=ddisa1 idp=https://id.${domain}"`);
5963
6096
  throw new CliError(`No DDISA record found for ${domain}`);
5964
6097
  }
5965
- consola39.success(`_ddisa.${domain} \u2192 ${result.idp}`);
6098
+ consola40.success(`_ddisa.${domain} \u2192 ${result.idp}`);
5966
6099
  console.log("");
5967
6100
  console.log(` Version: ${result.version || "ddisa1"}`);
5968
6101
  console.log(` IdP URL: ${result.idp}`);
@@ -5971,14 +6104,14 @@ var dnsCheckCommand = defineCommand49({
5971
6104
  if (result.priority !== void 0)
5972
6105
  console.log(` Priority: ${result.priority}`);
5973
6106
  console.log("");
5974
- consola39.start(`Verifying IdP at ${result.idp}...`);
6107
+ consola40.start(`Verifying IdP at ${result.idp}...`);
5975
6108
  const discoResp = await fetch(`${result.idp}/.well-known/openid-configuration`);
5976
6109
  if (!discoResp.ok) {
5977
- consola39.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
6110
+ consola40.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
5978
6111
  return;
5979
6112
  }
5980
6113
  const disco = await discoResp.json();
5981
- consola39.success(`IdP is reachable`);
6114
+ consola40.success(`IdP is reachable`);
5982
6115
  console.log(` Issuer: ${disco.issuer}`);
5983
6116
  console.log(` DDISA: v${disco.ddisa_version || "?"}`);
5984
6117
  if (disco.ddisa_auth_methods_supported) {
@@ -5996,7 +6129,7 @@ var dnsCheckCommand = defineCommand49({
5996
6129
  // src/commands/health.ts
5997
6130
  import { exec } from "child_process";
5998
6131
  import { promisify } from "util";
5999
- import { defineCommand as defineCommand50 } from "citty";
6132
+ import { defineCommand as defineCommand51 } from "citty";
6000
6133
  var execAsync = promisify(exec);
6001
6134
  async function resolveApeShellPath() {
6002
6135
  try {
@@ -6032,7 +6165,7 @@ async function bestEffortGrantCount(idp) {
6032
6165
  }
6033
6166
  }
6034
6167
  async function runHealth(args) {
6035
- const version = true ? "1.4.0" : "0.0.0";
6168
+ const version = true ? "1.5.0" : "0.0.0";
6036
6169
  const auth = loadAuth();
6037
6170
  if (!auth) {
6038
6171
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -6095,7 +6228,7 @@ async function runHealth(args) {
6095
6228
  throw new CliError(`IdP ${auth.idp} unreachable: ${idpProbe.error}`, 1);
6096
6229
  }
6097
6230
  }
6098
- var healthCommand = defineCommand50({
6231
+ var healthCommand = defineCommand51({
6099
6232
  meta: {
6100
6233
  name: "health",
6101
6234
  description: "Report CLI diagnostic state (auth, IdP, grants, binaries)"
@@ -6113,8 +6246,8 @@ var healthCommand = defineCommand50({
6113
6246
  });
6114
6247
 
6115
6248
  // src/commands/workflows.ts
6116
- import { defineCommand as defineCommand51 } from "citty";
6117
- import consola40 from "consola";
6249
+ import { defineCommand as defineCommand52 } from "citty";
6250
+ import consola41 from "consola";
6118
6251
 
6119
6252
  // src/guides/index.ts
6120
6253
  var guides = [
@@ -6164,7 +6297,7 @@ var guides = [
6164
6297
  ];
6165
6298
 
6166
6299
  // src/commands/workflows.ts
6167
- var workflowsCommand = defineCommand51({
6300
+ var workflowsCommand = defineCommand52({
6168
6301
  meta: {
6169
6302
  name: "workflows",
6170
6303
  description: "Discover workflow guides"
@@ -6185,7 +6318,7 @@ var workflowsCommand = defineCommand51({
6185
6318
  if (args.id) {
6186
6319
  const guide = guides.find((g) => g.id === String(args.id));
6187
6320
  if (!guide) {
6188
- consola40.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
6321
+ consola41.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
6189
6322
  throw new CliError(`Guide not found: ${args.id}`);
6190
6323
  }
6191
6324
  if (args.json) {
@@ -6228,7 +6361,7 @@ var workflowsCommand = defineCommand51({
6228
6361
  import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "fs";
6229
6362
  import { homedir as homedir12 } from "os";
6230
6363
  import { join as join12 } from "path";
6231
- import consola41 from "consola";
6364
+ import consola42 from "consola";
6232
6365
  var PACKAGE_NAME = "@openape/apes";
6233
6366
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
6234
6367
  var CACHE_FILE = join12(homedir12(), ".config", "apes", ".version-check.json");
@@ -6273,7 +6406,7 @@ async function fetchLatestVersion() {
6273
6406
  }
6274
6407
  function warnIfBehind(currentVersion, latest) {
6275
6408
  if (compareSemver(currentVersion, latest) < 0) {
6276
- consola41.warn(
6409
+ consola42.warn(
6277
6410
  `apes ${currentVersion} is behind latest @openape/apes@${latest}. Run \`npm i -g @openape/apes@latest\` to update. (Suppress with APES_NO_UPDATE_CHECK=1.)`
6278
6411
  );
6279
6412
  }
@@ -6305,10 +6438,10 @@ if (shellRewrite) {
6305
6438
  if (shellRewrite.action === "rewrite") {
6306
6439
  process.argv = shellRewrite.argv;
6307
6440
  } else if (shellRewrite.action === "version") {
6308
- console.log(`ape-shell ${"1.4.0"} (OpenApe DDISA shell wrapper)`);
6441
+ console.log(`ape-shell ${"1.5.0"} (OpenApe DDISA shell wrapper)`);
6309
6442
  process.exit(0);
6310
6443
  } else if (shellRewrite.action === "help") {
6311
- console.log(`ape-shell ${"1.4.0"} \u2014 OpenApe DDISA shell wrapper`);
6444
+ console.log(`ape-shell ${"1.5.0"} \u2014 OpenApe DDISA shell wrapper`);
6312
6445
  console.log("");
6313
6446
  console.log("Usage:");
6314
6447
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -6332,7 +6465,7 @@ if (shellRewrite) {
6332
6465
  }
6333
6466
  }
6334
6467
  var debug = process.argv.includes("--debug");
6335
- var grantsCommand = defineCommand52({
6468
+ var grantsCommand = defineCommand53({
6336
6469
  meta: {
6337
6470
  name: "grants",
6338
6471
  description: "Grant management"
@@ -6353,7 +6486,7 @@ var grantsCommand = defineCommand52({
6353
6486
  "delegation-revoke": delegationRevokeCommand
6354
6487
  }
6355
6488
  });
6356
- var configCommand = defineCommand52({
6489
+ var configCommand = defineCommand53({
6357
6490
  meta: {
6358
6491
  name: "config",
6359
6492
  description: "Configuration management"
@@ -6363,10 +6496,10 @@ var configCommand = defineCommand52({
6363
6496
  set: configSetCommand
6364
6497
  }
6365
6498
  });
6366
- var main = defineCommand52({
6499
+ var main = defineCommand53({
6367
6500
  meta: {
6368
6501
  name: "apes",
6369
- version: "1.4.0",
6502
+ version: "1.5.0",
6370
6503
  description: "Unified CLI for OpenApe"
6371
6504
  },
6372
6505
  subCommands: {
@@ -6422,20 +6555,20 @@ async function maybeRefreshAuth() {
6422
6555
  }
6423
6556
  }
6424
6557
  await maybeRefreshAuth();
6425
- await maybeWarnStaleVersion("1.4.0").catch(() => {
6558
+ await maybeWarnStaleVersion("1.5.0").catch(() => {
6426
6559
  });
6427
6560
  runMain(main).catch((err) => {
6428
6561
  if (err instanceof CliExit) {
6429
6562
  process.exit(err.exitCode);
6430
6563
  }
6431
6564
  if (err instanceof CliError) {
6432
- consola42.error(err.message);
6565
+ consola43.error(err.message);
6433
6566
  process.exit(err.exitCode);
6434
6567
  }
6435
6568
  if (debug) {
6436
- consola42.error(err);
6569
+ consola43.error(err);
6437
6570
  } else {
6438
- consola42.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
6571
+ consola43.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
6439
6572
  }
6440
6573
  process.exit(1);
6441
6574
  });