@openape/apes 0.21.1 → 0.22.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-IDPV5SNB.js";
64
64
 
65
65
  // src/cli.ts
66
- import consola35 from "consola";
66
+ import consola36 from "consola";
67
67
 
68
68
  // src/ape-shell.ts
69
69
  import path from "path";
@@ -379,7 +379,7 @@ async function loginWithPKCE(idp) {
379
379
  consola2.success(`Logged in as ${payload.email || payload.sub}`);
380
380
  }
381
381
  async function loginWithKey(idp, keyPath, agentEmail) {
382
- const { readFileSync: readFileSync7 } = await import("fs");
382
+ const { readFileSync: readFileSync8 } = await import("fs");
383
383
  const { sign: sign3 } = await import("crypto");
384
384
  const { loadEd25519PrivateKey: loadEd25519PrivateKey2 } = await import("./ssh-key-YBNNG5K5.js");
385
385
  const challengeUrl = await getAgentChallengeEndpoint(idp);
@@ -392,7 +392,7 @@ async function loginWithKey(idp, keyPath, agentEmail) {
392
392
  throw new CliError(`Challenge failed: ${await challengeResp.text()}`);
393
393
  }
394
394
  const { challenge } = await challengeResp.json();
395
- const keyContent = readFileSync7(keyPath, "utf-8");
395
+ const keyContent = readFileSync8(keyPath, "utf-8");
396
396
  const privateKey = loadEd25519PrivateKey2(keyContent);
397
397
  const signature = sign3(null, Buffer2.from(challenge), privateKey).toString("base64");
398
398
  const authenticateUrl = await getAgentAuthenticateEndpoint(idp);
@@ -3236,14 +3236,17 @@ async function runAudienceMode(audience, action, args) {
3236
3236
  throw new CliExit(getAsyncExitCode());
3237
3237
  }
3238
3238
  consola23.success(`Grant requested: ${grant.id}`);
3239
+ consola23.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
3239
3240
  consola23.info("Waiting for approval...");
3240
- const maxWait = 3e5;
3241
+ const maxWait = 15 * 60 * 1e3;
3241
3242
  const interval = 3e3;
3242
3243
  const start = Date.now();
3244
+ let approved = false;
3243
3245
  while (Date.now() - start < maxWait) {
3244
3246
  const status = await apiFetch(`${grantsUrl}/${grant.id}`);
3245
3247
  if (status.status === "approved") {
3246
3248
  consola23.success("Grant approved!");
3249
+ approved = true;
3247
3250
  break;
3248
3251
  }
3249
3252
  if (status.status === "denied" || status.status === "revoked") {
@@ -3251,6 +3254,12 @@ async function runAudienceMode(audience, action, args) {
3251
3254
  }
3252
3255
  await new Promise((r) => setTimeout(r, interval));
3253
3256
  }
3257
+ if (!approved) {
3258
+ const minutes = Math.round(maxWait / 6e4);
3259
+ throw new CliError(
3260
+ `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.`
3261
+ );
3262
+ }
3254
3263
  consola23.info("Fetching grant token...");
3255
3264
  const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, {
3256
3265
  method: "POST"
@@ -3761,7 +3770,7 @@ var mcpCommand = defineCommand32({
3761
3770
  if (transport !== "stdio" && transport !== "sse") {
3762
3771
  throw new Error('Transport must be "stdio" or "sse"');
3763
3772
  }
3764
- const { startMcpServer } = await import("./server-3KAKSSMI.js");
3773
+ const { startMcpServer } = await import("./server-GBFP2XSM.js");
3765
3774
  await startMcpServer(transport, port);
3766
3775
  }
3767
3776
  });
@@ -4399,7 +4408,7 @@ async function bestEffortGrantCount(idp) {
4399
4408
  }
4400
4409
  }
4401
4410
  async function runHealth(args) {
4402
- const version = true ? "0.21.1" : "0.0.0";
4411
+ const version = true ? "0.22.0" : "0.0.0";
4403
4412
  const auth = loadAuth();
4404
4413
  if (!auth) {
4405
4414
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -4591,6 +4600,77 @@ var workflowsCommand = defineCommand43({
4591
4600
  }
4592
4601
  });
4593
4602
 
4603
+ // src/version-check.ts
4604
+ import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4605
+ import { homedir as homedir5 } from "os";
4606
+ import { join as join6 } from "path";
4607
+ import consola35 from "consola";
4608
+ var PACKAGE_NAME = "@openape/apes";
4609
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
4610
+ var CACHE_FILE = join6(homedir5(), ".config", "apes", ".version-check.json");
4611
+ function readCache() {
4612
+ if (!existsSync9(CACHE_FILE)) return null;
4613
+ try {
4614
+ return JSON.parse(readFileSync7(CACHE_FILE, "utf-8"));
4615
+ } catch {
4616
+ return null;
4617
+ }
4618
+ }
4619
+ function writeCache(entry) {
4620
+ try {
4621
+ const dir = join6(homedir5(), ".config", "apes");
4622
+ if (!existsSync9(dir)) mkdirSync2(dir, { recursive: true, mode: 448 });
4623
+ writeFileSync6(CACHE_FILE, JSON.stringify(entry), { mode: 384 });
4624
+ } catch {
4625
+ }
4626
+ }
4627
+ function compareSemver(a, b) {
4628
+ const pa = a.split(".").map(Number);
4629
+ const pb = b.split(".").map(Number);
4630
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
4631
+ const x = pa[i] ?? 0;
4632
+ const y = pb[i] ?? 0;
4633
+ if (x !== y) return x - y;
4634
+ }
4635
+ return 0;
4636
+ }
4637
+ async function fetchLatestVersion() {
4638
+ try {
4639
+ const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`, {
4640
+ headers: { Accept: "application/json" },
4641
+ signal: AbortSignal.timeout(2e3)
4642
+ });
4643
+ if (!res.ok) return null;
4644
+ const body = await res.json();
4645
+ return typeof body.version === "string" ? body.version : null;
4646
+ } catch {
4647
+ return null;
4648
+ }
4649
+ }
4650
+ function warnIfBehind(currentVersion, latest) {
4651
+ if (compareSemver(currentVersion, latest) < 0) {
4652
+ consola35.warn(
4653
+ `apes ${currentVersion} is behind latest @openape/apes@${latest}. Run \`npm i -g @openape/apes@latest\` to update. (Suppress with APES_NO_UPDATE_CHECK=1.)`
4654
+ );
4655
+ }
4656
+ }
4657
+ async function maybeWarnStaleVersion(currentVersion) {
4658
+ if (process.env.APES_NO_UPDATE_CHECK) return;
4659
+ if (!currentVersion || currentVersion === "unknown") return;
4660
+ const cached = readCache();
4661
+ const now = Date.now();
4662
+ if (cached) {
4663
+ warnIfBehind(currentVersion, cached.latest);
4664
+ }
4665
+ if (!cached || now - cached.checkedAt >= CACHE_TTL_MS) {
4666
+ const latest = await fetchLatestVersion();
4667
+ if (latest) {
4668
+ writeCache({ latest, checkedAt: now });
4669
+ if (!cached) warnIfBehind(currentVersion, latest);
4670
+ }
4671
+ }
4672
+ }
4673
+
4594
4674
  // src/cli.ts
