@openape/apes 0.16.0 → 0.18.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
@@ -12,11 +12,9 @@ import {
12
12
  checkSudoRejection,
13
13
  isApesSelfDispatch,
14
14
  notifyGrantPending
15
- } from "./chunk-OFIVF6NH.js";
15
+ } from "./chunk-EDYICCBC.js";
16
16
  import {
17
- ApiError,
18
17
  GENERIC_OPERATION_ID,
19
- apiFetch,
20
18
  buildGenericResolved,
21
19
  buildStructuredCliGrantRequest,
22
20
  createShapesGrant,
@@ -28,10 +26,6 @@ import {
28
26
  findAdapter,
29
27
  findConflictingAdapters,
30
28
  findExistingGrant,
31
- getAgentAuthenticateEndpoint,
32
- getAgentChallengeEndpoint,
33
- getDelegationsEndpoint,
34
- getGrantsEndpoint,
35
29
  getInstalledDigest,
36
30
  installAdapter,
37
31
  isInstalled,
@@ -46,7 +40,15 @@ import {
46
40
  searchAdapters,
47
41
  verifyAndExecute,
48
42
  waitForGrantStatus
49
- } from "./chunk-O7GSG3OE.js";
43
+ } from "./chunk-IT6T6AKX.js";
44
+ import {
45
+ ApiError,
46
+ apiFetch,
47
+ getAgentAuthenticateEndpoint,
48
+ getAgentChallengeEndpoint,
49
+ getDelegationsEndpoint,
50
+ getGrantsEndpoint
51
+ } from "./chunk-7NUT2PFT.js";
50
52
  import {
51
53
  AUTH_FILE,
52
54
  CONFIG_DIR,
@@ -58,7 +60,7 @@ import {
58
60
  loadConfig,
59
61
  saveAuth,
60
62
  saveConfig
61
- } from "./chunk-6GPSKAMU.js";
63
+ } from "./chunk-IDPV5SNB.js";
62
64
 
63
65
  // src/cli.ts
64
66
  import consola33 from "consola";
@@ -147,29 +149,44 @@ async function resolveLoginInputs(flags) {
147
149
  );
148
150
  }
149
151
  let idp;
152
+ let idpSource;
150
153
  if (flags.idp) {
151
154
  idp = flags.idp;
155
+ idpSource = "flag";
152
156
  } else if (process.env.APES_IDP) {
153
157
  idp = process.env.APES_IDP;
158
+ idpSource = "env";
154
159
  } else if (process.env.GRAPES_IDP) {
155
160
  idp = process.env.GRAPES_IDP;
161
+ idpSource = "env";
156
162
  consola.warn(
157
163
  "GRAPES_IDP is deprecated, use APES_IDP instead. GRAPES_IDP support will be removed in a future release."
158
164
  );
159
165
  } else if (config.defaults?.idp) {
160
166
  idp = config.defaults.idp;
161
- } else if (email && email.includes("@")) {
167
+ idpSource = "config";
168
+ }
169
+ let ddisaIdp;
170
+ let ddisaDomain;
171
+ if (email && email.includes("@")) {
162
172
  const domain = email.split("@")[1];
173
+ ddisaDomain = domain;
163
174
  try {
164
175
  const record = await resolveDDISA(domain);
165
- if (record?.idp) {
166
- idp = record.idp;
167
- consola.info(`Discovered IdP via DDISA (_ddisa.${domain}): ${idp}`);
168
- }
176
+ if (record?.idp) ddisaIdp = record.idp;
169
177
  } catch {
170
178
  }
171
179
  }
172
- return { keyPath, email, idp };
180
+ if (!idp && ddisaIdp && ddisaDomain) {
181
+ idp = ddisaIdp;
182
+ idpSource = "ddisa";
183
+ consola.info(`Discovered IdP via DDISA (_ddisa.${ddisaDomain}): ${idp}`);
184
+ }
185
+ let ddisaMismatch;
186
+ if (idp && ddisaIdp && ddisaDomain && idp !== ddisaIdp && idpSource !== "ddisa") {
187
+ ddisaMismatch = { dnsIdp: ddisaIdp, chosenIdp: idp, domain: ddisaDomain };
188
+ }
189
+ return { keyPath, email, idp, ddisaMismatch };
173
190
  }
