@openape/apes 1.23.0 → 1.24.1
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
|
@@ -1773,13 +1773,15 @@ var adminCommand = defineCommand19({
|
|
|
1773
1773
|
import { defineCommand as defineCommand28 } from "citty";
|
|
1774
1774
|
|
|
1775
1775
|
// src/commands/agents/allow.ts
|
|
1776
|
-
import { execFileSync as
|
|
1776
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
1777
1777
|
import { defineCommand as defineCommand20 } from "citty";
|
|
1778
1778
|
import consola18 from "consola";
|
|
1779
1779
|
|
|
1780
1780
|
// src/lib/agent-bootstrap.ts
|
|
1781
1781
|
import { Buffer as Buffer3 } from "buffer";
|
|
1782
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
1782
1783
|
import { createPrivateKey, sign } from "crypto";
|
|
1784
|
+
import { rmSync } from "fs";
|
|
1783
1785
|
|
|
1784
1786
|
// ../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/node.mjs
|
|
1785
1787
|
import http from "http";
|
|
@@ -2650,9 +2652,30 @@ NAME=${shQuote(name)}
|
|
|
2650
2652
|
HOME_DIR=${shQuote(homeDir)}
|
|
2651
2653
|
SHELL_PATH=${shQuote(shellPath)}
|
|
2652
2654
|
|
|
2655
|
+
# Tombstone-reuse: \`apes agents destroy\` leaves the dscl user
|
|
2656
|
+
# record behind (opendirectoryd refuses \`dscl . -delete\` from
|
|
2657
|
+
# escapes' setuid-root context without admin auth, so we accept the
|
|
2658
|
+
# stranded record as a harmless tombstone \u2014 see
|
|
2659
|
+
# runPhaseGTeardownInProcess). When the operator re-spawns with the
|
|
2660
|
+
# same name, we recycle the tombstone instead of refusing: if the
|
|
2661
|
+
# previously-recorded home dir is gone from disk (matching the
|
|
2662
|
+
# Phase-G teardown's \`rm -rf\`), we reuse the existing UID +
|
|
2663
|
+
# overwrite the home. If the home is still on disk it's a real,
|
|
2664
|
+
# live agent \u2014 refuse.
|
|
2665
|
+
TOMBSTONE_REUSE=0
|
|
2653
2666
|
if dscl . -read "/Users/$NAME" >/dev/null 2>&1; then
|
|
2654
|
-
|
|
2655
|
-
|
|
2667
|
+
EXISTING_HOME=$(dscl . -read "/Users/$NAME" NFSHomeDirectory 2>/dev/null | awk '/NFSHomeDirectory:/ {print $2}')
|
|
2668
|
+
if [ -n "$EXISTING_HOME" ] && [ -d "$EXISTING_HOME" ]; then
|
|
2669
|
+
echo "User $NAME already exists with a live home at $EXISTING_HOME; refusing to overwrite." >&2
|
|
2670
|
+
exit 1
|
|
2671
|
+
fi
|
|
2672
|
+
NEXT_UID=$(dscl . -read "/Users/$NAME" UniqueID 2>/dev/null | awk '/UniqueID:/ {print $2}')
|
|
2673
|
+
if [ -z "$NEXT_UID" ]; then
|
|
2674
|
+
echo "User $NAME exists but has no UniqueID; record is malformed, refusing to recycle." >&2
|
|
2675
|
+
exit 1
|
|
2676
|
+
fi
|
|
2677
|
+
echo "Recycling tombstone dscl record for $NAME (uid=$NEXT_UID, prior home $EXISTING_HOME \u2014 gone)"
|
|
2678
|
+
TOMBSTONE_REUSE=1
|
|
2656
2679
|
fi
|
|
2657
2680
|
|
|
2658
2681
|
# Phase G: agent home dirs live under /var/openape/homes/, not
|
|
@@ -2661,24 +2684,30 @@ fi
|
|
|
2661
2684
|
mkdir -p /var/openape/homes
|
|
2662
2685
|
chmod 755 /var/openape/homes
|
|
2663
2686
|
|
|
2664
|
-
|
|
2665
|
-
#
|
|
2666
|
-
#
|
|
2667
|
-
NEXT_UID=
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2687
|
+
if [ "$TOMBSTONE_REUSE" = "0" ]; then
|
|
2688
|
+
# Pick the next free UID in the [200, 500) hidden service-account range.
|
|
2689
|
+
# Starts the running max at 199 so an empty range yields 200 after the
|
|
2690
|
+
# floor check; otherwise NEXT_UID = max(existing in-range UIDs) + 1.
|
|
2691
|
+
NEXT_UID=199
|
|
2692
|
+
for uid in $(dscl . -list /Users UniqueID | awk '$2 >= 200 && $2 < 500 {print $2}'); do
|
|
2693
|
+
if [ "$uid" -ge "$NEXT_UID" ]; then
|
|
2694
|
+
NEXT_UID=$((uid + 1))
|
|
2695
|
+
fi
|
|
2696
|
+
done
|
|
2697
|
+
if [ "$NEXT_UID" -lt 200 ]; then
|
|
2698
|
+
NEXT_UID=200
|
|
2671
2699
|
fi
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
fi
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
exit 1
|
|
2700
|
+
if [ "$NEXT_UID" -ge 500 ]; then
|
|
2701
|
+
echo "No free UID in [200, 500) \u2014 refusing to clobber a real user." >&2
|
|
2702
|
+
exit 1
|
|
2703
|
+
fi
|
|
2704
|
+
|
|
2705
|
+
dscl . -create "/Users/$NAME"
|
|
2679
2706
|
fi
|
|
2680
2707
|
|
|
2681
|
-
dscl . -create
|
|
2708
|
+
# Idempotent attribute writes \u2014 \`dscl . -create\` on an existing
|
|
2709
|
+
# property overwrites in place, so the tombstone-reuse path lands
|
|
2710
|
+
# the same end-state as a fresh create.
|
|
2682
2711
|
dscl . -create "/Users/$NAME" UserShell "$SHELL_PATH"
|
|
2683
2712
|
dscl . -create "/Users/$NAME" RealName "OpenApe Agent $NAME"
|
|
2684
2713
|
dscl . -create "/Users/$NAME" UniqueID "$NEXT_UID"
|
|
@@ -2725,34 +2754,37 @@ mkdir -p "$HOME_DIR/Library/Logs" "$HOME_DIR/.openape/agent/tasks"
|
|
|
2725
2754
|
function buildTroopBootstrapBlock(_troop, _name) {
|
|
2726
2755
|
return "";
|
|
2727
2756
|
}
|
|
2728
|
-
function
|
|
2757
|
+
function runPhaseGTeardownInProcess(input) {
|
|
2729
2758
|
const { name, homeDir } = input;
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2759
|
+
let uid = null;
|
|
2760
|
+
try {
|
|
2761
|
+
const out = execFileSync2("/usr/bin/dscl", [".", "-read", `/Users/${name}`, "UniqueID"], { encoding: "utf8" });
|
|
2762
|
+
const m = out.match(/UniqueID:\s*(\d+)/);
|
|
2763
|
+
if (m) uid = m[1];
|
|
2764
|
+
} catch {
|
|
2765
|
+
}
|
|
2766
|
+
if (uid) {
|
|
2767
|
+
try {
|
|
2768
|
+
execFileSync2("/bin/launchctl", ["bootout", `user/${uid}`], { stdio: "ignore" });
|
|
2769
|
+
} catch {
|
|
2770
|
+
}
|
|
2771
|
+
try {
|
|
2772
|
+
execFileSync2("/usr/bin/pkill", ["-9", "-u", uid], { stdio: "ignore" });
|
|
2773
|
+
} catch {
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
const agentDir = `/var/openape/agents/${name}`;
|
|
2777
|
+
try {
|
|
2778
|
+
rmSync(agentDir, { recursive: true, force: true });
|
|
2779
|
+
} catch {
|
|
2780
|
+
}
|
|
2781
|
+
if (homeDir && homeDir !== "/" && homeDir.startsWith("/var/openape/homes/")) {
|
|
2782
|
+
try {
|
|
2783
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
2784
|
+
} catch {
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
console.log(`OK Phase-G teardown done for ${name} (dscl record kept as tombstone)`);
|
|
2756
2788
|
}
|
|
2757
2789
|
function buildDestroyTeardownScript(input) {
|
|
2758
2790
|
const { name, homeDir, adminUser } = input;
|
|
@@ -2876,7 +2908,7 @@ print(json.dumps(out))
|
|
|
2876
2908
|
`;
|
|
2877
2909
|
|
|
2878
2910
|
// src/lib/macos-user.ts
|
|
2879
|
-
import { execFileSync as
|
|
2911
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
2880
2912
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
2881
2913
|
function isDarwin() {
|
|
2882
2914
|
return process.platform === "darwin";
|
|
@@ -2884,7 +2916,7 @@ function isDarwin() {
|
|
|
2884
2916
|
function readMacOSUser(name) {
|
|
2885
2917
|
let output;
|
|
2886
2918
|
try {
|
|
2887
|
-
output =
|
|
2919
|
+
output = execFileSync3("dscl", [".", "-read", `/Users/${name}`], {
|
|
2888
2920
|
encoding: "utf-8",
|
|
2889
2921
|
stdio: ["ignore", "pipe", "pipe"]
|
|
2890
2922
|
});
|
|
@@ -2904,7 +2936,7 @@ function readMacOSUser(name) {
|
|
|
2904
2936
|
function listMacOSUserNames() {
|
|
2905
2937
|
let output;
|
|
2906
2938
|
try {
|
|
2907
|
-
output =
|
|
2939
|
+
output = execFileSync3("dscl", [".", "-list", "/Users"], {
|
|
2908
2940
|
encoding: "utf-8",
|
|
2909
2941
|
stdio: ["ignore", "pipe", "pipe"]
|
|
2910
2942
|
});
|
|
@@ -2917,7 +2949,7 @@ function listMacOSUserNames() {
|
|
|
2917
2949
|
}
|
|
2918
2950
|
function whichBinary(name) {
|
|
2919
2951
|
try {
|
|
2920
|
-
const out =
|
|
2952
|
+
const out = execFileSync3("which", [name], {
|
|
2921
2953
|
encoding: "utf-8",
|
|
2922
2954
|
stdio: ["ignore", "pipe", "ignore"]
|
|
2923
2955
|
}).trim();
|
|
@@ -2994,7 +3026,7 @@ PY
|
|
|
2994
3026
|
chmod 600 "$F"
|
|
2995
3027
|
`;
|
|
2996
3028
|
consola18.start(`Adding ${email} to ${agent}'s allowlist\u2026`);
|
|
2997
|
-
|
|
3029
|
+
execFileSync4(apes, ["run", "--as", agent, "--wait", "--", "bash", "-c", script], { stdio: "inherit" });
|
|
2998
3030
|
consola18.success(`${agent} will auto-accept future contact requests from ${email} (within ~30s of next bridge connect).`);
|
|
2999
3031
|
}
|
|
3000
3032
|
});
|
|
@@ -3003,8 +3035,8 @@ function shQuote2(s) {
|
|
|
3003
3035
|
}
|
|
3004
3036
|
|
|
3005
3037
|
// src/commands/agents/destroy.ts
|
|
3006
|
-
import { execFileSync as
|
|
3007
|
-
import { mkdtempSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
3038
|
+
import { execFileSync as execFileSync5 } from "child_process";
|
|
3039
|
+
import { mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
3008
3040
|
import { tmpdir, userInfo } from "os";
|
|
3009
3041
|
import { join as join3 } from "path";
|
|
3010
3042
|
import { defineCommand as defineCommand21 } from "citty";
|
|
@@ -3136,6 +3168,10 @@ var destroyAgentCommand = defineCommand21({
|
|
|
3136
3168
|
"keep-os-user": {
|
|
3137
3169
|
type: "boolean",
|
|
3138
3170
|
description: "Skip OS-side teardown. Useful for CI where the agent has no OS user."
|
|
3171
|
+
},
|
|
3172
|
+
"root-stage": {
|
|
3173
|
+
type: "boolean",
|
|
3174
|
+
description: "Internal \u2014 destroy.ts re-invokes itself via `apes run --as root --` with this flag set, then runs only the Phase-G teardown (rm home, launchctl bootout, kill processes). Skips IdP + auth + interactive prompts since those already ran in the outer pass."
|
|
3139
3175
|
}
|
|
3140
3176
|
},
|
|
3141
3177
|
async run({ args }) {
|
|
@@ -3145,6 +3181,15 @@ var destroyAgentCommand = defineCommand21({
|
|
|
3145
3181
|
`Invalid agent name "${name}". Must match /^[a-z][a-z0-9-]{0,23}$/.`
|
|
3146
3182
|
);
|
|
3147
3183
|
}
|
|
3184
|
+
if (args["root-stage"]) {
|
|
3185
|
+
if (process.geteuid?.() !== 0) {
|
|
3186
|
+
throw new CliError("--root-stage was passed but this process is not running as root. Refusing to continue.");
|
|
3187
|
+
}
|
|
3188
|
+
const homeDir = readMacOSUser(name)?.homeDir ?? `/var/openape/homes/${name}`;
|
|
3189
|
+
consola19.start(`Running teardown for ${name} (Phase-G, root-stage)\u2026`);
|
|
3190
|
+
runPhaseGTeardownInProcess({ name, homeDir });
|
|
3191
|
+
return;
|
|
3192
|
+
}
|
|
3148
3193
|
const auth = loadAuth();
|
|
3149
3194
|
if (!auth) {
|
|
3150
3195
|
throw new CliError("Not authenticated. Run `apes login` first.");
|
|
@@ -3199,15 +3244,24 @@ ${consequences.join("\n")}`);
|
|
|
3199
3244
|
const homeDir = osUser?.homeDir ?? `/Users/${name}`;
|
|
3200
3245
|
const isPhaseG = homeDir.startsWith("/var/openape/homes/");
|
|
3201
3246
|
if (isPhaseG) {
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
writeFileSync2(scriptPath, script, { mode: 448 });
|
|
3247
|
+
if (process.geteuid?.() === 0) {
|
|
3248
|
+
consola19.start("Running teardown (Phase G \u2014 already root, no grant needed)\u2026");
|
|
3249
|
+
runPhaseGTeardownInProcess({ name, homeDir });
|
|
3250
|
+
} else {
|
|
3207
3251
|
consola19.start("Running teardown (Phase G \u2014 no admin password needed)\u2026");
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3252
|
+
execFileSync5("apes", [
|
|
3253
|
+
"run",
|
|
3254
|
+
"--as",
|
|
3255
|
+
"root",
|
|
3256
|
+
"--wait",
|
|
3257
|
+
"--",
|
|
3258
|
+
"apes",
|
|
3259
|
+
"agents",
|
|
3260
|
+
"destroy",
|
|
3261
|
+
name,
|
|
3262
|
+
"--force",
|
|
3263
|
+
"--root-stage"
|
|
3264
|
+
], { stdio: "inherit" });
|
|
3211
3265
|
}
|
|
3212
3266
|
consola19.info(`dscl record /Users/${name} kept as tombstone (hidden, no home). Run \`sudo sysadminctl -deleteUser ${name}\` to fully remove.`);
|
|
3213
3267
|
} else {
|
|
@@ -3235,14 +3289,14 @@ ${consequences.join("\n")}`);
|
|
|
3235
3289
|
const script = buildDestroyTeardownScript({ name, homeDir, adminUser });
|
|
3236
3290
|
writeFileSync2(scriptPath, script, { mode: 448 });
|
|
3237
3291
|
consola19.start("Running teardown via sudo\u2026");
|
|
3238
|
-
|
|
3292
|
+
execFileSync5(sudo, ["-S", "--prompt=", "--", "bash", scriptPath], {
|
|
3239
3293
|
input: `${adminPassword}
|
|
3240
3294
|
${adminPassword}
|
|
3241
3295
|
`,
|
|
3242
3296
|
stdio: ["pipe", "inherit", "inherit"]
|
|
3243
3297
|
});
|
|
3244
3298
|
} finally {
|
|
3245
|
-
|
|
3299
|
+
rmSync2(scratch, { recursive: true, force: true });
|
|
3246
3300
|
}
|
|
3247
3301
|
}
|
|
3248
3302
|
}
|
|
@@ -3768,8 +3822,8 @@ async function handleInbound(msg, sessions) {
|
|
|
3768
3822
|
}
|
|
3769
3823
|
|
|
3770
3824
|
// src/commands/agents/spawn.ts
|
|
3771
|
-
import { execFileSync as
|
|
3772
|
-
import { mkdtempSync as mkdtempSync2, rmSync as
|
|
3825
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
3826
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
3773
3827
|
import { tmpdir as tmpdir2 } from "os";
|
|
3774
3828
|
import { join as join7 } from "path";
|
|
3775
3829
|
import { defineCommand as defineCommand26 } from "citty";
|
|
@@ -3884,7 +3938,7 @@ function generateKeyPairInMemory() {
|
|
|
3884
3938
|
}
|
|
3885
3939
|
|
|
3886
3940
|
// src/lib/llm-bridge.ts
|
|
3887
|
-
import { execFileSync as
|
|
3941
|
+
import { execFileSync as execFileSync6 } from "child_process";
|
|
3888
3942
|
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
|
|
3889
3943
|
import { homedir as homedir8 } from "os";
|
|
3890
3944
|
import { dirname as dirname2, join as join6 } from "path";
|
|
@@ -3928,7 +3982,7 @@ function captureHostBinDirs() {
|
|
|
3928
3982
|
for (const bin of ["node", "ape-agent", "apes"]) {
|
|
3929
3983
|
let resolved;
|
|
3930
3984
|
try {
|
|
3931
|
-
resolved =
|
|
3985
|
+
resolved = execFileSync6("/usr/bin/which", [bin], { encoding: "utf8" }).trim();
|
|
3932
3986
|
} catch {
|
|
3933
3987
|
const installCmd = bin === "ape-agent" ? "npm i -g @openape/ape-agent" : bin === "apes" ? "npm i -g @openape/apes" : "install Node.js (e.g. brew install node)";
|
|
3934
3988
|
throw new Error(`'${bin}' not found on host PATH. ${installCmd} before spawning agents \u2014 the bridge runtime resolves these at spawn time and bakes the dir into the agent's launchd plist.`);
|
|
@@ -4192,11 +4246,11 @@ and try again.`
|
|
|
4192
4246
|
const alreadyRoot = process.getuid?.() === 0;
|
|
4193
4247
|
if (alreadyRoot) {
|
|
4194
4248
|
consola23.start("Running privileged setup directly (already root)\u2026");
|
|
4195
|
-
|
|
4249
|
+
execFileSync7("bash", [scriptPath], { stdio: "inherit" });
|
|
4196
4250
|
} else {
|
|
4197
4251
|
consola23.start("Running privileged setup as root via `apes run --as root --wait`\u2026");
|
|
4198
4252
|
consola23.info("You will be asked to approve the as=root grant in your DDISA inbox; this command blocks until you do.");
|
|
4199
|
-
|
|
4253
|
+
execFileSync7(apes, ["run", "--as", "root", "--wait", "--", "bash", scriptPath], { stdio: "inherit" });
|
|
4200
4254
|
}
|
|
4201
4255
|
try {
|
|
4202
4256
|
const uid = readMacOSUidOrNull(name);
|
|
@@ -4225,7 +4279,7 @@ and try again.`
|
|
|
4225
4279
|
console.log("Run as the agent with:");
|
|
4226
4280
|
console.log(` apes run --as ${name} -- claude --session-name ${name} --dangerously-skip-permissions`);
|
|
4227
4281
|
} finally {
|
|
4228
|
-
|
|
4282
|
+
rmSync3(scratch, { recursive: true, force: true });
|
|
4229
4283
|
}
|
|
4230
4284
|
}
|
|
4231
4285
|
});
|
|
@@ -4253,18 +4307,18 @@ async function resolveClaudeToken(opts) {
|
|
|
4253
4307
|
}
|
|
4254
4308
|
|
|
4255
4309
|
// src/commands/agents/sync.ts
|
|
4256
|
-
import { chownSync, existsSync as existsSync10, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync9, rmSync as
|
|
4310
|
+
import { chownSync, existsSync as existsSync10, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync9, rmSync as rmSync4, statSync, writeFileSync as writeFileSync5 } from "fs";
|
|
4257
4311
|
import { homedir as homedir9 } from "os";
|
|
4258
4312
|
import { join as join8 } from "path";
|
|
4259
4313
|
import { defineCommand as defineCommand27 } from "citty";
|
|
4260
4314
|
import consola24 from "consola";
|
|
4261
4315
|
|
|
4262
4316
|
// src/lib/macos-host.ts
|
|
4263
|
-
import { execFileSync as
|
|
4317
|
+
import { execFileSync as execFileSync8 } from "child_process";
|
|
4264
4318
|
import { hostname as hostname3 } from "os";
|
|
4265
4319
|
function getHostId() {
|
|
4266
4320
|
try {
|
|
4267
|
-
const output =
|
|
4321
|
+
const output = execFileSync8(
|
|
4268
4322
|
"/usr/sbin/ioreg",
|
|
4269
4323
|
["-d2", "-c", "IOPlatformExpertDevice"],
|
|
4270
4324
|
{ encoding: "utf8", timeout: 2e3 }
|
|
@@ -4397,7 +4451,7 @@ var syncAgentCommand = defineCommand27({
|
|
|
4397
4451
|
for (const entry of readdirSync(skillsDir)) {
|
|
4398
4452
|
if (incomingNames.has(entry)) continue;
|
|
4399
4453
|
try {
|
|
4400
|
-
|
|
4454
|
+
rmSync4(join8(skillsDir, entry), { recursive: true, force: true });
|
|
4401
4455
|
} catch {
|
|
4402
4456
|
}
|
|
4403
4457
|
}
|
|
@@ -4438,7 +4492,7 @@ var agentsCommand = defineCommand28({
|
|
|
4438
4492
|
import { defineCommand as defineCommand36 } from "citty";
|
|
4439
4493
|
|
|
4440
4494
|
// src/commands/nest/authorize.ts
|
|
4441
|
-
import { execFileSync as
|
|
4495
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
4442
4496
|
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
|
|
4443
4497
|
import { join as join10 } from "path";
|
|
4444
4498
|
import { defineCommand as defineCommand30 } from "citty";
|
|
@@ -4605,7 +4659,7 @@ var authorizeNestCommand = defineCommand30({
|
|
|
4605
4659
|
cmdArgs.push("--expires-in", args["expires-in"]);
|
|
4606
4660
|
}
|
|
4607
4661
|
try {
|
|
4608
|
-
|
|
4662
|
+
execFileSync9("apes", cmdArgs, { stdio: "inherit" });
|
|
4609
4663
|
} catch (err) {
|
|
4610
4664
|
throw new CliError(err instanceof Error ? err.message : String(err));
|
|
4611
4665
|
}
|
|
@@ -4615,7 +4669,7 @@ var authorizeNestCommand = defineCommand30({
|
|
|
4615
4669
|
});
|
|
4616
4670
|
|
|
4617
4671
|
// src/commands/nest/destroy.ts
|
|
4618
|
-
import { execFileSync as
|
|
4672
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
4619
4673
|
import { defineCommand as defineCommand31 } from "citty";
|
|
4620
4674
|
import consola27 from "consola";
|
|
4621
4675
|
var destroyNestCommand = defineCommand31({
|
|
@@ -4629,7 +4683,7 @@ var destroyNestCommand = defineCommand31({
|
|
|
4629
4683
|
async run({ args }) {
|
|
4630
4684
|
const name = String(args.name);
|
|
4631
4685
|
try {
|
|
4632
|
-
|
|
4686
|
+
execFileSync10("apes", ["run", "--as", "root", "--wait", "--", "apes", "agents", "destroy", name, "--force"], { stdio: "inherit" });
|
|
4633
4687
|
consola27.success(`Nest will tear down ${name}'s pm2 process on its next reconcile (\u22642s).`);
|
|
4634
4688
|
} catch (err) {
|
|
4635
4689
|
const status = err.status ?? 1;
|
|
@@ -4639,7 +4693,7 @@ var destroyNestCommand = defineCommand31({
|
|
|
4639
4693
|
});
|
|
4640
4694
|
|
|
4641
4695
|
// src/commands/nest/install.ts
|
|
4642
|
-
import { execFileSync as
|
|
4696
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
4643
4697
|
import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
|
|
4644
4698
|
import { homedir as homedir11, userInfo as userInfo2 } from "os";
|
|
4645
4699
|
import { dirname as dirname3, join as join11 } from "path";
|
|
@@ -4838,10 +4892,10 @@ var installNestCommand = defineCommand32({
|
|
|
4838
4892
|
}
|
|
4839
4893
|
const uid = userInfo2().uid;
|
|
4840
4894
|
try {
|
|
4841
|
-
|
|
4895
|
+
execFileSync11("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL}`], { stdio: "ignore" });
|
|
4842
4896
|
} catch {
|
|
4843
4897
|
}
|
|
4844
|
-
|
|
4898
|
+
execFileSync11("/bin/launchctl", ["bootstrap", `gui/${uid}`, plistPath()], { stdio: "inherit" });
|
|
4845
4899
|
consola28.success(`Nest daemon bootstrapped \u2014 http://127.0.0.1:${port}`);
|
|
4846
4900
|
consola28.info("");
|
|
4847
4901
|
consola28.info("Next steps for zero-prompt spawn \u2014 both one-time:");
|
|
@@ -4883,7 +4937,7 @@ var listNestCommand = defineCommand33({
|
|
|
4883
4937
|
});
|
|
4884
4938
|
|
|
4885
4939
|
// src/commands/nest/spawn.ts
|
|
4886
|
-
import { execFileSync as
|
|
4940
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
4887
4941
|
import { defineCommand as defineCommand34 } from "citty";
|
|
4888
4942
|
import consola30 from "consola";
|
|
4889
4943
|
var spawnNestCommand = defineCommand34({
|
|
@@ -4916,7 +4970,7 @@ var spawnNestCommand = defineCommand34({
|
|
|
4916
4970
|
if (typeof args["bridge-base-url"] === "string") apesArgs.push("--bridge-base-url", args["bridge-base-url"]);
|
|
4917
4971
|
if (typeof args["bridge-model"] === "string") apesArgs.push("--bridge-model", args["bridge-model"]);
|
|
4918
4972
|
try {
|
|
4919
|
-
|
|
4973
|
+
execFileSync12("apes", apesArgs, { stdio: "inherit" });
|
|
4920
4974
|
consola30.success(`Nest will pick up ${name} on its next reconcile (\u22642s).`);
|
|
4921
4975
|
} catch (err) {
|
|
4922
4976
|
const status = err.status ?? 1;
|
|
@@ -4926,7 +4980,7 @@ var spawnNestCommand = defineCommand34({
|
|
|
4926
4980
|
});
|
|
4927
4981
|
|
|
4928
4982
|
// src/commands/nest/uninstall.ts
|
|
4929
|
-
import { execFileSync as
|
|
4983
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
4930
4984
|
import { existsSync as existsSync14, unlinkSync } from "fs";
|
|
4931
4985
|
import { homedir as homedir12, userInfo as userInfo3 } from "os";
|
|
4932
4986
|
import { join as join12 } from "path";
|
|
@@ -4942,7 +4996,7 @@ var uninstallNestCommand = defineCommand35({
|
|
|
4942
4996
|
const uid = userInfo3().uid;
|
|
4943
4997
|
const path2 = join12(homedir12(), "Library", "LaunchAgents", `${PLIST_LABEL2}.plist`);
|
|
4944
4998
|
try {
|
|
4945
|
-
|
|
4999
|
+
execFileSync13("/bin/launchctl", ["bootout", `gui/${uid}/${PLIST_LABEL2}`], { stdio: "ignore" });
|
|
4946
5000
|
consola31.success("Nest daemon stopped");
|
|
4947
5001
|
} catch {
|
|
4948
5002
|
consola31.info("Nest daemon was not loaded");
|
|
@@ -5496,7 +5550,7 @@ var adapterCommand = defineCommand41({
|
|
|
5496
5550
|
});
|
|
5497
5551
|
|
|
5498
5552
|
// src/commands/run.ts
|
|
5499
|
-
import { execFileSync as
|
|
5553
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
5500
5554
|
import { hostname as hostname5 } from "os";
|
|
5501
5555
|
import { basename } from "path";
|
|
5502
5556
|
import { defineCommand as defineCommand42 } from "citty";
|
|
@@ -5774,7 +5828,7 @@ function execShellCommand(command) {
|
|
|
5774
5828
|
throw new CliError("No command to execute");
|
|
5775
5829
|
try {
|
|
5776
5830
|
const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
|
|
5777
|
-
|
|
5831
|
+
execFileSync14(command[0], command.slice(1), {
|
|
5778
5832
|
stdio: "inherit",
|
|
5779
5833
|
env: inheritedEnv
|
|
5780
5834
|
});
|
|
@@ -5943,7 +5997,7 @@ function executeWithGrantToken(opts) {
|
|
|
5943
5997
|
consola36.info(`Executing: ${command.join(" ")}`);
|
|
5944
5998
|
try {
|
|
5945
5999
|
const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
|
|
5946
|
-
|
|
6000
|
+
execFileSync14(args["escapes-path"] || "escapes", ["--grant", token, "--", ...command], {
|
|
5947
6001
|
stdio: "inherit",
|
|
5948
6002
|
env: inheritedEnv
|
|
5949
6003
|
});
|
|
@@ -6014,7 +6068,7 @@ note = "VPC-internal hostname suffix"
|
|
|
6014
6068
|
|
|
6015
6069
|
// src/proxy/local-proxy.ts
|
|
6016
6070
|
import { spawn } from "child_process";
|
|
6017
|
-
import { mkdtempSync as mkdtempSync3, rmSync as
|
|
6071
|
+
import { mkdtempSync as mkdtempSync3, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "fs";
|
|
6018
6072
|
import { createRequire } from "module";
|
|
6019
6073
|
import { tmpdir as tmpdir3 } from "os";
|
|
6020
6074
|
import { dirname as dirname4, join as join13, resolve as resolve3 } from "path";
|
|
@@ -6039,7 +6093,7 @@ async function startEphemeralProxy(configToml) {
|
|
|
6039
6093
|
});
|
|
6040
6094
|
const cleanupTmp = () => {
|
|
6041
6095
|
try {
|
|
6042
|
-
|
|
6096
|
+
rmSync5(tmpDir, { recursive: true, force: true });
|
|
6043
6097
|
} catch {
|
|
6044
6098
|
}
|
|
6045
6099
|
};
|
|
@@ -6466,7 +6520,7 @@ var mcpCommand = defineCommand48({
|
|
|
6466
6520
|
if (transport !== "stdio" && transport !== "sse") {
|
|
6467
6521
|
throw new Error('Transport must be "stdio" or "sse"');
|
|
6468
6522
|
}
|
|
6469
|
-
const { startMcpServer } = await import("./server-
|
|
6523
|
+
const { startMcpServer } = await import("./server-KR6GVKRI.js");
|
|
6470
6524
|
await startMcpServer(transport, port);
|
|
6471
6525
|
}
|
|
6472
6526
|
});
|
|
@@ -6474,7 +6528,7 @@ var mcpCommand = defineCommand48({
|
|
|
6474
6528
|
// src/commands/init/index.ts
|
|
6475
6529
|
import { existsSync as existsSync15, copyFileSync, writeFileSync as writeFileSync9 } from "fs";
|
|
6476
6530
|
import { randomBytes } from "crypto";
|
|
6477
|
-
import { execFileSync as
|
|
6531
|
+
import { execFileSync as execFileSync15 } from "child_process";
|
|
6478
6532
|
import { join as join14 } from "path";
|
|
6479
6533
|
import { defineCommand as defineCommand49 } from "citty";
|
|
6480
6534
|
import consola40 from "consola";
|
|
@@ -6486,11 +6540,11 @@ async function downloadTemplate(repo, targetDir) {
|
|
|
6486
6540
|
function installDeps(dir) {
|
|
6487
6541
|
const hasLockFile = (name) => existsSync15(join14(dir, name));
|
|
6488
6542
|
if (hasLockFile("pnpm-lock.yaml")) {
|
|
6489
|
-
|
|
6543
|
+
execFileSync15("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
6490
6544
|
} else if (hasLockFile("bun.lockb")) {
|
|
6491
|
-
|
|
6545
|
+
execFileSync15("bun", ["install"], { cwd: dir, stdio: "inherit" });
|
|
6492
6546
|
} else {
|
|
6493
|
-
|
|
6547
|
+
execFileSync15("npm", ["install"], { cwd: dir, stdio: "inherit" });
|
|
6494
6548
|
}
|
|
6495
6549
|
}
|
|
6496
6550
|
async function promptChoice(message, choices) {
|
|
@@ -7104,7 +7158,7 @@ async function bestEffortGrantCount(idp) {
|
|
|
7104
7158
|
}
|
|
7105
7159
|
}
|
|
7106
7160
|
async function runHealth(args) {
|
|
7107
|
-
const version = true ? "1.
|
|
7161
|
+
const version = true ? "1.24.1" : "0.0.0";
|
|
7108
7162
|
const auth = loadAuth();
|
|
7109
7163
|
if (!auth) {
|
|
7110
7164
|
throw new CliError("Not logged in. Run `apes login` first.", 1);
|
|
@@ -7377,10 +7431,10 @@ if (shellRewrite) {
|
|
|
7377
7431
|
if (shellRewrite.action === "rewrite") {
|
|
7378
7432
|
process.argv = shellRewrite.argv;
|
|
7379
7433
|
} else if (shellRewrite.action === "version") {
|
|
7380
|
-
console.log(`ape-shell ${"1.
|
|
7434
|
+
console.log(`ape-shell ${"1.24.1"} (OpenApe DDISA shell wrapper)`);
|
|
7381
7435
|
process.exit(0);
|
|
7382
7436
|
} else if (shellRewrite.action === "help") {
|
|
7383
|
-
console.log(`ape-shell ${"1.
|
|
7437
|
+
console.log(`ape-shell ${"1.24.1"} \u2014 OpenApe DDISA shell wrapper`);
|
|
7384
7438
|
console.log("");
|
|
7385
7439
|
console.log("Usage:");
|
|
7386
7440
|
console.log(" ape-shell Start interactive grant-mediated REPL");
|
|
@@ -7438,7 +7492,7 @@ var configCommand = defineCommand60({
|
|
|
7438
7492
|
var main = defineCommand60({
|
|
7439
7493
|
meta: {
|
|
7440
7494
|
name: "apes",
|
|
7441
|
-
version: "1.
|
|
7495
|
+
version: "1.24.1",
|
|
7442
7496
|
description: "Unified CLI for OpenApe"
|
|
7443
7497
|
},
|
|
7444
7498
|
subCommands: {
|
|
@@ -7495,7 +7549,7 @@ async function maybeRefreshAuth() {
|
|
|
7495
7549
|
}
|
|
7496
7550
|
}
|
|
7497
7551
|
await maybeRefreshAuth();
|
|
7498
|
-
await maybeWarnStaleVersion("1.
|
|
7552
|
+
await maybeWarnStaleVersion("1.24.1").catch(() => {
|
|
7499
7553
|
});
|
|
7500
7554
|
runMain(main).catch((err) => {
|
|
7501
7555
|
if (err instanceof CliExit) {
|