@openape/apes 0.8.0 → 0.9.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/{chunk-HGCKOCJA.js → chunk-UQ673USC.js} +19 -1
- package/dist/chunk-UQ673USC.js.map +1 -0
- package/dist/cli.js +317 -208
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{orchestrator-FTQW3ZRS.js → orchestrator-GPNL543L.js} +2 -2
- package/dist/{server-DPNFUTHG.js → server-FFOPFICW.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-HGCKOCJA.js.map +0 -1
- /package/dist/{orchestrator-FTQW3ZRS.js.map → orchestrator-GPNL543L.js.map} +0 -0
- /package/dist/{server-DPNFUTHG.js.map → server-FFOPFICW.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -37,10 +37,11 @@ import {
|
|
|
37
37
|
removeAdapter,
|
|
38
38
|
resolveCapabilityRequest,
|
|
39
39
|
resolveCommand,
|
|
40
|
+
resolveFromGrant,
|
|
40
41
|
searchAdapters,
|
|
41
42
|
verifyAndExecute,
|
|
42
43
|
waitForGrantStatus
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-UQ673USC.js";
|
|
44
45
|
import {
|
|
45
46
|
AUTH_FILE,
|
|
46
47
|
CONFIG_DIR,
|
|
@@ -54,7 +55,7 @@ import {
|
|
|
54
55
|
} from "./chunk-AZVY3X7Q.js";
|
|
55
56
|
|
|
56
57
|
// src/cli.ts
|
|
57
|
-
import
|
|
58
|
+
import consola27 from "consola";
|
|
58
59
|
|
|
59
60
|
// src/ape-shell.ts
|
|
60
61
|
import path from "path";
|
|
@@ -84,7 +85,7 @@ function rewriteApeShellArgs(argv, argv0) {
|
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
// src/cli.ts
|
|
87
|
-
import { defineCommand as
|
|
88
|
+
import { defineCommand as defineCommand33, runMain } from "citty";
|
|
88
89
|
|
|
89
90
|
// src/commands/auth/login.ts
|
|
90
91
|
import { Buffer } from "buffer";
|
|
@@ -1041,9 +1042,83 @@ var revokeCommand = defineCommand11({
|
|
|
1041
1042
|
}
|
|
1042
1043
|
});
|
|
1043
1044
|
|
|
1044
|
-
// src/commands/grants/
|
|
1045
|
+
// src/commands/grants/run.ts
|
|
1046
|
+
import { execFileSync } from "child_process";
|
|
1045
1047
|
import { defineCommand as defineCommand12 } from "citty";
|
|
1046
|
-
|
|
1048
|
+
import consola12 from "consola";
|
|
1049
|
+
var runGrantCommand = defineCommand12({
|
|
1050
|
+
meta: {
|
|
1051
|
+
name: "run",
|
|
1052
|
+
description: "Execute a previously-approved grant by ID"
|
|
1053
|
+
},
|
|
1054
|
+
args: {
|
|
1055
|
+
id: {
|
|
1056
|
+
type: "positional",
|
|
1057
|
+
description: "Grant ID",
|
|
1058
|
+
required: true
|
|
1059
|
+
},
|
|
1060
|
+
"escapes-path": {
|
|
1061
|
+
type: "string",
|
|
1062
|
+
description: "Path to escapes binary (audience=escapes only)",
|
|
1063
|
+
default: "escapes"
|
|
1064
|
+
}
|
|
1065
|
+
},
|
|
1066
|
+
async run({ args }) {
|
|
1067
|
+
const idp = getIdpUrl();
|
|
1068
|
+
if (!idp)
|
|
1069
|
+
throw new CliError("No IdP URL configured. Run `apes login` first or pass --idp.");
|
|
1070
|
+
const grantsUrl = await getGrantsEndpoint(idp);
|
|
1071
|
+
const grant = await apiFetch(`${grantsUrl}/${args.id}`);
|
|
1072
|
+
if (grant.status === "pending")
|
|
1073
|
+
throw new CliError(`Grant ${grant.id} is still pending. Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
1074
|
+
if (grant.status === "denied" || grant.status === "revoked")
|
|
1075
|
+
throw new CliError(`Grant ${grant.id} is ${grant.status}. Request a new one.`);
|
|
1076
|
+
if (grant.status === "used")
|
|
1077
|
+
throw new CliError(`Grant ${grant.id} has already been used. Request a new one (single-use grants cannot be re-executed).`);
|
|
1078
|
+
if (grant.status !== "approved")
|
|
1079
|
+
throw new CliError(`Grant ${grant.id} has unexpected status: ${grant.status}`);
|
|
1080
|
+
const audience = grant.request?.audience;
|
|
1081
|
+
const authDetails = grant.request?.authorization_details ?? [];
|
|
1082
|
+
const hasOpenApeCliDetail = authDetails.some((d) => d?.type === "openape_cli");
|
|
1083
|
+
const isShapesGrant = hasOpenApeCliDetail || audience === "shapes";
|
|
1084
|
+
if (isShapesGrant) {
|
|
1085
|
+
let resolved;
|
|
1086
|
+
try {
|
|
1087
|
+
resolved = await resolveFromGrant(grant);
|
|
1088
|
+
} catch (err) {
|
|
1089
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1090
|
+
throw new CliError(`Cannot re-resolve grant: ${msg}`);
|
|
1091
|
+
}
|
|
1092
|
+
const token = await fetchGrantToken(idp, grant.id);
|
|
1093
|
+
await verifyAndExecute(token, resolved);
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
if (audience === "escapes") {
|
|
1097
|
+
const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, { method: "POST" });
|
|
1098
|
+
const command = grant.request?.command ?? [];
|
|
1099
|
+
if (command.length === 0)
|
|
1100
|
+
throw new CliError(`Grant ${grant.id} has no command to execute.`);
|
|
1101
|
+
consola12.info(`Executing via escapes: ${command.join(" ")}`);
|
|
1102
|
+
try {
|
|
1103
|
+
execFileSync(args["escapes-path"], ["--grant", authz_jwt, "--", ...command], { stdio: "inherit" });
|
|
1104
|
+
} catch (err) {
|
|
1105
|
+
const exitCode = err.status || 1;
|
|
1106
|
+
throw new CliExit(exitCode);
|
|
1107
|
+
}
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
if (audience === "ape-shell") {
|
|
1111
|
+
throw new CliError(
|
|
1112
|
+
`Grant ${grant.id} is an ape-shell session grant and cannot be re-executed via \`apes grants run\`. Re-run the original command \u2014 if the grant was approved as timed/always, the REPL will reuse it automatically.`
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
throw new CliError(`Grant ${grant.id} has unsupported audience "${audience}" \u2014 no execution path available.`);
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
|
|
1119
|
+
// src/commands/grants/token.ts
|
|
1120
|
+
import { defineCommand as defineCommand13 } from "citty";
|
|
1121
|
+
var tokenCommand = defineCommand13({
|
|
1047
1122
|
meta: {
|
|
1048
1123
|
name: "token",
|
|
1049
1124
|
description: "Get grant token JWT"
|
|
@@ -1069,9 +1144,9 @@ var tokenCommand = defineCommand12({
|
|
|
1069
1144
|
});
|
|
1070
1145
|
|
|
1071
1146
|
// src/commands/grants/delegate.ts
|
|
1072
|
-
import { defineCommand as
|
|
1073
|
-
import
|
|
1074
|
-
var delegateCommand =
|
|
1147
|
+
import { defineCommand as defineCommand14 } from "citty";
|
|
1148
|
+
import consola13 from "consola";
|
|
1149
|
+
var delegateCommand = defineCommand14({
|
|
1075
1150
|
meta: {
|
|
1076
1151
|
name: "delegate",
|
|
1077
1152
|
description: "Create a delegation"
|
|
@@ -1123,7 +1198,7 @@ var delegateCommand = defineCommand13({
|
|
|
1123
1198
|
method: "POST",
|
|
1124
1199
|
body
|
|
1125
1200
|
});
|
|
1126
|
-
|
|
1201
|
+
consola13.success(`Delegation created: ${result.id}`);
|
|
1127
1202
|
console.log(` Delegate: ${args.to}`);
|
|
1128
1203
|
console.log(` Audience: ${args.at}`);
|
|
1129
1204
|
if (args.scopes)
|
|
@@ -1135,9 +1210,9 @@ var delegateCommand = defineCommand13({
|
|
|
1135
1210
|
});
|
|
1136
1211
|
|
|
1137
1212
|
// src/commands/grants/delegations.ts
|
|
1138
|
-
import { defineCommand as
|
|
1139
|
-
import
|
|
1140
|
-
var delegationsCommand =
|
|
1213
|
+
import { defineCommand as defineCommand15 } from "citty";
|
|
1214
|
+
import consola14 from "consola";
|
|
1215
|
+
var delegationsCommand = defineCommand15({
|
|
1141
1216
|
meta: {
|
|
1142
1217
|
name: "delegations",
|
|
1143
1218
|
description: "List delegations"
|
|
@@ -1159,7 +1234,7 @@ var delegationsCommand = defineCommand14({
|
|
|
1159
1234
|
return;
|
|
1160
1235
|
}
|
|
1161
1236
|
if (delegations.length === 0) {
|
|
1162
|
-
|
|
1237
|
+
consola14.info("No delegations found.");
|
|
1163
1238
|
return;
|
|
1164
1239
|
}
|
|
1165
1240
|
for (const d of delegations) {
|
|
@@ -1171,9 +1246,9 @@ var delegationsCommand = defineCommand14({
|
|
|
1171
1246
|
});
|
|
1172
1247
|
|
|
1173
1248
|
// src/commands/grants/delegation-revoke.ts
|
|
1174
|
-
import { defineCommand as
|
|
1175
|
-
import
|
|
1176
|
-
var delegationRevokeCommand =
|
|
1249
|
+
import { defineCommand as defineCommand16 } from "citty";
|
|
1250
|
+
import consola15 from "consola";
|
|
1251
|
+
var delegationRevokeCommand = defineCommand16({
|
|
1177
1252
|
meta: {
|
|
1178
1253
|
name: "delegation-revoke",
|
|
1179
1254
|
description: "Revoke a delegation"
|
|
@@ -1196,16 +1271,16 @@ var delegationRevokeCommand = defineCommand15({
|
|
|
1196
1271
|
`${delegationsUrl}/${id}`,
|
|
1197
1272
|
{ method: "DELETE" }
|
|
1198
1273
|
);
|
|
1199
|
-
|
|
1274
|
+
consola15.success(`Delegation ${result.id} revoked.`);
|
|
1200
1275
|
}
|
|
1201
1276
|
});
|
|
1202
1277
|
|
|
1203
1278
|
// src/commands/admin/index.ts
|
|
1204
|
-
import { defineCommand as
|
|
1279
|
+
import { defineCommand as defineCommand19 } from "citty";
|
|
1205
1280
|
|
|
1206
1281
|
// src/commands/admin/users.ts
|
|
1207
|
-
import { defineCommand as
|
|
1208
|
-
import
|
|
1282
|
+
import { defineCommand as defineCommand17 } from "citty";
|
|
1283
|
+
import consola16 from "consola";
|
|
1209
1284
|
function getManagementToken() {
|
|
1210
1285
|
const token = process.env.APES_MANAGEMENT_TOKEN;
|
|
1211
1286
|
if (!token) {
|
|
@@ -1213,7 +1288,7 @@ function getManagementToken() {
|
|
|
1213
1288
|
}
|
|
1214
1289
|
return token;
|
|
1215
1290
|
}
|
|
1216
|
-
var usersListCommand =
|
|
1291
|
+
var usersListCommand = defineCommand17({
|
|
1217
1292
|
meta: {
|
|
1218
1293
|
name: "list",
|
|
1219
1294
|
description: "List all users"
|
|
@@ -1255,7 +1330,7 @@ var usersListCommand = defineCommand16({
|
|
|
1255
1330
|
return;
|
|
1256
1331
|
}
|
|
1257
1332
|
if (result.data.length === 0) {
|
|
1258
|
-
|
|
1333
|
+
consola16.info("No users found.");
|
|
1259
1334
|
return;
|
|
1260
1335
|
}
|
|
1261
1336
|
for (const u of result.data) {
|
|
@@ -1264,11 +1339,11 @@ var usersListCommand = defineCommand16({
|
|
|
1264
1339
|
console.log(`${u.email} ${u.name}${owner}${active}`);
|
|
1265
1340
|
}
|
|
1266
1341
|
if (result.pagination.has_more) {
|
|
1267
|
-
|
|
1342
|
+
consola16.info(`More results available. Use --cursor="${result.pagination.cursor}" to see next page.`);
|
|
1268
1343
|
}
|
|
1269
1344
|
}
|
|
1270
1345
|
});
|
|
1271
|
-
var usersCreateCommand =
|
|
1346
|
+
var usersCreateCommand = defineCommand17({
|
|
1272
1347
|
meta: {
|
|
1273
1348
|
name: "create",
|
|
1274
1349
|
description: "Create a user"
|
|
@@ -1299,10 +1374,10 @@ var usersCreateCommand = defineCommand16({
|
|
|
1299
1374
|
token
|
|
1300
1375
|
}
|
|
1301
1376
|
);
|
|
1302
|
-
|
|
1377
|
+
consola16.success(`User created: ${result.email} (${result.name})`);
|
|
1303
1378
|
}
|
|
1304
1379
|
});
|
|
1305
|
-
var usersDeleteCommand =
|
|
1380
|
+
var usersDeleteCommand = defineCommand17({
|
|
1306
1381
|
meta: {
|
|
1307
1382
|
name: "delete",
|
|
1308
1383
|
description: "Delete a user"
|
|
@@ -1325,7 +1400,7 @@ var usersDeleteCommand = defineCommand16({
|
|
|
1325
1400
|
method: "DELETE",
|
|
1326
1401
|
token
|
|
1327
1402
|
});
|
|
1328
|
-
|
|
1403
|
+
consola16.success(`User deleted: ${email}`);
|
|
1329
1404
|
}
|
|
1330
1405
|
});
|
|
1331
1406
|
|
|
@@ -1333,8 +1408,8 @@ var usersDeleteCommand = defineCommand16({
|
|
|
1333
1408
|
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
1334
1409
|
import { resolve } from "path";
|
|
1335
1410
|
import { homedir as homedir3 } from "os";
|
|
1336
|
-
import { defineCommand as
|
|
1337
|
-
import
|
|
1411
|
+
import { defineCommand as defineCommand18 } from "citty";
|
|
1412
|
+
import consola17 from "consola";
|
|
1338
1413
|
function getManagementToken2() {
|
|
1339
1414
|
const token = process.env.APES_MANAGEMENT_TOKEN;
|
|
1340
1415
|
if (!token) {
|
|
@@ -1342,7 +1417,7 @@ function getManagementToken2() {
|
|
|
1342
1417
|
}
|
|
1343
1418
|
return token;
|
|
1344
1419
|
}
|
|
1345
|
-
var sshKeysListCommand =
|
|
1420
|
+
var sshKeysListCommand = defineCommand18({
|
|
1346
1421
|
meta: {
|
|
1347
1422
|
name: "list",
|
|
1348
1423
|
description: "List SSH keys for a user"
|
|
@@ -1375,7 +1450,7 @@ var sshKeysListCommand = defineCommand17({
|
|
|
1375
1450
|
return;
|
|
1376
1451
|
}
|
|
1377
1452
|
if (keys.length === 0) {
|
|
1378
|
-
|
|
1453
|
+
consola17.info(`No SSH keys found for ${email}.`);
|
|
1379
1454
|
return;
|
|
1380
1455
|
}
|
|
1381
1456
|
for (const k of keys) {
|
|
@@ -1383,7 +1458,7 @@ var sshKeysListCommand = defineCommand17({
|
|
|
1383
1458
|
}
|
|
1384
1459
|
}
|
|
1385
1460
|
});
|
|
1386
|
-
var sshKeysAddCommand =
|
|
1461
|
+
var sshKeysAddCommand = defineCommand18({
|
|
1387
1462
|
meta: {
|
|
1388
1463
|
name: "add",
|
|
1389
1464
|
description: "Add an SSH key for a user"
|
|
@@ -1427,10 +1502,10 @@ var sshKeysAddCommand = defineCommand17({
|
|
|
1427
1502
|
token
|
|
1428
1503
|
}
|
|
1429
1504
|
);
|
|
1430
|
-
|
|
1505
|
+
consola17.success(`SSH key added: ${result.keyId} (${result.name})`);
|
|
1431
1506
|
}
|
|
1432
1507
|
});
|
|
1433
|
-
var sshKeysDeleteCommand =
|
|
1508
|
+
var sshKeysDeleteCommand = defineCommand18({
|
|
1434
1509
|
meta: {
|
|
1435
1510
|
name: "delete",
|
|
1436
1511
|
description: "Delete an SSH key"
|
|
@@ -1461,12 +1536,12 @@ var sshKeysDeleteCommand = defineCommand17({
|
|
|
1461
1536
|
token
|
|
1462
1537
|
}
|
|
1463
1538
|
);
|
|
1464
|
-
|
|
1539
|
+
consola17.success(`SSH key deleted: ${keyId}`);
|
|
1465
1540
|
}
|
|
1466
1541
|
});
|
|
1467
1542
|
|
|
1468
1543
|
// src/commands/admin/index.ts
|
|
1469
|
-
var usersCommand =
|
|
1544
|
+
var usersCommand = defineCommand19({
|
|
1470
1545
|
meta: {
|
|
1471
1546
|
name: "users",
|
|
1472
1547
|
description: "Manage users"
|
|
@@ -1477,7 +1552,7 @@ var usersCommand = defineCommand18({
|
|
|
1477
1552
|
delete: usersDeleteCommand
|
|
1478
1553
|
}
|
|
1479
1554
|
});
|
|
1480
|
-
var sshKeysCommand =
|
|
1555
|
+
var sshKeysCommand = defineCommand19({
|
|
1481
1556
|
meta: {
|
|
1482
1557
|
name: "ssh-keys",
|
|
1483
1558
|
description: "Manage SSH keys"
|
|
@@ -1488,7 +1563,7 @@ var sshKeysCommand = defineCommand18({
|
|
|
1488
1563
|
delete: sshKeysDeleteCommand
|
|
1489
1564
|
}
|
|
1490
1565
|
});
|
|
1491
|
-
var adminCommand =
|
|
1566
|
+
var adminCommand = defineCommand19({
|
|
1492
1567
|
meta: {
|
|
1493
1568
|
name: "admin",
|
|
1494
1569
|
description: "Admin commands (requires APES_MANAGEMENT_TOKEN)"
|
|
@@ -1500,15 +1575,15 @@ var adminCommand = defineCommand18({
|
|
|
1500
1575
|
});
|
|
1501
1576
|
|
|
1502
1577
|
// src/commands/adapter/index.ts
|
|
1503
|
-
import { defineCommand as
|
|
1504
|
-
import
|
|
1505
|
-
var adapterCommand =
|
|
1578
|
+
import { defineCommand as defineCommand20 } from "citty";
|
|
1579
|
+
import consola18 from "consola";
|
|
1580
|
+
var adapterCommand = defineCommand20({
|
|
1506
1581
|
meta: {
|
|
1507
1582
|
name: "adapter",
|
|
1508
1583
|
description: "Manage CLI adapters"
|
|
1509
1584
|
},
|
|
1510
1585
|
subCommands: {
|
|
1511
|
-
list:
|
|
1586
|
+
list: defineCommand20({
|
|
1512
1587
|
meta: {
|
|
1513
1588
|
name: "list",
|
|
1514
1589
|
description: "List available adapters"
|
|
@@ -1539,7 +1614,7 @@ var adapterCommand = defineCommand19({
|
|
|
1539
1614
|
`);
|
|
1540
1615
|
return;
|
|
1541
1616
|
}
|
|
1542
|
-
|
|
1617
|
+
consola18.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
|
|
1543
1618
|
for (const a of index2.adapters) {
|
|
1544
1619
|
const installed = isInstalled(a.id, false) ? " [installed]" : "";
|
|
1545
1620
|
console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}${installed}`);
|
|
@@ -1561,7 +1636,7 @@ var adapterCommand = defineCommand19({
|
|
|
1561
1636
|
return;
|
|
1562
1637
|
}
|
|
1563
1638
|
if (local.length === 0) {
|
|
1564
|
-
|
|
1639
|
+
consola18.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
|
|
1565
1640
|
return;
|
|
1566
1641
|
}
|
|
1567
1642
|
for (const a of local) {
|
|
@@ -1569,7 +1644,7 @@ var adapterCommand = defineCommand19({
|
|
|
1569
1644
|
}
|
|
1570
1645
|
}
|
|
1571
1646
|
}),
|
|
1572
|
-
install:
|
|
1647
|
+
install: defineCommand20({
|
|
1573
1648
|
meta: {
|
|
1574
1649
|
name: "install",
|
|
1575
1650
|
description: "Install an adapter from the registry"
|
|
@@ -1598,24 +1673,24 @@ var adapterCommand = defineCommand19({
|
|
|
1598
1673
|
for (const id of ids) {
|
|
1599
1674
|
const entry = findAdapter(index, id);
|
|
1600
1675
|
if (!entry) {
|
|
1601
|
-
|
|
1676
|
+
consola18.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
|
|
1602
1677
|
continue;
|
|
1603
1678
|
}
|
|
1604
1679
|
const conflicts = findConflictingAdapters(entry.executable, id);
|
|
1605
1680
|
if (conflicts.length > 0) {
|
|
1606
1681
|
for (const c of conflicts) {
|
|
1607
|
-
|
|
1608
|
-
|
|
1682
|
+
consola18.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`);
|
|
1683
|
+
consola18.warn(` Remove it with: apes adapter remove ${c.adapterId}`);
|
|
1609
1684
|
}
|
|
1610
1685
|
}
|
|
1611
1686
|
const result = await installAdapter(entry, { local });
|
|
1612
1687
|
const verb = result.updated ? "Updated" : "Installed";
|
|
1613
|
-
|
|
1614
|
-
|
|
1688
|
+
consola18.success(`${verb} ${result.id} \u2192 ${result.path}`);
|
|
1689
|
+
consola18.info(`Digest: ${result.digest}`);
|
|
1615
1690
|
}
|
|
1616
1691
|
}
|
|
1617
1692
|
}),
|
|
1618
|
-
remove:
|
|
1693
|
+
remove: defineCommand20({
|
|
1619
1694
|
meta: {
|
|
1620
1695
|
name: "remove",
|
|
1621
1696
|
description: "Remove an installed adapter"
|
|
@@ -1638,9 +1713,9 @@ var adapterCommand = defineCommand19({
|
|
|
1638
1713
|
let failed = false;
|
|
1639
1714
|
for (const id of ids) {
|
|
1640
1715
|
if (removeAdapter(id, local)) {
|
|
1641
|
-
|
|
1716
|
+
consola18.success(`Removed adapter: ${id}`);
|
|
1642
1717
|
} else {
|
|
1643
|
-
|
|
1718
|
+
consola18.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
|
|
1644
1719
|
failed = true;
|
|
1645
1720
|
}
|
|
1646
1721
|
}
|
|
@@ -1648,7 +1723,7 @@ var adapterCommand = defineCommand19({
|
|
|
1648
1723
|
throw new CliError("Some adapters could not be removed");
|
|
1649
1724
|
}
|
|
1650
1725
|
}),
|
|
1651
|
-
info:
|
|
1726
|
+
info: defineCommand20({
|
|
1652
1727
|
meta: {
|
|
1653
1728
|
name: "info",
|
|
1654
1729
|
description: "Show detailed adapter information"
|
|
@@ -1690,7 +1765,7 @@ var adapterCommand = defineCommand19({
|
|
|
1690
1765
|
}
|
|
1691
1766
|
}
|
|
1692
1767
|
}),
|
|
1693
|
-
search:
|
|
1768
|
+
search: defineCommand20({
|
|
1694
1769
|
meta: {
|
|
1695
1770
|
name: "search",
|
|
1696
1771
|
description: "Search adapters in the registry"
|
|
@@ -1722,7 +1797,7 @@ var adapterCommand = defineCommand19({
|
|
|
1722
1797
|
return;
|
|
1723
1798
|
}
|
|
1724
1799
|
if (results.length === 0) {
|
|
1725
|
-
|
|
1800
|
+
consola18.info(`No adapters matching "${query}"`);
|
|
1726
1801
|
return;
|
|
1727
1802
|
}
|
|
1728
1803
|
for (const a of results) {
|
|
@@ -1731,7 +1806,7 @@ var adapterCommand = defineCommand19({
|
|
|
1731
1806
|
}
|
|
1732
1807
|
}
|
|
1733
1808
|
}),
|
|
1734
|
-
update:
|
|
1809
|
+
update: defineCommand20({
|
|
1735
1810
|
meta: {
|
|
1736
1811
|
name: "update",
|
|
1737
1812
|
description: "Update installed adapters"
|
|
@@ -1757,33 +1832,33 @@ var adapterCommand = defineCommand19({
|
|
|
1757
1832
|
const targetId = args.id ? String(args.id) : void 0;
|
|
1758
1833
|
const targets = targetId ? [targetId] : index.adapters.map((a) => a.id).filter((id) => isInstalled(id, false));
|
|
1759
1834
|
if (targets.length === 0) {
|
|
1760
|
-
|
|
1835
|
+
consola18.info("No adapters installed to update.");
|
|
1761
1836
|
return;
|
|
1762
1837
|
}
|
|
1763
1838
|
for (const id of targets) {
|
|
1764
1839
|
const entry = findAdapter(index, id);
|
|
1765
1840
|
if (!entry) {
|
|
1766
|
-
|
|
1841
|
+
consola18.warn(`${id}: not found in registry, skipping`);
|
|
1767
1842
|
continue;
|
|
1768
1843
|
}
|
|
1769
1844
|
const localDigest = getInstalledDigest(id, false);
|
|
1770
1845
|
if (localDigest === entry.digest) {
|
|
1771
|
-
|
|
1846
|
+
consola18.info(`${id}: already up to date`);
|
|
1772
1847
|
continue;
|
|
1773
1848
|
}
|
|
1774
1849
|
if (localDigest && !args.yes) {
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1850
|
+
consola18.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
|
|
1851
|
+
consola18.info(` Old: ${localDigest}`);
|
|
1852
|
+
consola18.info(` New: ${entry.digest}`);
|
|
1853
|
+
consola18.info(" Use --yes to confirm");
|
|
1779
1854
|
continue;
|
|
1780
1855
|
}
|
|
1781
1856
|
const result = await installAdapter(entry);
|
|
1782
|
-
|
|
1857
|
+
consola18.success(`Updated ${result.id} \u2192 ${result.path}`);
|
|
1783
1858
|
}
|
|
1784
1859
|
}
|
|
1785
1860
|
}),
|
|
1786
|
-
verify:
|
|
1861
|
+
verify: defineCommand20({
|
|
1787
1862
|
meta: {
|
|
1788
1863
|
name: "verify",
|
|
1789
1864
|
description: "Verify installed adapter against registry digest"
|
|
@@ -1816,7 +1891,7 @@ var adapterCommand = defineCommand19({
|
|
|
1816
1891
|
if (!localDigest)
|
|
1817
1892
|
throw new Error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
|
|
1818
1893
|
if (localDigest === entry.digest) {
|
|
1819
|
-
|
|
1894
|
+
consola18.success(`${id}: digest matches registry`);
|
|
1820
1895
|
} else {
|
|
1821
1896
|
console.log(` Local: ${localDigest}`);
|
|
1822
1897
|
console.log(` Registry: ${entry.digest}`);
|
|
@@ -1828,12 +1903,24 @@ var adapterCommand = defineCommand19({
|
|
|
1828
1903
|
});
|
|
1829
1904
|
|
|
1830
1905
|
// src/commands/run.ts
|
|
1831
|
-
import { execFileSync } from "child_process";
|
|
1906
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
1832
1907
|
import { hostname as hostname3 } from "os";
|
|
1833
1908
|
import { basename } from "path";
|
|
1834
|
-
import { defineCommand as
|
|
1835
|
-
import
|
|
1836
|
-
|
|
1909
|
+
import { defineCommand as defineCommand21 } from "citty";
|
|
1910
|
+
import consola19 from "consola";
|
|
1911
|
+
function shouldWaitForGrant(args) {
|
|
1912
|
+
return args.wait === true || process.env.APE_WAIT === "1";
|
|
1913
|
+
}
|
|
1914
|
+
function printPendingGrantInfo(grant, idp) {
|
|
1915
|
+
consola19.success(`Grant ${grant.id} erstellt`);
|
|
1916
|
+
console.log(` Approve: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
1917
|
+
console.log(` Status: apes grants status ${grant.id}`);
|
|
1918
|
+
console.log(` Ausf\xFChren: apes grants run ${grant.id}`);
|
|
1919
|
+
console.log("");
|
|
1920
|
+
console.log(' Tipp: Im Browser "als timed/always approven" w\xE4hlen, um das');
|
|
1921
|
+
console.log(" Kommando ohne erneuten Approval wiederzuverwenden.");
|
|
1922
|
+
}
|
|
1923
|
+
var runCommand = defineCommand21({
|
|
1837
1924
|
meta: {
|
|
1838
1925
|
name: "run",
|
|
1839
1926
|
description: "Execute a grant-secured command"
|
|
@@ -1874,6 +1961,11 @@ var runCommand = defineCommand20({
|
|
|
1874
1961
|
description: "Shell mode: use session grant with audience ape-shell",
|
|
1875
1962
|
default: false
|
|
1876
1963
|
},
|
|
1964
|
+
"wait": {
|
|
1965
|
+
type: "boolean",
|
|
1966
|
+
description: "Block until grant is approved (default: async, print grant info and exit 0). Equivalent to APE_WAIT=1.",
|
|
1967
|
+
default: false
|
|
1968
|
+
},
|
|
1877
1969
|
"_": {
|
|
1878
1970
|
type: "positional",
|
|
1879
1971
|
description: "Command to execute (after --)",
|
|
@@ -1920,7 +2012,7 @@ async function runShellMode(command, args) {
|
|
|
1920
2012
|
}
|
|
1921
2013
|
} catch {
|
|
1922
2014
|
}
|
|
1923
|
-
|
|
2015
|
+
consola19.info(`Requesting ape-shell session grant on ${targetHost}`);
|
|
1924
2016
|
const grant = await apiFetch(grantsUrl, {
|
|
1925
2017
|
method: "POST",
|
|
1926
2018
|
body: {
|
|
@@ -1932,8 +2024,6 @@ async function runShellMode(command, args) {
|
|
|
1932
2024
|
reason: `Shell session: ${command.join(" ").slice(0, 100)}`
|
|
1933
2025
|
}
|
|
1934
2026
|
});
|
|
1935
|
-
consola18.info(`Grant requested: ${grant.id}`);
|
|
1936
|
-
consola18.info("Waiting for approval...");
|
|
1937
2027
|
notifyGrantPending({
|
|
1938
2028
|
grantId: grant.id,
|
|
1939
2029
|
approveUrl: `${idp}/grant-approval?grant_id=${grant.id}`,
|
|
@@ -1941,18 +2031,24 @@ async function runShellMode(command, args) {
|
|
|
1941
2031
|
audience: "ape-shell",
|
|
1942
2032
|
host: targetHost
|
|
1943
2033
|
});
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
const
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
2034
|
+
if (shouldWaitForGrant(args)) {
|
|
2035
|
+
consola19.info(`Grant requested: ${grant.id}`);
|
|
2036
|
+
consola19.info("Waiting for approval...");
|
|
2037
|
+
const maxWait = 3e5;
|
|
2038
|
+
const interval = 3e3;
|
|
2039
|
+
const start = Date.now();
|
|
2040
|
+
while (Date.now() - start < maxWait) {
|
|
2041
|
+
const status = await apiFetch(`${grantsUrl}/${grant.id}`);
|
|
2042
|
+
if (status.status === "approved")
|
|
2043
|
+
break;
|
|
2044
|
+
if (status.status === "denied" || status.status === "revoked")
|
|
2045
|
+
throw new CliError(`Grant ${status.status}.`);
|
|
2046
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
2047
|
+
}
|
|
2048
|
+
execShellCommand(command);
|
|
2049
|
+
return;
|
|
1954
2050
|
}
|
|
1955
|
-
|
|
2051
|
+
printPendingGrantInfo(grant, idp);
|
|
1956
2052
|
}
|
|
1957
2053
|
async function tryAdapterModeFromShell(command, idp, args) {
|
|
1958
2054
|
const cmdString = extractShellCommandString(command);
|
|
@@ -1967,32 +2063,30 @@ async function tryAdapterModeFromShell(command, idp, args) {
|
|
|
1967
2063
|
try {
|
|
1968
2064
|
resolved = await resolveCommand(loaded, [normalizedExecutable, ...parsed.argv]);
|
|
1969
2065
|
} catch (err) {
|
|
1970
|
-
|
|
2066
|
+
consola19.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
|
|
1971
2067
|
return false;
|
|
1972
2068
|
}
|
|
1973
2069
|
try {
|
|
1974
2070
|
const existingGrantId = await findExistingGrant(resolved, idp);
|
|
1975
2071
|
if (existingGrantId) {
|
|
1976
|
-
|
|
1977
|
-
const
|
|
1978
|
-
await verifyAndExecute(
|
|
2072
|
+
consola19.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
|
|
2073
|
+
const token = await fetchGrantToken(idp, existingGrantId);
|
|
2074
|
+
await verifyAndExecute(token, resolved);
|
|
1979
2075
|
return true;
|
|
1980
2076
|
}
|
|
1981
2077
|
} catch {
|
|
1982
2078
|
}
|
|
1983
2079
|
const approval = args.approval ?? "once";
|
|
1984
|
-
|
|
2080
|
+
consola19.info(`Requesting grant for: ${resolved.detail.display}`);
|
|
1985
2081
|
const grant = await createShapesGrant(resolved, {
|
|
1986
2082
|
idp,
|
|
1987
2083
|
approval,
|
|
1988
2084
|
reason: args.reason || `ape-shell: ${resolved.detail.display}`
|
|
1989
2085
|
});
|
|
1990
|
-
consola18.info(`Grant requested: ${grant.id}`);
|
|
1991
|
-
consola18.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
1992
2086
|
if (grant.similar_grants?.similar_grants?.length) {
|
|
1993
2087
|
const n = grant.similar_grants.similar_grants.length;
|
|
1994
|
-
|
|
1995
|
-
|
|
2088
|
+
consola19.info("");
|
|
2089
|
+
consola19.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
|
|
1996
2090
|
}
|
|
1997
2091
|
notifyGrantPending({
|
|
1998
2092
|
grantId: grant.id,
|
|
@@ -2001,18 +2095,24 @@ async function tryAdapterModeFromShell(command, idp, args) {
|
|
|
2001
2095
|
audience: resolved.adapter?.cli?.audience ?? "shapes",
|
|
2002
2096
|
host: args.host || hostname3()
|
|
2003
2097
|
});
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2098
|
+
if (shouldWaitForGrant(args)) {
|
|
2099
|
+
consola19.info(`Grant requested: ${grant.id}`);
|
|
2100
|
+
consola19.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
2101
|
+
const status = await waitForGrantStatus(idp, grant.id);
|
|
2102
|
+
if (status !== "approved")
|
|
2103
|
+
throw new CliError(`Grant ${status}`);
|
|
2104
|
+
const token = await fetchGrantToken(idp, grant.id);
|
|
2105
|
+
await verifyAndExecute(token, resolved);
|
|
2106
|
+
return true;
|
|
2107
|
+
}
|
|
2108
|
+
printPendingGrantInfo(grant, idp);
|
|
2009
2109
|
return true;
|
|
2010
2110
|
}
|
|
2011
2111
|
function execShellCommand(command) {
|
|
2012
2112
|
if (command.length === 0)
|
|
2013
2113
|
throw new CliError("No command to execute");
|
|
2014
2114
|
try {
|
|
2015
|
-
|
|
2115
|
+
execFileSync2(command[0], command.slice(1), { stdio: "inherit" });
|
|
2016
2116
|
} catch (err) {
|
|
2017
2117
|
const exitCode = err.status || 1;
|
|
2018
2118
|
throw new CliExit(exitCode);
|
|
@@ -2049,9 +2149,9 @@ async function runAdapterMode(command, rawArgs, args) {
|
|
|
2049
2149
|
try {
|
|
2050
2150
|
const existingGrantId = await findExistingGrant(resolved, idp);
|
|
2051
2151
|
if (existingGrantId) {
|
|
2052
|
-
|
|
2053
|
-
const
|
|
2054
|
-
await verifyAndExecute(
|
|
2152
|
+
consola19.info(`Reusing existing grant: ${existingGrantId}`);
|
|
2153
|
+
const token = await fetchGrantToken(idp, existingGrantId);
|
|
2154
|
+
await verifyAndExecute(token, resolved);
|
|
2055
2155
|
return;
|
|
2056
2156
|
}
|
|
2057
2157
|
} catch {
|
|
@@ -2061,23 +2161,27 @@ async function runAdapterMode(command, rawArgs, args) {
|
|
|
2061
2161
|
approval,
|
|
2062
2162
|
...args.reason ? { reason: args.reason } : {}
|
|
2063
2163
|
});
|
|
2064
|
-
consola18.info(`Grant requested: ${grant.id}`);
|
|
2065
|
-
consola18.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
2066
2164
|
if (grant.similar_grants?.similar_grants?.length) {
|
|
2067
2165
|
const n = grant.similar_grants.similar_grants.length;
|
|
2068
|
-
|
|
2069
|
-
|
|
2166
|
+
consola19.info("");
|
|
2167
|
+
consola19.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
|
|
2070
2168
|
if (grant.similar_grants.widened_details?.length) {
|
|
2071
2169
|
const wider = grant.similar_grants.widened_details.map((d) => d.permission).join(", ");
|
|
2072
|
-
|
|
2073
|
-
}
|
|
2074
|
-
|
|
2170
|
+
consola19.info(` Broader scope: ${wider}`);
|
|
2171
|
+
}
|
|
2172
|
+
consola19.info("");
|
|
2173
|
+
}
|
|
2174
|
+
if (shouldWaitForGrant(args)) {
|
|
2175
|
+
consola19.info(`Grant requested: ${grant.id}`);
|
|
2176
|
+
consola19.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
2177
|
+
const status = await waitForGrantStatus(idp, grant.id);
|
|
2178
|
+
if (status !== "approved")
|
|
2179
|
+
throw new Error(`Grant ${status}`);
|
|
2180
|
+
const token = await fetchGrantToken(idp, grant.id);
|
|
2181
|
+
await verifyAndExecute(token, resolved);
|
|
2182
|
+
return;
|
|
2075
2183
|
}
|
|
2076
|
-
|
|
2077
|
-
if (status !== "approved")
|
|
2078
|
-
throw new Error(`Grant ${status}`);
|
|
2079
|
-
const token = await fetchGrantToken(idp, grant.id);
|
|
2080
|
-
await verifyAndExecute(token, resolved);
|
|
2184
|
+
printPendingGrantInfo(grant, idp);
|
|
2081
2185
|
}
|
|
2082
2186
|
async function runAudienceMode(audience, action, args) {
|
|
2083
2187
|
const auth = loadAuth();
|
|
@@ -2088,7 +2192,7 @@ async function runAudienceMode(audience, action, args) {
|
|
|
2088
2192
|
const grantsUrl = await getGrantsEndpoint(idp);
|
|
2089
2193
|
const command = action.split(" ");
|
|
2090
2194
|
const targetHost = args.host || hostname3();
|
|
2091
|
-
|
|
2195
|
+
consola19.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
|
|
2092
2196
|
const grant = await apiFetch(grantsUrl, {
|
|
2093
2197
|
method: "POST",
|
|
2094
2198
|
body: {
|
|
@@ -2101,15 +2205,19 @@ async function runAudienceMode(audience, action, args) {
|
|
|
2101
2205
|
...args.as ? { run_as: args.as } : {}
|
|
2102
2206
|
}
|
|
2103
2207
|
});
|
|
2104
|
-
|
|
2105
|
-
|
|
2208
|
+
if (!shouldWaitForGrant(args)) {
|
|
2209
|
+
printPendingGrantInfo(grant, idp);
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
consola19.success(`Grant requested: ${grant.id}`);
|
|
2213
|
+
consola19.info("Waiting for approval...");
|
|
2106
2214
|
const maxWait = 3e5;
|
|
2107
2215
|
const interval = 3e3;
|
|
2108
2216
|
const start = Date.now();
|
|
2109
2217
|
while (Date.now() - start < maxWait) {
|
|
2110
2218
|
const status = await apiFetch(`${grantsUrl}/${grant.id}`);
|
|
2111
2219
|
if (status.status === "approved") {
|
|
2112
|
-
|
|
2220
|
+
consola19.success("Grant approved!");
|
|
2113
2221
|
break;
|
|
2114
2222
|
}
|
|
2115
2223
|
if (status.status === "denied" || status.status === "revoked") {
|
|
@@ -2117,14 +2225,14 @@ async function runAudienceMode(audience, action, args) {
|
|
|
2117
2225
|
}
|
|
2118
2226
|
await new Promise((r) => setTimeout(r, interval));
|
|
2119
2227
|
}
|
|
2120
|
-
|
|
2228
|
+
consola19.info("Fetching grant token...");
|
|
2121
2229
|
const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, {
|
|
2122
2230
|
method: "POST"
|
|
2123
2231
|
});
|
|
2124
2232
|
if (audience === "escapes") {
|
|
2125
|
-
|
|
2233
|
+
consola19.info(`Executing: ${command.join(" ")}`);
|
|
2126
2234
|
try {
|
|
2127
|
-
|
|
2235
|
+
execFileSync2(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
|
|
2128
2236
|
stdio: "inherit"
|
|
2129
2237
|
});
|
|
2130
2238
|
} catch (err) {
|
|
@@ -2137,8 +2245,8 @@ async function runAudienceMode(audience, action, args) {
|
|
|
2137
2245
|
}
|
|
2138
2246
|
|
|
2139
2247
|
// src/commands/explain.ts
|
|
2140
|
-
import { defineCommand as
|
|
2141
|
-
var explainCommand =
|
|
2248
|
+
import { defineCommand as defineCommand22 } from "citty";
|
|
2249
|
+
var explainCommand = defineCommand22({
|
|
2142
2250
|
meta: {
|
|
2143
2251
|
name: "explain",
|
|
2144
2252
|
description: "Show what permission a command would need"
|
|
@@ -2176,9 +2284,9 @@ var explainCommand = defineCommand21({
|
|
|
2176
2284
|
});
|
|
2177
2285
|
|
|
2178
2286
|
// src/commands/config/get.ts
|
|
2179
|
-
import { defineCommand as
|
|
2180
|
-
import
|
|
2181
|
-
var configGetCommand =
|
|
2287
|
+
import { defineCommand as defineCommand23 } from "citty";
|
|
2288
|
+
import consola20 from "consola";
|
|
2289
|
+
var configGetCommand = defineCommand23({
|
|
2182
2290
|
meta: {
|
|
2183
2291
|
name: "get",
|
|
2184
2292
|
description: "Get a configuration value"
|
|
@@ -2198,7 +2306,7 @@ var configGetCommand = defineCommand22({
|
|
|
2198
2306
|
if (idp)
|
|
2199
2307
|
console.log(idp);
|
|
2200
2308
|
else
|
|
2201
|
-
|
|
2309
|
+
consola20.info("No IdP configured.");
|
|
2202
2310
|
break;
|
|
2203
2311
|
}
|
|
2204
2312
|
case "email": {
|
|
@@ -2206,7 +2314,7 @@ var configGetCommand = defineCommand22({
|
|
|
2206
2314
|
if (auth?.email)
|
|
2207
2315
|
console.log(auth.email);
|
|
2208
2316
|
else
|
|
2209
|
-
|
|
2317
|
+
consola20.info("Not logged in.");
|
|
2210
2318
|
break;
|
|
2211
2319
|
}
|
|
2212
2320
|
default: {
|
|
@@ -2219,7 +2327,7 @@ var configGetCommand = defineCommand22({
|
|
|
2219
2327
|
if (sectionObj && field in sectionObj) {
|
|
2220
2328
|
console.log(sectionObj[field]);
|
|
2221
2329
|
} else {
|
|
2222
|
-
|
|
2330
|
+
consola20.info(`Key "${key}" not set.`);
|
|
2223
2331
|
}
|
|
2224
2332
|
} else {
|
|
2225
2333
|
throw new CliError(`Unknown key: "${key}". Use: idp, email, defaults.idp, defaults.approval, agent.key, agent.email`);
|
|
@@ -2230,9 +2338,9 @@ var configGetCommand = defineCommand22({
|
|
|
2230
2338
|
});
|
|
2231
2339
|
|
|
2232
2340
|
// src/commands/config/set.ts
|
|
2233
|
-
import { defineCommand as
|
|
2234
|
-
import
|
|
2235
|
-
var configSetCommand =
|
|
2341
|
+
import { defineCommand as defineCommand24 } from "citty";
|
|
2342
|
+
import consola21 from "consola";
|
|
2343
|
+
var configSetCommand = defineCommand24({
|
|
2236
2344
|
meta: {
|
|
2237
2345
|
name: "set",
|
|
2238
2346
|
description: "Set a configuration value"
|
|
@@ -2268,12 +2376,12 @@ var configSetCommand = defineCommand23({
|
|
|
2268
2376
|
throw new CliError(`Unknown section: "${section}". Use: defaults, agent`);
|
|
2269
2377
|
}
|
|
2270
2378
|
saveConfig(config);
|
|
2271
|
-
|
|
2379
|
+
consola21.success(`Set ${key} = ${value}`);
|
|
2272
2380
|
}
|
|
2273
2381
|
});
|
|
2274
2382
|
|
|
2275
2383
|
// src/commands/fetch/index.ts
|
|
2276
|
-
import { defineCommand as
|
|
2384
|
+
import { defineCommand as defineCommand25 } from "citty";
|
|
2277
2385
|
async function doRequest(method, url, body, contentType, raw, showHeaders) {
|
|
2278
2386
|
const token = getAuthToken();
|
|
2279
2387
|
if (!token) {
|
|
@@ -2309,13 +2417,13 @@ async function doRequest(method, url, body, contentType, raw, showHeaders) {
|
|
|
2309
2417
|
throw new CliError(`HTTP ${response.status} ${response.statusText}`);
|
|
2310
2418
|
}
|
|
2311
2419
|
}
|
|
2312
|
-
var fetchCommand =
|
|
2420
|
+
var fetchCommand = defineCommand25({
|
|
2313
2421
|
meta: {
|
|
2314
2422
|
name: "fetch",
|
|
2315
2423
|
description: "Make authenticated HTTP requests"
|
|
2316
2424
|
},
|
|
2317
2425
|
subCommands: {
|
|
2318
|
-
get:
|
|
2426
|
+
get: defineCommand25({
|
|
2319
2427
|
meta: {
|
|
2320
2428
|
name: "get",
|
|
2321
2429
|
description: "GET request with auth token"
|
|
@@ -2341,7 +2449,7 @@ var fetchCommand = defineCommand24({
|
|
|
2341
2449
|
await doRequest("GET", String(args.url), void 0, "application/json", Boolean(args.raw), Boolean(args.headers));
|
|
2342
2450
|
}
|
|
2343
2451
|
}),
|
|
2344
|
-
post:
|
|
2452
|
+
post: defineCommand25({
|
|
2345
2453
|
meta: {
|
|
2346
2454
|
name: "post",
|
|
2347
2455
|
description: "POST request with auth token"
|
|
@@ -2380,8 +2488,8 @@ var fetchCommand = defineCommand24({
|
|
|
2380
2488
|
});
|
|
2381
2489
|
|
|
2382
2490
|
// src/commands/mcp/index.ts
|
|
2383
|
-
import { defineCommand as
|
|
2384
|
-
var mcpCommand =
|
|
2491
|
+
import { defineCommand as defineCommand26 } from "citty";
|
|
2492
|
+
var mcpCommand = defineCommand26({
|
|
2385
2493
|
meta: {
|
|
2386
2494
|
name: "mcp",
|
|
2387
2495
|
description: "Start MCP server for AI agents"
|
|
@@ -2404,7 +2512,7 @@ var mcpCommand = defineCommand25({
|
|
|
2404
2512
|
if (transport !== "stdio" && transport !== "sse") {
|
|
2405
2513
|
throw new Error('Transport must be "stdio" or "sse"');
|
|
2406
2514
|
}
|
|
2407
|
-
const { startMcpServer } = await import("./server-
|
|
2515
|
+
const { startMcpServer } = await import("./server-FFOPFICW.js");
|
|
2408
2516
|
await startMcpServer(transport, port);
|
|
2409
2517
|
}
|
|
2410
2518
|
});
|
|
@@ -2412,10 +2520,10 @@ var mcpCommand = defineCommand25({
|
|
|
2412
2520
|
// src/commands/init/index.ts
|
|
2413
2521
|
import { existsSync as existsSync3, copyFileSync, writeFileSync } from "fs";
|
|
2414
2522
|
import { randomBytes } from "crypto";
|
|
2415
|
-
import { execFileSync as
|
|
2523
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
2416
2524
|
import { join as join2 } from "path";
|
|
2417
|
-
import { defineCommand as
|
|
2418
|
-
import
|
|
2525
|
+
import { defineCommand as defineCommand27 } from "citty";
|
|
2526
|
+
import consola22 from "consola";
|
|
2419
2527
|
var DEFAULT_IDP_URL = "https://id.openape.at";
|
|
2420
2528
|
async function downloadTemplate(repo, targetDir) {
|
|
2421
2529
|
const { downloadTemplate: gigetDownload } = await import("giget");
|
|
@@ -2424,28 +2532,28 @@ async function downloadTemplate(repo, targetDir) {
|
|
|
2424
2532
|
function installDeps(dir) {
|
|
2425
2533
|
const hasLockFile = (name) => existsSync3(join2(dir, name));
|
|
2426
2534
|
if (hasLockFile("pnpm-lock.yaml")) {
|
|
2427
|
-
|
|
2535
|
+
execFileSync3("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
2428
2536
|
} else if (hasLockFile("bun.lockb")) {
|
|
2429
|
-
|
|
2537
|
+
execFileSync3("bun", ["install"], { cwd: dir, stdio: "inherit" });
|
|
2430
2538
|
} else {
|
|
2431
|
-
|
|
2539
|
+
execFileSync3("npm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
2432
2540
|
}
|
|
2433
2541
|
}
|
|
2434
2542
|
async function promptChoice(message, choices) {
|
|
2435
|
-
const result = await
|
|
2543
|
+
const result = await consola22.prompt(message, { type: "select", options: choices });
|
|
2436
2544
|
if (typeof result === "symbol") {
|
|
2437
2545
|
throw new CliExit(0);
|
|
2438
2546
|
}
|
|
2439
2547
|
return result;
|
|
2440
2548
|
}
|
|
2441
2549
|
async function promptText(message, defaultValue) {
|
|
2442
|
-
const result = await
|
|
2550
|
+
const result = await consola22.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
|
|
2443
2551
|
if (typeof result === "symbol") {
|
|
2444
2552
|
throw new CliExit(0);
|
|
2445
2553
|
}
|
|
2446
2554
|
return result || defaultValue || "";
|
|
2447
2555
|
}
|
|
2448
|
-
var initCommand =
|
|
2556
|
+
var initCommand = defineCommand27({
|
|
2449
2557
|
meta: {
|
|
2450
2558
|
name: "init",
|
|
2451
2559
|
description: "Scaffold a new OpenApe project"
|
|
@@ -2490,20 +2598,20 @@ async function initSP(targetDir) {
|
|
|
2490
2598
|
if (existsSync3(join2(dir, "package.json"))) {
|
|
2491
2599
|
throw new CliError(`Directory "${dir}" already contains a project.`);
|
|
2492
2600
|
}
|
|
2493
|
-
|
|
2601
|
+
consola22.start("Scaffolding SP starter...");
|
|
2494
2602
|
await downloadTemplate("openape-ai/openape-sp-starter", dir);
|
|
2495
|
-
|
|
2496
|
-
|
|
2603
|
+
consola22.success("Scaffolded from openape-sp-starter");
|
|
2604
|
+
consola22.start("Installing dependencies...");
|
|
2497
2605
|
installDeps(dir);
|
|
2498
|
-
|
|
2606
|
+
consola22.success("Dependencies installed");
|
|
2499
2607
|
const envExample = join2(dir, ".env.example");
|
|
2500
2608
|
const envFile = join2(dir, ".env");
|
|
2501
2609
|
if (existsSync3(envExample) && !existsSync3(envFile)) {
|
|
2502
2610
|
copyFileSync(envExample, envFile);
|
|
2503
|
-
|
|
2611
|
+
consola22.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
|
|
2504
2612
|
}
|
|
2505
2613
|
console.log("");
|
|
2506
|
-
|
|
2614
|
+
consola22.box([
|
|
2507
2615
|
`cd ${dir}`,
|
|
2508
2616
|
"npm run dev",
|
|
2509
2617
|
"",
|
|
@@ -2522,15 +2630,15 @@ async function initIdP(targetDir) {
|
|
|
2522
2630
|
"s3 (S3-compatible)"
|
|
2523
2631
|
]);
|
|
2524
2632
|
const adminEmail = await promptText("Admin email");
|
|
2525
|
-
|
|
2633
|
+
consola22.start("Scaffolding IdP starter...");
|
|
2526
2634
|
await downloadTemplate("openape-ai/openape-idp-starter", dir);
|
|
2527
|
-
|
|
2528
|
-
|
|
2635
|
+
consola22.success("Scaffolded from openape-idp-starter");
|
|
2636
|
+
consola22.start("Installing dependencies...");
|
|
2529
2637
|
installDeps(dir);
|
|
2530
|
-
|
|
2638
|
+
consola22.success("Dependencies installed");
|
|
2531
2639
|
const sessionSecret = randomBytes(32).toString("hex");
|
|
2532
2640
|
const managementToken = randomBytes(32).toString("hex");
|
|
2533
|
-
|
|
2641
|
+
consola22.success("Secrets generated");
|
|
2534
2642
|
const isLocalhost = domain === "localhost";
|
|
2535
2643
|
const origin = isLocalhost ? "http://localhost:3000" : `https://${domain}`;
|
|
2536
2644
|
const envContent = [
|
|
@@ -2546,9 +2654,9 @@ async function initIdP(targetDir) {
|
|
|
2546
2654
|
].join("\n");
|
|
2547
2655
|
writeFileSync(join2(dir, ".env"), `${envContent}
|
|
2548
2656
|
`, { mode: 384 });
|
|
2549
|
-
|
|
2657
|
+
consola22.success(".env created");
|
|
2550
2658
|
console.log("");
|
|
2551
|
-
|
|
2659
|
+
consola22.box([
|
|
2552
2660
|
`cd ${dir}`,
|
|
2553
2661
|
"npm run dev",
|
|
2554
2662
|
"",
|
|
@@ -2570,8 +2678,8 @@ import { execFile as execFile2 } from "child_process";
|
|
|
2570
2678
|
import { generateKeyPairSync, sign } from "crypto";
|
|
2571
2679
|
import { dirname, resolve as resolve2 } from "path";
|
|
2572
2680
|
import { homedir as homedir4 } from "os";
|
|
2573
|
-
import { defineCommand as
|
|
2574
|
-
import
|
|
2681
|
+
import { defineCommand as defineCommand28 } from "citty";
|
|
2682
|
+
import consola23 from "consola";
|
|
2575
2683
|
var DEFAULT_IDP_URL2 = "https://id.openape.at";
|
|
2576
2684
|
var DEFAULT_KEY_PATH = "~/.ssh/id_ed25519";
|
|
2577
2685
|
var POLL_INTERVAL = 3e3;
|
|
@@ -2656,7 +2764,7 @@ async function pollForEnrollment(idp, agentEmail, keyPath) {
|
|
|
2656
2764
|
}
|
|
2657
2765
|
throw new Error("Enrollment timed out. Please check the browser and try again.");
|
|
2658
2766
|
}
|
|
2659
|
-
var enrollCommand =
|
|
2767
|
+
var enrollCommand = defineCommand28({
|
|
2660
2768
|
meta: {
|
|
2661
2769
|
name: "enroll",
|
|
2662
2770
|
description: "Enroll an agent with an Identity Provider"
|
|
@@ -2676,18 +2784,18 @@ var enrollCommand = defineCommand27({
|
|
|
2676
2784
|
}
|
|
2677
2785
|
},
|
|
2678
2786
|
async run({ args }) {
|
|
2679
|
-
const idp = args.idp || await
|
|
2787
|
+
const idp = args.idp || await consola23.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r) => {
|
|
2680
2788
|
if (typeof r === "symbol") throw new CliExit(0);
|
|
2681
2789
|
return r;
|
|
2682
2790
|
}) || DEFAULT_IDP_URL2;
|
|
2683
|
-
const agentName = args.name || await
|
|
2791
|
+
const agentName = args.name || await consola23.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r) => {
|
|
2684
2792
|
if (typeof r === "symbol") throw new CliExit(0);
|
|
2685
2793
|
return r;
|
|
2686
2794
|
});
|
|
2687
2795
|
if (!agentName) {
|
|
2688
2796
|
throw new CliError("Agent name is required.");
|
|
2689
2797
|
}
|
|
2690
|
-
const keyPath = args.key || await
|
|
2798
|
+
const keyPath = args.key || await consola23.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => {
|
|
2691
2799
|
if (typeof r === "symbol") throw new CliExit(0);
|
|
2692
2800
|
return r;
|
|
2693
2801
|
}) || DEFAULT_KEY_PATH;
|
|
@@ -2695,19 +2803,19 @@ var enrollCommand = defineCommand27({
|
|
|
2695
2803
|
let publicKey;
|
|
2696
2804
|
if (existsSync4(resolvedKey)) {
|
|
2697
2805
|
publicKey = readPublicKey(resolvedKey);
|
|
2698
|
-
|
|
2806
|
+
consola23.success(`Using existing key ${keyPath}`);
|
|
2699
2807
|
} else {
|
|
2700
|
-
|
|
2808
|
+
consola23.start(`Generating Ed25519 key pair at ${keyPath}...`);
|
|
2701
2809
|
publicKey = generateAndSaveKey(keyPath);
|
|
2702
|
-
|
|
2810
|
+
consola23.success(`Key pair generated at ${keyPath}`);
|
|
2703
2811
|
}
|
|
2704
2812
|
const encodedKey = encodeURIComponent(publicKey);
|
|
2705
2813
|
const enrollUrl = `${idp}/enroll?name=${encodeURIComponent(agentName)}&key=${encodedKey}`;
|
|
2706
|
-
|
|
2707
|
-
|
|
2814
|
+
consola23.info("Opening browser for enrollment...");
|
|
2815
|
+
consola23.info(`\u2192 ${idp}/enroll`);
|
|
2708
2816
|
openBrowser2(enrollUrl);
|
|
2709
2817
|
console.log("");
|
|
2710
|
-
const agentEmail = await
|
|
2818
|
+
const agentEmail = await consola23.prompt(
|
|
2711
2819
|
"Agent email (shown in browser after enrollment)",
|
|
2712
2820
|
{ type: "text", placeholder: `agent+${agentName}@...` }
|
|
2713
2821
|
).then((r) => {
|
|
@@ -2717,7 +2825,7 @@ var enrollCommand = defineCommand27({
|
|
|
2717
2825
|
if (!agentEmail) {
|
|
2718
2826
|
throw new CliError("Agent email is required to verify enrollment.");
|
|
2719
2827
|
}
|
|
2720
|
-
|
|
2828
|
+
consola23.start("Verifying enrollment...");
|
|
2721
2829
|
const { token, expiresIn } = await pollForEnrollment(idp, agentEmail, keyPath);
|
|
2722
2830
|
saveAuth({
|
|
2723
2831
|
idp,
|
|
@@ -2729,18 +2837,18 @@ var enrollCommand = defineCommand27({
|
|
|
2729
2837
|
config.defaults = { ...config.defaults, idp };
|
|
2730
2838
|
config.agent = { key: keyPath, email: agentEmail };
|
|
2731
2839
|
saveConfig(config);
|
|
2732
|
-
|
|
2733
|
-
|
|
2840
|
+
consola23.success(`Agent enrolled as ${agentEmail}`);
|
|
2841
|
+
consola23.success("Config saved to ~/.config/apes/");
|
|
2734
2842
|
console.log("");
|
|
2735
|
-
|
|
2843
|
+
consola23.info("Verify with: apes whoami");
|
|
2736
2844
|
}
|
|
2737
2845
|
});
|
|
2738
2846
|
|
|
2739
2847
|
// src/commands/register-user.ts
|
|
2740
2848
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
2741
|
-
import { defineCommand as
|
|
2742
|
-
import
|
|
2743
|
-
var registerUserCommand =
|
|
2849
|
+
import { defineCommand as defineCommand29 } from "citty";
|
|
2850
|
+
import consola24 from "consola";
|
|
2851
|
+
var registerUserCommand = defineCommand29({
|
|
2744
2852
|
meta: {
|
|
2745
2853
|
name: "register-user",
|
|
2746
2854
|
description: "Register a sub-user with SSH key"
|
|
@@ -2795,15 +2903,15 @@ var registerUserCommand = defineCommand28({
|
|
|
2795
2903
|
...userType ? { type: userType } : {}
|
|
2796
2904
|
}
|
|
2797
2905
|
});
|
|
2798
|
-
|
|
2906
|
+
consola24.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
|
|
2799
2907
|
}
|
|
2800
2908
|
});
|
|
2801
2909
|
|
|
2802
2910
|
// src/commands/dns-check.ts
|
|
2803
|
-
import { defineCommand as
|
|
2804
|
-
import
|
|
2911
|
+
import { defineCommand as defineCommand30 } from "citty";
|
|
2912
|
+
import consola25 from "consola";
|
|
2805
2913
|
import { resolveDDISA as resolveDDISA2 } from "@openape/core";
|
|
2806
|
-
var dnsCheckCommand =
|
|
2914
|
+
var dnsCheckCommand = defineCommand30({
|
|
2807
2915
|
meta: {
|
|
2808
2916
|
name: "dns-check",
|
|
2809
2917
|
description: "Validate DDISA DNS TXT records for a domain"
|
|
@@ -2817,7 +2925,7 @@ var dnsCheckCommand = defineCommand29({
|
|
|
2817
2925
|
},
|
|
2818
2926
|
async run({ args }) {
|
|
2819
2927
|
const domain = args.domain;
|
|
2820
|
-
|
|
2928
|
+
consola25.start(`Checking _ddisa.${domain}...`);
|
|
2821
2929
|
try {
|
|
2822
2930
|
const result = await resolveDDISA2(domain);
|
|
2823
2931
|
if (!result) {
|
|
@@ -2826,7 +2934,7 @@ var dnsCheckCommand = defineCommand29({
|
|
|
2826
2934
|
console.log(` _ddisa.${domain} TXT "v=ddisa1 idp=https://id.${domain}"`);
|
|
2827
2935
|
throw new CliError(`No DDISA record found for ${domain}`);
|
|
2828
2936
|
}
|
|
2829
|
-
|
|
2937
|
+
consola25.success(`_ddisa.${domain} \u2192 ${result.idp}`);
|
|
2830
2938
|
console.log("");
|
|
2831
2939
|
console.log(` Version: ${result.version || "ddisa1"}`);
|
|
2832
2940
|
console.log(` IdP URL: ${result.idp}`);
|
|
@@ -2835,14 +2943,14 @@ var dnsCheckCommand = defineCommand29({
|
|
|
2835
2943
|
if (result.priority !== void 0)
|
|
2836
2944
|
console.log(` Priority: ${result.priority}`);
|
|
2837
2945
|
console.log("");
|
|
2838
|
-
|
|
2946
|
+
consola25.start(`Verifying IdP at ${result.idp}...`);
|
|
2839
2947
|
const discoResp = await fetch(`${result.idp}/.well-known/openid-configuration`);
|
|
2840
2948
|
if (!discoResp.ok) {
|
|
2841
|
-
|
|
2949
|
+
consola25.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
|
|
2842
2950
|
return;
|
|
2843
2951
|
}
|
|
2844
2952
|
const disco = await discoResp.json();
|
|
2845
|
-
|
|
2953
|
+
consola25.success(`IdP is reachable`);
|
|
2846
2954
|
console.log(` Issuer: ${disco.issuer}`);
|
|
2847
2955
|
console.log(` DDISA: v${disco.ddisa_version || "?"}`);
|
|
2848
2956
|
if (disco.ddisa_auth_methods_supported) {
|
|
@@ -2860,7 +2968,7 @@ var dnsCheckCommand = defineCommand29({
|
|
|
2860
2968
|
// src/commands/health.ts
|
|
2861
2969
|
import { exec } from "child_process";
|
|
2862
2970
|
import { promisify } from "util";
|
|
2863
|
-
import { defineCommand as
|
|
2971
|
+
import { defineCommand as defineCommand31 } from "citty";
|
|
2864
2972
|
var execAsync = promisify(exec);
|
|
2865
2973
|
async function resolveApeShellPath() {
|
|
2866
2974
|
try {
|
|
@@ -2896,7 +3004,7 @@ async function bestEffortGrantCount(idp) {
|
|
|
2896
3004
|
}
|
|
2897
3005
|
}
|
|
2898
3006
|
async function runHealth(args) {
|
|
2899
|
-
const version = true ? "0.
|
|
3007
|
+
const version = true ? "0.9.0" : "0.0.0";
|
|
2900
3008
|
const auth = loadAuth();
|
|
2901
3009
|
if (!auth) {
|
|
2902
3010
|
throw new CliError("Not logged in. Run `apes login` first.", 1);
|
|
@@ -2959,7 +3067,7 @@ async function runHealth(args) {
|
|
|
2959
3067
|
throw new CliError(`IdP ${auth.idp} unreachable: ${idpProbe.error}`, 1);
|
|
2960
3068
|
}
|
|
2961
3069
|
}
|
|
2962
|
-
var healthCommand =
|
|
3070
|
+
var healthCommand = defineCommand31({
|
|
2963
3071
|
meta: {
|
|
2964
3072
|
name: "health",
|
|
2965
3073
|
description: "Report CLI diagnostic state (auth, IdP, grants, binaries)"
|
|
@@ -2977,8 +3085,8 @@ var healthCommand = defineCommand30({
|
|
|
2977
3085
|
});
|
|
2978
3086
|
|
|
2979
3087
|
// src/commands/workflows.ts
|
|
2980
|
-
import { defineCommand as
|
|
2981
|
-
import
|
|
3088
|
+
import { defineCommand as defineCommand32 } from "citty";
|
|
3089
|
+
import consola26 from "consola";
|
|
2982
3090
|
|
|
2983
3091
|
// src/guides/index.ts
|
|
2984
3092
|
var guides = [
|
|
@@ -3028,7 +3136,7 @@ var guides = [
|
|
|
3028
3136
|
];
|
|
3029
3137
|
|
|
3030
3138
|
// src/commands/workflows.ts
|
|
3031
|
-
var workflowsCommand =
|
|
3139
|
+
var workflowsCommand = defineCommand32({
|
|
3032
3140
|
meta: {
|
|
3033
3141
|
name: "workflows",
|
|
3034
3142
|
description: "Discover workflow guides"
|
|
@@ -3049,7 +3157,7 @@ var workflowsCommand = defineCommand31({
|
|
|
3049
3157
|
if (args.id) {
|
|
3050
3158
|
const guide = guides.find((g) => g.id === String(args.id));
|
|
3051
3159
|
if (!guide) {
|
|
3052
|
-
|
|
3160
|
+
consola26.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
|
|
3053
3161
|
throw new CliError(`Guide not found: ${args.id}`);
|
|
3054
3162
|
}
|
|
3055
3163
|
if (args.json) {
|
|
@@ -3098,10 +3206,10 @@ if (shellRewrite) {
|
|
|
3098
3206
|
if (shellRewrite.action === "rewrite") {
|
|
3099
3207
|
process.argv = shellRewrite.argv;
|
|
3100
3208
|
} else if (shellRewrite.action === "version") {
|
|
3101
|
-
console.log(`ape-shell ${"0.
|
|
3209
|
+
console.log(`ape-shell ${"0.9.0"} (OpenApe DDISA shell wrapper)`);
|
|
3102
3210
|
process.exit(0);
|
|
3103
3211
|
} else if (shellRewrite.action === "help") {
|
|
3104
|
-
console.log(`ape-shell ${"0.
|
|
3212
|
+
console.log(`ape-shell ${"0.9.0"} \u2014 OpenApe DDISA shell wrapper`);
|
|
3105
3213
|
console.log("");
|
|
3106
3214
|
console.log("Usage:");
|
|
3107
3215
|
console.log(" ape-shell Start interactive grant-mediated REPL");
|
|
@@ -3116,7 +3224,7 @@ if (shellRewrite) {
|
|
|
3116
3224
|
console.log(" --help, -h Show this help message");
|
|
3117
3225
|
process.exit(0);
|
|
3118
3226
|
} else if (shellRewrite.action === "interactive") {
|
|
3119
|
-
const { runInteractiveShell } = await import("./orchestrator-
|
|
3227
|
+
const { runInteractiveShell } = await import("./orchestrator-GPNL543L.js");
|
|
3120
3228
|
await runInteractiveShell();
|
|
3121
3229
|
process.exit(0);
|
|
3122
3230
|
} else {
|
|
@@ -3125,7 +3233,7 @@ if (shellRewrite) {
|
|
|
3125
3233
|
}
|
|
3126
3234
|
}
|
|
3127
3235
|
var debug = process.argv.includes("--debug");
|
|
3128
|
-
var grantsCommand =
|
|
3236
|
+
var grantsCommand = defineCommand33({
|
|
3129
3237
|
meta: {
|
|
3130
3238
|
name: "grants",
|
|
3131
3239
|
description: "Grant management"
|
|
@@ -3139,13 +3247,14 @@ var grantsCommand = defineCommand32({
|
|
|
3139
3247
|
approve: approveCommand,
|
|
3140
3248
|
deny: denyCommand,
|
|
3141
3249
|
revoke: revokeCommand,
|
|
3250
|
+
run: runGrantCommand,
|
|
3142
3251
|
token: tokenCommand,
|
|
3143
3252
|
delegate: delegateCommand,
|
|
3144
3253
|
delegations: delegationsCommand,
|
|
3145
3254
|
"delegation-revoke": delegationRevokeCommand
|
|
3146
3255
|
}
|
|
3147
3256
|
});
|
|
3148
|
-
var configCommand =
|
|
3257
|
+
var configCommand = defineCommand33({
|
|
3149
3258
|
meta: {
|
|
3150
3259
|
name: "config",
|
|
3151
3260
|
description: "Configuration management"
|
|
@@ -3155,10 +3264,10 @@ var configCommand = defineCommand32({
|
|
|
3155
3264
|
set: configSetCommand
|
|
3156
3265
|
}
|
|
3157
3266
|
});
|
|
3158
|
-
var main =
|
|
3267
|
+
var main = defineCommand33({
|
|
3159
3268
|
meta: {
|
|
3160
3269
|
name: "apes",
|
|
3161
|
-
version: "0.
|
|
3270
|
+
version: "0.9.0",
|
|
3162
3271
|
description: "Unified CLI for OpenApe"
|
|
3163
3272
|
},
|
|
3164
3273
|
subCommands: {
|
|
@@ -3186,13 +3295,13 @@ runMain(main).catch((err) => {
|
|
|
3186
3295
|
process.exit(err.exitCode);
|
|
3187
3296
|
}
|
|
3188
3297
|
if (err instanceof CliError) {
|
|
3189
|
-
|
|
3298
|
+
consola27.error(err.message);
|
|
3190
3299
|
process.exit(err.exitCode);
|
|
3191
3300
|
}
|
|
3192
3301
|
if (debug) {
|
|
3193
|
-
|
|
3302
|
+
consola27.error(err);
|
|
3194
3303
|
} else {
|
|
3195
|
-
|
|
3304
|
+
consola27.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
|
|
3196
3305
|
}
|
|
3197
3306
|
process.exit(1);
|
|
3198
3307
|
});
|