@openape/apes 0.10.0 → 0.11.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 +110 -48
- package/dist/cli.js.map +1 -1
- package/dist/{orchestrator-QL3AT67U.js → orchestrator-U5TZ2KXF.js} +9 -1
- package/dist/orchestrator-U5TZ2KXF.js.map +1 -0
- package/dist/{server-N3DPYYBL.js → server-YNJ5SURM.js} +2 -2
- package/package.json +3 -3
- package/dist/orchestrator-QL3AT67U.js.map +0 -1
- /package/dist/{server-N3DPYYBL.js.map → server-YNJ5SURM.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -136,6 +136,11 @@ async function resolveLoginInputs(flags) {
|
|
|
136
136
|
consola.info(`Using email from ${keyPath}.pub comment: ${email}`);
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
+
if (process.env.APES_IDP && process.env.GRAPES_IDP) {
|
|
140
|
+
consola.warn(
|
|
141
|
+
"Both APES_IDP and GRAPES_IDP are set \u2014 using APES_IDP. GRAPES_IDP is deprecated and will be removed in a future release."
|
|
142
|
+
);
|
|
143
|
+
}
|
|
139
144
|
let idp;
|
|
140
145
|
if (flags.idp) {
|
|
141
146
|
idp = flags.idp;
|
|
@@ -143,6 +148,9 @@ async function resolveLoginInputs(flags) {
|
|
|
143
148
|
idp = process.env.APES_IDP;
|
|
144
149
|
} else if (process.env.GRAPES_IDP) {
|
|
145
150
|
idp = process.env.GRAPES_IDP;
|
|
151
|
+
consola.warn(
|
|
152
|
+
"GRAPES_IDP is deprecated, use APES_IDP instead. GRAPES_IDP support will be removed in a future release."
|
|
153
|
+
);
|
|
146
154
|
} else if (config.defaults?.idp) {
|
|
147
155
|
idp = config.defaults.idp;
|
|
148
156
|
} else if (email && email.includes("@")) {
|
|
@@ -161,7 +169,7 @@ async function resolveLoginInputs(flags) {
|
|
|
161
169
|
|
|
162
170
|
// src/commands/auth/login.ts
|
|
163
171
|
var CALLBACK_PORT = 9876;
|
|
164
|
-
var CLIENT_ID = "
|
|
172
|
+
var CLIENT_ID = "apes-cli";
|
|
165
173
|
var loginCommand = defineCommand({
|
|
166
174
|
meta: {
|
|
167
175
|
name: "login",
|
|
@@ -1064,6 +1072,59 @@ var revokeCommand = defineCommand11({
|
|
|
1064
1072
|
import { execFileSync } from "child_process";
|
|
1065
1073
|
import { defineCommand as defineCommand12 } from "citty";
|
|
1066
1074
|
import consola12 from "consola";
|
|
1075
|
+
|
|
1076
|
+
// src/grant-poll.ts
|
|
1077
|
+
function getPollIntervalSeconds() {
|
|
1078
|
+
const envValue = process.env.APES_GRANT_POLL_INTERVAL;
|
|
1079
|
+
if (envValue) {
|
|
1080
|
+
const n = Number(envValue);
|
|
1081
|
+
if (Number.isFinite(n) && n > 0)
|
|
1082
|
+
return Math.floor(n);
|
|
1083
|
+
}
|
|
1084
|
+
const cfg = loadConfig();
|
|
1085
|
+
const cfgValue = cfg.defaults?.grant_poll_interval_seconds;
|
|
1086
|
+
if (cfgValue) {
|
|
1087
|
+
const n = Number(cfgValue);
|
|
1088
|
+
if (Number.isFinite(n) && n > 0)
|
|
1089
|
+
return Math.floor(n);
|
|
1090
|
+
}
|
|
1091
|
+
return 10;
|
|
1092
|
+
}
|
|
1093
|
+
function getPollMaxMinutes() {
|
|
1094
|
+
const envValue = process.env.APES_GRANT_POLL_MAX_MINUTES;
|
|
1095
|
+
if (envValue) {
|
|
1096
|
+
const n = Number(envValue);
|
|
1097
|
+
if (Number.isFinite(n) && n > 0)
|
|
1098
|
+
return Math.floor(n);
|
|
1099
|
+
}
|
|
1100
|
+
const cfg = loadConfig();
|
|
1101
|
+
const cfgValue = cfg.defaults?.grant_poll_max_minutes;
|
|
1102
|
+
if (cfgValue) {
|
|
1103
|
+
const n = Number(cfgValue);
|
|
1104
|
+
if (Number.isFinite(n) && n > 0)
|
|
1105
|
+
return Math.floor(n);
|
|
1106
|
+
}
|
|
1107
|
+
return 5;
|
|
1108
|
+
}
|
|
1109
|
+
async function pollGrantUntilResolved(idp, grantId) {
|
|
1110
|
+
const grantsEndpoint = await getGrantsEndpoint(idp);
|
|
1111
|
+
const intervalSec = getPollIntervalSeconds();
|
|
1112
|
+
const maxMinutes = getPollMaxMinutes();
|
|
1113
|
+
const maxMs = maxMinutes * 6e4;
|
|
1114
|
+
const intervalMs = intervalSec * 1e3;
|
|
1115
|
+
const start = Date.now();
|
|
1116
|
+
while (Date.now() - start < maxMs) {
|
|
1117
|
+
const grant = await apiFetch(`${grantsEndpoint}/${grantId}`);
|
|
1118
|
+
if (grant.status === "approved")
|
|
1119
|
+
return { kind: "approved" };
|
|
1120
|
+
if (grant.status === "denied" || grant.status === "revoked" || grant.status === "used")
|
|
1121
|
+
return { kind: "terminal", status: grant.status };
|
|
1122
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
1123
|
+
}
|
|
1124
|
+
return { kind: "timeout" };
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// src/commands/grants/run.ts
|
|
1067
1128
|
var runGrantCommand = defineCommand12({
|
|
1068
1129
|
meta: {
|
|
1069
1130
|
name: "run",
|
|
@@ -1079,6 +1140,11 @@ var runGrantCommand = defineCommand12({
|
|
|
1079
1140
|
type: "string",
|
|
1080
1141
|
description: "Path to escapes binary (audience=escapes only)",
|
|
1081
1142
|
default: "escapes"
|
|
1143
|
+
},
|
|
1144
|
+
wait: {
|
|
1145
|
+
type: "boolean",
|
|
1146
|
+
description: "If the grant is pending, block and poll until approved (or denied/revoked/used/timeout). Reuses APES_GRANT_POLL_INTERVAL / APES_GRANT_POLL_MAX_MINUTES knobs.",
|
|
1147
|
+
default: false
|
|
1082
1148
|
}
|
|
1083
1149
|
},
|
|
1084
1150
|
async run({ args }) {
|
|
@@ -1086,9 +1152,29 @@ var runGrantCommand = defineCommand12({
|
|
|
1086
1152
|
if (!idp)
|
|
1087
1153
|
throw new CliError("No IdP URL configured. Run `apes login` first or pass --idp.");
|
|
1088
1154
|
const grantsUrl = await getGrantsEndpoint(idp);
|
|
1089
|
-
|
|
1090
|
-
if (grant.status === "pending")
|
|
1091
|
-
|
|
1155
|
+
let grant = await apiFetch(`${grantsUrl}/${args.id}`);
|
|
1156
|
+
if (grant.status === "pending") {
|
|
1157
|
+
if (!args.wait) {
|
|
1158
|
+
throw new CliError(
|
|
1159
|
+
`Grant ${grant.id} is still pending. Approve at: ${idp}/grant-approval?grant_id=${grant.id}`
|
|
1160
|
+
);
|
|
1161
|
+
}
|
|
1162
|
+
const maxMinutes = getPollMaxMinutes();
|
|
1163
|
+
consola12.info(`Waiting for grant ${grant.id} approval (up to ${maxMinutes} minute${maxMinutes === 1 ? "" : "s"})...`);
|
|
1164
|
+
const outcome = await pollGrantUntilResolved(idp, grant.id);
|
|
1165
|
+
if (outcome.kind === "timeout") {
|
|
1166
|
+
throw new CliError(
|
|
1167
|
+
`Grant ${grant.id} approval timed out after ${maxMinutes} minute${maxMinutes === 1 ? "" : "s"}. Re-run after approval, or extend the timeout via APES_GRANT_POLL_MAX_MINUTES.`
|
|
1168
|
+
);
|
|
1169
|
+
}
|
|
1170
|
+
if (outcome.kind === "terminal") {
|
|
1171
|
+
throw new CliError(
|
|
1172
|
+
`Grant ${grant.id} resolved to ${outcome.status}. Request a new one.`
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
grant = await apiFetch(`${grantsUrl}/${args.id}`);
|
|
1176
|
+
consola12.info(`Grant ${grant.id} approved \u2014 continuing`);
|
|
1177
|
+
}
|
|
1092
1178
|
if (grant.status === "denied" || grant.status === "revoked")
|
|
1093
1179
|
throw new CliError(`Grant ${grant.id} is ${grant.status}. Request a new one.`);
|
|
1094
1180
|
if (grant.status === "used")
|
|
@@ -1940,38 +2026,6 @@ function getUserMode() {
|
|
|
1940
2026
|
return "human";
|
|
1941
2027
|
return "agent";
|
|
1942
2028
|
}
|
|
1943
|
-
function getPollIntervalSeconds() {
|
|
1944
|
-
const envValue = process.env.APES_GRANT_POLL_INTERVAL;
|
|
1945
|
-
if (envValue) {
|
|
1946
|
-
const n = Number(envValue);
|
|
1947
|
-
if (Number.isFinite(n) && n > 0)
|
|
1948
|
-
return Math.floor(n);
|
|
1949
|
-
}
|
|
1950
|
-
const cfg = loadConfig();
|
|
1951
|
-
const cfgValue = cfg.defaults?.grant_poll_interval_seconds;
|
|
1952
|
-
if (cfgValue) {
|
|
1953
|
-
const n = Number(cfgValue);
|
|
1954
|
-
if (Number.isFinite(n) && n > 0)
|
|
1955
|
-
return Math.floor(n);
|
|
1956
|
-
}
|
|
1957
|
-
return 10;
|
|
1958
|
-
}
|
|
1959
|
-
function getPollMaxMinutes() {
|
|
1960
|
-
const envValue = process.env.APES_GRANT_POLL_MAX_MINUTES;
|
|
1961
|
-
if (envValue) {
|
|
1962
|
-
const n = Number(envValue);
|
|
1963
|
-
if (Number.isFinite(n) && n > 0)
|
|
1964
|
-
return Math.floor(n);
|
|
1965
|
-
}
|
|
1966
|
-
const cfg = loadConfig();
|
|
1967
|
-
const cfgValue = cfg.defaults?.grant_poll_max_minutes;
|
|
1968
|
-
if (cfgValue) {
|
|
1969
|
-
const n = Number(cfgValue);
|
|
1970
|
-
if (Number.isFinite(n) && n > 0)
|
|
1971
|
-
return Math.floor(n);
|
|
1972
|
-
}
|
|
1973
|
-
return 5;
|
|
1974
|
-
}
|
|
1975
2029
|
function getAsyncExitCode() {
|
|
1976
2030
|
const envValue = process.env.APES_ASYNC_EXIT_CODE;
|
|
1977
2031
|
if (envValue !== void 0 && envValue !== "") {
|
|
@@ -2003,17 +2057,25 @@ function printPendingGrantInfo(grant, idp) {
|
|
|
2003
2057
|
console.log(" this grant without re-approval on the next invocation.");
|
|
2004
2058
|
return;
|
|
2005
2059
|
}
|
|
2006
|
-
const pollSec = getPollIntervalSeconds();
|
|
2007
2060
|
const maxMin = getPollMaxMinutes();
|
|
2008
2061
|
consola19.success(`Grant ${grant.id} created (pending approval)`);
|
|
2009
2062
|
console.log(` Approve: ${approveUrl}`);
|
|
2010
2063
|
console.log(` Status: ${statusCmd} [--json]`);
|
|
2011
|
-
console.log(` Execute: ${executeCmd}`);
|
|
2064
|
+
console.log(` Execute: ${executeCmd} --wait`);
|
|
2065
|
+
console.log("");
|
|
2066
|
+
console.log(" For agents:");
|
|
2067
|
+
console.log(` 1. Tell the user about the pending grant and the approve URL above.`);
|
|
2068
|
+
console.log(` 2. Run \`${executeCmd} --wait\`. This blocks up to ${maxMin} minutes`);
|
|
2069
|
+
console.log(` until the user approves (or denies/timeout) and then executes`);
|
|
2070
|
+
console.log(` the command in a single step. The CLI handles the polling loop`);
|
|
2071
|
+
console.log(` internally \u2014 you do not need to poll the status yourself.`);
|
|
2072
|
+
console.log(` 3. Exit 0 means approved + executed; stdout is the command output.`);
|
|
2073
|
+
console.log(` Exit 75 (pending) only appears if you accidentally call this`);
|
|
2074
|
+
console.log(` without --wait. Any other non-zero exit means denied, revoked,`);
|
|
2075
|
+
console.log(` used, or timeout \u2014 report the reason to the user.`);
|
|
2012
2076
|
console.log("");
|
|
2013
|
-
console.log(
|
|
2014
|
-
console.log(
|
|
2015
|
-
console.log(` On "denied" or "revoked", stop and report to the user.`);
|
|
2016
|
-
console.log(` On timeout, stop and notify the user that approval has not happened.`);
|
|
2077
|
+
console.log(' Note: exit code 75 (EX_TEMPFAIL) from this command means "pending,');
|
|
2078
|
+
console.log(' retry later" \u2014 do not abort your workflow, follow the steps above.');
|
|
2017
2079
|
console.log("");
|
|
2018
2080
|
console.log(' Tip: Approve as "timed" or "always" in the browser to let this');
|
|
2019
2081
|
console.log(" grant be reused on subsequent invocations without re-approval.");
|
|
@@ -2626,7 +2688,7 @@ var mcpCommand = defineCommand26({
|
|
|
2626
2688
|
if (transport !== "stdio" && transport !== "sse") {
|
|
2627
2689
|
throw new Error('Transport must be "stdio" or "sse"');
|
|
2628
2690
|
}
|
|
2629
|
-
const { startMcpServer } = await import("./server-
|
|
2691
|
+
const { startMcpServer } = await import("./server-YNJ5SURM.js");
|
|
2630
2692
|
await startMcpServer(transport, port);
|
|
2631
2693
|
}
|
|
2632
2694
|
});
|
|
@@ -3118,7 +3180,7 @@ async function bestEffortGrantCount(idp) {
|
|
|
3118
3180
|
}
|
|
3119
3181
|
}
|
|
3120
3182
|
async function runHealth(args) {
|
|
3121
|
-
const version = true ? "0.
|
|
3183
|
+
const version = true ? "0.11.0" : "0.0.0";
|
|
3122
3184
|
const auth = loadAuth();
|
|
3123
3185
|
if (!auth) {
|
|
3124
3186
|
throw new CliError("Not logged in. Run `apes login` first.", 1);
|
|
@@ -3320,10 +3382,10 @@ if (shellRewrite) {
|
|
|
3320
3382
|
if (shellRewrite.action === "rewrite") {
|
|
3321
3383
|
process.argv = shellRewrite.argv;
|
|
3322
3384
|
} else if (shellRewrite.action === "version") {
|
|
3323
|
-
console.log(`ape-shell ${"0.
|
|
3385
|
+
console.log(`ape-shell ${"0.11.0"} (OpenApe DDISA shell wrapper)`);
|
|
3324
3386
|
process.exit(0);
|
|
3325
3387
|
} else if (shellRewrite.action === "help") {
|
|
3326
|
-
console.log(`ape-shell ${"0.
|
|
3388
|
+
console.log(`ape-shell ${"0.11.0"} \u2014 OpenApe DDISA shell wrapper`);
|
|
3327
3389
|
console.log("");
|
|
3328
3390
|
console.log("Usage:");
|
|
3329
3391
|
console.log(" ape-shell Start interactive grant-mediated REPL");
|
|
@@ -3338,7 +3400,7 @@ if (shellRewrite) {
|
|
|
3338
3400
|
console.log(" --help, -h Show this help message");
|
|
3339
3401
|
process.exit(0);
|
|
3340
3402
|
} else if (shellRewrite.action === "interactive") {
|
|
3341
|
-
const { runInteractiveShell } = await import("./orchestrator-
|
|
3403
|
+
const { runInteractiveShell } = await import("./orchestrator-U5TZ2KXF.js");
|
|
3342
3404
|
await runInteractiveShell();
|
|
3343
3405
|
process.exit(0);
|
|
3344
3406
|
} else {
|
|
@@ -3381,7 +3443,7 @@ var configCommand = defineCommand33({
|
|
|
3381
3443
|
var main = defineCommand33({
|
|
3382
3444
|
meta: {
|
|
3383
3445
|
name: "apes",
|
|
3384
|
-
version: "0.
|
|
3446
|
+
version: "0.11.0",
|
|
3385
3447
|
description: "Unified CLI for OpenApe"
|
|
3386
3448
|
},
|
|
3387
3449
|
subCommands: {
|