@openape/apes 1.13.0 → 1.14.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
|
@@ -2955,12 +2955,61 @@ function shQuote2(s) {
|
|
|
2955
2955
|
|
|
2956
2956
|
// src/commands/agents/destroy.ts
|
|
2957
2957
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
2958
|
-
import { mkdtempSync, rmSync, writeFileSync } from "fs";
|
|
2958
|
+
import { mkdtempSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
2959
2959
|
import { tmpdir, userInfo } from "os";
|
|
2960
|
-
import { join as
|
|
2960
|
+
import { join as join3 } from "path";
|
|
2961
2961
|
import { defineCommand as defineCommand21 } from "citty";
|
|
2962
2962
|
import consola19 from "consola";
|
|
2963
2963
|
|
|
2964
|
+
// src/lib/nest-registry.ts
|
|
2965
|
+
import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
2966
|
+
import { homedir as homedir4 } from "os";
|
|
2967
|
+
import { join as join2 } from "path";
|
|
2968
|
+
function resolveRegistryPath() {
|
|
2969
|
+
if (existsSync4("/var/openape/nest/agents.json")) return "/var/openape/nest/agents.json";
|
|
2970
|
+
if (existsSync4("/var/openape/nest")) return "/var/openape/nest/agents.json";
|
|
2971
|
+
return join2(homedir4(), ".openape", "nest", "agents.json");
|
|
2972
|
+
}
|
|
2973
|
+
function emptyRegistry() {
|
|
2974
|
+
return { version: 1, agents: [] };
|
|
2975
|
+
}
|
|
2976
|
+
function readNestRegistry() {
|
|
2977
|
+
const path2 = resolveRegistryPath();
|
|
2978
|
+
if (!existsSync4(path2)) return emptyRegistry();
|
|
2979
|
+
try {
|
|
2980
|
+
const parsed = JSON.parse(readFileSync3(path2, "utf8"));
|
|
2981
|
+
if (parsed?.version !== 1 || !Array.isArray(parsed.agents)) return emptyRegistry();
|
|
2982
|
+
return parsed;
|
|
2983
|
+
} catch {
|
|
2984
|
+
return emptyRegistry();
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
function writeNestRegistry(reg) {
|
|
2988
|
+
const path2 = resolveRegistryPath();
|
|
2989
|
+
const dir = path2.replace(/\/agents\.json$/, "");
|
|
2990
|
+
try {
|
|
2991
|
+
mkdirSync(dir, { recursive: true });
|
|
2992
|
+
} catch {
|
|
2993
|
+
}
|
|
2994
|
+
writeFileSync(path2, `${JSON.stringify(reg, null, 2)}
|
|
2995
|
+
`, { mode: 432 });
|
|
2996
|
+
}
|
|
2997
|
+
function upsertNestAgent(entry) {
|
|
2998
|
+
const reg = readNestRegistry();
|
|
2999
|
+
const existing = reg.agents.findIndex((a) => a.name === entry.name);
|
|
3000
|
+
if (existing >= 0) reg.agents[existing] = entry;
|
|
3001
|
+
else reg.agents.push(entry);
|
|
3002
|
+
writeNestRegistry(reg);
|
|
3003
|
+
}
|
|
3004
|
+
function removeNestAgent(name) {
|
|
3005
|
+
const reg = readNestRegistry();
|
|
3006
|
+
const before = reg.agents.length;
|
|
3007
|
+
reg.agents = reg.agents.filter((a) => a.name !== name);
|
|
3008
|
+
if (reg.agents.length === before) return false;
|
|
3009
|
+
writeNestRegistry(reg);
|
|
3010
|
+
return true;
|
|
3011
|
+
}
|
|
3012
|
+
|
|
2964
3013
|
// src/lib/silent-password.ts
|
|
2965
3014
|
function readPasswordSilent(prompt) {
|
|
2966
3015
|
if (!process.stdin.isTTY) {
|
|
@@ -3100,11 +3149,11 @@ ${consequences.join("\n")}`);
|
|
|
3100
3149
|
}
|
|
3101
3150
|
const adminUser = userInfo().username;
|
|
3102
3151
|
const adminPassword = await collectAdminPassword({ adminUser });
|
|
3103
|
-
const scratch = mkdtempSync(
|
|
3104
|
-
const scriptPath =
|
|
3152
|
+
const scratch = mkdtempSync(join3(tmpdir(), `apes-destroy-${name}-`));
|
|
3153
|
+
const scriptPath = join3(scratch, "teardown.sh");
|
|
3105
3154
|
try {
|
|
3106
3155
|
const script = buildDestroyTeardownScript({ name, homeDir: `/Users/${name}`, adminUser });
|
|
3107
|
-
|
|
3156
|
+
writeFileSync2(scriptPath, script, { mode: 448 });
|
|
3108
3157
|
consola19.start("Running teardown via sudo\u2026");
|
|
3109
3158
|
execFileSync4(sudo, ["-S", "--prompt=", "--", "bash", scriptPath], {
|
|
3110
3159
|
input: `${adminPassword}
|
|
@@ -3118,6 +3167,11 @@ ${adminPassword}
|
|
|
3118
3167
|
} else if (!args["keep-os-user"] && isDarwin()) {
|
|
3119
3168
|
consola19.info("No macOS user to remove (skipped).");
|
|
3120
3169
|
}
|
|
3170
|
+
try {
|
|
3171
|
+
removeNestAgent(name);
|
|
3172
|
+
} catch (err) {
|
|
3173
|
+
consola19.warn(`Could not update nest registry: ${err instanceof Error ? err.message : String(err)}`);
|
|
3174
|
+
}
|
|
3121
3175
|
consola19.success(`Destroyed ${name}.`);
|
|
3122
3176
|
}
|
|
3123
3177
|
});
|
|
@@ -3193,7 +3247,7 @@ var listAgentsCommand = defineCommand22({
|
|
|
3193
3247
|
});
|
|
3194
3248
|
|
|
3195
3249
|
// src/commands/agents/register.ts
|
|
3196
|
-
import { existsSync as
|
|
3250
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
3197
3251
|
import { defineCommand as defineCommand23 } from "citty";
|
|
3198
3252
|
import consola21 from "consola";
|
|
3199
3253
|
var registerAgentCommand = defineCommand23({
|
|
@@ -3241,10 +3295,10 @@ var registerAgentCommand = defineCommand23({
|
|
|
3241
3295
|
throw new CliError("Pass either --public-key or --public-key-file, not both.");
|
|
3242
3296
|
}
|
|
3243
3297
|
if (!publicKey && keyFile) {
|
|
3244
|
-
if (!
|
|
3298
|
+
if (!existsSync5(keyFile)) {
|
|
3245
3299
|
throw new CliError(`Public-key file not found: ${keyFile}`);
|
|
3246
3300
|
}
|
|
3247
|
-
publicKey =
|
|
3301
|
+
publicKey = readFileSync4(keyFile, "utf-8").trim();
|
|
3248
3302
|
}
|
|
3249
3303
|
if (!publicKey) {
|
|
3250
3304
|
throw new CliError('Provide --public-key "<ssh-ed25519 line>" or --public-key-file <path>.');
|
|
@@ -3279,9 +3333,9 @@ var registerAgentCommand = defineCommand23({
|
|
|
3279
3333
|
});
|
|
3280
3334
|
|
|
3281
3335
|
// src/commands/agents/run.ts
|
|
3282
|
-
import { existsSync as
|
|
3283
|
-
import { homedir as
|
|
3284
|
-
import { join as
|
|
3336
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
3337
|
+
import { homedir as homedir5 } from "os";
|
|
3338
|
+
import { join as join4 } from "path";
|
|
3285
3339
|
import { defineCommand as defineCommand24 } from "citty";
|
|
3286
3340
|
import consola22 from "consola";
|
|
3287
3341
|
|
|
@@ -3343,13 +3397,13 @@ function resolveTroopUrl(override) {
|
|
|
3343
3397
|
}
|
|
3344
3398
|
|
|
3345
3399
|
// src/commands/agents/run.ts
|
|
3346
|
-
var AUTH_PATH =
|
|
3347
|
-
var TASK_CACHE_DIR =
|
|
3400
|
+
var AUTH_PATH = join4(homedir5(), ".config", "apes", "auth.json");
|
|
3401
|
+
var TASK_CACHE_DIR = join4(homedir5(), ".openape", "agent", "tasks");
|
|
3348
3402
|
function readAuth() {
|
|
3349
|
-
if (!
|
|
3403
|
+
if (!existsSync6(AUTH_PATH)) {
|
|
3350
3404
|
throw new CliError(`No agent auth found at ${AUTH_PATH}. Run \`apes agents spawn <name>\` first.`);
|
|
3351
3405
|
}
|
|
3352
|
-
const parsed = JSON.parse(
|
|
3406
|
+
const parsed = JSON.parse(readFileSync5(AUTH_PATH, "utf8"));
|
|
3353
3407
|
if (!parsed.access_token) throw new CliError("auth.json missing access_token");
|
|
3354
3408
|
return parsed;
|
|
3355
3409
|
}
|
|
@@ -3385,26 +3439,26 @@ ${msg}`.slice(0, 9e3);
|
|
|
3385
3439
|
}
|
|
3386
3440
|
}
|
|
3387
3441
|
function readTaskSpec(taskId) {
|
|
3388
|
-
const path2 =
|
|
3389
|
-
if (!
|
|
3442
|
+
const path2 = join4(TASK_CACHE_DIR, `${taskId}.json`);
|
|
3443
|
+
if (!existsSync6(path2)) {
|
|
3390
3444
|
throw new CliError(`No cached task spec at ${path2}. Run \`apes agents sync\` first to pull the task list from troop.`);
|
|
3391
3445
|
}
|
|
3392
|
-
return JSON.parse(
|
|
3446
|
+
return JSON.parse(readFileSync5(path2, "utf8"));
|
|
3393
3447
|
}
|
|
3394
|
-
var AGENT_CONFIG_PATH =
|
|
3448
|
+
var AGENT_CONFIG_PATH = join4(homedir5(), ".openape", "agent", "agent.json");
|
|
3395
3449
|
function readAgentConfig() {
|
|
3396
|
-
if (!
|
|
3450
|
+
if (!existsSync6(AGENT_CONFIG_PATH)) return { systemPrompt: "" };
|
|
3397
3451
|
try {
|
|
3398
|
-
return JSON.parse(
|
|
3452
|
+
return JSON.parse(readFileSync5(AGENT_CONFIG_PATH, "utf8"));
|
|
3399
3453
|
} catch {
|
|
3400
3454
|
return { systemPrompt: "" };
|
|
3401
3455
|
}
|
|
3402
3456
|
}
|
|
3403
3457
|
function readLitellmConfig(model) {
|
|
3404
|
-
const envPath =
|
|
3458
|
+
const envPath = join4(homedir5(), "litellm", ".env");
|
|
3405
3459
|
const env = {};
|
|
3406
|
-
if (
|
|
3407
|
-
for (const line of
|
|
3460
|
+
if (existsSync6(envPath)) {
|
|
3461
|
+
for (const line of readFileSync5(envPath, "utf8").split(/\r?\n/)) {
|
|
3408
3462
|
const m = line.match(/^([A-Z_]+)=(.*)$/);
|
|
3409
3463
|
if (m) env[m[1]] = m[2].replace(/^["']|["']$/g, "");
|
|
3410
3464
|
}
|
|
@@ -3509,17 +3563,17 @@ var runAgentCommand = defineCommand24({
|
|
|
3509
3563
|
});
|
|
3510
3564
|
|
|
3511
3565
|
// src/commands/agents/serve.ts
|
|
3512
|
-
import { existsSync as
|
|
3513
|
-
import { homedir as
|
|
3514
|
-
import { join as
|
|
3566
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
3567
|
+
import { homedir as homedir6 } from "os";
|
|
3568
|
+
import { join as join5 } from "path";
|
|
3515
3569
|
import { createInterface } from "readline";
|
|
3516
3570
|
import { defineCommand as defineCommand25 } from "citty";
|
|
3517
|
-
var AUTH_PATH2 =
|
|
3571
|
+
var AUTH_PATH2 = join5(homedir6(), ".config", "apes", "auth.json");
|
|
3518
3572
|
function readLitellmConfig2(model) {
|
|
3519
|
-
const envPath =
|
|
3573
|
+
const envPath = join5(homedir6(), "litellm", ".env");
|
|
3520
3574
|
const env = {};
|
|
3521
|
-
if (
|
|
3522
|
-
for (const line of
|
|
3575
|
+
if (existsSync7(envPath)) {
|
|
3576
|
+
for (const line of readFileSync6(envPath, "utf8").split(/\r?\n/)) {
|
|
3523
3577
|
const m = line.match(/^([A-Z_]+)=(.*)$/);
|
|
3524
3578
|
if (m) env[m[1]] = m[2].replace(/^["']|["']$/g, "");
|
|
3525
3579
|
}
|
|
@@ -3551,9 +3605,9 @@ var serveAgentCommand = defineCommand25({
|
|
|
3551
3605
|
if (!args.rpc) {
|
|
3552
3606
|
throw new CliError("apes agents serve currently only supports --rpc mode");
|
|
3553
3607
|
}
|
|
3554
|
-
if (
|
|
3608
|
+
if (existsSync7(AUTH_PATH2)) {
|
|
3555
3609
|
try {
|
|
3556
|
-
JSON.parse(
|
|
3610
|
+
JSON.parse(readFileSync6(AUTH_PATH2, "utf8"));
|
|
3557
3611
|
} catch {
|
|
3558
3612
|
}
|
|
3559
3613
|
}
|
|
@@ -3629,9 +3683,9 @@ async function handleInbound(msg, sessions) {
|
|
|
3629
3683
|
|
|
3630
3684
|
// src/commands/agents/spawn.ts
|
|
3631
3685
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
3632
|
-
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync as
|
|
3686
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
3633
3687
|
import { tmpdir as tmpdir2 } from "os";
|
|
3634
|
-
import { join as
|
|
3688
|
+
import { join as join7 } from "path";
|
|
3635
3689
|
import { defineCommand as defineCommand26 } from "citty";
|
|
3636
3690
|
import consola23 from "consola";
|
|
3637
3691
|
|
|
@@ -3689,12 +3743,12 @@ ${envBlock} <key>StartInterval</key>
|
|
|
3689
3743
|
|
|
3690
3744
|
// src/lib/keygen.ts
|
|
3691
3745
|
import { Buffer as Buffer4 } from "buffer";
|
|
3692
|
-
import { existsSync as
|
|
3746
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync2, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
|
|
3693
3747
|
import { generateKeyPairSync } from "crypto";
|
|
3694
|
-
import { homedir as
|
|
3748
|
+
import { homedir as homedir7 } from "os";
|
|
3695
3749
|
import { dirname, resolve as resolve2 } from "path";
|
|
3696
3750
|
function resolveKeyPath(p2) {
|
|
3697
|
-
return resolve2(p2.replace(/^~/,
|
|
3751
|
+
return resolve2(p2.replace(/^~/, homedir7()));
|
|
3698
3752
|
}
|
|
3699
3753
|
function buildSshEd25519Line(rawPub) {
|
|
3700
3754
|
const keyTypeStr = "ssh-ed25519";
|
|
@@ -3707,10 +3761,10 @@ function buildSshEd25519Line(rawPub) {
|
|
|
3707
3761
|
}
|
|
3708
3762
|
function readPublicKey(keyPath) {
|
|
3709
3763
|
const pubPath = `${keyPath}.pub`;
|
|
3710
|
-
if (
|
|
3711
|
-
return
|
|
3764
|
+
if (existsSync8(pubPath)) {
|
|
3765
|
+
return readFileSync7(pubPath, "utf-8").trim();
|
|
3712
3766
|
}
|
|
3713
|
-
const keyContent =
|
|
3767
|
+
const keyContent = readFileSync7(keyPath, "utf-8");
|
|
3714
3768
|
const privateKey = loadEd25519PrivateKey(keyContent);
|
|
3715
3769
|
const jwk = privateKey.export({ format: "jwk" });
|
|
3716
3770
|
const pubBytes = Buffer4.from(jwk.x, "base64url");
|
|
@@ -3719,16 +3773,16 @@ function readPublicKey(keyPath) {
|
|
|
3719
3773
|
function generateAndSaveKey(keyPath) {
|
|
3720
3774
|
const resolved = resolveKeyPath(keyPath);
|
|
3721
3775
|
const dir = dirname(resolved);
|
|
3722
|
-
if (!
|
|
3723
|
-
|
|
3776
|
+
if (!existsSync8(dir)) {
|
|
3777
|
+
mkdirSync2(dir, { recursive: true });
|
|
3724
3778
|
}
|
|
3725
3779
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
3726
3780
|
const privatePem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
3727
|
-
|
|
3781
|
+
writeFileSync3(resolved, privatePem, { mode: 384 });
|
|
3728
3782
|
const jwk = publicKey.export({ format: "jwk" });
|
|
3729
3783
|
const pubBytes = Buffer4.from(jwk.x, "base64url");
|
|
3730
3784
|
const pubKeyStr = buildSshEd25519Line(pubBytes);
|
|
3731
|
-
|
|
3785
|
+
writeFileSync3(`${resolved}.pub`, `${pubKeyStr}
|
|
3732
3786
|
`, { mode: 420 });
|
|
3733
3787
|
return pubKeyStr;
|
|
3734
3788
|
}
|
|
@@ -3745,14 +3799,14 @@ function generateKeyPairInMemory() {
|
|
|
3745
3799
|
|
|
3746
3800
|
// src/lib/llm-bridge.ts
|
|
3747
3801
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
3748
|
-
import { existsSync as
|
|
3749
|
-
import { homedir as
|
|
3750
|
-
import { dirname as dirname2, join as
|
|
3802
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
|
|
3803
|
+
import { homedir as homedir8 } from "os";
|
|
3804
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
3751
3805
|
var PLIST_LABEL_PREFIX = "eco.hofmann.apes.bridge";
|
|
3752
|
-
function readLitellmEnv(envPath =
|
|
3753
|
-
if (!
|
|
3806
|
+
function readLitellmEnv(envPath = join6(homedir8(), "litellm", ".env")) {
|
|
3807
|
+
if (!existsSync9(envPath)) return null;
|
|
3754
3808
|
try {
|
|
3755
|
-
const text =
|
|
3809
|
+
const text = readFileSync8(envPath, "utf8");
|
|
3756
3810
|
const out = {};
|
|
3757
3811
|
for (const line of text.split("\n")) {
|
|
3758
3812
|
const trimmed = line.trim();
|
|
@@ -3881,6 +3935,14 @@ function buildBridgePlist(agentName, homeDir, ownerEmail, hostBinDirs) {
|
|
|
3881
3935
|
}
|
|
3882
3936
|
|
|
3883
3937
|
// src/commands/agents/spawn.ts
|
|
3938
|
+
function readMacOSUidOrNull(name) {
|
|
3939
|
+
try {
|
|
3940
|
+
const u = readMacOSUser(name);
|
|
3941
|
+
return u?.uid ?? null;
|
|
3942
|
+
} catch {
|
|
3943
|
+
return null;
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3884
3946
|
var spawnAgentCommand = defineCommand26({
|
|
3885
3947
|
meta: {
|
|
3886
3948
|
name: "spawn",
|
|
@@ -3968,8 +4030,8 @@ and try again.`
|
|
|
3968
4030
|
throw new CliError(`macOS user "${name}" already exists (uid=${existing.uid ?? "?"}). Refusing to overwrite.`);
|
|
3969
4031
|
}
|
|
3970
4032
|
const homeDir = `/Users/${name}`;
|
|
3971
|
-
const scratch = mkdtempSync2(
|
|
3972
|
-
const scriptPath =
|
|
4033
|
+
const scratch = mkdtempSync2(join7(tmpdir2(), `apes-spawn-${name}-`));
|
|
4034
|
+
const scriptPath = join7(scratch, "setup.sh");
|
|
3973
4035
|
try {
|
|
3974
4036
|
consola23.start(`Generating keypair for ${name}\u2026`);
|
|
3975
4037
|
const { privatePem, publicSshLine } = generateKeyPairInMemory();
|
|
@@ -4039,10 +4101,27 @@ and try again.`
|
|
|
4039
4101
|
bridge,
|
|
4040
4102
|
troop
|
|
4041
4103
|
});
|
|
4042
|
-
|
|
4104
|
+
writeFileSync4(scriptPath, script, { mode: 448 });
|
|
4043
4105
|
consola23.start("Running privileged setup as root via `apes run --as root --wait`\u2026");
|
|
4044
4106
|
consola23.info("You will be asked to approve the as=root grant in your DDISA inbox; this command blocks until you do.");
|
|
4045
4107
|
execFileSync6(apes, ["run", "--as", "root", "--wait", "--", "bash", scriptPath], { stdio: "inherit" });
|
|
4108
|
+
try {
|
|
4109
|
+
const uid = readMacOSUidOrNull(name);
|
|
4110
|
+
upsertNestAgent({
|
|
4111
|
+
name,
|
|
4112
|
+
uid: uid ?? -1,
|
|
4113
|
+
home: homeDir,
|
|
4114
|
+
email: registration.email,
|
|
4115
|
+
registeredAt: Math.floor(Date.now() / 1e3),
|
|
4116
|
+
bridge: args.bridge ? {
|
|
4117
|
+
baseUrl: typeof args["bridge-base-url"] === "string" ? args["bridge-base-url"] : void 0,
|
|
4118
|
+
apiKey: typeof args["bridge-key"] === "string" ? args["bridge-key"] : void 0,
|
|
4119
|
+
model: typeof args["bridge-model"] === "string" ? args["bridge-model"] : void 0
|
|
4120
|
+
} : void 0
|
|
4121
|
+
});
|
|
4122
|
+
} catch (err) {
|
|
4123
|
+
consola23.warn(`Could not write to nest registry: ${err instanceof Error ? err.message : String(err)}`);
|
|
4124
|
+
}
|
|
4046
4125
|
consola23.success(`Agent ${name} spawned.`);
|
|
4047
4126
|
consola23.info(`\u{1F517} Troop: https://troop.openape.ai/agents/${name}`);
|
|
4048
4127
|
if (args.bridge) {
|
|
@@ -4081,9 +4160,9 @@ async function resolveClaudeToken(opts) {
|
|
|
4081
4160
|
}
|
|
4082
4161
|
|
|
4083
4162
|
// src/commands/agents/sync.ts
|
|
4084
|
-
import { chownSync, existsSync as
|
|
4085
|
-
import { homedir as
|
|
4086
|
-
import { join as
|
|
4163
|
+
import { chownSync, existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync9, statSync, writeFileSync as writeFileSync5 } from "fs";
|
|
4164
|
+
import { homedir as homedir9 } from "os";
|
|
4165
|
+
import { join as join8 } from "path";
|
|
4087
4166
|
import { defineCommand as defineCommand27 } from "citty";
|
|
4088
4167
|
import consola24 from "consola";
|
|
4089
4168
|
|
|
@@ -4112,15 +4191,15 @@ function getHostname() {
|
|
|
4112
4191
|
}
|
|
4113
4192
|
|
|
4114
4193
|
// src/commands/agents/sync.ts
|
|
4115
|
-
var AUTH_PATH3 =
|
|
4116
|
-
var TASK_CACHE_DIR2 =
|
|
4194
|
+
var AUTH_PATH3 = join8(homedir9(), ".config", "apes", "auth.json");
|
|
4195
|
+
var TASK_CACHE_DIR2 = join8(homedir9(), ".openape", "agent", "tasks");
|
|
4117
4196
|
function readAuthJson() {
|
|
4118
|
-
if (!
|
|
4197
|
+
if (!existsSync10(AUTH_PATH3)) {
|
|
4119
4198
|
throw new CliError(
|
|
4120
4199
|
`No agent auth found at ${AUTH_PATH3}. Run \`apes agents spawn <name>\` to provision an agent first.`
|
|
4121
4200
|
);
|
|
4122
4201
|
}
|
|
4123
|
-
const raw =
|
|
4202
|
+
const raw = readFileSync9(AUTH_PATH3, "utf8");
|
|
4124
4203
|
let parsed;
|
|
4125
4204
|
try {
|
|
4126
4205
|
parsed = JSON.parse(raw);
|
|
@@ -4181,7 +4260,7 @@ var syncAgentCommand = defineCommand27({
|
|
|
4181
4260
|
let agentGid = null;
|
|
4182
4261
|
if (process.geteuid?.() === 0) {
|
|
4183
4262
|
try {
|
|
4184
|
-
const homeStat = statSync(
|
|
4263
|
+
const homeStat = statSync(homedir9());
|
|
4185
4264
|
agentUid = homeStat.uid;
|
|
4186
4265
|
agentGid = homeStat.gid;
|
|
4187
4266
|
} catch {
|
|
@@ -4195,23 +4274,23 @@ var syncAgentCommand = defineCommand27({
|
|
|
4195
4274
|
}
|
|
4196
4275
|
}
|
|
4197
4276
|
}
|
|
4198
|
-
const agentDir =
|
|
4199
|
-
|
|
4200
|
-
chownToAgent(
|
|
4277
|
+
const agentDir = join8(homedir9(), ".openape", "agent");
|
|
4278
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
4279
|
+
chownToAgent(join8(homedir9(), ".openape"));
|
|
4201
4280
|
chownToAgent(agentDir);
|
|
4202
|
-
const agentJsonPath =
|
|
4203
|
-
|
|
4281
|
+
const agentJsonPath = join8(agentDir, "agent.json");
|
|
4282
|
+
writeFileSync5(
|
|
4204
4283
|
agentJsonPath,
|
|
4205
4284
|
`${JSON.stringify({ systemPrompt }, null, 2)}
|
|
4206
4285
|
`,
|
|
4207
4286
|
{ mode: 384 }
|
|
4208
4287
|
);
|
|
4209
4288
|
chownToAgent(agentJsonPath);
|
|
4210
|
-
|
|
4289
|
+
mkdirSync3(TASK_CACHE_DIR2, { recursive: true });
|
|
4211
4290
|
chownToAgent(TASK_CACHE_DIR2);
|
|
4212
4291
|
for (const task of tasks) {
|
|
4213
|
-
const path2 =
|
|
4214
|
-
|
|
4292
|
+
const path2 = join8(TASK_CACHE_DIR2, `${task.taskId}.json`);
|
|
4293
|
+
writeFileSync5(path2, `${JSON.stringify(task, null, 2)}
|
|
4215
4294
|
`, { mode: 384 });
|
|
4216
4295
|
chownToAgent(path2);
|
|
4217
4296
|
}
|
|
@@ -4242,18 +4321,18 @@ import { defineCommand as defineCommand36 } from "citty";
|
|
|
4242
4321
|
|
|
4243
4322
|
// src/commands/nest/authorize.ts
|
|
4244
4323
|
import { execFileSync as execFileSync8 } from "child_process";
|
|
4245
|
-
import { existsSync as
|
|
4246
|
-
import { join as
|
|
4324
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
|
|
4325
|
+
import { join as join10 } from "path";
|
|
4247
4326
|
import { defineCommand as defineCommand30 } from "citty";
|
|
4248
4327
|
import consola26 from "consola";
|
|
4249
4328
|
|
|
4250
4329
|
// src/commands/nest/enroll.ts
|
|
4251
|
-
import { hostname as hostname4, homedir as
|
|
4252
|
-
import { existsSync as
|
|
4253
|
-
import { join as
|
|
4330
|
+
import { hostname as hostname4, homedir as homedir10 } from "os";
|
|
4331
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6, chmodSync } from "fs";
|
|
4332
|
+
import { join as join9 } from "path";
|
|
4254
4333
|
import { defineCommand as defineCommand29 } from "citty";
|
|
4255
4334
|
import consola25 from "consola";
|
|
4256
|
-
var NEST_DATA_DIR =
|
|
4335
|
+
var NEST_DATA_DIR = join9(homedir10(), ".openape", "nest");
|
|
4257
4336
|
function nestAgentName() {
|
|
4258
4337
|
const raw = hostname4().toLowerCase();
|
|
4259
4338
|
const head = raw.split(".")[0] ?? raw;
|
|
@@ -4286,19 +4365,19 @@ var enrollNestCommand = defineCommand29({
|
|
|
4286
4365
|
throw new CliError("Run `apes login <email>` first \u2014 nest enroll attaches the new identity to your owner account.");
|
|
4287
4366
|
}
|
|
4288
4367
|
const name = args.name || nestAgentName();
|
|
4289
|
-
const authPath =
|
|
4290
|
-
if (
|
|
4368
|
+
const authPath = join9(NEST_DATA_DIR, ".config", "apes", "auth.json");
|
|
4369
|
+
if (existsSync11(authPath) && !args.force) {
|
|
4291
4370
|
throw new CliError(`Nest already enrolled at ${authPath}. Pass --force to re-enroll.`);
|
|
4292
4371
|
}
|
|
4293
|
-
const sshDir =
|
|
4294
|
-
const configDir =
|
|
4295
|
-
|
|
4296
|
-
|
|
4372
|
+
const sshDir = join9(NEST_DATA_DIR, ".ssh");
|
|
4373
|
+
const configDir = join9(NEST_DATA_DIR, ".config", "apes");
|
|
4374
|
+
mkdirSync4(sshDir, { recursive: true });
|
|
4375
|
+
mkdirSync4(configDir, { recursive: true });
|
|
4297
4376
|
consola25.start(`Generating keypair for ${name}\u2026`);
|
|
4298
4377
|
const { privatePem, publicSshLine } = generateKeyPairInMemory();
|
|
4299
|
-
|
|
4378
|
+
writeFileSync6(join9(sshDir, "id_ed25519"), `${privatePem.trimEnd()}
|
|
4300
4379
|
`, { mode: 384 });
|
|
4301
|
-
|
|
4380
|
+
writeFileSync6(join9(sshDir, "id_ed25519.pub"), `${publicSshLine}
|
|
4302
4381
|
`, { mode: 420 });
|
|
4303
4382
|
chmodSync(sshDir, 448);
|
|
4304
4383
|
consola25.start(`Registering nest at ${idp}\u2026`);
|
|
@@ -4315,10 +4394,10 @@ var enrollNestCommand = defineCommand29({
|
|
|
4315
4394
|
accessToken: token,
|
|
4316
4395
|
email: registration.email,
|
|
4317
4396
|
expiresAt: Math.floor(Date.now() / 1e3) + expiresIn,
|
|
4318
|
-
keyPath:
|
|
4397
|
+
keyPath: join9(sshDir, "id_ed25519"),
|
|
4319
4398
|
ownerEmail: ownerAuth.email
|
|
4320
4399
|
});
|
|
4321
|
-
|
|
4400
|
+
writeFileSync6(authPath, authJson, { mode: 384 });
|
|
4322
4401
|
chmodSync(configDir, 448);
|
|
4323
4402
|
consola25.success(`Nest enrolled \u2014 auth.json at ${authPath}`);
|
|
4324
4403
|
consola25.info("");
|
|
@@ -4360,10 +4439,11 @@ var DEFAULT_ALLOW_PATTERNS = [
|
|
|
4360
4439
|
// wrapped invocation.
|
|
4361
4440
|
"openape-chat-bridge",
|
|
4362
4441
|
// Phase E: per-agent pm2 management. The Nest shells out
|
|
4363
|
-
// `apes run --as <agent> --
|
|
4364
|
-
//
|
|
4365
|
-
//
|
|
4366
|
-
|
|
4442
|
+
// `apes run --as <agent> -- bash /var/openape/agents/<agent>/start.sh`
|
|
4443
|
+
// (the start.sh sets HOME/PM2_HOME and redirects pm2's stdio so the
|
|
4444
|
+
// god-daemon detach doesn't block our exec parent), plus
|
|
4445
|
+
// `apes run --as <agent> -- pm2 delete openape-bridge-<agent>` for teardown.
|
|
4446
|
+
"bash /var/openape/agents/*/start.sh",
|
|
4367
4447
|
"pm2 delete openape-bridge-*",
|
|
4368
4448
|
"pm2 jlist"
|
|
4369
4449
|
];
|
|
@@ -4383,11 +4463,11 @@ var authorizeNestCommand = defineCommand30({
|
|
|
4383
4463
|
}
|
|
4384
4464
|
},
|
|
4385
4465
|
async run({ args }) {
|
|
4386
|
-
const nestAuthPath =
|
|
4387
|
-
if (!
|
|
4466
|
+
const nestAuthPath = join10(NEST_DATA_DIR, ".config", "apes", "auth.json");
|
|
4467
|
+
if (!existsSync12(nestAuthPath)) {
|
|
4388
4468
|
throw new CliError("Nest not enrolled. Run `apes nest enroll` first.");
|
|
4389
4469
|
}
|
|
4390
|
-
const nestAuth = JSON.parse(
|
|
4470
|
+
const nestAuth = JSON.parse(readFileSync10(nestAuthPath, "utf8"));
|
|
4391
4471
|
if (!nestAuth.email) throw new CliError(`${nestAuthPath} has no email`);
|
|
4392
4472
|
const allow = args.allow ?? DEFAULT_ALLOW_PATTERNS.join(",");
|
|
4393
4473
|
consola26.info(`Configuring YOLO-policy on ${nestAuth.email} via \`apes yolo set\`\u2026`);
|
|
@@ -4414,102 +4494,31 @@ var authorizeNestCommand = defineCommand30({
|
|
|
4414
4494
|
});
|
|
4415
4495
|
|
|
4416
4496
|
// src/commands/nest/destroy.ts
|
|
4497
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
4417
4498
|
import { defineCommand as defineCommand31 } from "citty";
|
|
4418
4499
|
import consola27 from "consola";
|
|
4419
|
-
|
|
4420
|
-
// src/lib/nest-intent.ts
|
|
4421
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync10, statSync as statSync2, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
|
|
4422
|
-
import { homedir as homedir10 } from "os";
|
|
4423
|
-
import { join as join10 } from "path";
|
|
4424
|
-
import { randomUUID } from "crypto";
|
|
4425
|
-
var POLL_INTERVAL_MS = 200;
|
|
4426
|
-
var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
4427
|
-
function resolveIntentDir() {
|
|
4428
|
-
if (process.env.OPENAPE_NEST_INTENT_DIR) return process.env.OPENAPE_NEST_INTENT_DIR;
|
|
4429
|
-
if (existsSync12("/var/openape/nest/intents")) return "/var/openape/nest/intents";
|
|
4430
|
-
return join10(homedir10(), ".openape", "nest", "intents");
|
|
4431
|
-
}
|
|
4432
|
-
async function dispatchIntent(intent, opts = {}) {
|
|
4433
|
-
const id = randomUUID();
|
|
4434
|
-
const dir = resolveIntentDir();
|
|
4435
|
-
if (!existsSync12(dir)) {
|
|
4436
|
-
throw new CliError(`Nest intent dir does not exist: ${dir}
|
|
4437
|
-
Is the nest daemon running? Try \`ps aux | grep openape-nest\`.`);
|
|
4438
|
-
}
|
|
4439
|
-
const intentPath = join10(dir, `${id}.json`);
|
|
4440
|
-
const responsePath = join10(dir, `${id}.response`);
|
|
4441
|
-
const tmpPath = `${intentPath}.tmp`;
|
|
4442
|
-
writeFileSync6(tmpPath, `${JSON.stringify({ id, ...intent })}
|
|
4443
|
-
`, { mode: 432 });
|
|
4444
|
-
try {
|
|
4445
|
-
const fs = await import("fs");
|
|
4446
|
-
fs.renameSync(tmpPath, intentPath);
|
|
4447
|
-
} catch (err) {
|
|
4448
|
-
try {
|
|
4449
|
-
unlinkSync(tmpPath);
|
|
4450
|
-
} catch {
|
|
4451
|
-
}
|
|
4452
|
-
throw err;
|
|
4453
|
-
}
|
|
4454
|
-
const deadline = Date.now() + (opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
4455
|
-
while (Date.now() < deadline) {
|
|
4456
|
-
if (existsSync12(responsePath)) {
|
|
4457
|
-
let raw;
|
|
4458
|
-
try {
|
|
4459
|
-
const st = statSync2(responsePath);
|
|
4460
|
-
if (Date.now() - st.mtimeMs < 50) {
|
|
4461
|
-
await sleep(50);
|
|
4462
|
-
}
|
|
4463
|
-
raw = readFileSync10(responsePath, "utf8");
|
|
4464
|
-
} catch {
|
|
4465
|
-
await sleep(POLL_INTERVAL_MS);
|
|
4466
|
-
continue;
|
|
4467
|
-
}
|
|
4468
|
-
try {
|
|
4469
|
-
unlinkSync(responsePath);
|
|
4470
|
-
} catch {
|
|
4471
|
-
}
|
|
4472
|
-
let parsed;
|
|
4473
|
-
try {
|
|
4474
|
-
parsed = JSON.parse(raw);
|
|
4475
|
-
} catch (err) {
|
|
4476
|
-
throw new CliError(`malformed nest response: ${err instanceof Error ? err.message : String(err)}`);
|
|
4477
|
-
}
|
|
4478
|
-
if (!parsed.ok) {
|
|
4479
|
-
throw new CliError(`nest: ${parsed.error}`);
|
|
4480
|
-
}
|
|
4481
|
-
return parsed.result;
|
|
4482
|
-
}
|
|
4483
|
-
await sleep(POLL_INTERVAL_MS);
|
|
4484
|
-
}
|
|
4485
|
-
try {
|
|
4486
|
-
unlinkSync(intentPath);
|
|
4487
|
-
} catch {
|
|
4488
|
-
}
|
|
4489
|
-
throw new CliError(`nest intent timeout (${(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS) / 1e3}s) \u2014 Nest daemon may not be running or is stuck.`);
|
|
4490
|
-
}
|
|
4491
|
-
function sleep(ms) {
|
|
4492
|
-
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
4493
|
-
}
|
|
4494
|
-
|
|
4495
|
-
// src/commands/nest/destroy.ts
|
|
4496
4500
|
var destroyNestCommand = defineCommand31({
|
|
4497
4501
|
meta: {
|
|
4498
4502
|
name: "destroy",
|
|
4499
|
-
description: "
|
|
4503
|
+
description: "Destroy a local agent. Wraps `apes run --as root -- apes agents destroy <name>`; the Nest watches its registry and pm2-deletes the bridge automatically."
|
|
4500
4504
|
},
|
|
4501
4505
|
args: {
|
|
4502
4506
|
name: { type: "positional", required: true, description: "Agent name to destroy" }
|
|
4503
4507
|
},
|
|
4504
4508
|
async run({ args }) {
|
|
4505
4509
|
const name = String(args.name);
|
|
4506
|
-
|
|
4507
|
-
|
|
4510
|
+
try {
|
|
4511
|
+
execFileSync9("apes", ["run", "--as", "root", "--wait", "--", "apes", "agents", "destroy", name, "--force"], { stdio: "inherit" });
|
|
4512
|
+
consola27.success(`Nest will tear down ${name}'s pm2 process on its next reconcile (\u22642s).`);
|
|
4513
|
+
} catch (err) {
|
|
4514
|
+
const status = err.status ?? 1;
|
|
4515
|
+
throw new CliExit(status);
|
|
4516
|
+
}
|
|
4508
4517
|
}
|
|
4509
4518
|
});
|
|
4510
4519
|
|
|
4511
4520
|
// src/commands/nest/install.ts
|
|
4512
|
-
import { execFileSync as
|
|
4521
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
4513
4522
|
import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
|
|
4514
4523
|
import { homedir as homedir11, userInfo as userInfo2 } from "os";
|
|
4515
4524
|
import { dirname as dirname3, join as join11 } from "path";
|
|
@@ -4707,10 +4716,10 @@ var installNestCommand = defineCommand32({
|
|
|
4707
4716
|
}
|
|
4708
4717
|
const uid = userInfo2().uid;
|
|
4709
4718
|
try {
|
|
4710
|
-
|
|
4719
|
+
execFileSync10("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL}`], { stdio: "ignore" });
|
|
4711
4720
|
} catch {
|
|
4712
4721
|
}
|
|
4713
|
-
|
|
4722
|
+
execFileSync10("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
|
|
4714
4723
|
consola28.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
|
|
4715
4724
|
consola28.info("");
|
|
4716
4725
|
consola28.info("Next steps for zero-prompt spawn \u2014 both one-time:");
|
|
@@ -4728,23 +4737,23 @@ import consola29 from "consola";
|
|
|
4728
4737
|
var listNestCommand = defineCommand33({
|
|
4729
4738
|
meta: {
|
|
4730
4739
|
name: "list",
|
|
4731
|
-
description: "List agents registered with the local nest.
|
|
4740
|
+
description: "List agents registered with the local nest. Reads /var/openape/nest/agents.json directly."
|
|
4732
4741
|
},
|
|
4733
4742
|
args: {
|
|
4734
4743
|
json: { type: "boolean", description: "JSON output for scripts" }
|
|
4735
4744
|
},
|
|
4736
4745
|
async run({ args }) {
|
|
4737
|
-
const
|
|
4746
|
+
const reg = readNestRegistry();
|
|
4738
4747
|
if (args.json) {
|
|
4739
|
-
console.log(JSON.stringify(
|
|
4748
|
+
console.log(JSON.stringify(reg, null, 2));
|
|
4740
4749
|
return;
|
|
4741
4750
|
}
|
|
4742
|
-
if (
|
|
4751
|
+
if (reg.agents.length === 0) {
|
|
4743
4752
|
consola29.info("(no agents registered with this nest)");
|
|
4744
4753
|
return;
|
|
4745
4754
|
}
|
|
4746
|
-
consola29.info(`${
|
|
4747
|
-
for (const a of
|
|
4755
|
+
consola29.info(`${reg.agents.length} agent(s) registered with this nest:`);
|
|
4756
|
+
for (const a of reg.agents) {
|
|
4748
4757
|
const bridge = a.bridge ? " bridge=on" : "";
|
|
4749
4758
|
consola29.info(` ${a.name.padEnd(16)} uid=${String(a.uid).padEnd(5)} home=${a.home}${bridge}`);
|
|
4750
4759
|
}
|
|
@@ -4752,38 +4761,51 @@ var listNestCommand = defineCommand33({
|
|
|
4752
4761
|
});
|
|
4753
4762
|
|
|
4754
4763
|
// src/commands/nest/spawn.ts
|
|
4764
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
4755
4765
|
import { defineCommand as defineCommand34 } from "citty";
|
|
4756
4766
|
import consola30 from "consola";
|
|
4757
4767
|
var spawnNestCommand = defineCommand34({
|
|
4758
4768
|
meta: {
|
|
4759
4769
|
name: "spawn",
|
|
4760
|
-
description: "Spawn a new agent
|
|
4770
|
+
description: "Spawn a new agent locally. Wraps `apes run --as root -- apes agents spawn <name>`; the Nest watches its registry and starts the bridge in pm2 automatically."
|
|
4761
4771
|
},
|
|
4762
4772
|
args: {
|
|
4763
4773
|
name: { type: "positional", required: true, description: "Agent name (lowercase, [a-z0-9-], max 24 chars)" },
|
|
4764
4774
|
"no-bridge": { type: "boolean", description: "Skip installing the chat-bridge daemon (default: install it)" },
|
|
4765
4775
|
"bridge-key": { type: "string", description: "Override LITELLM_API_KEY (default: read from ~/litellm/.env)" },
|
|
4766
|
-
"bridge-base-url": { type: "string", description: "Override LITELLM_BASE_URL
|
|
4776
|
+
"bridge-base-url": { type: "string", description: "Override LITELLM_BASE_URL" },
|
|
4767
4777
|
"bridge-model": { type: "string", description: "Override APE_CHAT_BRIDGE_MODEL" }
|
|
4768
4778
|
},
|
|
4769
4779
|
async run({ args }) {
|
|
4770
4780
|
const name = String(args.name);
|
|
4771
|
-
const
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
+
const apesArgs = [
|
|
4782
|
+
"run",
|
|
4783
|
+
"--as",
|
|
4784
|
+
"root",
|
|
4785
|
+
"--wait",
|
|
4786
|
+
"--",
|
|
4787
|
+
"apes",
|
|
4788
|
+
"agents",
|
|
4789
|
+
"spawn",
|
|
4790
|
+
name
|
|
4791
|
+
];
|
|
4792
|
+
if (!args["no-bridge"]) apesArgs.push("--bridge");
|
|
4793
|
+
if (typeof args["bridge-key"] === "string") apesArgs.push("--bridge-key", args["bridge-key"]);
|
|
4794
|
+
if (typeof args["bridge-base-url"] === "string") apesArgs.push("--bridge-base-url", args["bridge-base-url"]);
|
|
4795
|
+
if (typeof args["bridge-model"] === "string") apesArgs.push("--bridge-model", args["bridge-model"]);
|
|
4796
|
+
try {
|
|
4797
|
+
execFileSync11("apes", apesArgs, { stdio: "inherit" });
|
|
4798
|
+
consola30.success(`Nest will pick up ${name} on its next reconcile (\u22642s).`);
|
|
4799
|
+
} catch (err) {
|
|
4800
|
+
const status = err.status ?? 1;
|
|
4801
|
+
throw new CliExit(status);
|
|
4802
|
+
}
|
|
4781
4803
|
}
|
|
4782
4804
|
});
|
|
4783
4805
|
|
|
4784
4806
|
// src/commands/nest/uninstall.ts
|
|
4785
|
-
import { execFileSync as
|
|
4786
|
-
import { existsSync as existsSync14, unlinkSync
|
|
4807
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
4808
|
+
import { existsSync as existsSync14, unlinkSync } from "fs";
|
|
4787
4809
|
import { homedir as homedir12, userInfo as userInfo3 } from "os";
|
|
4788
4810
|
import { join as join12 } from "path";
|
|
4789
4811
|
import { defineCommand as defineCommand35 } from "citty";
|
|
@@ -4798,13 +4820,13 @@ var uninstallNestCommand = defineCommand35({
|
|
|
4798
4820
|
const uid = userInfo3().uid;
|
|
4799
4821
|
const path2 = join12(homedir12(), "Library", "LaunchAgents", `${PLIST_LABEL2}.plist`);
|
|
4800
4822
|
try {
|
|
4801
|
-
|
|
4823
|
+
execFileSync12("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
|
|
4802
4824
|
consola31.success("Nest daemon stopped");
|
|
4803
4825
|
} catch {
|
|
4804
4826
|
consola31.info("Nest daemon was not loaded");
|
|
4805
4827
|
}
|
|
4806
4828
|
if (existsSync14(path2)) {
|
|
4807
|
-
|
|
4829
|
+
unlinkSync(path2);
|
|
4808
4830
|
consola31.success(`Removed ${path2}`);
|
|
4809
4831
|
}
|
|
4810
4832
|
consola31.info("Registry at ~/.openape/nest/agents.json kept \u2014 re-run `apes nest install` to resume supervision.");
|
|
@@ -5352,7 +5374,7 @@ var adapterCommand = defineCommand41({
|
|
|
5352
5374
|
});
|
|
5353
5375
|
|
|
5354
5376
|
// src/commands/run.ts
|
|
5355
|
-
import { execFileSync as
|
|
5377
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
5356
5378
|
import { hostname as hostname5 } from "os";
|
|
5357
5379
|
import { basename } from "path";
|
|
5358
5380
|
import { defineCommand as defineCommand42 } from "citty";
|
|
@@ -5630,7 +5652,7 @@ function execShellCommand(command) {
|
|
|
5630
5652
|
throw new CliError("No command to execute");
|
|
5631
5653
|
try {
|
|
5632
5654
|
const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
|
|
5633
|
-
|
|
5655
|
+
execFileSync13(command[0], command.slice(1), {
|
|
5634
5656
|
stdio: "inherit",
|
|
5635
5657
|
env: inheritedEnv
|
|
5636
5658
|
});
|
|
@@ -5782,7 +5804,7 @@ async function runAudienceMode(audience, action, args) {
|
|
|
5782
5804
|
consola36.info(`Executing: ${command.join(" ")}`);
|
|
5783
5805
|
try {
|
|
5784
5806
|
const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
|
|
5785
|
-
|
|
5807
|
+
execFileSync13(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
|
|
5786
5808
|
stdio: "inherit",
|
|
5787
5809
|
env: inheritedEnv
|
|
5788
5810
|
});
|
|
@@ -6284,7 +6306,7 @@ var mcpCommand = defineCommand48({
|
|
|
6284
6306
|
if (transport !== "stdio" && transport !== "sse") {
|
|
6285
6307
|
throw new Error('Transport must be "stdio" or "sse"');
|
|
6286
6308
|
}
|
|
6287
|
-
const { startMcpServer } = await import("./server-
|
|
6309
|
+
const { startMcpServer } = await import("./server-P2XXAHS5.js");
|
|
6288
6310
|
await startMcpServer(transport, port);
|
|
6289
6311
|
}
|
|
6290
6312
|
});
|
|
@@ -6292,7 +6314,7 @@ var mcpCommand = defineCommand48({
|
|
|
6292
6314
|
// src/commands/init/index.ts
|
|
6293
6315
|
import { existsSync as existsSync15, copyFileSync, writeFileSync as writeFileSync9 } from "fs";
|
|
6294
6316
|
import { randomBytes } from "crypto";
|
|
6295
|
-
import { execFileSync as
|
|
6317
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
6296
6318
|
import { join as join14 } from "path";
|
|
6297
6319
|
import { defineCommand as defineCommand49 } from "citty";
|
|
6298
6320
|
import consola40 from "consola";
|
|
@@ -6304,11 +6326,11 @@ async function downloadTemplate(repo, targetDir) {
|
|
|
6304
6326
|
function installDeps(dir) {
|
|
6305
6327
|
const hasLockFile = (name) => existsSync15(join14(dir, name));
|
|
6306
6328
|
if (hasLockFile("pnpm-lock.yaml")) {
|
|
6307
|
-
|
|
6329
|
+
execFileSync14("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
6308
6330
|
} else if (hasLockFile("bun.lockb")) {
|
|
6309
|
-
|
|
6331
|
+
execFileSync14("bun", ["install"], { cwd: dir, stdio: "inherit" });
|
|
6310
6332
|
} else {
|
|
6311
|
-
|
|
6333
|
+
execFileSync14("npm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
6312
6334
|
}
|
|
6313
6335
|
}
|
|
6314
6336
|
async function promptChoice(message, choices) {
|
|
@@ -6922,7 +6944,7 @@ async function bestEffortGrantCount(idp) {
|
|
|
6922
6944
|
}
|
|
6923
6945
|
}
|
|
6924
6946
|
async function runHealth(args) {
|
|
6925
|
-
const version = true ? "1.
|
|
6947
|
+
const version = true ? "1.14.0" : "0.0.0";
|
|
6926
6948
|
const auth = loadAuth();
|
|
6927
6949
|
if (!auth) {
|
|
6928
6950
|
throw new CliError("Not logged in. Run `apes login` first.", 1);
|
|
@@ -7195,10 +7217,10 @@ if (shellRewrite) {
|
|
|
7195
7217
|
if (shellRewrite.action === "rewrite") {
|
|
7196
7218
|
process.argv = shellRewrite.argv;
|
|
7197
7219
|
} else if (shellRewrite.action === "version") {
|
|
7198
|
-
console.log(`ape-shell ${"1.
|
|
7220
|
+
console.log(`ape-shell ${"1.14.0"} (OpenApe DDISA shell wrapper)`);
|
|
7199
7221
|
process.exit(0);
|
|
7200
7222
|
} else if (shellRewrite.action === "help") {
|
|
7201
|
-
console.log(`ape-shell ${"1.
|
|
7223
|
+
console.log(`ape-shell ${"1.14.0"} \u2014 OpenApe DDISA shell wrapper`);
|
|
7202
7224
|
console.log("");
|
|
7203
7225
|
console.log("Usage:");
|
|
7204
7226
|
console.log(" ape-shell Start interactive grant-mediated REPL");
|
|
@@ -7256,7 +7278,7 @@ var configCommand = defineCommand60({
|
|
|
7256
7278
|
var main = defineCommand60({
|
|
7257
7279
|
meta: {
|
|
7258
7280
|
name: "apes",
|
|
7259
|
-
version: "1.
|
|
7281
|
+
version: "1.14.0",
|
|
7260
7282
|
description: "Unified CLI for OpenApe"
|
|
7261
7283
|
},
|
|
7262
7284
|
subCommands: {
|
|
@@ -7313,7 +7335,7 @@ async function maybeRefreshAuth() {
|
|
|
7313
7335
|
}
|
|
7314
7336
|
}
|
|
7315
7337
|
await maybeRefreshAuth();
|
|
7316
|
-
await maybeWarnStaleVersion("1.
|
|
7338
|
+
await maybeWarnStaleVersion("1.14.0").catch(() => {
|
|
7317
7339
|
});
|
|
7318
7340
|
runMain(main).catch((err) => {
|
|
7319
7341
|
if (err instanceof CliExit) {
|