@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
|
|
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:
|
|
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 =
|
|
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 =
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
4807
|
+
consola36.error(err.message);
|
|
4726
4808
|
process.exit(err.exitCode);
|
|
4727
4809
|
}
|
|
4728
4810
|
if (debug) {
|
|
4729
|
-
|
|
4811
|
+
consola36.error(err);
|
|
4730
4812
|
} else {
|
|
4731
|
-
|
|
4813
|
+
consola36.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
|
|
4732
4814
|
}
|
|
4733
4815
|
process.exit(1);
|
|
4734
4816
|
});
|