174
191
 
175
192
  // src/commands/auth/login.ts
@@ -181,6 +198,11 @@ var loginCommand = defineCommand({
181
198
  description: "Authenticate with an OpenApe IdP"
182
199
  },
183
200
  args: {
201
+ user: {
202
+ type: "positional",
203
+ required: false,
204
+ description: "Agent email (e.g. patrick@hofmann.eco). Extracted from <key>.pub comment if omitted."
205
+ },
184
206
  idp: {
185
207
  type: "string",
186
208
  description: "IdP URL (e.g. https://id.openape.at). Auto-discovered via DDISA DNS if omitted."
@@ -191,24 +213,52 @@ var loginCommand = defineCommand({
191
213
  },
192
214
  email: {
193
215
  type: "string",
194
- description: "Agent email. Extracted from <key>.pub comment if omitted."
216
+ description: "Same as the positional email \u2014 flag form for backwards compatibility."
195
217
  },
196
218
  browser: {
197
219
  type: "boolean",
198
220
  description: "Force browser (PKCE) login even if an SSH key exists"
221
+ },
222
+ force: {
223
+ type: "boolean",
224
+ description: "Override DDISA mismatch warnings (use with care)"
199
225
  }
200
226
  },
201
227
  async run({ args }) {
228
+ const emailArg = typeof args.user === "string" && args.user.includes("@") ? args.user : typeof args.email === "string" ? args.email : void 0;
202
229
  const resolved = await resolveLoginInputs({
203
230
  key: args.key,
204
231
  idp: args.idp,
205
- email: args.email,
232
+ email: emailArg,
206
233
  browser: args.browser
207
234
  });
235
+ if (resolved.ddisaMismatch && !args.force) {
236
+ const { dnsIdp, chosenIdp, domain } = resolved.ddisaMismatch;
237
+ throw new CliError(
238
+ `IdP mismatch for ${domain}.
239
+
240
+ Authoritative DDISA: ${dnsIdp}
241
+ You selected: ${chosenIdp}
242
+
243
+ Logging in against a different IdP than DDISA points to means SPs that
244
+ trust the DDISA-resolved IdP (e.g. preview.openape.ai) will reject the
245
+ resulting token with "IdP mismatch".
246
+
247
+ Fix one of:
248
+ \u2022 Drop --idp/APES_IDP/config.defaults.idp \u2014 DDISA will auto-pick ${dnsIdp}
249
+ \u2022 Update _ddisa.${domain} if ${chosenIdp} is genuinely the correct IdP
250
+ \u2022 Re-run with --force to authenticate anyway (NOT recommended)`
251
+ );
252
+ }
253
+ if (resolved.ddisaMismatch && args.force) {
254
+ consola2.warn(
255
+ `Bypassing DDISA mismatch \u2014 ${resolved.ddisaMismatch.domain} resolves to ${resolved.ddisaMismatch.dnsIdp}, but you forced ${resolved.ddisaMismatch.chosenIdp}.`
256
+ );
257
+ }
208
258
  if (resolved.keyPath) {
209
259
  if (!resolved.email) {
210
260
  throw new CliError(
211
- `Agent email required for key-based login. Add an email comment to ${resolved.keyPath}.pub (ssh-keygen -C <email>) or pass --email <agent-email>.`
261
+ `Agent email required for key-based login. Pass it as a positional (\`apes login <email>\`), set --email, or add an email comment to ${resolved.keyPath}.pub via ssh-keygen -C <email>.`
212
262
  );
213
263
  }
214
264
  if (!resolved.idp) {
@@ -414,7 +464,7 @@ var whoamiCommand = defineCommand3({
414
464
  console.log(`IdP: ${auth.idp}`);
415
465
  console.log(`Token: ${isExpired ? "\u26A0 EXPIRED" : "valid"} (until ${expiresAt})`);
416
466
  if (isExpired) {
417
- consola4.warn("Token is expired. Run `apes login` to re-authenticate.");
467
+ consola4.warn("Token is expired and could not be auto-refreshed. Run `apes login` to re-authenticate.");
418
468
  }
419
469
  }
420
470
  });
@@ -3651,7 +3701,7 @@ var mcpCommand = defineCommand32({
3651
3701
  if (transport !== "stdio" && transport !== "sse") {
3652
3702
  throw new Error('Transport must be "stdio" or "sse"');
3653
3703
  }
3654
- const { startMcpServer } = await import("./server-NZMLYPN4.js");
3704
+ const { startMcpServer } = await import("./server-RPC46G4J.js");
3655
3705
  await startMcpServer(transport, port);
3656
3706
  }
3657
3707
  });
@@ -4219,7 +4269,7 @@ async function bestEffortGrantCount(idp) {
4219
4269
  }
4220
4270
  }
4221
4271
  async function runHealth(args) {
4222
- const version = true ? "0.16.0" : "0.0.0";
4272
+ const version = true ? "0.18.0" : "0.0.0";
4223
4273
  const auth = loadAuth();
4224
4274
  if (!auth) {
4225
4275
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -4421,10 +4471,10 @@ if (shellRewrite) {
4421
4471
  if (shellRewrite.action === "rewrite") {
4422
4472
  process.argv = shellRewrite.argv;
4423
4473
  } else if (shellRewrite.action === "version") {
4424
- console.log(`ape-shell ${"0.16.0"} (OpenApe DDISA shell wrapper)`);
4474
+ console.log(`ape-shell ${"0.18.0"} (OpenApe DDISA shell wrapper)`);
4425
4475
  process.exit(0);
4426
4476
  } else if (shellRewrite.action === "help") {
4427
- console.log(`ape-shell ${"0.16.0"} \u2014 OpenApe DDISA shell wrapper`);
4477
+ console.log(`ape-shell ${"0.18.0"} \u2014 OpenApe DDISA shell wrapper`);
4428
4478
  console.log("");
4429
4479
  console.log("Usage:");
4430
4480
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -4439,7 +4489,7 @@ if (shellRewrite) {
4439
4489
  console.log(" --help, -h Show this help message");
4440
4490
  process.exit(0);
4441
4491
  } else if (shellRewrite.action === "interactive") {
4442
- const { runInteractiveShell } = await import("./orchestrator-PUAO57CY.js");
4492
+ const { runInteractiveShell } = await import("./orchestrator-FJVDWH45.js");
4443
4493
  await runInteractiveShell();
4444
4494
  process.exit(0);
4445
4495
  } else {
@@ -4482,7 +4532,7 @@ var configCommand = defineCommand41({
4482
4532
  var main = defineCommand41({
4483
4533
  meta: {
4484
4534
  name: "apes",
4485
- version: "0.16.0",
4535
+ version: "0.18.0",
4486
4536
  description: "Unified CLI for OpenApe"
4487
4537
  },
4488
4538
  subCommands: {
@@ -4508,6 +4558,34 @@ var main = defineCommand41({
4508
4558
  workflows: workflowsCommand
4509
4559
  }
4510
4560
  });
4561
+ var NO_REFRESH_COMMANDS = /* @__PURE__ */ new Set([
4562
+ "login",
4563
+ "logout",
4564
+ "init",
4565
+ "enroll",
4566
+ "register-user",
4567
+ "dns-check",
4568
+ "utils",
4569
+ "explain",
4570
+ "workflows",
4571
+ "--help",
4572
+ "-h",
4573
+ "help",
4574
+ "--version",
4575
+ "-v"
4576
+ ]);
4577
+ async function maybeRefreshAuth() {
4578
+ const sub = process.argv[2];
4579
+ if (!sub || NO_REFRESH_COMMANDS.has(sub)) return;
4580
+ const { loadAuth: loadAuth2 } = await import("./config-JH2IEPIR.js");
4581
+ if (!loadAuth2()) return;
4582
+ try {
4583
+ const { ensureFreshToken } = await import("./http-JZT4XV5I.js");
4584
+ await ensureFreshToken();
4585
+ } catch {
4586
+ }
4587
+ }
4588
+ await maybeRefreshAuth();
4511
4589
  runMain(main).catch((err) => {
4512
4590
  if (err instanceof CliExit) {
4513
4591
  process.exit(err.exitCode);