@openape/apes 0.16.0 → 0.17.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
@@ -147,29 +147,44 @@ async function resolveLoginInputs(flags) {
147
147
  );
148
148
  }
149
149
  let idp;
150
+ let idpSource;
150
151
  if (flags.idp) {
151
152
  idp = flags.idp;
153
+ idpSource = "flag";
152
154
  } else if (process.env.APES_IDP) {
153
155
  idp = process.env.APES_IDP;
156
+ idpSource = "env";
154
157
  } else if (process.env.GRAPES_IDP) {
155
158
  idp = process.env.GRAPES_IDP;
159
+ idpSource = "env";
156
160
  consola.warn(
157
161
  "GRAPES_IDP is deprecated, use APES_IDP instead. GRAPES_IDP support will be removed in a future release."
158
162
  );
159
163
  } else if (config.defaults?.idp) {
160
164
  idp = config.defaults.idp;
161
- } else if (email && email.includes("@")) {
165
+ idpSource = "config";
166
+ }
167
+ let ddisaIdp;
168
+ let ddisaDomain;
169
+ if (email && email.includes("@")) {
162
170
  const domain = email.split("@")[1];
171
+ ddisaDomain = domain;
163
172
  try {
164
173
  const record = await resolveDDISA(domain);
165
- if (record?.idp) {
166
- idp = record.idp;
167
- consola.info(`Discovered IdP via DDISA (_ddisa.${domain}): ${idp}`);
168
- }
174
+ if (record?.idp) ddisaIdp = record.idp;
169
175
  } catch {
170
176
  }
171
177
  }
172
- return { keyPath, email, idp };
178
+ if (!idp && ddisaIdp && ddisaDomain) {
179
+ idp = ddisaIdp;
180
+ idpSource = "ddisa";
181
+ consola.info(`Discovered IdP via DDISA (_ddisa.${ddisaDomain}): ${idp}`);
182
+ }
183
+ let ddisaMismatch;
184
+ if (idp && ddisaIdp && ddisaDomain && idp !== ddisaIdp && idpSource !== "ddisa") {
185
+ ddisaMismatch = { dnsIdp: ddisaIdp, chosenIdp: idp, domain: ddisaDomain };
186
+ }
187
+ return { keyPath, email, idp, ddisaMismatch };
173
188
  }
174
189
 
175
190
  // src/commands/auth/login.ts
@@ -181,6 +196,11 @@ var loginCommand = defineCommand({
181
196
  description: "Authenticate with an OpenApe IdP"
182
197
  },
183
198
  args: {
199
+ user: {
200
+ type: "positional",
201
+ required: false,
202
+ description: "Agent email (e.g. patrick@hofmann.eco). Extracted from <key>.pub comment if omitted."
203
+ },
184
204
  idp: {
185
205
  type: "string",
186
206
  description: "IdP URL (e.g. https://id.openape.at). Auto-discovered via DDISA DNS if omitted."
@@ -191,24 +211,52 @@ var loginCommand = defineCommand({
191
211
  },
192
212
  email: {
193
213
  type: "string",
194
- description: "Agent email. Extracted from <key>.pub comment if omitted."
214
+ description: "Same as the positional email \u2014 flag form for backwards compatibility."
195
215
  },
196
216
  browser: {
197
217
  type: "boolean",
198
218
  description: "Force browser (PKCE) login even if an SSH key exists"
219
+ },
220
+ force: {
221
+ type: "boolean",
222
+ description: "Override DDISA mismatch warnings (use with care)"
199
223
  }
200
224
  },
201
225
  async run({ args }) {
226
+ const emailArg = typeof args.user === "string" && args.user.includes("@") ? args.user : typeof args.email === "string" ? args.email : void 0;
202
227
  const resolved = await resolveLoginInputs({
203
228
  key: args.key,
204
229
  idp: args.idp,
205
- email: args.email,
230
+ email: emailArg,
206
231
  browser: args.browser
207
232
  });
233
+ if (resolved.ddisaMismatch && !args.force) {
234
+ const { dnsIdp, chosenIdp, domain } = resolved.ddisaMismatch;
235
+ throw new CliError(
236
+ `IdP mismatch for ${domain}.
237
+
238
+ Authoritative DDISA: ${dnsIdp}
239
+ You selected: ${chosenIdp}
240
+
241
+ Logging in against a different IdP than DDISA points to means SPs that
242
+ trust the DDISA-resolved IdP (e.g. preview.openape.ai) will reject the
243
+ resulting token with "IdP mismatch".
244
+
245
+ Fix one of:
246
+ \u2022 Drop --idp/APES_IDP/config.defaults.idp \u2014 DDISA will auto-pick ${dnsIdp}
247
+ \u2022 Update _ddisa.${domain} if ${chosenIdp} is genuinely the correct IdP
248
+ \u2022 Re-run with --force to authenticate anyway (NOT recommended)`
249
+ );
250
+ }
251
+ if (resolved.ddisaMismatch && args.force) {
252
+ consola2.warn(
253
+ `Bypassing DDISA mismatch \u2014 ${resolved.ddisaMismatch.domain} resolves to ${resolved.ddisaMismatch.dnsIdp}, but you forced ${resolved.ddisaMismatch.chosenIdp}.`
254
+ );
255
+ }
208
256
  if (resolved.keyPath) {
209
257
  if (!resolved.email) {
210
258
  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>.`
259
+ `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
260
  );
213
261
  }
214
262
  if (!resolved.idp) {
@@ -3651,7 +3699,7 @@ var mcpCommand = defineCommand32({
3651
3699
  if (transport !== "stdio" && transport !== "sse") {
3652
3700
  throw new Error('Transport must be "stdio" or "sse"');
3653
3701
  }
3654
- const { startMcpServer } = await import("./server-NZMLYPN4.js");
3702
+ const { startMcpServer } = await import("./server-YGRMW3OW.js");
3655
3703
  await startMcpServer(transport, port);
3656
3704
  }
3657
3705
  });
@@ -4219,7 +4267,7 @@ async function bestEffortGrantCount(idp) {
4219
4267
  }
4220
4268
  }
4221
4269
  async function runHealth(args) {
4222
- const version = true ? "0.16.0" : "0.0.0";
4270
+ const version = true ? "0.17.0" : "0.0.0";
4223
4271
  const auth = loadAuth();
4224
4272
  if (!auth) {
4225
4273
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -4421,10 +4469,10 @@ if (shellRewrite) {
4421
4469
  if (shellRewrite.action === "rewrite") {
4422
4470
  process.argv = shellRewrite.argv;
4423
4471
  } else if (shellRewrite.action === "version") {
4424
- console.log(`ape-shell ${"0.16.0"} (OpenApe DDISA shell wrapper)`);
4472
+ console.log(`ape-shell ${"0.17.0"} (OpenApe DDISA shell wrapper)`);
4425
4473
  process.exit(0);
4426
4474
  } else if (shellRewrite.action === "help") {
4427
- console.log(`ape-shell ${"0.16.0"} \u2014 OpenApe DDISA shell wrapper`);
4475
+ console.log(`ape-shell ${"0.17.0"} \u2014 OpenApe DDISA shell wrapper`);
4428
4476
  console.log("");
4429
4477
  console.log("Usage:");
4430
4478
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -4482,7 +4530,7 @@ var configCommand = defineCommand41({
4482
4530
  var main = defineCommand41({
4483
4531
  meta: {
4484
4532
  name: "apes",
4485
- version: "0.16.0",
4533
+ version: "0.17.0",
4486
4534
  description: "Unified CLI for OpenApe"
4487
4535
  },
4488
4536
  subCommands: {