@openape/apes 1.6.1 → 1.7.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-OBF7IMQ2.js";
|
|
64
64
|
|
|
65
65
|
// src/cli.ts
|
|
66
|
-
import
|
|
66
|
+
import consola47 from "consola";
|
|
67
67
|
|
|
68
68
|
// src/ape-shell.ts
|
|
69
69
|
import path from "path";
|
|
@@ -93,7 +93,7 @@ function rewriteApeShellArgs(argv, argv0) {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// src/cli.ts
|
|
96
|
-
import { defineCommand as
|
|
96
|
+
import { defineCommand as defineCommand58, runMain } from "citty";
|
|
97
97
|
|
|
98
98
|
// src/commands/auth/login.ts
|
|
99
99
|
import { Buffer as Buffer2 } from "buffer";
|
|
@@ -3921,6 +3921,7 @@ var agentsCommand = defineCommand28({
|
|
|
3921
3921
|
import { defineCommand as defineCommand34 } from "citty";
|
|
3922
3922
|
|
|
3923
3923
|
// src/commands/nest/authorize.ts
|
|
3924
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
3924
3925
|
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
3925
3926
|
import { join as join9 } from "path";
|
|
3926
3927
|
import { defineCommand as defineCommand30 } from "citty";
|
|
@@ -4020,8 +4021,8 @@ var DEFAULT_ALLOW_PATTERNS = [
|
|
|
4020
4021
|
// glob below limits the auto-approval to that exact lifecycle path
|
|
4021
4022
|
// — `bash *` would be unsafe.
|
|
4022
4023
|
"bash *apes-spawn-*setup.sh",
|
|
4023
|
-
// Bridge invocation the
|
|
4024
|
-
//
|
|
4024
|
+
// Bridge invocation the supervisor uses to keep agent processes
|
|
4025
|
+
// running. Pattern is intentionally precise — not a generic
|
|
4025
4026
|
// `apes run --as *` wildcard — so a compromised nest can't pivot
|
|
4026
4027
|
// to running arbitrary commands as arbitrary users.
|
|
4027
4028
|
"apes run --as * -- openape-chat-bridge"
|
|
@@ -4029,77 +4030,51 @@ var DEFAULT_ALLOW_PATTERNS = [
|
|
|
4029
4030
|
var authorizeNestCommand = defineCommand30({
|
|
4030
4031
|
meta: {
|
|
4031
4032
|
name: "authorize",
|
|
4032
|
-
description: "Set the YOLO-policy that lets the local nest spawn/destroy without per-call DDISA prompts"
|
|
4033
|
+
description: "Set the YOLO-policy that lets the local nest spawn/destroy without per-call DDISA prompts (wraps `apes yolo set`)"
|
|
4033
4034
|
},
|
|
4034
4035
|
args: {
|
|
4035
4036
|
"allow": {
|
|
4036
4037
|
type: "string",
|
|
4037
4038
|
description: "Override allow_patterns (comma-separated globs). Default: nest-managed agent lifecycle."
|
|
4038
4039
|
},
|
|
4039
|
-
"mode": {
|
|
4040
|
-
type: "string",
|
|
4041
|
-
description: "Policy mode (allow-list | deny-list). Default: allow-list \u2014 auto-approve only matched patterns."
|
|
4042
|
-
},
|
|
4043
4040
|
"expires-in": {
|
|
4044
4041
|
type: "string",
|
|
4045
4042
|
description: "Optional duration like 30d, 6h. Omit for no expiry."
|
|
4046
4043
|
}
|
|
4047
4044
|
},
|
|
4048
4045
|
async run({ args }) {
|
|
4049
|
-
const ownerAuth = loadAuth();
|
|
4050
|
-
if (!ownerAuth?.email || !ownerAuth.access_token) {
|
|
4051
|
-
throw new CliError("Run `apes login <email>` first \u2014 only the nest's owner can set its YOLO-policy.");
|
|
4052
|
-
}
|
|
4053
4046
|
const nestAuthPath = join9(NEST_DATA_DIR, ".config", "apes", "auth.json");
|
|
4054
4047
|
if (!existsSync11(nestAuthPath)) {
|
|
4055
4048
|
throw new CliError("Nest not enrolled. Run `apes nest enroll` first.");
|
|
4056
4049
|
}
|
|
4057
4050
|
const nestAuth = JSON.parse(readFileSync10(nestAuthPath, "utf8"));
|
|
4058
4051
|
if (!nestAuth.email) throw new CliError(`${nestAuthPath} has no email`);
|
|
4059
|
-
const
|
|
4060
|
-
|
|
4061
|
-
const
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
mode,
|
|
4078
|
-
allowPatterns,
|
|
4079
|
-
denyPatterns: [],
|
|
4080
|
-
expiresAt: expiresAt ?? null
|
|
4081
|
-
})
|
|
4082
|
-
});
|
|
4083
|
-
if (!res.ok) {
|
|
4084
|
-
const text = await res.text().catch(() => "");
|
|
4085
|
-
throw new CliError(`PUT /yolo-policy failed (${res.status}): ${text}`);
|
|
4052
|
+
const allow = args.allow ?? DEFAULT_ALLOW_PATTERNS.join(",");
|
|
4053
|
+
consola26.info(`Configuring YOLO-policy on ${nestAuth.email} via \`apes yolo set\`\u2026`);
|
|
4054
|
+
const cmdArgs = [
|
|
4055
|
+
"yolo",
|
|
4056
|
+
"set",
|
|
4057
|
+
nestAuth.email,
|
|
4058
|
+
"--mode",
|
|
4059
|
+
"allow-list",
|
|
4060
|
+
"--allow",
|
|
4061
|
+
allow
|
|
4062
|
+
];
|
|
4063
|
+
if (typeof args["expires-in"] === "string" && args["expires-in"]) {
|
|
4064
|
+
cmdArgs.push("--expires-in", args["expires-in"]);
|
|
4065
|
+
}
|
|
4066
|
+
try {
|
|
4067
|
+
execFileSync9("apes", cmdArgs, { stdio: "inherit" });
|
|
4068
|
+
} catch (err) {
|
|
4069
|
+
throw new CliError(err instanceof Error ? err.message : String(err));
|
|
4086
4070
|
}
|
|
4087
|
-
consola26.success("
|
|
4071
|
+
consola26.success("Nest-driven agent lifecycle is now zero-prompt.");
|
|
4088
4072
|
consola26.info("Test: apes agents spawn <name> via the nest API \u2192 no DDISA prompt.");
|
|
4089
4073
|
}
|
|
4090
4074
|
});
|
|
4091
|
-
function parseExpiresIn(s) {
|
|
4092
|
-
if (!s) return null;
|
|
4093
|
-
const m = s.match(/^(\d+)([hdw])$/);
|
|
4094
|
-
if (!m) throw new CliError(`Invalid --expires-in "${s}" \u2014 expected forms like 30d, 6h, 2w`);
|
|
4095
|
-
const n = Number(m[1]);
|
|
4096
|
-
const unit = m[2];
|
|
4097
|
-
const seconds = unit === "h" ? 3600 : unit === "d" ? 86400 : 7 * 86400;
|
|
4098
|
-
return Math.floor(Date.now() / 1e3) + n * seconds;
|
|
4099
|
-
}
|
|
4100
4075
|
|
|
4101
4076
|
// src/commands/nest/install.ts
|
|
4102
|
-
import { execFileSync as
|
|
4077
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
4103
4078
|
import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
|
|
4104
4079
|
import { homedir as homedir11, userInfo as userInfo2 } from "os";
|
|
4105
4080
|
import { dirname as dirname3, join as join10 } from "path";
|
|
@@ -4276,10 +4251,10 @@ var installNestCommand = defineCommand31({
|
|
|
4276
4251
|
}
|
|
4277
4252
|
const uid = userInfo2().uid;
|
|
4278
4253
|
try {
|
|
4279
|
-
|
|
4254
|
+
execFileSync10("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL}`], { stdio: "ignore" });
|
|
4280
4255
|
} catch {
|
|
4281
4256
|
}
|
|
4282
|
-
|
|
4257
|
+
execFileSync10("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
|
|
4283
4258
|
consola27.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
|
|
4284
4259
|
consola27.info("");
|
|
4285
4260
|
consola27.info("Next steps for zero-prompt spawn \u2014 both one-time:");
|
|
@@ -4346,7 +4321,7 @@ function humanDuration(sec) {
|
|
|
4346
4321
|
}
|
|
4347
4322
|
|
|
4348
4323
|
// src/commands/nest/uninstall.ts
|
|
4349
|
-
import { execFileSync as
|
|
4324
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
4350
4325
|
import { existsSync as existsSync13, unlinkSync } from "fs";
|
|
4351
4326
|
import { homedir as homedir12, userInfo as userInfo3 } from "os";
|
|
4352
4327
|
import { join as join11 } from "path";
|
|
@@ -4362,7 +4337,7 @@ var uninstallNestCommand = defineCommand33({
|
|
|
4362
4337
|
const uid = userInfo3().uid;
|
|
4363
4338
|
const path2 = join11(homedir12(), "Library", "LaunchAgents", `${PLIST_LABEL2}.plist`);
|
|
4364
4339
|
try {
|
|
4365
|
-
|
|
4340
|
+
execFileSync11("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
|
|
4366
4341
|
consola29.success("Nest daemon stopped");
|
|
4367
4342
|
} catch {
|
|
4368
4343
|
consola29.info("Nest daemon was not loaded");
|
|
@@ -4390,16 +4365,211 @@ var nestCommand = defineCommand34({
|
|
|
4390
4365
|
}
|
|
4391
4366
|
});
|
|
4392
4367
|
|
|
4393
|
-
// src/commands/
|
|
4368
|
+
// src/commands/yolo/index.ts
|
|
4369
|
+
import { defineCommand as defineCommand38 } from "citty";
|
|
4370
|
+
|
|
4371
|
+
// src/commands/yolo/clear.ts
|
|
4394
4372
|
import { defineCommand as defineCommand35 } from "citty";
|
|
4395
4373
|
import consola30 from "consola";
|
|
4396
|
-
var
|
|
4374
|
+
var yoloClearCommand = defineCommand35({
|
|
4375
|
+
meta: {
|
|
4376
|
+
name: "clear",
|
|
4377
|
+
description: "Remove the YOLO-policy from a DDISA agent (subsequent grants need human approval)"
|
|
4378
|
+
},
|
|
4379
|
+
args: {
|
|
4380
|
+
email: {
|
|
4381
|
+
type: "positional",
|
|
4382
|
+
description: "Target agent email",
|
|
4383
|
+
required: true
|
|
4384
|
+
}
|
|
4385
|
+
},
|
|
4386
|
+
async run({ args }) {
|
|
4387
|
+
const ownerAuth = loadAuth();
|
|
4388
|
+
if (!ownerAuth?.access_token) {
|
|
4389
|
+
throw new CliError("Run `apes login <email>` first.");
|
|
4390
|
+
}
|
|
4391
|
+
const idp = getIdpUrl();
|
|
4392
|
+
if (!idp) throw new CliError("No IdP configured.");
|
|
4393
|
+
const email = args.email;
|
|
4394
|
+
const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`;
|
|
4395
|
+
const res = await fetch(url, {
|
|
4396
|
+
method: "DELETE",
|
|
4397
|
+
headers: { Authorization: `Bearer ${ownerAuth.access_token}` }
|
|
4398
|
+
});
|
|
4399
|
+
if (!res.ok && res.status !== 404) {
|
|
4400
|
+
const text = await res.text().catch(() => "");
|
|
4401
|
+
throw new CliError(`DELETE /yolo-policy failed (${res.status}): ${text}`);
|
|
4402
|
+
}
|
|
4403
|
+
consola30.success(`YOLO-policy cleared on ${email}`);
|
|
4404
|
+
}
|
|
4405
|
+
});
|
|
4406
|
+
|
|
4407
|
+
// src/commands/yolo/set.ts
|
|
4408
|
+
import { defineCommand as defineCommand36 } from "citty";
|
|
4409
|
+
import consola31 from "consola";
|
|
4410
|
+
var VALID_MODES = ["allow-list", "deny-list"];
|
|
4411
|
+
var yoloSetCommand = defineCommand36({
|
|
4412
|
+
meta: {
|
|
4413
|
+
name: "set",
|
|
4414
|
+
description: "Write a YOLO-policy on a DDISA agent you own"
|
|
4415
|
+
},
|
|
4416
|
+
args: {
|
|
4417
|
+
"email": {
|
|
4418
|
+
type: "positional",
|
|
4419
|
+
description: "Target agent email (e.g. nest-mac-cb6bf26a+patrick+example_com@id.openape.ai)",
|
|
4420
|
+
required: true
|
|
4421
|
+
},
|
|
4422
|
+
"mode": {
|
|
4423
|
+
type: "string",
|
|
4424
|
+
description: "Policy mode (allow-list | deny-list)"
|
|
4425
|
+
},
|
|
4426
|
+
"allow": {
|
|
4427
|
+
type: "string",
|
|
4428
|
+
description: 'Allow patterns \u2014 comma-separated bash globs (e.g. "apes agents spawn *,apes agents sync")'
|
|
4429
|
+
},
|
|
4430
|
+
"deny": {
|
|
4431
|
+
type: "string",
|
|
4432
|
+
description: "Deny patterns \u2014 comma-separated bash globs"
|
|
4433
|
+
},
|
|
4434
|
+
"deny-risk": {
|
|
4435
|
+
type: "string",
|
|
4436
|
+
description: "Deny grants at this risk level or above (low|medium|high|critical)"
|
|
4437
|
+
},
|
|
4438
|
+
"expires-in": {
|
|
4439
|
+
type: "string",
|
|
4440
|
+
description: "Optional expiry like 30d, 6h, 2w. Omit for no expiry."
|
|
4441
|
+
}
|
|
4442
|
+
},
|
|
4443
|
+
async run({ args }) {
|
|
4444
|
+
const ownerAuth = loadAuth();
|
|
4445
|
+
if (!ownerAuth?.access_token) {
|
|
4446
|
+
throw new CliError("Run `apes login <email>` first.");
|
|
4447
|
+
}
|
|
4448
|
+
const idp = getIdpUrl();
|
|
4449
|
+
if (!idp) throw new CliError("No IdP configured.");
|
|
4450
|
+
const email = args.email;
|
|
4451
|
+
const mode = args.mode ?? "allow-list";
|
|
4452
|
+
if (!VALID_MODES.includes(mode)) {
|
|
4453
|
+
throw new CliError(`mode must be one of: ${VALID_MODES.join(", ")}`);
|
|
4454
|
+
}
|
|
4455
|
+
const allowPatterns = parseList(args.allow);
|
|
4456
|
+
const denyPatterns = parseList(args.deny);
|
|
4457
|
+
const denyRiskThreshold = args["deny-risk"] ?? null;
|
|
4458
|
+
const expiresAt = parseExpiresIn(args["expires-in"]);
|
|
4459
|
+
consola31.info(`Setting YOLO-policy on ${email}`);
|
|
4460
|
+
consola31.info(` mode: ${mode}`);
|
|
4461
|
+
if (allowPatterns.length) consola31.info(` allow_patterns: ${allowPatterns.join(", ")}`);
|
|
4462
|
+
if (denyPatterns.length) consola31.info(` deny_patterns: ${denyPatterns.join(", ")}`);
|
|
4463
|
+
if (denyRiskThreshold) consola31.info(` deny_risk: ${denyRiskThreshold}`);
|
|
4464
|
+
if (expiresAt) consola31.info(` expires_at: ${new Date(expiresAt * 1e3).toISOString()}`);
|
|
4465
|
+
const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`;
|
|
4466
|
+
const res = await fetch(url, {
|
|
4467
|
+
method: "PUT",
|
|
4468
|
+
headers: {
|
|
4469
|
+
"Authorization": `Bearer ${ownerAuth.access_token}`,
|
|
4470
|
+
"Content-Type": "application/json"
|
|
4471
|
+
},
|
|
4472
|
+
body: JSON.stringify({
|
|
4473
|
+
mode,
|
|
4474
|
+
allowPatterns,
|
|
4475
|
+
denyPatterns,
|
|
4476
|
+
denyRiskThreshold,
|
|
4477
|
+
expiresAt: expiresAt ?? null
|
|
4478
|
+
})
|
|
4479
|
+
});
|
|
4480
|
+
if (!res.ok) {
|
|
4481
|
+
const text = await res.text().catch(() => "");
|
|
4482
|
+
throw new CliError(`PUT /yolo-policy failed (${res.status}): ${text}`);
|
|
4483
|
+
}
|
|
4484
|
+
consola31.success(`YOLO-policy applied to ${email}`);
|
|
4485
|
+
}
|
|
4486
|
+
});
|
|
4487
|
+
function parseList(s) {
|
|
4488
|
+
if (!s) return [];
|
|
4489
|
+
return s.split(",").map((p) => p.trim()).filter(Boolean);
|
|
4490
|
+
}
|
|
4491
|
+
function parseExpiresIn(s) {
|
|
4492
|
+
if (!s) return null;
|
|
4493
|
+
const m = s.match(/^(\d+)([hdw])$/);
|
|
4494
|
+
if (!m) throw new CliError(`Invalid --expires-in "${s}" \u2014 expected forms like 30d, 6h, 2w`);
|
|
4495
|
+
const n = Number(m[1]);
|
|
4496
|
+
const unit = m[2];
|
|
4497
|
+
const seconds = unit === "h" ? 3600 : unit === "d" ? 86400 : 7 * 86400;
|
|
4498
|
+
return Math.floor(Date.now() / 1e3) + n * seconds;
|
|
4499
|
+
}
|
|
4500
|
+
|
|
4501
|
+
// src/commands/yolo/show.ts
|
|
4502
|
+
import { defineCommand as defineCommand37 } from "citty";
|
|
4503
|
+
import consola32 from "consola";
|
|
4504
|
+
var yoloShowCommand = defineCommand37({
|
|
4505
|
+
meta: {
|
|
4506
|
+
name: "show",
|
|
4507
|
+
description: "Print the YOLO-policy currently set on a DDISA agent"
|
|
4508
|
+
},
|
|
4509
|
+
args: {
|
|
4510
|
+
email: {
|
|
4511
|
+
type: "positional",
|
|
4512
|
+
description: "Target agent email",
|
|
4513
|
+
required: true
|
|
4514
|
+
},
|
|
4515
|
+
json: {
|
|
4516
|
+
type: "boolean",
|
|
4517
|
+
description: "JSON output for scripts"
|
|
4518
|
+
}
|
|
4519
|
+
},
|
|
4520
|
+
async run({ args }) {
|
|
4521
|
+
const ownerAuth = loadAuth();
|
|
4522
|
+
if (!ownerAuth?.access_token) {
|
|
4523
|
+
throw new CliError("Run `apes login <email>` first.");
|
|
4524
|
+
}
|
|
4525
|
+
const idp = getIdpUrl();
|
|
4526
|
+
if (!idp) throw new CliError("No IdP configured.");
|
|
4527
|
+
const email = args.email;
|
|
4528
|
+
const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`;
|
|
4529
|
+
const res = await fetch(url, {
|
|
4530
|
+
headers: { Authorization: `Bearer ${ownerAuth.access_token}` }
|
|
4531
|
+
});
|
|
4532
|
+
if (!res.ok) {
|
|
4533
|
+
const text = await res.text().catch(() => "");
|
|
4534
|
+
throw new CliError(`GET /yolo-policy failed (${res.status}): ${text}`);
|
|
4535
|
+
}
|
|
4536
|
+
const policy = await res.json();
|
|
4537
|
+
if (args.json) {
|
|
4538
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
4539
|
+
return;
|
|
4540
|
+
}
|
|
4541
|
+
consola32.info(`YOLO-policy for ${email}`);
|
|
4542
|
+
consola32.info(` mode: ${policy.mode}`);
|
|
4543
|
+
consola32.info(` allow_patterns: ${policy.allowPatterns.length ? policy.allowPatterns.join(", ") : "(none)"}`);
|
|
4544
|
+
consola32.info(` deny_patterns: ${policy.denyPatterns.length ? policy.denyPatterns.join(", ") : "(none)"}`);
|
|
4545
|
+
consola32.info(` deny_risk: ${policy.denyRiskThreshold ?? "(none)"}`);
|
|
4546
|
+
consola32.info(` expires_at: ${policy.expiresAt ? new Date(policy.expiresAt * 1e3).toISOString() : "(never)"}`);
|
|
4547
|
+
}
|
|
4548
|
+
});
|
|
4549
|
+
|
|
4550
|
+
// src/commands/yolo/index.ts
|
|
4551
|
+
var yoloCommand = defineCommand38({
|
|
4552
|
+
meta: {
|
|
4553
|
+
name: "yolo",
|
|
4554
|
+
description: "Manage YOLO-policies on DDISA agents you own \u2014 auto-approve grant patterns at the IdP layer (allow-list) or block dangerous ones outright (deny-list)."
|
|
4555
|
+
},
|
|
4556
|
+
subCommands: {
|
|
4557
|
+
set: yoloSetCommand,
|
|
4558
|
+
show: yoloShowCommand,
|
|
4559
|
+
clear: yoloClearCommand
|
|
4560
|
+
}
|
|
4561
|
+
});
|
|
4562
|
+
|
|
4563
|
+
// src/commands/adapter/index.ts
|
|
4564
|
+
import { defineCommand as defineCommand39 } from "citty";
|
|
4565
|
+
import consola33 from "consola";
|
|
4566
|
+
var adapterCommand = defineCommand39({
|
|
4397
4567
|
meta: {
|
|
4398
4568
|
name: "adapter",
|
|
4399
4569
|
description: "Manage CLI adapters"
|
|
4400
4570
|
},
|
|
4401
4571
|
subCommands: {
|
|
4402
|
-
list:
|
|
4572
|
+
list: defineCommand39({
|
|
4403
4573
|
meta: {
|
|
4404
4574
|
name: "list",
|
|
4405
4575
|
description: "List available adapters"
|
|
@@ -4430,7 +4600,7 @@ var adapterCommand = defineCommand35({
|
|
|
4430
4600
|
`);
|
|
4431
4601
|
return;
|
|
4432
4602
|
}
|
|
4433
|
-
|
|
4603
|
+
consola33.info(`Registry: ${index2.adapters.length} adapters (${index2.generated_at})`);
|
|
4434
4604
|
for (const a of index2.adapters) {
|
|
4435
4605
|
const installed = isInstalled(a.id, false) ? " [installed]" : "";
|
|
4436
4606
|
console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}${installed}`);
|
|
@@ -4452,7 +4622,7 @@ var adapterCommand = defineCommand35({
|
|
|
4452
4622
|
return;
|
|
4453
4623
|
}
|
|
4454
4624
|
if (local.length === 0) {
|
|
4455
|
-
|
|
4625
|
+
consola33.info("No adapters installed. Use `apes adapter list --remote` to see available adapters.");
|
|
4456
4626
|
return;
|
|
4457
4627
|
}
|
|
4458
4628
|
for (const a of local) {
|
|
@@ -4460,7 +4630,7 @@ var adapterCommand = defineCommand35({
|
|
|
4460
4630
|
}
|
|
4461
4631
|
}
|
|
4462
4632
|
}),
|
|
4463
|
-
install:
|
|
4633
|
+
install: defineCommand39({
|
|
4464
4634
|
meta: {
|
|
4465
4635
|
name: "install",
|
|
4466
4636
|
description: "Install an adapter from the registry"
|
|
@@ -4489,24 +4659,24 @@ var adapterCommand = defineCommand35({
|
|
|
4489
4659
|
for (const id of ids) {
|
|
4490
4660
|
const entry = findAdapter(index, id);
|
|
4491
4661
|
if (!entry) {
|
|
4492
|
-
|
|
4662
|
+
consola33.error(`Adapter "${id}" not found in registry. Use \`apes adapter search ${id}\` to search.`);
|
|
4493
4663
|
continue;
|
|
4494
4664
|
}
|
|
4495
4665
|
const conflicts = findConflictingAdapters(entry.executable, id);
|
|
4496
4666
|
if (conflicts.length > 0) {
|
|
4497
4667
|
for (const c of conflicts) {
|
|
4498
|
-
|
|
4499
|
-
|
|
4668
|
+
consola33.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`);
|
|
4669
|
+
consola33.warn(` Remove it with: apes adapter remove ${c.adapterId}`);
|
|
4500
4670
|
}
|
|
4501
4671
|
}
|
|
4502
4672
|
const result = await installAdapter(entry, { local });
|
|
4503
4673
|
const verb = result.updated ? "Updated" : "Installed";
|
|
4504
|
-
|
|
4505
|
-
|
|
4674
|
+
consola33.success(`${verb} ${result.id} \u2192 ${result.path}`);
|
|
4675
|
+
consola33.info(`Digest: ${result.digest}`);
|
|
4506
4676
|
}
|
|
4507
4677
|
}
|
|
4508
4678
|
}),
|
|
4509
|
-
remove:
|
|
4679
|
+
remove: defineCommand39({
|
|
4510
4680
|
meta: {
|
|
4511
4681
|
name: "remove",
|
|
4512
4682
|
description: "Remove an installed adapter"
|
|
@@ -4529,9 +4699,9 @@ var adapterCommand = defineCommand35({
|
|
|
4529
4699
|
let failed = false;
|
|
4530
4700
|
for (const id of ids) {
|
|
4531
4701
|
if (removeAdapter(id, local)) {
|
|
4532
|
-
|
|
4702
|
+
consola33.success(`Removed adapter: ${id}`);
|
|
4533
4703
|
} else {
|
|
4534
|
-
|
|
4704
|
+
consola33.error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
|
|
4535
4705
|
failed = true;
|
|
4536
4706
|
}
|
|
4537
4707
|
}
|
|
@@ -4539,7 +4709,7 @@ var adapterCommand = defineCommand35({
|
|
|
4539
4709
|
throw new CliError("Some adapters could not be removed");
|
|
4540
4710
|
}
|
|
4541
4711
|
}),
|
|
4542
|
-
info:
|
|
4712
|
+
info: defineCommand39({
|
|
4543
4713
|
meta: {
|
|
4544
4714
|
name: "info",
|
|
4545
4715
|
description: "Show detailed adapter information"
|
|
@@ -4581,7 +4751,7 @@ var adapterCommand = defineCommand35({
|
|
|
4581
4751
|
}
|
|
4582
4752
|
}
|
|
4583
4753
|
}),
|
|
4584
|
-
search:
|
|
4754
|
+
search: defineCommand39({
|
|
4585
4755
|
meta: {
|
|
4586
4756
|
name: "search",
|
|
4587
4757
|
description: "Search adapters in the registry"
|
|
@@ -4613,7 +4783,7 @@ var adapterCommand = defineCommand35({
|
|
|
4613
4783
|
return;
|
|
4614
4784
|
}
|
|
4615
4785
|
if (results.length === 0) {
|
|
4616
|
-
|
|
4786
|
+
consola33.info(`No adapters matching "${query}"`);
|
|
4617
4787
|
return;
|
|
4618
4788
|
}
|
|
4619
4789
|
for (const a of results) {
|
|
@@ -4622,7 +4792,7 @@ var adapterCommand = defineCommand35({
|
|
|
4622
4792
|
}
|
|
4623
4793
|
}
|
|
4624
4794
|
}),
|
|
4625
|
-
update:
|
|
4795
|
+
update: defineCommand39({
|
|
4626
4796
|
meta: {
|
|
4627
4797
|
name: "update",
|
|
4628
4798
|
description: "Update installed adapters"
|
|
@@ -4648,33 +4818,33 @@ var adapterCommand = defineCommand35({
|
|
|
4648
4818
|
const targetId = args.id ? String(args.id) : void 0;
|
|
4649
4819
|
const targets = targetId ? [targetId] : index.adapters.map((a) => a.id).filter((id) => isInstalled(id, false));
|
|
4650
4820
|
if (targets.length === 0) {
|
|
4651
|
-
|
|
4821
|
+
consola33.info("No adapters installed to update.");
|
|
4652
4822
|
return;
|
|
4653
4823
|
}
|
|
4654
4824
|
for (const id of targets) {
|
|
4655
4825
|
const entry = findAdapter(index, id);
|
|
4656
4826
|
if (!entry) {
|
|
4657
|
-
|
|
4827
|
+
consola33.warn(`${id}: not found in registry, skipping`);
|
|
4658
4828
|
continue;
|
|
4659
4829
|
}
|
|
4660
4830
|
const localDigest = getInstalledDigest(id, false);
|
|
4661
4831
|
if (localDigest === entry.digest) {
|
|
4662
|
-
|
|
4832
|
+
consola33.info(`${id}: already up to date`);
|
|
4663
4833
|
continue;
|
|
4664
4834
|
}
|
|
4665
4835
|
if (localDigest && !args.yes) {
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4836
|
+
consola33.warn(`${id}: digest will change \u2014 existing grants for this adapter will be invalidated`);
|
|
4837
|
+
consola33.info(` Old: ${localDigest}`);
|
|
4838
|
+
consola33.info(` New: ${entry.digest}`);
|
|
4839
|
+
consola33.info(" Use --yes to confirm");
|
|
4670
4840
|
continue;
|
|
4671
4841
|
}
|
|
4672
4842
|
const result = await installAdapter(entry);
|
|
4673
|
-
|
|
4843
|
+
consola33.success(`Updated ${result.id} \u2192 ${result.path}`);
|
|
4674
4844
|
}
|
|
4675
4845
|
}
|
|
4676
4846
|
}),
|
|
4677
|
-
verify:
|
|
4847
|
+
verify: defineCommand39({
|
|
4678
4848
|
meta: {
|
|
4679
4849
|
name: "verify",
|
|
4680
4850
|
description: "Verify installed adapter against registry digest"
|
|
@@ -4707,7 +4877,7 @@ var adapterCommand = defineCommand35({
|
|
|
4707
4877
|
if (!localDigest)
|
|
4708
4878
|
throw new Error(`Adapter "${id}" is not installed${local ? " locally" : ""}`);
|
|
4709
4879
|
if (localDigest === entry.digest) {
|
|
4710
|
-
|
|
4880
|
+
consola33.success(`${id}: digest matches registry`);
|
|
4711
4881
|
} else {
|
|
4712
4882
|
console.log(` Local: ${localDigest}`);
|
|
4713
4883
|
console.log(` Registry: ${entry.digest}`);
|
|
@@ -4719,11 +4889,11 @@ var adapterCommand = defineCommand35({
|
|
|
4719
4889
|
});
|
|
4720
4890
|
|
|
4721
4891
|
// src/commands/run.ts
|
|
4722
|
-
import { execFileSync as
|
|
4892
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
4723
4893
|
import { hostname as hostname5 } from "os";
|
|
4724
4894
|
import { basename } from "path";
|
|
4725
|
-
import { defineCommand as
|
|
4726
|
-
import
|
|
4895
|
+
import { defineCommand as defineCommand40 } from "citty";
|
|
4896
|
+
import consola34 from "consola";
|
|
4727
4897
|
function shouldWaitForGrant(args) {
|
|
4728
4898
|
return args.wait === true || process.env.APE_WAIT === "1";
|
|
4729
4899
|
}
|
|
@@ -4760,7 +4930,7 @@ function printPendingGrantInfo(grant, idp) {
|
|
|
4760
4930
|
const statusCmd = `apes grants status ${grant.id}`;
|
|
4761
4931
|
const executeCmd = `apes grants run ${grant.id}`;
|
|
4762
4932
|
if (mode === "human") {
|
|
4763
|
-
|
|
4933
|
+
consola34.success(`Grant ${grant.id} created \u2014 awaiting your approval`);
|
|
4764
4934
|
console.log(` Approve in browser: ${approveUrl}`);
|
|
4765
4935
|
console.log(` Check status: ${statusCmd}`);
|
|
4766
4936
|
console.log(` Run after approval: ${executeCmd}`);
|
|
@@ -4770,7 +4940,7 @@ function printPendingGrantInfo(grant, idp) {
|
|
|
4770
4940
|
return;
|
|
4771
4941
|
}
|
|
4772
4942
|
const maxMin = getPollMaxMinutes();
|
|
4773
|
-
|
|
4943
|
+
consola34.success(`Grant ${grant.id} created (pending approval)`);
|
|
4774
4944
|
console.log(` Approve: ${approveUrl}`);
|
|
4775
4945
|
console.log(` Status: ${statusCmd} [--json]`);
|
|
4776
4946
|
console.log(` Execute: ${executeCmd} --wait`);
|
|
@@ -4792,7 +4962,7 @@ function printPendingGrantInfo(grant, idp) {
|
|
|
4792
4962
|
console.log(' Tip: Approve as "timed" or "always" in the browser to let this');
|
|
4793
4963
|
console.log(" grant be reused on subsequent invocations without re-approval.");
|
|
4794
4964
|
}
|
|
4795
|
-
var runCommand =
|
|
4965
|
+
var runCommand = defineCommand40({
|
|
4796
4966
|
meta: {
|
|
4797
4967
|
name: "run",
|
|
4798
4968
|
description: "Execute a grant-secured command"
|
|
@@ -4895,7 +5065,7 @@ async function runShellMode(command, args) {
|
|
|
4895
5065
|
}
|
|
4896
5066
|
} catch {
|
|
4897
5067
|
}
|
|
4898
|
-
|
|
5068
|
+
consola34.info(`Requesting ape-shell session grant on ${targetHost}`);
|
|
4899
5069
|
const grant = await apiFetch(grantsUrl, {
|
|
4900
5070
|
method: "POST",
|
|
4901
5071
|
body: {
|
|
@@ -4915,8 +5085,8 @@ async function runShellMode(command, args) {
|
|
|
4915
5085
|
host: targetHost
|
|
4916
5086
|
});
|
|
4917
5087
|
if (shouldWaitForGrant(args)) {
|
|
4918
|
-
|
|
4919
|
-
|
|
5088
|
+
consola34.info(`Grant requested: ${grant.id}`);
|
|
5089
|
+
consola34.info("Waiting for approval...");
|
|
4920
5090
|
const maxWait = 3e5;
|
|
4921
5091
|
const interval = 3e3;
|
|
4922
5092
|
const start = Date.now();
|
|
@@ -4947,13 +5117,13 @@ async function tryAdapterModeFromShell(command, idp, args) {
|
|
|
4947
5117
|
try {
|
|
4948
5118
|
resolved = await resolveCommand(loaded, [normalizedExecutable, ...parsed.argv]);
|
|
4949
5119
|
} catch (err) {
|
|
4950
|
-
|
|
5120
|
+
consola34.debug(`ape-shell: adapter resolve failed for "${parsed.raw}":`, err);
|
|
4951
5121
|
return false;
|
|
4952
5122
|
}
|
|
4953
5123
|
try {
|
|
4954
5124
|
const existingGrantId = await findExistingGrant(resolved, idp);
|
|
4955
5125
|
if (existingGrantId) {
|
|
4956
|
-
|
|
5126
|
+
consola34.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`);
|
|
4957
5127
|
const token = await fetchGrantToken(idp, existingGrantId);
|
|
4958
5128
|
await verifyAndExecute(token, resolved, existingGrantId);
|
|
4959
5129
|
return true;
|
|
@@ -4961,7 +5131,7 @@ async function tryAdapterModeFromShell(command, idp, args) {
|
|
|
4961
5131
|
} catch {
|
|
4962
5132
|
}
|
|
4963
5133
|
const approval = args.approval ?? "once";
|
|
4964
|
-
|
|
5134
|
+
consola34.info(`Requesting grant for: ${resolved.detail.display}`);
|
|
4965
5135
|
const grant = await createShapesGrant(resolved, {
|
|
4966
5136
|
idp,
|
|
4967
5137
|
approval,
|
|
@@ -4969,8 +5139,8 @@ async function tryAdapterModeFromShell(command, idp, args) {
|
|
|
4969
5139
|
});
|
|
4970
5140
|
if (grant.similar_grants?.similar_grants?.length) {
|
|
4971
5141
|
const n = grant.similar_grants.similar_grants.length;
|
|
4972
|
-
|
|
4973
|
-
|
|
5142
|
+
consola34.info("");
|
|
5143
|
+
consola34.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
|
|
4974
5144
|
}
|
|
4975
5145
|
notifyGrantPending({
|
|
4976
5146
|
grantId: grant.id,
|
|
@@ -4980,8 +5150,8 @@ async function tryAdapterModeFromShell(command, idp, args) {
|
|
|
4980
5150
|
host: args.host || hostname5()
|
|
4981
5151
|
});
|
|
4982
5152
|
if (shouldWaitForGrant(args)) {
|
|
4983
|
-
|
|
4984
|
-
|
|
5153
|
+
consola34.info(`Grant requested: ${grant.id}`);
|
|
5154
|
+
consola34.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
4985
5155
|
const status = await waitForGrantStatus(idp, grant.id);
|
|
4986
5156
|
if (status !== "approved")
|
|
4987
5157
|
throw new CliError(`Grant ${status}`);
|
|
@@ -4997,7 +5167,7 @@ function execShellCommand(command) {
|
|
|
4997
5167
|
throw new CliError("No command to execute");
|
|
4998
5168
|
try {
|
|
4999
5169
|
const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
|
|
5000
|
-
|
|
5170
|
+
execFileSync12(command[0], command.slice(1), {
|
|
5001
5171
|
stdio: "inherit",
|
|
5002
5172
|
env: inheritedEnv
|
|
5003
5173
|
});
|
|
@@ -5055,7 +5225,7 @@ async function runAdapterMode(command, rawArgs, args) {
|
|
|
5055
5225
|
try {
|
|
5056
5226
|
const existingGrantId = await findExistingGrant(resolved, idp);
|
|
5057
5227
|
if (existingGrantId) {
|
|
5058
|
-
|
|
5228
|
+
consola34.info(`Reusing existing grant: ${existingGrantId}`);
|
|
5059
5229
|
const token = await fetchGrantToken(idp, existingGrantId);
|
|
5060
5230
|
await verifyAndExecute(token, resolved, existingGrantId);
|
|
5061
5231
|
return;
|
|
@@ -5069,17 +5239,17 @@ async function runAdapterMode(command, rawArgs, args) {
|
|
|
5069
5239
|
});
|
|
5070
5240
|
if (grant.similar_grants?.similar_grants?.length) {
|
|
5071
5241
|
const n = grant.similar_grants.similar_grants.length;
|
|
5072
|
-
|
|
5073
|
-
|
|
5242
|
+
consola34.info("");
|
|
5243
|
+
consola34.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`);
|
|
5074
5244
|
if (grant.similar_grants.widened_details?.length) {
|
|
5075
5245
|
const wider = grant.similar_grants.widened_details.map((d) => d.permission).join(", ");
|
|
5076
|
-
|
|
5246
|
+
consola34.info(` Broader scope: ${wider}`);
|
|
5077
5247
|
}
|
|
5078
|
-
|
|
5248
|
+
consola34.info("");
|
|
5079
5249
|
}
|
|
5080
5250
|
if (shouldWaitForGrant(args)) {
|
|
5081
|
-
|
|
5082
|
-
|
|
5251
|
+
consola34.info(`Grant requested: ${grant.id}`);
|
|
5252
|
+
consola34.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
5083
5253
|
const status = await waitForGrantStatus(idp, grant.id);
|
|
5084
5254
|
if (status !== "approved")
|
|
5085
5255
|
throw new Error(`Grant ${status}`);
|
|
@@ -5099,7 +5269,7 @@ async function runAudienceMode(audience, action, args) {
|
|
|
5099
5269
|
const grantsUrl = await getGrantsEndpoint(idp);
|
|
5100
5270
|
const command = action.split(" ");
|
|
5101
5271
|
const targetHost = args.host || hostname5();
|
|
5102
|
-
|
|
5272
|
+
consola34.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(" ")}`);
|
|
5103
5273
|
const grant = await apiFetch(grantsUrl, {
|
|
5104
5274
|
method: "POST",
|
|
5105
5275
|
body: {
|
|
@@ -5116,9 +5286,9 @@ async function runAudienceMode(audience, action, args) {
|
|
|
5116
5286
|
printPendingGrantInfo(grant, idp);
|
|
5117
5287
|
throw new CliExit(getAsyncExitCode());
|
|
5118
5288
|
}
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5289
|
+
consola34.success(`Grant requested: ${grant.id}`);
|
|
5290
|
+
consola34.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`);
|
|
5291
|
+
consola34.info("Waiting for approval...");
|
|
5122
5292
|
const maxWait = 15 * 60 * 1e3;
|
|
5123
5293
|
const interval = 3e3;
|
|
5124
5294
|
const start = Date.now();
|
|
@@ -5126,7 +5296,7 @@ async function runAudienceMode(audience, action, args) {
|
|
|
5126
5296
|
while (Date.now() - start < maxWait) {
|
|
5127
5297
|
const status = await apiFetch(`${grantsUrl}/${grant.id}`);
|
|
5128
5298
|
if (status.status === "approved") {
|
|
5129
|
-
|
|
5299
|
+
consola34.success("Grant approved!");
|
|
5130
5300
|
approved = true;
|
|
5131
5301
|
break;
|
|
5132
5302
|
}
|
|
@@ -5141,15 +5311,15 @@ async function runAudienceMode(audience, action, args) {
|
|
|
5141
5311
|
`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.`
|
|
5142
5312
|
);
|
|
5143
5313
|
}
|
|
5144
|
-
|
|
5314
|
+
consola34.info("Fetching grant token...");
|
|
5145
5315
|
const { authz_jwt } = await apiFetch(`${grantsUrl}/${grant.id}/token`, {
|
|
5146
5316
|
method: "POST"
|
|
5147
5317
|
});
|
|
5148
5318
|
if (audience === "escapes") {
|
|
5149
|
-
|
|
5319
|
+
consola34.info(`Executing: ${command.join(" ")}`);
|
|
5150
5320
|
try {
|
|
5151
5321
|
const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
|
|
5152
|
-
|
|
5322
|
+
execFileSync12(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
|
|
5153
5323
|
stdio: "inherit",
|
|
5154
5324
|
env: inheritedEnv
|
|
5155
5325
|
});
|
|
@@ -5164,8 +5334,8 @@ async function runAudienceMode(audience, action, args) {
|
|
|
5164
5334
|
|
|
5165
5335
|
// src/commands/proxy.ts
|
|
5166
5336
|
import { spawn as spawn2 } from "child_process";
|
|
5167
|
-
import { defineCommand as
|
|
5168
|
-
import
|
|
5337
|
+
import { defineCommand as defineCommand41 } from "citty";
|
|
5338
|
+
import consola35 from "consola";
|
|
5169
5339
|
|
|
5170
5340
|
// src/proxy/config.ts
|
|
5171
5341
|
function buildDefaultProxyConfigToml(opts) {
|
|
@@ -5308,10 +5478,10 @@ function resolveProxyConfigOptions() {
|
|
|
5308
5478
|
77
|
|
5309
5479
|
);
|
|
5310
5480
|
}
|
|
5311
|
-
|
|
5481
|
+
consola35.info(`[apes proxy] IdP-mediated mode \u2014 agent=${auth.email}, idp=${auth.idp}`);
|
|
5312
5482
|
return { agentEmail: auth.email, idpUrl: auth.idp, mediated: true };
|
|
5313
5483
|
}
|
|
5314
|
-
var proxyCommand =
|
|
5484
|
+
var proxyCommand = defineCommand41({
|
|
5315
5485
|
meta: {
|
|
5316
5486
|
name: "proxy",
|
|
5317
5487
|
description: "Run a command with HTTPS_PROXY routed through the OpenApe egress proxy."
|
|
@@ -5333,12 +5503,12 @@ var proxyCommand = defineCommand37({
|
|
|
5333
5503
|
let close = null;
|
|
5334
5504
|
if (reuseUrl) {
|
|
5335
5505
|
proxyUrl = reuseUrl;
|
|
5336
|
-
|
|
5506
|
+
consola35.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`);
|
|
5337
5507
|
} else {
|
|
5338
5508
|
const ephemeral = await startEphemeralProxy(buildDefaultProxyConfigToml(resolveProxyConfigOptions()));
|
|
5339
5509
|
proxyUrl = ephemeral.url;
|
|
5340
5510
|
close = ephemeral.close;
|
|
5341
|
-
|
|
5511
|
+
consola35.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`);
|
|
5342
5512
|
}
|
|
5343
5513
|
const noProxy = process.env.NO_PROXY ?? process.env.no_proxy ?? "127.0.0.1,localhost";
|
|
5344
5514
|
const childEnv = {
|
|
@@ -5370,7 +5540,7 @@ var proxyCommand = defineCommand37({
|
|
|
5370
5540
|
else resolveExit(code ?? 0);
|
|
5371
5541
|
});
|
|
5372
5542
|
child.once("error", (err) => {
|
|
5373
|
-
|
|
5543
|
+
consola35.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message);
|
|
5374
5544
|
resolveExit(127);
|
|
5375
5545
|
});
|
|
5376
5546
|
});
|
|
@@ -5384,8 +5554,8 @@ function signalNumber(signal) {
|
|
|
5384
5554
|
}
|
|
5385
5555
|
|
|
5386
5556
|
// src/commands/explain.ts
|
|
5387
|
-
import { defineCommand as
|
|
5388
|
-
var explainCommand =
|
|
5557
|
+
import { defineCommand as defineCommand42 } from "citty";
|
|
5558
|
+
var explainCommand = defineCommand42({
|
|
5389
5559
|
meta: {
|
|
5390
5560
|
name: "explain",
|
|
5391
5561
|
description: "Show what permission a command would need"
|
|
@@ -5423,9 +5593,9 @@ var explainCommand = defineCommand38({
|
|
|
5423
5593
|
});
|
|
5424
5594
|
|
|
5425
5595
|
// src/commands/config/get.ts
|
|
5426
|
-
import { defineCommand as
|
|
5427
|
-
import
|
|
5428
|
-
var configGetCommand =
|
|
5596
|
+
import { defineCommand as defineCommand43 } from "citty";
|
|
5597
|
+
import consola36 from "consola";
|
|
5598
|
+
var configGetCommand = defineCommand43({
|
|
5429
5599
|
meta: {
|
|
5430
5600
|
name: "get",
|
|
5431
5601
|
description: "Get a configuration value"
|
|
@@ -5445,7 +5615,7 @@ var configGetCommand = defineCommand39({
|
|
|
5445
5615
|
if (idp)
|
|
5446
5616
|
console.log(idp);
|
|
5447
5617
|
else
|
|
5448
|
-
|
|
5618
|
+
consola36.info("No IdP configured.");
|
|
5449
5619
|
break;
|
|
5450
5620
|
}
|
|
5451
5621
|
case "email": {
|
|
@@ -5453,7 +5623,7 @@ var configGetCommand = defineCommand39({
|
|
|
5453
5623
|
if (auth?.email)
|
|
5454
5624
|
console.log(auth.email);
|
|
5455
5625
|
else
|
|
5456
|
-
|
|
5626
|
+
consola36.info("Not logged in.");
|
|
5457
5627
|
break;
|
|
5458
5628
|
}
|
|
5459
5629
|
default: {
|
|
@@ -5466,7 +5636,7 @@ var configGetCommand = defineCommand39({
|
|
|
5466
5636
|
if (sectionObj && field in sectionObj) {
|
|
5467
5637
|
console.log(sectionObj[field]);
|
|
5468
5638
|
} else {
|
|
5469
|
-
|
|
5639
|
+
consola36.info(`Key "${key}" not set.`);
|
|
5470
5640
|
}
|
|
5471
5641
|
} else {
|
|
5472
5642
|
throw new CliError(`Unknown key: "${key}". Use: idp, email, defaults.idp, defaults.approval, agent.key, agent.email`);
|
|
@@ -5477,9 +5647,9 @@ var configGetCommand = defineCommand39({
|
|
|
5477
5647
|
});
|
|
5478
5648
|
|
|
5479
5649
|
// src/commands/config/set.ts
|
|
5480
|
-
import { defineCommand as
|
|
5481
|
-
import
|
|
5482
|
-
var configSetCommand =
|
|
5650
|
+
import { defineCommand as defineCommand44 } from "citty";
|
|
5651
|
+
import consola37 from "consola";
|
|
5652
|
+
var configSetCommand = defineCommand44({
|
|
5483
5653
|
meta: {
|
|
5484
5654
|
name: "set",
|
|
5485
5655
|
description: "Set a configuration value"
|
|
@@ -5515,12 +5685,12 @@ var configSetCommand = defineCommand40({
|
|
|
5515
5685
|
throw new CliError(`Unknown section: "${section}". Use: defaults, agent`);
|
|
5516
5686
|
}
|
|
5517
5687
|
saveConfig(config);
|
|
5518
|
-
|
|
5688
|
+
consola37.success(`Set ${key} = ${value}`);
|
|
5519
5689
|
}
|
|
5520
5690
|
});
|
|
5521
5691
|
|
|
5522
5692
|
// src/commands/fetch/index.ts
|
|
5523
|
-
import { defineCommand as
|
|
5693
|
+
import { defineCommand as defineCommand45 } from "citty";
|
|
5524
5694
|
async function doRequest(method, url, body, contentType, raw, showHeaders) {
|
|
5525
5695
|
const token = getAuthToken();
|
|
5526
5696
|
if (!token) {
|
|
@@ -5556,13 +5726,13 @@ async function doRequest(method, url, body, contentType, raw, showHeaders) {
|
|
|
5556
5726
|
throw new CliError(`HTTP ${response.status} ${response.statusText}`);
|
|
5557
5727
|
}
|
|
5558
5728
|
}
|
|
5559
|
-
var fetchCommand =
|
|
5729
|
+
var fetchCommand = defineCommand45({
|
|
5560
5730
|
meta: {
|
|
5561
5731
|
name: "fetch",
|
|
5562
5732
|
description: "Make authenticated HTTP requests"
|
|
5563
5733
|
},
|
|
5564
5734
|
subCommands: {
|
|
5565
|
-
get:
|
|
5735
|
+
get: defineCommand45({
|
|
5566
5736
|
meta: {
|
|
5567
5737
|
name: "get",
|
|
5568
5738
|
description: "GET request with auth token"
|
|
@@ -5588,7 +5758,7 @@ var fetchCommand = defineCommand41({
|
|
|
5588
5758
|
await doRequest("GET", String(args.url), void 0, "application/json", Boolean(args.raw), Boolean(args.headers));
|
|
5589
5759
|
}
|
|
5590
5760
|
}),
|
|
5591
|
-
post:
|
|
5761
|
+
post: defineCommand45({
|
|
5592
5762
|
meta: {
|
|
5593
5763
|
name: "post",
|
|
5594
5764
|
description: "POST request with auth token"
|
|
@@ -5627,8 +5797,8 @@ var fetchCommand = defineCommand41({
|
|
|
5627
5797
|
});
|
|
5628
5798
|
|
|
5629
5799
|
// src/commands/mcp/index.ts
|
|
5630
|
-
import { defineCommand as
|
|
5631
|
-
var mcpCommand =
|
|
5800
|
+
import { defineCommand as defineCommand46 } from "citty";
|
|
5801
|
+
var mcpCommand = defineCommand46({
|
|
5632
5802
|
meta: {
|
|
5633
5803
|
name: "mcp",
|
|
5634
5804
|
description: "Start MCP server for AI agents"
|
|
@@ -5651,7 +5821,7 @@ var mcpCommand = defineCommand42({
|
|
|
5651
5821
|
if (transport !== "stdio" && transport !== "sse") {
|
|
5652
5822
|
throw new Error('Transport must be "stdio" or "sse"');
|
|
5653
5823
|
}
|
|
5654
|
-
const { startMcpServer } = await import("./server-
|
|
5824
|
+
const { startMcpServer } = await import("./server-BSBIEKFK.js");
|
|
5655
5825
|
await startMcpServer(transport, port);
|
|
5656
5826
|
}
|
|
5657
5827
|
});
|
|
@@ -5659,10 +5829,10 @@ var mcpCommand = defineCommand42({
|
|
|
5659
5829
|
// src/commands/init/index.ts
|
|
5660
5830
|
import { existsSync as existsSync14, copyFileSync, writeFileSync as writeFileSync9 } from "fs";
|
|
5661
5831
|
import { randomBytes } from "crypto";
|
|
5662
|
-
import { execFileSync as
|
|
5832
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
5663
5833
|
import { join as join13 } from "path";
|
|
5664
|
-
import { defineCommand as
|
|
5665
|
-
import
|
|
5834
|
+
import { defineCommand as defineCommand47 } from "citty";
|
|
5835
|
+
import consola38 from "consola";
|
|
5666
5836
|
var DEFAULT_IDP_URL = "https://id.openape.at";
|
|
5667
5837
|
async function downloadTemplate(repo, targetDir) {
|
|
5668
5838
|
const { downloadTemplate: gigetDownload } = await import("giget");
|
|
@@ -5671,28 +5841,28 @@ async function downloadTemplate(repo, targetDir) {
|
|
|
5671
5841
|
function installDeps(dir) {
|
|
5672
5842
|
const hasLockFile = (name) => existsSync14(join13(dir, name));
|
|
5673
5843
|
if (hasLockFile("pnpm-lock.yaml")) {
|
|
5674
|
-
|
|
5844
|
+
execFileSync13("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
5675
5845
|
} else if (hasLockFile("bun.lockb")) {
|
|
5676
|
-
|
|
5846
|
+
execFileSync13("bun", ["install"], { cwd: dir, stdio: "inherit" });
|
|
5677
5847
|
} else {
|
|
5678
|
-
|
|
5848
|
+
execFileSync13("npm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
5679
5849
|
}
|
|
5680
5850
|
}
|
|
5681
5851
|
async function promptChoice(message, choices) {
|
|
5682
|
-
const result = await
|
|
5852
|
+
const result = await consola38.prompt(message, { type: "select", options: choices });
|
|
5683
5853
|
if (typeof result === "symbol") {
|
|
5684
5854
|
throw new CliExit(0);
|
|
5685
5855
|
}
|
|
5686
5856
|
return result;
|
|
5687
5857
|
}
|
|
5688
5858
|
async function promptText(message, defaultValue) {
|
|
5689
|
-
const result = await
|
|
5859
|
+
const result = await consola38.prompt(message, { type: "text", default: defaultValue, placeholder: defaultValue });
|
|
5690
5860
|
if (typeof result === "symbol") {
|
|
5691
5861
|
throw new CliExit(0);
|
|
5692
5862
|
}
|
|
5693
5863
|
return result || defaultValue || "";
|
|
5694
5864
|
}
|
|
5695
|
-
var initCommand =
|
|
5865
|
+
var initCommand = defineCommand47({
|
|
5696
5866
|
meta: {
|
|
5697
5867
|
name: "init",
|
|
5698
5868
|
description: "Scaffold a new OpenApe project"
|
|
@@ -5737,20 +5907,20 @@ async function initSP(targetDir) {
|
|
|
5737
5907
|
if (existsSync14(join13(dir, "package.json"))) {
|
|
5738
5908
|
throw new CliError(`Directory "${dir}" already contains a project.`);
|
|
5739
5909
|
}
|
|
5740
|
-
|
|
5910
|
+
consola38.start("Scaffolding SP starter...");
|
|
5741
5911
|
await downloadTemplate("openape-ai/openape-sp-starter", dir);
|
|
5742
|
-
|
|
5743
|
-
|
|
5912
|
+
consola38.success("Scaffolded from openape-sp-starter");
|
|
5913
|
+
consola38.start("Installing dependencies...");
|
|
5744
5914
|
installDeps(dir);
|
|
5745
|
-
|
|
5915
|
+
consola38.success("Dependencies installed");
|
|
5746
5916
|
const envExample = join13(dir, ".env.example");
|
|
5747
5917
|
const envFile = join13(dir, ".env");
|
|
5748
5918
|
if (existsSync14(envExample) && !existsSync14(envFile)) {
|
|
5749
5919
|
copyFileSync(envExample, envFile);
|
|
5750
|
-
|
|
5920
|
+
consola38.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
|
|
5751
5921
|
}
|
|
5752
5922
|
console.log("");
|
|
5753
|
-
|
|
5923
|
+
consola38.box([
|
|
5754
5924
|
`cd ${dir}`,
|
|
5755
5925
|
"npm run dev",
|
|
5756
5926
|
"",
|
|
@@ -5769,15 +5939,15 @@ async function initIdP(targetDir) {
|
|
|
5769
5939
|
"s3 (S3-compatible)"
|
|
5770
5940
|
]);
|
|
5771
5941
|
const adminEmail = await promptText("Admin email");
|
|
5772
|
-
|
|
5942
|
+
consola38.start("Scaffolding IdP starter...");
|
|
5773
5943
|
await downloadTemplate("openape-ai/openape-idp-starter", dir);
|
|
5774
|
-
|
|
5775
|
-
|
|
5944
|
+
consola38.success("Scaffolded from openape-idp-starter");
|
|
5945
|
+
consola38.start("Installing dependencies...");
|
|
5776
5946
|
installDeps(dir);
|
|
5777
|
-
|
|
5947
|
+
consola38.success("Dependencies installed");
|
|
5778
5948
|
const sessionSecret = randomBytes(32).toString("hex");
|
|
5779
5949
|
const managementToken = randomBytes(32).toString("hex");
|
|
5780
|
-
|
|
5950
|
+
consola38.success("Secrets generated");
|
|
5781
5951
|
const isLocalhost = domain === "localhost";
|
|
5782
5952
|
const origin = isLocalhost ? "http://localhost:3000" : `https://${domain}`;
|
|
5783
5953
|
const envContent = [
|
|
@@ -5793,9 +5963,9 @@ async function initIdP(targetDir) {
|
|
|
5793
5963
|
].join("\n");
|
|
5794
5964
|
writeFileSync9(join13(dir, ".env"), `${envContent}
|
|
5795
5965
|
`, { mode: 384 });
|
|
5796
|
-
|
|
5966
|
+
consola38.success(".env created");
|
|
5797
5967
|
console.log("");
|
|
5798
|
-
|
|
5968
|
+
consola38.box([
|
|
5799
5969
|
`cd ${dir}`,
|
|
5800
5970
|
"npm run dev",
|
|
5801
5971
|
"",
|
|
@@ -5815,8 +5985,8 @@ import { Buffer as Buffer5 } from "buffer";
|
|
|
5815
5985
|
import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
|
|
5816
5986
|
import { execFile as execFile2 } from "child_process";
|
|
5817
5987
|
import { sign as sign2 } from "crypto";
|
|
5818
|
-
import { defineCommand as
|
|
5819
|
-
import
|
|
5988
|
+
import { defineCommand as defineCommand48 } from "citty";
|
|
5989
|
+
import consola39 from "consola";
|
|
5820
5990
|
var DEFAULT_IDP_URL2 = "https://id.openape.at";
|
|
5821
5991
|
var DEFAULT_KEY_PATH = "~/.ssh/id_ed25519";
|
|
5822
5992
|
var POLL_INTERVAL = 3e3;
|
|
@@ -5859,7 +6029,7 @@ async function pollForEnrollment(idp, agentEmail, keyPath) {
|
|
|
5859
6029
|
}
|
|
5860
6030
|
throw new Error("Enrollment timed out. Please check the browser and try again.");
|
|
5861
6031
|
}
|
|
5862
|
-
var enrollCommand =
|
|
6032
|
+
var enrollCommand = defineCommand48({
|
|
5863
6033
|
meta: {
|
|
5864
6034
|
name: "enroll",
|
|
5865
6035
|
description: "Enroll an agent with an Identity Provider"
|
|
@@ -5879,18 +6049,18 @@ var enrollCommand = defineCommand44({
|
|
|
5879
6049
|
}
|
|
5880
6050
|
},
|
|
5881
6051
|
async run({ args }) {
|
|
5882
|
-
const idp = args.idp || await
|
|
6052
|
+
const idp = args.idp || await consola39.prompt("IdP URL", { type: "text", default: DEFAULT_IDP_URL2, placeholder: DEFAULT_IDP_URL2 }).then((r) => {
|
|
5883
6053
|
if (typeof r === "symbol") throw new CliExit(0);
|
|
5884
6054
|
return r;
|
|
5885
6055
|
}) || DEFAULT_IDP_URL2;
|
|
5886
|
-
const agentName = args.name || await
|
|
6056
|
+
const agentName = args.name || await consola39.prompt("Agent name", { type: "text", placeholder: "deploy-bot" }).then((r) => {
|
|
5887
6057
|
if (typeof r === "symbol") throw new CliExit(0);
|
|
5888
6058
|
return r;
|
|
5889
6059
|
});
|
|
5890
6060
|
if (!agentName) {
|
|
5891
6061
|
throw new CliError("Agent name is required.");
|
|
5892
6062
|
}
|
|
5893
|
-
const keyPath = args.key || await
|
|
6063
|
+
const keyPath = args.key || await consola39.prompt("Ed25519 key", { type: "text", default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => {
|
|
5894
6064
|
if (typeof r === "symbol") throw new CliExit(0);
|
|
5895
6065
|
return r;
|
|
5896
6066
|
}) || DEFAULT_KEY_PATH;
|
|
@@ -5898,19 +6068,19 @@ var enrollCommand = defineCommand44({
|
|
|
5898
6068
|
let publicKey;
|
|
5899
6069
|
if (existsSync15(resolvedKey)) {
|
|
5900
6070
|
publicKey = readPublicKey(resolvedKey);
|
|
5901
|
-
|
|
6071
|
+
consola39.success(`Using existing key ${keyPath}`);
|
|
5902
6072
|
} else {
|
|
5903
|
-
|
|
6073
|
+
consola39.start(`Generating Ed25519 key pair at ${keyPath}...`);
|
|
5904
6074
|
publicKey = generateAndSaveKey(keyPath);
|
|
5905
|
-
|
|
6075
|
+
consola39.success(`Key pair generated at ${keyPath}`);
|
|
5906
6076
|
}
|
|
5907
6077
|
const encodedKey = encodeURIComponent(publicKey);
|
|
5908
6078
|
const enrollUrl = `${idp}/enroll?name=${encodeURIComponent(agentName)}&key=${encodedKey}`;
|
|
5909
|
-
|
|
5910
|
-
|
|
6079
|
+
consola39.info("Opening browser for enrollment...");
|
|
6080
|
+
consola39.info(`\u2192 ${idp}/enroll`);
|
|
5911
6081
|
openBrowser2(enrollUrl);
|
|
5912
6082
|
console.log("");
|
|
5913
|
-
const agentEmail = await
|
|
6083
|
+
const agentEmail = await consola39.prompt(
|
|
5914
6084
|
"Agent email (shown in browser after enrollment)",
|
|
5915
6085
|
{ type: "text", placeholder: `agent+${agentName}@...` }
|
|
5916
6086
|
).then((r) => {
|
|
@@ -5920,7 +6090,7 @@ var enrollCommand = defineCommand44({
|
|
|
5920
6090
|
if (!agentEmail) {
|
|
5921
6091
|
throw new CliError("Agent email is required to verify enrollment.");
|
|
5922
6092
|
}
|
|
5923
|
-
|
|
6093
|
+
consola39.start("Verifying enrollment...");
|
|
5924
6094
|
const { token, expiresIn } = await pollForEnrollment(idp, agentEmail, keyPath);
|
|
5925
6095
|
saveAuth({
|
|
5926
6096
|
idp,
|
|
@@ -5932,18 +6102,18 @@ var enrollCommand = defineCommand44({
|
|
|
5932
6102
|
config.defaults = { ...config.defaults, idp };
|
|
5933
6103
|
config.agent = { key: keyPath, email: agentEmail };
|
|
5934
6104
|
saveConfig(config);
|
|
5935
|
-
|
|
5936
|
-
|
|
6105
|
+
consola39.success(`Agent enrolled as ${agentEmail}`);
|
|
6106
|
+
consola39.success("Config saved to ~/.config/apes/");
|
|
5937
6107
|
console.log("");
|
|
5938
|
-
|
|
6108
|
+
consola39.info("Verify with: apes whoami");
|
|
5939
6109
|
}
|
|
5940
6110
|
});
|
|
5941
6111
|
|
|
5942
6112
|
// src/commands/register-user.ts
|
|
5943
6113
|
import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
|
|
5944
|
-
import { defineCommand as
|
|
5945
|
-
import
|
|
5946
|
-
var registerUserCommand =
|
|
6114
|
+
import { defineCommand as defineCommand49 } from "citty";
|
|
6115
|
+
import consola40 from "consola";
|
|
6116
|
+
var registerUserCommand = defineCommand49({
|
|
5947
6117
|
meta: {
|
|
5948
6118
|
name: "register-user",
|
|
5949
6119
|
description: "Register a sub-user with SSH key"
|
|
@@ -5998,18 +6168,18 @@ var registerUserCommand = defineCommand45({
|
|
|
5998
6168
|
...userType ? { type: userType } : {}
|
|
5999
6169
|
}
|
|
6000
6170
|
});
|
|
6001
|
-
|
|
6171
|
+
consola40.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`);
|
|
6002
6172
|
}
|
|
6003
6173
|
});
|
|
6004
6174
|
|
|
6005
6175
|
// src/commands/utils/index.ts
|
|
6006
|
-
import { defineCommand as
|
|
6176
|
+
import { defineCommand as defineCommand51 } from "citty";
|
|
6007
6177
|
|
|
6008
6178
|
// src/commands/utils/dig.ts
|
|
6009
|
-
import { defineCommand as
|
|
6010
|
-
import
|
|
6179
|
+
import { defineCommand as defineCommand50 } from "citty";
|
|
6180
|
+
import consola41 from "consola";
|
|
6011
6181
|
import { resolveDDISA as resolveDDISA2 } from "@openape/core";
|
|
6012
|
-
var digCommand =
|
|
6182
|
+
var digCommand = defineCommand50({
|
|
6013
6183
|
meta: {
|
|
6014
6184
|
name: "dig",
|
|
6015
6185
|
description: "Resolve DDISA IdP for a domain or email (admin/diag tool)"
|
|
@@ -6082,12 +6252,12 @@ var digCommand = defineCommand46({
|
|
|
6082
6252
|
console.log(` domain: ${domain}`);
|
|
6083
6253
|
console.log("");
|
|
6084
6254
|
if (!result.ddisa.found) {
|
|
6085
|
-
|
|
6255
|
+
consola41.warn(`No DDISA record at _ddisa.${domain}`);
|
|
6086
6256
|
if (result.hint) console.log(`
|
|
6087
6257
|
${result.hint}`);
|
|
6088
6258
|
throw new CliError(`No DDISA record found for ${domain}`);
|
|
6089
6259
|
}
|
|
6090
|
-
|
|
6260
|
+
consola41.success(`_ddisa.${domain} \u2192 ${result.ddisa.idp}`);
|
|
6091
6261
|
console.log(` Version: ${result.ddisa.version || "ddisa1"}`);
|
|
6092
6262
|
console.log(` IdP URL: ${result.ddisa.idp}`);
|
|
6093
6263
|
if (result.ddisa.mode) console.log(` Mode: ${result.ddisa.mode}`);
|
|
@@ -6097,13 +6267,13 @@ ${result.hint}`);
|
|
|
6097
6267
|
return;
|
|
6098
6268
|
}
|
|
6099
6269
|
if (result.idpDiscovery.ok) {
|
|
6100
|
-
|
|
6270
|
+
consola41.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`);
|
|
6101
6271
|
if (result.idpDiscovery.issuer) console.log(` Issuer: ${result.idpDiscovery.issuer}`);
|
|
6102
6272
|
if (result.idpDiscovery.ddisaVersion) console.log(` DDISA: v${result.idpDiscovery.ddisaVersion}`);
|
|
6103
6273
|
if (result.idpDiscovery.authMethods?.length) console.log(` Auth: ${result.idpDiscovery.authMethods.join(", ")}`);
|
|
6104
6274
|
if (result.idpDiscovery.grantTypes?.length) console.log(` Grants: ${result.idpDiscovery.grantTypes.join(", ")}`);
|
|
6105
6275
|
} else {
|
|
6106
|
-
|
|
6276
|
+
consola41.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ""}`);
|
|
6107
6277
|
if (result.hint) console.log(`
|
|
6108
6278
|
${result.hint}`);
|
|
6109
6279
|
throw new CliError(`IdP at ${result.ddisa.idp} not reachable`);
|
|
@@ -6112,7 +6282,7 @@ ${result.hint}`);
|
|
|
6112
6282
|
});
|
|
6113
6283
|
|
|
6114
6284
|
// src/commands/utils/index.ts
|
|
6115
|
-
var utilsCommand =
|
|
6285
|
+
var utilsCommand = defineCommand51({
|
|
6116
6286
|
meta: {
|
|
6117
6287
|
name: "utils",
|
|
6118
6288
|
description: "Admin/diagnostic utilities (dig, \u2026)"
|
|
@@ -6123,12 +6293,12 @@ var utilsCommand = defineCommand47({
|
|
|
6123
6293
|
});
|
|
6124
6294
|
|
|
6125
6295
|
// src/commands/sessions/index.ts
|
|
6126
|
-
import { defineCommand as
|
|
6296
|
+
import { defineCommand as defineCommand54 } from "citty";
|
|
6127
6297
|
|
|
6128
6298
|
// src/commands/sessions/list.ts
|
|
6129
|
-
import { defineCommand as
|
|
6130
|
-
import
|
|
6131
|
-
var sessionsListCommand =
|
|
6299
|
+
import { defineCommand as defineCommand52 } from "citty";
|
|
6300
|
+
import consola42 from "consola";
|
|
6301
|
+
var sessionsListCommand = defineCommand52({
|
|
6132
6302
|
meta: {
|
|
6133
6303
|
name: "list",
|
|
6134
6304
|
description: "List your active refresh-token families (one per logged-in device)."
|
|
@@ -6146,7 +6316,7 @@ var sessionsListCommand = defineCommand48({
|
|
|
6146
6316
|
return;
|
|
6147
6317
|
}
|
|
6148
6318
|
if (result.data.length === 0) {
|
|
6149
|
-
|
|
6319
|
+
consola42.info("No active sessions.");
|
|
6150
6320
|
return;
|
|
6151
6321
|
}
|
|
6152
6322
|
for (const f of result.data) {
|
|
@@ -6158,9 +6328,9 @@ var sessionsListCommand = defineCommand48({
|
|
|
6158
6328
|
});
|
|
6159
6329
|
|
|
6160
6330
|
// src/commands/sessions/remove.ts
|
|
6161
|
-
import { defineCommand as
|
|
6162
|
-
import
|
|
6163
|
-
var sessionsRemoveCommand =
|
|
6331
|
+
import { defineCommand as defineCommand53 } from "citty";
|
|
6332
|
+
import consola43 from "consola";
|
|
6333
|
+
var sessionsRemoveCommand = defineCommand53({
|
|
6164
6334
|
meta: {
|
|
6165
6335
|
name: "remove",
|
|
6166
6336
|
description: "Revoke one of your active refresh-token families by id."
|
|
@@ -6176,12 +6346,12 @@ var sessionsRemoveCommand = defineCommand49({
|
|
|
6176
6346
|
const id = String(args.familyId).trim();
|
|
6177
6347
|
if (!id) throw new CliError("familyId required");
|
|
6178
6348
|
await apiFetch(`/api/me/sessions/${encodeURIComponent(id)}`, { method: "DELETE" });
|
|
6179
|
-
|
|
6349
|
+
consola43.success(`Session ${id} revoked. The device using it will need to \`apes login\` again on its next refresh.`);
|
|
6180
6350
|
}
|
|
6181
6351
|
});
|
|
6182
6352
|
|
|
6183
6353
|
// src/commands/sessions/index.ts
|
|
6184
|
-
var sessionsCommand =
|
|
6354
|
+
var sessionsCommand = defineCommand54({
|
|
6185
6355
|
meta: {
|
|
6186
6356
|
name: "sessions",
|
|
6187
6357
|
description: "Manage your active refresh-token sessions across devices"
|
|
@@ -6193,10 +6363,10 @@ var sessionsCommand = defineCommand50({
|
|
|
6193
6363
|
});
|
|
6194
6364
|
|
|
6195
6365
|
// src/commands/dns-check.ts
|
|
6196
|
-
import { defineCommand as
|
|
6197
|
-
import
|
|
6366
|
+
import { defineCommand as defineCommand55 } from "citty";
|
|
6367
|
+
import consola44 from "consola";
|
|
6198
6368
|
import { resolveDDISA as resolveDDISA3 } from "@openape/core";
|
|
6199
|
-
var dnsCheckCommand =
|
|
6369
|
+
var dnsCheckCommand = defineCommand55({
|
|
6200
6370
|
meta: {
|
|
6201
6371
|
name: "dns-check",
|
|
6202
6372
|
description: "Validate DDISA DNS TXT records for a domain"
|
|
@@ -6210,7 +6380,7 @@ var dnsCheckCommand = defineCommand51({
|
|
|
6210
6380
|
},
|
|
6211
6381
|
async run({ args }) {
|
|
6212
6382
|
const domain = args.domain;
|
|
6213
|
-
|
|
6383
|
+
consola44.start(`Checking _ddisa.${domain}...`);
|
|
6214
6384
|
try {
|
|
6215
6385
|
const result = await resolveDDISA3(domain);
|
|
6216
6386
|
if (!result) {
|
|
@@ -6219,7 +6389,7 @@ var dnsCheckCommand = defineCommand51({
|
|
|
6219
6389
|
console.log(` _ddisa.${domain} TXT "v=ddisa1 idp=https://id.${domain}"`);
|
|
6220
6390
|
throw new CliError(`No DDISA record found for ${domain}`);
|
|
6221
6391
|
}
|
|
6222
|
-
|
|
6392
|
+
consola44.success(`_ddisa.${domain} \u2192 ${result.idp}`);
|
|
6223
6393
|
console.log("");
|
|
6224
6394
|
console.log(` Version: ${result.version || "ddisa1"}`);
|
|
6225
6395
|
console.log(` IdP URL: ${result.idp}`);
|
|
@@ -6228,14 +6398,14 @@ var dnsCheckCommand = defineCommand51({
|
|
|
6228
6398
|
if (result.priority !== void 0)
|
|
6229
6399
|
console.log(` Priority: ${result.priority}`);
|
|
6230
6400
|
console.log("");
|
|
6231
|
-
|
|
6401
|
+
consola44.start(`Verifying IdP at ${result.idp}...`);
|
|
6232
6402
|
const discoResp = await fetch(`${result.idp}/.well-known/openid-configuration`);
|
|
6233
6403
|
if (!discoResp.ok) {
|
|
6234
|
-
|
|
6404
|
+
consola44.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`);
|
|
6235
6405
|
return;
|
|
6236
6406
|
}
|
|
6237
6407
|
const disco = await discoResp.json();
|
|
6238
|
-
|
|
6408
|
+
consola44.success(`IdP is reachable`);
|
|
6239
6409
|
console.log(` Issuer: ${disco.issuer}`);
|
|
6240
6410
|
console.log(` DDISA: v${disco.ddisa_version || "?"}`);
|
|
6241
6411
|
if (disco.ddisa_auth_methods_supported) {
|
|
@@ -6253,7 +6423,7 @@ var dnsCheckCommand = defineCommand51({
|
|
|
6253
6423
|
// src/commands/health.ts
|
|
6254
6424
|
import { exec } from "child_process";
|
|
6255
6425
|
import { promisify } from "util";
|
|
6256
|
-
import { defineCommand as
|
|
6426
|
+
import { defineCommand as defineCommand56 } from "citty";
|
|
6257
6427
|
var execAsync = promisify(exec);
|
|
6258
6428
|
async function resolveApeShellPath() {
|
|
6259
6429
|
try {
|
|
@@ -6289,7 +6459,7 @@ async function bestEffortGrantCount(idp) {
|
|
|
6289
6459
|
}
|
|
6290
6460
|
}
|
|
6291
6461
|
async function runHealth(args) {
|
|
6292
|
-
const version = true ? "1.
|
|
6462
|
+
const version = true ? "1.7.0" : "0.0.0";
|
|
6293
6463
|
const auth = loadAuth();
|
|
6294
6464
|
if (!auth) {
|
|
6295
6465
|
throw new CliError("Not logged in. Run `apes login` first.", 1);
|
|
@@ -6352,7 +6522,7 @@ async function runHealth(args) {
|
|
|
6352
6522
|
throw new CliError(`IdP ${auth.idp} unreachable: ${idpProbe.error}`, 1);
|
|
6353
6523
|
}
|
|
6354
6524
|
}
|
|
6355
|
-
var healthCommand =
|
|
6525
|
+
var healthCommand = defineCommand56({
|
|
6356
6526
|
meta: {
|
|
6357
6527
|
name: "health",
|
|
6358
6528
|
description: "Report CLI diagnostic state (auth, IdP, grants, binaries)"
|
|
@@ -6370,8 +6540,8 @@ var healthCommand = defineCommand52({
|
|
|
6370
6540
|
});
|
|
6371
6541
|
|
|
6372
6542
|
// src/commands/workflows.ts
|
|
6373
|
-
import { defineCommand as
|
|
6374
|
-
import
|
|
6543
|
+
import { defineCommand as defineCommand57 } from "citty";
|
|
6544
|
+
import consola45 from "consola";
|
|
6375
6545
|
|
|
6376
6546
|
// src/guides/index.ts
|
|
6377
6547
|
var guides = [
|
|
@@ -6421,7 +6591,7 @@ var guides = [
|
|
|
6421
6591
|
];
|
|
6422
6592
|
|
|
6423
6593
|
// src/commands/workflows.ts
|
|
6424
|
-
var workflowsCommand =
|
|
6594
|
+
var workflowsCommand = defineCommand57({
|
|
6425
6595
|
meta: {
|
|
6426
6596
|
name: "workflows",
|
|
6427
6597
|
description: "Discover workflow guides"
|
|
@@ -6442,7 +6612,7 @@ var workflowsCommand = defineCommand53({
|
|
|
6442
6612
|
if (args.id) {
|
|
6443
6613
|
const guide = guides.find((g) => g.id === String(args.id));
|
|
6444
6614
|
if (!guide) {
|
|
6445
|
-
|
|
6615
|
+
consola45.info(`Available: ${guides.map((g) => g.id).join(", ")}`);
|
|
6446
6616
|
throw new CliError(`Guide not found: ${args.id}`);
|
|
6447
6617
|
}
|
|
6448
6618
|
if (args.json) {
|
|
@@ -6485,7 +6655,7 @@ var workflowsCommand = defineCommand53({
|
|
|
6485
6655
|
import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
|
|
6486
6656
|
import { homedir as homedir13 } from "os";
|
|
6487
6657
|
import { join as join14 } from "path";
|
|
6488
|
-
import
|
|
6658
|
+
import consola46 from "consola";
|
|
6489
6659
|
var PACKAGE_NAME = "@openape/apes";
|
|
6490
6660
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
6491
6661
|
var CACHE_FILE = join14(homedir13(), ".config", "apes", ".version-check.json");
|
|
@@ -6530,7 +6700,7 @@ async function fetchLatestVersion() {
|
|
|
6530
6700
|
}
|
|
6531
6701
|
function warnIfBehind(currentVersion, latest) {
|
|
6532
6702
|
if (compareSemver(currentVersion, latest) < 0) {
|
|
6533
|
-
|
|
6703
|
+
consola46.warn(
|
|
6534
6704
|
`apes ${currentVersion} is behind latest @openape/apes@${latest}. Run \`npm i -g @openape/apes@latest\` to update. (Suppress with APES_NO_UPDATE_CHECK=1.)`
|
|
6535
6705
|
);
|
|
6536
6706
|
}
|
|
@@ -6562,10 +6732,10 @@ if (shellRewrite) {
|
|
|
6562
6732
|
if (shellRewrite.action === "rewrite") {
|
|
6563
6733
|
process.argv = shellRewrite.argv;
|
|
6564
6734
|
} else if (shellRewrite.action === "version") {
|
|
6565
|
-
console.log(`ape-shell ${"1.
|
|
6735
|
+
console.log(`ape-shell ${"1.7.0"} (OpenApe DDISA shell wrapper)`);
|
|
6566
6736
|
process.exit(0);
|
|
6567
6737
|
} else if (shellRewrite.action === "help") {
|
|
6568
|
-
console.log(`ape-shell ${"1.
|
|
6738
|
+
console.log(`ape-shell ${"1.7.0"} \u2014 OpenApe DDISA shell wrapper`);
|
|
6569
6739
|
console.log("");
|
|
6570
6740
|
console.log("Usage:");
|
|
6571
6741
|
console.log(" ape-shell Start interactive grant-mediated REPL");
|
|
@@ -6589,7 +6759,7 @@ if (shellRewrite) {
|
|
|
6589
6759
|
}
|
|
6590
6760
|
}
|
|
6591
6761
|
var debug = process.argv.includes("--debug");
|
|
6592
|
-
var grantsCommand =
|
|
6762
|
+
var grantsCommand = defineCommand58({
|
|
6593
6763
|
meta: {
|
|
6594
6764
|
name: "grants",
|
|
6595
6765
|
description: "Grant management"
|
|
@@ -6610,7 +6780,7 @@ var grantsCommand = defineCommand54({
|
|
|
6610
6780
|
"delegation-revoke": delegationRevokeCommand
|
|
6611
6781
|
}
|
|
6612
6782
|
});
|
|
6613
|
-
var configCommand =
|
|
6783
|
+
var configCommand = defineCommand58({
|
|
6614
6784
|
meta: {
|
|
6615
6785
|
name: "config",
|
|
6616
6786
|
description: "Configuration management"
|
|
@@ -6620,10 +6790,10 @@ var configCommand = defineCommand54({
|
|
|
6620
6790
|
set: configSetCommand
|
|
6621
6791
|
}
|
|
6622
6792
|
});
|
|
6623
|
-
var main =
|
|
6793
|
+
var main = defineCommand58({
|
|
6624
6794
|
meta: {
|
|
6625
6795
|
name: "apes",
|
|
6626
|
-
version: "1.
|
|
6796
|
+
version: "1.7.0",
|
|
6627
6797
|
description: "Unified CLI for OpenApe"
|
|
6628
6798
|
},
|
|
6629
6799
|
subCommands: {
|
|
@@ -6640,6 +6810,7 @@ var main = defineCommand54({
|
|
|
6640
6810
|
grants: grantsCommand,
|
|
6641
6811
|
agents: agentsCommand,
|
|
6642
6812
|
nest: nestCommand,
|
|
6813
|
+
yolo: yoloCommand,
|
|
6643
6814
|
admin: adminCommand,
|
|
6644
6815
|
run: runCommand,
|
|
6645
6816
|
proxy: proxyCommand,
|
|
@@ -6679,20 +6850,20 @@ async function maybeRefreshAuth() {
|
|
|
6679
6850
|
}
|
|
6680
6851
|
}
|
|
6681
6852
|
await maybeRefreshAuth();
|
|
6682
|
-
await maybeWarnStaleVersion("1.
|
|
6853
|
+
await maybeWarnStaleVersion("1.7.0").catch(() => {
|
|
6683
6854
|
});
|
|
6684
6855
|
runMain(main).catch((err) => {
|
|
6685
6856
|
if (err instanceof CliExit) {
|
|
6686
6857
|
process.exit(err.exitCode);
|
|
6687
6858
|
}
|
|
6688
6859
|
if (err instanceof CliError) {
|
|
6689
|
-
|
|
6860
|
+
consola47.error(err.message);
|
|
6690
6861
|
process.exit(err.exitCode);
|
|
6691
6862
|
}
|
|
6692
6863
|
if (debug) {
|
|
6693
|
-
|
|
6864
|
+
consola47.error(err);
|
|
6694
6865
|
} else {
|
|
6695
|
-
|
|
6866
|
+
consola47.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err));
|
|
6696
6867
|
}
|
|
6697
6868
|
process.exit(1);
|
|
6698
6869
|
});
|