@openape/apes 0.24.0 → 0.25.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
@@ -2087,6 +2087,60 @@ function isShellRegistered(shellPath) {
2087
2087
  return content.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).includes(shellPath);
2088
2088
  }
2089
2089
 
2090
+ // src/lib/silent-password.ts
2091
+ function readPasswordSilent(prompt) {
2092
+ if (!process.stdin.isTTY) {
2093
+ return Promise.reject(new CliError(
2094
+ "No TTY available for the silent password prompt. Set APES_ADMIN_PASSWORD in the environment instead."
2095
+ ));
2096
+ }
2097
+ return new Promise((resolve4, reject) => {
2098
+ process.stdout.write(prompt);
2099
+ const wasRaw = process.stdin.isRaw ?? false;
2100
+ process.stdin.setRawMode(true);
2101
+ process.stdin.resume();
2102
+ process.stdin.setEncoding("utf8");
2103
+ let buf = "";
2104
+ let cleanupFn;
2105
+ const cleanup = () => cleanupFn?.();
2106
+ const onData = (chunk) => {
2107
+ for (const ch of chunk) {
2108
+ const code = ch.charCodeAt(0);
2109
+ if (ch === "\r" || ch === "\n") {
2110
+ cleanup();
2111
+ process.stdout.write("\n");
2112
+ resolve4(buf);
2113
+ return;
2114
+ }
2115
+ if (code === 3) {
2116
+ cleanup();
2117
+ process.stdout.write("\n");
2118
+ reject(new CliError("Aborted by user (Ctrl-C)."));
2119
+ return;
2120
+ }
2121
+ if (code === 4 && buf.length === 0) {
2122
+ cleanup();
2123
+ process.stdout.write("\n");
2124
+ reject(new CliError("Aborted by user (Ctrl-D)."));
2125
+ return;
2126
+ }
2127
+ if (code === 127 || code === 8) {
2128
+ if (buf.length > 0) buf = buf.slice(0, -1);
2129
+ continue;
2130
+ }
2131
+ if (code < 32) continue;
2132
+ buf += ch;
2133
+ }
2134
+ };
2135
+ cleanupFn = () => {
2136
+ process.stdin.removeListener("data", onData);
2137
+ process.stdin.setRawMode(wasRaw);
2138
+ process.stdin.pause();
2139
+ };
2140
+ process.stdin.on("data", onData);
2141
+ });
2142
+ }
2143
+
2090
2144
  // src/commands/agents/destroy.ts
