@openape/apes 1.2.1 → 1.3.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
@@ -379,7 +379,7 @@ async function loginWithPKCE(idp) {
379
379
  consola2.success(`Logged in as ${payload.email || payload.sub}`);
380
380
  }
381
381
  async function loginWithKey(idp, keyPath, agentEmail) {
382
- const { readFileSync: readFileSync14 } = await import("fs");
382
+ const { readFileSync: readFileSync13 } = await import("fs");
383
383
  const { sign: sign3 } = await import("crypto");
384
384
  const { loadEd25519PrivateKey: loadEd25519PrivateKey2 } = await import("./ssh-key-YBNNG5K5.js");
385
385
  const challengeUrl = await getAgentChallengeEndpoint(idp);
@@ -392,7 +392,7 @@ async function loginWithKey(idp, keyPath, agentEmail) {
392
392
  throw new CliError(`Challenge failed: ${await challengeResp.text()}`);
393
393
  }
394
394
  const { challenge } = await challengeResp.json();
395
- const keyContent = readFileSync14(keyPath, "utf-8");
395
+ const keyContent = readFileSync13(keyPath, "utf-8");
396
396
  const privateKey = loadEd25519PrivateKey2(keyContent);
397
397
  const signature = sign3(null, Buffer2.from(challenge), privateKey).toString("base64");
398
398
  const authenticateUrl = await getAgentAuthenticateEndpoint(idp);
@@ -2851,9 +2851,18 @@ function taskTools(names) {
2851
2851
  function asOpenAiTools(tools) {
2852
2852
  return tools.map((t) => ({
2853
2853
  type: "function",
2854
- function: { name: t.name, description: t.description, parameters: t.parameters }
2854
+ function: { name: wireToolName(t.name), description: t.description, parameters: t.parameters }
2855
2855
  }));
2856
2856
  }
2857
+ function wireToolName(local) {
2858
+ return local.replace(/\./g, "_");
2859
+ }
2860
+ function localToolName(wire) {
2861
+ for (const t of Object.values(TOOLS)) {
2862
+ if (wireToolName(t.name) === wire) return t.name;
2863
+ }
2864
+ return wire;
2865
+ }
2857
2866
 
2858
2867
  // src/lib/agent-runtime.ts
2859
2868
  function previewJson(value, max = 500) {
@@ -2913,19 +2922,21 @@ async function runLoop(opts) {
2913
2922
  return result2;
2914
2923
  }
2915
2924
  for (const call of assistant.tool_calls) {
2916
- const tool = opts.tools.find((t) => t.name === call.function.name);
2925
+ const wireName = call.function.name;
2926
+ const localName = localToolName(wireName);
2927
+ const tool = opts.tools.find((t) => t.name === localName);
2917
2928
  let parsedArgs;
2918
2929
  try {
2919
2930
  parsedArgs = JSON.parse(call.function.arguments);
2920
2931
  } catch {
2921
2932
  parsedArgs = {};
2922
2933
  }
2923
- opts.handlers?.onToolCall?.({ name: call.function.name, args: parsedArgs });
2924
- trace.push({ step, type: "tool_call", tool: call.function.name, preview: previewJson(parsedArgs) });
2934
+ opts.handlers?.onToolCall?.({ name: localName, args: parsedArgs });
2935
+ trace.push({ step, type: "tool_call", tool: localName, preview: previewJson(parsedArgs) });
2925
2936
  let result2;
2926
2937
  let isError = false;
2927
2938
  if (!tool) {
2928
- result2 = `unknown tool: ${call.function.name}`;
2939
+ result2 = `unknown tool: ${localName}`;
2929
2940
  isError = true;
2930
2941
  } else {
2931
2942
  try {
@@ -2936,16 +2947,16 @@ async function runLoop(opts) {
2936
2947
  }
2937
2948
  }
2938
2949
  if (isError) {
2939
- opts.handlers?.onToolError?.({ name: call.function.name, error: String(result2) });
2940
- trace.push({ step, type: "tool_error", tool: call.function.name, preview: previewJson(result2) });
2950
+ opts.handlers?.onToolError?.({ name: localName, error: String(result2) });
2951
+ trace.push({ step, type: "tool_error", tool: localName, preview: previewJson(result2) });
2941
2952
  } else {
2942
- opts.handlers?.onToolResult?.({ name: call.function.name, result: result2 });
2943
- trace.push({ step, type: "tool_result", tool: call.function.name, preview: previewJson(result2) });
2953
+ opts.handlers?.onToolResult?.({ name: localName, result: result2 });
2954
+ trace.push({ step, type: "tool_result", tool: localName, preview: previewJson(result2) });
2944
2955
  }
2945
2956
  messages.push({
2946
2957
  role: "tool",
2947
2958
  tool_call_id: call.id,
2948
- name: call.function.name,
2959
+ name: wireToolName(localName),
2949
2960
  content: typeof result2 === "string" ? result2 : JSON.stringify(result2)
2950
2961
  });
2951
2962
  }
@@ -3750,208 +3761,18 @@ async function resolveClaudeToken(opts) {
3750
3761
  }
3751
3762
 
3752
3763
  // src/commands/agents/sync.ts
3753
- import { chownSync, existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync10, statSync, writeFileSync as writeFileSync6 } from "fs";
3764
+ import { chownSync, existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync9, statSync, writeFileSync as writeFileSync5 } from "fs";
3754
3765
  import { homedir as homedir9 } from "os";
3755
- import { join as join8 } from "path";
3766
+ import { join as join7 } from "path";
3756
3767
  import { defineCommand as defineCommand27 } from "citty";
3757
3768
  import consola24 from "consola";
3758
3769
 
3759
- // src/lib/launchd-reconcile.ts
3760
- import { execFileSync as execFileSync8 } from "child_process";
3761
- import { mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync9, unlinkSync, writeFileSync as writeFileSync5 } from "fs";
3762
- import { userInfo as userInfo2 } from "os";
3763
- import { join as join7 } from "path";
3764
- var PLIST_PREFIX = "openape.troop.";
3765
- function plistDir() {
3766
- return "/Library/LaunchDaemons";
3767
- }
3768
- function plistPath(agentName, taskId) {
3769
- return join7(plistDir(), `${PLIST_PREFIX}${agentName}.${taskId}.plist`);
3770
- }
3771
- function plistLabel(agentName, taskId) {
3772
- return `${PLIST_PREFIX}${agentName}.${taskId}`;
3773
- }
3774
- function fieldValues(token, range) {
3775
- const [min, max] = range;
3776
- if (token === "*") return null;
3777
- if (token.startsWith("*/")) {
3778
- const step = Number(token.slice(2));
3779
- if (!Number.isInteger(step) || step < 1) return [];
3780
- const values = [];
3781
- for (let i = min; i <= max; i++) {
3782
- if (i % step === 0) values.push(i);
3783
- }
3784
- return values;
3785
- }
3786
- const n = Number(token);
3787
- return Number.isInteger(n) ? [n] : [];
3788
- }
3789
- function cronToSchedule(expr) {
3790
- const parts = expr.trim().split(/\s+/);
3791
- if (parts.length !== 5) return [];
3792
- const [m, h, dom, mo, dow] = parts;
3793
- const minutes = fieldValues(m, [0, 59]);
3794
- const hours = fieldValues(h, [0, 23]);
3795
- const doms = fieldValues(dom, [1, 31]);
3796
- const months = fieldValues(mo, [1, 12]);
3797
- const dows = fieldValues(dow, [0, 7]);
3798
- const slots = [];
3799
- const minList = minutes ?? [null];
3800
- const hourList = hours ?? [null];
3801
- const domList = doms ?? [null];
3802
- const monthList = months ?? [null];
3803
- const dowList = dows ?? [null];
3804
- for (const M of minList) {
3805
- for (const H of hourList) {
3806
- for (const D of domList) {
3807
- for (const Mo of monthList) {
3808
- for (const W of dowList) {
3809
- const slot = {};
3810
- if (M !== null) slot.Minute = M;
3811
- if (H !== null) slot.Hour = H;
3812
- if (D !== null) slot.Day = D;
3813
- if (Mo !== null) slot.Month = Mo;
3814
- if (W !== null) slot.Weekday = W === 7 ? 0 : W;
3815
- slots.push(slot);
3816
- }
3817
- }
3818
- }
3819
- }
3820
- }
3821
- return slots;
3822
- }
3823
- function escape2(s) {
3824
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3825
- }
3826
- function plistBody(input) {
3827
- const calendarBlocks = input.schedule.map((slot) => {
3828
- const lines = [];
3829
- if (slot.Minute !== void 0) lines.push(` <key>Minute</key><integer>${slot.Minute}</integer>`);
3830
- if (slot.Hour !== void 0) lines.push(` <key>Hour</key><integer>${slot.Hour}</integer>`);
3831
- if (slot.Day !== void 0) lines.push(` <key>Day</key><integer>${slot.Day}</integer>`);
3832
- if (slot.Month !== void 0) lines.push(` <key>Month</key><integer>${slot.Month}</integer>`);
3833
- if (slot.Weekday !== void 0) lines.push(` <key>Weekday</key><integer>${slot.Weekday}</integer>`);
3834
- return ` <dict>
3835
- ${lines.join("\n")}
3836
- </dict>`;
3837
- }).join("\n");
3838
- const calendarKey = input.schedule.length === 1 ? ` <key>StartCalendarInterval</key>
3839
- <dict>
3840
- ${calendarBlocks.replace(/^ {4}/gm, " ").replace(/^ {2}<dict>\n|\n {2}<\/dict>$/g, "")}
3841
- </dict>` : ` <key>StartCalendarInterval</key>
3842
- <array>
3843
- ${calendarBlocks}
3844
- </array>`;
3845
- return `<?xml version="1.0" encoding="UTF-8"?>
3846
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3847
- <plist version="1.0">
3848
- <dict>
3849
- <key>Label</key>
3850
- <string>${escape2(input.label)}</string>
3851
- <key>UserName</key>
3852
- <string>${escape2(input.userName)}</string>
3853
- <key>ProgramArguments</key>
3854
- <array>
3855
- <string>${escape2(input.apesBin)}</string>
3856
- <string>agents</string>
3857
- <string>run</string>
3858
- <string>${escape2(input.taskId)}</string>
3859
- </array>
3860
- <key>WorkingDirectory</key>
3861
- <string>${escape2(input.homeDir)}</string>
3862
- <key>EnvironmentVariables</key>
3863
- <dict>
3864
- <key>HOME</key>
3865
- <string>${escape2(input.homeDir)}</string>
3866
- <key>PATH</key>
3867
- <string>${escape2(input.homeDir)}/.bun/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
3868
- </dict>
3869
- ${calendarKey}
3870
- <key>StandardOutPath</key>
3871
- <string>${escape2(input.homeDir)}/Library/Logs/openape-troop-${escape2(input.taskId)}.log</string>
3872
- <key>StandardErrorPath</key>
3873
- <string>${escape2(input.homeDir)}/Library/Logs/openape-troop-${escape2(input.taskId)}.log</string>
3874
- </dict>
3875
- </plist>
3876
- `;
3877
- }
3878
- function buildPlistContent(args) {
3879
- return plistBody({
3880
- label: plistLabel(args.agentName, args.task.taskId),
3881
- apesBin: args.apesBin,
3882
- taskId: args.task.taskId,
3883
- schedule: cronToSchedule(args.task.cron),
3884
- homeDir: args.homeDir,
3885
- userName: args.userName ?? userInfo2().username
3886
- });
3887
- }
3888
- function bootstrap(label, path2) {
3889
- try {
3890
- execFileSync8("/bin/launchctl", ["bootout", `system/${label}`], { stdio: "ignore" });
3891
- } catch {
3892
- }
3893
- execFileSync8("/bin/launchctl", ["bootstrap", "system", path2], { stdio: "ignore" });
3894
- }
3895
- function bootout(label) {
3896
- try {
3897
- execFileSync8("/bin/launchctl", ["bootout", `system/${label}`], { stdio: "ignore" });
3898
- } catch {
3899
- }
3900
- }
3901
- function reconcile(input) {
3902
- mkdirSync3(plistDir(), { recursive: true });
3903
- const present = readdirSync(plistDir()).filter((f) => f.startsWith(`${PLIST_PREFIX}${input.agentName}.`) && f.endsWith(".plist"));
3904
- const presentTaskIds = new Set(
3905
- present.map((f) => f.slice(`${PLIST_PREFIX}${input.agentName}.`.length, -".plist".length))
3906
- );
3907
- const desiredById = new Map(input.desired.map((t) => [t.taskId, t]));
3908
- const result = { added: [], updated: [], removed: [], unchanged: [] };
3909
- for (const taskId of presentTaskIds) {
3910
- if (!desiredById.has(taskId)) {
3911
- const path2 = plistPath(input.agentName, taskId);
3912
- bootout(plistLabel(input.agentName, taskId));
3913
- try {
3914
- unlinkSync(path2);
3915
- } catch {
3916
- }
3917
- result.removed.push(taskId);
3918
- }
3919
- }
3920
- for (const task of input.desired) {
3921
- const path2 = plistPath(input.agentName, task.taskId);
3922
- const desiredContent = buildPlistContent({
3923
- agentName: input.agentName,
3924
- apesBin: input.apesBin,
3925
- homeDir: input.homeDir,
3926
- task,
3927
- userName: input.userName
3928
- });
3929
- let existingContent = "";
3930
- try {
3931
- existingContent = readFileSync9(path2, "utf8");
3932
- } catch {
3933
- }
3934
- if (existingContent === desiredContent) {
3935
- if (task.enabled) bootstrap(plistLabel(input.agentName, task.taskId), path2);
3936
- else bootout(plistLabel(input.agentName, task.taskId));
3937
- result.unchanged.push(task.taskId);
3938
- continue;
3939
- }
3940
- writeFileSync5(path2, desiredContent, { mode: 420 });
3941
- if (task.enabled) bootstrap(plistLabel(input.agentName, task.taskId), path2);
3942
- else bootout(plistLabel(input.agentName, task.taskId));
3943
- if (presentTaskIds.has(task.taskId)) result.updated.push(task.taskId);
3944
- else result.added.push(task.taskId);
3945
- }
3946
- return result;
3947
- }
3948
-
3949
3770
  // src/lib/macos-host.ts
3950
- import { execFileSync as execFileSync9 } from "child_process";
3771
+ import { execFileSync as execFileSync8 } from "child_process";
3951
3772
  import { hostname as hostname3 } from "os";
3952
3773
  function getHostId() {
3953
3774
  try {
3954
- const output = execFileSync9(
3775
+ const output = execFileSync8(
3955
3776
  "/usr/sbin/ioreg",
3956
3777
  ["-d2", "-c", "IOPlatformExpertDevice"],
3957
3778
  { encoding: "utf8", timeout: 2e3 }
@@ -3971,15 +3792,15 @@ function getHostname() {
3971
3792
  }
3972
3793
 
3973
3794
  // src/commands/agents/sync.ts
3974
- var AUTH_PATH3 = join8(homedir9(), ".config", "apes", "auth.json");
3975
- var TASK_CACHE_DIR2 = join8(homedir9(), ".openape", "agent", "tasks");
3795
+ var AUTH_PATH3 = join7(homedir9(), ".config", "apes", "auth.json");
3796
+ var TASK_CACHE_DIR2 = join7(homedir9(), ".openape", "agent", "tasks");
3976
3797
  function readAuthJson() {
3977
3798
  if (!existsSync9(AUTH_PATH3)) {
3978
3799
  throw new CliError(
3979
3800
  `No agent auth found at ${AUTH_PATH3}. Run \`apes agents spawn <name>\` to provision an agent first.`
3980
3801
  );
3981
3802
  }
3982
- const raw = readFileSync10(AUTH_PATH3, "utf8");
3803
+ const raw = readFileSync9(AUTH_PATH3, "utf8");
3983
3804
  let parsed;
3984
3805
  try {
3985
3806
  parsed = JSON.parse(raw);
@@ -4003,14 +3824,6 @@ function agentNameFromEmail(email) {
4003
3824
  }
4004
3825
  return before.slice(0, dashIdx);
4005
3826
  }
4006
- function findApesBin() {
4007
- const argv1 = process.argv[1];
4008
- if (argv1 && existsSync9(argv1)) return argv1;
4009
- for (const candidate of ["/opt/homebrew/bin/apes", "/usr/local/bin/apes"]) {
4010
- if (existsSync9(candidate)) return candidate;
4011
- }
4012
- throw new CliError("Could not locate the apes binary path for launchd. Set APES_BIN env var to point at it.");
4013
- }
4014
3827
  var syncAgentCommand = defineCommand27({
4015
3828
  meta: {
4016
3829
  name: "sync",
@@ -4062,41 +3875,26 @@ var syncAgentCommand = defineCommand27({
4062
3875
  }
4063
3876
  }
4064
3877
  }
4065
- const agentDir = join8(homedir9(), ".openape", "agent");
4066
- mkdirSync4(agentDir, { recursive: true });
4067
- chownToAgent(join8(homedir9(), ".openape"));
3878
+ const agentDir = join7(homedir9(), ".openape", "agent");
3879
+ mkdirSync3(agentDir, { recursive: true });
3880
+ chownToAgent(join7(homedir9(), ".openape"));
4068
3881
  chownToAgent(agentDir);
4069
- const agentJsonPath = join8(agentDir, "agent.json");
4070
- writeFileSync6(
3882
+ const agentJsonPath = join7(agentDir, "agent.json");
3883
+ writeFileSync5(
4071
3884
  agentJsonPath,
4072
3885
  `${JSON.stringify({ systemPrompt }, null, 2)}
4073
3886
  `,
4074
3887
  { mode: 384 }
4075
3888
  );
4076
3889
  chownToAgent(agentJsonPath);
4077
- mkdirSync4(TASK_CACHE_DIR2, { recursive: true });
3890
+ mkdirSync3(TASK_CACHE_DIR2, { recursive: true });
4078
3891
  chownToAgent(TASK_CACHE_DIR2);
4079
3892
  for (const task of tasks) {
4080
- const path2 = join8(TASK_CACHE_DIR2, `${task.taskId}.json`);
4081
- writeFileSync6(path2, `${JSON.stringify(task, null, 2)}
3893
+ const path2 = join7(TASK_CACHE_DIR2, `${task.taskId}.json`);
3894
+ writeFileSync5(path2, `${JSON.stringify(task, null, 2)}
4082
3895
  `, { mode: 384 });
4083
3896
  chownToAgent(path2);
4084
3897
  }
4085
- const apesBin = findApesBin();
4086
- const result = reconcile({
4087
- agentName,
4088
- apesBin,
4089
- homeDir: homedir9(),
4090
- desired: tasks,
4091
- // Sync runs as root in production — pass the agent username
4092
- // explicitly for the UserName plist key (launchd will then run
4093
- // each task daemon AS the agent, not as root).
4094
- userName: process.env.AGENT_USER || void 0
4095
- });
4096
- if (result.added.length) consola24.success(`launchd: added ${result.added.join(", ")}`);
4097
- if (result.updated.length) consola24.success(`launchd: updated ${result.updated.join(", ")}`);
4098
- if (result.removed.length) consola24.warn(`launchd: removed ${result.removed.join(", ")}`);
4099
- if (result.unchanged.length) consola24.info(`launchd: ${result.unchanged.length} unchanged`);
4100
3898
  consola24.success("Sync complete.");
4101
3899
  }
4102
3900
  });
@@ -4448,7 +4246,7 @@ var adapterCommand = defineCommand29({
4448
4246
  });
4449
4247
 
4450
4248
  // src/commands/run.ts
4451
- import { execFileSync as execFileSync10 } from "child_process";
4249
+ import { execFileSync as execFileSync9 } from "child_process";
4452
4250
  import { hostname as hostname4 } from "os";
4453
4251
  import { basename } from "path";
4454
4252
  import { defineCommand as defineCommand30 } from "citty";
@@ -4726,7 +4524,7 @@ function execShellCommand(command) {
4726
4524
  throw new CliError("No command to execute");
4727
4525
  try {
4728
4526
  const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
4729
- execFileSync10(command[0], command.slice(1), {
4527
+ execFileSync9(command[0], command.slice(1), {
4730
4528
  stdio: "inherit",
4731
4529
  env: inheritedEnv
4732
4530
  });
@@ -4878,7 +4676,7 @@ async function runAudienceMode(audience, action, args) {
4878
4676
  consola26.info(`Executing: ${command.join(" ")}`);
4879
4677
  try {
4880
4678
  const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env;
4881
- execFileSync10(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
4679
+ execFileSync9(args["escapes-path"] || "escapes", ["--grant", authz_jwt, "--", ...command], {
4882
4680
  stdio: "inherit",
4883
4681
  env: inheritedEnv
4884
4682
  });
@@ -4928,10 +4726,10 @@ note = "VPC-internal hostname suffix"
4928
4726
 
4929
4727
  // src/proxy/local-proxy.ts
4930
4728
  import { spawn } from "child_process";
4931
- import { mkdtempSync as mkdtempSync3, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "fs";
4729
+ import { mkdtempSync as mkdtempSync3, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
4932
4730
  import { createRequire } from "module";
4933
4731
  import { tmpdir as tmpdir3 } from "os";
4934
- import { dirname as dirname3, join as join9, resolve as resolve4 } from "path";
4732
+ import { dirname as dirname3, join as join8, resolve as resolve4 } from "path";
4935
4733
  var require2 = createRequire(import.meta.url);
4936
4734
  function findProxyBin() {
4937
4735
  const pkgPath = require2.resolve("@openape/proxy/package.json");
@@ -4943,9 +4741,9 @@ function findProxyBin() {
4943
4741
  return resolve4(dirname3(pkgPath), binRel);
4944
4742
  }
4945
4743
  async function startEphemeralProxy(configToml) {
4946
- const tmpDir = mkdtempSync3(join9(tmpdir3(), "openape-proxy-"));
4947
- const configPath = join9(tmpDir, "config.toml");
4948
- writeFileSync7(configPath, configToml, { mode: 384 });
4744
+ const tmpDir = mkdtempSync3(join8(tmpdir3(), "openape-proxy-"));
4745
+ const configPath = join8(tmpDir, "config.toml");
4746
+ writeFileSync6(configPath, configToml, { mode: 384 });
4949
4747
  const binPath = findProxyBin();
4950
4748
  const child = spawn(process.execPath, [binPath, "-c", configPath], {
4951
4749
  stdio: ["ignore", "pipe", "pipe"],
@@ -5380,16 +5178,16 @@ var mcpCommand = defineCommand36({
5380
5178
  if (transport !== "stdio" && transport !== "sse") {
5381
5179
  throw new Error('Transport must be "stdio" or "sse"');
5382
5180
  }
5383
- const { startMcpServer } = await import("./server-YDC3S4PC.js");
5181
+ const { startMcpServer } = await import("./server-PNV5UGY3.js");
5384
5182
  await startMcpServer(transport, port);
5385
5183
  }
5386
5184
  });
5387
5185
 
5388
5186
  // src/commands/init/index.ts
5389
- import { existsSync as existsSync10, copyFileSync, writeFileSync as writeFileSync8 } from "fs";
5187
+ import { existsSync as existsSync10, copyFileSync, writeFileSync as writeFileSync7 } from "fs";
5390
5188
  import { randomBytes } from "crypto";
5391
- import { execFileSync as execFileSync11 } from "child_process";
5392
- import { join as join10 } from "path";
5189
+ import { execFileSync as execFileSync10 } from "child_process";
5190
+ import { join as join9 } from "path";
5393
5191
  import { defineCommand as defineCommand37 } from "citty";
5394
5192
  import consola30 from "consola";
5395
5193
  var DEFAULT_IDP_URL = "https://id.openape.at";
@@ -5398,13 +5196,13 @@ async function downloadTemplate(repo, targetDir) {
5398
5196
  await gigetDownload(`gh:${repo}`, { dir: targetDir, force: false });
5399
5197
  }
5400
5198
  function installDeps(dir) {
5401
- const hasLockFile = (name) => existsSync10(join10(dir, name));
5199
+ const hasLockFile = (name) => existsSync10(join9(dir, name));
5402
5200
  if (hasLockFile("pnpm-lock.yaml")) {
5403
- execFileSync11("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
5201
+ execFileSync10("pnpm", ["install"], { cwd: dir, stdio: "inherit" });
5404
5202
  } else if (hasLockFile("bun.lockb")) {
5405
- execFileSync11("bun", ["install"], { cwd: dir, stdio: "inherit" });
5203
+ execFileSync10("bun", ["install"], { cwd: dir, stdio: "inherit" });
5406
5204
  } else {
5407
- execFileSync11("npm", ["install"], { cwd: dir, stdio: "inherit" });
5205
+ execFileSync10("npm", ["install"], { cwd: dir, stdio: "inherit" });
5408
5206
  }
5409
5207
  }
5410
5208
  async function promptChoice(message, choices) {
@@ -5463,7 +5261,7 @@ var initCommand = defineCommand37({
5463
5261
  });
5464
5262
  async function initSP(targetDir) {
5465
5263
  const dir = targetDir || "my-app";
5466
- if (existsSync10(join10(dir, "package.json"))) {
5264
+ if (existsSync10(join9(dir, "package.json"))) {
5467
5265
  throw new CliError(`Directory "${dir}" already contains a project.`);
5468
5266
  }
5469
5267
  consola30.start("Scaffolding SP starter...");
@@ -5472,8 +5270,8 @@ async function initSP(targetDir) {
5472
5270
  consola30.start("Installing dependencies...");
5473
5271
  installDeps(dir);
5474
5272
  consola30.success("Dependencies installed");
5475
- const envExample = join10(dir, ".env.example");
5476
- const envFile = join10(dir, ".env");
5273
+ const envExample = join9(dir, ".env.example");
5274
+ const envFile = join9(dir, ".env");
5477
5275
  if (existsSync10(envExample) && !existsSync10(envFile)) {
5478
5276
  copyFileSync(envExample, envFile);
5479
5277
  consola30.success(`\`.env\` created (using Free IdP at ${DEFAULT_IDP_URL})`);
@@ -5488,7 +5286,7 @@ async function initSP(targetDir) {
5488
5286
  }
5489
5287
  async function initIdP(targetDir) {
5490
5288
  const dir = targetDir || "my-idp";
5491
- if (existsSync10(join10(dir, "package.json"))) {
5289
+ if (existsSync10(join9(dir, "package.json"))) {
5492
5290
  throw new CliError(`Directory "${dir}" already contains a project.`);
5493
5291
  }
5494
5292
  const domain = await promptText("Domain for the IdP", "localhost");
@@ -5520,7 +5318,7 @@ async function initIdP(targetDir) {
5520
5318
  `NUXT_OPENAPE_RP_ID=${domain}`,
5521
5319
  `NUXT_OPENAPE_RP_ORIGIN=${origin}`
5522
5320
  ].join("\n");
5523
- writeFileSync8(join10(dir, ".env"), `${envContent}
5321
+ writeFileSync7(join9(dir, ".env"), `${envContent}
5524
5322
  `, { mode: 384 });
5525
5323
  consola30.success(".env created");
5526
5324
  console.log("");
@@ -5541,7 +5339,7 @@ async function initIdP(targetDir) {
5541
5339
 
5542
5340
  // src/commands/enroll.ts
5543
5341
  import { Buffer as Buffer5 } from "buffer";
5544
- import { existsSync as existsSync11, readFileSync as readFileSync11 } from "fs";
5342
+ import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
5545
5343
  import { execFile as execFile2 } from "child_process";
5546
5344
  import { sign as sign2 } from "crypto";
5547
5345
  import { defineCommand as defineCommand38 } from "citty";
@@ -5557,7 +5355,7 @@ function openBrowser2(url) {
5557
5355
  }
5558
5356
  async function pollForEnrollment(idp, agentEmail, keyPath) {
5559
5357
  const resolvedKey = resolveKeyPath(keyPath);
5560
- const keyContent = readFileSync11(resolvedKey, "utf-8");
5358
+ const keyContent = readFileSync10(resolvedKey, "utf-8");
5561
5359
  const privateKey = loadEd25519PrivateKey(keyContent);
5562
5360
  const challengeUrl = await getAgentChallengeEndpoint(idp);
5563
5361
  const authenticateUrl = await getAgentAuthenticateEndpoint(idp);
@@ -5669,7 +5467,7 @@ var enrollCommand = defineCommand38({
5669
5467
  });
5670
5468
 
5671
5469
  // src/commands/register-user.ts
5672
- import { existsSync as existsSync12, readFileSync as readFileSync12 } from "fs";
5470
+ import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
5673
5471
  import { defineCommand as defineCommand39 } from "citty";
5674
5472
  import consola32 from "consola";
5675
5473
  var registerUserCommand = defineCommand39({
@@ -5709,7 +5507,7 @@ var registerUserCommand = defineCommand39({
5709
5507
  }
5710
5508
  let publicKey = args.key;
5711
5509
  if (existsSync12(args.key)) {
5712
- publicKey = readFileSync12(args.key, "utf-8").trim();
5510
+ publicKey = readFileSync11(args.key, "utf-8").trim();
5713
5511
  }
5714
5512
  if (!publicKey.startsWith("ssh-ed25519 ")) {
5715
5513
  throw new CliError("Public key must be in ssh-ed25519 format.");
@@ -6018,7 +5816,7 @@ async function bestEffortGrantCount(idp) {
6018
5816
  }
6019
5817
  }
6020
5818
  async function runHealth(args) {
6021
- const version = true ? "1.2.1" : "0.0.0";
5819
+ const version = true ? "1.3.1" : "0.0.0";
6022
5820
  const auth = loadAuth();
6023
5821
  if (!auth) {
6024
5822
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -6211,26 +6009,26 @@ var workflowsCommand = defineCommand47({
6211
6009
  });
6212
6010
 
6213
6011
  // src/version-check.ts
6214
- import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "fs";
6012
+ import { existsSync as existsSync13, mkdirSync as mkdirSync4, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "fs";
6215
6013
  import { homedir as homedir10 } from "os";
6216
- import { join as join11 } from "path";
6014
+ import { join as join10 } from "path";
6217
6015
  import consola38 from "consola";
6218
6016
  var PACKAGE_NAME = "@openape/apes";
6219
6017
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
6220
- var CACHE_FILE = join11(homedir10(), ".config", "apes", ".version-check.json");
6018
+ var CACHE_FILE = join10(homedir10(), ".config", "apes", ".version-check.json");
6221
6019
  function readCache() {
6222
6020
  if (!existsSync13(CACHE_FILE)) return null;
6223
6021
  try {
6224
- return JSON.parse(readFileSync13(CACHE_FILE, "utf-8"));
6022
+ return JSON.parse(readFileSync12(CACHE_FILE, "utf-8"));
6225
6023
  } catch {
6226
6024
  return null;
6227
6025
  }
6228
6026
  }
6229
6027
  function writeCache(entry) {
6230
6028
  try {
6231
- const dir = join11(homedir10(), ".config", "apes");
6232
- if (!existsSync13(dir)) mkdirSync5(dir, { recursive: true, mode: 448 });
6233
- writeFileSync9(CACHE_FILE, JSON.stringify(entry), { mode: 384 });
6029
+ const dir = join10(homedir10(), ".config", "apes");
6030
+ if (!existsSync13(dir)) mkdirSync4(dir, { recursive: true, mode: 448 });
6031
+ writeFileSync8(CACHE_FILE, JSON.stringify(entry), { mode: 384 });
6234
6032
  } catch {
6235
6033
  }
6236
6034
  }
@@ -6291,10 +6089,10 @@ if (shellRewrite) {
6291
6089
  if (shellRewrite.action === "rewrite") {
6292
6090
  process.argv = shellRewrite.argv;
6293
6091
  } else if (shellRewrite.action === "version") {
6294
- console.log(`ape-shell ${"1.2.1"} (OpenApe DDISA shell wrapper)`);
6092
+ console.log(`ape-shell ${"1.3.1"} (OpenApe DDISA shell wrapper)`);
6295
6093
  process.exit(0);
6296
6094
  } else if (shellRewrite.action === "help") {
6297
- console.log(`ape-shell ${"1.2.1"} \u2014 OpenApe DDISA shell wrapper`);
6095
+ console.log(`ape-shell ${"1.3.1"} \u2014 OpenApe DDISA shell wrapper`);
6298
6096
  console.log("");
6299
6097
  console.log("Usage:");
6300
6098
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -6352,7 +6150,7 @@ var configCommand = defineCommand48({
6352
6150
  var main = defineCommand48({
6353
6151
  meta: {
6354
6152
  name: "apes",
6355
- version: "1.2.1",
6153
+ version: "1.3.1",
6356
6154
  description: "Unified CLI for OpenApe"
6357
6155
  },
6358
6156
  subCommands: {
@@ -6407,7 +6205,7 @@ async function maybeRefreshAuth() {
6407
6205
  }
6408
6206
  }
6409
6207
  await maybeRefreshAuth();
6410
- await maybeWarnStaleVersion("1.2.1").catch(() => {
6208
+ await maybeWarnStaleVersion("1.3.1").catch(() => {
6411
6209
  });
6412
6210
  runMain(main).catch((err) => {
6413
6211
  if (err instanceof CliExit) {