@openape/apes 0.19.0 → 0.21.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 +86 -31
- package/dist/cli.js.map +1 -1
- package/dist/{orchestrator-FJVDWH45.js → orchestrator-RWTALOSA.js} +5 -1
- package/dist/orchestrator-RWTALOSA.js.map +1 -0
- package/dist/{server-GYHLAJXV.js → server-UWKEQDNM.js} +2 -2
- package/package.json +1 -1
- package/dist/orchestrator-FJVDWH45.js.map +0 -1
- /package/dist/{server-GYHLAJXV.js.map → server-UWKEQDNM.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -96,7 +96,7 @@ function rewriteApeShellArgs(argv, argv0) {
|
|
|
96
96
|
import { defineCommand as defineCommand44, runMain } from "citty";
|
|
97
97
|
|
|
98
98
|
// src/commands/auth/login.ts
|
|
99
|
-
import { Buffer } from "buffer";
|
|
99
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
100
100
|
import { execFile } from "child_process";
|
|
101
101
|
import { createServer } from "http";
|
|
102
102
|
import { homedir as homedir2 } from "os";
|
|
@@ -394,7 +394,7 @@ async function loginWithKey(idp, keyPath, agentEmail) {
|
|
|
394
394
|
const { challenge } = await challengeResp.json();
|
|
395
395
|
const keyContent = readFileSync7(keyPath, "utf-8");
|
|
396
396
|
const privateKey = loadEd25519PrivateKey2(keyContent);
|
|
397
|
-
const signature = sign3(null,
|
|
397
|
+
const signature = sign3(null, Buffer2.from(challenge), privateKey).toString("base64");
|
|
398
398
|
const authenticateUrl = await getAgentAuthenticateEndpoint(idp);
|
|
399
399
|
const authResp = await fetch(authenticateUrl, {
|
|
400
400
|
method: "POST",
|
|
@@ -1754,7 +1754,7 @@ import { defineCommand as defineCommand20 } from "citty";
|
|
|
1754
1754
|
import consola18 from "consola";
|
|
1755
1755
|
|
|
1756
1756
|
// src/lib/agent-bootstrap.ts
|
|
1757
|
-
import { Buffer as
|
|
1757
|
+
import { Buffer as Buffer3 } from "buffer";
|
|
1758
1758
|
import { createPrivateKey, sign } from "crypto";
|
|
1759
1759
|
var AGENT_NAME_REGEX = /^[a-z][a-z0-9-]{0,23}$/;
|
|
1760
1760
|
var SSH_ED25519_PREFIX = "ssh-ed25519 ";
|
|
@@ -1779,7 +1779,7 @@ async function issueAgentToken(input) {
|
|
|
1779
1779
|
throw new Error(`Challenge failed (${challengeResp.status}): ${text}`);
|
|
1780
1780
|
}
|
|
1781
1781
|
const { challenge } = await challengeResp.json();
|
|
1782
|
-
const signature = sign(null,
|
|
1782
|
+
const signature = sign(null, Buffer3.from(challenge), privateKey).toString("base64");
|
|
1783
1783
|
const authenticateUrl = await getAgentAuthenticateEndpoint(input.idp);
|
|
1784
1784
|
const authResp = await fetch(authenticateUrl, {
|
|
1785
1785
|
method: "POST",
|
|
@@ -1811,6 +1811,25 @@ mkdir -p "$HOME_DIR/.claude/hooks"
|
|
|
1811
1811
|
cat > "$HOME_DIR/.claude/settings.json" ${shHeredoc(input.claudeSettingsJson)}
|
|
1812
1812
|
cat > "$HOME_DIR/.claude/hooks/bash-via-ape-shell.sh" ${shHeredoc(input.hookScriptSource)}
|
|
1813
1813
|
chmod 755 "$HOME_DIR/.claude/hooks/bash-via-ape-shell.sh"
|
|
1814
|
+
` : "";
|
|
1815
|
+
const claudeTokenBlock = input.claudeOauthToken ? `
|
|
1816
|
+
mkdir -p "$HOME_DIR/.config/openape"
|
|
1817
|
+
cat > "$HOME_DIR/.config/openape/claude-token.env" ${shHeredoc(`# Auto-generated by 'apes agents spawn'. chmod 600 \u2014 contains a long-lived
|
|
1818
|
+
# Claude Code OAuth token. Rotate by editing this file in place; the
|
|
1819
|
+
# .zshenv / .profile source-lines below will pick it up automatically.
|
|
1820
|
+
export CLAUDE_CODE_OAUTH_TOKEN=${shQuote(input.claudeOauthToken)}
|
|
1821
|
+
`)}
|
|
1822
|
+
SOURCE_LINE='[ -f "$HOME/.config/openape/claude-token.env" ] && . "$HOME/.config/openape/claude-token.env"'
|
|
1823
|
+
for f in "$HOME_DIR/.zshenv" "$HOME_DIR/.profile"; do
|
|
1824
|
+
touch "$f"
|
|
1825
|
+
if ! grep -qF 'config/openape/claude-token.env' "$f" 2>/dev/null; then
|
|
1826
|
+
{
|
|
1827
|
+
echo ''
|
|
1828
|
+
echo '# OpenApe: load Claude Code OAuth token (added by apes agents spawn)'
|
|
1829
|
+
echo "$SOURCE_LINE"
|
|
1830
|
+
} >> "$f"
|
|
1831
|
+
fi
|
|
1832
|
+
done
|
|
1814
1833
|
` : "";
|
|
1815
1834
|
return `#!/bin/bash
|
|
1816
1835
|
set -euo pipefail
|
|
@@ -1854,13 +1873,17 @@ mkdir -p "$HOME_DIR/.ssh" "$HOME_DIR/.config/apes"
|
|
|
1854
1873
|
cat > "$HOME_DIR/.ssh/id_ed25519" ${shHeredoc(privatePemForHeredoc.trimEnd())}
|
|
1855
1874
|
cat > "$HOME_DIR/.ssh/id_ed25519.pub" ${shHeredoc(`${input.publicKeySshLine}`)}
|
|
1856
1875
|
cat > "$HOME_DIR/.config/apes/auth.json" ${shHeredoc(input.authJson)}
|
|
1857
|
-
${claudeBlock}
|
|
1876
|
+
${claudeBlock}${claudeTokenBlock}
|
|
1858
1877
|
chown -R "$NAME:staff" "$HOME_DIR"
|
|
1859
1878
|
chmod 700 "$HOME_DIR/.ssh"
|
|
1860
1879
|
chmod 700 "$HOME_DIR/.config"
|
|
1861
1880
|
chmod 600 "$HOME_DIR/.ssh/id_ed25519"
|
|
1862
1881
|
chmod 644 "$HOME_DIR/.ssh/id_ed25519.pub"
|
|
1863
1882
|
chmod 600 "$HOME_DIR/.config/apes/auth.json"
|
|
1883
|
+
if [ -f "$HOME_DIR/.config/openape/claude-token.env" ]; then
|
|
1884
|
+
chmod 700 "$HOME_DIR/.config/openape"
|
|
1885
|
+
chmod 600 "$HOME_DIR/.config/openape/claude-token.env"
|
|
1886
|
+
fi
|
|
1864
1887
|
|
|
1865
1888
|
echo "OK $NAME uid=$NEXT_UID home=$HOME_DIR"
|
|
1866
1889
|
`;
|
|
@@ -2268,7 +2291,7 @@ import { defineCommand as defineCommand23 } from "citty";
|
|
|
2268
2291
|
import consola21 from "consola";
|
|
2269
2292
|
|
|
2270
2293
|
// src/lib/keygen.ts
|
|
2271
|
-
import { Buffer as
|
|
2294
|
+
import { Buffer as Buffer4 } from "buffer";
|
|
2272
2295
|
import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
2273
2296
|
import { generateKeyPairSync } from "crypto";
|
|
2274
2297
|
import { homedir as homedir4 } from "os";
|
|
@@ -2278,11 +2301,11 @@ function resolveKeyPath(p) {
|
|
|
2278
2301
|
}
|
|
2279
2302
|
function buildSshEd25519Line(rawPub) {
|
|
2280
2303
|
const keyTypeStr = "ssh-ed25519";
|
|
2281
|
-
const keyTypeLen =
|
|
2304
|
+
const keyTypeLen = Buffer4.alloc(4);
|
|
2282
2305
|
keyTypeLen.writeUInt32BE(keyTypeStr.length);
|
|
2283
|
-
const pubKeyLen =
|
|
2306
|
+
const pubKeyLen = Buffer4.alloc(4);
|
|
2284
2307
|
pubKeyLen.writeUInt32BE(rawPub.length);
|
|
2285
|
-
const blob =
|
|
2308
|
+
const blob = Buffer4.concat([keyTypeLen, Buffer4.from(keyTypeStr), pubKeyLen, rawPub]);
|
|
2286
2309
|
return `ssh-ed25519 ${blob.toString("base64")}`;
|
|
2287
2310
|
}
|
|
2288
2311
|
function readPublicKey(keyPath) {
|
|
@@ -2293,7 +2316,7 @@ function readPublicKey(keyPath) {
|
|
|
2293
2316
|
const keyContent = readFileSync4(keyPath, "utf-8");
|
|
2294
2317
|
const privateKey = loadEd25519PrivateKey(keyContent);
|
|
2295
2318
|
const jwk = privateKey.export({ format: "jwk" });
|
|
2296
|
-
const pubBytes =
|
|
2319
|
+
const pubBytes = Buffer4.from(jwk.x, "base64url");
|
|
2297
2320
|
return buildSshEd25519Line(pubBytes);
|
|
2298
2321
|
}
|
|
2299
2322
|
function generateAndSaveKey(keyPath) {
|
|
@@ -2306,7 +2329,7 @@ function generateAndSaveKey(keyPath) {
|
|
|
2306
2329
|
const privatePem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
2307
2330
|
writeFileSync2(resolved, privatePem, { mode: 384 });
|
|
2308
2331
|
const jwk = publicKey.export({ format: "jwk" });
|
|
2309
|
-
const pubBytes =
|
|
2332
|
+
const pubBytes = Buffer4.from(jwk.x, "base64url");
|
|
2310
2333
|
const pubKeyStr = buildSshEd25519Line(pubBytes);
|
|
2311
2334
|
writeFileSync2(`${resolved}.pub`, `${pubKeyStr}
|
|
2312
2335
|
`, { mode: 420 });
|
|
@@ -2316,7 +2339,7 @@ function generateKeyPairInMemory() {
|
|
|
2316
2339
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
2317
2340
|
const privatePem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
2318
2341
|
const jwk = publicKey.export({ format: "jwk" });
|
|
2319
|
-
const pubBytes =
|
|
2342
|
+
const pubBytes = Buffer4.from(jwk.x, "base64url");
|
|
2320
2343
|
return {
|
|
2321
2344
|
privatePem,
|
|
2322
2345
|
publicSshLine: buildSshEd25519Line(pubBytes)
|
|
@@ -2327,7 +2350,7 @@ function generateKeyPairInMemory() {
|
|
|
2327
2350
|
var spawnAgentCommand = defineCommand23({
|
|
2328
2351
|
meta: {
|
|
2329
2352
|
name: "spawn",
|
|
2330
|
-
description: "Provision a local macOS agent end-to-end (OS user, keypair, IdP agent,
|
|
2353
|
+
description: "Provision a local macOS agent end-to-end (OS user, keypair, IdP agent, Claude hook)"
|
|
2331
2354
|
},
|
|
2332
2355
|
args: {
|
|
2333
2356
|
name: {
|
|
@@ -2337,11 +2360,19 @@ var spawnAgentCommand = defineCommand23({
|
|
|
2337
2360
|
},
|
|
2338
2361
|
shell: {
|
|
2339
2362
|
type: "string",
|
|
2340
|
-
description: "
|
|
2363
|
+
description: "Login shell for the macOS user. Default: /bin/zsh. Pass $(which ape-shell) to opt into the grant-mediated REPL as login shell."
|
|
2341
2364
|
},
|
|
2342
2365
|
"no-claude-hook": {
|
|
2343
2366
|
type: "boolean",
|
|
2344
2367
|
description: "Skip writing ~/.claude/settings.json + the Bash-rewrite hook"
|
|
2368
|
+
},
|
|
2369
|
+
"claude-token": {
|
|
2370
|
+
type: "string",
|
|
2371
|
+
description: "Claude Code OAuth token (sk-ant-oat01-\u2026) from `claude setup-token`. Visible to ps \u2014 prefer --claude-token-stdin in scripts."
|
|
2372
|
+
},
|
|
2373
|
+
"claude-token-stdin": {
|
|
2374
|
+
type: "boolean",
|
|
2375
|
+
description: "Read the Claude Code OAuth token from stdin (paranoid form of --claude-token)."
|
|
2345
2376
|
}
|
|
2346
2377
|
},
|
|
2347
2378
|
async run({ args }) {
|
|
@@ -2364,10 +2395,7 @@ var spawnAgentCommand = defineCommand23({
|
|
|
2364
2395
|
if (!idp) {
|
|
2365
2396
|
throw new CliError("No IdP URL configured. Run `apes login` first.");
|
|
2366
2397
|
}
|
|
2367
|
-
const
|
|
2368
|
-
if (!apeShell) {
|
|
2369
|
-
throw new CliError("`ape-shell` not found on PATH. Install @openape/apes globally first.");
|
|
2370
|
-
}
|
|
2398
|
+
const loginShell = (args.shell ?? "/bin/zsh").toString();
|
|
2371
2399
|
const apes = whichBinary("apes");
|
|
2372
2400
|
if (!apes) {
|
|
2373
2401
|
throw new CliError("`apes` not found on PATH. Install @openape/apes globally first.");
|
|
@@ -2378,10 +2406,10 @@ var spawnAgentCommand = defineCommand23({
|
|
|
2378
2406
|
"`escapes` not found on PATH. spawn delegates the privileged setup phase to escapes; install it before running spawn."
|
|
2379
2407
|
);
|
|
2380
2408
|
}
|
|
2381
|
-
if (!isShellRegistered(
|
|
2409
|
+
if (!isShellRegistered(loginShell)) {
|
|
2382
2410
|
throw new CliError(
|
|
2383
|
-
`${
|
|
2384
|
-
echo ${
|
|
2411
|
+
`${loginShell} is not registered in /etc/shells. macOS refuses to set it as a login shell. Run:
|
|
2412
|
+
echo ${loginShell} | sudo tee -a /etc/shells
|
|
2385
2413
|
and try again.`
|
|
2386
2414
|
);
|
|
2387
2415
|
}
|
|
@@ -2411,15 +2439,20 @@ and try again.`
|
|
|
2411
2439
|
expiresAt: Math.floor(Date.now() / 1e3) + expiresIn
|
|
2412
2440
|
});
|
|
2413
2441
|
const includeClaudeHook = !args["no-claude-hook"];
|
|
2442
|
+
const claudeOauthToken = await resolveClaudeToken({
|
|
2443
|
+
flag: typeof args["claude-token"] === "string" ? args["claude-token"] : void 0,
|
|
2444
|
+
fromStdin: !!args["claude-token-stdin"]
|
|
2445
|
+
});
|
|
2414
2446
|
const script = buildSpawnSetupScript({
|
|
2415
2447
|
name,
|
|
2416
2448
|
homeDir,
|
|
2417
|
-
shellPath:
|
|
2449
|
+
shellPath: loginShell,
|
|
2418
2450
|
privateKeyPem: privatePem,
|
|
2419
2451
|
publicKeySshLine: publicSshLine,
|
|
2420
2452
|
authJson,
|
|
2421
2453
|
claudeSettingsJson: includeClaudeHook ? CLAUDE_SETTINGS_JSON : null,
|
|
2422
|
-
hookScriptSource: includeClaudeHook ? BASH_VIA_APE_SHELL_HOOK_SOURCE : null
|
|
2454
|
+
hookScriptSource: includeClaudeHook ? BASH_VIA_APE_SHELL_HOOK_SOURCE : null,
|
|
2455
|
+
claudeOauthToken
|
|
2423
2456
|
});
|
|
2424
2457
|
writeFileSync3(scriptPath, script, { mode: 448 });
|
|
2425
2458
|
consola21.start("Running privileged setup as root via `apes run --as root --wait`\u2026");
|
|
@@ -2434,6 +2467,28 @@ and try again.`
|
|
|
2434
2467
|
}
|
|
2435
2468
|
}
|
|
2436
2469
|
});
|
|
2470
|
+
async function resolveClaudeToken(opts) {
|
|
2471
|
+
if (opts.flag && opts.fromStdin) {
|
|
2472
|
+
throw new CliError("Pass --claude-token OR --claude-token-stdin, not both.");
|
|
2473
|
+
}
|
|
2474
|
+
let raw = null;
|
|
2475
|
+
if (typeof opts.flag === "string") {
|
|
2476
|
+
raw = opts.flag.trim();
|
|
2477
|
+
} else if (opts.fromStdin) {
|
|
2478
|
+
const chunks = [];
|
|
2479
|
+
for await (const chunk of process.stdin) {
|
|
2480
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
2481
|
+
}
|
|
2482
|
+
raw = Buffer.concat(chunks).toString("utf-8").trim();
|
|
2483
|
+
}
|
|
2484
|
+
if (!raw) return null;
|
|
2485
|
+
if (!raw.startsWith("sk-ant-oat01-")) {
|
|
2486
|
+
throw new CliError(
|
|
2487
|
+
`Claude token doesn't look right (expected sk-ant-oat01-\u2026). Run \`claude setup-token\` and paste the resulting token.`
|
|
2488
|
+
);
|
|
2489
|
+
}
|
|
2490
|
+
return raw;
|
|
2491
|
+
}
|
|
2437
2492
|
|
|
2438
2493
|
// src/commands/agents/index.ts
|
|
2439
2494
|
var agentsCommand = defineCommand24({
|
|
@@ -3701,7 +3756,7 @@ var mcpCommand = defineCommand32({
|
|
|
3701
3756
|
if (transport !== "stdio" && transport !== "sse") {
|
|
3702
3757
|
throw new Error('Transport must be "stdio" or "sse"');
|
|
3703
3758
|
}
|
|
3704
|
-
const { startMcpServer } = await import("./server-
|
|
3759
|
+
const { startMcpServer } = await import("./server-UWKEQDNM.js");
|
|
3705
3760
|
await startMcpServer(transport, port);
|
|
3706
3761
|
}
|
|
3707
3762
|
});
|
|
@@ -3861,7 +3916,7 @@ async function initIdP(targetDir) {
|
|
|
3861
3916
|
}
|
|
3862
3917
|
|
|
3863
3918
|
// src/commands/enroll.ts
|
|
3864
|
-
import { Buffer as
|
|
3919
|
+
import { Buffer as Buffer5 } from "buffer";
|
|
3865
3920
|
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
3866
3921
|
import { execFile as execFile2 } from "child_process";
|
|
3867
3922
|
import { sign as sign2 } from "crypto";
|
|
@@ -3892,7 +3947,7 @@ async function pollForEnrollment(idp, agentEmail, keyPath) {
|
|
|
3892
3947
|
});
|
|
3893
3948
|
if (challengeResp.ok) {
|
|
3894
3949
|
const { challenge } = await challengeResp.json();
|
|
3895
|
-
const signature = sign2(null,
|
|
3950
|
+
const signature = sign2(null, Buffer5.from(challenge), privateKey).toString("base64");
|
|
3896
3951
|
const authResp = await fetch(authenticateUrl, {
|
|
3897
3952
|
method: "POST",
|
|
3898
3953
|
headers: { "Content-Type": "application/json" },
|
|
@@ -4339,7 +4394,7 @@ async function bestEffortGrantCount(idp) {
|
|
|
4339
4394
|
}
|
|
4340
4395
|
}
|
|
4341
4396
|
async function runHealth(args) {
|
|
4342
|
-
const version = true ? "0.
|
|
4397
|
+
const version = true ? "0.21.0" : "0.0.0";
|
|
4343
4398
|
const auth = loadAuth();
|
|
4344
4399
|
if (!auth) {
|
|
4345
4400
|
throw new CliError("Not logged in. Run `apes login` first.", 1);
|
|
@@ -4541,10 +4596,10 @@ if (shellRewrite) {
|
|
|
4541
4596
|
if (shellRewrite.action === "rewrite") {
|
|
4542
4597
|
process.argv = shellRewrite.argv;
|
|
4543
4598
|
} else if (shellRewrite.action === "version") {
|
|
4544
|
-
console.log(`ape-shell ${"0.
|
|
4599
|
+
console.log(`ape-shell ${"0.21.0"} (OpenApe DDISA shell wrapper)`);
|
|
4545
4600
|
process.exit(0);
|
|
4546
4601
|
} else if (shellRewrite.action === "help") {
|
|
4547
|
-
console.log(`ape-shell ${"0.
|
|
4602
|
+
console.log(`ape-shell ${"0.21.0"} \u2014 OpenApe DDISA shell wrapper`);
|
|
4548
4603
|
console.log("");
|
|
4549
4604
|
console.log("Usage:");
|
|
4550
4605
|
console.log(" ape-shell Start interactive grant-mediated REPL");
|
|
@@ -4559,7 +4614,7 @@ if (shellRewrite) {
|
|
|
4559
4614
|
console.log(" --help, -h Show this help message");
|
|
4560
4615
|
process.exit(0);
|
|
4561
4616
|
} else if (shellRewrite.action === "interactive") {
|
|
4562
|
-
const { runInteractiveShell } = await import("./orchestrator-
|
|
4617
|
+
const { runInteractiveShell } = await import("./orchestrator-RWTALOSA.js");
|
|
4563
4618
|
await runInteractiveShell();
|
|
4564
4619
|
process.exit(0);
|
|
4565
4620
|
} else {
|
|
@@ -4602,7 +4657,7 @@ var configCommand = defineCommand44({
|
|
|
4602
4657
|
var main = defineCommand44({
|
|
4603
4658
|
meta: {
|
|
4604
4659
|
name: "apes",
|
|
4605
|
-
version: "0.
|
|
4660
|
+
version: "0.21.0",
|
|
4606
4661
|
description: "Unified CLI for OpenApe"
|
|
4607
4662
|
},
|
|
4608
4663
|
subCommands: {
|