4595
4675
  process.stdout.on("error", (err) => {
4596
4676
  if (err.code === "EPIPE") process.exit(0);
@@ -4601,10 +4681,10 @@ if (shellRewrite) {
4601
4681
  if (shellRewrite.action === "rewrite") {
4602
4682
  process.argv = shellRewrite.argv;
4603
4683
  } else if (shellRewrite.action === "version") {
4604
- console.log(`ape-shell ${"0.21.1"} (OpenApe DDISA shell wrapper)`);
4684
+ console.log(`ape-shell ${"0.22.0"} (OpenApe DDISA shell wrapper)`);
4605
4685
  process.exit(0);
4606
4686
  } else if (shellRewrite.action === "help") {
4607
- console.log(`ape-shell ${"0.21.1"} \u2014 OpenApe DDISA shell wrapper`);
4687
+ console.log(`ape-shell ${"0.22.0"} \u2014 OpenApe DDISA shell wrapper`);
4608
4688
  console.log("");
4609
4689
  console.log("Usage:");
4610
4690
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -4662,7 +4742,7 @@ var configCommand = defineCommand44({
4662
4742
  var main = defineCommand44({
4663
4743
  meta: {
4664
4744
  name: "apes",
4665
- version: "0.21.1",
4745
+ version: "0.22.0",
4666
4746
  description: "Unified CLI for OpenApe"
4667
4747
  },
4668
4748
  subCommands: {
@@ -4717,18 +4797,20 @@ async function maybeRefreshAuth() {
4717
4797
  }
4718
4798
  }
4719
4799
  await maybeRefreshAuth();
4800
+ await maybeWarnStaleVersion("0.22.0").catch(() => {
4801
+ });
4720
4802
  runMain(main).catch((err) => {
4721
4803
  if (err instanceof CliExit) {
4722
4804
  process.exit(err.exitCode);
4723
4805
  }
4724
4806
  if (err instanceof CliError) {
4725
- consola35.error(err.message);
4807
+ consola36.error(err.message);
4726
4808
  process.exit(err.exitCode);
4727
4809
  }
4728
4810
  if (debug) {
4729
- consola35.error(err);
4811
+ consola36.error(err);
4730
4812
  } else {
4731
- consola35.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
4813
+ consola36.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
4732
4814
  }
4733
4815
  process.exit(1);
4734
4816
  });