2091
2145
  var destroyAgentCommand = defineCommand20({
2092
2146
  meta: {
@@ -2166,25 +2220,21 @@ ${consequences.join("\n")}`);
2166
2220
  consola18.info("No IdP agent to remove (skipped).");
2167
2221
  }
2168
2222
  if (osUserExists) {
2169
- const apes = whichBinary("apes");
2170
- if (!apes) {
2171
- throw new CliError("`apes` not found on PATH. Install @openape/apes globally first.");
2172
- }
2173
- const escapes = whichBinary("escapes");
2174
- if (!escapes) {
2175
- throw new CliError("`escapes` not found on PATH; OS teardown requires escapes.");
2223
+ const sudo = whichBinary("sudo");
2224
+ if (!sudo) {
2225
+ throw new CliError("`sudo` not found on PATH; required for OS teardown.");
2176
2226
  }
2177
2227
  const adminUser = userInfo().username;
2178
- const adminPassword = await collectAdminPassword({ adminUser, force: !!args.force });
2228
+ const adminPassword = await collectAdminPassword({ adminUser });
2179
2229
  const scratch = mkdtempSync(join2(tmpdir(), `apes-destroy-${name}-`));
2180
2230
  const scriptPath = join2(scratch, "teardown.sh");
2181
2231
  try {
2182
2232
  const script = buildDestroyTeardownScript({ name, homeDir: `/Users/${name}`, adminUser });
2183
2233
  writeFileSync(scriptPath, script, { mode: 448 });
2184
- consola18.start("Running teardown as root via `apes run --as root --wait`\u2026");
2185
- consola18.info("You will be asked to approve the as=root grant in your DDISA inbox; this command blocks until you do.");
2186
- execFileSync3(apes, ["run", "--as", "root", "--wait", "--", "bash", scriptPath], {
2234
+ consola18.start("Running teardown via sudo\u2026");
2235
+ execFileSync3(sudo, ["-S", "--prompt=", "--", "bash", scriptPath], {
2187
2236
  input: `${adminPassword}
2237
+ ${adminPassword}
2188
2238
  `,
2189
2239
  stdio: ["pipe", "inherit", "inherit"]
2190
2240
  });
@@ -2200,14 +2250,8 @@ ${consequences.join("\n")}`);
2200
2250
  async function collectAdminPassword(opts) {
2201
2251
  const fromEnv = process.env.APES_ADMIN_PASSWORD;
2202
2252
  if (fromEnv && fromEnv.length > 0) return fromEnv;
2203
- if (!process.stdin.isTTY) {
2204
- throw new CliError(
2205
- `Admin password required for sysadminctl -deleteUser. No TTY available for the silent prompt; set APES_ADMIN_PASSWORD in the environment (local admin password for ${opts.adminUser}). The teardown reads it from stdin and never stores it.`
2206
- );
2207
- }
2208
- consola18.info(`Local admin password for ${opts.adminUser} (used for sysadminctl -deleteUser; not stored):`);
2209
- const pw = await consola18.prompt("Admin password", { type: "text", mask: "*" });
2210
- if (typeof pw === "symbol" || !pw || pw.length === 0) {
2253
+ const pw = await readPasswordSilent(`Password for ${opts.adminUser}: `);
2254
+ if (pw.length === 0) {
2211
2255
  throw new CliExit(0);
2212
2256
  }
2213
2257
  return pw;
@@ -2534,9 +2578,10 @@ export NPM_CONFIG_PREFIX="$HOME/.npm-global"
2534
2578
  export PATH="$NPM_CONFIG_PREFIX/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
2535
2579
  mkdir -p "$NPM_CONFIG_PREFIX"
2536
2580
 
2537
- if ! command -v openape-chat-bridge >/dev/null 2>&1; then
2538
- npm install -g --silent @openape/chat-bridge
2539
- fi
2581
+ # Always pull @latest on boot. npm is cached so this is a no-op when the
2582
+ # global is already current; when a new version ships, the daemon auto-
2583
+ # upgrades on the next launchctl restart instead of needing manual touch.
2584
+ npm install -g --silent @openape/chat-bridge@latest
2540
2585
 
2541
2586
  if ! command -v pi >/dev/null 2>&1; then
2542
2587
  npm install -g --silent @mariozechner/pi-coding-agent
@@ -4094,7 +4139,7 @@ var mcpCommand = defineCommand32({
4094
4139
  if (transport !== "stdio" && transport !== "sse") {
4095
4140
  throw new Error('Transport must be "stdio" or "sse"');
4096
4141
  }
4097
- const { startMcpServer } = await import("./server-J4H4UV25.js");
4142
+ const { startMcpServer } = await import("./server-GQDX7PHW.js");
4098
4143
  await startMcpServer(transport, port);
4099
4144
  }
4100
4145
  });
@@ -4732,7 +4777,7 @@ async function bestEffortGrantCount(idp) {
4732
4777
  }
4733
4778
  }
4734
4779
  async function runHealth(args) {
4735
- const version = true ? "0.24.0" : "0.0.0";
4780
+ const version = true ? "0.25.1" : "0.0.0";
4736
4781
  const auth = loadAuth();
4737
4782
  if (!auth) {
4738
4783
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -5005,10 +5050,10 @@ if (shellRewrite) {
5005
5050
  if (shellRewrite.action === "rewrite") {
5006
5051
  process.argv = shellRewrite.argv;
5007
5052
  } else if (shellRewrite.action === "version") {
5008
- console.log(`ape-shell ${"0.24.0"} (OpenApe DDISA shell wrapper)`);
5053
+ console.log(`ape-shell ${"0.25.1"} (OpenApe DDISA shell wrapper)`);
5009
5054
  process.exit(0);
5010
5055
  } else if (shellRewrite.action === "help") {
5011
- console.log(`ape-shell ${"0.24.0"} \u2014 OpenApe DDISA shell wrapper`);
5056
+ console.log(`ape-shell ${"0.25.1"} \u2014 OpenApe DDISA shell wrapper`);
5012
5057
  console.log("");
5013
5058
  console.log("Usage:");
5014
5059
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -5066,7 +5111,7 @@ var configCommand = defineCommand44({
5066
5111
  var main = defineCommand44({
5067
5112
  meta: {
5068
5113
  name: "apes",
5069
- version: "0.24.0",
5114
+ version: "0.25.1",
5070
5115
  description: "Unified CLI for OpenApe"
5071
5116
  },
5072
5117
  subCommands: {
@@ -5121,7 +5166,7 @@ async function maybeRefreshAuth() {
5121
5166
  }
5122
5167
  }
5123
5168
  await maybeRefreshAuth();
5124
- await maybeWarnStaleVersion("0.24.0").catch(() => {
5169
+ await maybeWarnStaleVersion("0.25.1").catch(() => {
5125
5170
  });
5126
5171
  runMain(main).catch((err) => {
5127
5172
  if (err instanceof CliExit) {