@openape/apes 1.28.5 → 1.28.6
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/{chunk-AFTJZVOQ.js → chunk-OZDZCYJ7.js} +10 -6
- package/dist/chunk-OZDZCYJ7.js.map +1 -0
- package/dist/cli.js +11 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{server-QQ6WQ244.js → server-SMPRGV3D.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-AFTJZVOQ.js.map +0 -1
- /package/dist/{server-QQ6WQ244.js.map → server-SMPRGV3D.js.map} +0 -0
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/ape-shell.ts","../src/commands/auth/login.ts","../src/commands/auth/resolve-login.ts","../src/commands/auth/logout.ts","../src/commands/auth/whoami.ts","../src/commands/grants/list.ts","../src/commands/grants/inbox.ts","../src/commands/grants/status.ts","../src/commands/grants/request.ts","../src/commands/grants/request-capability.ts","../src/commands/grants/approve.ts","../src/commands/grants/deny.ts","../src/commands/grants/revoke.ts","../src/commands/grants/run.ts","../src/grant-poll.ts","../src/commands/grants/token.ts","../src/commands/grants/delegate.ts","../src/commands/grants/delegations.ts","../src/commands/grants/delegation-revoke.ts","../src/commands/admin/index.ts","../src/commands/admin/users.ts","../src/commands/admin/ssh-keys.ts","../src/commands/agent/index.ts","../src/commands/agent/deploy.ts","../src/lib/troop-client.ts","../src/commands/agents/index.ts","../src/commands/agents/allow.ts","../src/lib/agent-bootstrap.ts","../src/lib/macos-user.ts","../src/commands/agents/cleanup-orphans.ts","../src/commands/agents/code.ts","../src/lib/agent-secrets-runtime.ts","../src/lib/coding/issue-task.ts","../src/lib/coding/merge-policy.ts","../src/lib/coding/review-gate.ts","../src/lib/coding/coding-loop.ts","../src/lib/coding/llm-review.ts","../src/lib/coding/derive-policy.ts","../src/commands/agents/destroy.ts","../src/lib/nest-registry.ts","../src/lib/silent-password.ts","../src/commands/agents/list.ts","../src/commands/agents/register.ts","../src/commands/agents/run.ts","../src/commands/agents/serve.ts","../src/commands/agents/spawn.ts","../src/lib/troop-bootstrap.ts","../src/lib/keygen.ts","../src/lib/llm-bridge.ts","../src/commands/agents/sync.ts","../src/lib/macos-host.ts","../src/commands/nest/index.ts","../src/commands/nest/authorize.ts","../src/commands/nest/enroll.ts","../src/commands/nest/destroy.ts","../src/commands/nest/install.ts","../src/commands/nest/apes-agents-adapter.ts","../src/commands/nest/list.ts","../src/commands/nest/spawn.ts","../src/commands/nest/uninstall.ts","../src/commands/yolo/index.ts","../src/commands/yolo/clear.ts","../src/commands/yolo/set.ts","../src/commands/yolo/show.ts","../src/commands/adapter/index.ts","../src/commands/run.ts","../src/commands/proxy.ts","../src/proxy/config.ts","../src/proxy/local-proxy.ts","../src/proxy/trust-bundle.ts","../src/commands/explain.ts","../src/commands/config/get.ts","../src/commands/config/set.ts","../src/commands/fetch/index.ts","../src/commands/mcp/index.ts","../src/commands/init/index.ts","../src/commands/enroll.ts","../src/commands/register-user.ts","../src/commands/utils/index.ts","../src/commands/utils/dig.ts","../src/commands/sessions/index.ts","../src/commands/sessions/list.ts","../src/commands/sessions/remove.ts","../src/commands/dns-check.ts","../src/commands/health.ts","../src/commands/workflows.ts","../src/guides/index.ts","../src/version-check.ts"],"sourcesContent":["import consola from 'consola'\nimport { rewriteApeShellArgs } from './ape-shell'\nimport { defineCommand, runMain } from 'citty'\nimport { loginCommand } from './commands/auth/login'\nimport { logoutCommand } from './commands/auth/logout'\nimport { whoamiCommand } from './commands/auth/whoami'\nimport { listCommand } from './commands/grants/list'\nimport { inboxCommand } from './commands/grants/inbox'\nimport { statusCommand } from './commands/grants/status'\nimport { requestCommand } from './commands/grants/request'\nimport { requestCapabilityCommand } from './commands/grants/request-capability'\nimport { approveCommand } from './commands/grants/approve'\nimport { denyCommand } from './commands/grants/deny'\nimport { revokeCommand } from './commands/grants/revoke'\nimport { runGrantCommand } from './commands/grants/run'\nimport { tokenCommand } from './commands/grants/token'\nimport { delegateCommand } from './commands/grants/delegate'\nimport { delegationsCommand } from './commands/grants/delegations'\nimport { delegationRevokeCommand } from './commands/grants/delegation-revoke'\nimport { adminCommand } from './commands/admin/index'\nimport { agentCommand } from './commands/agent/index'\nimport { agentsCommand } from './commands/agents/index'\nimport { nestCommand } from './commands/nest/index'\nimport { yoloCommand } from './commands/yolo/index'\nimport { adapterCommand } from './commands/adapter/index'\nimport { runCommand } from './commands/run'\nimport { proxyCommand } from './commands/proxy'\nimport { explainCommand } from './commands/explain'\nimport { configGetCommand } from './commands/config/get'\nimport { configSetCommand } from './commands/config/set'\nimport { fetchCommand } from './commands/fetch/index'\nimport { mcpCommand } from './commands/mcp/index'\nimport { initCommand } from './commands/init/index'\nimport { enrollCommand } from './commands/enroll'\nimport { registerUserCommand } from './commands/register-user'\nimport { utilsCommand } from './commands/utils/index'\nimport { sessionsCommand } from './commands/sessions/index'\nimport { dnsCheckCommand } from './commands/dns-check'\nimport { healthCommand } from './commands/health'\nimport { workflowsCommand } from './commands/workflows'\nimport { ApiError } from './http'\nimport { CliError, CliExit } from './errors'\nimport { maybeWarnStaleVersion } from './version-check'\n\n// Gracefully handle EPIPE when stdout is closed early (e.g. piped to `head`)\nprocess.stdout.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EPIPE') process.exit(0)\n throw err\n})\n\ndeclare const __VERSION__: string\n\n// ape-shell mode:\n// • `ape-shell -c <command>` rewrites to `apes run --shell -- bash -c <command>` (one-shot)\n// • `ape-shell` (no args), `-i`, `-l`, or invoked as a login shell → interactive REPL\n// Pass `process.argv0` explicitly so the wrapper script path (which uses\n// bash's `exec -a \"$0\"` to preserve the original argv[0] from login/sshd)\n// still benefits from login-shell detection when the cli.js is invoked\n// indirectly via the ape-shell-wrapper.sh shim.\nconst shellRewrite = rewriteApeShellArgs(process.argv, process.argv0)\nif (shellRewrite) {\n if (shellRewrite.action === 'rewrite') {\n process.argv = shellRewrite.argv\n }\n else if (shellRewrite.action === 'version') {\n console.log(`ape-shell ${__VERSION__} (OpenApe DDISA shell wrapper)`)\n process.exit(0)\n }\n else if (shellRewrite.action === 'help') {\n console.log(`ape-shell ${__VERSION__} — OpenApe DDISA shell wrapper`)\n console.log('')\n console.log('Usage:')\n console.log(' ape-shell Start interactive grant-mediated REPL')\n console.log(' ape-shell -c <command> Run a single command through the grant flow')\n console.log(' ape-shell -i | -l Force interactive mode')\n console.log('')\n console.log('Options:')\n console.log(' -c <command> Execute <command> via the apes grant flow and exit')\n console.log(' -i Interactive REPL (default when no args are given)')\n console.log(' -l, --login Login shell semantics — currently same as -i')\n console.log(' --version, -v Show ape-shell version')\n console.log(' --help, -h Show this help message')\n process.exit(0)\n }\n else if (shellRewrite.action === 'interactive') {\n // Hand control to the interactive REPL orchestrator. Never returns to\n // citty dispatch. Dynamic import so the startup path for `ape-shell -c`\n // stays lean (node-pty native module is only loaded when needed).\n const { runInteractiveShell } = await import('./shell/orchestrator.js')\n await runInteractiveShell()\n process.exit(0)\n }\n else {\n console.error('ape-shell: unsupported invocation. Try `ape-shell --help`.')\n process.exit(1)\n }\n}\n\nconst debug = process.argv.includes('--debug')\n\nconst grantsCommand = defineCommand({\n meta: {\n name: 'grants',\n description: 'Grant management',\n },\n subCommands: {\n list: listCommand,\n inbox: inboxCommand,\n status: statusCommand,\n request: requestCommand,\n 'request-capability': requestCapabilityCommand,\n approve: approveCommand,\n deny: denyCommand,\n revoke: revokeCommand,\n run: runGrantCommand,\n token: tokenCommand,\n delegate: delegateCommand,\n delegations: delegationsCommand,\n 'delegation-revoke': delegationRevokeCommand,\n },\n})\n\nconst configCommand = defineCommand({\n meta: {\n name: 'config',\n description: 'Configuration management',\n },\n subCommands: {\n get: configGetCommand,\n set: configSetCommand,\n },\n})\n\nconst main = defineCommand({\n meta: {\n name: 'apes',\n version: __VERSION__,\n description: 'Unified CLI for OpenApe',\n },\n subCommands: {\n init: initCommand,\n enroll: enrollCommand,\n 'register-user': registerUserCommand,\n 'dns-check': dnsCheckCommand,\n utils: utilsCommand,\n sessions: sessionsCommand,\n login: loginCommand,\n logout: logoutCommand,\n whoami: whoamiCommand,\n health: healthCommand,\n grants: grantsCommand,\n agent: agentCommand,\n agents: agentsCommand,\n nest: nestCommand,\n yolo: yoloCommand,\n admin: adminCommand,\n run: runCommand,\n proxy: proxyCommand,\n explain: explainCommand,\n adapter: adapterCommand,\n config: configCommand,\n fetch: fetchCommand,\n mcp: mcpCommand,\n workflows: workflowsCommand,\n },\n})\n\n// Auto-refresh: every command except those that don't need (or shouldn't\n// touch) existing auth gets a transparent token refresh before its handler\n// runs. Matches `ape-shell` behavior — users no longer need to re-`apes\n// login` when an SP rejects their token; the CLI rotates it on the next\n// invocation. login/logout obviously skip; init/enroll/register-user are\n// pre-auth bootstrap; dns-check/utils/explain/workflows are diagnostic and\n// offline-safe.\nconst NO_REFRESH_COMMANDS = new Set([\n 'login', 'logout',\n 'init', 'enroll', 'register-user',\n 'dns-check', 'utils', 'explain', 'workflows',\n '--help', '-h', 'help',\n '--version', '-v',\n])\n\nasync function maybeRefreshAuth(): Promise<void> {\n const sub = process.argv[2]\n if (!sub || NO_REFRESH_COMMANDS.has(sub)) return\n const { loadAuth } = await import('./config.js')\n if (!loadAuth()) return // not logged in — nothing to refresh\n try {\n const { ensureFreshToken } = await import('./http.js')\n await ensureFreshToken()\n }\n catch {\n // Refresh failures are non-fatal — the actual command will surface a\n // proper auth error if the token is genuinely unusable.\n }\n}\n\nawait maybeRefreshAuth()\n\n// Stale-version notice. Synchronous cache read prints instantly when\n// we already know we're behind; the actual npm round-trip is bounded\n// to 2s by an AbortSignal so command startup never blocks for long.\n// Cached 24h, so this is a one-time cost per day.\nawait maybeWarnStaleVersion(__VERSION__).catch(() => { /* never block */ })\n\nrunMain(main).catch((err) => {\n if (err instanceof CliExit) {\n process.exit(err.exitCode)\n }\n if (err instanceof CliError) {\n consola.error(err.message)\n process.exit(err.exitCode)\n }\n if (debug) {\n consola.error(err)\n }\n else {\n consola.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err))\n }\n process.exit(1)\n})\n","import path from 'node:path'\n\n/**\n * Possible actions emitted by `rewriteApeShellArgs` for the caller to\n * dispatch. `rewrite` means argv has been transformed and the normal CLI\n * command dispatch should continue with the new argv. `interactive` means\n * the caller should hand control to the interactive REPL. The other\n * actions print version/help/error text and exit.\n */\nexport type ApeShellAction =\n | { action: 'rewrite', argv: string[] }\n | { action: 'version' }\n | { action: 'help' }\n | { action: 'error' }\n | { action: 'interactive' }\n\n/**\n * Decides how `ape-shell` was invoked and what the caller should do next.\n * Backward compatibility is strict: any invocation with `-c \"<command>\"`\n * keeps the historical rewrite behavior so `SHELL=$(which ape-shell) <prog>`\n * patterns (e.g. `SHELL=ape-shell openclaw tui`) continue to work.\n *\n * Detection strategy:\n * 1. `process.env.APES_SHELL_WRAPPER === '1'` is the strongest signal —\n * it means we were invoked via the ape-shell-wrapper.sh shell script,\n * which hoists node onto PATH before exec-ing cli.js. In that case\n * argv[1] becomes `cli.js` (or some dist/chunk file) and the old\n * basename check fails, so we trust the wrapper's declaration.\n * 2. Otherwise fall back to `argv[1]` basename matching literal\n * `ape-shell` / `ape-shell.js` (the direct-symlink invocation path).\n *\n * After detection, the rest of the rules decide the action (first match):\n * • `-c <command>` → rewrite to `apes run --shell -- bash -c <command>`.\n * • `--version` / `-v` → version action.\n * • `--help` / `-h` → help action.\n * • no args, `-i`, `-l`, `--login`, or a login-shell convention dash\n * prefix (on argv[1] or argv0) → interactive REPL.\n * • anything else → error action.\n */\nexport function rewriteApeShellArgs(argv: string[], argv0?: string): ApeShellAction | null {\n const rawInvokedAs = argv[1] ?? ''\n // sshd/login use a leading dash on argv[0] to signal \"login shell\".\n // Strip it for the basename comparison, but remember the flag. The dash\n // may appear on argv[1] (direct invocation) or on the separately-passed\n // argv0 parameter (wrapper invocation — shell `exec -a \"$0\"` sets node's\n // actual argv[0] / `process.argv0` independently from argv[1]).\n const dashFromArgv1 = rawInvokedAs.startsWith('-')\n const dashFromArgv0 = typeof argv0 === 'string' && argv0.startsWith('-')\n const looksLikeLoginShell = dashFromArgv1 || dashFromArgv0\n const normalizedInvokedAs = dashFromArgv1 ? rawInvokedAs.slice(1) : rawInvokedAs\n const invokedAs = path.basename(normalizedInvokedAs)\n\n // Primary detection: explicit wrapper signal via env var. Takes\n // precedence because argv-based detection gets clobbered when the\n // wrapper execs node directly and argv[1] becomes cli.js.\n const wrapperEnv = typeof process !== 'undefined' && process.env?.APES_SHELL_WRAPPER === '1'\n\n // Secondary detection: argv[1] basename matches literal `ape-shell` or\n // `ape-shell.js` — the direct-symlink invocation path.\n const argvMatch = invokedAs === 'ape-shell' || invokedAs === 'ape-shell.js'\n\n if (!wrapperEnv && !argvMatch)\n return null\n\n const shellArgs = argv.slice(2)\n\n // -c <command> is the historical one-shot path — must stay untouched so\n // programs that use `$SHELL -c \"<cmd>\"` (openclaw tui, xargs, git hooks,\n // sshd non-interactive, etc.) continue to work unchanged.\n if (shellArgs[0] === '-c' && shellArgs.length > 1) {\n return { action: 'rewrite', argv: [argv[0]!, argv[1]!, 'run', '--shell', '--', 'bash', '-c', ...shellArgs.slice(1)] }\n }\n\n if (shellArgs[0] === '--version' || shellArgs[0] === '-v')\n return { action: 'version' }\n\n if (shellArgs[0] === '--help' || shellArgs[0] === '-h')\n return { action: 'help' }\n\n // No positional args, explicit interactive flag, or login-shell\n // convention (`looksLikeLoginShell` detected from the dash-prefixed\n // argv[1] above) → enter the interactive REPL.\n if (\n shellArgs.length === 0\n || shellArgs[0] === '-i'\n || shellArgs[0] === '-l'\n || shellArgs[0] === '--login'\n || looksLikeLoginShell\n ) {\n return { action: 'interactive' }\n }\n\n return { action: 'error' }\n}\n","import { Buffer } from 'node:buffer'\nimport { execFile } from 'node:child_process'\nimport { createServer } from 'node:http'\nimport { homedir } from 'node:os'\nimport { resolve as resolvePath } from 'node:path'\nimport { defineCommand } from 'citty'\nimport { generateCodeChallenge, generateCodeVerifier } from '@openape/core'\nimport consola from 'consola'\nimport { loadConfig, saveAuth, saveConfig } from '../../config'\nimport { getAgentAuthenticateEndpoint, getAgentChallengeEndpoint } from '../../http'\nimport { CliError } from '../../errors'\nimport { resolveLoginInputs } from './resolve-login'\n\nconst CALLBACK_PORT = 9876\n// OAuth client ID registered with IdPs. Historically `grapes-cli`;\n// renamed to `apes-cli` as part of the apes/escapes naming alignment.\n// IdP operators must register this client id (free-idp already does;\n// third-party IdPs need a coordinated rollout with a transitional\n// period accepting both).\nconst CLIENT_ID = 'apes-cli'\n\nexport const loginCommand = defineCommand({\n meta: {\n name: 'login',\n description: 'Authenticate with an OpenApe IdP',\n },\n args: {\n user: {\n type: 'positional',\n required: false,\n description: 'Agent email (e.g. patrick@hofmann.eco). Extracted from <key>.pub comment if omitted.',\n },\n idp: {\n type: 'string',\n description: 'IdP URL (e.g. https://id.openape.at). Auto-discovered via DDISA DNS if omitted.',\n },\n key: {\n type: 'string',\n description: 'Path to agent private key. Defaults to ~/.ssh/id_ed25519 if present.',\n },\n email: {\n type: 'string',\n description: 'Same as the positional email — flag form for backwards compatibility.',\n },\n browser: {\n type: 'boolean',\n description: 'Force browser (PKCE) login even if an SSH key exists',\n },\n force: {\n type: 'boolean',\n description: 'Override DDISA mismatch warnings (use with care)',\n },\n },\n async run({ args }) {\n // Positional `user` and the legacy `--email` flag both set email.\n // Positional wins when both are present (it's the new ergonomic form).\n const emailArg = (typeof args.user === 'string' && args.user.includes('@'))\n ? args.user\n : (typeof args.email === 'string' ? args.email : undefined)\n\n const resolved = await resolveLoginInputs({\n key: args.key,\n idp: args.idp,\n email: emailArg,\n browser: args.browser,\n })\n\n if (resolved.ddisaMismatch && !args.force) {\n const { dnsIdp, chosenIdp, domain } = resolved.ddisaMismatch\n throw new CliError(\n `IdP mismatch for ${domain}.\\n\\n`\n + ` Authoritative DDISA: ${dnsIdp}\\n`\n + ` You selected: ${chosenIdp}\\n\\n`\n + `Logging in against a different IdP than DDISA points to means SPs that\\n`\n + `trust the DDISA-resolved IdP (e.g. preview.openape.ai) will reject the\\n`\n + `resulting token with \"IdP mismatch\".\\n\\n`\n + `Fix one of:\\n`\n + ` • Drop --idp/APES_IDP/config.defaults.idp — DDISA will auto-pick ${dnsIdp}\\n`\n + ` • Update _ddisa.${domain} if ${chosenIdp} is genuinely the correct IdP\\n`\n + ` • Re-run with --force to authenticate anyway (NOT recommended)`,\n )\n }\n if (resolved.ddisaMismatch && args.force) {\n consola.warn(\n `Bypassing DDISA mismatch — ${resolved.ddisaMismatch.domain} resolves to `\n + `${resolved.ddisaMismatch.dnsIdp}, but you forced ${resolved.ddisaMismatch.chosenIdp}.`,\n )\n }\n\n if (resolved.keyPath) {\n if (!resolved.email) {\n throw new CliError(\n `Agent email required for key-based login. Pass it as a positional `\n + `(\\`apes login <email>\\`), set --email, or add an email comment to `\n + `${resolved.keyPath}.pub via ssh-keygen -C <email>.`,\n )\n }\n if (!resolved.idp) {\n const domain = resolved.email.split('@')[1]\n throw new CliError(\n `No IdP found for ${resolved.email}.\\n\\n`\n + `There is no DDISA TXT record for ${domain} and no --idp was provided.\\n\\n`\n + `Options:\\n`\n + ` • Run your own IdP (recommended for production)\\n`\n + ` See: https://docs.openape.at\\n`\n + ` • Publish a DDISA TXT record for your domain:\\n`\n + ` _ddisa.${domain} TXT \"v=ddisa1 idp=https://your-idp.example\"\\n`\n + ` • Use OpenApe's free hosted IdP for testing:\\n`\n + ` apes login --idp https://id.openape.at`,\n )\n }\n await loginWithKey(resolved.idp, resolved.keyPath, resolved.email)\n }\n else {\n if (!resolved.idp) {\n throw new CliError('IdP URL required for browser login. Use --idp <url> or set APES_IDP.')\n }\n await loginWithPKCE(resolved.idp)\n }\n },\n})\n\nfunction openBrowser(url: string) {\n const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n execFile(cmd, [url], () => {})\n}\n\nasync function loginWithPKCE(idp: string) {\n const codeVerifier = generateCodeVerifier()\n const codeChallenge = await generateCodeChallenge(codeVerifier)\n const redirectUri = `http://localhost:${CALLBACK_PORT}/callback`\n\n const state = crypto.randomUUID()\n const nonce = crypto.randomUUID()\n\n const authUrl = new URL(`${idp}/authorize`)\n authUrl.searchParams.set('response_type', 'code')\n authUrl.searchParams.set('client_id', CLIENT_ID)\n authUrl.searchParams.set('redirect_uri', redirectUri)\n authUrl.searchParams.set('code_challenge', codeChallenge)\n authUrl.searchParams.set('code_challenge_method', 'S256')\n authUrl.searchParams.set('state', state)\n authUrl.searchParams.set('nonce', nonce)\n authUrl.searchParams.set('scope', 'openid email profile offline_access')\n\n // Start local callback server\n const code = await new Promise<string>((resolve, reject) => {\n const server = createServer((req, res) => {\n const url = new URL(req.url!, `http://localhost:${CALLBACK_PORT}`)\n if (url.pathname === '/callback') {\n const authCode = url.searchParams.get('code')\n const error = url.searchParams.get('error')\n\n if (error) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end('<h1>Login failed</h1><p>You can close this window.</p>')\n server.close()\n reject(new Error(`Auth error: ${error}`))\n return\n }\n\n if (authCode) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end('<h1>Login successful!</h1><p>You can close this window.</p>')\n server.close()\n resolve(authCode)\n return\n }\n\n res.writeHead(400)\n res.end('Missing code')\n }\n else {\n res.writeHead(404)\n res.end()\n }\n })\n\n server.listen(CALLBACK_PORT, () => {\n // Always print the URL so the user can copy it manually — headless SSH\n // sessions, containers, and restricted-user shells cannot open a browser.\n // The `open` attempt below is fire-and-forget convenience only.\n console.log('')\n console.log('Visit the following URL in a browser to authenticate:')\n console.log('')\n console.log(` ${authUrl.toString()}`)\n console.log('')\n consola.info(`Waiting for authentication callback on ${redirectUri} ...`)\n openBrowser(authUrl.toString())\n })\n\n // Timeout after 5 minutes\n const timeout = setTimeout(() => {\n server.close()\n reject(new Error('Login timed out'))\n }, 300_000)\n timeout.unref()\n })\n\n // Exchange code for tokens\n const tokenResponse = await fetch(`${idp}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n client_id: CLIENT_ID,\n }),\n })\n\n if (!tokenResponse.ok) {\n const text = await tokenResponse.text()\n throw new CliError(`Token exchange failed: ${text}`)\n }\n\n const tokens = await tokenResponse.json() as {\n access_token?: string\n id_token?: string\n refresh_token?: string\n expires_in?: number\n assertion?: string\n }\n\n const accessToken = tokens.access_token || tokens.id_token || tokens.assertion\n if (!accessToken) {\n throw new CliError('No access token received')\n }\n\n // Decode JWT to get email\n const payload = JSON.parse(atob(accessToken.split('.')[1]!))\n\n saveAuth({\n idp,\n access_token: accessToken,\n ...(tokens.refresh_token ? { refresh_token: tokens.refresh_token } : {}),\n email: payload.email || payload.sub,\n expires_at: Math.floor(Date.now() / 1000) + (tokens.expires_in || 3600),\n })\n\n consola.success(`Logged in as ${payload.email || payload.sub}`)\n}\n\nasync function loginWithKey(idp: string, keyPath: string, agentEmail: string) {\n const { readFileSync } = await import('node:fs')\n const { sign } = await import('node:crypto')\n const { loadEd25519PrivateKey } = await import('../../ssh-key.js')\n\n // Use challenge-response auth (endpoint resolved via OIDC discovery)\n const challengeUrl = await getAgentChallengeEndpoint(idp)\n const challengeResp = await fetch(challengeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: agentEmail }),\n })\n\n if (!challengeResp.ok) {\n throw new CliError(`Challenge failed: ${await challengeResp.text()}`)\n }\n\n const { challenge } = await challengeResp.json() as { challenge: string }\n\n // Sign challenge with Ed25519 private key (supports OpenSSH + PKCS8 format)\n const keyContent = readFileSync(keyPath, 'utf-8')\n const privateKey = loadEd25519PrivateKey(keyContent)\n const signature = sign(null, Buffer.from(challenge), privateKey).toString('base64')\n\n // Authenticate (endpoint resolved via OIDC discovery)\n const authenticateUrl = await getAgentAuthenticateEndpoint(idp)\n const authResp = await fetch(authenticateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agent_id: agentEmail,\n challenge,\n signature,\n }),\n })\n\n if (!authResp.ok) {\n throw new CliError(`Authentication failed: ${await authResp.text()}`)\n }\n\n const { token, expires_in } = await authResp.json() as { token: string, expires_in: number }\n\n // Persist the absolute key path on auth.json so any cli-auth consumer\n // (chat-bridge, ape-tasks, ape-plans, …) can refresh the agent token\n // in-process without shelling out to `apes login`. See issue #259.\n const absoluteKeyPath = resolvePath(keyPath.replace(/^~/, homedir()))\n saveAuth({\n idp,\n access_token: token,\n email: agentEmail,\n expires_at: Math.floor(Date.now() / 1000) + (expires_in || 3600),\n key_path: absoluteKeyPath,\n })\n const existingConfig = loadConfig()\n saveConfig({\n ...existingConfig,\n agent: {\n ...existingConfig.agent,\n key: absoluteKeyPath,\n email: agentEmail,\n },\n })\n\n consola.success(`Logged in as ${agentEmail}`)\n consola.info(`Auto-refresh enabled (key path saved to ~/.config/apes/config.toml)`)\n}\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { resolveDDISA } from '@openape/core'\nimport consola from 'consola'\nimport { loadConfig } from '../../config'\nimport { readPublicKeyComment } from '../../ssh-key'\n\nexport interface LoginInputs {\n key?: string\n idp?: string\n email?: string\n browser?: boolean\n}\n\nexport interface ResolvedLoginInputs {\n keyPath?: string\n email?: string\n idp?: string\n /**\n * Set when the chosen `idp` came from an explicit flag/env/config but the\n * email's domain has a DDISA record pointing at a *different* IdP. The\n * caller decides whether to refuse (default), warn-and-continue (`--force`),\n * etc. `undefined` means no mismatch (or no DDISA record to compare against).\n */\n ddisaMismatch?: { dnsIdp: string, chosenIdp: string, domain: string }\n}\n\nconst DEFAULT_KEY = join(homedir(), '.ssh', 'id_ed25519')\n\n/**\n * Resolve login inputs by walking a fallback cascade:\n * 1. explicit flag\n * 2. environment variable\n * 3. ~/.config/apes/config.toml\n * 4. derivation (default key path, pub key comment, DDISA DNS)\n *\n * When `browser` is true, no key is resolved so the caller falls back to PKCE.\n */\nexport async function resolveLoginInputs(\n flags: LoginInputs,\n): Promise<ResolvedLoginInputs> {\n const config = loadConfig()\n\n // 1. Key path — skipped entirely in forced browser mode\n let keyPath: string | undefined\n if (!flags.browser) {\n if (flags.key) {\n keyPath = flags.key\n }\n else if (process.env.APES_KEY) {\n keyPath = process.env.APES_KEY\n consola.info(`Using key from APES_KEY: ${keyPath}`)\n }\n else if (config.agent?.key) {\n keyPath = config.agent.key\n consola.info(`Using key from config: ${keyPath}`)\n }\n else if (existsSync(DEFAULT_KEY)) {\n keyPath = DEFAULT_KEY\n consola.info(`Using default key: ${keyPath}`)\n }\n }\n\n // 2. Email\n let email: string | undefined\n if (flags.email) {\n email = flags.email\n }\n else if (process.env.APES_EMAIL) {\n email = process.env.APES_EMAIL\n }\n else if (config.agent?.email) {\n email = config.agent.email\n }\n else if (keyPath) {\n const comment = readPublicKeyComment(`${keyPath}.pub`)\n if (comment && comment.includes('@')) {\n email = comment\n consola.info(`Using email from ${keyPath}.pub comment: ${email}`)\n }\n }\n\n // 3. IdP\n // APES_IDP is the canonical env var. GRAPES_IDP is a deprecated alias\n // kept for users with older shell profiles; APES_IDP wins on conflict.\n if (process.env.APES_IDP && process.env.GRAPES_IDP) {\n consola.warn(\n 'Both APES_IDP and GRAPES_IDP are set — using APES_IDP. '\n + 'GRAPES_IDP is deprecated and will be removed in a future release.',\n )\n }\n let idp: string | undefined\n let idpSource: 'flag' | 'env' | 'config' | 'ddisa' | undefined\n if (flags.idp) {\n idp = flags.idp\n idpSource = 'flag'\n }\n else if (process.env.APES_IDP) {\n idp = process.env.APES_IDP\n idpSource = 'env'\n }\n else if (process.env.GRAPES_IDP) {\n idp = process.env.GRAPES_IDP\n idpSource = 'env'\n consola.warn(\n 'GRAPES_IDP is deprecated, use APES_IDP instead. '\n + 'GRAPES_IDP support will be removed in a future release.',\n )\n }\n else if (config.defaults?.idp) {\n idp = config.defaults.idp\n idpSource = 'config'\n }\n\n // Always probe DDISA when we have an email — both as the auto-discovery\n // path (when no explicit IdP was supplied) and as a sanity-check against\n // explicit overrides. The caller surfaces the resulting mismatch and\n // gates it behind --force.\n let ddisaIdp: string | undefined\n let ddisaDomain: string | undefined\n if (email && email.includes('@')) {\n const domain = email.split('@')[1]!\n ddisaDomain = domain\n try {\n const record = await resolveDDISA(domain)\n if (record?.idp) ddisaIdp = record.idp\n }\n catch {\n // DNS failure is non-fatal\n }\n }\n\n if (!idp && ddisaIdp && ddisaDomain) {\n idp = ddisaIdp\n idpSource = 'ddisa'\n consola.info(`Discovered IdP via DDISA (_ddisa.${ddisaDomain}): ${idp}`)\n }\n\n // Mismatch only matters when the user explicitly chose an IdP that differs\n // from the authoritative DNS record. Auto-discovered IdPs (idpSource ===\n // 'ddisa') are by definition the DDISA record, so they can't mismatch.\n let ddisaMismatch: ResolvedLoginInputs['ddisaMismatch']\n if (idp && ddisaIdp && ddisaDomain && idp !== ddisaIdp && idpSource !== 'ddisa') {\n ddisaMismatch = { dnsIdp: ddisaIdp, chosenIdp: idp, domain: ddisaDomain }\n }\n\n return { keyPath, email, idp, ddisaMismatch }\n}\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { clearAuth } from '../../config'\n\nexport const logoutCommand = defineCommand({\n meta: {\n name: 'logout',\n description: 'Clear stored credentials',\n },\n run() {\n clearAuth()\n consola.success('Logged out.')\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const whoamiCommand = defineCommand({\n meta: {\n name: 'whoami',\n description: 'Show current identity',\n },\n run() {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n // Token freshness is handled centrally in cli.ts via ensureFreshToken\n // before any subcommand other than login/logout/init/etc. runs. By the\n // time we get here, auth.json is as fresh as it can be — we just print.\n const isAgent = auth.email.includes('agent+')\n const expiresAt = new Date(auth.expires_at * 1000).toISOString()\n const isExpired = Date.now() / 1000 > auth.expires_at\n\n console.log(`Email: ${auth.email}`)\n console.log(`Type: ${isAgent ? 'agent' : 'human'}`)\n console.log(`IdP: ${auth.idp}`)\n console.log(`Token: ${isExpired ? '⚠ EXPIRED' : 'valid'} (until ${expiresAt})`)\n\n if (isExpired) {\n consola.warn('Token is expired and could not be auto-refreshed. Run `apes login` to re-authenticate.')\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface Grant {\n id: string\n type: string\n status: string\n requester: string\n owner: string\n request: {\n command?: string[]\n grant_type?: string\n reason?: string\n }\n created_at?: string\n}\n\ninterface PaginatedGrants {\n data: Grant[]\n pagination: {\n cursor: string | null\n has_more: boolean\n }\n}\n\nexport const listCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List your grants (as requester)',\n },\n args: {\n status: {\n type: 'string',\n description: 'Filter by status (pending, approved, denied, revoked, used)',\n },\n all: {\n type: 'boolean',\n description: 'Show all visible grants (not just your own)',\n default: false,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n limit: {\n type: 'string',\n description: 'Max results (default 20, max 100)',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const auth = loadAuth()\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const params = new URLSearchParams()\n if (args.status)\n params.set('status', args.status)\n if (args.limit)\n params.set('limit', args.limit)\n const query = params.toString() ? `?${params.toString()}` : ''\n\n const response = await apiFetch<PaginatedGrants>(`${grantsUrl}${query}`)\n\n let grants = response.data\n\n // Filter to own grants unless --all\n if (!args.all && auth?.email) {\n grants = grants.filter(g => g.requester === auth.email)\n }\n\n if (args.json) {\n console.log(JSON.stringify(args.all ? response : { ...response, data: grants }, null, 2))\n return\n }\n\n if (grants.length === 0) {\n consola.info(args.all ? 'No grants found.' : 'No grants found. Use --all to see all visible grants.')\n return\n }\n\n for (const grant of grants) {\n const cmd = grant.request?.command?.join(' ') || '(no command)'\n const type = grant.request?.grant_type || grant.type\n console.log(`${grant.id} ${grant.status.padEnd(8)} ${type.padEnd(6)} ${cmd}`)\n if (grant.request?.reason) {\n console.log(` Reason: ${grant.request.reason}`)\n }\n }\n\n if (response.pagination.has_more) {\n consola.info('More results available. Use --limit or pagination cursor.')\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface Grant {\n id: string\n type: string\n status: string\n requester: string\n owner: string\n request: {\n command?: string[]\n grant_type?: string\n reason?: string\n }\n created_at?: string\n}\n\ninterface PaginatedGrants {\n data: Grant[]\n pagination: {\n cursor: string | null\n has_more: boolean\n }\n}\n\nexport const inboxCommand = defineCommand({\n meta: {\n name: 'inbox',\n description: 'Show grants awaiting your approval',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n limit: {\n type: 'string',\n description: 'Max results (default 20, max 100)',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const params = new URLSearchParams()\n params.set('status', 'pending')\n if (args.limit)\n params.set('limit', args.limit)\n const query = `?${params.toString()}`\n\n const response = await apiFetch<PaginatedGrants>(`${grantsUrl}${query}`)\n\n // Filter out own requests — inbox shows only grants from others\n const grants = response.data.filter(g => g.requester !== auth.email)\n\n if (args.json) {\n console.log(JSON.stringify({ ...response, data: grants }, null, 2))\n return\n }\n\n if (grants.length === 0) {\n consola.info('No pending grants to approve.')\n return\n }\n\n consola.info(`${grants.length} grant(s) awaiting approval:\\n`)\n\n for (const grant of grants) {\n const cmd = grant.request?.command?.join(' ') || '(no command)'\n const type = grant.request?.grant_type || grant.type\n console.log(`${grant.id} ${type.padEnd(6)} from ${grant.requester}`)\n console.log(` Command: ${cmd}`)\n if (grant.request?.reason) {\n console.log(` Reason: ${grant.request.reason}`)\n }\n if (grant.created_at) {\n console.log(` Created: ${grant.created_at}`)\n }\n console.log()\n }\n\n consola.info('Use `apes grants approve <id>` or `apes grants deny <id>` to respond.')\n },\n})\n","import { defineCommand } from 'citty'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\n\n/**\n * Shape returned by `GET /grants/<id>` on the OpenApe IdP. Matches the\n * free-idp response as of 2026-04: `requester`, `target_host`, `audience`,\n * `grant_type`, etc. all live under the nested `request` object. Top-level\n * `type` is a legacy field that is currently always `null`. Timestamps are\n * unix seconds (numbers), not ISO strings.\n */\ninterface GrantDetail {\n id: string\n type?: string | null\n status: string\n request?: {\n requester?: string\n target_host?: string\n audience?: string\n grant_type?: string\n command?: string[]\n reason?: string\n }\n created_at?: number\n decided_at?: number\n decided_by?: string\n used_at?: number\n expires_at?: number\n}\n\n/** Unix seconds → ISO-8601 with graceful fallback for bogus values. */\nfunction formatTs(ts: number | undefined): string | undefined {\n if (ts === undefined || ts === null)\n return undefined\n const ms = ts * 1000\n if (!Number.isFinite(ms))\n return undefined\n return new Date(ms).toISOString()\n}\n\nexport const statusCommand = defineCommand({\n meta: {\n name: 'status',\n description: 'Show grant status',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n const grant = await apiFetch<GrantDetail>(`${grantsUrl}/${args.id}`)\n\n if (args.json) {\n console.log(JSON.stringify(grant, null, 2))\n return\n }\n\n console.log(`Grant: ${grant.id}`)\n console.log(`Status: ${grant.status}`)\n if (grant.request?.audience)\n console.log(`Audience: ${grant.request.audience}`)\n if (grant.request?.requester)\n console.log(`Requester: ${grant.request.requester}`)\n if (grant.request?.target_host)\n console.log(`Host: ${grant.request.target_host}`)\n if (grant.request?.command)\n console.log(`Command: ${grant.request.command.join(' ')}`)\n if (grant.request?.grant_type)\n console.log(`Approval: ${grant.request.grant_type}`)\n if (grant.request?.reason)\n console.log(`Reason: ${grant.request.reason}`)\n const createdAt = formatTs(grant.created_at)\n if (createdAt)\n console.log(`Created: ${createdAt}`)\n if (grant.decided_by)\n console.log(`Decided by: ${grant.decided_by}`)\n const decidedAt = formatTs(grant.decided_at)\n if (decidedAt)\n console.log(`Decided at: ${decidedAt}`)\n const usedAt = formatTs(grant.used_at)\n if (usedAt)\n console.log(`Used at: ${usedAt}`)\n const expiresAt = formatTs(grant.expires_at)\n if (expiresAt)\n console.log(`Expires: ${expiresAt}`)\n },\n})\n","import { hostname } from 'node:os'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { parseDuration } from '../../duration'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const requestCommand = defineCommand({\n meta: {\n name: 'request',\n description: 'Request a new grant',\n },\n args: {\n command: {\n type: 'positional',\n description: 'Command to request permission for',\n required: true,\n },\n audience: {\n type: 'string',\n description: 'Service identifier (e.g. \"escapes\", \"proxy\")',\n required: true,\n },\n host: {\n type: 'string',\n description: 'Target host (default: system hostname)',\n },\n reason: {\n type: 'string',\n description: 'Reason for the request',\n },\n approval: {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n duration: {\n type: 'string',\n description: 'Duration for timed grants (e.g. 30m, 1h, 7d)',\n },\n 'run-as': {\n type: 'string',\n description: 'Execute as this user (e.g. openclaw, root)',\n },\n wait: {\n type: 'boolean',\n description: 'Wait for approval',\n default: false,\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n const command = args.command.split(' ')\n const targetHost = args.host || hostname()\n\n const duration = args.duration ? parseDuration(args.duration) : undefined\n\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n body: {\n requester: auth.email,\n target_host: targetHost,\n audience: args.audience,\n grant_type: args.approval,\n command,\n reason: args.reason || command.join(' '),\n ...(duration != null ? { duration } : {}),\n ...(args['run-as'] ? { run_as: args['run-as'] } : {}),\n },\n })\n\n consola.success(`Grant requested: ${grant.id} (status: ${grant.status})`)\n\n if (args.wait) {\n consola.info('Waiting for approval...')\n await waitForApproval(grantsUrl, grant.id)\n }\n },\n})\n\nasync function waitForApproval(grantsUrl: string, grantId: string): Promise<void> {\n const maxWait = 300_000 // 5 minutes\n const interval = 3_000\n const start = Date.now()\n\n while (Date.now() - start < maxWait) {\n const grant = await apiFetch<{ status: string }>(`${grantsUrl}/${grantId}`)\n\n if (grant.status === 'approved') {\n consola.success('Grant approved!')\n return\n }\n if (grant.status === 'denied') {\n throw new CliError('Grant denied.')\n }\n if (grant.status === 'revoked') {\n throw new CliError('Grant revoked.')\n }\n\n await new Promise(r => setTimeout(r, interval))\n }\n\n throw new CliError('Timed out waiting for approval.')\n}\n","import { hostname } from 'node:os'\nimport { buildStructuredCliGrantRequest, loadAdapter, resolveCapabilityRequest } from '../../shapes/index.js'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { parseDuration } from '../../duration'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nfunction parseCapabilityArgs(rawArgs: string[]): {\n cliId: string\n adapter?: string\n idp?: string\n approval: 'once' | 'timed' | 'always'\n reason?: string\n duration?: number\n runAs?: string\n wait: boolean\n resources: string[]\n selectors: string[]\n actions: string[]\n} {\n const tokens = [...rawArgs]\n if (tokens[0] === 'request-capability') {\n tokens.shift()\n }\n\n const cliId = tokens.shift()\n if (!cliId || cliId.startsWith('-')) {\n throw new Error('Missing CLI identifier')\n }\n\n const resources: string[] = []\n const selectors: string[] = []\n const actions: string[] = []\n let adapter: string | undefined\n let idp: string | undefined\n let approval: 'once' | 'timed' | 'always' = 'once'\n let reason: string | undefined\n let duration: number | undefined\n let runAs: string | undefined\n let wait = false\n\n for (let index = 0; index < tokens.length; index += 1) {\n const token = tokens[index]!\n const next = tokens[index + 1]\n switch (token) {\n case '--resource':\n if (!next)\n throw new Error('Missing value for --resource')\n resources.push(next)\n index += 1\n break\n case '--selector':\n if (!next)\n throw new Error('Missing value for --selector')\n selectors.push(next)\n index += 1\n break\n case '--action':\n if (!next)\n throw new Error('Missing value for --action')\n actions.push(next)\n index += 1\n break\n case '--adapter':\n if (!next)\n throw new Error('Missing value for --adapter')\n adapter = next\n index += 1\n break\n case '--idp':\n if (!next)\n throw new Error('Missing value for --idp')\n idp = next\n index += 1\n break\n case '--approval':\n if (!next || !['once', 'timed', 'always'].includes(next)) {\n throw new Error('Approval must be one of: once, timed, always')\n }\n approval = next as 'once' | 'timed' | 'always'\n index += 1\n break\n case '--reason':\n if (!next)\n throw new Error('Missing value for --reason')\n reason = next\n index += 1\n break\n case '--duration':\n if (!next)\n throw new Error('Missing value for --duration')\n duration = parseDuration(next)\n index += 1\n break\n case '--run-as':\n if (!next)\n throw new Error('Missing value for --run-as')\n runAs = next\n index += 1\n break\n case '--wait':\n wait = true\n break\n default:\n throw new Error(`Unknown argument: ${token}`)\n }\n }\n\n return {\n cliId,\n adapter,\n idp,\n approval,\n reason,\n duration,\n runAs,\n wait,\n resources,\n selectors,\n actions,\n }\n}\n\nasync function waitForApproval(grantsUrl: string, grantId: string): Promise<void> {\n const maxWait = 300_000\n const interval = 3_000\n const start = Date.now()\n\n while (Date.now() - start < maxWait) {\n const grant = await apiFetch<{ status: string }>(`${grantsUrl}/${grantId}`)\n if (grant.status === 'approved') {\n consola.success('Grant approved!')\n return\n }\n if (grant.status === 'denied') {\n throw new CliError('Grant denied.')\n }\n if (grant.status === 'revoked') {\n throw new CliError('Grant revoked.')\n }\n await new Promise(resolve => setTimeout(resolve, interval))\n }\n\n throw new CliError('Timed out waiting for approval.')\n}\n\nexport const requestCapabilityCommand = defineCommand({\n meta: {\n name: 'request-capability',\n description: 'Request a structured CLI capability grant',\n },\n args: {\n 'cliId': {\n type: 'positional',\n description: 'CLI adapter identifier (e.g. docker, kubectl)',\n required: true,\n },\n 'resource': {\n type: 'string',\n description: 'Resource scope (repeatable)',\n },\n 'selector': {\n type: 'string',\n description: 'Selector filter (repeatable)',\n },\n 'action': {\n type: 'string',\n description: 'Action to permit (repeatable)',\n },\n 'adapter': {\n type: 'string',\n description: 'Explicit path to adapter TOML file',\n },\n 'idp': {\n type: 'string',\n description: 'IdP URL',\n },\n 'approval': {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n 'reason': {\n type: 'string',\n description: 'Reason for the request',\n },\n 'duration': {\n type: 'string',\n description: 'Duration for timed grants (e.g. 30m, 1h, 7d)',\n },\n 'run-as': {\n type: 'string',\n description: 'Execute as this user (e.g. root)',\n },\n 'wait': {\n type: 'boolean',\n description: 'Wait for approval before returning',\n default: false,\n },\n },\n async run({ rawArgs }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const parsed = parseCapabilityArgs(rawArgs)\n const idp = getIdpUrl(parsed.idp)\n if (!idp) {\n throw new CliError('No IdP URL configured. Use --idp or log in first.')\n }\n\n const loaded = loadAdapter(parsed.cliId, parsed.adapter)\n const resolved = resolveCapabilityRequest(loaded, {\n resources: parsed.resources,\n selectors: parsed.selectors,\n actions: parsed.actions,\n })\n\n const { request } = await buildStructuredCliGrantRequest(resolved, {\n requester: auth.email,\n target_host: hostname(),\n grant_type: parsed.approval,\n ...(parsed.reason ? { reason: parsed.reason } : {}),\n })\n\n if (parsed.duration != null) {\n request.duration = parsed.duration\n }\n if (parsed.runAs) {\n request.run_as = parsed.runAs\n }\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n idp,\n body: request,\n })\n\n consola.success(`Grant requested: ${grant.id} (status: ${grant.status})`)\n\n if (parsed.wait) {\n consola.info('Waiting for approval...')\n await waitForApproval(grantsUrl, grant.id)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\n\nexport const approveCommand = defineCommand({\n meta: {\n name: 'approve',\n description: 'Approve a grant request',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n await apiFetch(`${grantsUrl}/${args.id}/approve`, {\n method: 'POST',\n })\n consola.success(`Grant ${args.id} approved.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\n\nexport const denyCommand = defineCommand({\n meta: {\n name: 'deny',\n description: 'Deny a grant request',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n await apiFetch(`${grantsUrl}/${args.id}/deny`, {\n method: 'POST',\n })\n consola.success(`Grant ${args.id} denied.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getAuthToken, getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface Grant {\n id: string\n status: string\n // Some list endpoints return requester nested under request\n requester?: string\n request?: { requester?: string, command?: string[] }\n}\n\ninterface PaginatedGrants {\n data: Grant[]\n pagination: { cursor: string | null, has_more: boolean }\n}\n\ninterface BatchResult {\n id: string\n status: string\n success: boolean\n error?: { title: string }\n}\n\nexport const revokeCommand = defineCommand({\n meta: {\n name: 'revoke',\n description: 'Revoke one or more grants',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID(s) to revoke',\n required: false,\n },\n allPending: {\n type: 'boolean',\n description: 'Revoke all own pending grants',\n default: false,\n },\n debug: {\n type: 'boolean',\n description: 'Print debug information (does not include full tokens)',\n default: false,\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n const token = getAuthToken()\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n\n if (args.debug) {\n consola.debug(`idp: ${idp}`)\n consola.debug(`grantsUrl: ${grantsUrl}`)\n consola.debug(`auth.email: ${auth?.email}`)\n consola.debug(`auth.expires_at: ${auth?.expires_at} (now: ${Math.floor(Date.now() / 1000)})`)\n consola.debug(`getAuthToken(): ${token ? `${token.substring(0, 20)}...` : 'NULL'}`)\n }\n\n if (!auth || !token) {\n throw new CliError('Authentication required. Run `apes login` and try again.')\n }\n\n const explicitIds = args.id\n ? [String(args.id), ...args._].filter(Boolean)\n : []\n\n if (args.allPending && explicitIds.length > 0) {\n throw new CliError('Use either --all-pending or grant IDs, not both.')\n }\n\n let ids: string[]\n\n if (args.allPending) {\n const auth = loadAuth()\n const response = await apiFetch<PaginatedGrants>(\n `${grantsUrl}?status=pending&limit=100`,\n { token },\n )\n const ownPending = auth?.email\n ? response.data.filter(g => g.request?.requester === auth.email)\n : response.data\n if (ownPending.length === 0) {\n consola.info('No pending grants to revoke.')\n return\n }\n ids = ownPending.map(g => g.id)\n consola.info(`Found ${ids.length} pending grant(s) to revoke.`)\n }\n else if (explicitIds.length > 0) {\n ids = explicitIds\n }\n else {\n throw new CliError('Provide grant ID(s) or use --all-pending.')\n }\n\n // Single grant: use direct endpoint\n if (ids.length === 1) {\n await apiFetch(`${grantsUrl}/${ids[0]}/revoke`, { method: 'POST', token })\n consola.success(`Grant ${ids[0]} revoked.`)\n return\n }\n\n // Multiple grants: use batch endpoint\n const operations = ids.map(id => ({ id, action: 'revoke' as const }))\n const { results } = await apiFetch<{ results: BatchResult[] }>(\n `${grantsUrl}/batch`,\n { method: 'POST', body: { operations }, token },\n )\n\n let succeeded = 0\n for (const r of results) {\n if (r.success) {\n consola.success(`Grant ${r.id} revoked.`)\n succeeded++\n }\n else {\n consola.error(`Grant ${r.id}: ${r.error?.title || 'Failed'}`)\n }\n }\n\n if (succeeded < results.length) {\n throw new CliError(`Revoked ${succeeded} of ${results.length} grants.`)\n }\n else {\n consola.success(`All ${succeeded} grants revoked.`)\n }\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { CliError, CliExit } from '../../errors'\nimport { getPollMaxMinutes, pollGrantUntilResolved } from '../../grant-poll'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { fetchGrantToken, resolveFromGrant, verifyAndExecute } from '../../shapes/index.js'\nimport { buildGenericResolved, GENERIC_OPERATION_ID } from '../../shapes/generic.js'\n\ninterface GrantDetail {\n id: string\n type: string\n status: string\n requester: string\n owner: string\n request: {\n command?: string[]\n audience?: string\n grant_type?: string\n target_host?: string\n execution_context?: { adapter_digest?: string, argv_hash?: string }\n authorization_details?: Array<{ type?: string, permission?: string, operation_id?: string, cli_id?: string }>\n }\n}\n\nexport const runGrantCommand = defineCommand({\n meta: {\n name: 'run',\n description: 'Execute a previously-approved grant by ID',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n 'escapes-path': {\n type: 'string',\n description: 'Path to escapes binary (audience=escapes only)',\n default: 'escapes',\n },\n wait: {\n type: 'boolean',\n description: 'If the grant is pending, block and poll until approved (or denied/revoked/used/timeout). Reuses APES_GRANT_POLL_INTERVAL / APES_GRANT_POLL_MAX_MINUTES knobs.',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp)\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n\n const grantsUrl = await getGrantsEndpoint(idp)\n let grant = await apiFetch<GrantDetail>(`${grantsUrl}/${args.id}`)\n\n // --- status gate ---\n // Pending status has two paths: default error, or --wait poll loop.\n // The CLI-side poll is the \"ape-shell -c \\\"apes grants run <id> --wait\\\"\"\n // pattern that agents use: one tool call, the CLI handles the wait,\n // and the agent only sees the final state. See `commands/run.ts`\n // `printPendingGrantInfo` agent-mode text for the usage contract.\n if (grant.status === 'pending') {\n if (!args.wait) {\n throw new CliError(\n `Grant ${grant.id} is still pending. Approve at: ${idp}/grant-approval?grant_id=${grant.id}`,\n )\n }\n const maxMinutes = getPollMaxMinutes()\n consola.info(`Waiting for grant ${grant.id} approval (up to ${maxMinutes} minute${maxMinutes === 1 ? '' : 's'})...`)\n const outcome = await pollGrantUntilResolved(idp, grant.id)\n if (outcome.kind === 'timeout') {\n throw new CliError(\n `Grant ${grant.id} approval timed out after ${maxMinutes} minute${maxMinutes === 1 ? '' : 's'}. `\n + `Re-run after approval, or extend the timeout via APES_GRANT_POLL_MAX_MINUTES.`,\n )\n }\n if (outcome.kind === 'terminal') {\n throw new CliError(\n `Grant ${grant.id} resolved to ${outcome.status}. Request a new one.`,\n )\n }\n // outcome.kind === 'approved' — re-fetch the grant so we have the\n // up-to-date shape (approver, decided_at, etc.) for downstream code.\n grant = await apiFetch<GrantDetail>(`${grantsUrl}/${args.id}`)\n consola.info(`Grant ${grant.id} approved — continuing`)\n }\n\n if (grant.status === 'denied' || grant.status === 'revoked')\n throw new CliError(`Grant ${grant.id} is ${grant.status}. Request a new one.`)\n if (grant.status === 'used')\n throw new CliError(`Grant ${grant.id} has already been used. Request a new one (single-use grants cannot be re-executed).`)\n if (grant.status !== 'approved')\n throw new CliError(`Grant ${grant.id} has unexpected status: ${grant.status}`)\n\n // --- dispatch by grant shape ---\n const audience = grant.request?.audience\n const authDetails = grant.request?.authorization_details ?? []\n const hasOpenApeCliDetail = authDetails.some(d => d?.type === 'openape_cli')\n const isShapesGrant = hasOpenApeCliDetail || audience === 'shapes'\n\n if (isShapesGrant) {\n // Generic-fallback grants have no adapter to re-resolve against —\n // their command is self-describing (argv + cli_id). Rebuild the\n // ResolvedCommand in memory via buildGenericResolved instead of\n // calling resolveFromGrant (which would try to loadOrInstallAdapter\n // and fail with \"No shapes adapter found\").\n const isGenericGrant = authDetails.some(d => d?.operation_id === GENERIC_OPERATION_ID)\n let resolved\n if (isGenericGrant) {\n const argv = grant.request?.command ?? []\n if (argv.length === 0)\n throw new CliError(`Generic grant ${grant.id} is missing command argv`)\n const cliId = authDetails.find(d => d?.operation_id === GENERIC_OPERATION_ID)?.cli_id ?? argv[0]!\n resolved = await buildGenericResolved(cliId, argv)\n }\n else {\n try {\n resolved = await resolveFromGrant(grant)\n }\n catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n throw new CliError(`Cannot re-resolve grant: ${msg}`)\n }\n }\n const token = await fetchGrantToken(idp, grant.id)\n await verifyAndExecute(token, resolved, grant.id)\n return\n }\n\n if (audience === 'escapes') {\n const { authz_jwt } = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${grant.id}/token`, { method: 'POST' })\n const command = grant.request?.command ?? []\n if (command.length === 0)\n throw new CliError(`Grant ${grant.id} has no command to execute.`)\n consola.info(`Executing via escapes: ${command.join(' ')}`)\n try {\n execFileSync(args['escapes-path'] as string, ['--grant', authz_jwt, '--', ...command], { stdio: 'inherit' })\n }\n catch (err: unknown) {\n const exitCode = (err as { status?: number }).status || 1\n throw new CliExit(exitCode)\n }\n return\n }\n\n if (audience === 'ape-shell') {\n // Legacy shell-session grants can't be re-executed standalone — they\n // were created for a specific bash -c line that only made sense inside\n // the original apes run --shell invocation.\n throw new CliError(\n `Grant ${grant.id} is an ape-shell session grant and cannot be re-executed via \\`apes grants run\\`. `\n + `Re-run the original command — if the grant was approved as timed/always, the REPL will reuse it automatically.`,\n )\n }\n\n throw new CliError(`Grant ${grant.id} has unsupported audience \"${audience}\" — no execution path available.`)\n },\n})\n","import { loadConfig } from './config.js'\nimport { apiFetch, getGrantsEndpoint } from './http.js'\n\n/**\n * Shared poll-config helpers used by both the one-shot grant-creation\n * wait loops in `commands/run.ts` and the CLI-side wait loop in\n * `commands/grants/run.ts --wait`.\n *\n * Source-of-truth for the default poll interval (10 s) and max-wait\n * duration (5 min). Env var wins over config.toml wins over baked-in\n * default; bogus values fall back gracefully.\n */\n\n/** Poll interval (seconds). Default 10. */\nexport function getPollIntervalSeconds(): number {\n const envValue = process.env.APES_GRANT_POLL_INTERVAL\n if (envValue) {\n const n = Number(envValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n const cfg = loadConfig()\n const cfgValue = cfg.defaults?.grant_poll_interval_seconds\n if (cfgValue) {\n const n = Number(cfgValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n return 10\n}\n\n/** Maximum poll duration (minutes). Default 5. */\nexport function getPollMaxMinutes(): number {\n const envValue = process.env.APES_GRANT_POLL_MAX_MINUTES\n if (envValue) {\n const n = Number(envValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n const cfg = loadConfig()\n const cfgValue = cfg.defaults?.grant_poll_max_minutes\n if (cfgValue) {\n const n = Number(cfgValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n return 5\n}\n\n/** Outcome of a grant polling loop. */\nexport type PollOutcome =\n | { kind: 'approved' }\n | { kind: 'terminal', status: 'denied' | 'revoked' | 'used' }\n | { kind: 'timeout' }\n\n/**\n * Poll a specific grant's status via `GET /grants/<id>` until it reaches\n * a terminal state or the max-wait budget is exhausted. Uses the shared\n * `getPollIntervalSeconds` / `getPollMaxMinutes` knobs so users get\n * consistent behavior across both the grant-creation wait loops and the\n * CLI-side `grants run --wait` loop.\n *\n * The caller is responsible for handling the outcome — this helper only\n * polls the status endpoint, it does not dispatch or execute the grant.\n * See `commands/grants/run.ts --wait` for the dispatch path.\n */\nexport async function pollGrantUntilResolved(\n idp: string,\n grantId: string,\n): Promise<PollOutcome> {\n const grantsEndpoint = await getGrantsEndpoint(idp)\n const intervalSec = getPollIntervalSeconds()\n const maxMinutes = getPollMaxMinutes()\n const maxMs = maxMinutes * 60_000\n const intervalMs = intervalSec * 1000\n const start = Date.now()\n\n while (Date.now() - start < maxMs) {\n const grant = await apiFetch<{ status: string }>(`${grantsEndpoint}/${grantId}`)\n if (grant.status === 'approved')\n return { kind: 'approved' }\n if (grant.status === 'denied' || grant.status === 'revoked' || grant.status === 'used')\n return { kind: 'terminal', status: grant.status }\n await new Promise(r => setTimeout(r, intervalMs))\n }\n\n return { kind: 'timeout' }\n}\n","import { defineCommand } from 'citty'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const tokenCommand = defineCommand({\n meta: {\n name: 'token',\n description: 'Get grant token JWT',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n const result = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${args.id}/token`, {\n method: 'POST',\n })\n\n if (!result.authz_jwt) {\n throw new CliError('No token received. Grant may not be approved.')\n }\n\n // Output raw token to stdout (pipeable)\n process.stdout.write(result.authz_jwt)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getDelegationsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const delegateCommand = defineCommand({\n meta: {\n name: 'delegate',\n description: 'Create a delegation',\n },\n args: {\n to: {\n type: 'string',\n description: 'Delegate email (who can act on your behalf)',\n required: true,\n },\n at: {\n type: 'string',\n description: 'Service/audience where delegation applies',\n required: true,\n },\n scopes: {\n type: 'string',\n description: 'Comma-separated scopes',\n },\n approval: {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n expires: {\n type: 'string',\n description: 'Expiration date (ISO 8601)',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()!\n const delegationsUrl = await getDelegationsEndpoint(idp)\n\n // Server expects `grant_type`, not `approval`. The CLI flag stays\n // named `--approval` for UX continuity (matches the term humans\n // see in the IdP grant-approval UI), but the request body must\n // carry the wire name. Without this rename the server always\n // defaults to grant_type='once' regardless of the flag value.\n const body: Record<string, unknown> = {\n delegate: args.to,\n audience: args.at,\n grant_type: args.approval,\n }\n\n if (args.scopes) {\n body.scopes = args.scopes.split(',').map(s => s.trim())\n }\n\n if (args.expires) {\n // The IdP's /api/delegations endpoint validates timed grants with a\n // `duration` field (seconds), not an ISO `expires_at`. Convert here\n // so users can keep using a human-friendly --expires timestamp.\n if (args.approval === 'timed') {\n const expiresMs = Date.parse(args.expires)\n if (Number.isNaN(expiresMs)) {\n throw new CliError(`Invalid --expires value: \"${args.expires}\" is not an ISO 8601 timestamp.`)\n }\n const durationSec = Math.floor((expiresMs - Date.now()) / 1000)\n if (durationSec <= 0) {\n throw new CliError(`Invalid --expires value: \"${args.expires}\" is in the past.`)\n }\n body.duration = durationSec\n }\n else {\n body.expires_at = args.expires\n }\n }\n\n const result = await apiFetch<{ id: string }>(delegationsUrl, {\n method: 'POST',\n body,\n })\n\n consola.success(`Delegation created: ${result.id}`)\n console.log(` Delegate: ${args.to}`)\n console.log(` Audience: ${args.at}`)\n if (args.scopes)\n console.log(` Scopes: ${args.scopes}`)\n console.log(` Approval: ${args.approval}`)\n if (args.expires)\n console.log(` Expires: ${args.expires}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getDelegationsEndpoint } from '../../http'\n\ninterface Delegation {\n id: string\n delegator: string\n delegate: string\n audience: string\n scopes?: string[]\n approval: string\n created_at?: string\n expires_at?: string\n}\n\ninterface PaginatedDelegations {\n data: Delegation[]\n pagination: { cursor: string | null, has_more: boolean }\n}\n\nexport const delegationsCommand = defineCommand({\n meta: {\n name: 'delegations',\n description: 'List delegations',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const delegationsUrl = await getDelegationsEndpoint(idp)\n const response = await apiFetch<PaginatedDelegations>(delegationsUrl)\n\n // Support both paginated and legacy plain-array responses\n const delegations = Array.isArray(response) ? response : response.data\n\n if (args.json) {\n console.log(JSON.stringify(delegations, null, 2))\n return\n }\n\n if (delegations.length === 0) {\n consola.info('No delegations found.')\n return\n }\n\n for (const d of delegations) {\n const scopes = d.scopes?.join(', ') || '(all)'\n const expires = d.expires_at ? ` expires ${d.expires_at}` : ''\n console.log(`${d.id} ${d.delegator} → ${d.delegate} at ${d.audience} [${scopes}]${expires}`)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getDelegationsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const delegationRevokeCommand = defineCommand({\n meta: {\n name: 'delegation-revoke',\n description: 'Revoke a delegation',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Delegation ID to revoke',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const delegationsUrl = await getDelegationsEndpoint(idp)\n const id = String(args.id)\n\n const result = await apiFetch<{ id: string, status: string }>(\n `${delegationsUrl}/${id}`,\n { method: 'DELETE' },\n )\n\n consola.success(`Delegation ${result.id} revoked.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { usersListCommand, usersCreateCommand, usersDeleteCommand } from './users'\nimport { sshKeysListCommand, sshKeysAddCommand, sshKeysDeleteCommand } from './ssh-keys'\n\nconst usersCommand = defineCommand({\n meta: {\n name: 'users',\n description: 'Manage users',\n },\n subCommands: {\n list: usersListCommand,\n create: usersCreateCommand,\n delete: usersDeleteCommand,\n },\n})\n\nconst sshKeysCommand = defineCommand({\n meta: {\n name: 'ssh-keys',\n description: 'Manage SSH keys',\n },\n subCommands: {\n list: sshKeysListCommand,\n add: sshKeysAddCommand,\n delete: sshKeysDeleteCommand,\n },\n})\n\nexport const adminCommand = defineCommand({\n meta: {\n name: 'admin',\n description: 'Admin commands (requires APES_MANAGEMENT_TOKEN)',\n },\n subCommands: {\n users: usersCommand,\n 'ssh-keys': sshKeysCommand,\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface AdminUser {\n email: string\n name: string\n isActive: boolean\n owner?: string\n createdAt: number\n}\n\nfunction getManagementToken(): string {\n const token = process.env.APES_MANAGEMENT_TOKEN\n if (!token) {\n throw new CliError('Management token required. Set APES_MANAGEMENT_TOKEN environment variable.')\n }\n return token\n}\n\ninterface UserListResponse {\n data: AdminUser[]\n pagination: {\n cursor: string | null\n has_more: boolean\n }\n}\n\nexport const usersListCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List all users',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n limit: {\n type: 'string',\n description: 'Max number of users to return (1-100, default 50)',\n },\n cursor: {\n type: 'string',\n description: 'Pagination cursor (email of last item from previous page)',\n },\n search: {\n type: 'string',\n description: 'Filter by email or name (case-insensitive)',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const params = new URLSearchParams()\n if (args.limit) params.set('limit', args.limit)\n if (args.cursor) params.set('cursor', args.cursor)\n if (args.search) params.set('search', args.search)\n const qs = params.toString()\n const url = qs ? `${idp}/api/admin/users?${qs}` : `${idp}/api/admin/users`\n\n const result = await apiFetch<UserListResponse>(url, { token })\n\n if (args.json) {\n console.log(JSON.stringify(result, null, 2))\n return\n }\n\n if (result.data.length === 0) {\n consola.info('No users found.')\n return\n }\n\n for (const u of result.data) {\n const owner = u.owner ? ` (agent of ${u.owner})` : ''\n const active = u.isActive ? '' : ' [inactive]'\n console.log(`${u.email} ${u.name}${owner}${active}`)\n }\n\n if (result.pagination.has_more) {\n consola.info(`More results available. Use --cursor=\"${result.pagination.cursor}\" to see next page.`)\n }\n },\n})\n\nexport const usersCreateCommand = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a user',\n },\n args: {\n email: {\n type: 'string',\n description: 'User email',\n required: true,\n },\n name: {\n type: 'string',\n description: 'User name',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n\n const result = await apiFetch<{ ok: boolean, email: string, name: string }>(\n `${idp}/api/admin/users`,\n {\n method: 'POST',\n body: { email: args.email, name: args.name },\n token,\n },\n )\n\n consola.success(`User created: ${result.email} (${result.name})`)\n },\n})\n\nexport const usersDeleteCommand = defineCommand({\n meta: {\n name: 'delete',\n description: 'Delete a user',\n },\n args: {\n email: {\n type: 'positional',\n description: 'User email',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const email = String(args.email)\n\n await apiFetch(`${idp}/api/admin/users/${encodeURIComponent(email)}`, {\n method: 'DELETE',\n token,\n })\n\n consola.success(`User deleted: ${email}`)\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { homedir } from 'node:os'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface SshKey {\n keyId: string\n userEmail: string\n publicKey: string\n name: string\n createdAt: number\n}\n\nfunction getManagementToken(): string {\n const token = process.env.APES_MANAGEMENT_TOKEN\n if (!token) {\n throw new CliError('Management token required. Set APES_MANAGEMENT_TOKEN environment variable.')\n }\n return token\n}\n\nexport const sshKeysListCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List SSH keys for a user',\n },\n args: {\n email: {\n type: 'positional',\n description: 'User email',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const email = String(args.email)\n const keys = await apiFetch<SshKey[]>(\n `${idp}/api/admin/users/${encodeURIComponent(email)}/ssh-keys`,\n { token },\n )\n\n if (args.json) {\n console.log(JSON.stringify(keys, null, 2))\n return\n }\n\n if (keys.length === 0) {\n consola.info(`No SSH keys found for ${email}.`)\n return\n }\n\n for (const k of keys) {\n console.log(`${k.keyId} ${k.name} ${k.publicKey.substring(0, 40)}...`)\n }\n },\n})\n\nexport const sshKeysAddCommand = defineCommand({\n meta: {\n name: 'add',\n description: 'Add an SSH key for a user',\n },\n args: {\n email: {\n type: 'string',\n description: 'User email',\n required: true,\n },\n key: {\n type: 'string',\n description: 'Path to public key file or key string',\n required: true,\n },\n name: {\n type: 'string',\n description: 'Key name/label',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n\n // Read key from file if path exists, otherwise treat as key string\n let publicKey = args.key\n const resolved = resolve(args.key.replace(/^~/, homedir()))\n if (existsSync(resolved)) {\n publicKey = readFileSync(resolved, 'utf-8').trim()\n }\n\n const body: Record<string, string> = { publicKey }\n if (args.name) {\n body.name = args.name\n }\n\n const result = await apiFetch<SshKey>(\n `${idp}/api/admin/users/${encodeURIComponent(args.email)}/ssh-keys`,\n {\n method: 'POST',\n body,\n token,\n },\n )\n\n consola.success(`SSH key added: ${result.keyId} (${result.name})`)\n },\n})\n\nexport const sshKeysDeleteCommand = defineCommand({\n meta: {\n name: 'delete',\n description: 'Delete an SSH key',\n },\n args: {\n email: {\n type: 'string',\n description: 'User email',\n required: true,\n },\n keyId: {\n type: 'positional',\n description: 'Key ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const keyId = String(args.keyId)\n\n await apiFetch(\n `${idp}/api/admin/users/${encodeURIComponent(args.email)}/ssh-keys/${keyId}`,\n {\n method: 'DELETE',\n token,\n },\n )\n\n consola.success(`SSH key deleted: ${keyId}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { deployAgentCommand } from './deploy'\n\n// `apes agent …` (singular) — owner-side recipe operations, distinct\n// from `apes agents …` (plural) which manages the owner's own agent\n// lifecycle on a host.\nexport const agentCommand = defineCommand({\n meta: {\n name: 'agent',\n description: 'Agent Recipe operations (deploy)',\n },\n subCommands: {\n deploy: deployAgentCommand,\n },\n})\n","import { ensureFreshIdpAuth } from '@openape/cli-auth'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { resolveTroopUrl } from '../../lib/troop-client'\n\n// `apes agent deploy <repo>@<ref> [--param k=v] [--secret ENV=val]`\n// — one-step Agent Recipe deploy. Calls troop's recipe-deploy endpoint\n// (M3), then binds the declared capability secrets (M2c). The owner's\n// IdP token (apes login) authenticates; troop enforces requireOwner.\n// See plans.openape.ai 01KRTAE8 (M4).\n\n/** Parse repeatable `KEY=value` flags into a record. Last wins. */\nexport function parseKeyValues(pairs: string[]): Record<string, string> {\n const out: Record<string, string> = {}\n for (const p of pairs) {\n const eq = p.indexOf('=')\n if (eq <= 0) throw new CliError(`bad key=value pair: \"${p}\" (expected KEY=value)`)\n out[p.slice(0, eq)] = p.slice(eq + 1)\n }\n return out\n}\n\n/** Capability envs the recipe needs that the caller hasn't supplied. */\nexport function missingCapabilities(required: string[], provided: Record<string, string>): string[] {\n return required.filter(env => !(env in provided))\n}\n\n// citty 0.2.2 coerces a repeated `type:'string'` flag to its LAST value\n// only (`--param a=1 --param b=2` → \"b=2\"), silently dropping earlier\n// occurrences. Collect every occurrence straight from the raw argv so\n// multiple --param / --secret flags all survive. Handles both\n// `--flag value` and `--flag=value` forms.\nexport function collectFlag(rawArgs: string[], name: string): string[] {\n const out: string[] = []\n const long = `--${name}`\n for (let i = 0; i < rawArgs.length; i++) {\n const a = rawArgs[i]!\n if (a === long) {\n const v = rawArgs[i + 1]\n if (v !== undefined && !v.startsWith('--')) {\n out.push(v)\n i++\n }\n }\n else if (a.startsWith(`${long}=`)) {\n out.push(a.slice(long.length + 1))\n }\n }\n return out\n}\n\ninterface DeployResponse {\n intent_id: string\n agent_name: string\n ref: string\n required_capabilities: string[]\n schedules: Array<{ task_id: string, cron: string, name: string }>\n}\n\nasync function api<T>(url: string, token: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', ...init?.headers },\n })\n if (!res.ok) {\n const body = await res.text().catch(() => '')\n throw new CliError(`${init?.method ?? 'GET'} ${url} → HTTP ${res.status}${body ? `: ${body.slice(0, 300)}` : ''}`)\n }\n return res.json() as Promise<T>\n}\n\nconst sleep = (ms: number) => new Promise<void>(r => setTimeout(r, ms))\n\nexport const deployAgentCommand = defineCommand({\n meta: { name: 'deploy', description: 'Deploy an Agent Recipe (<repo>@<ref>) in one step' },\n args: {\n repo: { type: 'positional', description: 'Recipe repo + pinned ref, e.g. github.com/owner/name@v1.0.0' },\n param: { type: 'string', description: 'Recipe param, KEY=value (repeatable)' },\n secret: { type: 'string', description: 'Capability secret, ENV=value (repeatable; else prompted)' },\n 'host-id': { type: 'string', description: 'Target nest host_id (default: first connected)' },\n json: { type: 'boolean', description: 'Machine-readable output, no prompts' },\n },\n async run({ args, rawArgs }) {\n const repoRef = args.repo as string\n if (!repoRef) throw new CliError('usage: apes agent deploy <repo>@<ref> [--param k=v] [--secret ENV=val]')\n const params = parseKeyValues(collectFlag(rawArgs, 'param'))\n const secrets = parseKeyValues(collectFlag(rawArgs, 'secret'))\n const json = !!args.json\n\n const token = (await ensureFreshIdpAuth()).access_token\n const troop = resolveTroopUrl()\n\n const deploy = await api<DeployResponse>(`${troop}/api/agents/recipe-deploy`, token, {\n method: 'POST',\n body: JSON.stringify({\n repo_ref: repoRef,\n params,\n ...(args['host-id'] ? { host_id: args['host-id'] as string } : {}),\n }),\n })\n\n if (!json) {\n consola.success(`Deploying ${deploy.agent_name} from ${repoRef} (ref ${deploy.ref})`)\n consola.info(`Schedules: ${deploy.schedules.map(s => `${s.task_id}=${s.cron}`).join(', ') || 'none'}`)\n }\n\n // Collect capability values: --secret flags first, then prompt for\n // the rest (unless --json, where missing is a hard error).\n const missing = missingCapabilities(deploy.required_capabilities, secrets)\n if (missing.length > 0) {\n if (json) {\n throw new CliError(`missing required capability secrets: ${missing.join(', ')} (pass via --secret in --json mode)`)\n }\n for (const env of missing) {\n const val = await consola.prompt(`Secret value for ${env}:`, { type: 'text' })\n if (typeof val !== 'string' || val.length === 0) throw new CliError(`no value provided for ${env} — aborting`)\n secrets[env] = val\n }\n }\n\n // Wait for the agent to come online (spawn-result), then bind the\n // sealed secrets. Binding 409s until the agent's first sync reports\n // its X25519 pubkey, so we retry with backoff. We bind whenever there\n // are secrets to seal — including optional capabilities the caller\n // supplied via --secret, which never appear in required_capabilities.\n if (Object.keys(secrets).length > 0) {\n if (!json) consola.start('Waiting for the agent to come online…')\n let online = false\n for (let i = 0; i < 90 && !online; i++) {\n const st = await api<{ pending: boolean, ok?: boolean, error?: string }>(\n `${troop}/api/agents/spawn-intent/${deploy.intent_id}`, token,\n )\n if (!st.pending) {\n if (!st.ok) throw new CliError(`spawn failed: ${st.error ?? 'unknown error'}`)\n online = true\n break\n }\n await sleep(2000)\n }\n if (!online) throw new CliError('timed out waiting for the agent to spawn — bind secrets later with `apes agent secret`')\n\n for (const [env, value] of Object.entries(secrets)) {\n let bound = false\n for (let i = 0; i < 60 && !bound; i++) {\n try {\n await api(`${troop}/api/agents/${deploy.agent_name}/secrets/${env}`, token, {\n method: 'PUT',\n body: JSON.stringify({ value }),\n })\n bound = true\n }\n catch (e) {\n // 404 (agent row not synced yet) / 409 (no pubkey yet) → retry.\n if (i === 59) throw e\n await sleep(3000)\n }\n }\n if (!json) consola.success(`Bound ${env}`)\n }\n }\n\n if (json) {\n consola.log(JSON.stringify({\n ok: true,\n agent_name: deploy.agent_name,\n ref: deploy.ref,\n intent_id: deploy.intent_id,\n schedules: deploy.schedules,\n bound: Object.keys(secrets),\n }))\n }\n else {\n consola.success(`${deploy.agent_name} deployed. Schedules are live; secrets sealed to the agent.`)\n }\n },\n})\n","// Typed thin client for troop.openape.ai's agent-side API. The CLI\n// never talks to the owner-side endpoints (those are for the web UI);\n// the troop-client only knows about the three /me/* endpoints needed\n// by `apes agents sync` and `apes agents run`.\n//\n// Default endpoint is https://troop.openape.ai. Override with the\n// OPENAPE_TROOP_URL env var (handy for staging or local dev). The\n// agent JWT comes from `~/.config/apes/auth.json` — the file\n// `apes agents spawn` writes when it provisions the macOS user.\n\nexport const DEFAULT_TROOP_URL = 'https://troop.openape.ai'\n\nexport interface TaskSpec {\n agentEmail: string\n taskId: string\n name: string\n cron: string\n /**\n * Imperative job description — sent as the LLM `user` message at run\n * time. The agent's persona / behaviour rules are in `agent.systemPrompt`\n * and served separately at sync time (see `AgentTasksResponse`).\n */\n userPrompt: string\n /**\n * Optional deterministic shell command. When present, the cron-runner\n * executes it via the gated ape-shell path (no LLM turn, no chat room)\n * and `userPrompt` is just the human-readable fallback. Carried through\n * `apes agents sync` into the per-task cache the cron-runner reads.\n */\n command?: string | null\n tools: string[]\n maxSteps: number\n enabled: boolean\n createdAt: number\n updatedAt: number\n}\n\nexport interface SkillSpec {\n /** Slug — becomes the directory name on disk (`skills/<name>/SKILL.md`). */\n name: string\n /** One-line summary the LLM sees in the system prompt's available_skills block. */\n description: string\n /** Full SKILL.md content the agent runtime writes to disk after sync. */\n body: string\n}\n\n/** Response from /api/agents/me/tasks — agent config + task list. */\nexport interface AgentTasksResponse {\n /**\n * Agent-level persona/behaviour rules — used as `system` for both\n * cron task runs and live chat-bridge messages. Empty string when the\n * owner hasn't set one.\n */\n system_prompt: string\n /**\n * Tool whitelist for chat-bridge runtime. Cron tasks have their own\n * per-task `tools[]` (see TaskSpec); this is the list the bridge\n * exposes to the LLM during live chat-thread turns. Empty array =\n * no tools (pure chat). Defaults to \"all known tools\" on first\n * sync — owner narrows via troop UI.\n */\n tools: string[]\n /**\n * Lazy-load skill catalog — only enabled rows from agent_skills.\n * Each one lands at `~/.openape/agent/skills/<name>/SKILL.md`.\n */\n skills: SkillSpec[]\n tasks: TaskSpec[]\n}\n\nexport interface SyncResponse {\n agent_email: string\n host_id: string\n first_sync: boolean\n last_seen_at: number\n}\n\nexport interface RunStartResponse {\n id: string\n started_at: number\n}\n\nexport interface RunFinalisePayload {\n status: 'ok' | 'error'\n final_message: string | null\n step_count: number\n trace?: unknown\n}\n\nexport class TroopClient {\n constructor(\n public readonly troopUrl: string,\n public readonly agentJwt: string,\n ) {}\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const res = await fetch(`${this.troopUrl}${path}`, {\n ...init,\n headers: {\n ...(init?.headers ?? {}),\n 'Authorization': `Bearer ${this.agentJwt}`,\n 'Content-Type': 'application/json',\n },\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`troop ${init?.method ?? 'GET'} ${path} failed: ${res.status} ${text}`)\n }\n if (res.status === 204) return undefined as T\n return await res.json() as T\n }\n\n sync(input: { hostname: string, hostId: string, ownerEmail: string, pubkeySsh?: string, pubkeyX25519?: string }): Promise<SyncResponse> {\n return this.request('/api/agents/me/sync', {\n method: 'POST',\n body: JSON.stringify({\n hostname: input.hostname,\n host_id: input.hostId,\n owner_email: input.ownerEmail,\n ...(input.pubkeySsh ? { pubkey_ssh: input.pubkeySsh } : {}),\n // Without this the agent's encryption pubkey never reaches troop,\n // so every sealed-capability bind 409s (\"no X25519 public key\n // yet\"). The keypair is written at spawn (agent-bootstrap); we\n // just have to report the public half here.\n ...(input.pubkeyX25519 ? { pubkey_x25519: input.pubkeyX25519 } : {}),\n }),\n })\n }\n\n listTasks(): Promise<AgentTasksResponse> {\n return this.request('/api/agents/me/tasks')\n }\n\n startRun(taskId: string): Promise<RunStartResponse> {\n return this.request('/api/agents/me/runs', {\n method: 'POST',\n body: JSON.stringify({ task_id: taskId }),\n })\n }\n\n finaliseRun(id: string, payload: RunFinalisePayload): Promise<unknown> {\n return this.request(`/api/agents/me/runs/${id}`, {\n method: 'PATCH',\n body: JSON.stringify(payload),\n })\n }\n}\n\nexport function resolveTroopUrl(override?: string): string {\n if (override) return override.replace(/\\/$/, '')\n const fromEnv = process.env.OPENAPE_TROOP_URL\n if (fromEnv) return fromEnv.replace(/\\/$/, '')\n return DEFAULT_TROOP_URL\n}\n","import { defineCommand } from 'citty'\nimport { allowAgentCommand } from './allow'\nimport { cleanupOrphansCommand } from './cleanup-orphans'\nimport { codeAgentCommand } from './code'\nimport { destroyAgentCommand } from './destroy'\nimport { listAgentsCommand } from './list'\nimport { registerAgentCommand } from './register'\nimport { runAgentCommand } from './run'\nimport { serveAgentCommand } from './serve'\nimport { spawnAgentCommand } from './spawn'\nimport { syncAgentCommand } from './sync'\n\nexport const agentsCommand = defineCommand({\n meta: {\n name: 'agents',\n description: 'Manage owned agents (register, spawn, list, destroy, allow, sync, run, serve, code, cleanup-orphans)',\n },\n subCommands: {\n register: registerAgentCommand,\n spawn: spawnAgentCommand,\n list: listAgentsCommand,\n destroy: destroyAgentCommand,\n allow: allowAgentCommand,\n sync: syncAgentCommand,\n run: runAgentCommand,\n serve: serveAgentCommand,\n code: codeAgentCommand,\n 'cleanup-orphans': cleanupOrphansCommand,\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { AGENT_NAME_REGEX } from '../../lib/agent-bootstrap'\nimport { isDarwin, lookupMacOSUserForAgent, whichBinary } from '../../lib/macos-user'\n\nexport const allowAgentCommand = defineCommand({\n meta: {\n name: 'allow',\n description:\n 'Add a peer to the agent\\'s contact-allowlist so the bridge auto-accepts that peer\\'s contact request.',\n },\n args: {\n agent: {\n type: 'positional',\n required: true,\n description: 'Agent name (the macOS short username spawn created)',\n },\n email: {\n type: 'positional',\n required: true,\n description: 'Peer email to allow (the address that will send the contact request)',\n },\n },\n async run({ args }) {\n const agent = args.agent as string\n const email = (args.email as string).trim().toLowerCase()\n if (!AGENT_NAME_REGEX.test(agent)) {\n throw new CliError(`Invalid agent name \"${agent}\".`)\n }\n if (!email.includes('@')) {\n throw new CliError(`Invalid email \"${email}\".`)\n }\n if (!isDarwin()) {\n throw new CliError('`apes agents allow` is currently macOS-only.')\n }\n if (!lookupMacOSUserForAgent(agent)) {\n throw new CliError(`No macOS user for agent \"${agent}\" — has it been spawned?`)\n }\n const apes = whichBinary('apes')\n if (!apes) throw new CliError('`apes` not found on PATH.')\n\n // Update the allowlist file inside the agent's home. python3 is\n // always present on macOS — avoids a jq dep. Idempotent: re-running\n // for the same email is a no-op.\n const script = `set -eu\nmkdir -p \"$HOME/.config/openape\"\nF=\"$HOME/.config/openape/bridge-allowlist.json\"\nEMAIL=${shQuote(email)}\npython3 - \"$F\" \"$EMAIL\" <<'PY'\nimport json, os, sys\npath, email = sys.argv[1], sys.argv[2].lower()\ndata = {\"emails\": []}\nif os.path.exists(path):\n try:\n with open(path) as f:\n data = json.load(f)\n if not isinstance(data, dict) or not isinstance(data.get(\"emails\"), list):\n data = {\"emails\": []}\n except Exception:\n data = {\"emails\": []}\nemails = {e.lower() for e in data[\"emails\"] if isinstance(e, str)}\nemails.add(email)\ndata[\"emails\"] = sorted(emails)\nwith open(path, \"w\") as f:\n json.dump(data, f, indent=2)\n f.write(\"\\\\n\")\nprint(\"ok\")\nPY\nchmod 600 \"$F\"\n`\n\n consola.start(`Adding ${email} to ${agent}'s allowlist…`)\n execFileSync(apes, ['run', '--as', agent, '--wait', '--', 'bash', '-c', script], { stdio: 'inherit' })\n consola.success(`${agent} will auto-accept future contact requests from ${email} (within ~30s of next bridge connect).`)\n },\n})\n\nfunction shQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`\n}\n","import { Buffer } from 'node:buffer'\nimport { execFileSync } from 'node:child_process'\nimport { createPrivateKey, sign } from 'node:crypto'\nimport { rmSync } from 'node:fs'\nimport { exchangeWithDelegation } from '@openape/cli-auth'\nimport { loadAuth } from '../config'\nimport { apiFetch, getAgentAuthenticateEndpoint, getAgentChallengeEndpoint } from '../http'\n\nexport const AGENT_NAME_REGEX = /^[a-z][a-z0-9-]{0,23}$/\nexport const SSH_ED25519_PREFIX = 'ssh-ed25519 '\nexport const SSH_ED25519_REGEX = /^ssh-ed25519 [A-Za-z0-9+/=]+(\\s.*)?$/\n\nconst ENROLL_AUDIENCE = 'enroll-agent'\n\nexport interface RegisterAgentResponse {\n email: string\n name: string\n owner: string\n approver: string\n status: string\n}\n\n/**\n * Enrol an agent at the IdP. When the local caller is itself an\n * agent (e.g. the local Nest enrolling a child agent), we look for\n * a delegation grant from the agent's owner authorising us to act\n * for them, and exchange both tokens for a delegated access token\n * (RFC 8693). The /api/enroll endpoint then sees `sub=owner` and\n * `act={sub:caller}` and attributes ownership correctly without\n * needing a server-side transitive-ownership heuristic.\n *\n * Falls back to the direct call (caller-as-requester) when no\n * delegation is available — the IdP's transitive-ownership lookup\n * still covers that path until M3 retires it.\n */\nexport async function registerAgentAtIdp(input: {\n name: string\n publicKey: string\n idp?: string\n}): Promise<RegisterAgentResponse> {\n const delegated = await tryDelegatedEnrollToken(input.idp)\n return await apiFetch<RegisterAgentResponse>('/api/enroll', {\n method: 'POST',\n body: { name: input.name, publicKey: input.publicKey },\n idp: input.idp,\n ...(delegated ? { headers: { Authorization: `Bearer ${delegated}` } } : {}),\n })\n}\n\n/**\n * If the caller is an agent and the owner has previously approved a\n * delegation grant (audience `enroll-agent`), exchange the agent's\n * access token + the delegation grant id for a delegated access\n * token whose `sub` is the owner.\n *\n * Lookup strategy: list active grants where requester = owner_email,\n * find the first delegation grant where delegate = us and audience is\n * `enroll-agent` or `*`. Returns null on any failure (no delegation\n * found, network error, etc.) so the caller falls back to the\n * direct-enroll path — token-exchange is an optimisation while the\n * IdP's transitive-ownership lookup still covers the gap.\n */\nasync function tryDelegatedEnrollToken(idp?: string): Promise<string | null> {\n try {\n const auth = loadAuth()\n if (!auth?.access_token) return null\n // Only agents need delegation. Humans always enrol on their own\n // behalf (sub=owner already).\n const claims = decodeJwtClaims(auth.access_token)\n if (claims?.act !== 'agent') return null\n const ownerEmail = (auth as { owner_email?: unknown }).owner_email\n if (typeof ownerEmail !== 'string' || !ownerEmail) return null\n const myEmail = auth.email\n if (typeof myEmail !== 'string' || !myEmail) return null\n\n const idpUrl = idp ?? auth.idp\n if (!idpUrl) return null\n\n const grantId = await findEnrollDelegationGrantId(idpUrl, ownerEmail, myEmail)\n if (!grantId) {\n // Visible signal during the rollout window so we can tell when\n // a Nest is still falling back to /api/enroll's transitive-\n // ownership heuristic (and therefore why removing that\n // heuristic would break it). Stays at debug volume so it\n // doesn't pollute the spawn flow's stdout.\n console.warn(`[agent-bootstrap] no enroll-agent delegation from ${ownerEmail} to ${myEmail} — falling back to direct enroll`)\n return null\n }\n\n const result = await exchangeWithDelegation({\n idp: idpUrl,\n actorToken: auth.access_token,\n audience: ENROLL_AUDIENCE,\n delegationGrantId: grantId,\n })\n console.log(`[agent-bootstrap] using delegated token from grant ${grantId} (sub=${ownerEmail}, act=${myEmail})`)\n return result.access_token\n }\n catch (err) {\n console.warn(`[agent-bootstrap] delegated-enroll exchange failed: ${err instanceof Error ? err.message : String(err)} — falling back to direct enroll`)\n return null\n }\n}\n\ninterface GrantListEntry {\n id: string\n type?: string\n status?: string\n expires_at?: number\n request: {\n audience?: string\n delegate?: string\n delegator?: string\n grant_type?: string\n }\n}\n\nasync function findEnrollDelegationGrantId(\n idp: string,\n delegator: string,\n delegate: string,\n): Promise<string | null> {\n const url = `${idp.replace(/\\/$/, '')}/api/grants?status=approved&limit=200&requester=${encodeURIComponent(delegator)}`\n // Anonymous request: the IdP allows listing one's own approved\n // grants without auth in some configurations; if it requires auth\n // and rejects, we return null and fall back. Acceptable because\n // the delegation lookup is optional.\n const res = await apiFetch<{ data: GrantListEntry[] }>(url)\n const now = Math.floor(Date.now() / 1000)\n for (const g of res.data ?? []) {\n if (g.type !== 'delegation') continue\n if (g.status !== 'approved') continue\n if (g.request.delegate !== delegate) continue\n const aud = g.request.audience\n if (aud !== '*' && aud !== ENROLL_AUDIENCE) continue\n if (g.expires_at && g.expires_at <= now) continue\n return g.id\n }\n return null\n}\n\nfunction decodeJwtClaims(token: string): { act?: unknown } | null {\n try {\n const part = token.split('.')[1]\n if (!part) return null\n const padded = part + '='.repeat((4 - part.length % 4) % 4)\n const json = Buffer.from(padded, 'base64').toString('utf8')\n return JSON.parse(json) as { act?: unknown }\n }\n catch {\n return null\n }\n}\n\nexport interface IssuedAgentToken {\n token: string\n expiresIn: number\n}\n\n/**\n * Single-shot challenge/authenticate using a privately held PEM key.\n * Used by `spawn` after registering the agent: we already know the keypair\n * works (we just generated it), so we skip the polling loop in `enroll.ts`.\n */\nexport async function issueAgentToken(input: {\n idp: string\n agentEmail: string\n privateKeyPem: string\n}): Promise<IssuedAgentToken> {\n const privateKey = createPrivateKey(input.privateKeyPem)\n\n const challengeUrl = await getAgentChallengeEndpoint(input.idp)\n const challengeResp = await fetch(challengeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: input.agentEmail }),\n })\n if (!challengeResp.ok) {\n const text = await challengeResp.text().catch(() => '')\n throw new Error(`Challenge failed (${challengeResp.status}): ${text}`)\n }\n const { challenge } = await challengeResp.json() as { challenge: string }\n\n const signature = sign(null, Buffer.from(challenge), privateKey).toString('base64')\n\n const authenticateUrl = await getAgentAuthenticateEndpoint(input.idp)\n const authResp = await fetch(authenticateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: input.agentEmail, challenge, signature }),\n })\n if (!authResp.ok) {\n const text = await authResp.text().catch(() => '')\n throw new Error(`Authenticate failed (${authResp.status}): ${text}`)\n }\n const result = await authResp.json() as { token: string, expires_in: number }\n return { token: result.token, expiresIn: result.expires_in || 3600 }\n}\n\nexport interface SpawnSetupScriptInput {\n name: string\n /**\n * macOS username for the dscl record + chown ops. Prefixed with\n * `openape-agent-` (see MACOS_USER_PREFIX) so operators can audit\n * `dscl . -list /Users` and `apes agents cleanup-orphans` can\n * recognise OpenApe-managed accounts without UID-range heuristics.\n * Kept separate from `name` so the bare agent name stays visible\n * on user-facing surfaces (email, troop UI, bridge data dir).\n */\n macOSUsername: string\n homeDir: string\n shellPath: string\n privateKeyPem: string\n publicKeySshLine: string\n /**\n * Agent X25519 keypair (base64url DER) for sealed capability secrets.\n * The private key is written to `~/.config/openape/agent-x25519.key`\n * (0600) so the agent runtime can open secrets troop sealed to its\n * public key. The public key is written alongside (`.pub`, 0644) so\n * the agent can report it to troop on sync.\n */\n x25519PrivateKey: string\n x25519PublicKey: string\n authJson: string\n claudeSettingsJson: string | null\n hookScriptSource: string | null\n /**\n * Long-lived Claude Code OAuth token (`sk-ant-oat01-…`) obtained via\n * `claude setup-token`. When provided, gets written to a chmod 600 env\n * file under the agent's HOME and sourced from .zshenv + .profile so\n * `claude -p \"…\"` works immediately without interactive auth.\n * `null` means the agent has no Claude credential — `claude` will\n * prompt for auth on first run inside that user.\n */\n claudeOauthToken: string | null\n /**\n * If set, also installs the ape-agent runtime for this agent:\n * drops a launchd plist + start script + .env with the LLM proxy master\n * key. The runtime expects `@openape/ape-agent` to already be installed\n * globally on the host. `null` skips the bridge entirely (current default).\n */\n bridge: SpawnBridgeFiles | null\n /**\n * Troop sync launchd plist. Always set for spawn-via-troop; passed\n * as null only by tests that exercise the legacy path. Drops the\n * plist into ~/Library/LaunchAgents/ and bootstraps it.\n */\n troop: SpawnTroopFiles | null\n}\n\nexport interface SpawnBridgeFiles {\n /** Plist label, e.g. `eco.hofmann.apes.bridge.<agent>` (must be unique). */\n plistLabel: string\n /** Absolute path of the plist file (under /Library/LaunchDaemons/). */\n plistPath: string\n /** XML plist content (full file). */\n plistContent: string\n /** start.sh content (idempotent installer + exec). */\n startScript: string\n /** .env content (`LITELLM_BASE_URL` + `LITELLM_API_KEY`). */\n envFile: string\n}\n\nconst SH_HEREDOC_DELIMITER = 'APES_HEREDOC_END'\n\nfunction shHeredoc(content: string): string {\n if (content.includes(SH_HEREDOC_DELIMITER)) {\n throw new Error(`Refusing to emit heredoc: content contains ${SH_HEREDOC_DELIMITER}`)\n }\n return `<< '${SH_HEREDOC_DELIMITER}'\\n${content}\\n${SH_HEREDOC_DELIMITER}`\n}\n\nexport function buildSpawnSetupScript(input: SpawnSetupScriptInput): string {\n const { name, macOSUsername, homeDir, shellPath } = input\n\n // Trailing newline on PEM keeps OpenSSL happy. JSON files we write as-is.\n const privatePemForHeredoc = input.privateKeyPem.endsWith('\\n')\n ? input.privateKeyPem\n : `${input.privateKeyPem}\\n`\n\n const claudeBlock = input.claudeSettingsJson && input.hookScriptSource\n ? `\nmkdir -p \"$HOME_DIR/.claude/hooks\"\ncat > \"$HOME_DIR/.claude/settings.json\" ${shHeredoc(input.claudeSettingsJson)}\ncat > \"$HOME_DIR/.claude/hooks/bash-via-ape-shell.sh\" ${shHeredoc(input.hookScriptSource)}\nchmod 755 \"$HOME_DIR/.claude/hooks/bash-via-ape-shell.sh\"\n`\n : ''\n\n // Claude Code OAuth token: write to a chmod 600 env file under\n // ~/.config/openape/, source it from both .zshenv (zsh always loads,\n // including non-interactive) and .profile (bash login shells, what\n // `escapes` ends up exec'ing through). Keeping the actual token in\n // one place means rotation = edit one file, no shell-rc grep needed.\n const claudeTokenBlock = input.claudeOauthToken\n ? `\nmkdir -p \"$HOME_DIR/.config/openape\"\ncat > \"$HOME_DIR/.config/openape/claude-token.env\" ${shHeredoc(`# Auto-generated by 'apes agents spawn'. chmod 600 — contains a long-lived\\n# Claude Code OAuth token. Rotate by editing this file in place; the\\n# .zshenv / .profile source-lines below will pick it up automatically.\\nexport CLAUDE_CODE_OAUTH_TOKEN=${shQuote(input.claudeOauthToken)}\\n`)}\nSOURCE_LINE='[ -f \"$HOME/.config/openape/claude-token.env\" ] && . \"$HOME/.config/openape/claude-token.env\"'\nfor f in \"$HOME_DIR/.zshenv\" \"$HOME_DIR/.profile\"; do\n touch \"$f\"\n if ! grep -qF 'config/openape/claude-token.env' \"$f\" 2>/dev/null; then\n {\n echo ''\n echo '# OpenApe: load Claude Code OAuth token (added by apes agents spawn)'\n echo \"$SOURCE_LINE\"\n } >> \"$f\"\n fi\ndone\n`\n : ''\n\n return `#!/bin/bash\nset -euo pipefail\n\n# escapes-spawned scripts inherit a minimal PATH that doesn't include\n# /usr/sbin — which is where chown / dscl / pwpolicy live. Force a\n# wide PATH so the privileged setup commands resolve without absolute\n# paths everywhere.\nexport PATH=\"/usr/sbin:/usr/bin:/bin:/sbin:/opt/homebrew/bin:/usr/local/bin\"\n\nNAME=${shQuote(name)}\nMACOS_USER=${shQuote(macOSUsername)}\nHOME_DIR=${shQuote(homeDir)}\nSHELL_PATH=${shQuote(shellPath)}\n\n# Tombstone-reuse: \\`apes agents destroy\\` leaves the dscl user\n# record behind (opendirectoryd refuses \\`dscl . -delete\\` from\n# escapes' setuid-root context without admin auth, so we accept the\n# stranded record as a harmless tombstone — see\n# runPhaseGTeardownInProcess). When the operator re-spawns with the\n# same name, we recycle the tombstone instead of refusing: if the\n# previously-recorded home dir is gone from disk (matching the\n# Phase-G teardown's \\`rm -rf\\`), we reuse the existing UID +\n# overwrite the home. If the home is still on disk it's a real,\n# live agent — refuse.\nTOMBSTONE_REUSE=0\nif dscl . -read \"/Users/$MACOS_USER\" >/dev/null 2>&1; then\n EXISTING_HOME=$(dscl . -read \"/Users/$MACOS_USER\" NFSHomeDirectory 2>/dev/null | awk '/NFSHomeDirectory:/ {print $2}')\n if [ -n \"$EXISTING_HOME\" ] && [ -d \"$EXISTING_HOME\" ]; then\n echo \"User $MACOS_USER already exists with a live home at $EXISTING_HOME; refusing to overwrite.\" >&2\n exit 1\n fi\n NEXT_UID=$(dscl . -read \"/Users/$MACOS_USER\" UniqueID 2>/dev/null | awk '/UniqueID:/ {print $2}')\n if [ -z \"$NEXT_UID\" ]; then\n echo \"User $MACOS_USER exists but has no UniqueID; record is malformed, refusing to recycle.\" >&2\n exit 1\n fi\n echo \"Recycling tombstone dscl record for $MACOS_USER (uid=$NEXT_UID, prior home $EXISTING_HOME — gone)\"\n TOMBSTONE_REUSE=1\nfi\n\n# Phase G: agent home dirs live under /var/openape/homes/, not\n# /Users/. Pre-create the parent and chmod it world-traversable\n# so per-agent dirs can be reached by their respective uids.\nmkdir -p /var/openape/homes\nchmod 755 /var/openape/homes\n\nif [ \"$TOMBSTONE_REUSE\" = \"0\" ]; then\n # Pick the LOWEST free UID in the [200, 500) hidden service-account\n # range. We must skip every occupied UID — agent users AND the many\n # macOS system _* accounts — and reuse gaps. The old code took\n # max(existing)+1, so a single agent landing on 499 wedged every\n # future spawn (\"No free UID\") even with 100+ UIDs free. Now we scan\n # for the first actually-unused UID.\n OCCUPIED_UIDS=$(dscl . -list /Users UniqueID | awk '$2 >= 200 && $2 < 500 {print $2}' | sort -n -u)\n NEXT_UID=\"\"\n candidate=200\n while [ \"$candidate\" -lt 500 ]; do\n if ! printf '%s\\n' \"$OCCUPIED_UIDS\" | grep -qx \"$candidate\"; then\n NEXT_UID=$candidate\n break\n fi\n candidate=$((candidate + 1))\n done\n if [ -z \"$NEXT_UID\" ]; then\n echo \"No free UID in [200, 500) — refusing to clobber a real user.\" >&2\n exit 1\n fi\n\n dscl . -create \"/Users/$MACOS_USER\"\nfi\n\n# Idempotent attribute writes — \\`dscl . -create\\` on an existing\n# property overwrites in place, so the tombstone-reuse path lands\n# the same end-state as a fresh create.\ndscl . -create \"/Users/$MACOS_USER\" UserShell \"$SHELL_PATH\"\ndscl . -create \"/Users/$MACOS_USER\" RealName \"OpenApe Agent $NAME\"\ndscl . -create \"/Users/$MACOS_USER\" UniqueID \"$NEXT_UID\"\ndscl . -create \"/Users/$MACOS_USER\" PrimaryGroupID 20\ndscl . -create \"/Users/$MACOS_USER\" NFSHomeDirectory \"$HOME_DIR\"\ndscl . -create \"/Users/$MACOS_USER\" IsHidden 1\n\nmkdir -p \"$HOME_DIR/.ssh\" \"$HOME_DIR/.config/apes\"\n\ncat > \"$HOME_DIR/.ssh/id_ed25519\" ${shHeredoc(privatePemForHeredoc.trimEnd())}\ncat > \"$HOME_DIR/.ssh/id_ed25519.pub\" ${shHeredoc(`${input.publicKeySshLine}`)}\ncat > \"$HOME_DIR/.config/apes/auth.json\" ${shHeredoc(input.authJson)}\nmkdir -p \"$HOME_DIR/.config/openape\"\ncat > \"$HOME_DIR/.config/openape/agent-x25519.key\" ${shHeredoc(input.x25519PrivateKey)}\ncat > \"$HOME_DIR/.config/openape/agent-x25519.key.pub\" ${shHeredoc(input.x25519PublicKey)}\n${claudeBlock}${claudeTokenBlock}${buildBridgeBlock(input.bridge)}${buildTroopBlock(input.troop)}\nchown -R \"$MACOS_USER:staff\" \"$HOME_DIR\"\nchmod 700 \"$HOME_DIR/.ssh\"\nchmod 700 \"$HOME_DIR/.config\"\nchmod 700 \"$HOME_DIR/.config/openape\"\nchmod 600 \"$HOME_DIR/.ssh/id_ed25519\"\nchmod 644 \"$HOME_DIR/.ssh/id_ed25519.pub\"\nchmod 600 \"$HOME_DIR/.config/apes/auth.json\"\nchmod 600 \"$HOME_DIR/.config/openape/agent-x25519.key\"\nchmod 644 \"$HOME_DIR/.config/openape/agent-x25519.key.pub\"\nif [ -f \"$HOME_DIR/.config/openape/claude-token.env\" ]; then\n chmod 700 \"$HOME_DIR/.config/openape\"\n chmod 600 \"$HOME_DIR/.config/openape/claude-token.env\"\nfi\n\necho \"OK $NAME (macOS user $MACOS_USER) uid=$NEXT_UID home=$HOME_DIR\"\n${buildBridgeBootstrapBlock(input.bridge, name)}${buildTroopBootstrapBlock(input.troop, name)}`\n}\n\nfunction buildBridgeBlock(bridge: SpawnBridgeFiles | null): string {\n if (!bridge) return ''\n // Phase B (#sim-arch): no per-agent system-domain bridge plist\n // anymore. The Nest's in-process supervisor owns bridge lifecycle\n // (`apps/openape-nest/src/lib/supervisor.ts`). We still drop the\n // bridge .env into the agent home so the bridge's\n // resolveBridgeConfig finds it at runtime — same path the\n // supervisor's child process uses. start.sh is no longer needed\n // (the supervisor invokes ape-agent directly via\n // \\`apes run --as <agent>\\`), and the system-domain plist is no\n // longer written.\n return `\nmkdir -p \"$HOME_DIR/Library/Application Support/openape/bridge\" \"$HOME_DIR/Library/Logs\"\ncat > \"$HOME_DIR/Library/Application Support/openape/bridge/.env\" ${shHeredoc(bridge.envFile)}\nchmod 600 \"$HOME_DIR/Library/Application Support/openape/bridge/.env\"\n`\n}\n\nfunction buildBridgeBootstrapBlock(_bridge: SpawnBridgeFiles | null, _name: string): string {\n // Phase B: no launchd plist to bootstrap — Nest supervisor takes\n // over at the next /agents POST handler reconcile. Caller (the\n // Nest's POST /agents handler) calls supervisor.reconcile(...)\n // after the spawn succeeds.\n return ''\n}\n\nexport interface SpawnTroopFiles {\n /** Plist label, e.g. `openape.troop.sync.<agent>`. */\n plistLabel: string\n /** Absolute path under $HOME/Library/LaunchAgents/. */\n plistPath: string\n /** Full plist XML content. */\n plistContent: string\n}\n\n/**\n * Troop sync launchd plist — installed for every spawned agent.\n * Drops `~/Library/LaunchAgents/openape.troop.sync.<agent>.plist`,\n * bootstraps it into the agent's user-domain (gui/<uid>), then runs\n * `apes agents sync` once eagerly so the agent appears at the troop\n * SP within seconds rather than waiting a full sync interval.\n */\nfunction buildTroopBlock(_troop: SpawnTroopFiles | null): string {\n // Phase C (#sim-arch): no per-agent troop-sync plist anymore. The\n // Nest's centralised TroopSync loop walks the registry every 5 min\n // and runs `apes agents sync` for each agent (see\n // apps/openape-nest/src/lib/troop-sync.ts). We still create the\n // agent-side dirs that `apes agents sync` writes to.\n return `\nmkdir -p \"$HOME_DIR/Library/Logs\" \"$HOME_DIR/.openape/agent/tasks\"\n`\n}\n\nfunction buildTroopBootstrapBlock(_troop: SpawnTroopFiles | null, _name: string): string {\n // Phase C: no system-domain plist to bootstrap. The Nest's\n // centralised troop-sync loop will pick the new agent up at the\n // next tick (≤5 min after spawn).\n return ''\n}\n\nexport interface DestroyTeardownScriptInput {\n name: string\n homeDir: string\n adminUser: string\n}\n\n/**\n * Phase G teardown — for agents whose home is under /var/openape/homes/.\n * Skips sysadminctl + admin-password because:\n * 1. The home dir is on /var/, not FDA-protected → root can rm.\n * 2. We accept leaving the dscl user record as a tombstone\n * (hidden, IsHidden=1, no home, no processes) — opendirectoryd\n * refuses dscl . -delete from escapes' setuid-root context\n * without admin auth, but the tombstone is harmless.\n * Result: fully scriptable destroy without an interactive admin\n * password prompt.\n */\n/**\n * Phase-G teardown — Node implementation. The shell variant\n * (`buildPhaseGTeardownScript` below) is kept for back-compat but\n * unused in the new flow: instead of `apes run --as root -- bash\n * <tempScript>`, the destroy command does `apes run --as root --\n * apes agents destroy <name> --force --root-stage`, then this\n * function runs the same ops directly in-process when re-invoked\n * as root. Net effect: the DDISA grant request reads\n * \"apes agents destroy <name> --force --root-stage\" (matches the\n * existing `apes agents destroy *` YOLO pattern) instead of an\n * opaque `bash /var/folders/.../teardown.sh`.\n *\n * Caller invariant: process.geteuid() === 0. The shell script\n * tolerated being called as non-root by no-op'ing on the privileged\n * lines; this version trusts the caller to have already escalated\n * via `apes run --as root`.\n */\nexport function runPhaseGTeardownInProcess(input: { name: string, homeDir: string, macOSUsername?: string }): void {\n const { name, homeDir } = input\n // macOSUsername is the dscl record name; for new agents it's\n // `openape-agent-<name>`, for legacy pre-prefix agents it's just\n // <name>. Callers pass it explicitly; if absent we fall back to\n // the agent name so the legacy code path still resolves.\n const macOSUser = input.macOSUsername ?? name\n\n // Read agent's UID via dscl. Same approach as the shell version —\n // dscl . -read /Users/<user> UniqueID emits \"UniqueID: <n>\".\n let uid: string | null = null\n try {\n const out = execFileSync('/usr/bin/dscl', ['.', '-read', `/Users/${macOSUser}`, 'UniqueID'], { encoding: 'utf8' })\n const m = out.match(/UniqueID:\\s*(\\d+)/)\n if (m) uid = m[1]!\n }\n catch { /* dscl returns non-zero when the user doesn't exist — that's fine */ }\n\n if (uid) {\n // bootout the user-domain launchd + kill any live processes\n // owned by the agent uid. Both allowed to fail (no live session\n // is the common case after a clean spawn). We swallow failures\n // identically to the shell script's `|| true`.\n try { execFileSync('/bin/launchctl', ['bootout', `user/${uid}`], { stdio: 'ignore' }) }\n catch { /* no live session — fine */ }\n try { execFileSync('/usr/bin/pkill', ['-9', '-u', uid], { stdio: 'ignore' }) }\n catch { /* no live procs — fine */ }\n }\n\n // Per-agent ecosystem files written by the Nest's pm2-supervisor.\n const agentDir = `/var/openape/agents/${name}`\n try { rmSync(agentDir, { recursive: true, force: true }) }\n catch { /* nothing to remove */ }\n\n // Home dir lives under /var/openape/homes/ — no FDA wall, root can\n // rm directly. Same safety check as the shell script: refuse on\n // empty / root-fs paths so a misconfigured agent.json can't nuke\n // the filesystem.\n if (homeDir && homeDir !== '/' && homeDir.startsWith('/var/openape/homes/')) {\n try { rmSync(homeDir, { recursive: true, force: true }) }\n catch { /* already gone */ }\n }\n\n // dscl record stays as a tombstone — opendirectoryd rejects the\n // delete from escapes' setuid-root context without admin auth, so\n // the user record sticks around hidden (IsHidden=1) with a stale\n // NFSHomeDirectory. Run `sudo apes agents cleanup-orphans` from a\n // shell later to sysadminctl-deleteUser the accumulated tombstones.\n // eslint-disable-next-line no-console\n console.log(`OK Phase-G teardown done for ${name} (dscl record /Users/${macOSUser} kept as tombstone)`)\n}\n\n// Legacy: bash-script version of the same teardown. Kept as a\n// reference until we've verified the in-process variant covers all\n// the edge cases in production; no caller in this repo uses it.\nexport function buildPhaseGTeardownScript(input: { name: string, homeDir: string }): string {\n const { name, homeDir } = input\n return `#!/bin/bash\nset -u\n\nNAME=${shQuote(name)}\nHOME_DIR=${shQuote(homeDir)}\n\nUID_OF=$(dscl . -read \"/Users/$NAME\" UniqueID 2>/dev/null | awk '/UniqueID:/ {print $2}')\n\nif [ -n \"$UID_OF\" ]; then\n launchctl bootout \"user/$UID_OF\" 2>/dev/null || true\n pkill -9 -u \"$UID_OF\" 2>/dev/null || true\nfi\n\n# Per-agent ecosystem files written by the Nest's pm2-supervisor.\nrm -rf \"/var/openape/agents/$NAME\"\n\n# Home dir lives under /var/openape/homes/ — no FDA wall, root can\n# remove directly.\nif [ -d \"$HOME_DIR\" ] && [ \"$HOME_DIR\" != \"/\" ] && [ \"$HOME_DIR\" != \"\" ]; then\n rm -rf \"$HOME_DIR\"\nfi\n\n# dscl record stays as a tombstone. Operators run\n# \\`sudo sysadminctl -deleteUser $NAME\\` to fully clean up if desired.\necho \"OK Phase-G teardown done for $NAME (dscl record kept as tombstone)\"\n`\n}\n\nexport function buildDestroyTeardownScript(input: DestroyTeardownScriptInput): string {\n const { name, homeDir, adminUser } = input\n return `#!/bin/bash\n# Best-effort teardown. set -u catches typos; we deliberately do NOT use -e\n# because pkill / launchctl are allowed to fail when the user has no live\n# sessions.\nset -u\n\nNAME=${shQuote(name)}\nHOME_DIR=${shQuote(homeDir)}\nADMIN_USER=${shQuote(adminUser)}\n\n# Read the admin password from stdin (line 1). The caller pipes it in.\n# We never accept it as an argv element so it can't show up in process\n# listings or escapes' audit log.\nread -r ADMIN_PASSWORD\nif [ -z \"$ADMIN_PASSWORD\" ]; then\n echo \"ERROR: no admin password on stdin (expected one line).\" >&2\n exit 2\nfi\n\nUID_OF=$(dscl . -read \"/Users/$NAME\" UniqueID 2>/dev/null | awk '/UniqueID:/ {print $2}')\n\nif [ -n \"$UID_OF\" ]; then\n launchctl bootout \"user/$UID_OF\" 2>/dev/null || true\n pkill -9 -u \"$UID_OF\" 2>/dev/null || true\nfi\n\n# Per-agent system LaunchDaemon written by spawn (unless --no-bridge). Bootout +\n# delete must come BEFORE we delete the user, otherwise launchd keeps a\n# zombie reference. No-op if the plist isn't there.\nBRIDGE_LABEL=\"eco.hofmann.apes.bridge.$NAME\"\nBRIDGE_PLIST=\"/Library/LaunchDaemons/$BRIDGE_LABEL.plist\"\nif [ -f \"$BRIDGE_PLIST\" ]; then\n launchctl bootout \"system/$BRIDGE_LABEL\" 2>/dev/null || true\n rm -f \"$BRIDGE_PLIST\"\nfi\n\nif [ -d \"$HOME_DIR\" ] && [ \"$HOME_DIR\" != \"/\" ] && [ \"$HOME_DIR\" != \"\" ]; then\n rm -rf \"$HOME_DIR\"\nfi\n\n# \\`escapes\\` is a plain setuid binary — opendirectoryd sees no audit/PAM\n# session attached (AUDIT_SESSION_ID=unset) and rejects DirectoryService\n# writes from this context: a bare \\`sysadminctl -deleteUser\\` or\n# \\`dscl . -delete\\` hangs ~5 minutes and exits with eUndefinedError -14987\n# at DSRecord.m:563. Passing explicit -adminUser/-adminPassword bypasses\n# opendirectoryd's implicit \"is current session admin?\" check and\n# authenticates against DirectoryService directly — the delete then\n# completes in ~1 second.\nif ! command -v sysadminctl >/dev/null 2>&1; then\n echo \"ERROR: sysadminctl not available; cannot delete user record.\" >&2\n exit 1\nfi\n\nsysadminctl \\\\\n -deleteUser \"$NAME\" \\\\\n -adminUser \"$ADMIN_USER\" \\\\\n -adminPassword \"$ADMIN_PASSWORD\"\nSYSAD_EC=$?\nunset ADMIN_PASSWORD\n\nif [ $SYSAD_EC -ne 0 ]; then\n echo \"ERROR: sysadminctl -deleteUser failed (exit=$SYSAD_EC).\" >&2\n echo \" Common causes: wrong admin password, admin user '$ADMIN_USER'\" >&2\n echo \" not in admin group, or target user '$NAME' is the last secure\" >&2\n echo \" token holder (run \\\\\\`sysadminctl -secureTokenStatus $NAME\\\\\\`).\" >&2\n exit 1\nfi\n\n# Verify the record is actually gone.\nif dscl . -read \"/Users/$NAME\" >/dev/null 2>&1; then\n echo \"ERROR: user record /Users/$NAME still exists after teardown\" >&2\n exit 1\nfi\n\necho \"OK destroyed $NAME\"\n`\n}\n\n/**\n * Quote a string for safe use as a single bash argument.\n * Wraps in single quotes and escapes embedded single quotes.\n */\nexport function shQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`\n}\n\nexport interface AuthJsonInput {\n idp: string\n accessToken: string\n email: string\n expiresAt: number\n /**\n * Absolute path to the agent's Ed25519 private key on its own home\n * directory. Lets `@openape/cli-auth` refresh the access token in\n * process via challenge-response — see #259. Spawn writes the key\n * to `${homeDir}/.ssh/id_ed25519` so the path is deterministic.\n */\n keyPath: string\n /**\n * Email of the human owner who spawned this agent. Persisted so the\n * bridge daemon can (a) send the initial contact request to the right\n * person and (b) seed its allowlist with the only peer it should\n * trust by default. Other peers go through `apes agents allow`.\n */\n ownerEmail: string\n}\n\nexport function buildAgentAuthJson(input: AuthJsonInput): string {\n return `${JSON.stringify({\n idp: input.idp,\n access_token: input.accessToken,\n email: input.email,\n expires_at: input.expiresAt,\n key_path: input.keyPath,\n owner_email: input.ownerEmail,\n }, null, 2)}\\n`\n}\n\nexport const CLAUDE_SETTINGS_JSON: string = `${JSON.stringify({\n hooks: {\n PreToolUse: [\n {\n matcher: 'Bash',\n hooks: [\n { type: 'command', command: '$HOME/.claude/hooks/bash-via-ape-shell.sh' },\n ],\n },\n ],\n },\n}, null, 2)}\\n`\n\n/**\n * Inlined source of `packages/apes/scripts/bash-via-ape-shell.sh`.\n * Kept identical to the .sh file via the bundled-hook-source.test.ts\n * drift check; resolving the file at runtime is unreliable across\n * dev/built/installed layouts, so we embed once at build time.\n */\nexport const BASH_VIA_APE_SHELL_HOOK_SOURCE = `#!/bin/bash\n# PreToolUse hook for the Bash tool: rewrite the tool input so the\n# original command runs via \\`ape-shell -c <cmd>\\`. That re-routes every\n# Bash invocation through the apes grant flow, so the agent cannot\n# execute shell commands without an approved grant.\nexec python3 -c '\nimport json, shlex, sys\ndata = json.load(sys.stdin)\ncmd = data[\"tool_input\"][\"command\"]\nwrapped = \"ape-shell -c \" + shlex.quote(cmd)\nout = {\"hookSpecificOutput\": {\"hookEventName\": \"PreToolUse\", \"updatedToolInput\": {\"command\": wrapped}}}\nprint(json.dumps(out))\n'\n`\n","import { execFileSync } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\n\nexport interface MacOSUserSummary {\n name: string\n uid: number | null\n shell: string | null\n /** Resolved NFSHomeDirectory — varies between /Users/<name> for\n * legacy agents and /var/openape/homes/<name> for Phase G+ agents. */\n homeDir: string | null\n}\n\nexport function isDarwin(): boolean {\n return process.platform === 'darwin'\n}\n\n/**\n * Prefix every spawned macOS service user with this string so\n * `cleanup-orphans`, operator tooling, and any future `dscl . -list\n * /Users` audit can identify OpenApe-managed accounts at a glance\n * without scanning the full UID range. Agent-facing surfaces (email,\n * troop UI, bridge data dir, `apes agents list`) keep the bare agent\n * name — the prefix lives only at the macOS layer.\n */\nexport const MACOS_USER_PREFIX = 'openape-agent-'\n\nexport function macOSUsernameForAgent(agentName: string): string {\n return `${MACOS_USER_PREFIX}${agentName}`\n}\n\n/**\n * Resolve the macOS user record for an agent, trying the prefixed\n * name first (new spawns) and falling back to the bare agent name\n * (pre-prefix agents). Returns null when neither exists. Used by\n * destroy / run --as / list so legacy agents keep working\n * transparently.\n */\nexport function lookupMacOSUserForAgent(agentName: string): MacOSUserSummary | null {\n return readMacOSUser(macOSUsernameForAgent(agentName)) ?? readMacOSUser(agentName)\n}\n\nexport interface OrphanRecord {\n /** dscl record name (e.g. `openape-agent-igor`). */\n name: string\n uid: number | null\n /** The NFSHomeDirectory the record points at — already verified to be missing. */\n homeDir: string\n}\n\n/**\n * Enumerate dscl user records that look like OpenApe agent tombstones:\n * either prefixed with `openape-agent-`, or whose home dir is under\n * `/var/openape/homes/` (legacy agents pre-prefix). A record counts as\n * orphaned when its NFSHomeDirectory does not exist on disk anymore —\n * matching the post-destroy state that opendirectoryd refuses to clean\n * up from escapes' setuid-root audit-session.\n *\n * Caller invariant: process is running with admin audit-session\n * (i.e. invoked under interactive `sudo`). The dscl/readFile calls\n * themselves don't strictly need root, but the cleanup pass that\n * consumes this list does.\n */\nexport function listOrphanedAgentRecords(): OrphanRecord[] {\n if (!isDarwin()) return []\n let output: string\n try {\n output = execFileSync('dscl', ['.', '-list', '/Users', 'NFSHomeDirectory'], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n }\n catch { return [] }\n\n const orphans: OrphanRecord[] = []\n for (const line of output.split('\\n')) {\n // dscl emits \"<name>\\t<homeDir>\" — but the separator can collapse\n // to runs of whitespace, so split on /\\s+/ and take first + last.\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 2) continue\n const name = parts[0]!\n const homeDir = parts.slice(1).join(' ')\n const looksLikeAgent = name.startsWith(MACOS_USER_PREFIX) || homeDir.startsWith('/var/openape/homes/')\n if (!looksLikeAgent) continue\n if (existsSync(homeDir)) continue\n const record = readMacOSUser(name)\n orphans.push({ name, uid: record?.uid ?? null, homeDir })\n }\n return orphans\n}\n\n/**\n * Read a single user via `dscl . -read /Users/<name>`.\n * Returns null when the user doesn't exist (dscl exits non-zero with a\n * `eDSRecordNotFound`-style error). Any other error propagates.\n */\nexport function readMacOSUser(name: string): MacOSUserSummary | null {\n let output: string\n try {\n output = execFileSync('dscl', ['.', '-read', `/Users/${name}`], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n }\n catch {\n return null\n }\n\n const uidMatch = output.match(/UniqueID:\\s*(\\d+)/)\n const shellMatch = output.match(/UserShell:\\s*(\\S.*)$/m)\n const homeMatch = output.match(/NFSHomeDirectory:\\s*(\\S.*)$/m)\n return {\n name,\n uid: uidMatch ? Number.parseInt(uidMatch[1]!, 10) : null,\n shell: shellMatch ? shellMatch[1]!.trim() : null,\n homeDir: homeMatch ? homeMatch[1]!.trim() : null,\n }\n}\n\n/**\n * List all macOS user names via `dscl . -list /Users`.\n * Returns the raw set of names (no filtering), one per line.\n */\nexport function listMacOSUserNames(): Set<string> {\n let output: string\n try {\n output = execFileSync('dscl', ['.', '-list', '/Users'], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n }\n catch {\n return new Set()\n }\n return new Set(\n output\n .split('\\n')\n .map(line => line.trim())\n .filter(line => line.length > 0),\n )\n}\n\n/**\n * Resolve a binary on PATH using `which`. Returns the absolute path or null.\n */\nexport function whichBinary(name: string): string | null {\n try {\n const out = execFileSync('which', [name], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim()\n return out || null\n }\n catch {\n return null\n }\n}\n\n/**\n * Check whether the given shell path is registered in /etc/shells. macOS\n * (and chsh on most Unixes) refuses to set a login shell that isn't listed.\n */\nexport function isShellRegistered(shellPath: string): boolean {\n if (!existsSync('/etc/shells')) return false\n const content = readFileSync('/etc/shells', 'utf-8')\n return content\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l && !l.startsWith('#'))\n .includes(shellPath)\n}\n","import { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { isDarwin, listOrphanedAgentRecords } from '../../lib/macos-user'\n\n/**\n * Sweep accumulated agent-user tombstones left behind by\n * `apes agents destroy`. opendirectoryd refuses `dscl . -delete` from\n * escapes' setuid-root context (the audit-session is unset, so it\n * cannot verify admin authorisation), but accepts `sysadminctl\n * -deleteUser` when invoked under an interactive `sudo` session\n * because that inherits the operator's admin audit-session.\n *\n * Detection rule: any dscl user record whose NFSHomeDirectory is\n * under `/var/openape/homes/` OR whose name starts with\n * `openape-agent-`, AND whose home dir is missing on disk. The\n * combination is unambiguous — Phase G+ agents always put homes\n * under that path, and the prefix narrows it further once all\n * agents are migrated.\n *\n * Run as: `sudo apes agents cleanup-orphans` (interactive admin\n * session required). The command refuses to proceed when not root.\n */\nexport const cleanupOrphansCommand = defineCommand({\n meta: {\n name: 'cleanup-orphans',\n description: 'Delete tombstoned macOS user records left behind by `apes agents destroy` (run with sudo).',\n },\n args: {\n 'dry-run': {\n type: 'boolean',\n description: 'List orphans without deleting.',\n },\n 'force': {\n type: 'boolean',\n description: 'Skip the interactive confirmation. Required when stdin is not a TTY.',\n },\n },\n async run({ args }) {\n if (!isDarwin()) {\n throw new CliError(`\\`apes agents cleanup-orphans\\` is macOS-only. Detected platform: ${process.platform}.`)\n }\n\n const orphans = listOrphanedAgentRecords()\n if (orphans.length === 0) {\n consola.success('No agent tombstones found — dscl is clean.')\n return\n }\n\n consola.info(`Found ${orphans.length} agent tombstone${orphans.length === 1 ? '' : 's'}:`)\n for (const o of orphans) {\n console.log(` • ${o.name}${o.uid !== null ? ` (uid=${o.uid})` : ''} — was ${o.homeDir}`)\n }\n\n if (args['dry-run']) {\n consola.info('Dry-run — no records deleted. Re-run without --dry-run to clean up.')\n return\n }\n\n if (process.geteuid?.() !== 0) {\n throw new CliError(\n 'Must run as root so opendirectoryd accepts the sysadminctl-deleteUser calls. '\n + 'Re-run with `sudo apes agents cleanup-orphans` from a shell login (the sudo '\n + 'session inherits your admin audit-session, which opendirectoryd verifies).',\n )\n }\n\n if (!args.force) {\n if (!process.stdin.isTTY) {\n throw new CliError(\n 'No TTY available for the interactive confirmation. Re-run with --force '\n + '(this is the same flag CI / scripted callers use).',\n )\n }\n const confirmed = await consola.prompt(`Delete ${orphans.length} tombstone${orphans.length === 1 ? '' : 's'}?`, {\n type: 'confirm',\n initial: false,\n })\n if (typeof confirmed === 'symbol' || !confirmed) {\n consola.info('Aborted — no records deleted.')\n return\n }\n }\n\n let deleted = 0\n let failed = 0\n for (const o of orphans) {\n try {\n execFileSync('/usr/sbin/sysadminctl', ['-deleteUser', o.name], {\n stdio: ['ignore', 'inherit', 'inherit'],\n })\n consola.success(`Deleted ${o.name}`)\n deleted++\n }\n catch (err) {\n consola.warn(`Failed to delete ${o.name}: ${err instanceof Error ? err.message : String(err)}`)\n failed++\n }\n }\n\n if (failed > 0) {\n throw new CliError(`Cleanup finished with errors: ${deleted} deleted, ${failed} failed.`)\n }\n consola.success(`Cleanup complete — ${deleted} tombstone${deleted === 1 ? '' : 's'} removed.`)\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\nimport { consola } from 'consola'\nimport type { RuntimeConfig } from '../../lib/agent-runtime'\nimport { taskTools } from '../../lib/agent-tools'\nimport { runApeShell } from '../../lib/agent-tools/ape-shell-exec'\nimport { materializeSecrets } from '../../lib/agent-secrets-runtime'\nimport { runCodingTask } from '../../lib/coding/coding-loop'\nimport { buildIssueGet, detectForge } from '../../lib/coding/forge'\nimport type { Forge } from '../../lib/coding/forge'\nimport type { IssueRef } from '../../lib/coding/issue-task'\nimport { createLlmReviewer, createLlmRiskAssessor } from '../../lib/coding/llm-review'\nimport { resolveMergePolicy } from '../../lib/coding/derive-policy'\n\nclass CliError extends Error {}\n\n// The LLM toolset for coding — file.*/bash/verify + read-only forge.\n// Deliberately NO forge.pr.merge (the orchestrator owns merge).\nconst CODING_TOOLS = ['file.read', 'file.write', 'file.edit', 'bash', 'git.worktree', 'verify', 'forge.issue.get', 'forge.pr.status']\n\nconst DEFAULT_PERSONA = [\n 'You are an autonomous coding agent. You implement an assigned issue in',\n 'the provided git worktree: read the relevant code, make small targeted',\n 'edits with file.edit, and make the repo verification command pass via',\n 'the verify tool. Do not open or merge PRs — the orchestrator does that.',\n 'No change is done until verify is green.',\n].join(' ')\n\nfunction readLitellmConfig(model?: string): RuntimeConfig {\n const env: Record<string, string> = {}\n const envPath = join(homedir(), 'litellm', '.env')\n if (existsSync(envPath)) {\n for (const raw of readFileSync(envPath, 'utf8').split('\\n')) {\n const line = raw.trim()\n const m = /^([A-Z_][A-Z0-9_]*)=(.*)$/.exec(line)\n if (m) env[m[1]!] = m[2]!.trim().replace(/^[\"']|[\"']$/g, '')\n }\n }\n for (const k of ['LITELLM_API_KEY', 'LITELLM_MASTER_KEY', 'LITELLM_BASE_URL']) {\n if (process.env[k]) env[k] = process.env[k]!\n }\n const apiKey = env.LITELLM_API_KEY || env.LITELLM_MASTER_KEY\n const apiBase = (env.LITELLM_BASE_URL || 'http://127.0.0.1:4000/v1').replace(/\\/$/, '')\n if (!apiKey) throw new CliError('No LITELLM_API_KEY / LITELLM_MASTER_KEY in ~/litellm/.env or env.')\n return { apiBase, apiKey, model: model || process.env.APE_CHAT_BRIDGE_MODEL || 'claude-haiku-4-5' }\n}\n\nfunction readPersona(file?: string): string {\n if (file && existsSync(file)) return readFileSync(file, 'utf8')\n const agentJson = join(homedir(), '.openape', 'agent', 'agent.json')\n if (existsSync(agentJson)) {\n try {\n const p = JSON.parse(readFileSync(agentJson, 'utf8')) as { systemPrompt?: string }\n if (p.systemPrompt?.trim()) return p.systemPrompt\n }\n catch { /* fall through */ }\n }\n return DEFAULT_PERSONA\n}\n\nasync function fetchIssue(forge: Forge, ref: string): Promise<IssueRef> {\n const res = await runApeShell(buildIssueGet(forge, ref))\n if (res.exit_code !== 0) throw new CliError(`could not fetch issue ${ref}: ${res.stderr.slice(0, 200)}`)\n const j = JSON.parse(res.stdout) as { number?: number, id?: number, title?: string, fields?: { 'System.Title'?: string }, body?: string }\n const number = j.number ?? j.id ?? Number(ref)\n const title = j.title ?? j.fields?.['System.Title'] ?? `issue ${ref}`\n return { number, title, body: j.body }\n}\n\nexport const codeAgentCommand = defineCommand({\n meta: {\n name: 'code',\n description: 'Run a coding task: issue to worktree to edit to verify to PR (policy-gated merge). The agent never self-merges.',\n },\n args: {\n 'issue': { type: 'string', description: 'Issue / work-item ref to work on.' },\n 'repo': { type: 'string', description: 'Git remote URL of the target repo.', required: true },\n 'forge': { type: 'string', description: 'github | azure | registered forge. Auto-detected from --repo if omitted.' },\n 'model': { type: 'string', description: 'Override LLM model.' },\n 'max-steps': { type: 'string', description: 'Max tool-call rounds (default 40).' },\n 'persona-file': { type: 'string', description: 'File with the agent persona/system prompt.' },\n 'poll-label': { type: 'string', description: 'Poll mode: work all open issues with this label.' },\n },\n async run({ args }) {\n const repo = args.repo as string\n const forge: Forge = (args.forge as string) || detectForge(repo)\n\n // Inject sealed capability secrets (e.g. GH_TOKEN / AZ_PAT) into this\n // process's env so the forge CLIs we shell out to are authenticated.\n // The cron-runner invokes us as the agent user, so the blobs + the\n // X25519 key in ~/.config/openape are readable. Best-effort: no key /\n // no blobs just means nothing to inject. Without this, `gh` runs\n // unauthenticated and silently returns an empty issue list.\n try {\n const { applied } = materializeSecrets()\n if (applied.length > 0) consola.info(`Capabilities available: ${applied.join(', ')}`)\n }\n catch { /* no secrets to materialize */ }\n const config = readLitellmConfig(args.model as string | undefined)\n const persona = readPersona(args['persona-file'] as string | undefined)\n const maxSteps = Number(args['max-steps']) > 0 ? Number(args['max-steps']) : 40\n const tools = taskTools(CODING_TOOLS)\n\n const deps = {\n runtimeConfig: config,\n tools,\n persona,\n maxSteps,\n resolvePolicy: (worktree: string) => resolveMergePolicy(worktree),\n reviewer: createLlmReviewer(config),\n riskAssessor: createLlmRiskAssessor(config),\n log: (l: string) => consola.info(l),\n }\n\n // Determine the issue list (single or poll).\n const refs: string[] = []\n if (args['poll-label']) {\n const slug = repo.replace(/^https:\\/\\/github\\.com\\//, '').replace(/\\.git$/, '')\n const list = await runApeShell(`gh issue list --repo ${slug} --label '${args['poll-label']}' --state open --json number --jq '.[].number'`)\n if (list.exit_code !== 0) {\n throw new CliError(`gh issue list failed (exit ${list.exit_code}): ${(list.stderr || list.stdout).slice(0, 300)}`)\n }\n // `gh` exits 0 with empty stdout when it is unauthenticated, which\n // would otherwise look identical to \"no matching issues\". Detect that\n // explicitly so a missing GH_TOKEN is a loud error, not a silent no-op.\n if (list.stdout.trim() === '' && /gh auth login|GH_TOKEN/i.test(list.stderr)) {\n throw new CliError('gh is not authenticated (no GH_TOKEN). The agent\\'s GH_TOKEN capability is not materialized — bind it via the deploy/secrets flow.')\n }\n // Keep only numeric issue ids — defensive against any stray line.\n refs.push(...list.stdout.split('\\n').map(s => s.trim()).filter(s => /^\\d+$/.test(s)))\n if (refs.length === 0) { consola.info('no open issues with that label'); return }\n }\n else if (args.issue) {\n refs.push(args.issue as string)\n }\n else {\n throw new CliError('provide --issue <ref> or --poll-label <label>')\n }\n\n for (const ref of refs) {\n const issue = await fetchIssue(forge, ref)\n consola.start(`coding issue #${issue.number}: ${issue.title}`)\n const result = await runCodingTask({ issue, repo, forge }, deps)\n consola.box(`#${issue.number} -> ${result.outcome}\\nPR: ${result.prRef ?? '(none)'}\\n${result.reason}`)\n }\n },\n})\n","import type { SealedBox } from '@openape/core'\nimport { existsSync, readdirSync, readFileSync, watch } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { openString } from '@openape/core'\n\n// Agent-side of the capability broker. troop seals a secret to this\n// agent's X25519 pubkey (M2a/M2c); nest drops the opaque blob into\n// ~/.config/openape/secrets.d/<ENV>.blob (M2d). Here the agent — the\n// ONLY place plaintext exists — opens it with its private key and\n// injects it into process.env so its tools (bash etc.) see it. Revoke\n// = blob removed → the env var is dropped on the next materialize.\n// See plans.openape.ai 01KRTAE8 (M2e).\n\nconst CONFIG_DIR = join(homedir(), '.config', 'openape')\nexport const SECRETS_DIR = join(CONFIG_DIR, 'secrets.d')\nexport const X25519_KEY_PATH = join(CONFIG_DIR, 'agent-x25519.key')\n// Public half written alongside the private key at spawn (agent-bootstrap).\n// Reported to troop on sync so the capability broker can seal secrets to it.\nexport const X25519_PUBKEY_PATH = `${X25519_KEY_PATH}.pub`\n\nfunction envNameFromFile(file: string): string | null {\n if (!file.endsWith('.blob')) return null\n const env = file.slice(0, -'.blob'.length)\n return /^[A-Z][A-Z0-9_]*$/.test(env) ? env : null\n}\n\nexport function readAgentEncryptionKey(keyPath = X25519_KEY_PATH): string | null {\n if (!existsSync(keyPath)) return null\n const k = readFileSync(keyPath, 'utf8').trim()\n return k.length > 0 ? k : null\n}\n\nexport function readAgentEncryptionPublicKey(pubPath = X25519_PUBKEY_PATH): string | null {\n if (!existsSync(pubPath)) return null\n const k = readFileSync(pubPath, 'utf8').trim()\n return k.length > 0 ? k : null\n}\n\nexport interface MaterializeOptions {\n dir?: string\n keyPath?: string\n /** Target env map (defaults to process.env). Injected in tests. */\n env?: NodeJS.ProcessEnv\n /** Env names applied by a previous materialize, to drop on revoke. */\n previouslyApplied?: Iterable<string>\n log?: (line: string) => void\n}\n\nexport interface MaterializeResult {\n applied: string[]\n failed: string[]\n}\n\n/**\n * Open every sealed blob in the secrets dir and set the corresponding\n * env var. Any env that was applied before but whose blob is now gone\n * (revoke) is deleted. Best-effort per blob — a corrupt/foreign blob\n * is logged and skipped, never throws.\n */\nexport function materializeSecrets(opts: MaterializeOptions = {}): MaterializeResult {\n const dir = opts.dir ?? SECRETS_DIR\n const env = opts.env ?? process.env\n const log = opts.log ?? (() => {})\n const applied: string[] = []\n const failed: string[] = []\n\n const key = readAgentEncryptionKey(opts.keyPath)\n const files = key && existsSync(dir) ? readdirSync(dir) : []\n\n for (const file of files) {\n const name = envNameFromFile(file)\n if (!name) continue\n try {\n const box = JSON.parse(readFileSync(join(dir, file), 'utf8')) as SealedBox\n env[name] = openString(box, key!)\n applied.push(name)\n }\n catch (e) {\n failed.push(file)\n log(`secrets: failed to open ${file}: ${(e as Error).message}`)\n }\n }\n\n // Revoke: env names we set last time but that have no blob now.\n const live = new Set(applied)\n for (const prev of opts.previouslyApplied ?? []) {\n if (!live.has(prev)) {\n delete env[prev]\n log(`secrets: revoked ${prev}`)\n }\n }\n\n return { applied, failed }\n}\n\n/**\n * Materialize once, then fs.watch the secrets dir and re-materialize\n * on any change (rotate/revoke take effect live — the user's M2 v1\n * choice). Returns a stop function. Safe to call when the dir doesn't\n * exist yet (watch attaches once it appears on the next agent start).\n */\nexport function startSecretsWatcher(opts: MaterializeOptions = {}): () => void {\n const dir = opts.dir ?? SECRETS_DIR\n const log = opts.log ?? (() => {})\n let appliedNames = new Set<string>()\n\n const run = () => {\n const r = materializeSecrets({ ...opts, previouslyApplied: appliedNames })\n appliedNames = new Set(r.applied)\n }\n\n run()\n if (!existsSync(dir)) return () => {}\n\n let timer: NodeJS.Timeout | null = null\n const watcher = watch(dir, () => {\n // Debounce — a single rotate is several fs events (create, write).\n if (timer) clearTimeout(timer)\n timer = setTimeout(run, 150)\n })\n watcher.on('error', err => log(`secrets: watcher error: ${err.message}`))\n\n return () => {\n if (timer) clearTimeout(timer)\n watcher.close()\n }\n}\n","// Issue → task mapping (M4). Pure helpers that turn a fetched issue /\n// work-item into the branch name + run prompt the coding loop uses.\n//\n// Neither the branch convention nor the prompt/persona is hard-coded\n// policy: the branch name is a configurable TEMPLATE and the prompt is\n// composed from a recipe-supplied PERSONA. The fallbacks are neutral\n// (overridable), not team-specific opinions baked into the library.\n\nexport interface IssueRef {\n number: number | string\n title: string\n body?: string\n // 'fix' | 'feat' | 'chore' … used by the {type} placeholder.\n type?: string\n}\n\nexport interface BranchNaming {\n // Template with {type} {number} {slug} placeholders. Repo/recipe-\n // supplied; the fallback is a neutral convention, not a mandate.\n template?: string\n // Fallback type when the issue carries none.\n defaultType?: string\n // Max slug length (forge/CI branch-length limits vary).\n slugMax?: number\n}\n\nexport interface TaskFraming {\n // The agent's persona/instructions from its recipe — prepended so the\n // task prompt reflects THIS agent, not a hard-coded English script.\n persona?: string\n // Override the default closing instructions entirely.\n instructions?: string\n}\n\nconst DEFAULT_TEMPLATE = '{type}/issue-{number}-{slug}'\nconst DEFAULT_TYPE = 'fix'\nconst DEFAULT_SLUG_MAX = 48\n\n// Minimal, provider-neutral closing instructions. Overridable via\n// TaskFraming.instructions; the recipe persona carries the real voice.\nconst DEFAULT_INSTRUCTIONS = [\n 'Work in the provided worktree. When done:',\n '- ensure the verification command passes (no PR on red)',\n '- open a PR that references this issue',\n '- leave risk-path / agent-judged-risky changes for human approval',\n].join('\\n')\n\nconst TYPE_RE = /^[a-z]{2,12}$/\n\nexport function slugify(title: string, max: number = DEFAULT_SLUG_MAX): string {\n return title\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/[\\s_]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, max)\n .replace(/-$/, '')\n}\n\nexport function buildBranchName(issue: IssueRef, naming: BranchNaming = {}): string {\n const num = String(issue.number).replace(/\\D/g, '')\n if (!num) throw new Error('issue number required')\n const type = issue.type && TYPE_RE.test(issue.type)\n ? issue.type\n : (naming.defaultType ?? DEFAULT_TYPE)\n const slug = slugify(issue.title, naming.slugMax ?? DEFAULT_SLUG_MAX) || 'task'\n return (naming.template ?? DEFAULT_TEMPLATE)\n .replace(/\\{type\\}/g, type)\n .replace(/\\{number\\}/g, num)\n .replace(/\\{slug\\}/g, slug)\n}\n\nexport function buildTaskPrompt(issue: IssueRef, framing: TaskFraming = {}): string {\n const num = String(issue.number)\n const parts: string[] = []\n if (framing.persona?.trim()) parts.push(framing.persona.trim())\n parts.push(`Issue #${num}: ${issue.title}`)\n parts.push(issue.body?.trim() ? issue.body.trim() : '(no description provided)')\n parts.push(framing.instructions?.trim() ? framing.instructions.trim() : DEFAULT_INSTRUCTIONS)\n return parts.join('\\n\\n')\n}\n","// Merge policy (M5): classify a PR's changed files and decide how it\n// may be merged, per the B+C-Overlay policy:\n// - chore → auto-merge on green CI\n// - code → auto-merge after reviewer-agent approval\n// - risk → human approval required, never auto\n//\n// IMPORTANT: this library hard-codes ZERO risk knowledge — no example\n// paths, no `auth`/`proxy`/`migrations` opinions, nothing. A change is\n// \"risk\" only when one of these says so:\n// 1. the AGENT judges it risky (semantic — catches what no glob can),\n// 2. the repo's own config declares it (`.openape/coding.json`),\n// 3. it's derived from signals the repo already has (deploy-workflow\n// `paths:` filters, CODEOWNERS — see derive-policy.ts).\n// The `riskPaths`/`autoPaths` globs are repo-supplied config, never\n// shipped defaults. Hand-maintained parallel lists rot; baked-in lists\n// are worse (wrong for every repo but ours).\n//\n// Secure by default: `autoMergeEnabled` is false → nothing auto-merges\n// until a repo opts in. Auto-merge is opt-in, declared per-repo.\n//\n// Pure + unit-tested. CI-green is enforced server-side by branch\n// protection; this layer only governs whether the agent may ARM the\n// merge and which review/human gate applies.\n\nexport type ChangeClass = 'chore' | 'code' | 'risk'\n\nexport interface MergePolicy {\n // Master switch. False (default) = secure: never auto-merge, every\n // change is handed to a human until the repo opts in.\n autoMergeEnabled: boolean\n // Repo-supplied globs marking low-risk chore paths (auto-merge candidate).\n autoPaths: string[]\n // Repo-supplied + derived globs marking risk paths. NOT a shipped\n // default — empty unless the repo declares them or they're derived.\n riskPaths: string[]\n}\n\n// The agent's own semantic risk judgment on a diff. Injected by the\n// orchestration (LLM-backed); pure decision code just consumes the\n// boolean. This is the PRIMARY risk source — globs are the fallback.\nexport interface AgentRiskAssessment {\n risky: boolean\n reason?: string\n}\n\nexport type RiskAssessorFn = (input: { paths: string[], diff: string }) => Promise<AgentRiskAssessment>\n\n// Secure fallback used when a repo has no `.openape/coding.json`. No\n// path opinions; auto-merge disabled.\nexport const SECURE_DEFAULT_POLICY: MergePolicy = {\n autoMergeEnabled: false,\n autoPaths: [],\n riskPaths: [],\n}\n\n// Minimal glob → RegExp. Supports `**` (any chars incl. `/`), `*` (any\n// chars except `/`), and `?` (single non-`/`). Everything else literal.\nexport function globToRegExp(glob: string): RegExp {\n let re = ''\n for (let i = 0; i < glob.length; i++) {\n const c = glob[i]!\n if (c === '*') {\n if (glob[i + 1] === '*') {\n re += '.*'\n i++\n // consume an immediately following slash so `**/x` also matches `x`\n if (glob[i + 1] === '/') i++\n }\n else {\n re += '[^/]*'\n }\n }\n else if (c === '?') {\n re += '[^/]'\n }\n else if ('.+^${}()|[]\\\\'.includes(c)) {\n re += `\\\\${c}`\n }\n else {\n re += c\n }\n }\n return new RegExp(`^${re}$`)\n}\n\nexport function matchesAny(path: string, globs: string[]): boolean {\n return globs.some(g => globToRegExp(g).test(path))\n}\n\n// Classify a set of changed file paths (repo-relative).\n// - any risk-path match → 'risk'\n// - else all paths are auto-paths → 'chore'\n// - else → 'code'\nexport function classifyChange(paths: string[], policy: MergePolicy = SECURE_DEFAULT_POLICY): ChangeClass {\n if (paths.length === 0) return 'code' // empty/unknown diff is treated conservatively\n if (paths.some(p => matchesAny(p, policy.riskPaths))) return 'risk'\n if (policy.autoPaths.length > 0 && paths.every(p => matchesAny(p, policy.autoPaths))) return 'chore'\n return 'code'\n}\n\nexport interface MergeDecision {\n classification: ChangeClass\n // May the agent arm a merge at all (CI-green still enforced by branch protection)?\n autoMerge: boolean\n // Does a reviewer-agent approval gate the auto-merge?\n needsReview: boolean\n // Must a human approve (agent only opens the PR, then stops)?\n needsHuman: boolean\n reason: string\n}\n\n// Decide how a PR may be merged. Risk comes from EITHER the agent's\n// semantic judgment (`agentRisk`, the primary source) OR the repo's\n// config/derived globs — whichever flags risk wins. The library itself\n// contributes no risk opinion.\nexport function decideMerge(\n paths: string[],\n policy: MergePolicy = SECURE_DEFAULT_POLICY,\n agentRisk?: AgentRiskAssessment,\n): MergeDecision {\n const globClass = classifyChange(paths, policy)\n // Effective risk = repo/derived globs OR the agent's judgment.\n const isRisk = globClass === 'risk' || agentRisk?.risky === true\n const classification: ChangeClass = isRisk ? 'risk' : globClass\n\n // Master switch off → secure default: nothing auto-merges, hand to a\n // human. The repo must opt in via `.openape/coding.json`.\n if (!policy.autoMergeEnabled) {\n return { classification, autoMerge: false, needsReview: false, needsHuman: true, reason: 'auto-merge not enabled for this repo — human approval required (set autoMergeEnabled in .openape/coding.json to opt in)' }\n }\n if (isRisk) {\n const why = agentRisk?.risky\n ? `agent judged this risky${agentRisk.reason ? `: ${agentRisk.reason}` : ''}`\n : 'matches a repo/derived risk path'\n return { classification, autoMerge: false, needsReview: false, needsHuman: true, reason: `${why} — human approval required` }\n }\n if (classification === 'chore') {\n return { classification, autoMerge: true, needsReview: false, needsHuman: false, reason: 'chore/docs only — auto-merge on green CI' }\n }\n return { classification, autoMerge: true, needsReview: true, needsHuman: false, reason: 'code change — auto-merge after reviewer-agent approval' }\n}\n\n// Load the merge policy for a worktree from `<dir>/.openape/coding.json`\n// (the `mergePolicy` key). Missing/invalid → secure default. This keeps\n// the policy with the repo it governs, never in this package. A future\n// step derives sensible globs from existing signals (deploy-workflow\n// `paths:` filters, CODEOWNERS) when the file is absent — see plan.\nexport async function loadMergePolicy(worktreeDir: string): Promise<MergePolicy> {\n const { readFile } = await import('node:fs/promises')\n const { join } = await import('node:path')\n try {\n const raw = await readFile(join(worktreeDir, '.openape', 'coding.json'), 'utf8')\n const parsed = JSON.parse(raw) as { mergePolicy?: Partial<MergePolicy> }\n const mp = parsed.mergePolicy\n if (!mp) return SECURE_DEFAULT_POLICY\n return {\n autoMergeEnabled: mp.autoMergeEnabled === true,\n autoPaths: Array.isArray(mp.autoPaths) ? mp.autoPaths.filter(g => typeof g === 'string') : [],\n riskPaths: Array.isArray(mp.riskPaths) ? mp.riskPaths.filter(g => typeof g === 'string') : [],\n }\n }\n catch {\n return SECURE_DEFAULT_POLICY\n }\n}\n","// Reviewer-agent gate (M7). Sits between \"verify passed\" and \"arm the\n// merge\". For code-class changes a second agent reviews the diff and\n// must approve; risk-class changes never auto-merge (human only);\n// chore-class skips review.\n//\n// The actual reviewer-agent dispatch is injected as a `ReviewerFn` so\n// this module stays pure + testable and the heavy second-agent spawn\n// lives in the integration layer.\n\nimport type { MergeDecision } from './merge-policy'\n\nexport interface ReviewVerdict {\n approved: boolean\n reason?: string\n}\n\nexport interface ReviewRequest {\n prRef: string | number\n diff: string\n classification: MergeDecision['classification']\n}\n\nexport type ReviewerFn = (req: ReviewRequest) => Promise<ReviewVerdict>\n\nexport interface GateOutcome {\n // May the agent now arm the (auto-)merge?\n armMerge: boolean\n // Did we stop and hand off to a human?\n awaitingHuman: boolean\n reason: string\n}\n\n// Decide + (when needed) run the reviewer. Branch protection still\n// enforces CI-green server-side regardless of this outcome.\nexport async function gateMerge(\n decision: MergeDecision,\n req: Omit<ReviewRequest, 'classification'>,\n reviewer: ReviewerFn,\n): Promise<GateOutcome> {\n if (decision.needsHuman) {\n return { armMerge: false, awaitingHuman: true, reason: 'risk-path change — handed off to human reviewer' }\n }\n if (!decision.needsReview) {\n // chore/docs — straight to arm-merge (CI still gates server-side).\n return { armMerge: true, awaitingHuman: false, reason: 'chore change — no reviewer gate' }\n }\n // code — require reviewer-agent approval.\n const verdict = await reviewer({ ...req, classification: decision.classification })\n if (verdict.approved) {\n return { armMerge: true, awaitingHuman: false, reason: `reviewer approved${verdict.reason ? `: ${verdict.reason}` : ''}` }\n }\n return { armMerge: false, awaitingHuman: false, reason: `reviewer blocked${verdict.reason ? `: ${verdict.reason}` : ''}` }\n}\n","// Coding-task orchestrator (INT-1). Ties the M1–M7 pieces into one run:\n// issue → worktree → LLM coding loop → verify → PR → merge gate.\n//\n// Division of responsibility (deliberate):\n// - The LLM does the CODING (edit files, run the verify command). It\n// gets file.* / bash / verify tools — NOT forge.pr.merge. Even if it\n// shells `gh pr merge`, that's a high-risk grant the agent doesn't\n// hold a YOLO scope for, so it can't self-merge.\n// - The ORCHESTRATOR owns everything policy-critical: branch + worktree\n// lifecycle, opening the PR, classifying the diff, running the risk\n// assessor + reviewer gate, and arming the merge. The LLM never\n// decides whether to merge.\n//\n// All I/O (shell, runLoop, reviewer, riskAssessor) is injected so the\n// orchestration is unit-testable without a live LLM or git.\n\nimport type { ToolDefinition } from '../agent-tools'\nimport type { RunOptions, RunResult, RuntimeConfig } from '../agent-runtime'\nimport { runLoop } from '../agent-runtime'\nimport { runApeShell } from '../agent-tools/ape-shell-exec'\nimport { buildCreateCommand, worktreePathFor } from '../agent-tools/git-worktree'\nimport { buildPrCreate, buildPrMerge } from './forge'\nimport type { Forge } from './forge'\nimport type { IssueRef, BranchNaming } from './issue-task'\nimport { buildBranchName, buildTaskPrompt } from './issue-task'\nimport { decideMerge, SECURE_DEFAULT_POLICY } from './merge-policy'\nimport type { MergeDecision, MergePolicy, RiskAssessorFn } from './merge-policy'\nimport { gateMerge } from './review-gate'\nimport type { ReviewerFn } from './review-gate'\n\nconst DIFF_CAP = 60 * 1024\n\nexport interface ShellResult { stdout: string, stderr: string, exit_code: number }\nexport type ShellFn = (cmd: string, timeoutMs?: number) => Promise<ShellResult>\n\nexport interface CodingTaskInput {\n issue: IssueRef\n repo: string // URL or $HOME path\n forge: Forge\n}\n\nexport interface CodingTaskDeps {\n runtimeConfig: RuntimeConfig\n // Coding tools given to the LLM (file.*, bash, verify, …) — must NOT\n // include forge.pr.merge.\n tools: ToolDefinition[]\n persona: string\n maxSteps: number\n // Static policy, OR resolvePolicy to load it from the cloned worktree\n // (e.g. the repo's .openape/coding.json + derived signals). When both\n // are absent the secure default applies (auto-merge off).\n policy?: MergePolicy\n resolvePolicy?: (worktree: string) => Promise<MergePolicy>\n reviewer: ReviewerFn\n riskAssessor: RiskAssessorFn\n branchNaming?: BranchNaming\n // Merge strategy + auto behaviour for the PR the orchestrator opens.\n squash?: boolean\n // Injected I/O (defaults wired to production impls).\n shell?: ShellFn\n runLoopImpl?: (opts: RunOptions) => Promise<RunResult>\n log?: (line: string) => void\n}\n\nexport type MergeOutcome = 'auto-armed' | 'awaiting-human' | 'reviewer-blocked' | 'run-failed'\n\nexport interface CodingTaskResult {\n branch: string\n worktree: string\n runStatus: 'ok' | 'error'\n changedFiles: string[]\n decision?: MergeDecision\n outcome: MergeOutcome\n prRef?: string\n reason: string\n}\n\nfunction taskIdFromIssue(issue: IssueRef): string {\n const num = String(issue.number).replace(/\\D/g, '')\n return `issue-${num || 'x'}`\n}\n\nexport async function runCodingTask(input: CodingTaskInput, deps: CodingTaskDeps): Promise<CodingTaskResult> {\n const shell = deps.shell ?? (async (cmd, t) => {\n const r = await runApeShell(cmd, t)\n return { stdout: r.stdout, stderr: r.stderr, exit_code: r.exit_code }\n })\n const loop = deps.runLoopImpl ?? runLoop\n const log = deps.log ?? (() => {})\n\n const branch = buildBranchName(input.issue, deps.branchNaming)\n const taskId = taskIdFromIssue(input.issue)\n const worktree = worktreePathFor(taskId)\n\n // 1. Orchestrator creates the isolated worktree (deterministic path).\n log(`[coding] creating worktree ${worktree} on ${branch}`)\n const wt = await shell(buildCreateCommand(input.repo, taskId, branch))\n if (wt.exit_code !== 0) {\n return { branch, worktree, runStatus: 'error', changedFiles: [], outcome: 'run-failed', reason: `worktree create failed: ${wt.stderr.slice(0, 300)}` }\n }\n\n // Resolve the merge policy from the cloned repo (config + derived\n // signals), or use the static one, or the secure default.\n const policy = deps.resolvePolicy\n ? await deps.resolvePolicy(worktree)\n : (deps.policy ?? SECURE_DEFAULT_POLICY)\n\n // 2. LLM does the coding (it has file.*/bash/verify; NOT pr.merge).\n const prompt = buildTaskPrompt(input.issue, { persona: deps.persona })\n const run = await loop({\n config: deps.runtimeConfig,\n systemPrompt: deps.persona,\n userMessage: `${prompt}\\n\\nWorktree: ${worktree}`,\n tools: deps.tools,\n maxSteps: deps.maxSteps,\n })\n if (run.status !== 'ok') {\n return { branch, worktree, runStatus: 'error', changedFiles: [], outcome: 'run-failed', reason: `coding loop errored after ${run.stepCount} steps` }\n }\n\n // 3. Determine the actual diff (orchestrator, not the LLM's word).\n const namesRes = await shell(`git -C '${worktree}' add -A && git -C '${worktree}' diff --cached --name-only`)\n const changedFiles = namesRes.stdout.split('\\n').map(s => s.trim()).filter(Boolean)\n if (changedFiles.length === 0) {\n return { branch, worktree, runStatus: 'ok', changedFiles: [], outcome: 'run-failed', reason: 'no changes produced — nothing to PR' }\n }\n const diffRes = await shell(`git -C '${worktree}' diff --cached`)\n const diff = diffRes.stdout.slice(0, DIFF_CAP)\n\n // 4. Risk + merge decision (agent judgment ∪ config/derived).\n const agentRisk = await deps.riskAssessor({ paths: changedFiles, diff })\n const decision = decideMerge(changedFiles, policy, agentRisk)\n log(`[coding] decision=${decision.classification} (${decision.reason})`)\n\n // 5. Commit + push + open the PR (orchestrator owns this).\n await shell(`git -C '${worktree}' commit -m ${shqMsg(input.issue)} && git -C '${worktree}' push -u origin '${branch}'`)\n const prCmd = buildPrCreate({ forge: input.forge, title: prTitle(input.issue), body: prBody(input.issue), head: branch })\n const prRes = await shell(`cd '${worktree}' && ${prCmd}`)\n const prRef = (prRes.stdout.match(/\\/pull\\/(\\d+)|!(\\d+)|\\bpr\\/(\\d+)/i)?.slice(1).find(Boolean)) ?? branch\n\n // 6. Merge gate. Human/risk → stop. Code → reviewer. Chore → arm.\n if (decision.needsHuman) {\n return { branch, worktree, runStatus: 'ok', changedFiles, decision, outcome: 'awaiting-human', prRef, reason: decision.reason }\n }\n const gate = await gateMerge(decision, { prRef, diff }, deps.reviewer)\n if (!gate.armMerge) {\n return { branch, worktree, runStatus: 'ok', changedFiles, decision, outcome: 'reviewer-blocked', prRef, reason: gate.reason }\n }\n // Arm merge-when-green (never bypasses required checks — branch protection).\n const mergeCmd = buildPrMerge({ forge: input.forge, ref: prRef, auto: true, squash: deps.squash, deleteBranch: true })\n await shell(`cd '${worktree}' && ${mergeCmd}`)\n return { branch, worktree, runStatus: 'ok', changedFiles, decision, outcome: 'auto-armed', prRef, reason: gate.reason }\n}\n\n// Local helpers (kept here so the file is self-contained).\nfunction prTitle(issue: IssueRef): string {\n return `${issue.type ?? 'fix'}: ${issue.title} (#${String(issue.number).replace(/\\D/g, '')})`\n}\nfunction prBody(issue: IssueRef): string {\n return `Resolves #${String(issue.number).replace(/\\D/g, '')}.\\n\\nAutomated by the OpenApe coding agent.`\n}\nfunction shqMsg(issue: IssueRef): string {\n return `'${prTitle(issue).replace(/'/g, '\\'\\\\\\'\\'')}'`\n}\n","// LLM-backed risk assessor + reviewer (INT-2). These satisfy the\n// injected `RiskAssessorFn` / `ReviewerFn` interfaces with real model\n// calls, so the coding loop's \"is this risky?\" and \"approve this diff?\"\n// decisions are semantic, not glob-only.\n//\n// Fail-safe: if the model errors or returns unparseable output, the\n// assessor treats the change as RISKY and the reviewer BLOCKS — unsure\n// always degrades toward human/no-merge, never toward silent auto-merge.\n\nimport type { RuntimeConfig } from '../agent-runtime'\nimport type { AgentRiskAssessment, RiskAssessorFn } from './merge-policy'\nimport type { ReviewerFn, ReviewVerdict } from './review-gate'\n\nconst DIFF_CAP = 48 * 1024\n\nasync function jsonCompletion(\n config: RuntimeConfig,\n system: string,\n user: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<Record<string, unknown> | null> {\n try {\n const res = await fetchImpl(`${config.apiBase}/chat/completions`, {\n method: 'POST',\n headers: { 'authorization': `Bearer ${config.apiKey}`, 'content-type': 'application/json' },\n body: JSON.stringify({\n model: config.model,\n messages: [{ role: 'system', content: system }, { role: 'user', content: user }],\n response_format: { type: 'json_object' },\n }),\n })\n if (!res.ok) return null\n const data = await res.json() as { choices?: { message?: { content?: string } }[] }\n const content = data.choices?.[0]?.message?.content\n if (!content) return null\n return JSON.parse(content) as Record<string, unknown>\n }\n catch {\n return null\n }\n}\n\nconst RISK_SYSTEM = [\n 'You are a security/risk classifier for an autonomous coding agent.',\n 'Given a diff + changed file paths, decide whether merging it WITHOUT a human is risky.',\n 'Risky = touches authentication, authorization, secrets/credentials, payment, data migrations,',\n 'deploy/release/CI config, cryptography, deletion of data, or anything whose failure is hard to',\n 'reverse in production. Routine code/tests/docs/refactors are NOT risky.',\n 'Respond ONLY as JSON: {\"risky\": boolean, \"reason\": string}.',\n].join(' ')\n\nexport function createLlmRiskAssessor(config: RuntimeConfig, fetchImpl?: typeof fetch): RiskAssessorFn {\n return async ({ paths, diff }): Promise<AgentRiskAssessment> => {\n const user = `Changed files:\\n${paths.join('\\n')}\\n\\nDiff (truncated):\\n${diff.slice(0, DIFF_CAP)}`\n const out = await jsonCompletion(config, RISK_SYSTEM, user, fetchImpl)\n if (!out || typeof out.risky !== 'boolean') {\n return { risky: true, reason: 'risk classifier unavailable/unparseable — treating as risky (fail-safe)' }\n }\n return { risky: out.risky, reason: typeof out.reason === 'string' ? out.reason : undefined }\n }\n}\n\nconst REVIEW_SYSTEM = [\n 'You are a code reviewer for an autonomous coding agent.',\n 'Given a PR diff, decide whether it is correct, safe, and complete enough to auto-merge.',\n 'Approve only if you would be comfortable shipping it without further human review.',\n 'Block if you see bugs, missing tests, security issues, or incomplete work.',\n 'Respond ONLY as JSON: {\"approved\": boolean, \"reason\": string}.',\n].join(' ')\n\nexport function createLlmReviewer(config: RuntimeConfig, fetchImpl?: typeof fetch): ReviewerFn {\n return async ({ prRef, diff }): Promise<ReviewVerdict> => {\n const user = `PR ${String(prRef)} diff (truncated):\\n${diff.slice(0, DIFF_CAP)}`\n const out = await jsonCompletion(config, REVIEW_SYSTEM, user, fetchImpl)\n if (!out || typeof out.approved !== 'boolean') {\n return { approved: false, reason: 'reviewer unavailable/unparseable — blocking (fail-safe)' }\n }\n return { approved: out.approved, reason: typeof out.reason === 'string' ? out.reason : undefined }\n }\n}\n","// Derive risk paths from signals that ALREADY exist in the repo, so\n// nobody maintains a parallel list that rots (M5 follow-up):\n//\n// 1. Deploy-workflow `paths:` filters — the paths whose change ships\n// to prod ARE the real risk surface. You already maintain them.\n// 2. CODEOWNERS — paths with an owner mean \"someone must review\".\n//\n// These AUGMENT (never reduce) the repo's explicit riskPaths and never\n// flip `autoMergeEnabled` on — derivation only makes the risk\n// classification safer, it doesn't enable automation.\n//\n// Parsers are pure + unit-tested. No YAML dependency: we extract just\n// the `paths:` blocks we care about. File reads use node:fs/promises.\n\nimport type { MergePolicy } from './merge-policy'\nimport { loadMergePolicy, SECURE_DEFAULT_POLICY } from './merge-policy'\n\nfunction indentOf(line: string): number {\n return line.length - line.trimStart().length\n}\n\nfunction unquote(s: string): string {\n return s.trim().replace(/^['\"]|['\"]$/g, '').trim()\n}\n\n// Extract globs from `paths:` filters in a GitHub Actions workflow.\n// Handles both block lists and inline arrays. Ignores `paths-ignore:`\n// (that's the inverse of a risk filter).\nexport function extractWorkflowPaths(yamlText: string): string[] {\n const out: string[] = []\n const lines = yamlText.split('\\n')\n let inBlock = false\n let keyIndent = -1\n\n for (const line of lines) {\n if (inBlock) {\n const m = /^\\s*-\\s*(\\S.*)$/.exec(line)\n if (m && indentOf(line) > keyIndent) {\n out.push(unquote(m[1]!))\n continue\n }\n if (line.trim() !== '') inBlock = false // dedented / next key\n }\n // Inline array: `paths: ['a/**', \"b/**\"]`\n const inline = /^\\s*paths:\\s*\\[(.+)\\]\\s*$/.exec(line)\n if (inline) {\n for (const tok of inline[1]!.split(',')) {\n const g = unquote(tok)\n if (g) out.push(g)\n }\n continue\n }\n // Block form: `paths:` then `- glob` lines below.\n if (/^\\s*paths:\\s*$/.test(line)) {\n inBlock = true\n keyIndent = indentOf(line)\n }\n }\n return [...new Set(out)]\n}\n\n// Parse CODEOWNERS path patterns → our glob style. CODEOWNERS lines are\n// `pattern owner...`; we take the pattern. Leading `/` is repo-root\n// anchored (drop it); a trailing `/` means a directory (→ `**`).\nexport function parseCodeowners(text: string): string[] {\n const out: string[] = []\n for (const raw of text.split('\\n')) {\n const line = raw.trim()\n if (!line || line.startsWith('#')) continue\n const pattern = line.split(/\\s+/)[0]\n if (!pattern || pattern.startsWith('@')) continue\n let g = pattern.replace(/^\\//, '')\n if (g.endsWith('/')) g += '**'\n if (g) out.push(g)\n }\n return [...new Set(out)]\n}\n\n// Read the repo's deploy-workflow + CODEOWNERS signals and return the\n// union of derived risk globs. Best-effort: missing files → [].\nexport async function deriveRiskGlobs(worktreeDir: string): Promise<string[]> {\n const { readFile, readdir } = await import('node:fs/promises')\n const { join } = await import('node:path')\n const globs = new Set<string>()\n\n // 1. deploy-*.yml workflows\n try {\n const wfDir = join(worktreeDir, '.github', 'workflows')\n const files = await readdir(wfDir)\n for (const f of files) {\n if (!/deploy.*\\.ya?ml$/i.test(f)) continue\n try {\n const text = await readFile(join(wfDir, f), 'utf8')\n for (const g of extractWorkflowPaths(text)) globs.add(g)\n }\n catch { /* unreadable file — skip */ }\n }\n }\n catch { /* no workflows dir */ }\n\n // 2. CODEOWNERS (common locations)\n for (const loc of ['.github/CODEOWNERS', 'CODEOWNERS', 'docs/CODEOWNERS']) {\n try {\n const text = await readFile(join(worktreeDir, loc), 'utf8')\n for (const g of parseCodeowners(text)) globs.add(g)\n break\n }\n catch { /* try next */ }\n }\n\n return [...globs]\n}\n\n// The main entry the orchestration uses: explicit `.openape/coding.json`\n// policy, with risk paths AUGMENTED by derived signals. autoMergeEnabled\n// + autoPaths come solely from explicit config (derivation never enables\n// automation).\nexport async function resolveMergePolicy(worktreeDir: string): Promise<MergePolicy> {\n const explicit = await loadMergePolicy(worktreeDir).catch(() => SECURE_DEFAULT_POLICY)\n const derived = await deriveRiskGlobs(worktreeDir).catch(() => [])\n return {\n autoMergeEnabled: explicit.autoMergeEnabled,\n autoPaths: explicit.autoPaths,\n riskPaths: [...new Set([...explicit.riskPaths, ...derived])],\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs'\nimport { tmpdir, userInfo } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError, CliExit } from '../../errors'\nimport { apiFetch } from '../../http'\nimport { AGENT_NAME_REGEX, buildDestroyTeardownScript, runPhaseGTeardownInProcess } from '../../lib/agent-bootstrap'\nimport { isDarwin, lookupMacOSUserForAgent, macOSUsernameForAgent, whichBinary } from '../../lib/macos-user'\nimport { removeNestAgent } from '../../lib/nest-registry'\nimport { readPasswordSilent } from '../../lib/silent-password'\n\ninterface IdpUser {\n email: string\n name: string\n owner: string | null\n isActive: boolean\n}\n\nexport const destroyAgentCommand = defineCommand({\n meta: {\n name: 'destroy',\n description: 'Tear down an agent: remove macOS user, hard-delete IdP agent, drop all SSH keys',\n },\n args: {\n name: {\n type: 'positional',\n description: 'Agent name to destroy',\n required: true,\n },\n force: {\n type: 'boolean',\n description: 'Skip the interactive confirmation. Required for CI.',\n },\n soft: {\n type: 'boolean',\n description: 'Soft deactivate at the IdP (PATCH isActive=false) instead of hard-delete',\n },\n 'keep-os-user': {\n type: 'boolean',\n description: 'Skip OS-side teardown. Useful for CI where the agent has no OS user.',\n },\n 'root-stage': {\n type: 'boolean',\n description: 'Internal — 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.',\n },\n },\n async run({ args }) {\n const name = args.name as string\n if (!AGENT_NAME_REGEX.test(name)) {\n throw new CliError(\n `Invalid agent name \"${name}\". Must match /^[a-z][a-z0-9-]{0,23}$/.`,\n )\n }\n\n // Inner re-entry: this process IS root (escapes-setuid'd via the\n // outer `apes run --as root --`). Skip auth + IdP + prompts and\n // just do the privileged ops. The outer pass already removed the\n // IdP record and the nest-registry row by the time it called us.\n if (args['root-stage']) {\n if (process.geteuid?.() !== 0) {\n throw new CliError('--root-stage was passed but this process is not running as root. Refusing to continue.')\n }\n const resolved = lookupMacOSUserForAgent(name)\n const macOSUsername = resolved?.name ?? macOSUsernameForAgent(name)\n const homeDir = resolved?.homeDir ?? `/var/openape/homes/${macOSUsername}`\n consola.start(`Running teardown for ${name} (Phase-G, root-stage)…`)\n runPhaseGTeardownInProcess({ name, homeDir, macOSUsername })\n return\n }\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const owned = await apiFetch<IdpUser[]>('/api/my-agents', { idp })\n const idpAgent = owned.find(u => u.name === name)\n const idpExists = idpAgent !== undefined\n\n const osUser = isDarwin() ? lookupMacOSUserForAgent(name) : null\n const osUserExists = !args['keep-os-user'] && osUser !== null\n\n if (!idpExists && !osUserExists) {\n consola.info(`Nothing to destroy: no IdP agent and no OS user for \"${name}\".`)\n return\n }\n\n if (!args.force) {\n const consequences: string[] = []\n if (osUserExists) {\n const home = osUser?.homeDir ?? `/Users/${name}`\n consequences.push(`• Remove macOS user ${osUser?.name ?? name} and rm -rf ${home}`)\n }\n if (idpExists) {\n consequences.push(args.soft\n ? `• Deactivate IdP agent ${idpAgent!.email} (PATCH isActive=false)`\n : `• Hard-delete IdP agent ${idpAgent!.email} and all its SSH keys`)\n }\n consola.warn(`About to destroy \"${name}\":\\n${consequences.join('\\n')}`)\n // Without a TTY, consola.prompt would crash with `uv_tty_init returned\n // EINVAL` and leave the user with an opaque stack trace. Detect and\n // refuse with a clear hint instead — `--force` is the explicit\n // non-interactive path (CI, subprocess invocations, this script's\n // own caller when piped).\n if (!process.stdin.isTTY) {\n throw new CliError(\n 'No TTY available for the interactive confirmation. Re-run with --force '\n + 'to skip the prompt (this is the same flag CI uses).',\n )\n }\n const confirmed = await consola.prompt('Proceed?', { type: 'confirm', initial: false })\n if (typeof confirmed === 'symbol' || !confirmed) {\n throw new CliExit(0)\n }\n }\n\n // IdP-side first so the parent's bearer is still fresh. The sudo step\n // below blocks for the password prompt, which the user might take a\n // moment to complete — running the IdP DELETE after a stale-token\n // window would leave the agent record orphaned.\n if (idpExists) {\n const id = encodeURIComponent(idpAgent!.email)\n if (args.soft) {\n await apiFetch(`/api/my-agents/${id}`, { method: 'PATCH', body: { isActive: false }, idp })\n consola.success(`Deactivated IdP agent ${idpAgent!.email}`)\n }\n else {\n await apiFetch(`/api/my-agents/${id}`, { method: 'DELETE', idp })\n consola.success(`Deleted IdP agent ${idpAgent!.email}`)\n }\n }\n else {\n consola.info('No IdP agent to remove (skipped).')\n }\n\n if (osUserExists) {\n const macOSUsername = osUser?.name ?? macOSUsernameForAgent(name)\n // Fallback path depends on which dscl record we matched:\n // legacy bare-name records live under /Users/<name>, new\n // prefixed records under /var/openape/homes/<macOSUsername>.\n // The dscl record's NFSHomeDirectory is the source of truth\n // when present; the fallback only fires when it's missing\n // (mostly fixture-driven test paths).\n const fallbackHome = macOSUsername.startsWith('openape-agent-')\n ? `/var/openape/homes/${macOSUsername}`\n : `/Users/${macOSUsername}`\n const homeDir = osUser?.homeDir ?? fallbackHome\n const isPhaseG = homeDir.startsWith('/var/openape/homes/')\n\n if (isPhaseG) {\n // Phase G agents live under /var/openape/homes/ — root via\n // escapes can `rm -rf` the home (no FDA wall on /var/) and\n // bootout the user-domain launchd. The dscl record removal\n // still needs sysadminctl + admin password (escapes' setuid\n // context lacks an audit session, opendirectoryd rejects a\n // plain `dscl . -delete`), so we skip it: the user record\n // becomes a harmless tombstone — uid in the hidden range,\n // IsHidden=1, NFSHomeDirectory pointing at a path that no\n // longer exists. Operators can run `sudo sysadminctl\n // -deleteUser <name>` interactively later if they want full\n // cleanup.\n //\n // Re-enter ourselves as root via `apes run --as root --`\n // instead of writing+executing a temp bash script. The\n // resulting DDISA grant request reads\n // `apes agents destroy <name> --force --root-stage`\n // which is semantic + matches the existing nest YOLO pattern\n // `apes agents destroy *` for zero-prompt auto-approval.\n // The inner re-entry detects --root-stage and runs just the\n // Phase-G teardown ops via runPhaseGTeardownInProcess().\n if (process.geteuid?.() === 0) {\n // Already root (rare — `apes agents destroy` invoked from\n // inside a setuid-root context like a CI runner with\n // sudo). Do the teardown directly, no second escalation.\n consola.start('Running teardown (Phase G — already root, no grant needed)…')\n runPhaseGTeardownInProcess({ name, homeDir, macOSUsername })\n }\n else {\n consola.start('Running teardown (Phase G — no admin password needed)…')\n execFileSync('apes', [\n 'run', '--as', 'root', '--wait', '--',\n 'apes', 'agents', 'destroy', name, '--force', '--root-stage',\n ], { stdio: 'inherit' })\n }\n consola.info(`dscl record /Users/${macOSUsername} kept as tombstone (hidden, no home). Run \\`sudo apes agents cleanup-orphans\\` to sweep accumulated tombstones.`)\n }\n else {\n // Legacy path: home under /Users/, FDA-blocked. Need sudo\n // + admin password to invoke sysadminctl. If we're running\n // headless (no TTY, no APES_ADMIN_PASSWORD) — typical for the\n // troop-WS destroy path from the nest — degrade gracefully:\n // skip the OS-side teardown so the rest of the destroy still\n // proceeds (IdP de-register + nest-registry removal). The\n // dscl record + home dir become orphans; operator cleans up\n // later interactively with `apes agents destroy` from a shell.\n const sudo = whichBinary('sudo')\n if (!sudo) {\n throw new CliError('`sudo` not found on PATH; required for OS teardown.')\n }\n const adminUser = userInfo().username\n let adminPassword: string\n try {\n adminPassword = await collectAdminPassword({ adminUser })\n }\n catch (err) {\n const headless = !process.stdin.isTTY && !process.env.APES_ADMIN_PASSWORD\n if (headless) {\n consola.warn(`Legacy OS teardown for ${name} requires a TTY or APES_ADMIN_PASSWORD; skipping. Run \\`apes agents destroy ${name}\\` from a shell later to fully clean up /Users/${name} + dscl record.`)\n adminPassword = ''\n }\n else {\n throw err\n }\n }\n if (adminPassword) {\n const scratch = mkdtempSync(join(tmpdir(), `apes-destroy-${name}-`))\n const scriptPath = join(scratch, 'teardown.sh')\n try {\n const script = buildDestroyTeardownScript({ name, homeDir, adminUser })\n writeFileSync(scriptPath, script, { mode: 0o700 })\n consola.start('Running teardown via sudo…')\n execFileSync(sudo, ['-S', '--prompt=', '--', 'bash', scriptPath], {\n input: `${adminPassword}\\n${adminPassword}\\n`,\n stdio: ['pipe', 'inherit', 'inherit'],\n })\n }\n finally {\n rmSync(scratch, { recursive: true, force: true })\n }\n }\n }\n }\n else if (!args['keep-os-user'] && isDarwin()) {\n consola.info('No macOS user to remove (skipped).')\n }\n\n // Phase F: drop the entry from the Nest's registry. The Nest's\n // file-watcher reconciles its pm2-supervisor → bridge gets pm2-\n // deleted automatically.\n try { removeNestAgent(name) }\n catch (err) {\n consola.warn(`Could not update nest registry: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n consola.success(`Destroyed ${name}.`)\n },\n})\n\n/**\n * Resolve the local admin password used for sudo + `sysadminctl\n * -deleteUser`. Single secret, single prompt:\n *\n * 1. `APES_ADMIN_PASSWORD` env var (CI / orchestrators)\n * 2. Silent terminal prompt (raw-mode stdin, no echo, no mask)\n * 3. Refuse with a clear hint when neither is available\n */\nasync function collectAdminPassword(opts: { adminUser: string }): Promise<string> {\n const fromEnv = process.env.APES_ADMIN_PASSWORD\n if (fromEnv && fromEnv.length > 0) return fromEnv\n const pw = await readPasswordSilent(`Password for ${opts.adminUser}: `)\n if (pw.length === 0) {\n throw new CliExit(0)\n }\n return pw\n}\n","// Shared \"Nest registry\" helper — Phase F (#sim-arch) lets the\n// apes-cli read+write the Nest's `agents.json` directly instead of\n// going through an intent-channel handler in the Nest. The Nest\n// watches the file and reconciles its pm2-supervisor automatically.\n//\n// The registry is the source of truth for \"which agents live on\n// this computer\" — the Nest reads it at boot and after every fs\n// change, the apes-cli writes to it after every `apes agents\n// spawn|destroy`.\n//\n// Path: `/var/openape/nest/agents.json` (mode 660, owner\n// `_openape_nest:_openape_nest`). Patrick is in the\n// `_openape_nest` group post-`apes nest migrate-to-service-user`,\n// so he can rw the file directly. Pre-migration installs use\n// `~/.openape/nest/agents.json` under the human's home and don't\n// need the group dance — the file is plain Patrick-owned.\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport interface AgentEntry {\n name: string\n uid: number\n home: string\n email: string\n registeredAt: number\n bridge?: {\n baseUrl?: string\n apiKey?: string\n model?: string\n }\n}\n\ninterface RegistryFile {\n version: 1\n agents: AgentEntry[]\n}\n\n/** Resolve the registry path. Prefers the post-migration system\n * location; falls back to the per-user location otherwise. */\nexport function resolveRegistryPath(): string {\n if (existsSync('/var/openape/nest/agents.json')) return '/var/openape/nest/agents.json'\n if (existsSync('/var/openape/nest')) return '/var/openape/nest/agents.json'\n return join(homedir(), '.openape', 'nest', 'agents.json')\n}\n\nfunction emptyRegistry(): RegistryFile {\n return { version: 1, agents: [] }\n}\n\nexport function readNestRegistry(): RegistryFile {\n const path = resolveRegistryPath()\n if (!existsSync(path)) return emptyRegistry()\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as RegistryFile\n if (parsed?.version !== 1 || !Array.isArray(parsed.agents)) return emptyRegistry()\n return parsed\n }\n catch {\n return emptyRegistry()\n }\n}\n\nexport function writeNestRegistry(reg: RegistryFile): void {\n const path = resolveRegistryPath()\n const dir = path.replace(/\\/agents\\.json$/, '')\n try { mkdirSync(dir, { recursive: true }) }\n catch { /* may exist with stricter perms */ }\n writeFileSync(path, `${JSON.stringify(reg, null, 2)}\\n`, { mode: 0o660 })\n}\n\nexport function upsertNestAgent(entry: AgentEntry): void {\n const reg = readNestRegistry()\n const existing = reg.agents.findIndex(a => a.name === entry.name)\n if (existing >= 0) reg.agents[existing] = entry\n else reg.agents.push(entry)\n writeNestRegistry(reg)\n}\n\nexport function removeNestAgent(name: string): boolean {\n const reg = readNestRegistry()\n const before = reg.agents.length\n reg.agents = reg.agents.filter(a => a.name !== name)\n if (reg.agents.length === before) return false\n writeNestRegistry(reg)\n return true\n}\n","// Silent password input using raw-mode stdin. consola.prompt's `mask`\n// option is honoured by some terminals (iTerm, Terminal.app) but ignored\n// by others (Warp, some VT-emulator wrappers) — falling back to plain\n// echoed text. Native readline with raw mode + manual character handling\n// works uniformly: stdin is muted (no echo) and we render exactly what\n// the user has come to expect from `sudo` / `ssh-keygen -p` / etc — the\n// prompt label, no mask, just the trailing newline once Enter is hit.\n\nimport { CliError } from '../errors'\n\n/**\n * Prompt for a password without echoing keystrokes. Resolves with the\n * typed string (without trailing newline). Throws `CliError` on Ctrl-C\n * / Ctrl-D / non-TTY stdin.\n */\nexport function readPasswordSilent(prompt: string): Promise<string> {\n if (!process.stdin.isTTY) {\n return Promise.reject(new CliError(\n 'No TTY available for the silent password prompt. '\n + 'Set APES_ADMIN_PASSWORD in the environment instead.',\n ))\n }\n return new Promise<string>((resolve, reject) => {\n process.stdout.write(prompt)\n const wasRaw = process.stdin.isRaw ?? false\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.setEncoding('utf8')\n\n let buf = ''\n let cleanupFn: (() => void) | undefined\n const cleanup = () => cleanupFn?.()\n const onData = (chunk: string) => {\n for (const ch of chunk) {\n const code = ch.charCodeAt(0)\n if (ch === '\\r' || ch === '\\n') {\n cleanup()\n process.stdout.write('\\n')\n resolve(buf)\n return\n }\n if (code === 3) { // Ctrl-C\n cleanup()\n process.stdout.write('\\n')\n reject(new CliError('Aborted by user (Ctrl-C).'))\n return\n }\n if (code === 4 && buf.length === 0) { // Ctrl-D on empty\n cleanup()\n process.stdout.write('\\n')\n reject(new CliError('Aborted by user (Ctrl-D).'))\n return\n }\n if (code === 0x7F || code === 8) { // DEL / backspace\n if (buf.length > 0) buf = buf.slice(0, -1)\n continue\n }\n if (code < 32) continue // ignore other control chars\n buf += ch\n }\n }\n cleanupFn = () => {\n process.stdin.removeListener('data', onData)\n process.stdin.setRawMode(wasRaw)\n process.stdin.pause()\n }\n process.stdin.on('data', onData)\n })\n}\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport { apiFetch } from '../../http'\nimport { isDarwin, listMacOSUserNames, lookupMacOSUserForAgent, macOSUsernameForAgent } from '../../lib/macos-user'\n\ninterface IdpUser {\n email: string\n name: string\n owner: string | null\n approver: string | null\n type: string | null\n isActive: boolean\n createdAt: number\n}\n\nexport const listAgentsCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List agents owned by the current user, with local OS-user status',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n },\n 'include-inactive': {\n type: 'boolean',\n description: 'Include agents whose IdP record is deactivated (default hides them)',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const all = await apiFetch<IdpUser[]>('/api/my-agents', { idp })\n const filtered = args['include-inactive']\n ? all\n : all.filter(u => u.isActive !== false)\n\n const osUsers = isDarwin() ? listMacOSUserNames() : new Set<string>()\n // Resolve macOS state per agent, checking both the prefixed\n // (`openape-agent-<name>`) and bare (`<name>`) dscl records so\n // legacy pre-prefix agents keep showing up in the table.\n const osStateOf = (agentName: string): { osUser: boolean, home: string | null } => {\n const u = lookupMacOSUserForAgent(agentName)\n if (u) return { osUser: true, home: u.homeDir }\n // listMacOSUserNames covers ad-hoc records that dscl-read can't see\n // (e.g. names with unusual characters) — keep it as a sentinel.\n if (osUsers.has(macOSUsernameForAgent(agentName)) || osUsers.has(agentName)) {\n return { osUser: true, home: null }\n }\n return { osUser: false, home: null }\n }\n\n const rows = filtered.map((u) => {\n const os = osStateOf(u.name)\n return {\n name: u.name,\n email: u.email,\n isActive: u.isActive !== false,\n osUser: os.osUser,\n home: os.home,\n }\n })\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(rows, null, 2)}\\n`)\n return\n }\n\n if (rows.length === 0) {\n consola.info(args['include-inactive'] ? 'No agents found.' : 'No active agents found. Use --include-inactive to show deactivated.')\n return\n }\n\n const nameW = Math.max(4, ...rows.map(r => r.name.length))\n const emailW = Math.max(5, ...rows.map(r => r.email.length))\n const header = `${'NAME'.padEnd(nameW)} ${'EMAIL'.padEnd(emailW)} ACTIVE OS-USER HOME`\n console.log(header)\n console.log('-'.repeat(header.length))\n for (const r of rows) {\n const active = r.isActive ? '✓' : '✗'\n const os = r.osUser ? '✓' : '✗'\n const homeCol = r.home ?? (isDarwin() ? '(missing)' : '(non-darwin)')\n console.log(`${r.name.padEnd(nameW)} ${r.email.padEnd(emailW)} ${active.padEnd(6)} ${os.padEnd(7)} ${homeCol}`)\n }\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport { AGENT_NAME_REGEX, registerAgentAtIdp, SSH_ED25519_PREFIX, SSH_ED25519_REGEX } from '../../lib/agent-bootstrap'\n\nexport const registerAgentCommand = defineCommand({\n meta: {\n name: 'register',\n description: 'Register an agent at the IdP using a supplied public key',\n },\n args: {\n name: {\n type: 'string',\n description: 'Agent name (lowercase, [a-z0-9-], 1–24 chars, must start with a letter)',\n required: true,\n },\n 'public-key': {\n type: 'string',\n description: 'Full ssh-ed25519 public key line (e.g. \"ssh-ed25519 AAAAC3...\")',\n },\n 'public-key-file': {\n type: 'string',\n description: 'Path to a .pub file containing the ssh-ed25519 line',\n },\n json: {\n type: 'boolean',\n description: 'Emit machine-readable JSON instead of a human summary',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const name = args.name\n if (!AGENT_NAME_REGEX.test(name)) {\n throw new CliError(\n `Invalid agent name \"${name}\". Must match /^[a-z][a-z0-9-]{0,23}$/ — `\n + `lowercase letters, digits and hyphens, 1–24 chars, must start with a letter.`,\n )\n }\n\n let publicKey: string | undefined = args['public-key']\n const keyFile = args['public-key-file']\n\n if (publicKey && keyFile) {\n throw new CliError('Pass either --public-key or --public-key-file, not both.')\n }\n\n if (!publicKey && keyFile) {\n if (!existsSync(keyFile)) {\n throw new CliError(`Public-key file not found: ${keyFile}`)\n }\n publicKey = readFileSync(keyFile, 'utf-8').trim()\n }\n\n if (!publicKey) {\n throw new CliError('Provide --public-key \"<ssh-ed25519 line>\" or --public-key-file <path>.')\n }\n\n if (!publicKey.startsWith(SSH_ED25519_PREFIX) || !SSH_ED25519_REGEX.test(publicKey)) {\n throw new CliError(\n 'Public key must be a full ssh-ed25519 line, e.g. '\n + '\"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... [optional comment]\".',\n )\n }\n\n const result = await registerAgentAtIdp({ name, publicKey, idp })\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify({\n email: result.email,\n name: result.name,\n owner: result.owner,\n approver: result.approver,\n idp,\n })}\\n`)\n return\n }\n\n consola.success('Agent registered.')\n console.log(` Name: ${result.name}`)\n console.log(` Email: ${result.email}`)\n console.log(` IdP: ${idp}`)\n console.log(` Owner: ${result.owner}`)\n console.log(` Approver: ${result.approver}`)\n console.log('')\n console.log('Tell the agent to log in with:')\n console.log(` apes login --idp ${idp} --email ${result.email} --key <path-to-matching-private-key>`)\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { taskTools } from '../../lib/agent-tools'\nimport { runLoop } from '../../lib/agent-runtime'\nimport type { RuntimeConfig } from '../../lib/agent-runtime'\nimport { materializeSecrets } from '../../lib/agent-secrets-runtime'\nimport { resolveTroopUrl, TroopClient } from '../../lib/troop-client'\nimport type { TaskSpec } from '../../lib/troop-client'\n\nconst AUTH_PATH = join(homedir(), '.config', 'apes', 'auth.json')\nconst TASK_CACHE_DIR = join(homedir(), '.openape', 'agent', 'tasks')\n\ninterface AuthJson { access_token: string, email: string, owner_email?: string }\n\nfunction readAuth(): AuthJson {\n if (!existsSync(AUTH_PATH)) {\n throw new CliError(`No agent auth found at ${AUTH_PATH}. Run \\`apes agents spawn <name>\\` first.`)\n }\n const parsed = JSON.parse(readFileSync(AUTH_PATH, 'utf8')) as AuthJson\n if (!parsed.access_token) throw new CliError('auth.json missing access_token')\n return parsed\n}\n\n/**\n * Post the run result as a chat DM from the agent to its owner. Best-\n * effort: any failure (no room yet because owner hasn't accepted the\n * contact request, chat down, network, …) just logs and returns. The\n * run record on troop is still authoritative; the chat DM is the\n * convenience surface so the owner sees the answer in the same\n * conversation thread they'd expect to ask about it.\n */\nasync function postRunResultToChat(opts: {\n authToken: string\n ownerEmail: string\n taskName: string\n status: 'ok' | 'error'\n stepCount: number\n finalMessage: string | null\n endpoint?: string\n}): Promise<void> {\n const endpoint = (opts.endpoint ?? process.env.APE_CHAT_ENDPOINT ?? 'https://chat.openape.ai').replace(/\\/$/, '')\n try {\n // Find the room with the owner. The bridge sets up the contact\n // relationship on first boot — if the owner hasn't accepted yet,\n // there's no room and we silently no-op.\n const contactsRes = await fetch(`${endpoint}/api/contacts`, {\n headers: { Authorization: `Bearer ${opts.authToken}` },\n })\n if (!contactsRes.ok) return\n const contacts = await contactsRes.json() as Array<{ peerEmail: string, roomId: string | null, connected: boolean }>\n const ownerLower = opts.ownerEmail.toLowerCase()\n const ownerRow = contacts.find(c => c.peerEmail.toLowerCase() === ownerLower && c.connected && c.roomId)\n if (!ownerRow?.roomId) {\n consola.info('chat DM skipped — no active room with owner (accept the contact request in chat to enable)')\n return\n }\n const prefix = opts.status === 'ok' ? '✅' : '❌'\n const msg = opts.finalMessage?.trim() || (opts.status === 'ok' ? '(no output)' : '(crashed)')\n const body = `${prefix} *${opts.taskName}* (${opts.stepCount} steps)\\n\\n${msg}`.slice(0, 9000)\n const postRes = await fetch(`${endpoint}/api/rooms/${encodeURIComponent(ownerRow.roomId)}/messages`, {\n method: 'POST',\n headers: { 'Authorization': `Bearer ${opts.authToken}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ body }),\n })\n if (!postRes.ok) {\n consola.warn(`chat DM post failed: ${postRes.status}`)\n }\n }\n catch (err) {\n consola.warn(`chat DM error: ${(err as Error).message}`)\n }\n}\n\nfunction readTaskSpec(taskId: string): TaskSpec {\n const path = join(TASK_CACHE_DIR, `${taskId}.json`)\n if (!existsSync(path)) {\n throw new CliError(`No cached task spec at ${path}. Run \\`apes agents sync\\` first to pull the task list from troop.`)\n }\n return JSON.parse(readFileSync(path, 'utf8')) as TaskSpec\n}\n\ninterface AgentJson { systemPrompt: string }\nconst AGENT_CONFIG_PATH = join(homedir(), '.openape', 'agent', 'agent.json')\n\n/**\n * Read the cached agent-level config (systemPrompt). Falls back to an\n * empty systemPrompt if the file is missing — older agents written\n * before the system-prompt refactor (#346) won't have one yet, and the\n * next sync will create it. Empty systemPrompt is fine: the runtime\n * just sends the user message with no system message.\n */\nfunction readAgentConfig(): AgentJson {\n if (!existsSync(AGENT_CONFIG_PATH)) return { systemPrompt: '' }\n try { return JSON.parse(readFileSync(AGENT_CONFIG_PATH, 'utf8')) as AgentJson }\n catch { return { systemPrompt: '' } }\n}\n\nfunction readLitellmConfig(model?: string): RuntimeConfig {\n // ~/litellm/.env carries LITELLM_API_KEY (or LITELLM_MASTER_KEY) +\n // LITELLM_BASE_URL — same file `apes agents spawn` writes during\n // the bridge bootstrap. The agent's macOS user owns the file.\n const envPath = join(homedir(), 'litellm', '.env')\n const env: Record<string, string> = {}\n if (existsSync(envPath)) {\n for (const line of readFileSync(envPath, 'utf8').split(/\\r?\\n/)) {\n const m = line.match(/^([A-Z_]+)=(.*)$/)\n if (m) env[m[1]!] = m[2]!.replace(/^[\"']|[\"']$/g, '')\n }\n }\n // Allow process.env to override (tests + ad-hoc dev).\n for (const k of ['LITELLM_API_KEY', 'LITELLM_MASTER_KEY', 'LITELLM_BASE_URL']) {\n if (process.env[k]) env[k] = process.env[k]!\n }\n const apiKey = env.LITELLM_API_KEY || env.LITELLM_MASTER_KEY\n const apiBase = (env.LITELLM_BASE_URL || 'http://127.0.0.1:4000/v1').replace(/\\/$/, '')\n if (!apiKey) {\n throw new CliError('No LITELLM_API_KEY / LITELLM_MASTER_KEY in ~/litellm/.env or env.')\n }\n return { apiBase, apiKey, model: model || 'claude-haiku-4-5' }\n}\n\nexport const runAgentCommand = defineCommand({\n meta: {\n name: 'run',\n description: 'Execute one task (typically launchd-invoked). Reports the run record to troop.',\n },\n args: {\n 'task-id': {\n type: 'positional',\n description: 'Task ID (slug) to run. The cached spec at ~/.openape/agent/tasks/<id>.json is used.',\n required: true,\n },\n 'troop-url': {\n type: 'string',\n description: 'Override troop SP base URL.',\n },\n 'model': {\n type: 'string',\n description: 'Override the LLM model name. Default: claude-haiku-4-5.',\n },\n },\n async run({ args }) {\n const taskId = args['task-id'] as string\n const auth = readAuth()\n // Inject any capability secrets troop sealed to this agent before\n // the task runs, so the agent's tools see them in process.env.\n materializeSecrets({ log: l => consola.info(l) })\n const spec = readTaskSpec(taskId)\n const agentCfg = readAgentConfig()\n const config = readLitellmConfig(args.model as string | undefined)\n\n let tools: ReturnType<typeof taskTools>\n try { tools = taskTools(spec.tools) }\n catch (err) {\n // Don't even POST a run record — task is structurally broken.\n // Surfaced via launchd's StandardErrorPath log; the next sync\n // pulls a fresh spec which may have the typo fixed.\n throw new CliError(`task ${taskId}: ${(err as Error).message}`)\n }\n\n const troop = new TroopClient(resolveTroopUrl(args['troop-url'] as string | undefined), auth.access_token)\n const { id: runId } = await troop.startRun(taskId)\n consola.info(`Run ${runId} started for task ${taskId}`)\n\n try {\n const result = await runLoop({\n config,\n // Agent persona/behaviour (\"you are Igor, …\") set at agent level;\n // the task's userPrompt is the imperative job (\"read my mail and\n // summarise\"). The cron firing is the trigger — the message body\n // is the task itself.\n systemPrompt: agentCfg.systemPrompt,\n userMessage: spec.userPrompt,\n tools,\n maxSteps: spec.maxSteps,\n })\n\n await troop.finaliseRun(runId, {\n status: result.status,\n final_message: result.finalMessage,\n step_count: result.stepCount,\n trace: result.trace,\n })\n consola.success(`Run ${runId} ${result.status} (${result.stepCount} steps)`)\n if (auth.owner_email) {\n await postRunResultToChat({\n authToken: auth.access_token,\n ownerEmail: auth.owner_email,\n taskName: spec.name,\n status: result.status,\n stepCount: result.stepCount,\n finalMessage: result.finalMessage,\n })\n }\n if (result.status === 'error') process.exit(1)\n }\n catch (err) {\n const message = (err as Error)?.message ?? String(err)\n await troop.finaliseRun(runId, {\n status: 'error',\n final_message: message.slice(0, 4000),\n step_count: 0,\n trace: [],\n }).catch(() => { /* best-effort */ })\n if (auth.owner_email) {\n await postRunResultToChat({\n authToken: auth.access_token,\n ownerEmail: auth.owner_email,\n taskName: spec.name,\n status: 'error',\n stepCount: 0,\n finalMessage: message,\n })\n }\n throw new CliError(`Run ${runId} crashed: ${message}`)\n }\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { createInterface } from 'node:readline'\nimport { defineCommand } from 'citty'\nimport { CliError } from '../../errors'\nimport { taskTools } from '../../lib/agent-tools'\nimport { runLoop, RpcSessionMap } from '../../lib/agent-runtime'\nimport type { RuntimeConfig } from '../../lib/agent-runtime'\nimport { startSecretsWatcher } from '../../lib/agent-secrets-runtime'\n\n// `apes agents serve --rpc` — long-running stdio JSON server.\n// Replaces `pi --mode rpc` for chat-bridge's per-room subprocesses.\n// Each inbound line is a JSON object describing a single message;\n// outbound is a stream of text_delta / tool_call / tool_result /\n// done / error events. Sessions keyed by `session_id` keep\n// per-conversation memory across messages.\n//\n// The chat-bridge package owns the policy of \"which model, which\n// system prompt, which tools\" — the runtime is purely the executor.\n\ninterface InboundMessage {\n type?: 'message'\n session_id: string\n system_prompt: string\n tools: string[]\n max_steps?: number\n model?: string\n user_msg: string\n}\n\ninterface AuthJson { access_token: string, email: string }\n\nconst AUTH_PATH = join(homedir(), '.config', 'apes', 'auth.json')\n\nfunction readLitellmConfig(model?: string): RuntimeConfig {\n const envPath = join(homedir(), 'litellm', '.env')\n const env: Record<string, string> = {}\n if (existsSync(envPath)) {\n for (const line of readFileSync(envPath, 'utf8').split(/\\r?\\n/)) {\n const m = line.match(/^([A-Z_]+)=(.*)$/)\n if (m) env[m[1]!] = m[2]!.replace(/^[\"']|[\"']$/g, '')\n }\n }\n for (const k of ['LITELLM_API_KEY', 'LITELLM_MASTER_KEY', 'LITELLM_BASE_URL']) {\n if (process.env[k]) env[k] = process.env[k]!\n }\n const apiKey = env.LITELLM_API_KEY || env.LITELLM_MASTER_KEY\n const apiBase = (env.LITELLM_BASE_URL || 'http://127.0.0.1:4000/v1').replace(/\\/$/, '')\n if (!apiKey) throw new CliError('No LITELLM_API_KEY / LITELLM_MASTER_KEY in ~/litellm/.env or env.')\n return { apiBase, apiKey, model: model || 'claude-haiku-4-5' }\n}\n\nfunction emit(event: Record<string, unknown>): void {\n process.stdout.write(`${JSON.stringify(event)}\\n`)\n}\n\nexport const serveAgentCommand = defineCommand({\n meta: {\n name: 'serve',\n description: 'Long-running stdio RPC server for chat-bridge subprocess use.',\n },\n args: {\n rpc: {\n type: 'boolean',\n description: 'Use the line-delimited JSON RPC protocol on stdio (the only mode for now).',\n },\n },\n async run({ args }) {\n if (!args.rpc) {\n throw new CliError('apes agents serve currently only supports --rpc mode')\n }\n if (existsSync(AUTH_PATH)) {\n // We don't actually use the agent JWT in serve mode — the bridge\n // is the only caller and it talks to chat.openape.ai itself —\n // but reading auth.json is a sanity check that we're running\n // as a troop-spawned agent user, not stray.\n try { JSON.parse(readFileSync(AUTH_PATH, 'utf8')) as AuthJson }\n catch { /* tolerate */ }\n }\n\n // Materialize capability secrets and keep them live: troop can\n // rotate/revoke while this long-running process is up (M2 v1\n // live-hotswap). Log to stderr — stdout is the RPC channel.\n const stopSecrets = startSecretsWatcher({ log: l => process.stderr.write(`${l}\\n`) })\n\n const sessions = new RpcSessionMap()\n const evictTimer = setInterval(() => sessions.evictStale(), 5 * 60 * 1000)\n process.on('exit', () => { clearInterval(evictTimer); stopSecrets() })\n\n const rl = createInterface({ input: process.stdin, terminal: false })\n rl.on('line', async (line) => {\n const trimmed = line.trim()\n if (!trimmed) return\n let msg: InboundMessage\n try { msg = JSON.parse(trimmed) as InboundMessage }\n catch (err) {\n emit({ type: 'error', message: `invalid JSON: ${(err as Error).message}` })\n return\n }\n if (!msg.session_id || !msg.user_msg) {\n emit({ type: 'error', message: 'session_id and user_msg are required' })\n return\n }\n try {\n await handleInbound(msg, sessions)\n }\n catch (err) {\n emit({ type: 'error', session_id: msg.session_id, message: (err as Error)?.message ?? String(err) })\n emit({ type: 'done', session_id: msg.session_id, step_count: 0, status: 'error' })\n }\n })\n\n rl.on('close', () => process.exit(0))\n\n // Block forever — readline keeps the loop alive.\n },\n})\n\nasync function handleInbound(msg: InboundMessage, sessions: RpcSessionMap): Promise<void> {\n const config = readLitellmConfig(msg.model)\n const tools = taskTools(msg.tools ?? [])\n const maxSteps = msg.max_steps ?? 10\n\n let session = sessions.get(msg.session_id)\n if (!session) {\n session = {\n systemPrompt: msg.system_prompt,\n tools,\n maxSteps,\n messages: [],\n lastTouched: Date.now(),\n }\n sessions.put(msg.session_id, session)\n }\n\n const result = await runLoop({\n config,\n systemPrompt: session.systemPrompt,\n userMessage: msg.user_msg,\n tools: session.tools,\n maxSteps: session.maxSteps,\n history: session.messages,\n handlers: {\n onTextDelta: delta => emit({ type: 'text_delta', session_id: msg.session_id, delta }),\n onToolCall: ({ name, args }) => emit({ type: 'tool_call', session_id: msg.session_id, name, args }),\n onToolResult: ({ name, result }) => emit({ type: 'tool_result', session_id: msg.session_id, name, result }),\n onToolError: ({ name, error }) => emit({ type: 'tool_error', session_id: msg.session_id, name, error }),\n },\n })\n\n // Persist session memory by appending the user_msg + assistant\n // response so the next inbound message has the full thread.\n session.messages.push({ role: 'user', content: msg.user_msg })\n if (result.finalMessage) {\n session.messages.push({ role: 'assistant', content: result.finalMessage })\n }\n\n emit({\n type: 'done',\n session_id: msg.session_id,\n step_count: result.stepCount,\n status: result.status,\n final_message: result.finalMessage,\n })\n}\n","import { execFileSync } from 'node:child_process'\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport {\n AGENT_NAME_REGEX,\n BASH_VIA_APE_SHELL_HOOK_SOURCE,\n buildAgentAuthJson,\n buildSpawnSetupScript,\n CLAUDE_SETTINGS_JSON,\n issueAgentToken,\n registerAgentAtIdp,\n} from '../../lib/agent-bootstrap'\nimport { buildSyncPlist } from '../../lib/troop-bootstrap'\nimport { generateKeyPairInMemory } from '../../lib/keygen'\nimport {\n bridgePlistLabel,\n bridgePlistPath,\n buildBridgeEnvFile,\n buildBridgePlist,\n buildBridgeStartScript,\n captureHostBinDirs,\n resolveBridgeConfig,\n} from '../../lib/llm-bridge'\nimport { isDarwin, isShellRegistered, macOSUsernameForAgent, readMacOSUser, whichBinary } from '../../lib/macos-user'\nimport { upsertNestAgent } from '../../lib/nest-registry'\n\nfunction readMacOSUidOrNull(name: string): number | null {\n try {\n const u = readMacOSUser(name)\n return u?.uid ?? null\n }\n catch { return null }\n}\n\nexport const spawnAgentCommand = defineCommand({\n meta: {\n name: 'spawn',\n description: 'Provision a local macOS agent end-to-end (OS user, keypair, IdP agent, Claude hook)',\n },\n args: {\n name: {\n type: 'positional',\n description: 'Agent name — also the macOS short username (lowercase, [a-z0-9-], must start with a letter)',\n required: true,\n },\n shell: {\n type: 'string',\n description: 'Login shell for the macOS user. Default: /bin/zsh. Pass $(which ape-shell) to opt into the grant-mediated REPL as login shell.',\n },\n 'no-claude-hook': {\n type: 'boolean',\n description: 'Skip writing ~/.claude/settings.json + the Bash-rewrite hook',\n },\n 'claude-token': {\n type: 'string',\n description: 'Claude Code OAuth token (sk-ant-oat01-…) from `claude setup-token`. Visible to ps — prefer --claude-token-stdin in scripts.',\n },\n 'claude-token-stdin': {\n type: 'boolean',\n description: 'Read the Claude Code OAuth token from stdin (paranoid form of --claude-token).',\n },\n 'no-bridge': {\n type: 'boolean',\n description:\n 'Skip the ape-agent runtime install. Default behaviour installs the runtime so the agent answers chat.openape.ai messages (reads LITELLM_API_KEY/BASE_URL from ~/litellm/.env; override via --bridge-key / --bridge-base-url). Use --no-bridge for headless / CI / IdP-only account provisioning where the agent will not run a chat loop.',\n },\n 'bridge-key': {\n type: 'string',\n description: 'Override LITELLM_API_KEY for the bridge (default: read from ~/litellm/.env).',\n },\n 'bridge-base-url': {\n type: 'string',\n description: 'Override LITELLM_BASE_URL for the bridge (default: read from ~/litellm/.env or http://127.0.0.1:4000/v1).',\n },\n 'bridge-model': {\n type: 'string',\n description: 'Model the bridge sends in chat-completion requests (default: claude-haiku-4-5). Override when fronting a proxy that doesn\\'t route the default — e.g. ChatGPT-only proxy needs `gpt-5.4`.',\n },\n },\n async run({ args }) {\n const name = args.name as string\n if (!AGENT_NAME_REGEX.test(name)) {\n throw new CliError(\n `Invalid agent name \"${name}\". Must match /^[a-z][a-z0-9-]{0,23}$/ — `\n + `lowercase letters, digits and hyphens, 1–24 chars, must start with a letter.`,\n )\n }\n\n if (!isDarwin()) {\n throw new CliError(\n `\\`apes agents spawn\\` is currently macOS-only. Detected platform: ${process.platform}. `\n + `Linux support is a follow-up; for now, use \\`apes agents register\\` plus a manually provisioned user.`,\n )\n }\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n // Default to plain /bin/zsh (macOS modern default) — ape-shell as login\n // shell is opt-in via --shell. Rationale: ape-shell intercepts every\n // command through the grant flow which is the right model for unattended\n // agents but trips on interactive niceties (terminal control sequences\n // sent by tools like Warp, exit semantics, etc.). The Claude\n // bash-rewrite hook still routes Claude-issued commands through\n // ape-shell — that's where grant-mediation actually matters.\n const loginShell = (args.shell ?? '/bin/zsh').toString()\n const apes = whichBinary('apes')\n if (!apes) {\n throw new CliError('`apes` not found on PATH. Install @openape/apes globally first.')\n }\n const escapes = whichBinary('escapes')\n if (!escapes) {\n throw new CliError(\n '`escapes` not found on PATH. spawn delegates the privileged setup phase to escapes; '\n + 'install it before running spawn.',\n )\n }\n if (!isShellRegistered(loginShell)) {\n throw new CliError(\n `${loginShell} is not registered in /etc/shells. macOS refuses to set it as a login shell. Run:\\n`\n + ` echo ${loginShell} | sudo tee -a /etc/shells\\n`\n + 'and try again.',\n )\n }\n\n // macOSUsername is the dscl record name + chown target. Prefixed\n // (`openape-agent-<name>`) so `cleanup-orphans` and any operator\n // running `dscl . -list /Users` can spot OpenApe-managed accounts\n // immediately. Agent-facing surfaces (email, troop UI, bridge data\n // dir, `apes agents list`) stay on the bare `name`. Legacy agents\n // (pre-prefix) keep working via `lookupMacOSUserForAgent` which\n // falls through to the unprefixed lookup.\n const macOSUsername = macOSUsernameForAgent(name)\n const existing = readMacOSUser(macOSUsername) ?? readMacOSUser(name)\n if (existing) {\n throw new CliError(`macOS user \"${existing.name}\" already exists (uid=${existing.uid ?? '?'}). Refusing to overwrite.`)\n }\n\n // Phase G (#sim-arch): hidden service-account agents live under\n // /var/openape/homes/<macOSUsername>, matching macOS convention\n // for hidden services (_www → /var/empty, _postgres → /var/empty,\n // our own _openape_nest → /var/openape/nest). Keeps /Users/ for\n // real human accounts only — Finder, TimeMachine, Migration\n // Assistant stop seeing agents.\n //\n // The dscl record stays at /Users/<macOSUsername> (that's the\n // dscl namespace, not a filesystem path) — only the\n // NFSHomeDirectory attribute changes. setup.sh below interpolates\n // both into the dscl create call.\n const homeDir = `/var/openape/homes/${macOSUsername}`\n const scratch = mkdtempSync(join(tmpdir(), `apes-spawn-${name}-`))\n const scriptPath = join(scratch, 'setup.sh')\n\n try {\n consola.start(`Generating keypair for ${name}…`)\n const { privatePem, publicSshLine, x25519PrivateKey, x25519PublicKey } = generateKeyPairInMemory()\n\n consola.start(`Registering agent at ${idp}…`)\n const registration = await registerAgentAtIdp({ name, publicKey: publicSshLine, idp })\n consola.success(`Registered as ${registration.email}`)\n\n consola.start('Issuing agent access token…')\n const { token, expiresIn } = await issueAgentToken({\n idp,\n agentEmail: registration.email,\n privateKeyPem: privatePem,\n })\n\n const authJson = buildAgentAuthJson({\n idp,\n accessToken: token,\n email: registration.email,\n expiresAt: Math.floor(Date.now() / 1000) + expiresIn,\n keyPath: `${homeDir}/.ssh/id_ed25519`,\n // The IdP resolves the owner transitively (when the caller\n // is itself an agent — e.g. a Nest spawning a child — the\n // human at the top of the chain becomes owner). Use the\n // server-resolved owner, not the local caller's auth.email,\n // otherwise the agent's auth.json will carry the Nest's\n // email and troop will reject sync calls because the\n // encoded owner-domain in the agent email doesn't match\n // the auth.json's owner_email domain.\n ownerEmail: registration.owner,\n })\n\n const includeClaudeHook = !args['no-claude-hook']\n const claudeOauthToken = await resolveClaudeToken({\n flag: typeof args['claude-token'] === 'string' ? args['claude-token'] : undefined,\n fromStdin: !!args['claude-token-stdin'],\n })\n\n // Bridge install is the default — every agent needs the runtime\n // to answer chat or fire cron tasks. `--no-bridge` is the explicit\n // escape for headless / CI / account-only provisioning.\n const withBridge = !args['no-bridge']\n const bridge = withBridge\n ? (() => {\n const cfg = resolveBridgeConfig({\n cliKey: typeof args['bridge-key'] === 'string' ? args['bridge-key'] : undefined,\n cliBaseUrl: typeof args['bridge-base-url'] === 'string' ? args['bridge-base-url'] : undefined,\n cliModel: typeof args['bridge-model'] === 'string' ? args['bridge-model'] : undefined,\n })\n // Capture the host's bin dirs ONCE per spawn — same dirs\n // are baked into both the plist's PATH and start.sh.\n // Throws if node / ape-agent / apes aren't on\n // the host PATH.\n const hostBinDirs = captureHostBinDirs()\n return {\n plistLabel: bridgePlistLabel(name),\n plistPath: bridgePlistPath(name),\n plistContent: buildBridgePlist(name, homeDir, auth.email, hostBinDirs),\n startScript: buildBridgeStartScript(hostBinDirs),\n envFile: buildBridgeEnvFile(cfg),\n }\n })()\n : null\n\n // Troop sync launchd — installed for every agent (no opt-out\n // for v1). The plist runs `apes agents sync` every 5min and\n // RunAtLoad fires it once eagerly so the agent registers at\n // troop.openape.ai within seconds of spawn finishing.\n const troopPlistLabel = `openape.troop.sync.${name}`\n const troopPlistPath = `/Library/LaunchDaemons/${troopPlistLabel}.plist`\n // Reuse the bridge's host-bin-dir capture if a bridge was set\n // up; otherwise capture once for the troop sync alone. The\n // sync daemon needs `node` (apes-cli's shebang) and `apes`\n // (the actual binary it runs) on PATH.\n const troopBinDirs = bridge ? captureHostBinDirs() : captureHostBinDirs()\n const troop = {\n plistLabel: troopPlistLabel,\n plistPath: troopPlistPath,\n plistContent: buildSyncPlist({ agentName: name, apesBin: apes, homeDir, userName: name, hostBinDirs: troopBinDirs }),\n }\n\n const script = buildSpawnSetupScript({\n name,\n macOSUsername,\n homeDir,\n shellPath: loginShell,\n privateKeyPem: privatePem,\n publicKeySshLine: publicSshLine,\n x25519PrivateKey,\n x25519PublicKey,\n authJson,\n claudeSettingsJson: includeClaudeHook ? CLAUDE_SETTINGS_JSON : null,\n hookScriptSource: includeClaudeHook ? BASH_VIA_APE_SHELL_HOOK_SOURCE : null,\n claudeOauthToken,\n bridge,\n troop,\n })\n writeFileSync(scriptPath, script, { mode: 0o700 })\n\n // Skip the second escalation if we're already root. This happens\n // when `apes nest spawn` (or any wrapper) invokes us via\n // `apes run --as root -- apes agents spawn` — the outer `apes\n // run` already obtained Patrick's grant + escapes-setuid us to\n // root, so an inner `apes run --as root` would just request a\n // second redundant grant. Direct call to bash skips that and\n // gets us down to ONE approval per spawn (the outer one).\n const alreadyRoot = process.getuid?.() === 0\n if (alreadyRoot) {\n consola.start('Running privileged setup directly (already root)…')\n execFileSync('bash', [scriptPath], { stdio: 'inherit' })\n }\n else {\n consola.start('Running privileged setup as root via `apes run --as root --wait`…')\n consola.info('You will be asked to approve the as=root grant in your DDISA inbox; this command blocks until you do.')\n // --wait is critical: without it `apes run --as root` returns\n // exit 75 (pending) immediately, which we'd interpret as\n // failure and which would leave a dangling grant referencing\n // a scratch dir we'd cleaned up in the finally below.\n execFileSync(apes, ['run', '--as', 'root', '--wait', '--', 'bash', scriptPath], { stdio: 'inherit' })\n }\n\n // Phase F: register in the Nest's registry directly (replaces\n // the old intent-channel handler in the Nest). The Nest\n // watches agents.json and reconciles its pm2-supervisor when\n // it sees a new entry — bridge starts within a second.\n try {\n const uid = readMacOSUidOrNull(macOSUsername) ?? readMacOSUidOrNull(name)\n upsertNestAgent({\n name,\n uid: uid ?? -1,\n home: homeDir,\n email: registration.email,\n registeredAt: Math.floor(Date.now() / 1000),\n bridge: withBridge\n ? {\n baseUrl: typeof args['bridge-base-url'] === 'string' ? args['bridge-base-url'] : undefined,\n apiKey: typeof args['bridge-key'] === 'string' ? args['bridge-key'] : undefined,\n model: typeof args['bridge-model'] === 'string' ? args['bridge-model'] : undefined,\n }\n : undefined,\n })\n }\n catch (err) {\n // Don't fail the spawn just because the registry write\n // glitched — the agent exists in macOS, the human can\n // manually register later. Log loudly.\n consola.warn(`Could not write to nest registry: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n consola.success(`Agent ${name} spawned.`)\n consola.info(`🔗 Troop: https://troop.openape.ai/agents/${name}`)\n\n if (withBridge) {\n consola.info(`On first boot, the bridge will send you a contact request from ${registration.email}.`)\n consola.info('Open chat.openape.ai and accept it to start chatting with the agent.')\n }\n\n console.log('')\n console.log('Run as the agent with:')\n console.log(` apes run --as ${name} -- claude --session-name ${name} --dangerously-skip-permissions`)\n }\n finally {\n rmSync(scratch, { recursive: true, force: true })\n }\n },\n})\n\n/**\n * Resolve the Claude Code OAuth token from --claude-token, --claude-token-stdin,\n * or neither (returns null = agent will need interactive auth on first claude\n * run). --flag and --stdin together is rejected as ambiguous.\n *\n * Validation: Claude tokens start with `sk-ant-oat01-`. We reject anything\n * else with a clear hint instead of silently writing a useless string.\n */\nasync function resolveClaudeToken(opts: { flag?: string, fromStdin: boolean }): Promise<string | null> {\n if (opts.flag && opts.fromStdin) {\n throw new CliError('Pass --claude-token OR --claude-token-stdin, not both.')\n }\n let raw: string | null = null\n if (typeof opts.flag === 'string') {\n raw = opts.flag.trim()\n }\n else if (opts.fromStdin) {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n raw = Buffer.concat(chunks).toString('utf-8').trim()\n }\n if (!raw) return null\n if (!raw.startsWith('sk-ant-oat01-')) {\n throw new CliError(\n `Claude token doesn't look right (expected sk-ant-oat01-…). Run \\`claude setup-token\\``\n + ` and paste the resulting token.`,\n )\n }\n return raw\n}\n","// Troop-side spawn integration. Installs the periodic sync launchd\n// plist for a freshly spawned agent and bootstraps it into the system\n// domain (run-as the agent via UserName) so it kicks off immediately.\n//\n// Why /Library/LaunchDaemons + system domain (not ~/Library/LaunchAgents\n// + gui/<uid>): spawned agents are hidden service accounts (IsHidden=1)\n// that never log in graphically, so their per-user launchd domain\n// doesn't exist. `launchctl bootstrap gui/<uid>` fails with \"Domain does\n// not support specified action\". The bridge had the same constraint and\n// solved it the same way — system-level plist with UserName key. Keeps\n// the daemon running 24/7 regardless of login state.\n//\n// The sync plist runs `apes agents sync` every 5 minutes (StartInterval).\n// It also fires once on bootstrap (the implicit launchctl bootstrap\n// run) so the agent's first appearance in the troop SP UI doesn't\n// have to wait a full sync cycle after spawn finishes.\n\nconst SYNC_LABEL_PREFIX = 'openape.troop.sync'\nconst SYNC_INTERVAL_SECONDS = 300\n\nexport function syncPlistLabel(agentName: string): string {\n return `${SYNC_LABEL_PREFIX}.${agentName}`\n}\n\nexport function syncPlistPath(_homeDir: string, agentName: string): string {\n return `/Library/LaunchDaemons/${syncPlistLabel(agentName)}.plist`\n}\n\ninterface SyncPlistInput {\n agentName: string\n apesBin: string\n homeDir: string\n /**\n * macOS short username for the agent. The sync daemon itself runs\n * as ROOT (so it can write into /Library/LaunchDaemons/ and\n * `launchctl bootstrap system` task plists — system-domain\n * operations a hidden service-account agent has no permission for).\n * Sync resolves the agent's numeric uid/gid by stat-ing $HOME at\n * runtime, then chowns its writes back to those ids.\n */\n userName: string\n // Optional override for OPENAPE_TROOP_URL — exposed in the plist\n // EnvironmentVariables so the launchd-spawned `apes agents sync`\n // talks to the right SP. Default: https://troop.openape.ai (via\n // the apes binary's resolveTroopUrl). Useful for testing against\n // a staging troop.\n troopUrl?: string\n /**\n * Host bin dirs (e.g. ['/opt/homebrew/bin']) baked into the plist's\n * PATH so the launchd-spawned `apes` binary's `#!/usr/bin/env node`\n * shebang resolves. Captured at spawn time via captureHostBinDirs.\n * Falls back to ['/opt/homebrew/bin','/usr/local/bin'] if not given,\n * for backwards compat with older callers.\n */\n hostBinDirs?: string[]\n}\n\nfunction escape(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')\n}\n\nexport function buildSyncPlist(input: SyncPlistInput): string {\n // launchd defaults PATH to /usr/bin:/bin:/usr/sbin:/sbin — too narrow\n // for the apes binary's `#!/usr/bin/env node` shebang to find node.\n // We bake the host's resolved bin dirs (where node and apes already\n // live, captured via captureHostBinDirs at spawn time) and the\n // standard system path. Per-agent `~/.bun/bin` is gone — agents\n // now share the host's tooling install. See agent-bootstrap M9.\n //\n // HOME is set to the agent's home dir even though the daemon runs as\n // root — Node's `os.homedir()` reads $HOME first, so all of sync's\n // file operations stay scoped under /Users/<agent>/. AGENT_UID/GID\n // tell sync who to chown those files to after writing.\n const pathDirs = (input.hostBinDirs && input.hostBinDirs.length > 0\n ? input.hostBinDirs\n : ['/opt/homebrew/bin', '/usr/local/bin']).join(':')\n const pathLine = ` <key>PATH</key><string>${escape(pathDirs)}:/usr/bin:/bin</string>\\n`\n const agentUserLine = ` <key>AGENT_USER</key><string>${escape(input.userName)}</string>\\n`\n const envBlock = input.troopUrl\n ? ` <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key><string>${escape(input.homeDir)}</string>\n${pathLine}${agentUserLine} <key>OPENAPE_TROOP_URL</key><string>${escape(input.troopUrl)}</string>\n </dict>\n`\n : ` <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key><string>${escape(input.homeDir)}</string>\n${pathLine}${agentUserLine} </dict>\n`\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${escape(syncPlistLabel(input.agentName))}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escape(input.apesBin)}</string>\n <string>agents</string>\n <string>sync</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${escape(input.homeDir)}</string>\n${envBlock} <key>StartInterval</key>\n <integer>${SYNC_INTERVAL_SECONDS}</integer>\n <key>RunAtLoad</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${escape(input.homeDir)}/Library/Logs/openape-troop-sync.log</string>\n <key>StandardErrorPath</key>\n <string>${escape(input.homeDir)}/Library/Logs/openape-troop-sync.log</string>\n</dict>\n</plist>\n`\n}\n\nexport const _internal = { SYNC_INTERVAL_SECONDS, SYNC_LABEL_PREFIX }\n","import { Buffer } from 'node:buffer'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { generateKeyPairSync } from 'node:crypto'\nimport { homedir } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { generateX25519KeyPair } from '@openape/core'\nimport { loadEd25519PrivateKey } from '../ssh-key'\n\nexport function resolveKeyPath(p: string): string {\n return resolve(p.replace(/^~/, homedir()))\n}\n\nfunction buildSshEd25519Line(rawPub: Buffer): string {\n const keyTypeStr = 'ssh-ed25519'\n const keyTypeLen = Buffer.alloc(4)\n keyTypeLen.writeUInt32BE(keyTypeStr.length)\n const pubKeyLen = Buffer.alloc(4)\n pubKeyLen.writeUInt32BE(rawPub.length)\n const blob = Buffer.concat([keyTypeLen, Buffer.from(keyTypeStr), pubKeyLen, rawPub])\n return `ssh-ed25519 ${blob.toString('base64')}`\n}\n\nexport function readPublicKey(keyPath: string): string {\n const pubPath = `${keyPath}.pub`\n if (existsSync(pubPath)) {\n return readFileSync(pubPath, 'utf-8').trim()\n }\n\n const keyContent = readFileSync(keyPath, 'utf-8')\n const privateKey = loadEd25519PrivateKey(keyContent)\n const jwk = privateKey.export({ format: 'jwk' }) as { x: string }\n const pubBytes = Buffer.from(jwk.x, 'base64url')\n return buildSshEd25519Line(pubBytes)\n}\n\nexport function generateAndSaveKey(keyPath: string): string {\n const resolved = resolveKeyPath(keyPath)\n const dir = dirname(resolved)\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n const { publicKey, privateKey } = generateKeyPairSync('ed25519')\n\n const privatePem = privateKey.export({ type: 'pkcs8', format: 'pem' }) as string\n writeFileSync(resolved, privatePem, { mode: 0o600 })\n\n const jwk = publicKey.export({ format: 'jwk' }) as { x: string }\n const pubBytes = Buffer.from(jwk.x, 'base64url')\n const pubKeyStr = buildSshEd25519Line(pubBytes)\n\n writeFileSync(`${resolved}.pub`, `${pubKeyStr}\\n`, { mode: 0o644 })\n\n return pubKeyStr\n}\n\nexport interface GeneratedKeyPair {\n privatePem: string\n publicSshLine: string\n /**\n * Agent encryption keypair (X25519, base64url DER). Separate from the\n * ed25519 auth key on purpose — auth signs, this one decrypts. troop\n * seals capability secrets to `x25519PublicKey`; the agent opens them\n * with `x25519PrivateKey`. See @openape/core sealed-box.\n */\n x25519PrivateKey: string\n x25519PublicKey: string\n}\n\nexport function generateKeyPairInMemory(): GeneratedKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync('ed25519')\n const privatePem = privateKey.export({ type: 'pkcs8', format: 'pem' }) as string\n const jwk = publicKey.export({ format: 'jwk' }) as { x: string }\n const pubBytes = Buffer.from(jwk.x, 'base64url')\n const enc = generateX25519KeyPair()\n return {\n privatePem,\n publicSshLine: buildSshEd25519Line(pubBytes),\n x25519PrivateKey: enc.privateKey,\n x25519PublicKey: enc.publicKey,\n }\n}\n","// Helpers for `apes agents spawn`. The chat-bridge is a daemon\n// that runs as the agent user, listens to chat.openape.ai, and forwards\n// messages to a local LLM CLI (pi). It needs access to a local litellm\n// proxy — set up out-of-band by the spawning user (today: hand-crafted\n// at ~/litellm/.env).\n//\n// As of #236 the daemon is installed as a system-wide LaunchDaemon at\n// /Library/LaunchDaemons/eco.hofmann.apes.bridge.<agent>.plist with the\n// agent set as <UserName>. That makes it boot without anyone being logged\n// in (matters for hidden service accounts in the [200,500) UID range\n// which never get a GUI session).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\nconst PLIST_LABEL_PREFIX = 'eco.hofmann.apes.bridge'\n\nexport interface BridgeConfig {\n /** Where the bridge will POST messages — http://host:port/v1 */\n baseUrl: string\n /** Master key for the litellm proxy */\n apiKey: string\n /**\n * Model the bridge sends in every chat-completion request. Optional:\n * if undefined, the bridge falls back to its built-in default\n * (`claude-haiku-4-5`). Set this when the upstream proxy doesn't\n * route that model — e.g. a LiteLLM proxy fronting only ChatGPT\n * subscription needs `gpt-5.4` or the proxy 404s every request.\n */\n model?: string\n}\n\n/**\n * Read defaults from `~/litellm/.env` (the hand-crafted location patrick\n * uses today). Returns null if no file or no key found.\n */\nexport function readLitellmEnv(envPath: string = join(homedir(), 'litellm', '.env')): { apiKey?: string, baseUrl?: string, model?: string } | null {\n if (!existsSync(envPath)) return null\n try {\n const text = readFileSync(envPath, 'utf8')\n const out: { apiKey?: string, baseUrl?: string, model?: string } = {}\n for (const line of text.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n const eq = trimmed.indexOf('=')\n if (eq < 0) continue\n const key = trimmed.slice(0, eq).trim()\n const value = trimmed.slice(eq + 1).trim()\n if (key === 'LITELLM_MASTER_KEY' || key === 'LITELLM_API_KEY') out.apiKey = value\n if (key === 'LITELLM_BASE_URL') out.baseUrl = value\n if (key === 'APE_CHAT_BRIDGE_MODEL') out.model = value\n }\n return out\n }\n catch {\n return null\n }\n}\n\n/** Resolve config from CLI flags + env defaults. CLI wins. */\nexport function resolveBridgeConfig(opts: {\n cliKey?: string\n cliBaseUrl?: string\n cliModel?: string\n envPath?: string\n}): BridgeConfig {\n const env = readLitellmEnv(opts.envPath)\n const apiKey = opts.cliKey ?? env?.apiKey\n const baseUrl = opts.cliBaseUrl ?? env?.baseUrl ?? 'http://127.0.0.1:4000/v1'\n const model = opts.cliModel ?? env?.model\n if (!apiKey) {\n throw new Error(\n 'No LITELLM_API_KEY resolved. Pass --bridge-key sk-… or write LITELLM_MASTER_KEY into ~/litellm/.env first.',\n )\n }\n return { baseUrl, apiKey, model }\n}\n\n/**\n * Capture the host's bin directories the bridge needs at runtime:\n * `node` (for the `#!/usr/bin/env node` shebang on the bridge binary),\n * `ape-agent` (the bridge itself), and `apes` (for the\n * `apes agents serve --rpc` subprocess the bridge spawns).\n *\n * On Homebrew macOS these all live in /opt/homebrew/bin. Resolved\n * dynamically so the same code works under nvm, volta, asdf, or\n * system Node. Throws if any required binary isn't on the host PATH —\n * that means the operator hasn't installed the OpenApe stack yet\n * (`npm i -g @openape/apes @openape/ape-agent` fixes it). The\n * thrown error is the right surface area: previously the spawn flow\n * silently `bun add -g`'d the missing pieces per agent, costing\n * 30-90s/spawn and ~100MB/agent.\n *\n * `ape-agent` is the canonical binary name (renamed from\n * `openape-chat-bridge` in @openape/ape-agent@2.0.0). The old name\n * is still shipped as an alias by the same package, so existing\n * pm2 ecosystem.config.js that reference `openape-chat-bridge`\n * keep working on hosts that have @openape/ape-agent installed.\n */\nexport function captureHostBinDirs(): string[] {\n const dirs: string[] = []\n const seen = new Set<string>()\n for (const bin of ['node', 'ape-agent', 'apes']) {\n let resolved: string\n try {\n resolved = execFileSync('/usr/bin/which', [bin], { encoding: 'utf8' }).trim()\n }\n catch {\n const installCmd = bin === 'ape-agent'\n ? 'npm i -g @openape/ape-agent'\n : bin === 'apes'\n ? 'npm i -g @openape/apes'\n : 'install Node.js (e.g. brew install node)'\n throw new Error(`'${bin}' not found on host PATH. ${installCmd} before spawning agents — the bridge runtime resolves these at spawn time and bakes the dir into the agent's launchd plist.`)\n }\n const dir = dirname(resolved)\n if (!seen.has(dir)) {\n seen.add(dir)\n dirs.push(dir)\n }\n }\n return dirs\n}\n\nexport function bridgePlistLabel(agentName: string): string {\n return `${PLIST_LABEL_PREFIX}.${agentName}`\n}\n\n/** Path of the system LaunchDaemon plist. Root-owned, writable only by root. */\nexport function bridgePlistPath(agentName: string): string {\n return `/Library/LaunchDaemons/${bridgePlistLabel(agentName)}.plist`\n}\n\nexport function buildBridgeEnvFile(cfg: BridgeConfig): string {\n const modelLine = cfg.model ? `APE_CHAT_BRIDGE_MODEL=${cfg.model}\\n` : ''\n return `# Auto-generated by 'apes agents spawn'.\n# Read by the chat-bridge daemon at boot to talk to the local LLM proxy.\nLITELLM_BASE_URL=${cfg.baseUrl}\nLITELLM_API_KEY=${cfg.apiKey}\n${modelLine}`\n}\n\n/**\n * start.sh content. Slim — assumes the bridge stack (chat-bridge + apes\n * + pi) was already bun-installed during spawn. Each launchd boot only:\n *\n * 1. Drops the litellm pi extension if missing (idempotent).\n * 2. Sources the proxy env + execs the bridge.\n *\n * Boot time goes from ~75s (with installs) to ~3-5s.\n *\n * Token refresh: handled in-process by `@openape/cli-auth`, which\n * does its own Ed25519 challenge-response when the cached IdP token\n * expires (`auth.json.key_path` points at `~/.ssh/id_ed25519`). No\n * `apes login` shell-out needed at boot — the daemon stays connected\n * across the 1h expiry boundary instead of crash-restarting. See #259.\n *\n * To upgrade an agent's bridge after a new release:\n * npm i -g @openape/ape-agent@latest\n * apes run --as <name> -- pm2 reload openape-bridge-<name>\n */\nexport function buildBridgeStartScript(hostBinDirs: string[]): string {\n // PATH is the host's resolved bin dirs (from captureHostBinDirs)\n // followed by the standard system path. The PATH key in the launchd\n // plist already sets this for the exec'd process — start.sh repeats\n // it because some shells reset PATH on `set -a`.\n const pathLine = `export PATH=\"${hostBinDirs.join(':')}:/usr/bin:/bin\"`\n return `#!/usr/bin/env bash\n# Auto-generated by 'apes agents spawn'.\n# Slim launcher — bridge stack lives on the host, no per-agent install.\nset -euo pipefail\n\n${pathLine}\n\n# Token refresh is in-process via @openape/cli-auth's challenge-response\n# path (auth.json.key_path -> ~/.ssh/id_ed25519). No \"apes login\" needed\n# at boot — keeping start.sh slim avoids the rate-limit dance the old\n# refresh hit when KeepAlive crash-restarted the daemon every 1h.\n\nset -a\n. \"$HOME/Library/Application Support/openape/bridge/.env\"\nset +a\nexec ape-agent\n`\n}\n\n/**\n * System LaunchDaemon plist. Lives at /Library/LaunchDaemons/. macOS boots\n * it automatically and respawns on crash via KeepAlive. UserName ensures\n * launchd starts the process as the agent (not root), even though the\n * plist itself is root-owned.\n *\n * `OPENAPE_OWNER_EMAIL` is stamped into the daemon environment as a\n * defense-in-depth fallback for the chat-bridge identity check: the\n * canonical source is `owner_email` in `~/.config/apes/auth.json`\n * (written by spawn), but if a future `apes login` ever clobbers that\n * field the bridge can still resolve its owner from this env var.\n */\nexport function buildBridgePlist(agentName: string, homeDir: string, ownerEmail: string, hostBinDirs: string[]): string {\n const startScript = `${homeDir}/Library/Application Support/openape/bridge/start.sh`\n const stdoutLog = `${homeDir}/Library/Logs/ape-agent.log`\n const stderrLog = `${homeDir}/Library/Logs/ape-agent.err.log`\n // PATH = host's resolved bin dirs (where node, ape-agent,\n // and apes already live) + standard system path. No `~/.bun/bin`\n // entry — the per-agent bun install was retired in favour of host-\n // wide tooling. See captureHostBinDirs for resolution.\n const pathValue = `${hostBinDirs.join(':')}:/usr/bin:/bin`\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${bridgePlistLabel(agentName)}</string>\n <key>UserName</key>\n <string>${agentName}</string>\n <key>ProgramArguments</key>\n <array>\n <string>/bin/bash</string>\n <string>${startScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${homeDir}</string>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>StandardOutPath</key>\n <string>${stdoutLog}</string>\n <key>StandardErrorPath</key>\n <string>${stderrLog}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key>\n <string>${homeDir}</string>\n <key>PATH</key>\n <string>${pathValue}</string>\n <key>OPENAPE_OWNER_EMAIL</key>\n <string>${ownerEmail}</string>\n </dict>\n</dict>\n</plist>\n`\n}\n","import { chownSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { readAgentEncryptionPublicKey } from '../../lib/agent-secrets-runtime'\nimport { CliError } from '../../errors'\nimport { getHostId, getHostname } from '../../lib/macos-host'\nimport { resolveTroopUrl, TroopClient } from '../../lib/troop-client'\n\ninterface AuthJson {\n idp: string\n access_token: string\n email: string\n expires_at?: number\n key_path?: string\n owner_email?: string\n}\n\nconst AUTH_PATH = join(homedir(), '.config', 'apes', 'auth.json')\nconst TASK_CACHE_DIR = join(homedir(), '.openape', 'agent', 'tasks')\n\nfunction readAuthJson(): AuthJson {\n if (!existsSync(AUTH_PATH)) {\n throw new CliError(\n `No agent auth found at ${AUTH_PATH}. Run \\`apes agents spawn <name>\\` to provision an agent first.`,\n )\n }\n const raw = readFileSync(AUTH_PATH, 'utf8')\n let parsed: AuthJson\n try { parsed = JSON.parse(raw) as AuthJson }\n catch (err) {\n throw new CliError(`${AUTH_PATH} is not valid JSON: ${(err as Error).message}`)\n }\n if (!parsed.access_token) throw new CliError(`${AUTH_PATH} is missing access_token`)\n if (!parsed.email) throw new CliError(`${AUTH_PATH} is missing email`)\n // Agent addresses derived by deriveAgentEmail() in the IdP's enroll\n // endpoint look like:\n // <safeName>-<ownerHash>+<owner-local>+<owner-domain>@<idp-host>\n // (e.g. \"igor4-cb6bf26a+patrick+hofmann_eco@id.openape.ai\"). The\n // distinguishing feature vs. a human address is the embedded `+` from\n // the subaddressing — humans never have that.\n if (!parsed.email.includes('+')) {\n throw new CliError(\n `${AUTH_PATH} email is \"${parsed.email}\" — expected an agent address (with embedded +owner+domain). Run \\`apes agents spawn\\` rather than calling sync from a human user.`,\n )\n }\n return parsed\n}\n\nfunction agentNameFromEmail(email: string): string {\n // <name>-<ownerHash>+<owner-local>+<owner-domain>@<idp-host>\n // The agent NAME is everything up to the last `-` before the first\n // `+` — the suffix `-<ownerHash>` is appended at registration time\n // to disambiguate same-named agents across owners.\n const before = email.split('+')[0]!\n const dashIdx = before.lastIndexOf('-')\n if (dashIdx <= 0) {\n // Pre-hash format (e.g. \"agenta+patrick+hofmann_eco@…\") — fall back\n // to the local-part as-is so we keep working with older agents.\n return before\n }\n return before.slice(0, dashIdx)\n}\n\nexport const syncAgentCommand = defineCommand({\n meta: {\n name: 'sync',\n description: 'Pull this agent\\'s task list from troop.openape.ai and reconcile launchd plists',\n },\n args: {\n 'troop-url': {\n type: 'string',\n description: 'Override troop SP base URL (default: $OPENAPE_TROOP_URL or https://troop.openape.ai)',\n },\n },\n async run({ args }) {\n const auth = readAuthJson()\n const agentName = agentNameFromEmail(auth.email)\n const troopUrl = resolveTroopUrl(args['troop-url'] as string | undefined)\n const client = new TroopClient(troopUrl, auth.access_token)\n\n const hostId = getHostId()\n const host = getHostname()\n if (!hostId) {\n throw new CliError('Could not read IOPlatformUUID — is this macOS? Troop sync only works on macOS for v1.')\n }\n if (!auth.owner_email) {\n throw new CliError(`${AUTH_PATH} is missing owner_email — re-run \\`apes agents spawn\\` to update.`)\n }\n\n consola.start(`Syncing ${agentName} (${host}, hostId ${hostId.slice(0, 8)}…) with ${troopUrl}`)\n\n // Report the agent's X25519 public key so troop's capability broker\n // can seal secrets to it. Without this every sealed bind 409s with\n // \"no X25519 public key yet\". The keypair is written at spawn; we read\n // the public half from ~/.config/openape/agent-x25519.key.pub.\n const pubkeyX25519 = readAgentEncryptionPublicKey() ?? undefined\n const sync = await client.sync({\n hostname: host,\n hostId,\n ownerEmail: auth.owner_email,\n ...(pubkeyX25519 ? { pubkeyX25519 } : {}),\n })\n consola.info(sync.first_sync ? '✓ first sync — agent registered' : '✓ presence updated')\n if (!pubkeyX25519) consola.warn('No X25519 public key found on disk — sealed capability secrets cannot be bound until the agent is re-spawned.')\n\n const { system_prompt: systemPrompt, tools, skills, tasks } = await client.listTasks()\n consola.info(`Pulled ${tasks.length} task${tasks.length === 1 ? '' : 's'}`)\n consola.info(`Tools enabled: ${tools.length === 0 ? '(none)' : tools.join(', ')}`)\n consola.info(`Skills: ${skills.length === 0 ? '(none)' : skills.map(s => s.name).join(', ')}`)\n\n // Sync runs as ROOT in production (the launchd plist sets\n // UserName=root so it can write /Library/LaunchDaemons/ and\n // bootstrap into the system domain — a hidden service-account\n // agent has no permission for either). Files we write into the\n // agent's home need to be owned by the agent so the bridge daemon\n // and `apes agents run` (both running AS the agent) can read\n // them. Resolve agent's uid/gid by stat-ing $HOME — that's\n // already chown'd to the agent at spawn time.\n let agentUid: number | null = null\n let agentGid: number | null = null\n if (process.geteuid?.() === 0) {\n try {\n const homeStat = statSync(homedir())\n agentUid = homeStat.uid\n agentGid = homeStat.gid\n }\n catch { /* fall through, no chowning */ }\n }\n function chownToAgent(path: string): void {\n if (agentUid !== null && agentGid !== null) {\n try { chownSync(path, agentUid, agentGid) }\n catch { /* best-effort */ }\n }\n }\n\n // Cache full task specs + agent-level config locally so the bridge\n // daemon and `apes agents run <task_id>` can execute without going\n // to network. Cache layout:\n // ~/.openape/agent/agent.json — { systemPrompt }\n // ~/.openape/agent/tasks/<task_id>.json\n const agentDir = join(homedir(), '.openape', 'agent')\n mkdirSync(agentDir, { recursive: true })\n chownToAgent(join(homedir(), '.openape'))\n chownToAgent(agentDir)\n const agentJsonPath = join(agentDir, 'agent.json')\n writeFileSync(\n agentJsonPath,\n `${JSON.stringify({ systemPrompt, tools }, null, 2)}\\n`,\n { mode: 0o600 },\n )\n chownToAgent(agentJsonPath)\n mkdirSync(TASK_CACHE_DIR, { recursive: true })\n chownToAgent(TASK_CACHE_DIR)\n for (const task of tasks) {\n const path = join(TASK_CACHE_DIR, `${task.taskId}.json`)\n writeFileSync(path, `${JSON.stringify(task, null, 2)}\\n`, { mode: 0o600 })\n chownToAgent(path)\n }\n\n // SOUL.md retired — the per-agent persona is now part of\n // `systemPrompt` (above) which the bridge composes into the\n // system message on every turn. Any pre-existing\n // `~/.openape/agent/SOUL.md` file on disk is left in place so a\n // legacy bridge / agent runtime that still reads it keeps\n // working until upgraded; nothing here writes or overwrites it.\n\n // Skills mirror — one-way sync from troop. Anything currently\n // on disk that's not in the response gets pruned, so disabling\n // or deleting a skill in troop UI takes effect on the next sync\n // (instead of leaving stale SKILL.md files behind that the\n // available_skills block would still list).\n const skillsDir = join(agentDir, 'skills')\n mkdirSync(skillsDir, { recursive: true })\n chownToAgent(skillsDir)\n const incomingNames = new Set(skills.map(s => s.name))\n // Prune\n try {\n for (const entry of readdirSync(skillsDir)) {\n if (incomingNames.has(entry)) continue\n try { rmSync(join(skillsDir, entry), { recursive: true, force: true }) }\n catch { /* best-effort prune; next sync retries */ }\n }\n }\n catch { /* directory just created, nothing to prune */ }\n // Write\n for (const skill of skills) {\n const skillDir = join(skillsDir, skill.name)\n mkdirSync(skillDir, { recursive: true })\n chownToAgent(skillDir)\n const skillPath = join(skillDir, 'SKILL.md')\n writeFileSync(skillPath, skill.body.endsWith('\\n') ? skill.body : `${skill.body}\\n`, { mode: 0o600 })\n chownToAgent(skillPath)\n }\n\n // Cron tasks no longer get a per-task launchd plist (#347 was the\n // last attempt — too many failure modes for hidden agents). The\n // chat-bridge daemon's CronRunner ticks every 60s, reads these\n // task specs and fires the ones whose cron matches inside the\n // already-running ApesRpcSession. Sync just keeps the cache fresh.\n\n consola.success('Sync complete.')\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { hostname } from 'node:os'\n\n// Stable hardware-rooted host identifier on macOS. We pull\n// IOPlatformUUID via `ioreg`, which survives hostname changes,\n// disk wipes that preserve hardware (e.g. macOS reinstalls), and\n// most other operator-side reshuffles. Replacing the SoC / logic\n// board changes it; that's the intended \"different host\" signal.\n//\n// Returns a lowercase string with no surrounding whitespace. Empty\n// string on failure (we never throw — the caller decides what to do\n// when the host can't be identified).\nexport function getHostId(): string {\n try {\n const output = execFileSync(\n '/usr/sbin/ioreg',\n ['-d2', '-c', 'IOPlatformExpertDevice'],\n { encoding: 'utf8', timeout: 2000 },\n )\n const match = output.match(/\"IOPlatformUUID\"\\s*=\\s*\"([^\"]+)\"/)\n return match ? match[1]!.trim().toLowerCase() : ''\n }\n catch {\n return ''\n }\n}\n\nexport function getHostname(): string {\n try { return hostname() }\n catch { return '' }\n}\n","import { defineCommand } from 'citty'\nimport { authorizeNestCommand } from './authorize'\nimport { destroyNestCommand } from './destroy'\nimport { enrollNestCommand } from './enroll'\nimport { installNestCommand } from './install'\nimport { listNestCommand } from './list'\nimport { spawnNestCommand } from './spawn'\nimport { uninstallNestCommand } from './uninstall'\n\nexport const nestCommand = defineCommand({\n meta: {\n name: 'nest',\n description: 'Manage the local Nest control-plane daemon. One-time setup: `install` → `enroll` → `authorize`. Day-to-day: `list` / `spawn` / `destroy`. As of Phase D the Nest is a long-running CLIENT — commands talk to it via filesystem intent files in $NEST_HOME/intents (mode 770, group _openape_nest) instead of HTTP.',\n },\n subCommands: {\n install: installNestCommand,\n enroll: enrollNestCommand,\n authorize: authorizeNestCommand,\n list: listNestCommand,\n spawn: spawnNestCommand,\n destroy: destroyNestCommand,\n uninstall: uninstallNestCommand,\n },\n})\n","// `apes nest authorize` — set the YOLO-policy on the local nest's\n// DDISA-agent identity so its grant-creation hits auto-approve.\n//\n// Implementation: shells out to `apes yolo set <nest-email> ...`. The\n// YOLO-management surface is generic (any agent), so it lives in\n// `apes yolo`; this command is just the nest-specific wrapper that\n// fills in the right defaults (mode=allow-list, allow_patterns\n// covering nest-managed agent lifecycle ops).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { NEST_DATA_DIR } from './enroll'\n\ninterface NestAuth {\n email: string\n}\n\nconst DEFAULT_ALLOW_PATTERNS = [\n // Caller → Nest API gates. The new-style flow: `apes nest <op>`\n // requests a grant with audience='nest' and command=['nest','<op>',\n // ...]. Patrick's YOLO auto-approves these so the local Nest API\n // is gated cryptographically without a per-call human prompt.\n 'nest status',\n 'nest list',\n // spawn uses a wildcard-name grant (one approval, any name)\n 'nest spawn',\n // destroy stays per-name (typed in command), so the YOLO pattern\n // matches the per-name shape `nest destroy igor18`.\n 'nest destroy *',\n // Inner spawn/destroy grants the nest itself triggers via\n // `apes run --as root --wait -- apes agents spawn|destroy`.\n 'apes agents spawn *',\n 'apes agents destroy *',\n 'apes agents sync',\n // Inner setup.sh-grant — `apes agents spawn` itself shells out to\n // `apes run --as root --wait -- bash <tempdir>/setup.sh` to do the\n // dscl/launchctl/heredoc-write work. Path looks like\n // `bash /var/folders/.../apes-spawn-<name>-XXXX/setup.sh`. The narrow\n // glob below limits the auto-approval to that exact lifecycle path\n // — `bash *` would be unsafe.\n 'bash *apes-spawn-*setup.sh',\n // Bridge invocation. The grant request escapes-helper sends to the\n // IdP contains the *inner* command only — `apes run --as <agent> --`\n // is the wrapper that gets unwrapped before grant creation. So the\n // YOLO target string is just the agent-runtime binary name, not\n // the full wrapped invocation. We list both the new canonical\n // name and the legacy alias — pm2 ecosystem.config.js files\n // written before @openape/ape-agent@2.0.0 still use the old name.\n 'ape-agent',\n 'openape-chat-bridge',\n // Phase E: per-agent pm2 management. The Nest shells out\n // `apes run --as <agent> -- bash /var/openape/agents/<agent>/start.sh`\n // (the start.sh sets HOME/PM2_HOME and redirects pm2's stdio so the\n // god-daemon detach doesn't block our exec parent), plus\n // `apes run --as <agent> -- pm2 delete openape-bridge-<agent>` for teardown.\n 'bash /var/openape/agents/*/start.sh',\n 'pm2 delete openape-bridge-*',\n 'pm2 jlist',\n]\n\nexport const authorizeNestCommand = defineCommand({\n meta: {\n name: 'authorize',\n description: 'Set the YOLO-policy that lets the local nest spawn/destroy without per-call DDISA prompts (wraps `apes yolo set`)',\n },\n args: {\n 'allow': {\n type: 'string',\n description: 'Override allow_patterns (comma-separated globs). Default: nest-managed agent lifecycle.',\n },\n 'expires-in': {\n type: 'string',\n description: 'Optional duration like 30d, 6h. Omit for no expiry.',\n },\n },\n async run({ args }) {\n const nestAuthPath = join(NEST_DATA_DIR, '.config', 'apes', 'auth.json')\n if (!existsSync(nestAuthPath)) {\n throw new CliError('Nest not enrolled. Run `apes nest enroll` first.')\n }\n const nestAuth = JSON.parse(readFileSync(nestAuthPath, 'utf8')) as NestAuth\n if (!nestAuth.email) throw new CliError(`${nestAuthPath} has no email`)\n\n const allow = (args.allow as string | undefined) ?? DEFAULT_ALLOW_PATTERNS.join(',')\n\n consola.info(`Configuring YOLO-policy on ${nestAuth.email} via \\`apes yolo set\\`…`)\n\n const cmdArgs = [\n 'yolo', 'set', nestAuth.email,\n '--mode', 'allow-list',\n '--allow', allow,\n ]\n if (typeof args['expires-in'] === 'string' && args['expires-in']) {\n cmdArgs.push('--expires-in', args['expires-in'])\n }\n\n try {\n execFileSync('apes', cmdArgs, { stdio: 'inherit' })\n }\n catch (err) {\n throw new CliError(err instanceof Error ? err.message : String(err))\n }\n consola.success('Nest-driven agent lifecycle is now zero-prompt.')\n consola.info('Test: apes agents spawn <name> via the nest API → no DDISA prompt.')\n },\n})\n","// `apes nest enroll` — create a DDISA agent identity for the local nest.\n//\n// The Nest needs its own identity (separate from the human) so its\n// privileged ops (apes run --as root -- apes agents spawn <name>) hit\n// the IdP grant-creation flow as the *Nest*, where a Nest-scoped\n// YOLO-policy can auto-approve them. Without that, the Nest would have\n// to either re-prompt the human on every spawn (today's Stage 1) or\n// share the human's identity (security regression).\n//\n// Identity layout:\n// ~/.openape/nest/.ssh/id_ed25519 private key\n// ~/.openape/nest/.ssh/id_ed25519.pub public key (ssh-ed25519 …)\n// ~/.openape/nest/.config/apes/auth.json agent-token + email\n//\n// The nest-daemon's launchd plist sets HOME=~/.openape/nest (set by\n// `apes nest install`), so apes-CLI subprocesses spawned by the daemon\n// pick up THIS auth.json automatically — no env-var plumbing needed.\n\nimport { hostname, homedir } from 'node:os'\nimport { existsSync, mkdirSync, writeFileSync, chmodSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport {\n buildAgentAuthJson,\n issueAgentToken,\n registerAgentAtIdp,\n} from '../../lib/agent-bootstrap'\nimport { generateKeyPairInMemory } from '../../lib/keygen'\n\nexport const NEST_DATA_DIR = join(homedir(), '.openape', 'nest')\n\nfunction nestAgentName(): string {\n // Stable + recognisable — lowercase host, dashes only. The IdP-side\n // validateAgentName regex is /^[a-z][a-z0-9-]{0,23}$/ so we keep\n // under that ceiling and skip illegal chars.\n const raw = hostname().toLowerCase()\n // Strip everything after first dot (\"MinivonPatrick.fritz.box\" → \"minivonpatrick\"),\n // map non-alphanum to dashes, collapse runs.\n const head = raw.split('.')[0] ?? raw\n const safe = head.replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-+|-+$/g, '')\n const trimmed = safe.slice(0, 16) // leave room for `nest-` prefix\n return `nest-${trimmed || 'host'}`\n}\n\nexport const enrollNestCommand = defineCommand({\n meta: {\n name: 'enroll',\n description: 'Register the local nest as a DDISA agent at the IdP. One-time per machine. Required before `apes nest authorize` so YOLO-policies have a target identity.',\n },\n args: {\n name: {\n type: 'string',\n description: 'Override the nest agent name (default: nest-<short-hostname>)',\n },\n force: {\n type: 'boolean',\n description: 'Re-enroll even if ~/.openape/nest/.config/apes/auth.json already exists',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP configured. Run `apes login <email>` first.')\n }\n const ownerAuth = loadAuth()\n if (!ownerAuth?.email) {\n throw new CliError('Run `apes login <email>` first — nest enroll attaches the new identity to your owner account.')\n }\n\n const name = (args.name as string | undefined) || nestAgentName()\n const authPath = join(NEST_DATA_DIR, '.config', 'apes', 'auth.json')\n if (existsSync(authPath) && !args.force) {\n throw new CliError(`Nest already enrolled at ${authPath}. Pass --force to re-enroll.`)\n }\n\n const sshDir = join(NEST_DATA_DIR, '.ssh')\n const configDir = join(NEST_DATA_DIR, '.config', 'apes')\n mkdirSync(sshDir, { recursive: true })\n mkdirSync(configDir, { recursive: true })\n\n consola.start(`Generating keypair for ${name}…`)\n const { privatePem, publicSshLine } = generateKeyPairInMemory()\n writeFileSync(join(sshDir, 'id_ed25519'), `${privatePem.trimEnd()}\\n`, { mode: 0o600 })\n writeFileSync(join(sshDir, 'id_ed25519.pub'), `${publicSshLine}\\n`, { mode: 0o644 })\n chmodSync(sshDir, 0o700)\n\n consola.start(`Registering nest at ${idp}…`)\n const registration = await registerAgentAtIdp({ name, publicKey: publicSshLine, idp })\n consola.success(`Registered as ${registration.email}`)\n\n consola.start('Issuing nest access token…')\n const { token, expiresIn } = await issueAgentToken({\n idp,\n agentEmail: registration.email,\n privateKeyPem: privatePem,\n })\n\n const authJson = buildAgentAuthJson({\n idp,\n accessToken: token,\n email: registration.email,\n expiresAt: Math.floor(Date.now() / 1000) + expiresIn,\n keyPath: join(sshDir, 'id_ed25519'),\n ownerEmail: ownerAuth.email,\n })\n writeFileSync(authPath, authJson, { mode: 0o600 })\n chmodSync(configDir, 0o700)\n\n consola.success(`Nest enrolled — auth.json at ${authPath}`)\n consola.info('')\n consola.info('Next: configure the YOLO-policy so the nest can spawn/destroy without prompts:')\n consola.info('')\n consola.info(' apes nest authorize')\n },\n})\n","// `apes nest destroy <name>` — Phase F: direct shell-out to\n// `apes run --as root -- apes agents destroy <name>`. The destroy\n// command removes the registry entry; the Nest watches the file\n// and pm2-deletes the bridge automatically.\n\nimport { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliExit } from '../../errors'\n\nexport const destroyNestCommand = defineCommand({\n meta: {\n name: 'destroy',\n 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.',\n },\n args: {\n name: { type: 'positional', required: true, description: 'Agent name to destroy' },\n },\n async run({ args }) {\n const name = String(args.name)\n try {\n execFileSync('apes', ['run', '--as', 'root', '--wait', '--', 'apes', 'agents', 'destroy', name, '--force'], { stdio: 'inherit' })\n consola.success(`Nest will tear down ${name}'s pm2 process on its next reconcile (≤2s).`)\n }\n catch (err: unknown) {\n const status = (err as { status?: number }).status ?? 1\n throw new CliExit(status)\n }\n },\n})\n","// `apes nest install` — bootstrap the local nest-daemon.\n//\n// Stage 1 MVP: the daemon runs as the human user (a future stage will\n// migrate to a dedicated `_openape_nest` service-account). Setup is\n// three things:\n//\n// 1. Write ~/Library/LaunchAgents/ai.openape.nest.plist (user domain\n// — autostarts at login, KeepAlive=true)\n// 2. `launchctl bootstrap` the plist into the user-launchd domain\n// 3. Print instructions for the always-grant the user needs to\n// approve once at id.openape.ai/grant-approval\n//\n// Idempotent — re-running on an already-installed nest just re-bootstraps\n// (effectively a restart).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir, userInfo } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { APES_AGENTS_ADAPTER_TOML } from './apes-agents-adapter'\nimport { NEST_DATA_DIR } from './enroll'\n\nconst PLIST_LABEL = 'ai.openape.nest'\n\nfunction plistPath(): string {\n return join(homedir(), 'Library', 'LaunchAgents', `${PLIST_LABEL}.plist`)\n}\n\nfunction escape(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')\n}\n\ninterface PlistArgs {\n nestBin: string\n apesBin: string\n /** macOS user home — used for log file path + PATH (where bun lives). */\n userHome: string\n /**\n * Nest data dir — `HOME` for the daemon process so apes-cli reads\n * the nest's own auth.json (not the human's) when invoking\n * subprocesses like `apes run --as root -- apes agents spawn`.\n */\n nestHome: string\n port: number\n}\n\nfunction buildPlist(args: PlistArgs): string {\n const logsDir = join(args.userHome, 'Library', 'Logs')\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${escape(PLIST_LABEL)}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escape(args.nestBin)}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${escape(args.nestHome)}</string>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key><string>${escape(args.nestHome)}</string>\n <key>PATH</key><string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n <key>OPENAPE_NEST_PORT</key><string>${args.port}</string>\n <key>OPENAPE_APES_BIN</key><string>${escape(args.apesBin)}</string>\n </dict>\n <key>StandardOutPath</key>\n <string>${escape(logsDir)}/openape-nest.log</string>\n <key>StandardErrorPath</key>\n <string>${escape(logsDir)}/openape-nest.log</string>\n</dict>\n</plist>\n`\n}\n\n/**\n * Bundled `apes-agents` shapes adapter — written into\n * `~/.openape/shapes/adapters/` so a capability-grant with selector\n * `name=*` can cover any agent name (selectorValueMatches glob).\n * Without this adapter, every spawn/destroy hits exact-arg matching\n * and the always-grant doesn't reuse.\n */\nfunction installAdapter(): boolean {\n const target = join(homedir(), '.openape', 'shapes', 'adapters', 'apes-agents.toml')\n mkdirSync(dirname(target), { recursive: true })\n let existing = ''\n try { existing = readFileSync(target, 'utf8') }\n catch { /* not yet */ }\n if (existing === APES_AGENTS_ADAPTER_TOML) return false\n writeFileSync(target, APES_AGENTS_ADAPTER_TOML, { mode: 0o644 })\n consola.success(`Wrote shapes adapter ${target}`)\n return true\n}\n\n/**\n * Write `APE_CHAT_BRIDGE_MODEL=<value>` to `~/litellm/.env` AND to\n * the nest's own `litellm/.env` (under `NEST_DATA_DIR`). The same\n * file resolveBridgeConfig (in lib/llm-bridge.ts) reads at\n * `apes [nest|agents] spawn` time — but it resolves the path via\n * `homedir()`, so:\n *\n * - Patrick-driven spawn (`apes agents spawn …` from a shell)\n * reads `~/litellm/.env`.\n * - Nest-driven spawn (TroopWs handler running as the daemon)\n * reads `~/.openape/nest/litellm/.env` because the launchd plist\n * pins `HOME=NEST_DATA_DIR` for the daemon process.\n *\n * Writing to both keeps the model default consistent between the\n * two entry points — without this, freshly-installed nests had no\n * `APE_CHAT_BRIDGE_MODEL` line and the bridge crash-looped on every\n * spawn-from-troop-UI with `fatal: APE_CHAT_BRIDGE_MODEL is not set`.\n *\n * Idempotent: replaces an existing line in place, appends otherwise.\n */\nfunction writeBridgeModelDefault(model: string): void {\n for (const envDir of [join(homedir(), 'litellm'), join(NEST_DATA_DIR, 'litellm')]) {\n const envFile = join(envDir, '.env')\n mkdirSync(envDir, { recursive: true })\n let lines: string[] = []\n if (existsSync(envFile)) {\n lines = readFileSync(envFile, 'utf8').split('\\n').filter(l => !l.startsWith('APE_CHAT_BRIDGE_MODEL='))\n }\n lines.push(`APE_CHAT_BRIDGE_MODEL=${model}`)\n while (lines.length > 0 && lines.at(-1)!.trim() === '') lines.pop()\n writeFileSync(envFile, `${lines.join('\\n')}\\n`, { mode: 0o600 })\n }\n}\n\nfunction findBinary(name: string): string {\n for (const dir of [\n join(homedir(), '.bun', 'bin'),\n '/opt/homebrew/bin',\n '/usr/local/bin',\n '/usr/bin',\n ]) {\n const p = join(dir, name)\n if (existsSync(p)) return p\n }\n throw new Error(`could not locate ${name} on PATH; install it first`)\n}\n\nexport const installNestCommand = defineCommand({\n meta: {\n name: 'install',\n description: 'Install + start the local nest-daemon (idempotent — re-running just restarts)',\n },\n args: {\n port: {\n type: 'string',\n description: 'Port for the nest HTTP API (default: 9091)',\n },\n 'bridge-model': {\n type: 'string',\n description: 'Default model for ape-agent spawns. Persisted as APE_CHAT_BRIDGE_MODEL in ~/litellm/.env so every `apes [nest|agents] spawn` picks it up automatically. Common values: `gpt-5.4` (ChatGPT-only LiteLLM proxy), `claude-haiku-4-5` (Anthropic-only). Re-run install with a new value to overwrite.',\n },\n },\n async run({ args }) {\n const homeDir = homedir()\n const port = Number(args.port ?? 9091)\n if (!Number.isInteger(port) || port < 1024 || port > 65535) {\n throw new Error(`invalid port ${port}`)\n }\n const nestBin = findBinary('openape-nest')\n const apesBin = findBinary('apes')\n\n consola.info(`Installing nest at ${plistPath()}`)\n consola.info(` nest binary: ${nestBin}`)\n consola.info(` apes binary: ${apesBin}`)\n consola.info(` HTTP port: ${port}`)\n\n if (typeof args['bridge-model'] === 'string' && args['bridge-model']) {\n writeBridgeModelDefault(args['bridge-model'])\n consola.success(`Default bridge model set to ${args['bridge-model']} (in ~/litellm/.env)`)\n }\n\n // Adapter first — capability-grants need it.\n installAdapter()\n\n mkdirSync(join(homeDir, 'Library', 'LaunchAgents'), { recursive: true })\n\n // nest-data-dir is HOME for the daemon — apes-cli subprocesses\n // it spawns (apes run --as root --) read auth.json from the nest's\n // own enrolled identity, not the human's, so YOLO-policy on the\n // nest-agent gates them.\n mkdirSync(NEST_DATA_DIR, { recursive: true })\n const desired = buildPlist({ nestBin, apesBin, userHome: homeDir, nestHome: NEST_DATA_DIR, port })\n let existing = ''\n try { existing = readFileSync(plistPath(), 'utf8') }\n catch { /* not yet installed */ }\n\n if (existing !== desired) {\n writeFileSync(plistPath(), desired, { mode: 0o644 })\n consola.success('Wrote launchd plist')\n }\n else {\n consola.info('plist already up to date')\n }\n\n // Idempotent (re)load. bootout silently no-ops if the job isn't\n // loaded yet; bootstrap fails loud if the plist has a syntax error,\n // which is what we want.\n const uid = userInfo().uid\n try {\n execFileSync('/bin/launchctl', ['bootout', `gui/${uid}/${PLIST_LABEL}`], { stdio: 'ignore' })\n }\n catch { /* not loaded */ }\n execFileSync('/bin/launchctl', ['bootstrap', `gui/${uid}`, plistPath()], { stdio: 'inherit' })\n consola.success(`Nest daemon bootstrapped — http://127.0.0.1:${port}`)\n\n consola.info('')\n consola.info('Next steps for zero-prompt spawn — both one-time:')\n consola.info('')\n consola.info(' 1. apes nest enroll # register nest as DDISA agent (creates own auth.json)')\n consola.info(' 2. apes nest authorize # set YOLO-policy on the nest agent')\n consola.info('')\n consola.info('After that, every `POST http://127.0.0.1:9091/agents` runs without DDISA prompts.')\n },\n})\n","// Bundled `apes-agents` shapes adapter — written into\n// ~/.openape/shapes/adapters/apes-agents.toml by `apes nest install`.\n// Inlined as a TS constant (vs. shipping the .toml file) because tsup\n// only bundles JS/TS — a sibling .toml gets stripped from dist.\n\nexport const APES_AGENTS_ADAPTER_TOML = `schema = \"openape-shapes/v1\"\n\n# Adapter for the \\`apes agents\\` subtree — written by \\`apes nest install\\`.\n# A capability-grant with selector \\`name=*\\` covers any agent name\n# (selectorValueMatches treats '*' as a glob), letting the nest spawn\n# and destroy without per-agent DDISA prompts.\n\n[cli]\nid = \"apes-agents\"\nexecutable = \"apes\"\naudience = \"shapes\"\nversion = \"1\"\n\n# ══════════════════════════════════════════════════════\n# AGENT LIFECYCLE — spawn / destroy / sync\n# ══════════════════════════════════════════════════════\n\n[[operation]]\nid = \"agents.spawn\"\ncommand = [\"agents\", \"spawn\"]\npositionals = [\"name\"]\ndisplay = \"Spawn agent {name}\"\naction = \"create\"\nrisk = \"high\"\nresource_chain = [\"agents:name={name}\"]\n\n[[operation]]\nid = \"agents.destroy\"\ncommand = [\"agents\", \"destroy\"]\npositionals = [\"name\"]\ndisplay = \"Destroy agent {name}\"\naction = \"delete\"\nrisk = \"critical\"\nresource_chain = [\"agents:name={name}\"]\n\n[[operation]]\nid = \"agents.sync\"\ncommand = [\"agents\", \"sync\"]\ndisplay = \"Sync agent state with troop\"\naction = \"edit\"\nrisk = \"low\"\nresource_chain = [\"agents:*\"]\n\n[[operation]]\nid = \"agents.list\"\ncommand = [\"agents\", \"list\"]\ndisplay = \"List agents\"\naction = \"list\"\nrisk = \"low\"\nresource_chain = [\"agents:*\"]\n\n[[operation]]\nid = \"agents.allow\"\ncommand = [\"agents\", \"allow\"]\npositionals = [\"name\", \"peer_email\"]\ndisplay = \"Allow agent {name} to accept contact requests from {peer_email}\"\naction = \"edit\"\nrisk = \"medium\"\nresource_chain = [\"agents:name={name}\", \"allowlist:email={peer_email}\"]\n`\n","// `apes nest list` — Phase F: read the registry directly. No\n// inter-process communication needed; the file is shared between\n// Nest + apes-cli (mode 660 group _openape_nest, Patrick is in the\n// group post-migration).\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { readNestRegistry } from '../../lib/nest-registry'\n\nexport const listNestCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List agents registered with the local nest. Reads /var/openape/nest/agents.json directly.',\n },\n args: {\n json: { type: 'boolean', description: 'JSON output for scripts' },\n },\n async run({ args }) {\n const reg = readNestRegistry()\n if (args.json) {\n console.log(JSON.stringify(reg, null, 2))\n return\n }\n if (reg.agents.length === 0) {\n consola.info('(no agents registered with this nest)')\n return\n }\n consola.info(`${reg.agents.length} agent(s) registered with this nest:`)\n for (const a of reg.agents) {\n const bridge = a.bridge ? ' bridge=on' : ''\n consola.info(` ${a.name.padEnd(16)} uid=${String(a.uid).padEnd(5)} home=${a.home}${bridge}`)\n }\n },\n})\n","// `apes nest spawn <name>` — Phase F (#sim-arch): direct shell-out to\n// `apes run --as root --wait -- apes agents spawn ...`. The spawn\n// command itself writes to the Nest's `agents.json` registry; the\n// Nest watches the file and starts the bridge via pm2 automatically.\n// No intent-channel, no HTTP API — the CLI just does the work.\n\nimport { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliExit } from '../../errors'\n\nexport const spawnNestCommand = defineCommand({\n meta: {\n name: 'spawn',\n 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.',\n },\n args: {\n name: { type: 'positional', required: true, description: 'Agent name (lowercase, [a-z0-9-], max 24 chars)' },\n 'no-bridge': { type: 'boolean', description: 'Skip installing the chat-bridge daemon (default: install it)' },\n 'bridge-key': { type: 'string', description: 'Override LITELLM_API_KEY (default: read from ~/litellm/.env)' },\n 'bridge-base-url': { type: 'string', description: 'Override LITELLM_BASE_URL' },\n 'bridge-model': { type: 'string', description: 'Override APE_CHAT_BRIDGE_MODEL' },\n },\n async run({ args }) {\n const name = String(args.name)\n const apesArgs = [\n 'run', '--as', 'root', '--wait', '--', 'apes', 'agents', 'spawn', name,\n ]\n // Inner `apes agents spawn` installs the bridge by default; pass the\n // opt-out through when the user gave us --no-bridge here.\n if (args['no-bridge']) apesArgs.push('--no-bridge')\n if (typeof args['bridge-key'] === 'string') apesArgs.push('--bridge-key', args['bridge-key'])\n if (typeof args['bridge-base-url'] === 'string') apesArgs.push('--bridge-base-url', args['bridge-base-url'])\n if (typeof args['bridge-model'] === 'string') apesArgs.push('--bridge-model', args['bridge-model'])\n\n try {\n execFileSync('apes', apesArgs, { stdio: 'inherit' })\n consola.success(`Nest will pick up ${name} on its next reconcile (≤2s).`)\n }\n catch (err: unknown) {\n const status = (err as { status?: number }).status ?? 1\n throw new CliExit(status)\n }\n },\n})\n","// `apes nest uninstall` — bootout + remove the nest-daemon's launchd\n// plist. Doesn't touch the registered agents or their macOS users —\n// they stay; only the supervisor goes away. After uninstall, agents\n// can still be re-supervised by re-installing later (registry persists\n// at ~/.openape/nest/agents.json).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, unlinkSync } from 'node:fs'\nimport { homedir, userInfo } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nconst PLIST_LABEL = 'ai.openape.nest'\n\nexport const uninstallNestCommand = defineCommand({\n meta: {\n name: 'uninstall',\n description: 'Stop + remove the local nest-daemon (registry + agents preserved)',\n },\n async run() {\n const uid = userInfo().uid\n const path = join(homedir(), 'Library', 'LaunchAgents', `${PLIST_LABEL}.plist`)\n try {\n execFileSync('/bin/launchctl', ['bootout', `gui/${uid}/${PLIST_LABEL}`], { stdio: 'ignore' })\n consola.success('Nest daemon stopped')\n }\n catch {\n consola.info('Nest daemon was not loaded')\n }\n if (existsSync(path)) {\n unlinkSync(path)\n consola.success(`Removed ${path}`)\n }\n consola.info('Registry at ~/.openape/nest/agents.json kept — re-run `apes nest install` to resume supervision.')\n },\n})\n","import { defineCommand } from 'citty'\nimport { yoloClearCommand } from './clear'\nimport { yoloSetCommand } from './set'\nimport { yoloShowCommand } from './show'\n\nexport const yoloCommand = defineCommand({\n meta: {\n name: 'yolo',\n description: 'Manage YOLO-policies on DDISA agents you own — auto-approve grant patterns at the IdP layer (allow-list) or block dangerous ones outright (deny-list).',\n },\n subCommands: {\n set: yoloSetCommand,\n show: yoloShowCommand,\n clear: yoloClearCommand,\n },\n})\n","// `apes yolo clear <agent-email>` — remove the YOLO-policy from a\n// DDISA agent. After clear, every grant request goes through normal\n// human approval. Useful for revocation: drop the policy and the agent\n// can no longer auto-approve anything until you set a new one.\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const yoloClearCommand = defineCommand({\n meta: {\n name: 'clear',\n description: 'Remove the YOLO-policy from a DDISA agent (subsequent grants need human approval)',\n },\n args: {\n email: {\n type: 'positional',\n description: 'Target agent email',\n required: true,\n },\n },\n async run({ args }) {\n const ownerAuth = loadAuth()\n if (!ownerAuth?.access_token) {\n throw new CliError('Run `apes login <email>` first.')\n }\n const idp = getIdpUrl()\n if (!idp) throw new CliError('No IdP configured.')\n\n const email = args.email as string\n const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`\n const res = await fetch(url, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${ownerAuth.access_token}` },\n })\n if (!res.ok && res.status !== 404) {\n const text = await res.text().catch(() => '')\n throw new CliError(`DELETE /yolo-policy failed (${res.status}): ${text}`)\n }\n consola.success(`YOLO-policy cleared on ${email}`)\n },\n})\n","// `apes yolo set <agent-email>` — write a YOLO-policy on a DDISA agent\n// you own. The IdP's grant-creation hook evaluates the agent's policy\n// before opening the human-approval flow; allow_patterns matches mean\n// \"auto-approve, no prompt\" (mode='allow-list') and deny_patterns means\n// \"block without asking\" (mode='deny-list').\n//\n// PUT-shape mirrors the IdP endpoint\n// `/api/users/<email>/yolo-policy` (modules/nuxt-auth-idp). Owner-auth\n// is enforced server-side: only the agent's owner / approver / admin\n// can change the policy, regardless of who's invoking the CLI.\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\nconst VALID_MODES = ['allow-list', 'deny-list'] as const\ntype Mode = typeof VALID_MODES[number]\n\nexport const yoloSetCommand = defineCommand({\n meta: {\n name: 'set',\n description: 'Write a YOLO-policy on a DDISA agent you own',\n },\n args: {\n 'email': {\n type: 'positional',\n description: 'Target agent email (e.g. nest-mac-cb6bf26a+patrick+example_com@id.openape.ai)',\n required: true,\n },\n 'mode': {\n type: 'string',\n description: 'Policy mode (allow-list | deny-list)',\n },\n 'allow': {\n type: 'string',\n description: 'Allow patterns — comma-separated bash globs (e.g. \"apes agents spawn *,apes agents sync\")',\n },\n 'deny': {\n type: 'string',\n description: 'Deny patterns — comma-separated bash globs',\n },\n 'deny-risk': {\n type: 'string',\n description: 'Deny grants at this risk level or above (low|medium|high|critical)',\n },\n 'expires-in': {\n type: 'string',\n description: 'Optional expiry like 30d, 6h, 2w. Omit for no expiry.',\n },\n },\n async run({ args }) {\n const ownerAuth = loadAuth()\n if (!ownerAuth?.access_token) {\n throw new CliError('Run `apes login <email>` first.')\n }\n const idp = getIdpUrl()\n if (!idp) throw new CliError('No IdP configured.')\n\n const email = args.email as string\n const mode = (args.mode as string | undefined) ?? 'allow-list'\n if (!VALID_MODES.includes(mode as Mode)) {\n throw new CliError(`mode must be one of: ${VALID_MODES.join(', ')}`)\n }\n const allowPatterns = parseList(args.allow as string | undefined)\n const denyPatterns = parseList(args.deny as string | undefined)\n const denyRiskThreshold = (args['deny-risk'] as string | undefined) ?? null\n const expiresAt = parseExpiresIn(args['expires-in'] as string | undefined)\n\n consola.info(`Setting YOLO-policy on ${email}`)\n consola.info(` mode: ${mode}`)\n if (allowPatterns.length) consola.info(` allow_patterns: ${allowPatterns.join(', ')}`)\n if (denyPatterns.length) consola.info(` deny_patterns: ${denyPatterns.join(', ')}`)\n if (denyRiskThreshold) consola.info(` deny_risk: ${denyRiskThreshold}`)\n if (expiresAt) consola.info(` expires_at: ${new Date(expiresAt * 1000).toISOString()}`)\n\n const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`\n const res = await fetch(url, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${ownerAuth.access_token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n mode,\n allowPatterns,\n denyPatterns,\n denyRiskThreshold,\n expiresAt: expiresAt ?? null,\n }),\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new CliError(`PUT /yolo-policy failed (${res.status}): ${text}`)\n }\n consola.success(`YOLO-policy applied to ${email}`)\n },\n})\n\nfunction parseList(s: string | undefined): string[] {\n if (!s) return []\n return s.split(',').map(p => p.trim()).filter(Boolean)\n}\n\nfunction parseExpiresIn(s: string | undefined): number | null {\n if (!s) return null\n const m = s.match(/^(\\d+)([hdw])$/)\n if (!m) throw new CliError(`Invalid --expires-in \"${s}\" — expected forms like 30d, 6h, 2w`)\n const n = Number(m[1])\n const unit = m[2]\n const seconds = unit === 'h' ? 3600 : unit === 'd' ? 86400 : 7 * 86400\n return Math.floor(Date.now() / 1000) + n * seconds\n}\n","// `apes yolo show <agent-email>` — print the YOLO-policy currently set\n// on an agent. Returns the empty default (`mode: deny-list`, no patterns)\n// when no policy has been written. JSON output via --json.\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\ninterface YoloPolicy {\n mode: string\n allowPatterns: string[]\n denyPatterns: string[]\n denyRiskThreshold: string | null\n expiresAt: number | null\n}\n\nexport const yoloShowCommand = defineCommand({\n meta: {\n name: 'show',\n description: 'Print the YOLO-policy currently set on a DDISA agent',\n },\n args: {\n email: {\n type: 'positional',\n description: 'Target agent email',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'JSON output for scripts',\n },\n },\n async run({ args }) {\n const ownerAuth = loadAuth()\n if (!ownerAuth?.access_token) {\n throw new CliError('Run `apes login <email>` first.')\n }\n const idp = getIdpUrl()\n if (!idp) throw new CliError('No IdP configured.')\n\n const email = args.email as string\n const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${ownerAuth.access_token}` },\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new CliError(`GET /yolo-policy failed (${res.status}): ${text}`)\n }\n const policy = (await res.json()) as YoloPolicy\n\n if (args.json) {\n console.log(JSON.stringify(policy, null, 2))\n return\n }\n consola.info(`YOLO-policy for ${email}`)\n consola.info(` mode: ${policy.mode}`)\n consola.info(` allow_patterns: ${policy.allowPatterns.length ? policy.allowPatterns.join(', ') : '(none)'}`)\n consola.info(` deny_patterns: ${policy.denyPatterns.length ? policy.denyPatterns.join(', ') : '(none)'}`)\n consola.info(` deny_risk: ${policy.denyRiskThreshold ?? '(none)'}`)\n consola.info(` expires_at: ${policy.expiresAt ? new Date(policy.expiresAt * 1000).toISOString() : '(never)'}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport {\n fetchRegistry,\n findAdapter,\n findConflictingAdapters,\n getInstalledDigest,\n installAdapter,\n isInstalled,\n loadAdapter,\n removeAdapter,\n searchAdapters,\n} from '../../shapes/index.js'\nimport { CliError } from '../../errors'\n\nexport const adapterCommand = defineCommand({\n meta: {\n name: 'adapter',\n description: 'Manage CLI adapters',\n },\n subCommands: {\n list: defineCommand({\n meta: {\n name: 'list',\n description: 'List available adapters',\n },\n args: {\n remote: {\n type: 'boolean',\n description: 'List adapters from the remote registry',\n default: false,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const forceRefresh = Boolean(args.refresh)\n if (args.remote) {\n const index = await fetchRegistry(forceRefresh)\n if (args.json) {\n process.stdout.write(`${JSON.stringify(index.adapters, null, 2)}\\n`)\n return\n }\n consola.info(`Registry: ${index.adapters.length} adapters (${index.generated_at})`)\n for (const a of index.adapters) {\n const installed = isInstalled(a.id, false) ? ' [installed]' : ''\n console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}${installed}`)\n }\n return\n }\n\n const index = await fetchRegistry(forceRefresh)\n const local: { id: string, source: string, digest: string }[] = []\n for (const a of index.adapters) {\n try {\n const loaded = loadAdapter(a.id)\n local.push({ id: a.id, source: loaded.source, digest: loaded.digest })\n }\n catch {\n // not installed locally\n }\n }\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(local, null, 2)}\\n`)\n return\n }\n\n if (local.length === 0) {\n consola.info('No adapters installed. Use `apes adapter list --remote` to see available adapters.')\n return\n }\n\n for (const a of local) {\n console.log(` ${a.id.padEnd(12)} ${a.source}`)\n }\n },\n }),\n\n install: defineCommand({\n meta: {\n name: 'install',\n description: 'Install an adapter from the registry',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID to install',\n required: true,\n },\n local: {\n type: 'boolean',\n description: 'Install to project-local .openape/ instead of ~/.openape/',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const ids = [String(args.id), ...args._].filter(Boolean)\n const local = Boolean(args.local)\n const index = await fetchRegistry(Boolean(args.refresh))\n\n for (const id of ids) {\n const entry = findAdapter(index, id)\n if (!entry) {\n consola.error(`Adapter \"${id}\" not found in registry. Use \\`apes adapter search ${id}\\` to search.`)\n continue\n }\n\n const conflicts = findConflictingAdapters(entry.executable, id)\n if (conflicts.length > 0) {\n for (const c of conflicts) {\n consola.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`)\n consola.warn(` Remove it with: apes adapter remove ${c.adapterId}`)\n }\n }\n\n const result = await installAdapter(entry, { local })\n const verb = result.updated ? 'Updated' : 'Installed'\n consola.success(`${verb} ${result.id} → ${result.path}`)\n consola.info(`Digest: ${result.digest}`)\n }\n },\n }),\n\n remove: defineCommand({\n meta: {\n name: 'remove',\n description: 'Remove an installed adapter',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID to remove',\n required: true,\n },\n local: {\n type: 'boolean',\n description: 'Remove from project-local .openape/',\n default: false,\n },\n },\n async run({ args }) {\n const ids = [String(args.id), ...args._].filter(Boolean)\n const local = Boolean(args.local)\n let failed = false\n\n for (const id of ids) {\n if (removeAdapter(id, local)) {\n consola.success(`Removed adapter: ${id}`)\n }\n else {\n consola.error(`Adapter \"${id}\" is not installed${local ? ' locally' : ''}`)\n failed = true\n }\n }\n\n if (failed)\n throw new CliError('Some adapters could not be removed')\n },\n }),\n\n info: defineCommand({\n meta: {\n name: 'info',\n description: 'Show detailed adapter information',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID',\n required: true,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const id = String(args.id)\n const index = await fetchRegistry(Boolean(args.refresh))\n const entry = findAdapter(index, id)\n if (!entry)\n throw new Error(`Adapter \"${id}\" not found in registry`)\n\n console.log(`ID: ${entry.id}`)\n console.log(`Name: ${entry.name}`)\n console.log(`Description: ${entry.description}`)\n console.log(`Category: ${entry.category}`)\n console.log(`Tags: ${entry.tags.join(', ')}`)\n console.log(`Author: ${entry.author}`)\n console.log(`Executable: ${entry.executable}`)\n console.log(`Digest: ${entry.digest}`)\n console.log(`Min version: ${entry.min_shapes_version}`)\n console.log(`URL: ${entry.download_url}`)\n\n const localDigest = getInstalledDigest(id, false)\n if (localDigest) {\n const upToDate = localDigest === entry.digest\n console.log(`Installed: yes${upToDate ? ' (up to date)' : ' (update available)'}`)\n }\n else {\n console.log(`Installed: no`)\n }\n },\n }),\n\n search: defineCommand({\n meta: {\n name: 'search',\n description: 'Search adapters in the registry',\n },\n args: {\n query: {\n type: 'positional',\n description: 'Search query',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const query = String(args.query)\n const index = await fetchRegistry(Boolean(args.refresh))\n const results = searchAdapters(index, query)\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(results, null, 2)}\\n`)\n return\n }\n\n if (results.length === 0) {\n consola.info(`No adapters matching \"${query}\"`)\n return\n }\n\n for (const a of results) {\n console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}`)\n console.log(` ${a.description}`)\n }\n },\n }),\n\n update: defineCommand({\n meta: {\n name: 'update',\n description: 'Update installed adapters',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID (omit to update all)',\n },\n yes: {\n type: 'boolean',\n description: 'Skip confirmation',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: true,\n },\n },\n async run({ args }) {\n const index = await fetchRegistry(Boolean(args.refresh))\n const targetId = args.id ? String(args.id) : undefined\n const targets = targetId\n ? [targetId]\n : index.adapters.map(a => a.id).filter(id => isInstalled(id, false))\n\n if (targets.length === 0) {\n consola.info('No adapters installed to update.')\n return\n }\n\n for (const id of targets) {\n const entry = findAdapter(index, id)\n if (!entry) {\n consola.warn(`${id}: not found in registry, skipping`)\n continue\n }\n\n const localDigest = getInstalledDigest(id, false)\n if (localDigest === entry.digest) {\n consola.info(`${id}: already up to date`)\n continue\n }\n\n if (localDigest && !args.yes) {\n consola.warn(`${id}: digest will change — existing grants for this adapter will be invalidated`)\n consola.info(` Old: ${localDigest}`)\n consola.info(` New: ${entry.digest}`)\n consola.info(' Use --yes to confirm')\n continue\n }\n\n const result = await installAdapter(entry)\n consola.success(`Updated ${result.id} → ${result.path}`)\n }\n },\n }),\n\n verify: defineCommand({\n meta: {\n name: 'verify',\n description: 'Verify installed adapter against registry digest',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID',\n required: true,\n },\n local: {\n type: 'boolean',\n description: 'Check project-local adapter',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const id = String(args.id)\n const local = Boolean(args.local)\n const index = await fetchRegistry(Boolean(args.refresh))\n const entry = findAdapter(index, id)\n if (!entry)\n throw new Error(`Adapter \"${id}\" not found in registry`)\n\n const localDigest = getInstalledDigest(id, local)\n if (!localDigest)\n throw new Error(`Adapter \"${id}\" is not installed${local ? ' locally' : ''}`)\n\n if (localDigest === entry.digest) {\n consola.success(`${id}: digest matches registry`)\n }\n else {\n console.log(` Local: ${localDigest}`)\n console.log(` Registry: ${entry.digest}`)\n throw new CliError(`${id}: digest mismatch`)\n }\n },\n }),\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { hostname } from 'node:os'\nimport { basename } from 'node:path'\nimport { defineCommand } from 'citty'\nimport {\n createShapesGrant,\n extractOption,\n extractShellCommandString,\n extractWrappedCommand,\n fetchGrantToken,\n findExistingGrant,\n loadAdapter,\n loadOrInstallAdapter,\n parseShellCommand,\n resolveCommand,\n resolveGenericOrReject,\n verifyAndExecute,\n waitForGrantStatus,\n} from '../shapes/index.js'\nimport type { ResolvedCommand } from '../shapes/index.js'\nimport consola from 'consola'\nimport { getIdpUrl, isGenericFallbackEnabled, loadAuth, loadConfig } from '../config'\nimport { getPollMaxMinutes } from '../grant-poll'\nimport { apiFetch, getGrantsEndpoint } from '../http'\nimport { CliError, CliExit } from '../errors'\nimport { notifyGrantPending } from '../notifications'\nimport { checkSudoRejection, isApesSelfDispatch } from '../shell/apes-self-dispatch'\nimport { AGENT_NAME_REGEX } from '../lib/agent-bootstrap'\nimport { isDarwin, macOSUsernameForAgent, readMacOSUser } from '../lib/macos-user'\n\n/**\n * Map an agent name (`igor`) to its macOS username (`openape-agent-igor`)\n * when the prefixed dscl record exists. Returns the input unchanged for:\n * - non-Darwin platforms (escapes-helper isn't macOS-specific in theory)\n * - non-agent values like `root`, `_postgres`, etc.\n * - legacy agents that pre-date the prefix (the prefixed record is\n * absent, so we fall through and let escapes setuid to the plain\n * name — backward-compatible)\n *\n * The mapping is transparent to all callers: nest/troop-ws.ts,\n * pm2-supervisor.ts, allow.ts and operators typing `apes run --as\n * igor` keep working without knowing about the prefix.\n */\nfunction resolveRunAsTarget(runAs: string | undefined): string | undefined {\n if (!runAs) return runAs\n if (!isDarwin()) return runAs\n if (!AGENT_NAME_REGEX.test(runAs)) return runAs\n // Already prefixed (operator typed the full macOS username) — pass through.\n if (runAs.startsWith('openape-agent-')) return runAs\n const prefixed = macOSUsernameForAgent(runAs)\n if (readMacOSUser(prefixed)) return prefixed\n return runAs\n}\n\n/**\n * Returns true when the caller asked for the legacy blocking path via\n * `--wait` or `APE_WAIT=1`. Default is non-blocking (async exit).\n */\nfunction shouldWaitForGrant(args: Record<string, unknown>): boolean {\n return args.wait === true || process.env.APE_WAIT === '1'\n}\n\n/**\n * Audience of the `apes run` async info block. Drives whether the output\n * targets a human reader (short, friendly) or an AI agent (verbose, with\n * explicit polling protocol).\n *\n * Default is `'agent'` — zero-config for agent ecosystems (openclaw, Claude,\n * etc.), and humans who want brevity just set `APES_USER=human` once in\n * their shell rc. Env var wins over config.toml; unknown values fall back\n * to the agent default.\n */\ntype ApesUserMode = 'agent' | 'human'\n\nfunction getUserMode(): ApesUserMode {\n const envValue = process.env.APES_USER\n if (envValue === 'human')\n return 'human'\n if (envValue === 'agent')\n return 'agent'\n const cfg = loadConfig()\n if (cfg.defaults?.user === 'human')\n return 'human'\n return 'agent'\n}\n\n// When apes runs a wrapped command for an agent (ape-shell / `apes run --\n// <cmd>`), the agent captures THIS process's stdout as the command's\n// result. The wrapped command's own output reaches fd 1 directly\n// (execFileSync stdio:'inherit'), but apes's own diagnostics — grant\n// requests, adapter installs, \"Fetching grant token\", etc., emitted via\n// consola and console.log — also write to the JS-level stdout stream and\n// would corrupt that result (e.g. `gh … --jq '.[].number'` returning\n// \"ℹ Requesting grant…\\n473\"). Point JS-level stdout writes at stderr for\n// the duration so the captured result is exactly the wrapped command's\n// output. The wrapped command (fd 1) is unaffected; the grant-token\n// branch keeps its token on real stdout via writeRealStdout. Human mode\n// is untouched — diagnostics stay on stdout for interactive use.\nlet writeRealStdout: (s: string) => void = (s) => { process.stdout.write(s) }\n\nfunction routeDiagnosticsToStderrForWrappedAgentRun(): void {\n const original = process.stdout.write.bind(process.stdout)\n writeRealStdout = (s) => { original(s) }\n process.stdout.write = ((chunk: string | Uint8Array, ...rest: unknown[]) =>\n (process.stderr.write as (c: string | Uint8Array, ...a: unknown[]) => boolean)(chunk, ...rest)\n ) as typeof process.stdout.write\n}\n\n// Poll interval + max-minutes helpers live in `../grant-poll.ts` so they\n// are shared with the CLI-side wait loop in `commands/grants/run.ts --wait`.\n// See that module for the full rationale; in this file we only need the\n// max-minutes value for the agent-facing text block.\n\n/**\n * Exit code for the async-default pending-grant path.\n *\n * Default is **75** (`EX_TEMPFAIL` from `sysexits.h`, semantically \"temporary\n * failure — try again later\"). This is the clearest POSIX-adjacent signal\n * that the command was accepted but the target action has not yet been\n * performed and needs a retry. Unlike exit 1 (general error) or exit 2\n * (usage error), 75 does not collide with common shell conventions, and\n * it happens to be the same code `sendmail` and other mail delivery agents\n * have used for decades to signal \"defer and retry\".\n *\n * The non-zero exit has a very practical effect on AI-agent consumers:\n * openclaw's exec-runtime (and most similar frameworks) maps non-zero\n * exits to a `failed` / `error` tool-result status, which LLMs attend\n * to much more carefully than a `success` result with the same text in\n * stdout. In 0.9.3 we added explicit agent-facing instructions to the\n * async info block; in practice agents still ignored them because the\n * wrapping tool-result looked like a success. The non-zero exit is the\n * structural attention anchor that the text alone couldn't provide.\n *\n * Overridable via `APES_ASYNC_EXIT_CODE` env var or `config.toml`\n * `defaults.async_exit_code`. Set to `0` to restore the legacy exit-0\n * behaviour (for CI scripts that rely on it, or humans who find the\n * non-zero exit noisy). Valid range is 0–255 (POSIX exit code space);\n * bogus values fall back to the default 75.\n */\nfunction getAsyncExitCode(): number {\n const envValue = process.env.APES_ASYNC_EXIT_CODE\n if (envValue !== undefined && envValue !== '') {\n const n = Number(envValue)\n if (Number.isFinite(n) && n >= 0 && n <= 255)\n return Math.floor(n)\n }\n const cfg = loadConfig()\n const cfgValue = cfg.defaults?.async_exit_code\n if (cfgValue !== undefined && cfgValue !== '') {\n const n = Number(cfgValue)\n if (Number.isFinite(n) && n >= 0 && n <= 255)\n return Math.floor(n)\n }\n return 75 // EX_TEMPFAIL\n}\n\n/**\n * Print the async info block for a freshly created pending grant. Two\n * output modes:\n *\n * - **agent** (default): verbose, with an explicit polling protocol so\n * the consuming LLM knows exactly what to do next. Tells the agent to\n * poll `apes grants status <id> --json` every N seconds for up to M\n * minutes, handle each terminal status, and run `apes grants run <id>`\n * once approved. Every agent in every ecosystem sees the same text\n * without needing a per-tool skill integration.\n *\n * - **human** (opt-in via `APES_USER=human` or `config.toml` defaults.user):\n * short, friendly, no polling block. Humans at a terminal know to wait\n * for approval and then come back.\n *\n * Both modes keep the same core Approve / Status / Execute lines so\n * external scripts that grep for those labels keep working.\n */\nfunction printPendingGrantInfo(grant: { id: string }, idp: string): void {\n const mode = getUserMode()\n const approveUrl = `${idp}/grant-approval?grant_id=${grant.id}`\n const statusCmd = `apes grants status ${grant.id}`\n const executeCmd = `apes grants run ${grant.id}`\n\n if (mode === 'human') {\n consola.success(`Grant ${grant.id} created — awaiting your approval`)\n console.log(` Approve in browser: ${approveUrl}`)\n console.log(` Check status: ${statusCmd}`)\n console.log(` Run after approval: ${executeCmd}`)\n console.log('')\n console.log(' Tip: Approve as \"timed\" or \"always\" in the browser to reuse')\n console.log(' this grant without re-approval on the next invocation.')\n return\n }\n\n // agent mode (default)\n const maxMin = getPollMaxMinutes()\n consola.success(`Grant ${grant.id} created (pending approval)`)\n console.log(` Approve: ${approveUrl}`)\n console.log(` Status: ${statusCmd} [--json]`)\n console.log(` Execute: ${executeCmd} --wait`)\n console.log('')\n console.log(' For agents:')\n console.log(` 1. Tell the user about the pending grant and the approve URL above.`)\n console.log(` 2. Run \\`${executeCmd} --wait\\`. This blocks up to ${maxMin} minutes`)\n console.log(` until the user approves (or denies/timeout) and then executes`)\n console.log(` the command in a single step. The CLI handles the polling loop`)\n console.log(` internally — you do not need to poll the status yourself.`)\n console.log(` 3. Exit 0 means approved + executed; stdout is the command output.`)\n console.log(` Exit 75 (pending) only appears if you accidentally call this`)\n console.log(` without --wait. Any other non-zero exit means denied, revoked,`)\n console.log(` used, or timeout — report the reason to the user.`)\n console.log('')\n console.log(' Note: exit code 75 (EX_TEMPFAIL) from this command means \"pending,')\n console.log(' retry later\" — do not abort your workflow, follow the steps above.')\n console.log('')\n console.log(' Tip: Approve as \"timed\" or \"always\" in the browser to let this')\n console.log(' grant be reused on subsequent invocations without re-approval.')\n}\n\nexport const runCommand = defineCommand({\n meta: {\n name: 'run',\n description: 'Execute a grant-secured command',\n },\n args: {\n 'approval': {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n 'reason': {\n type: 'string',\n description: 'Reason for the grant request',\n },\n 'adapter': {\n type: 'string',\n description: 'Explicit path to adapter TOML file',\n },\n 'as': {\n type: 'string',\n description: 'Execute as this user (delegates to escapes)',\n },\n 'host': {\n type: 'string',\n description: 'Target host (default: system hostname)',\n },\n 'escapes-path': {\n type: 'string',\n description: 'Path to escapes binary',\n default: 'escapes',\n },\n 'idp': {\n type: 'string',\n description: 'IdP URL',\n },\n 'shell': {\n type: 'boolean',\n description: 'Shell mode: use session grant with audience ape-shell',\n default: false,\n },\n 'wait': {\n type: 'boolean',\n description: 'Block until grant is approved (default: async, print grant info and exit 0). Equivalent to APE_WAIT=1.',\n default: false,\n },\n '_': {\n type: 'positional',\n description: 'Command to execute (after --)',\n required: false,\n },\n },\n async run({ rawArgs, args }) {\n const wrappedCommand = extractWrappedCommand(rawArgs ?? [])\n\n // Agent capturing a wrapped command's stdout — keep apes diagnostics\n // off it (see routeDiagnosticsToStderrForWrappedAgentRun).\n if (wrappedCommand.length > 0 && getUserMode() === 'agent') {\n routeDiagnosticsToStderrForWrappedAgentRun()\n }\n\n if (args.shell && wrappedCommand.length > 0) {\n // Shell mode: ape-shell -c \"command\" → apes run --shell -- bash -c \"command\"\n await runShellMode(wrappedCommand, args)\n return\n }\n\n if (wrappedCommand.length > 0) {\n // Adapter mode: apes run [options] -- <cli> <args...>\n await runAdapterMode(wrappedCommand, rawArgs ?? [], args)\n }\n else {\n // Audience mode: apes run <audience> <action>\n // Extract audience and action from rawArgs (before --)\n const positionals = extractPositionals(rawArgs ?? [])\n if (positionals.length < 2)\n throw new Error('Usage: apes run -- <cli> <args...> OR apes run <audience> <action>')\n await runAudienceMode(positionals[0]!, positionals[1]!, args)\n }\n },\n})\n\nasync function runShellMode(\n command: string[],\n args: Record<string, unknown>,\n) {\n const auth = loadAuth()\n if (!auth)\n throw new CliError('Not logged in. Run `apes login` first.')\n\n const idp = getIdpUrl(args.idp as string | undefined)\n if (!idp)\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n\n // --- 0. apes self-dispatch shortcut (pre-adapter) ---\n // If `ape-shell -c \"apes <subcmd>\"` was rewritten into this shell-mode\n // invocation, the inner command is a trusted apes self-call and should\n // bypass the grant flow entirely. Same trust-root reasoning as the\n // interactive REPL path in `shell/grant-dispatch.ts` — see\n // `shell/apes-self-dispatch.ts` for the full rationale. Without this,\n // polling flows like openclaw's `ape-shell -c \"apes grants status <id>\"`\n // cascade infinitely: every poll creates a new pending grant, every\n // grant needs approval, turtles all the way down.\n const innerLine = extractShellCommandString(command)\n if (innerLine) {\n const parsedInner = parseShellCommand(innerLine)\n if (isApesSelfDispatch(parsedInner)) {\n execShellCommand(command)\n return\n }\n // --- 0b. sudo reject ---\n // Parallels the REPL path in `shell/grant-dispatch.ts`. Agents that\n // habitually prefix commands with `sudo` inside `ape-shell -c \"…\"`\n // would otherwise silently fall through to the generic session-grant\n // path and ultimately hit a bash error with no guidance. Short-circuit\n // with an explicit migration hint to `apes run --as root -- <cmd>`.\n const sudoRejection = checkSudoRejection(parsedInner)\n if (sudoRejection)\n throw new CliError(sudoRejection.reason)\n }\n\n // Try to handle this command via the shapes adapter system first.\n // This gives us structured grants with resource chains (e.g. \"rm file:/tmp/foo.txt\")\n // instead of opaque \"bash -c …\" grants.\n const adapterHandled = await tryAdapterModeFromShell(command, idp, args)\n if (adapterHandled) return\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const targetHost = (args.host as string) || hostname()\n\n // Try to find an existing timed/always session grant for ape-shell\n try {\n const grants = await apiFetch<{ data: Array<{ id: string, status: string, request: { audience: string, target_host: string, grant_type: string } }> }>(\n `${grantsUrl}?requester=${encodeURIComponent(auth.email)}&status=approved&limit=20`,\n )\n const sessionGrant = grants.data.find(g =>\n g.request.audience === 'ape-shell'\n && g.request.target_host === targetHost\n && g.request.grant_type !== 'once',\n )\n if (sessionGrant) {\n execShellCommand(command)\n return\n }\n }\n catch {\n // Fall through to creating a new grant\n }\n\n // No session grant found — request one. Default: 'once', but the approver\n // can upgrade to 'timed' or 'always' during approval to enable reuse.\n consola.info(`Requesting ape-shell session grant on ${targetHost}`)\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n body: {\n requester: auth.email,\n target_host: targetHost,\n audience: 'ape-shell',\n grant_type: 'once',\n command: command.slice(0, 3),\n reason: `Shell session: ${command.join(' ').slice(0, 100)}`,\n },\n })\n\n notifyGrantPending({\n grantId: grant.id,\n approveUrl: `${idp}/grant-approval?grant_id=${grant.id}`,\n command: command.join(' ').slice(0, 200),\n audience: 'ape-shell',\n host: targetHost,\n })\n\n if (shouldWaitForGrant(args)) {\n consola.info(`Grant requested: ${grant.id}`)\n consola.info('Waiting for approval...')\n\n const maxWait = 300_000\n const interval = 3_000\n const start = Date.now()\n\n while (Date.now() - start < maxWait) {\n const status = await apiFetch<{ status: string }>(`${grantsUrl}/${grant.id}`)\n if (status.status === 'approved')\n break\n if (status.status === 'denied' || status.status === 'revoked')\n throw new CliError(`Grant ${status.status}.`)\n await new Promise(r => setTimeout(r, interval))\n }\n\n execShellCommand(command)\n return\n }\n\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n}\n\n/**\n * Try to handle a shell command via the shapes adapter system.\n *\n * Flow:\n * 1. Extract the command string from `bash -c \"…\"` argv\n * 2. Parse into executable + argv (bail out on compound commands)\n * 3. Load adapter locally, or auto-install from registry\n * 4. Resolve the command against adapter operations → structured CLI grant detail\n * 5. Reuse an existing matching grant, or request a new one and execute\n *\n * Returns true when the command was handled (executed or failed hard).\n * Returns false for any reason — caller should fall back to the generic session grant.\n */\nasync function tryAdapterModeFromShell(\n command: string[],\n idp: string,\n args: Record<string, unknown>,\n): Promise<boolean> {\n const cmdString = extractShellCommandString(command)\n if (!cmdString) return false\n\n const parsed = parseShellCommand(cmdString)\n if (!parsed) return false\n if (parsed.isCompound) return false\n\n const loaded = await loadOrInstallAdapter(parsed.executable)\n if (!loaded) return false\n\n // resolveCommand does a strict comparison against `adapter.cli.executable`,\n // which is always the bare binary name. When the user typed an absolute\n // path we must pass the basename, not the full path.\n const normalizedExecutable = basename(parsed.executable)\n\n let resolved: ResolvedCommand\n try {\n resolved = await resolveCommand(loaded, [normalizedExecutable, ...parsed.argv])\n }\n catch (err) {\n consola.debug(`ape-shell: adapter resolve failed for \"${parsed.raw}\":`, err)\n return false\n }\n\n // Try to reuse an existing matching grant (with widening support)\n try {\n const existingGrantId = await findExistingGrant(resolved, idp)\n if (existingGrantId) {\n consola.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`)\n const token = await fetchGrantToken(idp, existingGrantId)\n await verifyAndExecute(token, resolved, existingGrantId)\n return true\n }\n }\n catch {\n // Fall through to request a new grant\n }\n\n // Request a new grant for this specific command\n const approval = (args.approval ?? 'once') as 'once' | 'timed' | 'always'\n consola.info(`Requesting grant for: ${resolved.detail.display}`)\n const grant = await createShapesGrant(resolved, {\n idp,\n approval,\n reason: (args.reason as string) || `ape-shell: ${resolved.detail.display}`,\n })\n\n if (grant.similar_grants?.similar_grants?.length) {\n const n = grant.similar_grants.similar_grants.length\n consola.info('')\n consola.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`)\n }\n\n notifyGrantPending({\n grantId: grant.id,\n approveUrl: `${idp}/grant-approval?grant_id=${grant.id}`,\n command: resolved.detail?.display || parsed?.raw || 'unknown',\n audience: resolved.adapter?.cli?.audience ?? 'shapes',\n host: (args.host as string) || hostname(),\n })\n\n if (shouldWaitForGrant(args)) {\n consola.info(`Grant requested: ${grant.id}`)\n consola.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`)\n\n const status = await waitForGrantStatus(idp, grant.id)\n if (status !== 'approved')\n throw new CliError(`Grant ${status}`)\n\n const token = await fetchGrantToken(idp, grant.id)\n await verifyAndExecute(token, resolved, grant.id)\n return true\n }\n\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n}\n\n/**\n * Execute a shell command as [shell, '-c', command_string] via execFileSync.\n *\n * Strips `APES_SHELL_WRAPPER` from the env so any nested `apes` process\n * spawned by the bash child runs in normal citty-dispatch mode instead\n * of self-detecting as ape-shell and rejecting its argv. This mirrors\n * the pty-bridge.ts fix from 0.8.0 (Finding 4) for the one-shot path —\n * openclaw's polling flow `ape-shell -c \"apes grants status <id>\"` would\n * hit this leak on the nested `apes` call inside bash, manifesting as\n * \"ape-shell: unsupported invocation\" and breaking the async-grant loop.\n */\nfunction execShellCommand(command: string[]): void {\n if (command.length === 0)\n throw new CliError('No command to execute')\n try {\n const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env\n execFileSync(command[0]!, command.slice(1), {\n stdio: 'inherit',\n env: inheritedEnv,\n })\n }\n catch (err: unknown) {\n const exitCode = (err as { status?: number }).status || 1\n throw new CliExit(exitCode)\n }\n}\n\nfunction extractPositionals(rawArgs: string[]): string[] {\n const positionals: string[] = []\n const delimiter = rawArgs.indexOf('--')\n const args = delimiter >= 0 ? rawArgs.slice(0, delimiter) : rawArgs\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!\n if (arg === 'run')\n continue\n if (arg.startsWith('--')) {\n i++ // skip flag value\n continue\n }\n positionals.push(arg)\n }\n return positionals\n}\n\n/**\n * Print a stderr warning when an unshaped CLI is being run through the\n * generic-fallback path. Written to stderr (not stdout) so shell pipelines\n * capturing stdout see the command output, not the warning.\n */\nfunction printGenericWarning(cliId: string): void {\n process.stderr.write(`⚠ No shape registered for \\`${cliId}\\`.\\n`)\n process.stderr.write('Generic mode active — single-use grant will be required.\\n')\n}\n\nasync function runAdapterMode(\n command: string[],\n rawArgs: string[],\n args: Record<string, unknown>,\n) {\n const idp = getIdpUrl(args.idp as string | undefined)\n if (!idp)\n throw new Error('No IdP URL configured. Run `apes login` first or pass --idp.')\n\n // If caller wants to run as another user (e.g. root), auto-switch to the escapes audience flow.\n // Adapter mode (Shapes) is user-level and cannot elevate privileges.\n // Pass the argv array through so commands carrying shell metacharacters\n // or spaces (e.g. `sh -c \"mkdir … && cat > …\"` from the nest secret\n // relay) survive intact — joining to a string and re-splitting on spaces\n // would shatter them and escapes would reject the mangled argv (exit 64).\n if (args.as) {\n await runAudienceMode('escapes', command.join(' '), args, command)\n return\n }\n\n const adapterOpt = extractOption(rawArgs, 'adapter')\n const cliId = command[0]!\n let resolved: ResolvedCommand\n try {\n const loaded = loadAdapter(cliId, adapterOpt)\n resolved = await resolveCommand(loaded, command)\n }\n catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const isNoAdapter = message.startsWith('No adapter found for ')\n if (!isNoAdapter)\n throw err\n // Fallback to generic synthetic adapter (opt-out via [generic] enabled = false)\n resolved = await resolveGenericOrReject(cliId, command, {\n genericEnabled: isGenericFallbackEnabled(),\n })\n printGenericWarning(cliId)\n }\n const approval = (args.approval ?? 'once') as 'once' | 'timed' | 'always'\n\n // Try reusing an existing timed/always grant (findExistingGrant skips once grants)\n try {\n const existingGrantId = await findExistingGrant(resolved, idp)\n if (existingGrantId) {\n consola.info(`Reusing existing grant: ${existingGrantId}`)\n const token = await fetchGrantToken(idp, existingGrantId)\n await verifyAndExecute(token, resolved, existingGrantId)\n return\n }\n }\n catch {\n // Fall through to creating a new grant\n }\n\n const grant = await createShapesGrant(resolved, {\n idp,\n approval,\n ...(args.reason ? { reason: args.reason as string } : {}),\n })\n\n if (grant.similar_grants?.similar_grants?.length) {\n const n = grant.similar_grants.similar_grants.length\n consola.info('')\n consola.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`)\n if (grant.similar_grants.widened_details?.length) {\n const wider = grant.similar_grants.widened_details.map(d => d.permission).join(', ')\n consola.info(` Broader scope: ${wider}`)\n }\n consola.info('')\n }\n\n if (shouldWaitForGrant(args)) {\n consola.info(`Grant requested: ${grant.id}`)\n consola.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`)\n\n const status = await waitForGrantStatus(idp, grant.id)\n if (status !== 'approved')\n throw new Error(`Grant ${status}`)\n\n const token = await fetchGrantToken(idp, grant.id)\n await verifyAndExecute(token, resolved, grant.id)\n return\n }\n\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n}\n\nasync function runAudienceMode(\n audience: string,\n action: string,\n args: Record<string, unknown>,\n // When provided, the exact argv to authorize + execute. Avoids the\n // lossy `action.split(' ')` round-trip for commands whose arguments\n // contain spaces or shell metacharacters (the `--as` wrapped-command\n // path). `action` is still used for the human-readable grant display.\n commandArgv?: string[],\n) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const idp = getIdpUrl(args.idp as string | undefined)!\n const grantsUrl = await getGrantsEndpoint(idp)\n const command = commandArgv ?? action.split(' ')\n const targetHost = (args.host as string) || hostname()\n const runAs = resolveRunAsTarget((args.as as string | undefined) ?? undefined)\n\n // Step 0: Reuse path — look for an existing approved 'timed' /\n // 'always' grant that matches our command exactly, instead of\n // creating a new pending grant every call. The legacy behaviour\n // (always create new) meant `apes run --as root --approval always`\n // re-prompted on every invocation despite the always-grant being\n // designed for reuse. Now: first call creates+approves once,\n // subsequent calls fetch a fresh token off the same grant id.\n const reusableId = await findReusableAudienceGrant({\n grantsUrl, requester: auth.email, audience, command, targetHost, runAs,\n })\n if (reusableId) {\n const { authz_jwt } = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${reusableId}/token`, { method: 'POST' })\n return executeWithGrantToken({ audience, command, args, token: authz_jwt })\n }\n\n // Step 1: Request grant\n consola.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(' ')}`)\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n body: {\n requester: auth.email,\n target_host: targetHost,\n audience,\n grant_type: args.approval,\n command,\n reason: (args.reason as string) || command.join(' '),\n ...(runAs ? { run_as: runAs } : {}),\n },\n })\n if (!shouldWaitForGrant(args)) {\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n }\n\n consola.success(`Grant requested: ${grant.id}`)\n consola.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`)\n\n // Step 2: Wait for approval. Human-in-the-loop, so the budget is generous\n // (15 min default). The poll loop MUST throw on timeout — if it falls\n // through to the token-fetch below with status='pending', the server\n // rejects with a confusing \"Grant is not approved (status: pending)\"\n // and the user can't tell the timeout from a real auth error.\n consola.info('Waiting for approval...')\n const maxWait = 15 * 60 * 1000\n const interval = 3_000\n const start = Date.now()\n let approved = false\n\n while (Date.now() - start < maxWait) {\n const status = await apiFetch<{ status: string }>(`${grantsUrl}/${grant.id}`)\n if (status.status === 'approved') {\n consola.success('Grant approved!')\n approved = true\n break\n }\n if (status.status === 'denied' || status.status === 'revoked') {\n throw new CliError(`Grant ${status.status}.`)\n }\n await new Promise(r => setTimeout(r, interval))\n }\n\n if (!approved) {\n const minutes = Math.round(maxWait / 60_000)\n throw new CliError(\n `Grant approval timed out after ${minutes} min (still pending). `\n + `Check your DDISA inbox at ${idp}/grant-approval?grant_id=${grant.id} — `\n + `if approved later, re-run the same \\`apes run\\` command and it will reuse the grant.`,\n )\n }\n\n // Step 3: Get grant token\n consola.info('Fetching grant token...')\n const { authz_jwt } = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${grant.id}/token`, {\n method: 'POST',\n })\n\n // Step 4: Execute or output token\n return executeWithGrantToken({ audience, command, args, token: authz_jwt })\n}\n\nfunction executeWithGrantToken(opts: {\n audience: string\n command: string[]\n args: Record<string, unknown>\n token: string\n}): void {\n const { audience, command, args, token } = opts\n if (audience === 'escapes') {\n consola.info(`Executing: ${command.join(' ')}`)\n try {\n // Strip APES_SHELL_WRAPPER so nested `apes` invocations inside\n // the escapes pipe don't self-detect as ape-shell mode.\n const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env\n execFileSync((args['escapes-path'] as string) || 'escapes', ['--grant', token, '--', ...command], {\n stdio: 'inherit',\n env: inheritedEnv,\n })\n }\n catch (err: unknown) {\n const exitCode = (err as { status?: number }).status || 1\n throw new CliExit(exitCode)\n }\n }\n else {\n // The token IS the intended result for non-escapes audiences, so it\n // must reach real stdout even when diagnostics were routed to stderr.\n writeRealStdout(token)\n }\n}\n\n/**\n * Look for an existing approved `timed`/`always` grant matching the\n * current request exactly. Returns the grant id, or null if no\n * reusable grant exists. Network/parse errors fall through to null\n * (the caller then creates a fresh grant).\n *\n * Match criteria (all required):\n * - status === 'approved'\n * - grant_type !== 'once' (once-grants get consumed on use)\n * - audience matches\n * - target_host matches\n * - command array equals exactly\n * - run_as matches (or both undefined)\n * - not expired (if grant_type=timed)\n */\nasync function findReusableAudienceGrant(opts: {\n grantsUrl: string\n requester: string\n audience: string\n command: string[]\n targetHost: string\n runAs?: string\n}): Promise<string | null> {\n try {\n const grants = await apiFetch<{\n data: Array<{\n id: string\n status: string\n expires_at?: number\n request: {\n audience: string\n target_host: string\n grant_type: string\n command?: string[]\n run_as?: string\n }\n }>\n }>(`${opts.grantsUrl}?requester=${encodeURIComponent(opts.requester)}&status=approved&limit=50`)\n const now = Math.floor(Date.now() / 1000)\n const match = grants.data.find((g) => {\n const r = g.request\n if (r.audience !== opts.audience) return false\n if (r.target_host !== opts.targetHost) return false\n if (r.grant_type === 'once') return false\n if (r.grant_type === 'timed' && g.expires_at && g.expires_at <= now) return false\n const cmd = r.command ?? []\n if (cmd.length !== opts.command.length) return false\n if (!cmd.every((c, i) => c === opts.command[i])) return false\n if ((r.run_as ?? undefined) !== opts.runAs) return false\n return true\n })\n return match?.id ?? null\n }\n catch {\n return null\n }\n}\n","import { spawn } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadAuth } from '../config.js'\nimport { CliError } from '../errors.js'\nimport { buildDefaultProxyConfigToml } from '../proxy/config.js'\nimport type { ProxyConfigOptions } from '../proxy/config.js'\nimport { startEphemeralProxy } from '../proxy/local-proxy.js'\nimport { buildTrustBundle, detectSystemCaPath } from '../proxy/trust-bundle.js'\nimport type { TrustBundle } from '../proxy/trust-bundle.js'\nimport { extractWrappedCommand } from '../shapes/index.js'\n\n/**\n * Pull the agent email + IdP URL from the cached `apes login` session and\n * return options for an IdP-mediated proxy. Throws if no valid session is on\n * disk: the proxy needs the user's identity to attribute grant requests\n * (`requester` field) and to find the right YOLO policy row keyed on\n * `(agent_email, audience='ape-proxy')`. Without that we'd silently fall\n * back to permissive transparent mode, which lies to the user about the\n * UI-side YOLO config having an effect — better to fail loudly.\n */\nfunction resolveProxyConfigOptions(): ProxyConfigOptions {\n const auth = loadAuth()\n if (!auth?.email || !auth?.idp) {\n throw new CliError(\n 'apes proxy requires `apes login` first.\\n\\n'\n + 'Without a login the proxy has no agent identity to attribute grant\\n'\n + 'requests to, so the YOLO / Allow / Deny policy on id.openape.ai cannot\\n'\n + 'apply. Run:\\n\\n'\n + ' apes login\\n\\n'\n + 'and re-run `apes proxy -- ...`.',\n // 77 = EX_NOPERM from sysexits.h (\"permission denied\"); fits \"user has\\n'\n // not authenticated to use this command\" better than the default 1.\n 77,\n )\n }\n consola.info(`[apes proxy] IdP-mediated mode — agent=${auth.email}, idp=${auth.idp}`)\n return { agentEmail: auth.email, idpUrl: auth.idp, mediated: true }\n}\n\n/**\n * `apes proxy -- <cmd> [args...]`\n *\n * Run a command with `HTTPS_PROXY` (and `HTTP_PROXY`) routed through the\n * OpenApe egress proxy. Two lifecycle modes:\n *\n * 1. `OPENAPE_PROXY_URL` is set in the environment → reuse that proxy. The\n * wrapped command inherits `HTTPS_PROXY=$OPENAPE_PROXY_URL`. No spawn,\n * no cleanup. This is the path ape-shell takes (M1b) when the user\n * started a long-lived `openape-proxy &` themselves.\n *\n * 2. `OPENAPE_PROXY_URL` is NOT set → spawn an ephemeral `openape-proxy`\n * child process bound to a random free port, exec the wrapped command\n * with `HTTPS_PROXY` pointing at it, kill the proxy on wrapped-command\n * exit. Per-invocation lifecycle, like `time` or `op run`.\n *\n * Mirrors the `apes run --root → escapes` orchestration pattern: this\n * subcommand is a thin shell around an external runnable that owns the\n * actual policy + audit logic.\n */\nexport const proxyCommand = defineCommand({\n meta: {\n name: 'proxy',\n description: 'Run a command with HTTPS_PROXY routed through the OpenApe egress proxy.',\n },\n args: {\n _: {\n type: 'positional',\n description: 'Command to execute (after --)',\n required: false,\n },\n },\n async run({ rawArgs }) {\n const wrapped = extractWrappedCommand(rawArgs ?? [])\n if (wrapped.length === 0) {\n throw new CliError('Usage: apes proxy -- <cmd> [args...]')\n }\n\n // OPENAPE_PROXY (host:port) — long-running daemon path (Phase 6).\n // The system-installed daemon already authenticates via its own\n // auth.json, so we deliberately skip resolveProxyConfigOptions() here\n // (no `apes login` required for the wrapping user). We do, however,\n // need to teach the wrapped subprocess to trust the daemon's local\n // CA so its TLS interception (mitmproxy-style) doesn't break.\n const reuseHostPort = process.env.OPENAPE_PROXY\n const reuseUrl = process.env.OPENAPE_PROXY_URL\n let proxyUrl: string\n let bundle: TrustBundle | null = null\n let close: (() => Promise<void>) | null = null\n\n if (reuseHostPort) {\n proxyUrl = `http://${reuseHostPort}`\n consola.info(`[apes proxy] using long-running daemon at ${proxyUrl}`)\n\n const localCaPath = join(homedir(), '.openape', 'proxy', 'ca.crt')\n if (!existsSync(localCaPath)) {\n throw new CliError(\n `OPENAPE_PROXY is set but no local CA found at ${localCaPath}. `\n + `Start the daemon (sudo -u <agent> apes proxy --global < secrets.toml) first.`,\n )\n }\n bundle = buildTrustBundle({\n systemCaPath: detectSystemCaPath(),\n localCaPath,\n })\n consola.debug(`[apes proxy] trust bundle: ${bundle.path}`)\n }\n else if (reuseUrl) {\n proxyUrl = reuseUrl\n consola.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`)\n }\n else {\n const ephemeral = await startEphemeralProxy(buildDefaultProxyConfigToml(resolveProxyConfigOptions()))\n proxyUrl = ephemeral.url\n close = ephemeral.close\n consola.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`)\n }\n\n // Forward SIGINT/SIGTERM so the user's Ctrl-C stops the wrapped command\n // gracefully (which then triggers our finally-block cleanup of the proxy).\n //\n // We set every common variant of the proxy env-vars because tools differ:\n // - libcurl / curl honors lowercase `https_proxy` and uppercase\n // `HTTPS_PROXY` (and security advisories caused some distros to ignore\n // uppercase `HTTP_PROXY` for HTTP requests; setting both is safest).\n // - Many Go / Rust / Python tools read uppercase only.\n // - `ALL_PROXY` is honored by curl, rsync, ftp, and others as a fallback\n // when the per-scheme variant is absent.\n // - Node 24+ native `fetch` (undici) honors `NODE_USE_ENV_PROXY=1`. Setting\n // it here means the wrapped command's Node code routes through the proxy\n // without per-app ProxyAgent wiring.\n const noProxy = process.env.NO_PROXY ?? process.env.no_proxy ?? '127.0.0.1,localhost'\n // When a trust bundle is built (OPENAPE_PROXY daemon path), point every\n // common TLS-trust env var at it so the wrapped subprocess accepts the\n // daemon's intercepted-TLS leaf certs without an OS-wide trust install.\n // Each runtime/tooling reads a different variable:\n // NODE_EXTRA_CA_CERTS Node.js (additive to the bundled Mozilla store)\n // SSL_CERT_FILE OpenSSL (Python `requests`, libpq, many CLIs)\n // CURL_CA_BUNDLE libcurl\n // REQUESTS_CA_BUNDLE Python `requests` explicit override\n // GIT_SSL_CAINFO Git's libcurl-backed HTTPS transport\n const childEnv: NodeJS.ProcessEnv = {\n ...process.env,\n HTTPS_PROXY: proxyUrl,\n https_proxy: proxyUrl,\n HTTP_PROXY: proxyUrl,\n http_proxy: proxyUrl,\n ALL_PROXY: proxyUrl,\n all_proxy: proxyUrl,\n NO_PROXY: noProxy,\n no_proxy: noProxy,\n NODE_USE_ENV_PROXY: '1',\n ...(bundle\n ? {\n NODE_EXTRA_CA_CERTS: bundle.path,\n SSL_CERT_FILE: bundle.path,\n CURL_CA_BUNDLE: bundle.path,\n REQUESTS_CA_BUNDLE: bundle.path,\n GIT_SSL_CAINFO: bundle.path,\n }\n : {}),\n }\n\n let exitCode: number\n try {\n exitCode = await new Promise<number>((resolveExit) => {\n const child = spawn(wrapped[0]!, wrapped.slice(1), {\n stdio: 'inherit',\n env: childEnv,\n })\n const forward = (sig: NodeJS.Signals) => () => child.kill(sig)\n const onSigint = forward('SIGINT')\n const onSigterm = forward('SIGTERM')\n process.on('SIGINT', onSigint)\n process.on('SIGTERM', onSigterm)\n child.once('exit', (code, signal) => {\n process.off('SIGINT', onSigint)\n process.off('SIGTERM', onSigterm)\n if (signal) resolveExit(128 + (signalNumber(signal) ?? 0))\n else resolveExit(code ?? 0)\n })\n child.once('error', (err) => {\n consola.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message)\n resolveExit(127)\n })\n })\n }\n finally {\n // Run cleanup on both happy and exception paths so a thrown error\n // (or signal that aborts the await) doesn't leak the temp trust\n // bundle or leave the ephemeral proxy running.\n bundle?.cleanup()\n if (close) await close()\n }\n\n // Propagate the wrapped command's exit code without going through\n // CliExit + citty's runMain. `runMain` catches everything inside its own\n // try/catch and prints `consola.error(error, \"\\n\")` before our top-level\n // handler in cli.ts can intercept — and since CliExit has no message,\n // that surfaces as a bare \"ERROR\" header followed by an internal stack\n // trace, which is misleading on a *successful* deny path (curl exits 56,\n // proxy did its job correctly). process.exit here means the user sees\n // their wrapped command's exit code and nothing else.\n if (exitCode !== 0) process.exit(exitCode)\n },\n})\n\n/**\n * Map a POSIX signal name to its numeric value for the conventional\n * 128+sig exit-code encoding. Returns undefined for unknown names so the\n * caller can fall back to a plain non-zero.\n */\nfunction signalNumber(signal: NodeJS.Signals): number | undefined {\n const map: Record<string, number> = { SIGINT: 2, SIGTERM: 15, SIGHUP: 1, SIGQUIT: 3, SIGKILL: 9 }\n return map[signal]\n}\n","export interface ProxyConfigOptions {\n /**\n * The agent's email (sub-claim of their IdP token). Used as `requester` in\n * grant requests so IdP-side YOLO/allow/deny lookups key on the real user.\n */\n agentEmail: string\n /** IdP base URL the proxy talks to for grant approval + JWKS verify. */\n idpUrl: string\n /**\n * `true` (M3 default when logged in): every unmatched egress goes through an\n * IdP grant request → user's YOLO policy (audience='ape-proxy') applies.\n * `false` (fallback when not logged in): default-allow + local deny-list +\n * audit-log only. No IdP roundtrip. Honest about the trade-off.\n */\n mediated: boolean\n}\n\n/**\n * Build a default TOML config for the ephemeral proxy spawned by `apes proxy --`.\n *\n * Two modes:\n *\n * - **Mediated (`mediated=true`)**: `default_action=\"request\"` so every\n * unmatched host hits the IdP grant flow. The user's YOLO policy on\n * `id.openape.ai/agents/<email>` (Web tab) decides auto-approve vs human.\n * This is the M3 mode and what `apes proxy --` does when the caller is\n * logged in via `apes login`.\n *\n * - **Transparent (`mediated=false`)**: legacy M1a behaviour — `default_action\n * =\"allow\"` plus the cloud-metadata deny-list, no IdP roundtrip. Used when\n * the caller isn't logged in (we can't synthesize an identity for grant\n * lookups, so falling back to permissive-with-audit is the honest default\n * instead of locking everything down).\n *\n * No local audit-log path is written: anything stored on the user's machine\n * is also writable by the user, so it can't function as a tamper-proof trail.\n * The trustworthy audit lives server-side on the IdP for grant decisions; the\n * proxy still emits an operator-readable summary to stderr for live debugging.\n */\nexport function buildDefaultProxyConfigToml(opts: ProxyConfigOptions): string {\n const defaultAction = opts.mediated ? 'request' : 'allow'\n const escEmail = opts.agentEmail.replace(/\"/g, '\\\\\"')\n const escIdp = opts.idpUrl.replace(/\"/g, '\\\\\"')\n return `# Auto-generated by \\`apes proxy --\\`. Do not edit; this file is\n# recreated for every invocation and deleted on exit.\n# Mode: ${opts.mediated ? 'IdP-mediated (every unmatched host → grant flow)' : 'transparent (default-allow + audit-only)'}.\n[proxy]\nlisten = \"127.0.0.1:0\"\nidp_url = \"${escIdp}\"\nagent_email = \"${escEmail}\"\ndefault_action = \"${defaultAction}\"\n\n# Cloud / link-local metadata endpoints — never let agent traffic reach these\n# even if a downstream policy mistake would otherwise allow it.\n[[deny]]\ndomain = \"169.254.169.254\"\nnote = \"AWS / DigitalOcean / Azure metadata endpoint\"\n\n[[deny]]\ndomain = \"metadata.google.internal\"\nnote = \"GCP metadata endpoint\"\n\n[[deny]]\ndomain = \"*.internal\"\nnote = \"VPC-internal hostname suffix\"\n`\n}\n","import type { ChildProcess } from 'node:child_process'\nimport { spawn } from 'node:child_process'\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { tmpdir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\n\nconst require = createRequire(import.meta.url)\n\nexport interface EphemeralProxy {\n url: string\n port: number\n child: ChildProcess\n close: () => Promise<void>\n}\n\n/**\n * Resolve the absolute path to the `openape-proxy` executable shipped by the\n * `@openape/proxy` workspace package. Uses `require.resolve` against the\n * package's `package.json` so it works both in the workspace (where pnpm\n * symlinks the package into `node_modules/@openape/proxy`) and after a\n * regular `npm install -g @openape/apes` global install.\n */\nexport function findProxyBin(): string {\n const pkgPath = require.resolve('@openape/proxy/package.json')\n const pkg = require('@openape/proxy/package.json') as { bin?: Record<string, string> }\n const binRel = pkg.bin?.['openape-proxy']\n if (!binRel) {\n throw new Error('@openape/proxy is missing the openape-proxy bin entry')\n }\n return resolve(dirname(pkgPath), binRel)\n}\n\n/**\n * Spawn an ephemeral `openape-proxy` child process bound to a random free\n * port on 127.0.0.1. Resolves once the child has logged its `Listening on …`\n * line. Caller MUST `close()` to terminate the child + clean up the temp\n * config directory.\n *\n * Why temp file instead of stdin: the proxy binary today only accepts\n * `-c <path>`. Once it grows a stdin/env mode we can drop the temp dir.\n */\nexport async function startEphemeralProxy(configToml: string): Promise<EphemeralProxy> {\n const tmpDir = mkdtempSync(join(tmpdir(), 'openape-proxy-'))\n const configPath = join(tmpDir, 'config.toml')\n writeFileSync(configPath, configToml, { mode: 0o600 })\n\n const binPath = findProxyBin()\n const child = spawn(process.execPath, [binPath, '-c', configPath], {\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: false,\n })\n\n const cleanupTmp = () => {\n try { rmSync(tmpDir, { recursive: true, force: true }) }\n catch { /* best effort */ }\n }\n\n let port: number\n try {\n port = await waitForListenLine(child)\n }\n catch (err) {\n child.kill('SIGTERM')\n cleanupTmp()\n throw err\n }\n\n // Surface unexpected proxy stderr to ours so users can see crashes.\n child.stderr?.on('data', (chunk: Buffer) => process.stderr.write(chunk))\n\n return {\n url: `http://127.0.0.1:${port}`,\n port,\n child,\n close: () => new Promise<void>((resolveClose) => {\n const done = () => {\n cleanupTmp()\n resolveClose()\n }\n if (child.exitCode !== null || child.signalCode !== null) {\n done()\n return\n }\n child.once('exit', done)\n child.kill('SIGTERM')\n // Force-kill if SIGTERM doesn't take within 2s.\n setTimeout(() => {\n if (child.exitCode === null && child.signalCode === null) {\n child.kill('SIGKILL')\n }\n }, 2000).unref()\n }),\n }\n}\n\n/**\n * Read the proxy's stdout until we see the `Listening on http://…:<port>`\n * banner. Rejects if the child exits early or the timeout fires.\n *\n * `setTimeout(...).unref()` so the timer doesn't keep the apes process\n * alive past its natural exit if everything else has finished.\n */\nfunction waitForListenLine(child: ChildProcess): Promise<number> {\n return new Promise<number>((resolveWait, rejectWait) => {\n let buf = ''\n let timer: NodeJS.Timeout\n\n function onData(chunk: Buffer): void {\n buf += chunk.toString('utf8')\n const m = buf.match(/Listening on http:\\/\\/[^:\\s]+:(\\d+)/)\n if (m) {\n cleanup()\n resolveWait(Number(m[1]))\n }\n }\n function onExit(code: number | null): void {\n cleanup()\n rejectWait(new Error(`openape-proxy exited before listening (code=${code}, stderr accumulated above)`))\n }\n function onError(err: Error): void {\n cleanup()\n rejectWait(err)\n }\n function cleanup(): void {\n clearTimeout(timer)\n child.stdout?.off('data', onData)\n child.off('exit', onExit)\n child.off('error', onError)\n }\n\n timer = setTimeout(() => {\n cleanup()\n rejectWait(new Error('openape-proxy startup timeout (5s)'))\n }, 5000)\n timer.unref()\n\n child.stdout?.on('data', onData)\n child.once('exit', onExit)\n child.once('error', onError)\n })\n}\n","import { existsSync, mkdtempSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\n\nconst CANDIDATES = [\n '/etc/ssl/cert.pem', // macOS\n '/etc/ssl/certs/ca-certificates.crt', // Debian / Ubuntu\n '/etc/pki/tls/certs/ca-bundle.crt', // RHEL / Fedora\n '/etc/ssl/ca-bundle.pem', // OpenSUSE\n]\n\nexport function detectSystemCaPath(): string {\n for (const p of CANDIDATES) {\n if (existsSync(p)) return p\n }\n throw new Error(\n `Could not locate a system CA bundle. Tried: ${CANDIDATES.join(', ')}. `\n + `Set NODE_EXTRA_CA_CERTS yourself or pass --allow-no-system-ca.`,\n )\n}\n\nexport interface TrustBundle {\n path: string\n cleanup: () => void\n}\n\nexport function buildTrustBundle(opts: { systemCaPath: string, localCaPath: string }): TrustBundle {\n const dir = mkdtempSync(join(tmpdir(), 'openape-trust-'))\n const path = join(dir, 'bundle.pem')\n const sys = readFileSync(opts.systemCaPath, 'utf-8')\n const local = readFileSync(opts.localCaPath, 'utf-8')\n writeFileSync(path, `${sys.trimEnd()}\\n${local.trimEnd()}\\n`, { mode: 0o600 })\n return {\n path,\n cleanup: () => {\n try { unlinkSync(path) }\n catch { /* ignore */ }\n try { rmdirSync(dir) }\n catch { /* ignore */ }\n },\n }\n}\n","import { defineCommand } from 'citty'\nimport { extractOption, extractWrappedCommand, loadAdapter, resolveCommand } from '../shapes/index.js'\n\nexport const explainCommand = defineCommand({\n meta: {\n name: 'explain',\n description: 'Show what permission a command would need',\n },\n args: {\n adapter: {\n type: 'string',\n description: 'Explicit path to adapter TOML file',\n },\n _: {\n type: 'positional',\n description: 'Wrapped command (after --)',\n required: false,\n },\n },\n async run({ rawArgs }) {\n const command = extractWrappedCommand(rawArgs ?? [])\n if (command.length === 0)\n throw new Error('Missing wrapped command. Usage: apes explain [--adapter <file>] -- <cli> ...')\n\n const adapterOpt = extractOption(rawArgs ?? [], 'adapter')\n const loaded = loadAdapter(command[0]!, adapterOpt)\n const resolved = await resolveCommand(loaded, command)\n\n process.stdout.write(`${JSON.stringify({\n adapter: resolved.adapter.cli.id,\n source: resolved.source,\n operation: resolved.detail.operation_id,\n display: resolved.detail.display,\n permission: resolved.permission,\n resource_chain: resolved.detail.resource_chain,\n exact_command: resolved.detail.constraints?.exact_command ?? false,\n adapter_digest: resolved.digest,\n }, null, 2)}\\n`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth, loadConfig } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const configGetCommand = defineCommand({\n meta: {\n name: 'get',\n description: 'Get a configuration value',\n },\n args: {\n key: {\n type: 'positional',\n description: 'Config key: idp, email, defaults.idp, defaults.approval, agent.key, agent.email',\n required: true,\n },\n },\n run({ args }) {\n const key = args.key\n\n switch (key) {\n case 'idp': {\n const idp = getIdpUrl()\n if (idp)\n console.log(idp)\n else\n consola.info('No IdP configured.')\n break\n }\n case 'email': {\n const auth = loadAuth()\n if (auth?.email)\n console.log(auth.email)\n else\n consola.info('Not logged in.')\n break\n }\n default: {\n // Dot-notation: defaults.idp, defaults.approval, agent.key, agent.email\n const config = loadConfig()\n const parts = key.split('.')\n if (parts.length === 2) {\n const section = parts[0] as keyof typeof config\n const field = parts[1]!\n const sectionObj = config[section] as Record<string, string> | undefined\n if (sectionObj && field in sectionObj) {\n console.log(sectionObj[field])\n }\n else {\n consola.info(`Key \"${key}\" not set.`)\n }\n }\n else {\n throw new CliError(`Unknown key: \"${key}\". Use: idp, email, defaults.idp, defaults.approval, agent.key, agent.email`)\n }\n }\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadConfig, saveConfig } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const configSetCommand = defineCommand({\n meta: {\n name: 'set',\n description: 'Set a configuration value',\n },\n args: {\n key: {\n type: 'positional',\n description: 'Config key: defaults.idp, defaults.approval, agent.key, agent.email',\n required: true,\n },\n value: {\n type: 'positional',\n description: 'Value to set',\n required: true,\n },\n },\n run({ args }) {\n const key = args.key\n const value = args.value\n const config = loadConfig()\n\n const parts = key.split('.')\n if (parts.length !== 2) {\n throw new CliError(`Invalid key: \"${key}\". Use: defaults.idp, defaults.approval, agent.key, agent.email`)\n }\n\n const [section, field] = parts as [string, string]\n\n if (section === 'defaults') {\n config.defaults = config.defaults || {}\n ;(config.defaults as Record<string, string>)[field] = value\n }\n else if (section === 'agent') {\n config.agent = config.agent || {}\n ;(config.agent as Record<string, string>)[field] = value\n }\n else {\n throw new CliError(`Unknown section: \"${section}\". Use: defaults, agent`)\n }\n\n saveConfig(config)\n consola.success(`Set ${key} = ${value}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { getAuthToken } from '../../config'\nimport { CliError } from '../../errors'\n\nasync function doRequest(method: string, url: string, body: string | undefined, contentType: string, raw: boolean, showHeaders: boolean) {\n const token = getAuthToken()\n if (!token) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n\n const response = await fetch(url, {\n method,\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': contentType,\n },\n body: body || undefined,\n })\n\n if (showHeaders) {\n console.log(`HTTP ${response.status} ${response.statusText}`)\n for (const [key, value] of response.headers.entries()) {\n console.log(`${key}: ${value}`)\n }\n console.log()\n }\n\n const respContentType = response.headers.get('content-type') || ''\n const text = await response.text()\n\n if (raw || !respContentType.includes('json')) {\n process.stdout.write(text)\n }\n else {\n try {\n console.log(JSON.stringify(JSON.parse(text), null, 2))\n }\n catch {\n process.stdout.write(text)\n }\n }\n\n if (!response.ok) {\n throw new CliError(`HTTP ${response.status} ${response.statusText}`)\n }\n}\n\nexport const fetchCommand = defineCommand({\n meta: {\n name: 'fetch',\n description: 'Make authenticated HTTP requests',\n },\n subCommands: {\n get: defineCommand({\n meta: {\n name: 'get',\n description: 'GET request with auth token',\n },\n args: {\n url: {\n type: 'positional',\n description: 'URL to fetch',\n required: true,\n },\n raw: {\n type: 'boolean',\n description: 'Output raw response body',\n default: false,\n },\n headers: {\n type: 'boolean',\n description: 'Show response headers',\n default: false,\n },\n },\n async run({ args }) {\n await doRequest('GET', String(args.url), undefined, 'application/json', Boolean(args.raw), Boolean(args.headers))\n },\n }),\n\n post: defineCommand({\n meta: {\n name: 'post',\n description: 'POST request with auth token',\n },\n args: {\n url: {\n type: 'positional',\n description: 'URL to fetch',\n required: true,\n },\n body: {\n type: 'string',\n description: 'Request body (JSON string)',\n },\n 'content-type': {\n type: 'string',\n description: 'Content-Type header',\n default: 'application/json',\n },\n raw: {\n type: 'boolean',\n description: 'Output raw response body',\n default: false,\n },\n headers: {\n type: 'boolean',\n description: 'Show response headers',\n default: false,\n },\n },\n async run({ args }) {\n await doRequest('POST', String(args.url), args.body as string | undefined, String(args['content-type'] || 'application/json'), Boolean(args.raw), Boolean(args.headers))\n },\n }),\n },\n})\n","import { defineCommand } from 'citty'\n\nexport const mcpCommand = defineCommand({\n meta: {\n name: 'mcp',\n description: 'Start MCP server for AI agents',\n },\n args: {\n transport: {\n type: 'string',\n description: 'Transport type: stdio or sse',\n default: 'stdio',\n },\n port: {\n type: 'string',\n description: 'Port for SSE transport',\n default: '3001',\n },\n },\n async run({ args }) {\n const transport = (args.transport || 'stdio') as 'stdio' | 'sse'\n const port = Number.parseInt(String(args.port), 10)\n\n if (transport !== 'stdio' && transport !== 'sse') {\n throw new Error('Transport must be \"stdio\" or \"sse\"')\n }\n\n const { startMcpServer } = await import('./server.js')\n await startMcpServer(transport, port)\n },\n})\n","import { existsSync, copyFileSync, writeFileSync } from 'node:fs'\nimport { randomBytes } from 'node:crypto'\nimport { execFileSync } from 'node:child_process'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError, CliExit } from '../../errors'\n\nconst DEFAULT_IDP_URL = 'https://id.openape.at'\n\nasync function downloadTemplate(repo: string, targetDir: string) {\n const { downloadTemplate: gigetDownload } = await import('giget')\n await gigetDownload(`gh:${repo}`, { dir: targetDir, force: false })\n}\n\nfunction installDeps(dir: string) {\n const hasLockFile = (name: string) => existsSync(join(dir, name))\n\n if (hasLockFile('pnpm-lock.yaml')) {\n execFileSync('pnpm', ['install'], { cwd: dir, stdio: 'inherit' })\n }\n else if (hasLockFile('bun.lockb')) {\n execFileSync('bun', ['install'], { cwd: dir, stdio: 'inherit' })\n }\n else {\n execFileSync('npm', ['install'], { cwd: dir, stdio: 'inherit' })\n }\n}\n\nasync function promptChoice(message: string, choices: string[]): Promise<string> {\n const result = await consola.prompt(message, { type: 'select', options: choices })\n if (typeof result === 'symbol') {\n throw new CliExit(0)\n }\n return result as string\n}\n\nasync function promptText(message: string, defaultValue?: string): Promise<string> {\n const result = await consola.prompt(message, { type: 'text', default: defaultValue, placeholder: defaultValue })\n if (typeof result === 'symbol') {\n throw new CliExit(0)\n }\n return (result as string) || defaultValue || ''\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'Scaffold a new OpenApe project',\n },\n args: {\n sp: {\n type: 'boolean',\n description: 'Create a Service Provider app',\n },\n idp: {\n type: 'boolean',\n description: 'Create an Identity Provider app',\n },\n dir: {\n type: 'positional',\n description: 'Target directory',\n required: false,\n },\n },\n async run({ args }) {\n let mode: 'sp' | 'idp'\n\n if (args.sp) {\n mode = 'sp'\n }\n else if (args.idp) {\n mode = 'idp'\n }\n else {\n const choice = await promptChoice('What do you want to set up?', [\n 'SP — Add login to my app',\n 'IdP — Run my own Identity Provider',\n ])\n mode = choice.startsWith('SP') ? 'sp' : 'idp'\n }\n\n if (mode === 'sp') {\n await initSP(args.dir)\n }\n else {\n await initIdP(args.dir)\n }\n },\n})\n\nasync function initSP(targetDir?: string) {\n const dir = targetDir || 'my-app'\n\n if (existsSync(join(dir, 'package.json'))) {\n throw new CliError(`Directory \"${dir}\" already contains a project.`)\n }\n\n consola.start('Scaffolding SP starter...')\n await downloadTemplate('openape-ai/openape-sp-starter', dir)\n consola.success('Scaffolded from openape-sp-starter')\n\n consola.start('Installing dependencies...')\n installDeps(dir)\n consola.success('Dependencies installed')\n\n // Create .env from .env.example\n const envExample = join(dir, '.env.example')\n const envFile = join(dir, '.env')\n if (existsSync(envExample) && !existsSync(envFile)) {\n copyFileSync(envExample, envFile)\n consola.success(`\\`.env\\` created (using Free IdP at ${DEFAULT_IDP_URL})`)\n }\n\n console.log('')\n consola.box([\n `cd ${dir}`,\n 'npm run dev',\n '',\n 'Then open http://localhost:3001/login',\n ].join('\\n'))\n}\n\nasync function initIdP(targetDir?: string) {\n const dir = targetDir || 'my-idp'\n\n if (existsSync(join(dir, 'package.json'))) {\n throw new CliError(`Directory \"${dir}\" already contains a project.`)\n }\n\n // Interactive questions\n const domain = await promptText('Domain for the IdP', 'localhost')\n const storage = await promptChoice('Storage backend', [\n 'memory (dev only, data lost on restart)',\n 'fs (local filesystem)',\n 's3 (S3-compatible)',\n ])\n const adminEmail = await promptText('Admin email')\n\n consola.start('Scaffolding IdP starter...')\n await downloadTemplate('openape-ai/openape-idp-starter', dir)\n consola.success('Scaffolded from openape-idp-starter')\n\n consola.start('Installing dependencies...')\n installDeps(dir)\n consola.success('Dependencies installed')\n\n // Generate secrets\n const sessionSecret = randomBytes(32).toString('hex')\n const managementToken = randomBytes(32).toString('hex')\n consola.success('Secrets generated')\n\n // Determine origin/issuer\n const isLocalhost = domain === 'localhost'\n const origin = isLocalhost ? 'http://localhost:3000' : `https://${domain}`\n\n // Write .env\n const envContent = [\n '# Generated by apes init --idp',\n '',\n `NUXT_OPENAPE_SESSION_SECRET=${sessionSecret}`,\n `NUXT_OPENAPE_ADMIN_EMAILS=${adminEmail}`,\n `NUXT_OPENAPE_MANAGEMENT_TOKEN=${managementToken}`,\n `NUXT_OPENAPE_ISSUER=${origin}`,\n `NUXT_OPENAPE_RP_NAME=My Identity Provider`,\n `NUXT_OPENAPE_RP_ID=${domain}`,\n `NUXT_OPENAPE_RP_ORIGIN=${origin}`,\n ].join('\\n')\n\n writeFileSync(join(dir, '.env'), `${envContent}\\n`, { mode: 0o600 })\n consola.success('.env created')\n\n console.log('')\n consola.box([\n `cd ${dir}`,\n 'npm run dev',\n '',\n 'Then open http://localhost:3000/admin',\n '',\n ...(isLocalhost\n ? []\n : [\n 'For production:',\n ` 1. DNS TXT Record: _ddisa.${domain.replace(/^id\\./, '')} → \"v=ddisa1 idp=${origin}\"`,\n ` 2. Storage: switch to ${storage.includes('s3') ? 's3' : 'fs'} in nuxt.config.ts`,\n ' 3. Deploy: vercel deploy',\n ]),\n ].join('\\n'))\n}\n","import { Buffer } from 'node:buffer'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { execFile } from 'node:child_process'\nimport { sign } from 'node:crypto'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadEd25519PrivateKey } from '../ssh-key'\nimport { generateAndSaveKey, readPublicKey, resolveKeyPath } from '../lib/keygen'\nimport { getAgentAuthenticateEndpoint, getAgentChallengeEndpoint } from '../http'\nimport { loadConfig, saveAuth, saveConfig } from '../config'\nimport { CliError, CliExit } from '../errors'\n\nconst DEFAULT_IDP_URL = 'https://id.openape.at'\nconst DEFAULT_KEY_PATH = '~/.ssh/id_ed25519'\nconst POLL_INTERVAL = 3000\nconst POLL_TIMEOUT = 300_000 // 5 minutes\n\nfunction openBrowser(url: string) {\n const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n execFile(cmd, [url], () => {})\n}\n\nasync function pollForEnrollment(\n idp: string,\n agentEmail: string,\n keyPath: string,\n): Promise<{ token: string, expiresIn: number }> {\n const resolvedKey = resolveKeyPath(keyPath)\n const keyContent = readFileSync(resolvedKey, 'utf-8')\n const privateKey = loadEd25519PrivateKey(keyContent)\n\n const challengeUrl = await getAgentChallengeEndpoint(idp)\n const authenticateUrl = await getAgentAuthenticateEndpoint(idp)\n const startTime = Date.now()\n\n while (Date.now() - startTime < POLL_TIMEOUT) {\n try {\n // Try to get a challenge — if it works, agent is enrolled\n const challengeResp = await fetch(challengeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: agentEmail }),\n })\n\n if (challengeResp.ok) {\n const { challenge } = await challengeResp.json() as { challenge: string }\n const signature = sign(null, Buffer.from(challenge), privateKey).toString('base64')\n\n const authResp = await fetch(authenticateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: agentEmail, challenge, signature }),\n })\n\n if (authResp.ok) {\n const result = await authResp.json() as { token: string, expires_in: number }\n return { token: result.token, expiresIn: result.expires_in }\n }\n }\n }\n catch {\n // Ignore network errors during polling\n }\n\n await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL))\n }\n\n throw new Error('Enrollment timed out. Please check the browser and try again.')\n}\n\nexport const enrollCommand = defineCommand({\n meta: {\n name: 'enroll',\n description: 'Enroll an agent with an Identity Provider',\n },\n args: {\n idp: {\n type: 'string',\n description: `IdP URL (default: ${DEFAULT_IDP_URL})`,\n },\n name: {\n type: 'string',\n description: 'Agent name',\n },\n key: {\n type: 'string',\n description: `Path to Ed25519 key (default: ${DEFAULT_KEY_PATH})`,\n },\n },\n async run({ args }) {\n // 1. Gather inputs\n const idp = args.idp\n || await consola.prompt('IdP URL', { type: 'text', default: DEFAULT_IDP_URL, placeholder: DEFAULT_IDP_URL }).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n || DEFAULT_IDP_URL\n\n const agentName = args.name\n || await consola.prompt('Agent name', { type: 'text', placeholder: 'deploy-bot' }).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n\n if (!agentName) {\n throw new CliError('Agent name is required.')\n }\n\n const keyPath = args.key\n || await consola.prompt('Ed25519 key', { type: 'text', default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n || DEFAULT_KEY_PATH\n\n // 2. Handle key\n const resolvedKey = resolveKeyPath(keyPath)\n let publicKey: string\n\n if (existsSync(resolvedKey)) {\n publicKey = readPublicKey(resolvedKey)\n consola.success(`Using existing key ${keyPath}`)\n }\n else {\n consola.start(`Generating Ed25519 key pair at ${keyPath}...`)\n publicKey = generateAndSaveKey(keyPath)\n consola.success(`Key pair generated at ${keyPath}`)\n }\n\n // 3. Open browser for enrollment\n const encodedKey = encodeURIComponent(publicKey)\n const enrollUrl = `${idp}/enroll?name=${encodeURIComponent(agentName)}&key=${encodedKey}`\n\n consola.info('Opening browser for enrollment...')\n consola.info(`→ ${idp}/enroll`)\n openBrowser(enrollUrl)\n\n // 4. Determine expected agent email\n // For the free IdP, the email format is: {name}+{user_local}+{user_domain}@id.openape.at\n // For custom IdPs, the format varies. We'll try common patterns.\n // The polling will try the challenge endpoint which accepts email as agent_id.\n // We need to guess the email, or poll without knowing it.\n // Best approach: ask the user to confirm the email shown in browser.\n console.log('')\n const agentEmail = await consola.prompt(\n 'Agent email (shown in browser after enrollment)',\n { type: 'text', placeholder: `agent+${agentName}@...` },\n ).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n\n if (!agentEmail) {\n throw new CliError('Agent email is required to verify enrollment.')\n }\n\n // 5. Poll for enrollment confirmation via challenge endpoint\n consola.start('Verifying enrollment...')\n const { token, expiresIn } = await pollForEnrollment(idp, agentEmail, keyPath)\n\n // 6. Save auth + config\n saveAuth({\n idp,\n access_token: token,\n email: agentEmail,\n expires_at: Math.floor(Date.now() / 1000) + (expiresIn || 3600),\n })\n\n const config = loadConfig()\n config.defaults = { ...config.defaults, idp }\n config.agent = { key: keyPath, email: agentEmail }\n saveConfig(config)\n\n consola.success(`Agent enrolled as ${agentEmail}`)\n consola.success('Config saved to ~/.config/apes/')\n\n console.log('')\n consola.info('Verify with: apes whoami')\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { apiFetch } from '../http'\nimport { loadAuth, getIdpUrl } from '../config'\nimport { CliError } from '../errors'\n\nexport const registerUserCommand = defineCommand({\n meta: {\n name: 'register-user',\n description: 'Register a sub-user with SSH key',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email for the new user',\n required: true,\n },\n name: {\n type: 'string',\n description: 'Name for the new user',\n required: true,\n },\n key: {\n type: 'string',\n description: 'Path to SSH public key file or key string',\n required: true,\n },\n type: {\n type: 'string',\n description: 'User type: human or agent (default: agent)',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n // Read key from file or use as string\n let publicKey = args.key\n if (existsSync(args.key)) {\n publicKey = readFileSync(args.key, 'utf-8').trim()\n }\n\n if (!publicKey.startsWith('ssh-ed25519 ')) {\n throw new CliError('Public key must be in ssh-ed25519 format.')\n }\n\n const userType = args.type as 'human' | 'agent' | undefined\n if (userType && userType !== 'human' && userType !== 'agent') {\n throw new CliError('Type must be \"human\" or \"agent\".')\n }\n\n const result = await apiFetch<{\n email: string\n name: string\n owner: string\n type: string\n }>(`${idp}/api/auth/enroll`, {\n method: 'POST',\n body: {\n email: args.email,\n name: args.name,\n publicKey,\n ...(userType ? { type: userType } : {}),\n },\n })\n\n consola.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { digCommand } from './dig'\n\n/**\n * `apes utils …` — admin/diagnostic utilities. Started with `dig` (DDISA\n * IdP resolution); intended home for future probes (token decoders,\n * config dumpers, version reporters, etc.) that don't fit into the\n * grants/agents/auth namespaces.\n */\nexport const utilsCommand = defineCommand({\n meta: {\n name: 'utils',\n description: 'Admin/diagnostic utilities (dig, …)',\n },\n subCommands: {\n dig: digCommand,\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { resolveDDISA } from '@openape/core'\nimport { CliError } from '../../errors'\n\n/**\n * `apes utils dig <domain|email>` — DDISA-aware DNS lookup.\n *\n * Resolves the IdP for a domain (or strips the local part of an email and\n * resolves the domain). Prints the TXT record, parsed DDISA fields, and a\n * one-shot OIDC discovery probe so you can tell at a glance whether\n * `apes login user@<domain>` will work.\n *\n * Supersedes the older `apes dns-check` which only accepted a bare domain.\n */\nexport const digCommand = defineCommand({\n meta: {\n name: 'dig',\n description: 'Resolve DDISA IdP for a domain or email (admin/diag tool)',\n },\n args: {\n target: {\n type: 'positional',\n description: 'Domain (example.com) or email (alice@example.com)',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Machine-readable JSON output',\n },\n },\n async run({ args }) {\n const raw = String(args.target).trim()\n const at = raw.indexOf('@')\n const domain = at >= 0 ? raw.slice(at + 1) : raw\n const localPart = at >= 0 ? raw.slice(0, at) : null\n\n if (!domain || !/^[a-z0-9.-]+\\.[a-z]{2,}$/i.test(domain)) {\n throw new CliError(`Invalid domain: ${domain}`)\n }\n\n interface DigResult {\n input: string\n domain: string\n localPart: string | null\n ddisa: { found: boolean, idp?: string, version?: string, mode?: string, priority?: number }\n idpDiscovery?: { ok: boolean, status?: number, issuer?: string, ddisaVersion?: string, authMethods?: string[], grantTypes?: string[] }\n hint?: string\n }\n const result: DigResult = {\n input: raw,\n domain,\n localPart,\n ddisa: { found: false },\n }\n\n const ddisa = await resolveDDISA(domain)\n if (ddisa) {\n result.ddisa = {\n found: true,\n idp: ddisa.idp,\n version: ddisa.version,\n mode: ddisa.mode,\n priority: ddisa.priority,\n }\n\n try {\n const resp = await fetch(`${ddisa.idp}/.well-known/openid-configuration`)\n if (resp.ok) {\n const disco = await resp.json() as Record<string, unknown>\n result.idpDiscovery = {\n ok: true,\n status: resp.status,\n issuer: typeof disco.issuer === 'string' ? disco.issuer : undefined,\n ddisaVersion: typeof disco.ddisa_version === 'string' ? disco.ddisa_version : undefined,\n authMethods: Array.isArray(disco.ddisa_auth_methods_supported) ? disco.ddisa_auth_methods_supported as string[] : undefined,\n grantTypes: Array.isArray(disco.openape_grant_types_supported) ? disco.openape_grant_types_supported as string[] : undefined,\n }\n }\n else {\n result.idpDiscovery = { ok: false, status: resp.status }\n }\n }\n catch (err) {\n result.idpDiscovery = { ok: false }\n result.hint = `IdP at ${ddisa.idp} unreachable: ${err instanceof Error ? err.message : String(err)}`\n }\n }\n else {\n result.hint = `No DDISA record. Add a TXT record:\\n _ddisa.${domain} TXT \"v=ddisa1 idp=https://id.${domain}; mode=open\"`\n }\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n if (!result.ddisa.found || result.idpDiscovery?.ok === false) process.exit(1)\n return\n }\n\n console.log(`Target: ${raw}`)\n if (localPart) console.log(` user: ${localPart}`)\n console.log(` domain: ${domain}`)\n console.log('')\n\n if (!result.ddisa.found) {\n consola.warn(`No DDISA record at _ddisa.${domain}`)\n if (result.hint) console.log(`\\n${result.hint}`)\n throw new CliError(`No DDISA record found for ${domain}`)\n }\n\n consola.success(`_ddisa.${domain} → ${result.ddisa.idp}`)\n console.log(` Version: ${result.ddisa.version || 'ddisa1'}`)\n console.log(` IdP URL: ${result.ddisa.idp}`)\n if (result.ddisa.mode) console.log(` Mode: ${result.ddisa.mode}`)\n if (result.ddisa.priority !== undefined) console.log(` Priority: ${result.ddisa.priority}`)\n console.log('')\n\n if (!result.idpDiscovery) {\n // No discovery attempt happened — shouldn't reach here in practice\n return\n }\n if (result.idpDiscovery.ok) {\n consola.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`)\n if (result.idpDiscovery.issuer) console.log(` Issuer: ${result.idpDiscovery.issuer}`)\n if (result.idpDiscovery.ddisaVersion) console.log(` DDISA: v${result.idpDiscovery.ddisaVersion}`)\n if (result.idpDiscovery.authMethods?.length) console.log(` Auth: ${result.idpDiscovery.authMethods.join(', ')}`)\n if (result.idpDiscovery.grantTypes?.length) console.log(` Grants: ${result.idpDiscovery.grantTypes.join(', ')}`)\n }\n else {\n consola.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ''}`)\n if (result.hint) console.log(`\\n${result.hint}`)\n throw new CliError(`IdP at ${result.ddisa.idp} not reachable`)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { sessionsListCommand } from './list'\nimport { sessionsRemoveCommand } from './remove'\n\n/**\n * `apes sessions …` — manage your own refresh-token families across\n * devices. One family per `apes login`. Use `list` to see what's active,\n * `remove <familyId>` to revoke a stale device.\n */\nexport const sessionsCommand = defineCommand({\n meta: {\n name: 'sessions',\n description: 'Manage your active refresh-token sessions across devices',\n },\n subCommands: {\n list: sessionsListCommand,\n remove: sessionsRemoveCommand,\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { apiFetch } from '../../http'\n\ninterface Family {\n familyId: string\n userId: string\n clientId: string\n createdAt: number\n expiresAt: number\n revoked: boolean\n}\n\ninterface ListResponse {\n data: Family[]\n pagination?: { cursor: string | null, has_more: boolean }\n}\n\nexport const sessionsListCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List your active refresh-token families (one per logged-in device).',\n },\n args: {\n json: { type: 'boolean', description: 'JSON output' },\n limit: { type: 'string', description: 'Max rows (default 50)' },\n },\n async run({ args }) {\n const path = args.limit ? `/api/me/sessions?limit=${encodeURIComponent(String(args.limit))}` : '/api/me/sessions'\n const result = await apiFetch<ListResponse>(path)\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n return\n }\n\n if (result.data.length === 0) {\n consola.info('No active sessions.')\n return\n }\n\n for (const f of result.data) {\n const created = new Date(f.createdAt).toISOString()\n const expires = new Date(f.expiresAt).toISOString()\n console.log(`${f.familyId} client=${f.clientId} created=${created} expires=${expires}`)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { apiFetch } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const sessionsRemoveCommand = defineCommand({\n meta: {\n name: 'remove',\n description: 'Revoke one of your active refresh-token families by id.',\n },\n args: {\n familyId: {\n type: 'positional',\n required: true,\n description: 'Family id (from `apes sessions list`).',\n },\n },\n async run({ args }) {\n const id = String(args.familyId).trim()\n if (!id) throw new CliError('familyId required')\n await apiFetch(`/api/me/sessions/${encodeURIComponent(id)}`, { method: 'DELETE' })\n consola.success(`Session ${id} revoked. The device using it will need to \\`apes login\\` again on its next refresh.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { resolveDDISA } from '@openape/core'\nimport { CliError } from '../errors'\n\nexport const dnsCheckCommand = defineCommand({\n meta: {\n name: 'dns-check',\n description: 'Validate DDISA DNS TXT records for a domain',\n },\n args: {\n domain: {\n type: 'positional',\n description: 'Domain to check (e.g. example.com)',\n required: true,\n },\n },\n async run({ args }) {\n const domain = args.domain\n\n consola.start(`Checking _ddisa.${domain}...`)\n\n try {\n const result = await resolveDDISA(domain)\n\n if (!result) {\n console.log('')\n console.log('To set up DDISA, add a DNS TXT record:')\n console.log(` _ddisa.${domain} TXT \"v=ddisa1 idp=https://id.${domain}\"`)\n throw new CliError(`No DDISA record found for ${domain}`)\n }\n\n consola.success(`_ddisa.${domain} → ${result.idp}`)\n console.log('')\n console.log(` Version: ${result.version || 'ddisa1'}`)\n console.log(` IdP URL: ${result.idp}`)\n if (result.mode)\n console.log(` Mode: ${result.mode}`)\n if (result.priority !== undefined)\n console.log(` Priority: ${result.priority}`)\n\n // Try OIDC discovery on the IdP\n console.log('')\n consola.start(`Verifying IdP at ${result.idp}...`)\n\n const discoResp = await fetch(`${result.idp}/.well-known/openid-configuration`)\n\n if (!discoResp.ok) {\n consola.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`)\n return\n }\n\n const disco = await discoResp.json() as Record<string, unknown>\n\n consola.success(`IdP is reachable`)\n console.log(` Issuer: ${disco.issuer}`)\n console.log(` DDISA: v${disco.ddisa_version || '?'}`)\n\n if (disco.ddisa_auth_methods_supported) {\n console.log(` Auth: ${(disco.ddisa_auth_methods_supported as string[]).join(', ')}`)\n }\n\n if (disco.openape_grant_types_supported) {\n console.log(` Grants: ${(disco.openape_grant_types_supported as string[]).join(', ')}`)\n }\n }\n catch (err) {\n throw new CliError(`DNS check failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n },\n})\n","import { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { defineCommand } from 'citty'\nimport { AUTH_FILE, CONFIG_DIR, loadAuth } from '../config'\nimport { apiFetch, getGrantsEndpoint } from '../http'\nimport { CliError } from '../errors'\n\ndeclare const __VERSION__: string\n\ninterface HealthArgs {\n json: boolean\n}\n\ninterface HealthReport {\n version: string\n config: { dir: string }\n auth: {\n file: string\n present: boolean\n email?: string\n type?: 'human' | 'agent'\n idp?: string\n expires_at_iso?: string\n expires_at_local?: string\n expired?: boolean\n }\n idp: { url?: string, reachable: boolean, error?: string }\n grants: { count?: number, error?: string }\n ape_shell_binary: string | null\n ok: boolean\n}\n\nconst execAsync = promisify(exec)\n\nasync function resolveApeShellPath(): Promise<string | null> {\n try {\n const { stdout } = await execAsync('command -v ape-shell', { shell: '/bin/bash' })\n const trimmed = stdout.trim()\n return trimmed.length > 0 ? trimmed : null\n }\n catch {\n return null\n }\n}\n\nasync function probeIdp(url: string): Promise<{ reachable: true } | { reachable: false, error: string }> {\n const ctrl = new AbortController()\n const timeout = setTimeout(() => ctrl.abort(), 3000)\n try {\n // Plain fetch — we don't want apiFetch's bearer token or retry logic.\n // HEAD may not be supported; fall back to GET if needed.\n await fetch(url, { method: 'GET', signal: ctrl.signal })\n return { reachable: true }\n }\n catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { reachable: false, error: message }\n }\n finally {\n clearTimeout(timeout)\n }\n}\n\nasync function bestEffortGrantCount(idp: string): Promise<{ count: number } | { error: string }> {\n try {\n const grantsUrl = await getGrantsEndpoint(idp)\n const res = await apiFetch<{ data: unknown[] }>(`${grantsUrl}?limit=1`)\n const count = Array.isArray(res?.data) ? res.data.length : 0\n return { count }\n }\n catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { error: message }\n }\n}\n\nexport async function runHealth(args: HealthArgs): Promise<void> {\n const version = typeof __VERSION__ === 'string' ? __VERSION__ : '0.0.0'\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.', 1)\n }\n\n const isAgent = auth.email.includes('agent+')\n const expiresDate = new Date(auth.expires_at * 1000)\n const isExpired = Date.now() / 1000 > auth.expires_at\n\n if (isExpired) {\n throw new CliError(`Token expired at ${expiresDate.toISOString()}. Run \\`apes login\\`.`, 1)\n }\n\n const idpProbe = await probeIdp(auth.idp)\n const grantInfo = await bestEffortGrantCount(auth.idp)\n const apeShellPath = await resolveApeShellPath()\n\n const report: HealthReport = {\n version,\n config: { dir: CONFIG_DIR },\n auth: {\n file: AUTH_FILE,\n present: true,\n email: auth.email,\n type: isAgent ? 'agent' : 'human',\n idp: auth.idp,\n expires_at_iso: expiresDate.toISOString(),\n expires_at_local: expiresDate.toLocaleString(),\n expired: false,\n },\n idp: {\n url: auth.idp,\n reachable: idpProbe.reachable,\n ...('error' in idpProbe ? { error: idpProbe.error } : {}),\n },\n grants: 'count' in grantInfo\n ? { count: grantInfo.count }\n : { error: grantInfo.error },\n ape_shell_binary: apeShellPath,\n ok: idpProbe.reachable,\n }\n\n if (args.json) {\n console.log(JSON.stringify(report, null, 2))\n }\n else {\n console.log(`apes ${version}`)\n console.log('')\n console.log(`Config: ${CONFIG_DIR}`)\n console.log(`Auth: ${AUTH_FILE}`)\n console.log(` ${auth.email} (${isAgent ? 'agent' : 'human'})`)\n console.log(` IdP: ${auth.idp}`)\n console.log(` Token: valid until ${expiresDate.toISOString()} (local: ${expiresDate.toLocaleString()})`)\n console.log('')\n if (idpProbe.reachable) {\n console.log('IdP: reachable')\n }\n else {\n console.log(`IdP: <unreachable: ${idpProbe.error}>`)\n }\n if ('count' in grantInfo) {\n console.log(`Grants: ${grantInfo.count}`)\n }\n else {\n console.log(`Grants: <unreachable: ${grantInfo.error}>`)\n }\n console.log(`ape-shell: ${apeShellPath ?? '(not on PATH)'}`)\n }\n\n if (!idpProbe.reachable) {\n throw new CliError(`IdP ${auth.idp} unreachable: ${idpProbe.error}`, 1)\n }\n}\n\nexport const healthCommand = defineCommand({\n meta: {\n name: 'health',\n description: 'Report CLI diagnostic state (auth, IdP, grants, binaries)',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Emit a machine-readable JSON report',\n default: false,\n },\n },\n async run({ args }) {\n await runHealth({ json: Boolean(args.json) })\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { guides } from '../guides'\nimport { CliError } from '../errors'\n\nexport const workflowsCommand = defineCommand({\n meta: {\n name: 'workflows',\n description: 'Discover workflow guides',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Guide ID to show (omit for list)',\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n run({ args }) {\n if (args.id) {\n const guide = guides.find(g => g.id === String(args.id))\n if (!guide) {\n consola.info(`Available: ${guides.map(g => g.id).join(', ')}`)\n throw new CliError(`Guide not found: ${args.id}`)\n }\n\n if (args.json) {\n console.log(JSON.stringify(guide, null, 2))\n return\n }\n\n console.log(`\\n ${guide.title}`)\n console.log(` ${guide.description}\\n`)\n for (let i = 0; i < guide.steps.length; i++) {\n const step = guide.steps[i]!\n if (step.note) {\n console.log(` Note: ${step.note}`)\n }\n else {\n console.log(` ${i + 1}. ${step.description}`)\n if (step.command) {\n console.log(` $ ${step.command}`)\n }\n }\n }\n console.log()\n return\n }\n\n // List mode\n if (args.json) {\n console.log(JSON.stringify(guides.map(g => ({ id: g.id, title: g.title, description: g.description })), null, 2))\n return\n }\n\n console.log('\\n Workflow Guides\\n')\n for (const guide of guides) {\n console.log(` ${guide.id.padEnd(24)} ${guide.title}`)\n }\n console.log(`\\n Show a guide: apes workflows <id>\\n`)\n },\n})\n","export interface WorkflowStep {\n description?: string\n command?: string\n note?: string\n}\n\nexport interface WorkflowGuide {\n id: string\n title: string\n description: string\n steps: WorkflowStep[]\n}\n\nexport const guides: WorkflowGuide[] = [\n {\n id: 'timed-session',\n title: 'Timed maintenance session',\n description: 'Request a timed grant for multiple commands without per-command approval.',\n steps: [\n { description: 'Request a timed grant (e.g. 1 hour)', command: 'apes run --approval timed -- <your-command>' },\n { description: 'Approve the grant in the browser (link is printed)' },\n { description: 'Subsequent commands reuse the timed grant until it expires' },\n { note: 'Use --approval always for standing permissions (revoke manually when done)' },\n ],\n },\n {\n id: 'agent-onboarding',\n title: 'Onboard a new agent',\n description: 'Register an AI agent with a DDISA identity in under 3 minutes.',\n steps: [\n { description: 'Initialize a new project (optional)', command: 'apes init --sp my-app' },\n { description: 'Enroll the agent at an IdP', command: 'apes enroll' },\n { description: 'Verify enrollment', command: 'apes whoami' },\n { description: 'Check DNS discovery', command: 'apes dns-check' },\n ],\n },\n {\n id: 'delegation',\n title: 'Delegate permissions',\n description: 'Let an agent act on your behalf at a specific service.',\n steps: [\n { description: 'Create a delegation', command: 'apes grants delegate --to agent@example.com --at api.example.com' },\n { description: 'List active delegations', command: 'apes grants delegations' },\n { description: 'Revoke when no longer needed', command: 'apes grants revoke <delegation-id>' },\n ],\n },\n {\n id: 'privilege-escalation',\n title: 'Run commands as root (escapes)',\n description: 'Execute privileged commands with grant-verified escalation.',\n steps: [\n { description: 'Request a grant to run a command as root', command: 'apes run --as root -- apt-get upgrade' },\n { description: 'Approve the grant in the browser' },\n { description: 'The command executes via escapes with verified authorization' },\n { note: 'escapes must be installed on the target machine (cargo build && sudo make install)' },\n ],\n },\n]\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport consola from 'consola'\n\n/**\n * Compare the running apes version against the latest published on npm\n * and warn the user if they're behind. Skipped silently when:\n * - the env var APES_NO_UPDATE_CHECK is set (CI, scripts that are\n * deliberate about pin)\n * - the cached lookup is fresh (24h TTL — npm registry rate-limit\n * friendly and the warning is annoying if it fires every command)\n * - the network call fails (offline, dns down, npm hiccup) — no\n * warning is more useful than a confusing one\n *\n * Cached state lives at `~/.config/apes/.version-check.json`:\n * { latest: \"0.21.2\", checkedAt: 1714770000 }\n *\n * Called from cli.ts at process start. Async-fire-and-forget — the\n * actual command runs immediately; the warning prints when the lookup\n * completes (usually <100ms, well before any human-in-the-loop step).\n */\n\nconst PACKAGE_NAME = '@openape/apes'\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000\nconst CACHE_FILE = join(homedir(), '.config', 'apes', '.version-check.json')\n\ninterface CacheEntry {\n latest: string\n checkedAt: number\n}\n\nfunction readCache(): CacheEntry | null {\n if (!existsSync(CACHE_FILE)) return null\n try {\n return JSON.parse(readFileSync(CACHE_FILE, 'utf-8')) as CacheEntry\n }\n catch {\n return null\n }\n}\n\nfunction writeCache(entry: CacheEntry): void {\n try {\n const dir = join(homedir(), '.config', 'apes')\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 0o700 })\n writeFileSync(CACHE_FILE, JSON.stringify(entry), { mode: 0o600 })\n }\n catch { /* best effort */ }\n}\n\n/**\n * Tiny semver compare — assumes valid x.y.z (no pre-release suffixes for\n * apes). Returns negative if a < b, 0 if equal, positive if a > b.\n */\nfunction compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number)\n const pb = b.split('.').map(Number)\n for (let i = 0; i < Math.max(pa.length, pb.length); i++) {\n const x = pa[i] ?? 0\n const y = pb[i] ?? 0\n if (x !== y) return x - y\n }\n return 0\n}\n\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n // Plain `application/json` — the vnd.npm.install-v1+json variant is\n // only valid on the full package endpoint, NOT on /latest (returns 406).\n const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(2_000),\n })\n if (!res.ok) return null\n const body = await res.json() as { version?: string }\n return typeof body.version === 'string' ? body.version : null\n }\n catch {\n return null\n }\n}\n\nfunction warnIfBehind(currentVersion: string, latest: string): void {\n if (compareSemver(currentVersion, latest) < 0) {\n consola.warn(\n `apes ${currentVersion} is behind latest @openape/apes@${latest}. `\n + `Run \\`npm i -g @openape/apes@latest\\` to update. `\n + `(Suppress with APES_NO_UPDATE_CHECK=1.)`,\n )\n }\n}\n\n/**\n * Two-phase check so users see the warning immediately when something\n * is known stale, without paying network latency on every command:\n *\n * 1. Synchronous cache read. If the cache is fresh AND says we're\n * behind, warn now. Most calls hit this path with zero latency.\n * 2. Async refresh in the background (fire-and-forget, doesn't\n * block the actual command). Updates cache for the next call.\n * If no cache existed at all (first run), this won't print on\n * this invocation — but the next invocation will see the cache.\n *\n * Bypass with `APES_NO_UPDATE_CHECK=1` (CI, scripts pinning a version).\n */\nexport async function maybeWarnStaleVersion(currentVersion: string): Promise<void> {\n if (process.env.APES_NO_UPDATE_CHECK) return\n if (!currentVersion || currentVersion === 'unknown') return\n\n const cached = readCache()\n const now = Date.now()\n\n if (cached) {\n warnIfBehind(currentVersion, cached.latest)\n }\n\n if (!cached || now - cached.checkedAt >= CACHE_TTL_MS) {\n const latest = await fetchLatestVersion()\n if (latest) {\n writeCache({ latest, checkedAt: now })\n if (!cached) warnIfBehind(currentVersion, latest)\n }\n }\n}\n"],"mappings":"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","names":["consola","defineCommand","Buffer","homedir","consola","consola","resolve","readFileSync","sign","loadEd25519PrivateKey","Buffer","homedir","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","hostname","defineCommand","consola","waitForApproval","consola","resolve","defineCommand","hostname","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","auth","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","consola","defineCommand","consola","existsSync","homedir","defineCommand","consola","getManagementToken","defineCommand","consola","homedir","existsSync","defineCommand","defineCommand","defineCommand","consola","path","defineCommand","consola","defineCommand","defineCommand","execFileSync","defineCommand","consola","Buffer","execFileSync","Buffer","execFileSync","execFileSync","existsSync","readFileSync","defineCommand","shQuote","consola","execFileSync","execFileSync","defineCommand","consola","defineCommand","consola","execFileSync","existsSync","readFileSync","homedir","join","process","defineCommand","consola","existsSync","readFileSync","homedir","join","CONFIG_DIR","path","join","DIFF_CAP","join","CliError","join","homedir","existsSync","readFileSync","process","defineCommand","consola","execFileSync","rmSync","writeFileSync","join","defineCommand","consola","existsSync","readFileSync","homedir","join","path","resolve","defineCommand","consola","execFileSync","join","writeFileSync","rmSync","defineCommand","consola","defineCommand","consola","existsSync","readFileSync","defineCommand","consola","defineCommand","existsSync","readFileSync","consola","existsSync","readFileSync","homedir","join","defineCommand","consola","join","homedir","existsSync","readFileSync","consola","path","readLitellmConfig","defineCommand","existsSync","readFileSync","homedir","join","defineCommand","AUTH_PATH","join","homedir","readLitellmConfig","existsSync","readFileSync","defineCommand","result","execFileSync","mkdtempSync","rmSync","writeFileSync","tmpdir","join","defineCommand","consola","Buffer","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","resolve","resolve","homedir","Buffer","existsSync","readFileSync","mkdirSync","writeFileSync","execFileSync","existsSync","readFileSync","homedir","dirname","join","defineCommand","mkdtempSync","join","tmpdir","consola","writeFileSync","execFileSync","rmSync","existsSync","mkdirSync","readdirSync","readFileSync","rmSync","writeFileSync","homedir","join","defineCommand","consola","execFileSync","hostname","AUTH_PATH","join","homedir","TASK_CACHE_DIR","existsSync","readFileSync","defineCommand","consola","path","mkdirSync","writeFileSync","readdirSync","rmSync","defineCommand","defineCommand","execFileSync","existsSync","readFileSync","join","defineCommand","consola","hostname","homedir","existsSync","mkdirSync","writeFileSync","join","defineCommand","consola","join","homedir","hostname","defineCommand","existsSync","mkdirSync","consola","writeFileSync","defineCommand","join","existsSync","readFileSync","consola","execFileSync","execFileSync","defineCommand","consola","defineCommand","execFileSync","consola","execFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","userInfo","dirname","join","defineCommand","consola","join","homedir","escape","installAdapter","mkdirSync","dirname","readFileSync","writeFileSync","consola","existsSync","defineCommand","userInfo","execFileSync","defineCommand","consola","defineCommand","consola","execFileSync","defineCommand","consola","defineCommand","execFileSync","consola","execFileSync","existsSync","homedir","userInfo","join","defineCommand","consola","PLIST_LABEL","path","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","consola","defineCommand","index","consola","execFileSync","hostname","defineCommand","consola","consola","defineCommand","hostname","execFileSync","authz_jwt","spawn","existsSync","homedir","join","defineCommand","consola","mkdtempSync","rmSync","writeFileSync","tmpdir","dirname","join","resolve","require","existsSync","mkdtempSync","readFileSync","unlinkSync","writeFileSync","tmpdir","join","path","consola","defineCommand","join","homedir","existsSync","spawn","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","defineCommand","existsSync","writeFileSync","execFileSync","join","defineCommand","consola","existsSync","join","execFileSync","consola","defineCommand","writeFileSync","Buffer","existsSync","readFileSync","execFile","sign","defineCommand","consola","DEFAULT_IDP_URL","openBrowser","execFile","readFileSync","sign","Buffer","resolve","defineCommand","consola","existsSync","existsSync","readFileSync","defineCommand","consola","defineCommand","existsSync","readFileSync","consola","defineCommand","defineCommand","consola","resolveDDISA","defineCommand","resolveDDISA","consola","defineCommand","defineCommand","defineCommand","consola","defineCommand","path","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","consola","resolveDDISA","defineCommand","consola","resolveDDISA","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","consola","defineCommand","loadAuth","consola"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/ape-shell.ts","../src/commands/auth/login.ts","../src/commands/auth/resolve-login.ts","../src/commands/auth/logout.ts","../src/commands/auth/whoami.ts","../src/commands/grants/list.ts","../src/commands/grants/inbox.ts","../src/commands/grants/status.ts","../src/commands/grants/request.ts","../src/commands/grants/request-capability.ts","../src/commands/grants/approve.ts","../src/commands/grants/deny.ts","../src/commands/grants/revoke.ts","../src/commands/grants/run.ts","../src/grant-poll.ts","../src/commands/grants/token.ts","../src/commands/grants/delegate.ts","../src/commands/grants/delegations.ts","../src/commands/grants/delegation-revoke.ts","../src/commands/admin/index.ts","../src/commands/admin/users.ts","../src/commands/admin/ssh-keys.ts","../src/commands/agent/index.ts","../src/commands/agent/deploy.ts","../src/lib/troop-client.ts","../src/commands/agents/index.ts","../src/commands/agents/allow.ts","../src/lib/agent-bootstrap.ts","../src/lib/macos-user.ts","../src/commands/agents/cleanup-orphans.ts","../src/commands/agents/code.ts","../src/lib/agent-secrets-runtime.ts","../src/lib/coding/issue-task.ts","../src/lib/coding/merge-policy.ts","../src/lib/coding/review-gate.ts","../src/lib/coding/coding-loop.ts","../src/lib/coding/llm-review.ts","../src/lib/coding/derive-policy.ts","../src/commands/agents/destroy.ts","../src/lib/nest-registry.ts","../src/lib/silent-password.ts","../src/commands/agents/list.ts","../src/commands/agents/register.ts","../src/commands/agents/run.ts","../src/commands/agents/serve.ts","../src/commands/agents/spawn.ts","../src/lib/troop-bootstrap.ts","../src/lib/keygen.ts","../src/lib/llm-bridge.ts","../src/commands/agents/sync.ts","../src/lib/macos-host.ts","../src/commands/nest/index.ts","../src/commands/nest/authorize.ts","../src/commands/nest/enroll.ts","../src/commands/nest/destroy.ts","../src/commands/nest/install.ts","../src/commands/nest/apes-agents-adapter.ts","../src/commands/nest/list.ts","../src/commands/nest/spawn.ts","../src/commands/nest/uninstall.ts","../src/commands/yolo/index.ts","../src/commands/yolo/clear.ts","../src/commands/yolo/set.ts","../src/commands/yolo/show.ts","../src/commands/adapter/index.ts","../src/commands/run.ts","../src/commands/proxy.ts","../src/proxy/config.ts","../src/proxy/local-proxy.ts","../src/proxy/trust-bundle.ts","../src/commands/explain.ts","../src/commands/config/get.ts","../src/commands/config/set.ts","../src/commands/fetch/index.ts","../src/commands/mcp/index.ts","../src/commands/init/index.ts","../src/commands/enroll.ts","../src/commands/register-user.ts","../src/commands/utils/index.ts","../src/commands/utils/dig.ts","../src/commands/sessions/index.ts","../src/commands/sessions/list.ts","../src/commands/sessions/remove.ts","../src/commands/dns-check.ts","../src/commands/health.ts","../src/commands/workflows.ts","../src/guides/index.ts","../src/version-check.ts"],"sourcesContent":["import consola from 'consola'\nimport { rewriteApeShellArgs } from './ape-shell'\nimport { defineCommand, runMain } from 'citty'\nimport { loginCommand } from './commands/auth/login'\nimport { logoutCommand } from './commands/auth/logout'\nimport { whoamiCommand } from './commands/auth/whoami'\nimport { listCommand } from './commands/grants/list'\nimport { inboxCommand } from './commands/grants/inbox'\nimport { statusCommand } from './commands/grants/status'\nimport { requestCommand } from './commands/grants/request'\nimport { requestCapabilityCommand } from './commands/grants/request-capability'\nimport { approveCommand } from './commands/grants/approve'\nimport { denyCommand } from './commands/grants/deny'\nimport { revokeCommand } from './commands/grants/revoke'\nimport { runGrantCommand } from './commands/grants/run'\nimport { tokenCommand } from './commands/grants/token'\nimport { delegateCommand } from './commands/grants/delegate'\nimport { delegationsCommand } from './commands/grants/delegations'\nimport { delegationRevokeCommand } from './commands/grants/delegation-revoke'\nimport { adminCommand } from './commands/admin/index'\nimport { agentCommand } from './commands/agent/index'\nimport { agentsCommand } from './commands/agents/index'\nimport { nestCommand } from './commands/nest/index'\nimport { yoloCommand } from './commands/yolo/index'\nimport { adapterCommand } from './commands/adapter/index'\nimport { runCommand } from './commands/run'\nimport { proxyCommand } from './commands/proxy'\nimport { explainCommand } from './commands/explain'\nimport { configGetCommand } from './commands/config/get'\nimport { configSetCommand } from './commands/config/set'\nimport { fetchCommand } from './commands/fetch/index'\nimport { mcpCommand } from './commands/mcp/index'\nimport { initCommand } from './commands/init/index'\nimport { enrollCommand } from './commands/enroll'\nimport { registerUserCommand } from './commands/register-user'\nimport { utilsCommand } from './commands/utils/index'\nimport { sessionsCommand } from './commands/sessions/index'\nimport { dnsCheckCommand } from './commands/dns-check'\nimport { healthCommand } from './commands/health'\nimport { workflowsCommand } from './commands/workflows'\nimport { ApiError } from './http'\nimport { CliError, CliExit } from './errors'\nimport { maybeWarnStaleVersion } from './version-check'\n\n// Gracefully handle EPIPE when stdout is closed early (e.g. piped to `head`)\nprocess.stdout.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EPIPE') process.exit(0)\n throw err\n})\n\ndeclare const __VERSION__: string\n\n// ape-shell mode:\n// • `ape-shell -c <command>` rewrites to `apes run --shell -- bash -c <command>` (one-shot)\n// • `ape-shell` (no args), `-i`, `-l`, or invoked as a login shell → interactive REPL\n// Pass `process.argv0` explicitly so the wrapper script path (which uses\n// bash's `exec -a \"$0\"` to preserve the original argv[0] from login/sshd)\n// still benefits from login-shell detection when the cli.js is invoked\n// indirectly via the ape-shell-wrapper.sh shim.\nconst shellRewrite = rewriteApeShellArgs(process.argv, process.argv0)\nif (shellRewrite) {\n if (shellRewrite.action === 'rewrite') {\n process.argv = shellRewrite.argv\n }\n else if (shellRewrite.action === 'version') {\n console.log(`ape-shell ${__VERSION__} (OpenApe DDISA shell wrapper)`)\n process.exit(0)\n }\n else if (shellRewrite.action === 'help') {\n console.log(`ape-shell ${__VERSION__} — OpenApe DDISA shell wrapper`)\n console.log('')\n console.log('Usage:')\n console.log(' ape-shell Start interactive grant-mediated REPL')\n console.log(' ape-shell -c <command> Run a single command through the grant flow')\n console.log(' ape-shell -i | -l Force interactive mode')\n console.log('')\n console.log('Options:')\n console.log(' -c <command> Execute <command> via the apes grant flow and exit')\n console.log(' -i Interactive REPL (default when no args are given)')\n console.log(' -l, --login Login shell semantics — currently same as -i')\n console.log(' --version, -v Show ape-shell version')\n console.log(' --help, -h Show this help message')\n process.exit(0)\n }\n else if (shellRewrite.action === 'interactive') {\n // Hand control to the interactive REPL orchestrator. Never returns to\n // citty dispatch. Dynamic import so the startup path for `ape-shell -c`\n // stays lean (node-pty native module is only loaded when needed).\n const { runInteractiveShell } = await import('./shell/orchestrator.js')\n await runInteractiveShell()\n process.exit(0)\n }\n else {\n console.error('ape-shell: unsupported invocation. Try `ape-shell --help`.')\n process.exit(1)\n }\n}\n\nconst debug = process.argv.includes('--debug')\n\nconst grantsCommand = defineCommand({\n meta: {\n name: 'grants',\n description: 'Grant management',\n },\n subCommands: {\n list: listCommand,\n inbox: inboxCommand,\n status: statusCommand,\n request: requestCommand,\n 'request-capability': requestCapabilityCommand,\n approve: approveCommand,\n deny: denyCommand,\n revoke: revokeCommand,\n run: runGrantCommand,\n token: tokenCommand,\n delegate: delegateCommand,\n delegations: delegationsCommand,\n 'delegation-revoke': delegationRevokeCommand,\n },\n})\n\nconst configCommand = defineCommand({\n meta: {\n name: 'config',\n description: 'Configuration management',\n },\n subCommands: {\n get: configGetCommand,\n set: configSetCommand,\n },\n})\n\nconst main = defineCommand({\n meta: {\n name: 'apes',\n version: __VERSION__,\n description: 'Unified CLI for OpenApe',\n },\n subCommands: {\n init: initCommand,\n enroll: enrollCommand,\n 'register-user': registerUserCommand,\n 'dns-check': dnsCheckCommand,\n utils: utilsCommand,\n sessions: sessionsCommand,\n login: loginCommand,\n logout: logoutCommand,\n whoami: whoamiCommand,\n health: healthCommand,\n grants: grantsCommand,\n agent: agentCommand,\n agents: agentsCommand,\n nest: nestCommand,\n yolo: yoloCommand,\n admin: adminCommand,\n run: runCommand,\n proxy: proxyCommand,\n explain: explainCommand,\n adapter: adapterCommand,\n config: configCommand,\n fetch: fetchCommand,\n mcp: mcpCommand,\n workflows: workflowsCommand,\n },\n})\n\n// Auto-refresh: every command except those that don't need (or shouldn't\n// touch) existing auth gets a transparent token refresh before its handler\n// runs. Matches `ape-shell` behavior — users no longer need to re-`apes\n// login` when an SP rejects their token; the CLI rotates it on the next\n// invocation. login/logout obviously skip; init/enroll/register-user are\n// pre-auth bootstrap; dns-check/utils/explain/workflows are diagnostic and\n// offline-safe.\nconst NO_REFRESH_COMMANDS = new Set([\n 'login', 'logout',\n 'init', 'enroll', 'register-user',\n 'dns-check', 'utils', 'explain', 'workflows',\n '--help', '-h', 'help',\n '--version', '-v',\n])\n\nasync function maybeRefreshAuth(): Promise<void> {\n const sub = process.argv[2]\n if (!sub || NO_REFRESH_COMMANDS.has(sub)) return\n const { loadAuth } = await import('./config.js')\n if (!loadAuth()) return // not logged in — nothing to refresh\n try {\n const { ensureFreshToken } = await import('./http.js')\n await ensureFreshToken()\n }\n catch {\n // Refresh failures are non-fatal — the actual command will surface a\n // proper auth error if the token is genuinely unusable.\n }\n}\n\nawait maybeRefreshAuth()\n\n// Stale-version notice. Synchronous cache read prints instantly when\n// we already know we're behind; the actual npm round-trip is bounded\n// to 2s by an AbortSignal so command startup never blocks for long.\n// Cached 24h, so this is a one-time cost per day.\nawait maybeWarnStaleVersion(__VERSION__).catch(() => { /* never block */ })\n\nrunMain(main).catch((err) => {\n if (err instanceof CliExit) {\n process.exit(err.exitCode)\n }\n if (err instanceof CliError) {\n consola.error(err.message)\n process.exit(err.exitCode)\n }\n if (debug) {\n consola.error(err)\n }\n else {\n consola.error(err instanceof ApiError ? err.message : err instanceof Error ? err.message : String(err))\n }\n process.exit(1)\n})\n","import path from 'node:path'\n\n/**\n * Possible actions emitted by `rewriteApeShellArgs` for the caller to\n * dispatch. `rewrite` means argv has been transformed and the normal CLI\n * command dispatch should continue with the new argv. `interactive` means\n * the caller should hand control to the interactive REPL. The other\n * actions print version/help/error text and exit.\n */\nexport type ApeShellAction =\n | { action: 'rewrite', argv: string[] }\n | { action: 'version' }\n | { action: 'help' }\n | { action: 'error' }\n | { action: 'interactive' }\n\n/**\n * Decides how `ape-shell` was invoked and what the caller should do next.\n * Backward compatibility is strict: any invocation with `-c \"<command>\"`\n * keeps the historical rewrite behavior so `SHELL=$(which ape-shell) <prog>`\n * patterns (e.g. `SHELL=ape-shell openclaw tui`) continue to work.\n *\n * Detection strategy:\n * 1. `process.env.APES_SHELL_WRAPPER === '1'` is the strongest signal —\n * it means we were invoked via the ape-shell-wrapper.sh shell script,\n * which hoists node onto PATH before exec-ing cli.js. In that case\n * argv[1] becomes `cli.js` (or some dist/chunk file) and the old\n * basename check fails, so we trust the wrapper's declaration.\n * 2. Otherwise fall back to `argv[1]` basename matching literal\n * `ape-shell` / `ape-shell.js` (the direct-symlink invocation path).\n *\n * After detection, the rest of the rules decide the action (first match):\n * • `-c <command>` → rewrite to `apes run --shell -- bash -c <command>`.\n * • `--version` / `-v` → version action.\n * • `--help` / `-h` → help action.\n * • no args, `-i`, `-l`, `--login`, or a login-shell convention dash\n * prefix (on argv[1] or argv0) → interactive REPL.\n * • anything else → error action.\n */\nexport function rewriteApeShellArgs(argv: string[], argv0?: string): ApeShellAction | null {\n const rawInvokedAs = argv[1] ?? ''\n // sshd/login use a leading dash on argv[0] to signal \"login shell\".\n // Strip it for the basename comparison, but remember the flag. The dash\n // may appear on argv[1] (direct invocation) or on the separately-passed\n // argv0 parameter (wrapper invocation — shell `exec -a \"$0\"` sets node's\n // actual argv[0] / `process.argv0` independently from argv[1]).\n const dashFromArgv1 = rawInvokedAs.startsWith('-')\n const dashFromArgv0 = typeof argv0 === 'string' && argv0.startsWith('-')\n const looksLikeLoginShell = dashFromArgv1 || dashFromArgv0\n const normalizedInvokedAs = dashFromArgv1 ? rawInvokedAs.slice(1) : rawInvokedAs\n const invokedAs = path.basename(normalizedInvokedAs)\n\n // Primary detection: explicit wrapper signal via env var. Takes\n // precedence because argv-based detection gets clobbered when the\n // wrapper execs node directly and argv[1] becomes cli.js.\n const wrapperEnv = typeof process !== 'undefined' && process.env?.APES_SHELL_WRAPPER === '1'\n\n // Secondary detection: argv[1] basename matches literal `ape-shell` or\n // `ape-shell.js` — the direct-symlink invocation path.\n const argvMatch = invokedAs === 'ape-shell' || invokedAs === 'ape-shell.js'\n\n if (!wrapperEnv && !argvMatch)\n return null\n\n const shellArgs = argv.slice(2)\n\n // -c <command> is the historical one-shot path — must stay untouched so\n // programs that use `$SHELL -c \"<cmd>\"` (openclaw tui, xargs, git hooks,\n // sshd non-interactive, etc.) continue to work unchanged.\n if (shellArgs[0] === '-c' && shellArgs.length > 1) {\n return { action: 'rewrite', argv: [argv[0]!, argv[1]!, 'run', '--shell', '--', 'bash', '-c', ...shellArgs.slice(1)] }\n }\n\n if (shellArgs[0] === '--version' || shellArgs[0] === '-v')\n return { action: 'version' }\n\n if (shellArgs[0] === '--help' || shellArgs[0] === '-h')\n return { action: 'help' }\n\n // No positional args, explicit interactive flag, or login-shell\n // convention (`looksLikeLoginShell` detected from the dash-prefixed\n // argv[1] above) → enter the interactive REPL.\n if (\n shellArgs.length === 0\n || shellArgs[0] === '-i'\n || shellArgs[0] === '-l'\n || shellArgs[0] === '--login'\n || looksLikeLoginShell\n ) {\n return { action: 'interactive' }\n }\n\n return { action: 'error' }\n}\n","import { Buffer } from 'node:buffer'\nimport { execFile } from 'node:child_process'\nimport { createServer } from 'node:http'\nimport { homedir } from 'node:os'\nimport { resolve as resolvePath } from 'node:path'\nimport { defineCommand } from 'citty'\nimport { generateCodeChallenge, generateCodeVerifier } from '@openape/core'\nimport consola from 'consola'\nimport { loadConfig, saveAuth, saveConfig } from '../../config'\nimport { getAgentAuthenticateEndpoint, getAgentChallengeEndpoint } from '../../http'\nimport { CliError } from '../../errors'\nimport { resolveLoginInputs } from './resolve-login'\n\nconst CALLBACK_PORT = 9876\n// OAuth client ID registered with IdPs. Historically `grapes-cli`;\n// renamed to `apes-cli` as part of the apes/escapes naming alignment.\n// IdP operators must register this client id (free-idp already does;\n// third-party IdPs need a coordinated rollout with a transitional\n// period accepting both).\nconst CLIENT_ID = 'apes-cli'\n\nexport const loginCommand = defineCommand({\n meta: {\n name: 'login',\n description: 'Authenticate with an OpenApe IdP',\n },\n args: {\n user: {\n type: 'positional',\n required: false,\n description: 'Agent email (e.g. patrick@hofmann.eco). Extracted from <key>.pub comment if omitted.',\n },\n idp: {\n type: 'string',\n description: 'IdP URL (e.g. https://id.openape.at). Auto-discovered via DDISA DNS if omitted.',\n },\n key: {\n type: 'string',\n description: 'Path to agent private key. Defaults to ~/.ssh/id_ed25519 if present.',\n },\n email: {\n type: 'string',\n description: 'Same as the positional email — flag form for backwards compatibility.',\n },\n browser: {\n type: 'boolean',\n description: 'Force browser (PKCE) login even if an SSH key exists',\n },\n force: {\n type: 'boolean',\n description: 'Override DDISA mismatch warnings (use with care)',\n },\n },\n async run({ args }) {\n // Positional `user` and the legacy `--email` flag both set email.\n // Positional wins when both are present (it's the new ergonomic form).\n const emailArg = (typeof args.user === 'string' && args.user.includes('@'))\n ? args.user\n : (typeof args.email === 'string' ? args.email : undefined)\n\n const resolved = await resolveLoginInputs({\n key: args.key,\n idp: args.idp,\n email: emailArg,\n browser: args.browser,\n })\n\n if (resolved.ddisaMismatch && !args.force) {\n const { dnsIdp, chosenIdp, domain } = resolved.ddisaMismatch\n throw new CliError(\n `IdP mismatch for ${domain}.\\n\\n`\n + ` Authoritative DDISA: ${dnsIdp}\\n`\n + ` You selected: ${chosenIdp}\\n\\n`\n + `Logging in against a different IdP than DDISA points to means SPs that\\n`\n + `trust the DDISA-resolved IdP (e.g. preview.openape.ai) will reject the\\n`\n + `resulting token with \"IdP mismatch\".\\n\\n`\n + `Fix one of:\\n`\n + ` • Drop --idp/APES_IDP/config.defaults.idp — DDISA will auto-pick ${dnsIdp}\\n`\n + ` • Update _ddisa.${domain} if ${chosenIdp} is genuinely the correct IdP\\n`\n + ` • Re-run with --force to authenticate anyway (NOT recommended)`,\n )\n }\n if (resolved.ddisaMismatch && args.force) {\n consola.warn(\n `Bypassing DDISA mismatch — ${resolved.ddisaMismatch.domain} resolves to `\n + `${resolved.ddisaMismatch.dnsIdp}, but you forced ${resolved.ddisaMismatch.chosenIdp}.`,\n )\n }\n\n if (resolved.keyPath) {\n if (!resolved.email) {\n throw new CliError(\n `Agent email required for key-based login. Pass it as a positional `\n + `(\\`apes login <email>\\`), set --email, or add an email comment to `\n + `${resolved.keyPath}.pub via ssh-keygen -C <email>.`,\n )\n }\n if (!resolved.idp) {\n const domain = resolved.email.split('@')[1]\n throw new CliError(\n `No IdP found for ${resolved.email}.\\n\\n`\n + `There is no DDISA TXT record for ${domain} and no --idp was provided.\\n\\n`\n + `Options:\\n`\n + ` • Run your own IdP (recommended for production)\\n`\n + ` See: https://docs.openape.at\\n`\n + ` • Publish a DDISA TXT record for your domain:\\n`\n + ` _ddisa.${domain} TXT \"v=ddisa1 idp=https://your-idp.example\"\\n`\n + ` • Use OpenApe's free hosted IdP for testing:\\n`\n + ` apes login --idp https://id.openape.at`,\n )\n }\n await loginWithKey(resolved.idp, resolved.keyPath, resolved.email)\n }\n else {\n if (!resolved.idp) {\n throw new CliError('IdP URL required for browser login. Use --idp <url> or set APES_IDP.')\n }\n await loginWithPKCE(resolved.idp)\n }\n },\n})\n\nfunction openBrowser(url: string) {\n const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n execFile(cmd, [url], () => {})\n}\n\nasync function loginWithPKCE(idp: string) {\n const codeVerifier = generateCodeVerifier()\n const codeChallenge = await generateCodeChallenge(codeVerifier)\n const redirectUri = `http://localhost:${CALLBACK_PORT}/callback`\n\n const state = crypto.randomUUID()\n const nonce = crypto.randomUUID()\n\n const authUrl = new URL(`${idp}/authorize`)\n authUrl.searchParams.set('response_type', 'code')\n authUrl.searchParams.set('client_id', CLIENT_ID)\n authUrl.searchParams.set('redirect_uri', redirectUri)\n authUrl.searchParams.set('code_challenge', codeChallenge)\n authUrl.searchParams.set('code_challenge_method', 'S256')\n authUrl.searchParams.set('state', state)\n authUrl.searchParams.set('nonce', nonce)\n authUrl.searchParams.set('scope', 'openid email profile offline_access')\n\n // Start local callback server\n const code = await new Promise<string>((resolve, reject) => {\n const server = createServer((req, res) => {\n const url = new URL(req.url!, `http://localhost:${CALLBACK_PORT}`)\n if (url.pathname === '/callback') {\n const authCode = url.searchParams.get('code')\n const error = url.searchParams.get('error')\n\n if (error) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end('<h1>Login failed</h1><p>You can close this window.</p>')\n server.close()\n reject(new Error(`Auth error: ${error}`))\n return\n }\n\n if (authCode) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end('<h1>Login successful!</h1><p>You can close this window.</p>')\n server.close()\n resolve(authCode)\n return\n }\n\n res.writeHead(400)\n res.end('Missing code')\n }\n else {\n res.writeHead(404)\n res.end()\n }\n })\n\n server.listen(CALLBACK_PORT, () => {\n // Always print the URL so the user can copy it manually — headless SSH\n // sessions, containers, and restricted-user shells cannot open a browser.\n // The `open` attempt below is fire-and-forget convenience only.\n console.log('')\n console.log('Visit the following URL in a browser to authenticate:')\n console.log('')\n console.log(` ${authUrl.toString()}`)\n console.log('')\n consola.info(`Waiting for authentication callback on ${redirectUri} ...`)\n openBrowser(authUrl.toString())\n })\n\n // Timeout after 5 minutes\n const timeout = setTimeout(() => {\n server.close()\n reject(new Error('Login timed out'))\n }, 300_000)\n timeout.unref()\n })\n\n // Exchange code for tokens\n const tokenResponse = await fetch(`${idp}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n client_id: CLIENT_ID,\n }),\n })\n\n if (!tokenResponse.ok) {\n const text = await tokenResponse.text()\n throw new CliError(`Token exchange failed: ${text}`)\n }\n\n const tokens = await tokenResponse.json() as {\n access_token?: string\n id_token?: string\n refresh_token?: string\n expires_in?: number\n assertion?: string\n }\n\n const accessToken = tokens.access_token || tokens.id_token || tokens.assertion\n if (!accessToken) {\n throw new CliError('No access token received')\n }\n\n // Decode JWT to get email\n const payload = JSON.parse(atob(accessToken.split('.')[1]!))\n\n saveAuth({\n idp,\n access_token: accessToken,\n ...(tokens.refresh_token ? { refresh_token: tokens.refresh_token } : {}),\n email: payload.email || payload.sub,\n expires_at: Math.floor(Date.now() / 1000) + (tokens.expires_in || 3600),\n })\n\n consola.success(`Logged in as ${payload.email || payload.sub}`)\n}\n\nasync function loginWithKey(idp: string, keyPath: string, agentEmail: string) {\n const { readFileSync } = await import('node:fs')\n const { sign } = await import('node:crypto')\n const { loadEd25519PrivateKey } = await import('../../ssh-key.js')\n\n // Use challenge-response auth (endpoint resolved via OIDC discovery)\n const challengeUrl = await getAgentChallengeEndpoint(idp)\n const challengeResp = await fetch(challengeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: agentEmail }),\n })\n\n if (!challengeResp.ok) {\n throw new CliError(`Challenge failed: ${await challengeResp.text()}`)\n }\n\n const { challenge } = await challengeResp.json() as { challenge: string }\n\n // Sign challenge with Ed25519 private key (supports OpenSSH + PKCS8 format)\n const keyContent = readFileSync(keyPath, 'utf-8')\n const privateKey = loadEd25519PrivateKey(keyContent)\n const signature = sign(null, Buffer.from(challenge), privateKey).toString('base64')\n\n // Authenticate (endpoint resolved via OIDC discovery)\n const authenticateUrl = await getAgentAuthenticateEndpoint(idp)\n const authResp = await fetch(authenticateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agent_id: agentEmail,\n challenge,\n signature,\n }),\n })\n\n if (!authResp.ok) {\n throw new CliError(`Authentication failed: ${await authResp.text()}`)\n }\n\n const { token, expires_in } = await authResp.json() as { token: string, expires_in: number }\n\n // Persist the absolute key path on auth.json so any cli-auth consumer\n // (chat-bridge, ape-tasks, ape-plans, …) can refresh the agent token\n // in-process without shelling out to `apes login`. See issue #259.\n const absoluteKeyPath = resolvePath(keyPath.replace(/^~/, homedir()))\n saveAuth({\n idp,\n access_token: token,\n email: agentEmail,\n expires_at: Math.floor(Date.now() / 1000) + (expires_in || 3600),\n key_path: absoluteKeyPath,\n })\n const existingConfig = loadConfig()\n saveConfig({\n ...existingConfig,\n agent: {\n ...existingConfig.agent,\n key: absoluteKeyPath,\n email: agentEmail,\n },\n })\n\n consola.success(`Logged in as ${agentEmail}`)\n consola.info(`Auto-refresh enabled (key path saved to ~/.config/apes/config.toml)`)\n}\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { resolveDDISA } from '@openape/core'\nimport consola from 'consola'\nimport { loadConfig } from '../../config'\nimport { readPublicKeyComment } from '../../ssh-key'\n\nexport interface LoginInputs {\n key?: string\n idp?: string\n email?: string\n browser?: boolean\n}\n\nexport interface ResolvedLoginInputs {\n keyPath?: string\n email?: string\n idp?: string\n /**\n * Set when the chosen `idp` came from an explicit flag/env/config but the\n * email's domain has a DDISA record pointing at a *different* IdP. The\n * caller decides whether to refuse (default), warn-and-continue (`--force`),\n * etc. `undefined` means no mismatch (or no DDISA record to compare against).\n */\n ddisaMismatch?: { dnsIdp: string, chosenIdp: string, domain: string }\n}\n\nconst DEFAULT_KEY = join(homedir(), '.ssh', 'id_ed25519')\n\n/**\n * Resolve login inputs by walking a fallback cascade:\n * 1. explicit flag\n * 2. environment variable\n * 3. ~/.config/apes/config.toml\n * 4. derivation (default key path, pub key comment, DDISA DNS)\n *\n * When `browser` is true, no key is resolved so the caller falls back to PKCE.\n */\nexport async function resolveLoginInputs(\n flags: LoginInputs,\n): Promise<ResolvedLoginInputs> {\n const config = loadConfig()\n\n // 1. Key path — skipped entirely in forced browser mode\n let keyPath: string | undefined\n if (!flags.browser) {\n if (flags.key) {\n keyPath = flags.key\n }\n else if (process.env.APES_KEY) {\n keyPath = process.env.APES_KEY\n consola.info(`Using key from APES_KEY: ${keyPath}`)\n }\n else if (config.agent?.key) {\n keyPath = config.agent.key\n consola.info(`Using key from config: ${keyPath}`)\n }\n else if (existsSync(DEFAULT_KEY)) {\n keyPath = DEFAULT_KEY\n consola.info(`Using default key: ${keyPath}`)\n }\n }\n\n // 2. Email\n let email: string | undefined\n if (flags.email) {\n email = flags.email\n }\n else if (process.env.APES_EMAIL) {\n email = process.env.APES_EMAIL\n }\n else if (config.agent?.email) {\n email = config.agent.email\n }\n else if (keyPath) {\n const comment = readPublicKeyComment(`${keyPath}.pub`)\n if (comment && comment.includes('@')) {\n email = comment\n consola.info(`Using email from ${keyPath}.pub comment: ${email}`)\n }\n }\n\n // 3. IdP\n // APES_IDP is the canonical env var. GRAPES_IDP is a deprecated alias\n // kept for users with older shell profiles; APES_IDP wins on conflict.\n if (process.env.APES_IDP && process.env.GRAPES_IDP) {\n consola.warn(\n 'Both APES_IDP and GRAPES_IDP are set — using APES_IDP. '\n + 'GRAPES_IDP is deprecated and will be removed in a future release.',\n )\n }\n let idp: string | undefined\n let idpSource: 'flag' | 'env' | 'config' | 'ddisa' | undefined\n if (flags.idp) {\n idp = flags.idp\n idpSource = 'flag'\n }\n else if (process.env.APES_IDP) {\n idp = process.env.APES_IDP\n idpSource = 'env'\n }\n else if (process.env.GRAPES_IDP) {\n idp = process.env.GRAPES_IDP\n idpSource = 'env'\n consola.warn(\n 'GRAPES_IDP is deprecated, use APES_IDP instead. '\n + 'GRAPES_IDP support will be removed in a future release.',\n )\n }\n else if (config.defaults?.idp) {\n idp = config.defaults.idp\n idpSource = 'config'\n }\n\n // Always probe DDISA when we have an email — both as the auto-discovery\n // path (when no explicit IdP was supplied) and as a sanity-check against\n // explicit overrides. The caller surfaces the resulting mismatch and\n // gates it behind --force.\n let ddisaIdp: string | undefined\n let ddisaDomain: string | undefined\n if (email && email.includes('@')) {\n const domain = email.split('@')[1]!\n ddisaDomain = domain\n try {\n const record = await resolveDDISA(domain)\n if (record?.idp) ddisaIdp = record.idp\n }\n catch {\n // DNS failure is non-fatal\n }\n }\n\n if (!idp && ddisaIdp && ddisaDomain) {\n idp = ddisaIdp\n idpSource = 'ddisa'\n consola.info(`Discovered IdP via DDISA (_ddisa.${ddisaDomain}): ${idp}`)\n }\n\n // Mismatch only matters when the user explicitly chose an IdP that differs\n // from the authoritative DNS record. Auto-discovered IdPs (idpSource ===\n // 'ddisa') are by definition the DDISA record, so they can't mismatch.\n let ddisaMismatch: ResolvedLoginInputs['ddisaMismatch']\n if (idp && ddisaIdp && ddisaDomain && idp !== ddisaIdp && idpSource !== 'ddisa') {\n ddisaMismatch = { dnsIdp: ddisaIdp, chosenIdp: idp, domain: ddisaDomain }\n }\n\n return { keyPath, email, idp, ddisaMismatch }\n}\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { clearAuth } from '../../config'\n\nexport const logoutCommand = defineCommand({\n meta: {\n name: 'logout',\n description: 'Clear stored credentials',\n },\n run() {\n clearAuth()\n consola.success('Logged out.')\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const whoamiCommand = defineCommand({\n meta: {\n name: 'whoami',\n description: 'Show current identity',\n },\n run() {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n // Token freshness is handled centrally in cli.ts via ensureFreshToken\n // before any subcommand other than login/logout/init/etc. runs. By the\n // time we get here, auth.json is as fresh as it can be — we just print.\n const isAgent = auth.email.includes('agent+')\n const expiresAt = new Date(auth.expires_at * 1000).toISOString()\n const isExpired = Date.now() / 1000 > auth.expires_at\n\n console.log(`Email: ${auth.email}`)\n console.log(`Type: ${isAgent ? 'agent' : 'human'}`)\n console.log(`IdP: ${auth.idp}`)\n console.log(`Token: ${isExpired ? '⚠ EXPIRED' : 'valid'} (until ${expiresAt})`)\n\n if (isExpired) {\n consola.warn('Token is expired and could not be auto-refreshed. Run `apes login` to re-authenticate.')\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface Grant {\n id: string\n type: string\n status: string\n requester: string\n owner: string\n request: {\n command?: string[]\n grant_type?: string\n reason?: string\n }\n created_at?: string\n}\n\ninterface PaginatedGrants {\n data: Grant[]\n pagination: {\n cursor: string | null\n has_more: boolean\n }\n}\n\nexport const listCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List your grants (as requester)',\n },\n args: {\n status: {\n type: 'string',\n description: 'Filter by status (pending, approved, denied, revoked, used)',\n },\n all: {\n type: 'boolean',\n description: 'Show all visible grants (not just your own)',\n default: false,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n limit: {\n type: 'string',\n description: 'Max results (default 20, max 100)',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const auth = loadAuth()\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const params = new URLSearchParams()\n if (args.status)\n params.set('status', args.status)\n if (args.limit)\n params.set('limit', args.limit)\n const query = params.toString() ? `?${params.toString()}` : ''\n\n const response = await apiFetch<PaginatedGrants>(`${grantsUrl}${query}`)\n\n let grants = response.data\n\n // Filter to own grants unless --all\n if (!args.all && auth?.email) {\n grants = grants.filter(g => g.requester === auth.email)\n }\n\n if (args.json) {\n console.log(JSON.stringify(args.all ? response : { ...response, data: grants }, null, 2))\n return\n }\n\n if (grants.length === 0) {\n consola.info(args.all ? 'No grants found.' : 'No grants found. Use --all to see all visible grants.')\n return\n }\n\n for (const grant of grants) {\n const cmd = grant.request?.command?.join(' ') || '(no command)'\n const type = grant.request?.grant_type || grant.type\n console.log(`${grant.id} ${grant.status.padEnd(8)} ${type.padEnd(6)} ${cmd}`)\n if (grant.request?.reason) {\n console.log(` Reason: ${grant.request.reason}`)\n }\n }\n\n if (response.pagination.has_more) {\n consola.info('More results available. Use --limit or pagination cursor.')\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface Grant {\n id: string\n type: string\n status: string\n requester: string\n owner: string\n request: {\n command?: string[]\n grant_type?: string\n reason?: string\n }\n created_at?: string\n}\n\ninterface PaginatedGrants {\n data: Grant[]\n pagination: {\n cursor: string | null\n has_more: boolean\n }\n}\n\nexport const inboxCommand = defineCommand({\n meta: {\n name: 'inbox',\n description: 'Show grants awaiting your approval',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n limit: {\n type: 'string',\n description: 'Max results (default 20, max 100)',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const params = new URLSearchParams()\n params.set('status', 'pending')\n if (args.limit)\n params.set('limit', args.limit)\n const query = `?${params.toString()}`\n\n const response = await apiFetch<PaginatedGrants>(`${grantsUrl}${query}`)\n\n // Filter out own requests — inbox shows only grants from others\n const grants = response.data.filter(g => g.requester !== auth.email)\n\n if (args.json) {\n console.log(JSON.stringify({ ...response, data: grants }, null, 2))\n return\n }\n\n if (grants.length === 0) {\n consola.info('No pending grants to approve.')\n return\n }\n\n consola.info(`${grants.length} grant(s) awaiting approval:\\n`)\n\n for (const grant of grants) {\n const cmd = grant.request?.command?.join(' ') || '(no command)'\n const type = grant.request?.grant_type || grant.type\n console.log(`${grant.id} ${type.padEnd(6)} from ${grant.requester}`)\n console.log(` Command: ${cmd}`)\n if (grant.request?.reason) {\n console.log(` Reason: ${grant.request.reason}`)\n }\n if (grant.created_at) {\n console.log(` Created: ${grant.created_at}`)\n }\n console.log()\n }\n\n consola.info('Use `apes grants approve <id>` or `apes grants deny <id>` to respond.')\n },\n})\n","import { defineCommand } from 'citty'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\n\n/**\n * Shape returned by `GET /grants/<id>` on the OpenApe IdP. Matches the\n * free-idp response as of 2026-04: `requester`, `target_host`, `audience`,\n * `grant_type`, etc. all live under the nested `request` object. Top-level\n * `type` is a legacy field that is currently always `null`. Timestamps are\n * unix seconds (numbers), not ISO strings.\n */\ninterface GrantDetail {\n id: string\n type?: string | null\n status: string\n request?: {\n requester?: string\n target_host?: string\n audience?: string\n grant_type?: string\n command?: string[]\n reason?: string\n }\n created_at?: number\n decided_at?: number\n decided_by?: string\n used_at?: number\n expires_at?: number\n}\n\n/** Unix seconds → ISO-8601 with graceful fallback for bogus values. */\nfunction formatTs(ts: number | undefined): string | undefined {\n if (ts === undefined || ts === null)\n return undefined\n const ms = ts * 1000\n if (!Number.isFinite(ms))\n return undefined\n return new Date(ms).toISOString()\n}\n\nexport const statusCommand = defineCommand({\n meta: {\n name: 'status',\n description: 'Show grant status',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n const grant = await apiFetch<GrantDetail>(`${grantsUrl}/${args.id}`)\n\n if (args.json) {\n console.log(JSON.stringify(grant, null, 2))\n return\n }\n\n console.log(`Grant: ${grant.id}`)\n console.log(`Status: ${grant.status}`)\n if (grant.request?.audience)\n console.log(`Audience: ${grant.request.audience}`)\n if (grant.request?.requester)\n console.log(`Requester: ${grant.request.requester}`)\n if (grant.request?.target_host)\n console.log(`Host: ${grant.request.target_host}`)\n if (grant.request?.command)\n console.log(`Command: ${grant.request.command.join(' ')}`)\n if (grant.request?.grant_type)\n console.log(`Approval: ${grant.request.grant_type}`)\n if (grant.request?.reason)\n console.log(`Reason: ${grant.request.reason}`)\n const createdAt = formatTs(grant.created_at)\n if (createdAt)\n console.log(`Created: ${createdAt}`)\n if (grant.decided_by)\n console.log(`Decided by: ${grant.decided_by}`)\n const decidedAt = formatTs(grant.decided_at)\n if (decidedAt)\n console.log(`Decided at: ${decidedAt}`)\n const usedAt = formatTs(grant.used_at)\n if (usedAt)\n console.log(`Used at: ${usedAt}`)\n const expiresAt = formatTs(grant.expires_at)\n if (expiresAt)\n console.log(`Expires: ${expiresAt}`)\n },\n})\n","import { hostname } from 'node:os'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { parseDuration } from '../../duration'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const requestCommand = defineCommand({\n meta: {\n name: 'request',\n description: 'Request a new grant',\n },\n args: {\n command: {\n type: 'positional',\n description: 'Command to request permission for',\n required: true,\n },\n audience: {\n type: 'string',\n description: 'Service identifier (e.g. \"escapes\", \"proxy\")',\n required: true,\n },\n host: {\n type: 'string',\n description: 'Target host (default: system hostname)',\n },\n reason: {\n type: 'string',\n description: 'Reason for the request',\n },\n approval: {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n duration: {\n type: 'string',\n description: 'Duration for timed grants (e.g. 30m, 1h, 7d)',\n },\n 'run-as': {\n type: 'string',\n description: 'Execute as this user (e.g. openclaw, root)',\n },\n wait: {\n type: 'boolean',\n description: 'Wait for approval',\n default: false,\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n const command = args.command.split(' ')\n const targetHost = args.host || hostname()\n\n const duration = args.duration ? parseDuration(args.duration) : undefined\n\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n body: {\n requester: auth.email,\n target_host: targetHost,\n audience: args.audience,\n grant_type: args.approval,\n command,\n reason: args.reason || command.join(' '),\n ...(duration != null ? { duration } : {}),\n ...(args['run-as'] ? { run_as: args['run-as'] } : {}),\n },\n })\n\n consola.success(`Grant requested: ${grant.id} (status: ${grant.status})`)\n\n if (args.wait) {\n consola.info('Waiting for approval...')\n await waitForApproval(grantsUrl, grant.id)\n }\n },\n})\n\nasync function waitForApproval(grantsUrl: string, grantId: string): Promise<void> {\n const maxWait = 300_000 // 5 minutes\n const interval = 3_000\n const start = Date.now()\n\n while (Date.now() - start < maxWait) {\n const grant = await apiFetch<{ status: string }>(`${grantsUrl}/${grantId}`)\n\n if (grant.status === 'approved') {\n consola.success('Grant approved!')\n return\n }\n if (grant.status === 'denied') {\n throw new CliError('Grant denied.')\n }\n if (grant.status === 'revoked') {\n throw new CliError('Grant revoked.')\n }\n\n await new Promise(r => setTimeout(r, interval))\n }\n\n throw new CliError('Timed out waiting for approval.')\n}\n","import { hostname } from 'node:os'\nimport { buildStructuredCliGrantRequest, loadAdapter, resolveCapabilityRequest } from '../../shapes/index.js'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { parseDuration } from '../../duration'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nfunction parseCapabilityArgs(rawArgs: string[]): {\n cliId: string\n adapter?: string\n idp?: string\n approval: 'once' | 'timed' | 'always'\n reason?: string\n duration?: number\n runAs?: string\n wait: boolean\n resources: string[]\n selectors: string[]\n actions: string[]\n} {\n const tokens = [...rawArgs]\n if (tokens[0] === 'request-capability') {\n tokens.shift()\n }\n\n const cliId = tokens.shift()\n if (!cliId || cliId.startsWith('-')) {\n throw new Error('Missing CLI identifier')\n }\n\n const resources: string[] = []\n const selectors: string[] = []\n const actions: string[] = []\n let adapter: string | undefined\n let idp: string | undefined\n let approval: 'once' | 'timed' | 'always' = 'once'\n let reason: string | undefined\n let duration: number | undefined\n let runAs: string | undefined\n let wait = false\n\n for (let index = 0; index < tokens.length; index += 1) {\n const token = tokens[index]!\n const next = tokens[index + 1]\n switch (token) {\n case '--resource':\n if (!next)\n throw new Error('Missing value for --resource')\n resources.push(next)\n index += 1\n break\n case '--selector':\n if (!next)\n throw new Error('Missing value for --selector')\n selectors.push(next)\n index += 1\n break\n case '--action':\n if (!next)\n throw new Error('Missing value for --action')\n actions.push(next)\n index += 1\n break\n case '--adapter':\n if (!next)\n throw new Error('Missing value for --adapter')\n adapter = next\n index += 1\n break\n case '--idp':\n if (!next)\n throw new Error('Missing value for --idp')\n idp = next\n index += 1\n break\n case '--approval':\n if (!next || !['once', 'timed', 'always'].includes(next)) {\n throw new Error('Approval must be one of: once, timed, always')\n }\n approval = next as 'once' | 'timed' | 'always'\n index += 1\n break\n case '--reason':\n if (!next)\n throw new Error('Missing value for --reason')\n reason = next\n index += 1\n break\n case '--duration':\n if (!next)\n throw new Error('Missing value for --duration')\n duration = parseDuration(next)\n index += 1\n break\n case '--run-as':\n if (!next)\n throw new Error('Missing value for --run-as')\n runAs = next\n index += 1\n break\n case '--wait':\n wait = true\n break\n default:\n throw new Error(`Unknown argument: ${token}`)\n }\n }\n\n return {\n cliId,\n adapter,\n idp,\n approval,\n reason,\n duration,\n runAs,\n wait,\n resources,\n selectors,\n actions,\n }\n}\n\nasync function waitForApproval(grantsUrl: string, grantId: string): Promise<void> {\n const maxWait = 300_000\n const interval = 3_000\n const start = Date.now()\n\n while (Date.now() - start < maxWait) {\n const grant = await apiFetch<{ status: string }>(`${grantsUrl}/${grantId}`)\n if (grant.status === 'approved') {\n consola.success('Grant approved!')\n return\n }\n if (grant.status === 'denied') {\n throw new CliError('Grant denied.')\n }\n if (grant.status === 'revoked') {\n throw new CliError('Grant revoked.')\n }\n await new Promise(resolve => setTimeout(resolve, interval))\n }\n\n throw new CliError('Timed out waiting for approval.')\n}\n\nexport const requestCapabilityCommand = defineCommand({\n meta: {\n name: 'request-capability',\n description: 'Request a structured CLI capability grant',\n },\n args: {\n 'cliId': {\n type: 'positional',\n description: 'CLI adapter identifier (e.g. docker, kubectl)',\n required: true,\n },\n 'resource': {\n type: 'string',\n description: 'Resource scope (repeatable)',\n },\n 'selector': {\n type: 'string',\n description: 'Selector filter (repeatable)',\n },\n 'action': {\n type: 'string',\n description: 'Action to permit (repeatable)',\n },\n 'adapter': {\n type: 'string',\n description: 'Explicit path to adapter TOML file',\n },\n 'idp': {\n type: 'string',\n description: 'IdP URL',\n },\n 'approval': {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n 'reason': {\n type: 'string',\n description: 'Reason for the request',\n },\n 'duration': {\n type: 'string',\n description: 'Duration for timed grants (e.g. 30m, 1h, 7d)',\n },\n 'run-as': {\n type: 'string',\n description: 'Execute as this user (e.g. root)',\n },\n 'wait': {\n type: 'boolean',\n description: 'Wait for approval before returning',\n default: false,\n },\n },\n async run({ rawArgs }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const parsed = parseCapabilityArgs(rawArgs)\n const idp = getIdpUrl(parsed.idp)\n if (!idp) {\n throw new CliError('No IdP URL configured. Use --idp or log in first.')\n }\n\n const loaded = loadAdapter(parsed.cliId, parsed.adapter)\n const resolved = resolveCapabilityRequest(loaded, {\n resources: parsed.resources,\n selectors: parsed.selectors,\n actions: parsed.actions,\n })\n\n const { request } = await buildStructuredCliGrantRequest(resolved, {\n requester: auth.email,\n target_host: hostname(),\n grant_type: parsed.approval,\n ...(parsed.reason ? { reason: parsed.reason } : {}),\n })\n\n if (parsed.duration != null) {\n request.duration = parsed.duration\n }\n if (parsed.runAs) {\n request.run_as = parsed.runAs\n }\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n idp,\n body: request,\n })\n\n consola.success(`Grant requested: ${grant.id} (status: ${grant.status})`)\n\n if (parsed.wait) {\n consola.info('Waiting for approval...')\n await waitForApproval(grantsUrl, grant.id)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\n\nexport const approveCommand = defineCommand({\n meta: {\n name: 'approve',\n description: 'Approve a grant request',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n await apiFetch(`${grantsUrl}/${args.id}/approve`, {\n method: 'POST',\n })\n consola.success(`Grant ${args.id} approved.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\n\nexport const denyCommand = defineCommand({\n meta: {\n name: 'deny',\n description: 'Deny a grant request',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n await apiFetch(`${grantsUrl}/${args.id}/deny`, {\n method: 'POST',\n })\n consola.success(`Grant ${args.id} denied.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getAuthToken, getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface Grant {\n id: string\n status: string\n // Some list endpoints return requester nested under request\n requester?: string\n request?: { requester?: string, command?: string[] }\n}\n\ninterface PaginatedGrants {\n data: Grant[]\n pagination: { cursor: string | null, has_more: boolean }\n}\n\ninterface BatchResult {\n id: string\n status: string\n success: boolean\n error?: { title: string }\n}\n\nexport const revokeCommand = defineCommand({\n meta: {\n name: 'revoke',\n description: 'Revoke one or more grants',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID(s) to revoke',\n required: false,\n },\n allPending: {\n type: 'boolean',\n description: 'Revoke all own pending grants',\n default: false,\n },\n debug: {\n type: 'boolean',\n description: 'Print debug information (does not include full tokens)',\n default: false,\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n const token = getAuthToken()\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n\n if (args.debug) {\n consola.debug(`idp: ${idp}`)\n consola.debug(`grantsUrl: ${grantsUrl}`)\n consola.debug(`auth.email: ${auth?.email}`)\n consola.debug(`auth.expires_at: ${auth?.expires_at} (now: ${Math.floor(Date.now() / 1000)})`)\n consola.debug(`getAuthToken(): ${token ? `${token.substring(0, 20)}...` : 'NULL'}`)\n }\n\n if (!auth || !token) {\n throw new CliError('Authentication required. Run `apes login` and try again.')\n }\n\n const explicitIds = args.id\n ? [String(args.id), ...args._].filter(Boolean)\n : []\n\n if (args.allPending && explicitIds.length > 0) {\n throw new CliError('Use either --all-pending or grant IDs, not both.')\n }\n\n let ids: string[]\n\n if (args.allPending) {\n const auth = loadAuth()\n const response = await apiFetch<PaginatedGrants>(\n `${grantsUrl}?status=pending&limit=100`,\n { token },\n )\n const ownPending = auth?.email\n ? response.data.filter(g => g.request?.requester === auth.email)\n : response.data\n if (ownPending.length === 0) {\n consola.info('No pending grants to revoke.')\n return\n }\n ids = ownPending.map(g => g.id)\n consola.info(`Found ${ids.length} pending grant(s) to revoke.`)\n }\n else if (explicitIds.length > 0) {\n ids = explicitIds\n }\n else {\n throw new CliError('Provide grant ID(s) or use --all-pending.')\n }\n\n // Single grant: use direct endpoint\n if (ids.length === 1) {\n await apiFetch(`${grantsUrl}/${ids[0]}/revoke`, { method: 'POST', token })\n consola.success(`Grant ${ids[0]} revoked.`)\n return\n }\n\n // Multiple grants: use batch endpoint\n const operations = ids.map(id => ({ id, action: 'revoke' as const }))\n const { results } = await apiFetch<{ results: BatchResult[] }>(\n `${grantsUrl}/batch`,\n { method: 'POST', body: { operations }, token },\n )\n\n let succeeded = 0\n for (const r of results) {\n if (r.success) {\n consola.success(`Grant ${r.id} revoked.`)\n succeeded++\n }\n else {\n consola.error(`Grant ${r.id}: ${r.error?.title || 'Failed'}`)\n }\n }\n\n if (succeeded < results.length) {\n throw new CliError(`Revoked ${succeeded} of ${results.length} grants.`)\n }\n else {\n consola.success(`All ${succeeded} grants revoked.`)\n }\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { CliError, CliExit } from '../../errors'\nimport { getPollMaxMinutes, pollGrantUntilResolved } from '../../grant-poll'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { fetchGrantToken, resolveFromGrant, verifyAndExecute } from '../../shapes/index.js'\nimport { buildGenericResolved, GENERIC_OPERATION_ID } from '../../shapes/generic.js'\n\ninterface GrantDetail {\n id: string\n type: string\n status: string\n requester: string\n owner: string\n request: {\n command?: string[]\n audience?: string\n grant_type?: string\n target_host?: string\n execution_context?: { adapter_digest?: string, argv_hash?: string }\n authorization_details?: Array<{ type?: string, permission?: string, operation_id?: string, cli_id?: string }>\n }\n}\n\nexport const runGrantCommand = defineCommand({\n meta: {\n name: 'run',\n description: 'Execute a previously-approved grant by ID',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n 'escapes-path': {\n type: 'string',\n description: 'Path to escapes binary (audience=escapes only)',\n default: 'escapes',\n },\n wait: {\n type: 'boolean',\n description: 'If the grant is pending, block and poll until approved (or denied/revoked/used/timeout). Reuses APES_GRANT_POLL_INTERVAL / APES_GRANT_POLL_MAX_MINUTES knobs.',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp)\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n\n const grantsUrl = await getGrantsEndpoint(idp)\n let grant = await apiFetch<GrantDetail>(`${grantsUrl}/${args.id}`)\n\n // --- status gate ---\n // Pending status has two paths: default error, or --wait poll loop.\n // The CLI-side poll is the \"ape-shell -c \\\"apes grants run <id> --wait\\\"\"\n // pattern that agents use: one tool call, the CLI handles the wait,\n // and the agent only sees the final state. See `commands/run.ts`\n // `printPendingGrantInfo` agent-mode text for the usage contract.\n if (grant.status === 'pending') {\n if (!args.wait) {\n throw new CliError(\n `Grant ${grant.id} is still pending. Approve at: ${idp}/grant-approval?grant_id=${grant.id}`,\n )\n }\n const maxMinutes = getPollMaxMinutes()\n consola.info(`Waiting for grant ${grant.id} approval (up to ${maxMinutes} minute${maxMinutes === 1 ? '' : 's'})...`)\n const outcome = await pollGrantUntilResolved(idp, grant.id)\n if (outcome.kind === 'timeout') {\n throw new CliError(\n `Grant ${grant.id} approval timed out after ${maxMinutes} minute${maxMinutes === 1 ? '' : 's'}. `\n + `Re-run after approval, or extend the timeout via APES_GRANT_POLL_MAX_MINUTES.`,\n )\n }\n if (outcome.kind === 'terminal') {\n throw new CliError(\n `Grant ${grant.id} resolved to ${outcome.status}. Request a new one.`,\n )\n }\n // outcome.kind === 'approved' — re-fetch the grant so we have the\n // up-to-date shape (approver, decided_at, etc.) for downstream code.\n grant = await apiFetch<GrantDetail>(`${grantsUrl}/${args.id}`)\n consola.info(`Grant ${grant.id} approved — continuing`)\n }\n\n if (grant.status === 'denied' || grant.status === 'revoked')\n throw new CliError(`Grant ${grant.id} is ${grant.status}. Request a new one.`)\n if (grant.status === 'used')\n throw new CliError(`Grant ${grant.id} has already been used. Request a new one (single-use grants cannot be re-executed).`)\n if (grant.status !== 'approved')\n throw new CliError(`Grant ${grant.id} has unexpected status: ${grant.status}`)\n\n // --- dispatch by grant shape ---\n const audience = grant.request?.audience\n const authDetails = grant.request?.authorization_details ?? []\n const hasOpenApeCliDetail = authDetails.some(d => d?.type === 'openape_cli')\n const isShapesGrant = hasOpenApeCliDetail || audience === 'shapes'\n\n if (isShapesGrant) {\n // Generic-fallback grants have no adapter to re-resolve against —\n // their command is self-describing (argv + cli_id). Rebuild the\n // ResolvedCommand in memory via buildGenericResolved instead of\n // calling resolveFromGrant (which would try to loadOrInstallAdapter\n // and fail with \"No shapes adapter found\").\n const isGenericGrant = authDetails.some(d => d?.operation_id === GENERIC_OPERATION_ID)\n let resolved\n if (isGenericGrant) {\n const argv = grant.request?.command ?? []\n if (argv.length === 0)\n throw new CliError(`Generic grant ${grant.id} is missing command argv`)\n const cliId = authDetails.find(d => d?.operation_id === GENERIC_OPERATION_ID)?.cli_id ?? argv[0]!\n resolved = await buildGenericResolved(cliId, argv)\n }\n else {\n try {\n resolved = await resolveFromGrant(grant)\n }\n catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n throw new CliError(`Cannot re-resolve grant: ${msg}`)\n }\n }\n const token = await fetchGrantToken(idp, grant.id)\n await verifyAndExecute(token, resolved, grant.id)\n return\n }\n\n if (audience === 'escapes') {\n const { authz_jwt } = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${grant.id}/token`, { method: 'POST' })\n const command = grant.request?.command ?? []\n if (command.length === 0)\n throw new CliError(`Grant ${grant.id} has no command to execute.`)\n consola.info(`Executing via escapes: ${command.join(' ')}`)\n try {\n execFileSync(args['escapes-path'] as string, ['--grant', authz_jwt, '--', ...command], { stdio: 'inherit' })\n }\n catch (err: unknown) {\n const exitCode = (err as { status?: number }).status || 1\n throw new CliExit(exitCode)\n }\n return\n }\n\n if (audience === 'ape-shell') {\n // Legacy shell-session grants can't be re-executed standalone — they\n // were created for a specific bash -c line that only made sense inside\n // the original apes run --shell invocation.\n throw new CliError(\n `Grant ${grant.id} is an ape-shell session grant and cannot be re-executed via \\`apes grants run\\`. `\n + `Re-run the original command — if the grant was approved as timed/always, the REPL will reuse it automatically.`,\n )\n }\n\n throw new CliError(`Grant ${grant.id} has unsupported audience \"${audience}\" — no execution path available.`)\n },\n})\n","import { loadConfig } from './config.js'\nimport { apiFetch, getGrantsEndpoint } from './http.js'\n\n/**\n * Shared poll-config helpers used by both the one-shot grant-creation\n * wait loops in `commands/run.ts` and the CLI-side wait loop in\n * `commands/grants/run.ts --wait`.\n *\n * Source-of-truth for the default poll interval (10 s) and max-wait\n * duration (5 min). Env var wins over config.toml wins over baked-in\n * default; bogus values fall back gracefully.\n */\n\n/** Poll interval (seconds). Default 10. */\nexport function getPollIntervalSeconds(): number {\n const envValue = process.env.APES_GRANT_POLL_INTERVAL\n if (envValue) {\n const n = Number(envValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n const cfg = loadConfig()\n const cfgValue = cfg.defaults?.grant_poll_interval_seconds\n if (cfgValue) {\n const n = Number(cfgValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n return 10\n}\n\n/** Maximum poll duration (minutes). Default 5. */\nexport function getPollMaxMinutes(): number {\n const envValue = process.env.APES_GRANT_POLL_MAX_MINUTES\n if (envValue) {\n const n = Number(envValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n const cfg = loadConfig()\n const cfgValue = cfg.defaults?.grant_poll_max_minutes\n if (cfgValue) {\n const n = Number(cfgValue)\n if (Number.isFinite(n) && n > 0)\n return Math.floor(n)\n }\n return 5\n}\n\n/** Outcome of a grant polling loop. */\nexport type PollOutcome =\n | { kind: 'approved' }\n | { kind: 'terminal', status: 'denied' | 'revoked' | 'used' }\n | { kind: 'timeout' }\n\n/**\n * Poll a specific grant's status via `GET /grants/<id>` until it reaches\n * a terminal state or the max-wait budget is exhausted. Uses the shared\n * `getPollIntervalSeconds` / `getPollMaxMinutes` knobs so users get\n * consistent behavior across both the grant-creation wait loops and the\n * CLI-side `grants run --wait` loop.\n *\n * The caller is responsible for handling the outcome — this helper only\n * polls the status endpoint, it does not dispatch or execute the grant.\n * See `commands/grants/run.ts --wait` for the dispatch path.\n */\nexport async function pollGrantUntilResolved(\n idp: string,\n grantId: string,\n): Promise<PollOutcome> {\n const grantsEndpoint = await getGrantsEndpoint(idp)\n const intervalSec = getPollIntervalSeconds()\n const maxMinutes = getPollMaxMinutes()\n const maxMs = maxMinutes * 60_000\n const intervalMs = intervalSec * 1000\n const start = Date.now()\n\n while (Date.now() - start < maxMs) {\n const grant = await apiFetch<{ status: string }>(`${grantsEndpoint}/${grantId}`)\n if (grant.status === 'approved')\n return { kind: 'approved' }\n if (grant.status === 'denied' || grant.status === 'revoked' || grant.status === 'used')\n return { kind: 'terminal', status: grant.status }\n await new Promise(r => setTimeout(r, intervalMs))\n }\n\n return { kind: 'timeout' }\n}\n","import { defineCommand } from 'citty'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getGrantsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const tokenCommand = defineCommand({\n meta: {\n name: 'token',\n description: 'Get grant token JWT',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Grant ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const grantsUrl = await getGrantsEndpoint(idp)\n const result = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${args.id}/token`, {\n method: 'POST',\n })\n\n if (!result.authz_jwt) {\n throw new CliError('No token received. Grant may not be approved.')\n }\n\n // Output raw token to stdout (pipeable)\n process.stdout.write(result.authz_jwt)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { apiFetch, getDelegationsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const delegateCommand = defineCommand({\n meta: {\n name: 'delegate',\n description: 'Create a delegation',\n },\n args: {\n to: {\n type: 'string',\n description: 'Delegate email (who can act on your behalf)',\n required: true,\n },\n at: {\n type: 'string',\n description: 'Service/audience where delegation applies',\n required: true,\n },\n scopes: {\n type: 'string',\n description: 'Comma-separated scopes',\n },\n approval: {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n expires: {\n type: 'string',\n description: 'Expiration date (ISO 8601)',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()!\n const delegationsUrl = await getDelegationsEndpoint(idp)\n\n // Server expects `grant_type`, not `approval`. The CLI flag stays\n // named `--approval` for UX continuity (matches the term humans\n // see in the IdP grant-approval UI), but the request body must\n // carry the wire name. Without this rename the server always\n // defaults to grant_type='once' regardless of the flag value.\n const body: Record<string, unknown> = {\n delegate: args.to,\n audience: args.at,\n grant_type: args.approval,\n }\n\n if (args.scopes) {\n body.scopes = args.scopes.split(',').map(s => s.trim())\n }\n\n if (args.expires) {\n // The IdP's /api/delegations endpoint validates timed grants with a\n // `duration` field (seconds), not an ISO `expires_at`. Convert here\n // so users can keep using a human-friendly --expires timestamp.\n if (args.approval === 'timed') {\n const expiresMs = Date.parse(args.expires)\n if (Number.isNaN(expiresMs)) {\n throw new CliError(`Invalid --expires value: \"${args.expires}\" is not an ISO 8601 timestamp.`)\n }\n const durationSec = Math.floor((expiresMs - Date.now()) / 1000)\n if (durationSec <= 0) {\n throw new CliError(`Invalid --expires value: \"${args.expires}\" is in the past.`)\n }\n body.duration = durationSec\n }\n else {\n body.expires_at = args.expires\n }\n }\n\n const result = await apiFetch<{ id: string }>(delegationsUrl, {\n method: 'POST',\n body,\n })\n\n consola.success(`Delegation created: ${result.id}`)\n console.log(` Delegate: ${args.to}`)\n console.log(` Audience: ${args.at}`)\n if (args.scopes)\n console.log(` Scopes: ${args.scopes}`)\n console.log(` Approval: ${args.approval}`)\n if (args.expires)\n console.log(` Expires: ${args.expires}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getDelegationsEndpoint } from '../../http'\n\ninterface Delegation {\n id: string\n delegator: string\n delegate: string\n audience: string\n scopes?: string[]\n approval: string\n created_at?: string\n expires_at?: string\n}\n\ninterface PaginatedDelegations {\n data: Delegation[]\n pagination: { cursor: string | null, has_more: boolean }\n}\n\nexport const delegationsCommand = defineCommand({\n meta: {\n name: 'delegations',\n description: 'List delegations',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()!\n const delegationsUrl = await getDelegationsEndpoint(idp)\n const response = await apiFetch<PaginatedDelegations>(delegationsUrl)\n\n // Support both paginated and legacy plain-array responses\n const delegations = Array.isArray(response) ? response : response.data\n\n if (args.json) {\n console.log(JSON.stringify(delegations, null, 2))\n return\n }\n\n if (delegations.length === 0) {\n consola.info('No delegations found.')\n return\n }\n\n for (const d of delegations) {\n const scopes = d.scopes?.join(', ') || '(all)'\n const expires = d.expires_at ? ` expires ${d.expires_at}` : ''\n console.log(`${d.id} ${d.delegator} → ${d.delegate} at ${d.audience} [${scopes}]${expires}`)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch, getDelegationsEndpoint } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const delegationRevokeCommand = defineCommand({\n meta: {\n name: 'delegation-revoke',\n description: 'Revoke a delegation',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Delegation ID to revoke',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const delegationsUrl = await getDelegationsEndpoint(idp)\n const id = String(args.id)\n\n const result = await apiFetch<{ id: string, status: string }>(\n `${delegationsUrl}/${id}`,\n { method: 'DELETE' },\n )\n\n consola.success(`Delegation ${result.id} revoked.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { usersListCommand, usersCreateCommand, usersDeleteCommand } from './users'\nimport { sshKeysListCommand, sshKeysAddCommand, sshKeysDeleteCommand } from './ssh-keys'\n\nconst usersCommand = defineCommand({\n meta: {\n name: 'users',\n description: 'Manage users',\n },\n subCommands: {\n list: usersListCommand,\n create: usersCreateCommand,\n delete: usersDeleteCommand,\n },\n})\n\nconst sshKeysCommand = defineCommand({\n meta: {\n name: 'ssh-keys',\n description: 'Manage SSH keys',\n },\n subCommands: {\n list: sshKeysListCommand,\n add: sshKeysAddCommand,\n delete: sshKeysDeleteCommand,\n },\n})\n\nexport const adminCommand = defineCommand({\n meta: {\n name: 'admin',\n description: 'Admin commands (requires APES_MANAGEMENT_TOKEN)',\n },\n subCommands: {\n users: usersCommand,\n 'ssh-keys': sshKeysCommand,\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface AdminUser {\n email: string\n name: string\n isActive: boolean\n owner?: string\n createdAt: number\n}\n\nfunction getManagementToken(): string {\n const token = process.env.APES_MANAGEMENT_TOKEN\n if (!token) {\n throw new CliError('Management token required. Set APES_MANAGEMENT_TOKEN environment variable.')\n }\n return token\n}\n\ninterface UserListResponse {\n data: AdminUser[]\n pagination: {\n cursor: string | null\n has_more: boolean\n }\n}\n\nexport const usersListCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List all users',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n limit: {\n type: 'string',\n description: 'Max number of users to return (1-100, default 50)',\n },\n cursor: {\n type: 'string',\n description: 'Pagination cursor (email of last item from previous page)',\n },\n search: {\n type: 'string',\n description: 'Filter by email or name (case-insensitive)',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const params = new URLSearchParams()\n if (args.limit) params.set('limit', args.limit)\n if (args.cursor) params.set('cursor', args.cursor)\n if (args.search) params.set('search', args.search)\n const qs = params.toString()\n const url = qs ? `${idp}/api/admin/users?${qs}` : `${idp}/api/admin/users`\n\n const result = await apiFetch<UserListResponse>(url, { token })\n\n if (args.json) {\n console.log(JSON.stringify(result, null, 2))\n return\n }\n\n if (result.data.length === 0) {\n consola.info('No users found.')\n return\n }\n\n for (const u of result.data) {\n const owner = u.owner ? ` (agent of ${u.owner})` : ''\n const active = u.isActive ? '' : ' [inactive]'\n console.log(`${u.email} ${u.name}${owner}${active}`)\n }\n\n if (result.pagination.has_more) {\n consola.info(`More results available. Use --cursor=\"${result.pagination.cursor}\" to see next page.`)\n }\n },\n})\n\nexport const usersCreateCommand = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a user',\n },\n args: {\n email: {\n type: 'string',\n description: 'User email',\n required: true,\n },\n name: {\n type: 'string',\n description: 'User name',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n\n const result = await apiFetch<{ ok: boolean, email: string, name: string }>(\n `${idp}/api/admin/users`,\n {\n method: 'POST',\n body: { email: args.email, name: args.name },\n token,\n },\n )\n\n consola.success(`User created: ${result.email} (${result.name})`)\n },\n})\n\nexport const usersDeleteCommand = defineCommand({\n meta: {\n name: 'delete',\n description: 'Delete a user',\n },\n args: {\n email: {\n type: 'positional',\n description: 'User email',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const email = String(args.email)\n\n await apiFetch(`${idp}/api/admin/users/${encodeURIComponent(email)}`, {\n method: 'DELETE',\n token,\n })\n\n consola.success(`User deleted: ${email}`)\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { homedir } from 'node:os'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl } from '../../config'\nimport { apiFetch } from '../../http'\nimport { CliError } from '../../errors'\n\ninterface SshKey {\n keyId: string\n userEmail: string\n publicKey: string\n name: string\n createdAt: number\n}\n\nfunction getManagementToken(): string {\n const token = process.env.APES_MANAGEMENT_TOKEN\n if (!token) {\n throw new CliError('Management token required. Set APES_MANAGEMENT_TOKEN environment variable.')\n }\n return token\n}\n\nexport const sshKeysListCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List SSH keys for a user',\n },\n args: {\n email: {\n type: 'positional',\n description: 'User email',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const email = String(args.email)\n const keys = await apiFetch<SshKey[]>(\n `${idp}/api/admin/users/${encodeURIComponent(email)}/ssh-keys`,\n { token },\n )\n\n if (args.json) {\n console.log(JSON.stringify(keys, null, 2))\n return\n }\n\n if (keys.length === 0) {\n consola.info(`No SSH keys found for ${email}.`)\n return\n }\n\n for (const k of keys) {\n console.log(`${k.keyId} ${k.name} ${k.publicKey.substring(0, 40)}...`)\n }\n },\n})\n\nexport const sshKeysAddCommand = defineCommand({\n meta: {\n name: 'add',\n description: 'Add an SSH key for a user',\n },\n args: {\n email: {\n type: 'string',\n description: 'User email',\n required: true,\n },\n key: {\n type: 'string',\n description: 'Path to public key file or key string',\n required: true,\n },\n name: {\n type: 'string',\n description: 'Key name/label',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n\n // Read key from file if path exists, otherwise treat as key string\n let publicKey = args.key\n const resolved = resolve(args.key.replace(/^~/, homedir()))\n if (existsSync(resolved)) {\n publicKey = readFileSync(resolved, 'utf-8').trim()\n }\n\n const body: Record<string, string> = { publicKey }\n if (args.name) {\n body.name = args.name\n }\n\n const result = await apiFetch<SshKey>(\n `${idp}/api/admin/users/${encodeURIComponent(args.email)}/ssh-keys`,\n {\n method: 'POST',\n body,\n token,\n },\n )\n\n consola.success(`SSH key added: ${result.keyId} (${result.name})`)\n },\n})\n\nexport const sshKeysDeleteCommand = defineCommand({\n meta: {\n name: 'delete',\n description: 'Delete an SSH key',\n },\n args: {\n email: {\n type: 'string',\n description: 'User email',\n required: true,\n },\n keyId: {\n type: 'positional',\n description: 'Key ID',\n required: true,\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n }\n\n const token = getManagementToken()\n const keyId = String(args.keyId)\n\n await apiFetch(\n `${idp}/api/admin/users/${encodeURIComponent(args.email)}/ssh-keys/${keyId}`,\n {\n method: 'DELETE',\n token,\n },\n )\n\n consola.success(`SSH key deleted: ${keyId}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { deployAgentCommand } from './deploy'\n\n// `apes agent …` (singular) — owner-side recipe operations, distinct\n// from `apes agents …` (plural) which manages the owner's own agent\n// lifecycle on a host.\nexport const agentCommand = defineCommand({\n meta: {\n name: 'agent',\n description: 'Agent Recipe operations (deploy)',\n },\n subCommands: {\n deploy: deployAgentCommand,\n },\n})\n","import { ensureFreshIdpAuth } from '@openape/cli-auth'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { resolveTroopUrl } from '../../lib/troop-client'\n\n// `apes agent deploy <repo>@<ref> [--param k=v] [--secret ENV=val]`\n// — one-step Agent Recipe deploy. Calls troop's recipe-deploy endpoint\n// (M3), then binds the declared capability secrets (M2c). The owner's\n// IdP token (apes login) authenticates; troop enforces requireOwner.\n// See plans.openape.ai 01KRTAE8 (M4).\n\n/** Parse repeatable `KEY=value` flags into a record. Last wins. */\nexport function parseKeyValues(pairs: string[]): Record<string, string> {\n const out: Record<string, string> = {}\n for (const p of pairs) {\n const eq = p.indexOf('=')\n if (eq <= 0) throw new CliError(`bad key=value pair: \"${p}\" (expected KEY=value)`)\n out[p.slice(0, eq)] = p.slice(eq + 1)\n }\n return out\n}\n\n/** Capability envs the recipe needs that the caller hasn't supplied. */\nexport function missingCapabilities(required: string[], provided: Record<string, string>): string[] {\n return required.filter(env => !(env in provided))\n}\n\n// citty 0.2.2 coerces a repeated `type:'string'` flag to its LAST value\n// only (`--param a=1 --param b=2` → \"b=2\"), silently dropping earlier\n// occurrences. Collect every occurrence straight from the raw argv so\n// multiple --param / --secret flags all survive. Handles both\n// `--flag value` and `--flag=value` forms.\nexport function collectFlag(rawArgs: string[], name: string): string[] {\n const out: string[] = []\n const long = `--${name}`\n for (let i = 0; i < rawArgs.length; i++) {\n const a = rawArgs[i]!\n if (a === long) {\n const v = rawArgs[i + 1]\n if (v !== undefined && !v.startsWith('--')) {\n out.push(v)\n i++\n }\n }\n else if (a.startsWith(`${long}=`)) {\n out.push(a.slice(long.length + 1))\n }\n }\n return out\n}\n\ninterface DeployResponse {\n intent_id: string\n agent_name: string\n ref: string\n required_capabilities: string[]\n schedules: Array<{ task_id: string, cron: string, name: string }>\n}\n\nasync function api<T>(url: string, token: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', ...init?.headers },\n })\n if (!res.ok) {\n const body = await res.text().catch(() => '')\n throw new CliError(`${init?.method ?? 'GET'} ${url} → HTTP ${res.status}${body ? `: ${body.slice(0, 300)}` : ''}`)\n }\n return res.json() as Promise<T>\n}\n\nconst sleep = (ms: number) => new Promise<void>(r => setTimeout(r, ms))\n\nexport const deployAgentCommand = defineCommand({\n meta: { name: 'deploy', description: 'Deploy an Agent Recipe (<repo>@<ref>) in one step' },\n args: {\n repo: { type: 'positional', description: 'Recipe repo + pinned ref, e.g. github.com/owner/name@v1.0.0' },\n param: { type: 'string', description: 'Recipe param, KEY=value (repeatable)' },\n secret: { type: 'string', description: 'Capability secret, ENV=value (repeatable; else prompted)' },\n 'host-id': { type: 'string', description: 'Target nest host_id (default: first connected)' },\n json: { type: 'boolean', description: 'Machine-readable output, no prompts' },\n },\n async run({ args, rawArgs }) {\n const repoRef = args.repo as string\n if (!repoRef) throw new CliError('usage: apes agent deploy <repo>@<ref> [--param k=v] [--secret ENV=val]')\n const params = parseKeyValues(collectFlag(rawArgs, 'param'))\n const secrets = parseKeyValues(collectFlag(rawArgs, 'secret'))\n const json = !!args.json\n\n const token = (await ensureFreshIdpAuth()).access_token\n const troop = resolveTroopUrl()\n\n const deploy = await api<DeployResponse>(`${troop}/api/agents/recipe-deploy`, token, {\n method: 'POST',\n body: JSON.stringify({\n repo_ref: repoRef,\n params,\n ...(args['host-id'] ? { host_id: args['host-id'] as string } : {}),\n }),\n })\n\n if (!json) {\n consola.success(`Deploying ${deploy.agent_name} from ${repoRef} (ref ${deploy.ref})`)\n consola.info(`Schedules: ${deploy.schedules.map(s => `${s.task_id}=${s.cron}`).join(', ') || 'none'}`)\n }\n\n // Collect capability values: --secret flags first, then prompt for\n // the rest (unless --json, where missing is a hard error).\n const missing = missingCapabilities(deploy.required_capabilities, secrets)\n if (missing.length > 0) {\n if (json) {\n throw new CliError(`missing required capability secrets: ${missing.join(', ')} (pass via --secret in --json mode)`)\n }\n for (const env of missing) {\n const val = await consola.prompt(`Secret value for ${env}:`, { type: 'text' })\n if (typeof val !== 'string' || val.length === 0) throw new CliError(`no value provided for ${env} — aborting`)\n secrets[env] = val\n }\n }\n\n // Wait for the agent to come online (spawn-result), then bind the\n // sealed secrets. Binding 409s until the agent's first sync reports\n // its X25519 pubkey, so we retry with backoff. We bind whenever there\n // are secrets to seal — including optional capabilities the caller\n // supplied via --secret, which never appear in required_capabilities.\n if (Object.keys(secrets).length > 0) {\n if (!json) consola.start('Waiting for the agent to come online…')\n let online = false\n for (let i = 0; i < 90 && !online; i++) {\n const st = await api<{ pending: boolean, ok?: boolean, error?: string }>(\n `${troop}/api/agents/spawn-intent/${deploy.intent_id}`, token,\n )\n if (!st.pending) {\n if (!st.ok) throw new CliError(`spawn failed: ${st.error ?? 'unknown error'}`)\n online = true\n break\n }\n await sleep(2000)\n }\n if (!online) throw new CliError('timed out waiting for the agent to spawn — bind secrets later with `apes agent secret`')\n\n for (const [env, value] of Object.entries(secrets)) {\n let bound = false\n for (let i = 0; i < 60 && !bound; i++) {\n try {\n await api(`${troop}/api/agents/${deploy.agent_name}/secrets/${env}`, token, {\n method: 'PUT',\n body: JSON.stringify({ value }),\n })\n bound = true\n }\n catch (e) {\n // 404 (agent row not synced yet) / 409 (no pubkey yet) → retry.\n if (i === 59) throw e\n await sleep(3000)\n }\n }\n if (!json) consola.success(`Bound ${env}`)\n }\n }\n\n if (json) {\n consola.log(JSON.stringify({\n ok: true,\n agent_name: deploy.agent_name,\n ref: deploy.ref,\n intent_id: deploy.intent_id,\n schedules: deploy.schedules,\n bound: Object.keys(secrets),\n }))\n }\n else {\n consola.success(`${deploy.agent_name} deployed. Schedules are live; secrets sealed to the agent.`)\n }\n },\n})\n","// Typed thin client for troop.openape.ai's agent-side API. The CLI\n// never talks to the owner-side endpoints (those are for the web UI);\n// the troop-client only knows about the three /me/* endpoints needed\n// by `apes agents sync` and `apes agents run`.\n//\n// Default endpoint is https://troop.openape.ai. Override with the\n// OPENAPE_TROOP_URL env var (handy for staging or local dev). The\n// agent JWT comes from `~/.config/apes/auth.json` — the file\n// `apes agents spawn` writes when it provisions the macOS user.\n\nexport const DEFAULT_TROOP_URL = 'https://troop.openape.ai'\n\nexport interface TaskSpec {\n agentEmail: string\n taskId: string\n name: string\n cron: string\n /**\n * Imperative job description — sent as the LLM `user` message at run\n * time. The agent's persona / behaviour rules are in `agent.systemPrompt`\n * and served separately at sync time (see `AgentTasksResponse`).\n */\n userPrompt: string\n /**\n * Optional deterministic shell command. When present, the cron-runner\n * executes it via the gated ape-shell path (no LLM turn, no chat room)\n * and `userPrompt` is just the human-readable fallback. Carried through\n * `apes agents sync` into the per-task cache the cron-runner reads.\n */\n command?: string | null\n tools: string[]\n maxSteps: number\n enabled: boolean\n createdAt: number\n updatedAt: number\n}\n\nexport interface SkillSpec {\n /** Slug — becomes the directory name on disk (`skills/<name>/SKILL.md`). */\n name: string\n /** One-line summary the LLM sees in the system prompt's available_skills block. */\n description: string\n /** Full SKILL.md content the agent runtime writes to disk after sync. */\n body: string\n}\n\n/** Response from /api/agents/me/tasks — agent config + task list. */\nexport interface AgentTasksResponse {\n /**\n * Agent-level persona/behaviour rules — used as `system` for both\n * cron task runs and live chat-bridge messages. Empty string when the\n * owner hasn't set one.\n */\n system_prompt: string\n /**\n * Tool whitelist for chat-bridge runtime. Cron tasks have their own\n * per-task `tools[]` (see TaskSpec); this is the list the bridge\n * exposes to the LLM during live chat-thread turns. Empty array =\n * no tools (pure chat). Defaults to \"all known tools\" on first\n * sync — owner narrows via troop UI.\n */\n tools: string[]\n /**\n * Lazy-load skill catalog — only enabled rows from agent_skills.\n * Each one lands at `~/.openape/agent/skills/<name>/SKILL.md`.\n */\n skills: SkillSpec[]\n tasks: TaskSpec[]\n}\n\nexport interface SyncResponse {\n agent_email: string\n host_id: string\n first_sync: boolean\n last_seen_at: number\n}\n\nexport interface RunStartResponse {\n id: string\n started_at: number\n}\n\nexport interface RunFinalisePayload {\n status: 'ok' | 'error'\n final_message: string | null\n step_count: number\n trace?: unknown\n}\n\nexport class TroopClient {\n constructor(\n public readonly troopUrl: string,\n public readonly agentJwt: string,\n ) {}\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const res = await fetch(`${this.troopUrl}${path}`, {\n ...init,\n headers: {\n ...(init?.headers ?? {}),\n 'Authorization': `Bearer ${this.agentJwt}`,\n 'Content-Type': 'application/json',\n },\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`troop ${init?.method ?? 'GET'} ${path} failed: ${res.status} ${text}`)\n }\n if (res.status === 204) return undefined as T\n return await res.json() as T\n }\n\n sync(input: { hostname: string, hostId: string, ownerEmail: string, pubkeySsh?: string, pubkeyX25519?: string }): Promise<SyncResponse> {\n return this.request('/api/agents/me/sync', {\n method: 'POST',\n body: JSON.stringify({\n hostname: input.hostname,\n host_id: input.hostId,\n owner_email: input.ownerEmail,\n ...(input.pubkeySsh ? { pubkey_ssh: input.pubkeySsh } : {}),\n // Without this the agent's encryption pubkey never reaches troop,\n // so every sealed-capability bind 409s (\"no X25519 public key\n // yet\"). The keypair is written at spawn (agent-bootstrap); we\n // just have to report the public half here.\n ...(input.pubkeyX25519 ? { pubkey_x25519: input.pubkeyX25519 } : {}),\n }),\n })\n }\n\n listTasks(): Promise<AgentTasksResponse> {\n return this.request('/api/agents/me/tasks')\n }\n\n startRun(taskId: string): Promise<RunStartResponse> {\n return this.request('/api/agents/me/runs', {\n method: 'POST',\n body: JSON.stringify({ task_id: taskId }),\n })\n }\n\n finaliseRun(id: string, payload: RunFinalisePayload): Promise<unknown> {\n return this.request(`/api/agents/me/runs/${id}`, {\n method: 'PATCH',\n body: JSON.stringify(payload),\n })\n }\n}\n\nexport function resolveTroopUrl(override?: string): string {\n if (override) return override.replace(/\\/$/, '')\n const fromEnv = process.env.OPENAPE_TROOP_URL\n if (fromEnv) return fromEnv.replace(/\\/$/, '')\n return DEFAULT_TROOP_URL\n}\n","import { defineCommand } from 'citty'\nimport { allowAgentCommand } from './allow'\nimport { cleanupOrphansCommand } from './cleanup-orphans'\nimport { codeAgentCommand } from './code'\nimport { destroyAgentCommand } from './destroy'\nimport { listAgentsCommand } from './list'\nimport { registerAgentCommand } from './register'\nimport { runAgentCommand } from './run'\nimport { serveAgentCommand } from './serve'\nimport { spawnAgentCommand } from './spawn'\nimport { syncAgentCommand } from './sync'\n\nexport const agentsCommand = defineCommand({\n meta: {\n name: 'agents',\n description: 'Manage owned agents (register, spawn, list, destroy, allow, sync, run, serve, code, cleanup-orphans)',\n },\n subCommands: {\n register: registerAgentCommand,\n spawn: spawnAgentCommand,\n list: listAgentsCommand,\n destroy: destroyAgentCommand,\n allow: allowAgentCommand,\n sync: syncAgentCommand,\n run: runAgentCommand,\n serve: serveAgentCommand,\n code: codeAgentCommand,\n 'cleanup-orphans': cleanupOrphansCommand,\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { AGENT_NAME_REGEX } from '../../lib/agent-bootstrap'\nimport { isDarwin, lookupMacOSUserForAgent, whichBinary } from '../../lib/macos-user'\n\nexport const allowAgentCommand = defineCommand({\n meta: {\n name: 'allow',\n description:\n 'Add a peer to the agent\\'s contact-allowlist so the bridge auto-accepts that peer\\'s contact request.',\n },\n args: {\n agent: {\n type: 'positional',\n required: true,\n description: 'Agent name (the macOS short username spawn created)',\n },\n email: {\n type: 'positional',\n required: true,\n description: 'Peer email to allow (the address that will send the contact request)',\n },\n },\n async run({ args }) {\n const agent = args.agent as string\n const email = (args.email as string).trim().toLowerCase()\n if (!AGENT_NAME_REGEX.test(agent)) {\n throw new CliError(`Invalid agent name \"${agent}\".`)\n }\n if (!email.includes('@')) {\n throw new CliError(`Invalid email \"${email}\".`)\n }\n if (!isDarwin()) {\n throw new CliError('`apes agents allow` is currently macOS-only.')\n }\n if (!lookupMacOSUserForAgent(agent)) {\n throw new CliError(`No macOS user for agent \"${agent}\" — has it been spawned?`)\n }\n const apes = whichBinary('apes')\n if (!apes) throw new CliError('`apes` not found on PATH.')\n\n // Update the allowlist file inside the agent's home. python3 is\n // always present on macOS — avoids a jq dep. Idempotent: re-running\n // for the same email is a no-op.\n const script = `set -eu\nmkdir -p \"$HOME/.config/openape\"\nF=\"$HOME/.config/openape/bridge-allowlist.json\"\nEMAIL=${shQuote(email)}\npython3 - \"$F\" \"$EMAIL\" <<'PY'\nimport json, os, sys\npath, email = sys.argv[1], sys.argv[2].lower()\ndata = {\"emails\": []}\nif os.path.exists(path):\n try:\n with open(path) as f:\n data = json.load(f)\n if not isinstance(data, dict) or not isinstance(data.get(\"emails\"), list):\n data = {\"emails\": []}\n except Exception:\n data = {\"emails\": []}\nemails = {e.lower() for e in data[\"emails\"] if isinstance(e, str)}\nemails.add(email)\ndata[\"emails\"] = sorted(emails)\nwith open(path, \"w\") as f:\n json.dump(data, f, indent=2)\n f.write(\"\\\\n\")\nprint(\"ok\")\nPY\nchmod 600 \"$F\"\n`\n\n consola.start(`Adding ${email} to ${agent}'s allowlist…`)\n execFileSync(apes, ['run', '--as', agent, '--wait', '--', 'bash', '-c', script], { stdio: 'inherit' })\n consola.success(`${agent} will auto-accept future contact requests from ${email} (within ~30s of next bridge connect).`)\n },\n})\n\nfunction shQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`\n}\n","import { Buffer } from 'node:buffer'\nimport { execFileSync } from 'node:child_process'\nimport { createPrivateKey, sign } from 'node:crypto'\nimport { rmSync } from 'node:fs'\nimport { exchangeWithDelegation } from '@openape/cli-auth'\nimport { loadAuth } from '../config'\nimport { apiFetch, getAgentAuthenticateEndpoint, getAgentChallengeEndpoint } from '../http'\n\nexport const AGENT_NAME_REGEX = /^[a-z][a-z0-9-]{0,23}$/\nexport const SSH_ED25519_PREFIX = 'ssh-ed25519 '\nexport const SSH_ED25519_REGEX = /^ssh-ed25519 [A-Za-z0-9+/=]+(\\s.*)?$/\n\nconst ENROLL_AUDIENCE = 'enroll-agent'\n\nexport interface RegisterAgentResponse {\n email: string\n name: string\n owner: string\n approver: string\n status: string\n}\n\n/**\n * Enrol an agent at the IdP. When the local caller is itself an\n * agent (e.g. the local Nest enrolling a child agent), we look for\n * a delegation grant from the agent's owner authorising us to act\n * for them, and exchange both tokens for a delegated access token\n * (RFC 8693). The /api/enroll endpoint then sees `sub=owner` and\n * `act={sub:caller}` and attributes ownership correctly without\n * needing a server-side transitive-ownership heuristic.\n *\n * Falls back to the direct call (caller-as-requester) when no\n * delegation is available — the IdP's transitive-ownership lookup\n * still covers that path until M3 retires it.\n */\nexport async function registerAgentAtIdp(input: {\n name: string\n publicKey: string\n idp?: string\n}): Promise<RegisterAgentResponse> {\n const delegated = await tryDelegatedEnrollToken(input.idp)\n return await apiFetch<RegisterAgentResponse>('/api/enroll', {\n method: 'POST',\n body: { name: input.name, publicKey: input.publicKey },\n idp: input.idp,\n ...(delegated ? { headers: { Authorization: `Bearer ${delegated}` } } : {}),\n })\n}\n\n/**\n * If the caller is an agent and the owner has previously approved a\n * delegation grant (audience `enroll-agent`), exchange the agent's\n * access token + the delegation grant id for a delegated access\n * token whose `sub` is the owner.\n *\n * Lookup strategy: list active grants where requester = owner_email,\n * find the first delegation grant where delegate = us and audience is\n * `enroll-agent` or `*`. Returns null on any failure (no delegation\n * found, network error, etc.) so the caller falls back to the\n * direct-enroll path — token-exchange is an optimisation while the\n * IdP's transitive-ownership lookup still covers the gap.\n */\nasync function tryDelegatedEnrollToken(idp?: string): Promise<string | null> {\n try {\n const auth = loadAuth()\n if (!auth?.access_token) return null\n // Only agents need delegation. Humans always enrol on their own\n // behalf (sub=owner already).\n const claims = decodeJwtClaims(auth.access_token)\n if (claims?.act !== 'agent') return null\n const ownerEmail = (auth as { owner_email?: unknown }).owner_email\n if (typeof ownerEmail !== 'string' || !ownerEmail) return null\n const myEmail = auth.email\n if (typeof myEmail !== 'string' || !myEmail) return null\n\n const idpUrl = idp ?? auth.idp\n if (!idpUrl) return null\n\n const grantId = await findEnrollDelegationGrantId(idpUrl, ownerEmail, myEmail)\n if (!grantId) {\n // Visible signal during the rollout window so we can tell when\n // a Nest is still falling back to /api/enroll's transitive-\n // ownership heuristic (and therefore why removing that\n // heuristic would break it). Stays at debug volume so it\n // doesn't pollute the spawn flow's stdout.\n console.warn(`[agent-bootstrap] no enroll-agent delegation from ${ownerEmail} to ${myEmail} — falling back to direct enroll`)\n return null\n }\n\n const result = await exchangeWithDelegation({\n idp: idpUrl,\n actorToken: auth.access_token,\n audience: ENROLL_AUDIENCE,\n delegationGrantId: grantId,\n })\n console.log(`[agent-bootstrap] using delegated token from grant ${grantId} (sub=${ownerEmail}, act=${myEmail})`)\n return result.access_token\n }\n catch (err) {\n console.warn(`[agent-bootstrap] delegated-enroll exchange failed: ${err instanceof Error ? err.message : String(err)} — falling back to direct enroll`)\n return null\n }\n}\n\ninterface GrantListEntry {\n id: string\n type?: string\n status?: string\n expires_at?: number\n request: {\n audience?: string\n delegate?: string\n delegator?: string\n grant_type?: string\n }\n}\n\nasync function findEnrollDelegationGrantId(\n idp: string,\n delegator: string,\n delegate: string,\n): Promise<string | null> {\n const url = `${idp.replace(/\\/$/, '')}/api/grants?status=approved&limit=200&requester=${encodeURIComponent(delegator)}`\n // Anonymous request: the IdP allows listing one's own approved\n // grants without auth in some configurations; if it requires auth\n // and rejects, we return null and fall back. Acceptable because\n // the delegation lookup is optional.\n const res = await apiFetch<{ data: GrantListEntry[] }>(url)\n const now = Math.floor(Date.now() / 1000)\n for (const g of res.data ?? []) {\n if (g.type !== 'delegation') continue\n if (g.status !== 'approved') continue\n if (g.request.delegate !== delegate) continue\n const aud = g.request.audience\n if (aud !== '*' && aud !== ENROLL_AUDIENCE) continue\n if (g.expires_at && g.expires_at <= now) continue\n return g.id\n }\n return null\n}\n\nfunction decodeJwtClaims(token: string): { act?: unknown } | null {\n try {\n const part = token.split('.')[1]\n if (!part) return null\n const padded = part + '='.repeat((4 - part.length % 4) % 4)\n const json = Buffer.from(padded, 'base64').toString('utf8')\n return JSON.parse(json) as { act?: unknown }\n }\n catch {\n return null\n }\n}\n\nexport interface IssuedAgentToken {\n token: string\n expiresIn: number\n}\n\n/**\n * Single-shot challenge/authenticate using a privately held PEM key.\n * Used by `spawn` after registering the agent: we already know the keypair\n * works (we just generated it), so we skip the polling loop in `enroll.ts`.\n */\nexport async function issueAgentToken(input: {\n idp: string\n agentEmail: string\n privateKeyPem: string\n}): Promise<IssuedAgentToken> {\n const privateKey = createPrivateKey(input.privateKeyPem)\n\n const challengeUrl = await getAgentChallengeEndpoint(input.idp)\n const challengeResp = await fetch(challengeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: input.agentEmail }),\n })\n if (!challengeResp.ok) {\n const text = await challengeResp.text().catch(() => '')\n throw new Error(`Challenge failed (${challengeResp.status}): ${text}`)\n }\n const { challenge } = await challengeResp.json() as { challenge: string }\n\n const signature = sign(null, Buffer.from(challenge), privateKey).toString('base64')\n\n const authenticateUrl = await getAgentAuthenticateEndpoint(input.idp)\n const authResp = await fetch(authenticateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: input.agentEmail, challenge, signature }),\n })\n if (!authResp.ok) {\n const text = await authResp.text().catch(() => '')\n throw new Error(`Authenticate failed (${authResp.status}): ${text}`)\n }\n const result = await authResp.json() as { token: string, expires_in: number }\n return { token: result.token, expiresIn: result.expires_in || 3600 }\n}\n\nexport interface SpawnSetupScriptInput {\n name: string\n /**\n * macOS username for the dscl record + chown ops. Prefixed with\n * `openape-agent-` (see MACOS_USER_PREFIX) so operators can audit\n * `dscl . -list /Users` and `apes agents cleanup-orphans` can\n * recognise OpenApe-managed accounts without UID-range heuristics.\n * Kept separate from `name` so the bare agent name stays visible\n * on user-facing surfaces (email, troop UI, bridge data dir).\n */\n macOSUsername: string\n homeDir: string\n shellPath: string\n privateKeyPem: string\n publicKeySshLine: string\n /**\n * Agent X25519 keypair (base64url DER) for sealed capability secrets.\n * The private key is written to `~/.config/openape/agent-x25519.key`\n * (0600) so the agent runtime can open secrets troop sealed to its\n * public key. The public key is written alongside (`.pub`, 0644) so\n * the agent can report it to troop on sync.\n */\n x25519PrivateKey: string\n x25519PublicKey: string\n authJson: string\n claudeSettingsJson: string | null\n hookScriptSource: string | null\n /**\n * Long-lived Claude Code OAuth token (`sk-ant-oat01-…`) obtained via\n * `claude setup-token`. When provided, gets written to a chmod 600 env\n * file under the agent's HOME and sourced from .zshenv + .profile so\n * `claude -p \"…\"` works immediately without interactive auth.\n * `null` means the agent has no Claude credential — `claude` will\n * prompt for auth on first run inside that user.\n */\n claudeOauthToken: string | null\n /**\n * If set, also installs the ape-agent runtime for this agent:\n * drops a launchd plist + start script + .env with the LLM proxy master\n * key. The runtime expects `@openape/ape-agent` to already be installed\n * globally on the host. `null` skips the bridge entirely (current default).\n */\n bridge: SpawnBridgeFiles | null\n /**\n * Troop sync launchd plist. Always set for spawn-via-troop; passed\n * as null only by tests that exercise the legacy path. Drops the\n * plist into ~/Library/LaunchAgents/ and bootstraps it.\n */\n troop: SpawnTroopFiles | null\n}\n\nexport interface SpawnBridgeFiles {\n /** Plist label, e.g. `eco.hofmann.apes.bridge.<agent>` (must be unique). */\n plistLabel: string\n /** Absolute path of the plist file (under /Library/LaunchDaemons/). */\n plistPath: string\n /** XML plist content (full file). */\n plistContent: string\n /** start.sh content (idempotent installer + exec). */\n startScript: string\n /** .env content (`LITELLM_BASE_URL` + `LITELLM_API_KEY`). */\n envFile: string\n}\n\nconst SH_HEREDOC_DELIMITER = 'APES_HEREDOC_END'\n\nfunction shHeredoc(content: string): string {\n if (content.includes(SH_HEREDOC_DELIMITER)) {\n throw new Error(`Refusing to emit heredoc: content contains ${SH_HEREDOC_DELIMITER}`)\n }\n return `<< '${SH_HEREDOC_DELIMITER}'\\n${content}\\n${SH_HEREDOC_DELIMITER}`\n}\n\nexport function buildSpawnSetupScript(input: SpawnSetupScriptInput): string {\n const { name, macOSUsername, homeDir, shellPath } = input\n\n // Trailing newline on PEM keeps OpenSSL happy. JSON files we write as-is.\n const privatePemForHeredoc = input.privateKeyPem.endsWith('\\n')\n ? input.privateKeyPem\n : `${input.privateKeyPem}\\n`\n\n const claudeBlock = input.claudeSettingsJson && input.hookScriptSource\n ? `\nmkdir -p \"$HOME_DIR/.claude/hooks\"\ncat > \"$HOME_DIR/.claude/settings.json\" ${shHeredoc(input.claudeSettingsJson)}\ncat > \"$HOME_DIR/.claude/hooks/bash-via-ape-shell.sh\" ${shHeredoc(input.hookScriptSource)}\nchmod 755 \"$HOME_DIR/.claude/hooks/bash-via-ape-shell.sh\"\n`\n : ''\n\n // Claude Code OAuth token: write to a chmod 600 env file under\n // ~/.config/openape/, source it from both .zshenv (zsh always loads,\n // including non-interactive) and .profile (bash login shells, what\n // `escapes` ends up exec'ing through). Keeping the actual token in\n // one place means rotation = edit one file, no shell-rc grep needed.\n const claudeTokenBlock = input.claudeOauthToken\n ? `\nmkdir -p \"$HOME_DIR/.config/openape\"\ncat > \"$HOME_DIR/.config/openape/claude-token.env\" ${shHeredoc(`# Auto-generated by 'apes agents spawn'. chmod 600 — contains a long-lived\\n# Claude Code OAuth token. Rotate by editing this file in place; the\\n# .zshenv / .profile source-lines below will pick it up automatically.\\nexport CLAUDE_CODE_OAUTH_TOKEN=${shQuote(input.claudeOauthToken)}\\n`)}\nSOURCE_LINE='[ -f \"$HOME/.config/openape/claude-token.env\" ] && . \"$HOME/.config/openape/claude-token.env\"'\nfor f in \"$HOME_DIR/.zshenv\" \"$HOME_DIR/.profile\"; do\n touch \"$f\"\n if ! grep -qF 'config/openape/claude-token.env' \"$f\" 2>/dev/null; then\n {\n echo ''\n echo '# OpenApe: load Claude Code OAuth token (added by apes agents spawn)'\n echo \"$SOURCE_LINE\"\n } >> \"$f\"\n fi\ndone\n`\n : ''\n\n return `#!/bin/bash\nset -euo pipefail\n\n# escapes-spawned scripts inherit a minimal PATH that doesn't include\n# /usr/sbin — which is where chown / dscl / pwpolicy live. Force a\n# wide PATH so the privileged setup commands resolve without absolute\n# paths everywhere.\nexport PATH=\"/usr/sbin:/usr/bin:/bin:/sbin:/opt/homebrew/bin:/usr/local/bin\"\n\nNAME=${shQuote(name)}\nMACOS_USER=${shQuote(macOSUsername)}\nHOME_DIR=${shQuote(homeDir)}\nSHELL_PATH=${shQuote(shellPath)}\n\n# Tombstone-reuse: \\`apes agents destroy\\` leaves the dscl user\n# record behind (opendirectoryd refuses \\`dscl . -delete\\` from\n# escapes' setuid-root context without admin auth, so we accept the\n# stranded record as a harmless tombstone — see\n# runPhaseGTeardownInProcess). When the operator re-spawns with the\n# same name, we recycle the tombstone instead of refusing: if the\n# previously-recorded home dir is gone from disk (matching the\n# Phase-G teardown's \\`rm -rf\\`), we reuse the existing UID +\n# overwrite the home. If the home is still on disk it's a real,\n# live agent — refuse.\nTOMBSTONE_REUSE=0\nif dscl . -read \"/Users/$MACOS_USER\" >/dev/null 2>&1; then\n EXISTING_HOME=$(dscl . -read \"/Users/$MACOS_USER\" NFSHomeDirectory 2>/dev/null | awk '/NFSHomeDirectory:/ {print $2}')\n if [ -n \"$EXISTING_HOME\" ] && [ -d \"$EXISTING_HOME\" ]; then\n echo \"User $MACOS_USER already exists with a live home at $EXISTING_HOME; refusing to overwrite.\" >&2\n exit 1\n fi\n NEXT_UID=$(dscl . -read \"/Users/$MACOS_USER\" UniqueID 2>/dev/null | awk '/UniqueID:/ {print $2}')\n if [ -z \"$NEXT_UID\" ]; then\n echo \"User $MACOS_USER exists but has no UniqueID; record is malformed, refusing to recycle.\" >&2\n exit 1\n fi\n echo \"Recycling tombstone dscl record for $MACOS_USER (uid=$NEXT_UID, prior home $EXISTING_HOME — gone)\"\n TOMBSTONE_REUSE=1\nfi\n\n# Phase G: agent home dirs live under /var/openape/homes/, not\n# /Users/. Pre-create the parent and chmod it world-traversable\n# so per-agent dirs can be reached by their respective uids.\nmkdir -p /var/openape/homes\nchmod 755 /var/openape/homes\n\nif [ \"$TOMBSTONE_REUSE\" = \"0\" ]; then\n # Pick the LOWEST free UID in the [200, 500) hidden service-account\n # range. We must skip every occupied UID — agent users AND the many\n # macOS system _* accounts — and reuse gaps. The old code took\n # max(existing)+1, so a single agent landing on 499 wedged every\n # future spawn (\"No free UID\") even with 100+ UIDs free. Now we scan\n # for the first actually-unused UID.\n OCCUPIED_UIDS=$(dscl . -list /Users UniqueID | awk '$2 >= 200 && $2 < 500 {print $2}' | sort -n -u)\n NEXT_UID=\"\"\n candidate=200\n while [ \"$candidate\" -lt 500 ]; do\n if ! printf '%s\\n' \"$OCCUPIED_UIDS\" | grep -qx \"$candidate\"; then\n NEXT_UID=$candidate\n break\n fi\n candidate=$((candidate + 1))\n done\n if [ -z \"$NEXT_UID\" ]; then\n echo \"No free UID in [200, 500) — refusing to clobber a real user.\" >&2\n exit 1\n fi\n\n dscl . -create \"/Users/$MACOS_USER\"\nfi\n\n# Idempotent attribute writes — \\`dscl . -create\\` on an existing\n# property overwrites in place, so the tombstone-reuse path lands\n# the same end-state as a fresh create.\ndscl . -create \"/Users/$MACOS_USER\" UserShell \"$SHELL_PATH\"\ndscl . -create \"/Users/$MACOS_USER\" RealName \"OpenApe Agent $NAME\"\ndscl . -create \"/Users/$MACOS_USER\" UniqueID \"$NEXT_UID\"\ndscl . -create \"/Users/$MACOS_USER\" PrimaryGroupID 20\ndscl . -create \"/Users/$MACOS_USER\" NFSHomeDirectory \"$HOME_DIR\"\ndscl . -create \"/Users/$MACOS_USER\" IsHidden 1\n\nmkdir -p \"$HOME_DIR/.ssh\" \"$HOME_DIR/.config/apes\"\n\ncat > \"$HOME_DIR/.ssh/id_ed25519\" ${shHeredoc(privatePemForHeredoc.trimEnd())}\ncat > \"$HOME_DIR/.ssh/id_ed25519.pub\" ${shHeredoc(`${input.publicKeySshLine}`)}\ncat > \"$HOME_DIR/.config/apes/auth.json\" ${shHeredoc(input.authJson)}\nmkdir -p \"$HOME_DIR/.config/openape\"\ncat > \"$HOME_DIR/.config/openape/agent-x25519.key\" ${shHeredoc(input.x25519PrivateKey)}\ncat > \"$HOME_DIR/.config/openape/agent-x25519.key.pub\" ${shHeredoc(input.x25519PublicKey)}\n${claudeBlock}${claudeTokenBlock}${buildBridgeBlock(input.bridge)}${buildTroopBlock(input.troop)}\nchown -R \"$MACOS_USER:staff\" \"$HOME_DIR\"\nchmod 700 \"$HOME_DIR/.ssh\"\nchmod 700 \"$HOME_DIR/.config\"\nchmod 700 \"$HOME_DIR/.config/openape\"\nchmod 600 \"$HOME_DIR/.ssh/id_ed25519\"\nchmod 644 \"$HOME_DIR/.ssh/id_ed25519.pub\"\nchmod 600 \"$HOME_DIR/.config/apes/auth.json\"\nchmod 600 \"$HOME_DIR/.config/openape/agent-x25519.key\"\nchmod 644 \"$HOME_DIR/.config/openape/agent-x25519.key.pub\"\nif [ -f \"$HOME_DIR/.config/openape/claude-token.env\" ]; then\n chmod 700 \"$HOME_DIR/.config/openape\"\n chmod 600 \"$HOME_DIR/.config/openape/claude-token.env\"\nfi\n\necho \"OK $NAME (macOS user $MACOS_USER) uid=$NEXT_UID home=$HOME_DIR\"\n${buildBridgeBootstrapBlock(input.bridge, name)}${buildTroopBootstrapBlock(input.troop, name)}`\n}\n\nfunction buildBridgeBlock(bridge: SpawnBridgeFiles | null): string {\n if (!bridge) return ''\n // Phase B (#sim-arch): no per-agent system-domain bridge plist\n // anymore. The Nest's in-process supervisor owns bridge lifecycle\n // (`apps/openape-nest/src/lib/supervisor.ts`). We still drop the\n // bridge .env into the agent home so the bridge's\n // resolveBridgeConfig finds it at runtime — same path the\n // supervisor's child process uses. start.sh is no longer needed\n // (the supervisor invokes ape-agent directly via\n // \\`apes run --as <agent>\\`), and the system-domain plist is no\n // longer written.\n return `\nmkdir -p \"$HOME_DIR/Library/Application Support/openape/bridge\" \"$HOME_DIR/Library/Logs\"\ncat > \"$HOME_DIR/Library/Application Support/openape/bridge/.env\" ${shHeredoc(bridge.envFile)}\nchmod 600 \"$HOME_DIR/Library/Application Support/openape/bridge/.env\"\n`\n}\n\nfunction buildBridgeBootstrapBlock(_bridge: SpawnBridgeFiles | null, _name: string): string {\n // Phase B: no launchd plist to bootstrap — Nest supervisor takes\n // over at the next /agents POST handler reconcile. Caller (the\n // Nest's POST /agents handler) calls supervisor.reconcile(...)\n // after the spawn succeeds.\n return ''\n}\n\nexport interface SpawnTroopFiles {\n /** Plist label, e.g. `openape.troop.sync.<agent>`. */\n plistLabel: string\n /** Absolute path under $HOME/Library/LaunchAgents/. */\n plistPath: string\n /** Full plist XML content. */\n plistContent: string\n}\n\n/**\n * Troop sync launchd plist — installed for every spawned agent.\n * Drops `~/Library/LaunchAgents/openape.troop.sync.<agent>.plist`,\n * bootstraps it into the agent's user-domain (gui/<uid>), then runs\n * `apes agents sync` once eagerly so the agent appears at the troop\n * SP within seconds rather than waiting a full sync interval.\n */\nfunction buildTroopBlock(_troop: SpawnTroopFiles | null): string {\n // Phase C (#sim-arch): no per-agent troop-sync plist anymore. The\n // Nest's centralised TroopSync loop walks the registry every 5 min\n // and runs `apes agents sync` for each agent (see\n // apps/openape-nest/src/lib/troop-sync.ts). We still create the\n // agent-side dirs that `apes agents sync` writes to.\n return `\nmkdir -p \"$HOME_DIR/Library/Logs\" \"$HOME_DIR/.openape/agent/tasks\"\n`\n}\n\nfunction buildTroopBootstrapBlock(_troop: SpawnTroopFiles | null, _name: string): string {\n // Phase C: no system-domain plist to bootstrap. The Nest's\n // centralised troop-sync loop will pick the new agent up at the\n // next tick (≤5 min after spawn).\n return ''\n}\n\nexport interface DestroyTeardownScriptInput {\n name: string\n homeDir: string\n adminUser: string\n}\n\n/**\n * Phase G teardown — for agents whose home is under /var/openape/homes/.\n * Skips sysadminctl + admin-password because:\n * 1. The home dir is on /var/, not FDA-protected → root can rm.\n * 2. We accept leaving the dscl user record as a tombstone\n * (hidden, IsHidden=1, no home, no processes) — opendirectoryd\n * refuses dscl . -delete from escapes' setuid-root context\n * without admin auth, but the tombstone is harmless.\n * Result: fully scriptable destroy without an interactive admin\n * password prompt.\n */\n/**\n * Phase-G teardown — Node implementation. The shell variant\n * (`buildPhaseGTeardownScript` below) is kept for back-compat but\n * unused in the new flow: instead of `apes run --as root -- bash\n * <tempScript>`, the destroy command does `apes run --as root --\n * apes agents destroy <name> --force --root-stage`, then this\n * function runs the same ops directly in-process when re-invoked\n * as root. Net effect: the DDISA grant request reads\n * \"apes agents destroy <name> --force --root-stage\" (matches the\n * existing `apes agents destroy *` YOLO pattern) instead of an\n * opaque `bash /var/folders/.../teardown.sh`.\n *\n * Caller invariant: process.geteuid() === 0. The shell script\n * tolerated being called as non-root by no-op'ing on the privileged\n * lines; this version trusts the caller to have already escalated\n * via `apes run --as root`.\n */\nexport function runPhaseGTeardownInProcess(input: { name: string, homeDir: string, macOSUsername?: string }): void {\n const { name, homeDir } = input\n // macOSUsername is the dscl record name; for new agents it's\n // `openape-agent-<name>`, for legacy pre-prefix agents it's just\n // <name>. Callers pass it explicitly; if absent we fall back to\n // the agent name so the legacy code path still resolves.\n const macOSUser = input.macOSUsername ?? name\n\n // Read agent's UID via dscl. Same approach as the shell version —\n // dscl . -read /Users/<user> UniqueID emits \"UniqueID: <n>\".\n let uid: string | null = null\n try {\n const out = execFileSync('/usr/bin/dscl', ['.', '-read', `/Users/${macOSUser}`, 'UniqueID'], { encoding: 'utf8' })\n const m = out.match(/UniqueID:\\s*(\\d+)/)\n if (m) uid = m[1]!\n }\n catch { /* dscl returns non-zero when the user doesn't exist — that's fine */ }\n\n if (uid) {\n // bootout the user-domain launchd + kill any live processes\n // owned by the agent uid. Both allowed to fail (no live session\n // is the common case after a clean spawn). We swallow failures\n // identically to the shell script's `|| true`.\n try { execFileSync('/bin/launchctl', ['bootout', `user/${uid}`], { stdio: 'ignore' }) }\n catch { /* no live session — fine */ }\n try { execFileSync('/usr/bin/pkill', ['-9', '-u', uid], { stdio: 'ignore' }) }\n catch { /* no live procs — fine */ }\n }\n\n // Per-agent ecosystem files written by the Nest's pm2-supervisor.\n const agentDir = `/var/openape/agents/${name}`\n try { rmSync(agentDir, { recursive: true, force: true }) }\n catch { /* nothing to remove */ }\n\n // Home dir lives under /var/openape/homes/ — no FDA wall, root can\n // rm directly. Same safety check as the shell script: refuse on\n // empty / root-fs paths so a misconfigured agent.json can't nuke\n // the filesystem.\n if (homeDir && homeDir !== '/' && homeDir.startsWith('/var/openape/homes/')) {\n try { rmSync(homeDir, { recursive: true, force: true }) }\n catch { /* already gone */ }\n }\n\n // dscl record stays as a tombstone — opendirectoryd rejects the\n // delete from escapes' setuid-root context without admin auth, so\n // the user record sticks around hidden (IsHidden=1) with a stale\n // NFSHomeDirectory. Run `sudo apes agents cleanup-orphans` from a\n // shell later to sysadminctl-deleteUser the accumulated tombstones.\n // eslint-disable-next-line no-console\n console.log(`OK Phase-G teardown done for ${name} (dscl record /Users/${macOSUser} kept as tombstone)`)\n}\n\n// Legacy: bash-script version of the same teardown. Kept as a\n// reference until we've verified the in-process variant covers all\n// the edge cases in production; no caller in this repo uses it.\nexport function buildPhaseGTeardownScript(input: { name: string, homeDir: string }): string {\n const { name, homeDir } = input\n return `#!/bin/bash\nset -u\n\nNAME=${shQuote(name)}\nHOME_DIR=${shQuote(homeDir)}\n\nUID_OF=$(dscl . -read \"/Users/$NAME\" UniqueID 2>/dev/null | awk '/UniqueID:/ {print $2}')\n\nif [ -n \"$UID_OF\" ]; then\n launchctl bootout \"user/$UID_OF\" 2>/dev/null || true\n pkill -9 -u \"$UID_OF\" 2>/dev/null || true\nfi\n\n# Per-agent ecosystem files written by the Nest's pm2-supervisor.\nrm -rf \"/var/openape/agents/$NAME\"\n\n# Home dir lives under /var/openape/homes/ — no FDA wall, root can\n# remove directly.\nif [ -d \"$HOME_DIR\" ] && [ \"$HOME_DIR\" != \"/\" ] && [ \"$HOME_DIR\" != \"\" ]; then\n rm -rf \"$HOME_DIR\"\nfi\n\n# dscl record stays as a tombstone. Operators run\n# \\`sudo sysadminctl -deleteUser $NAME\\` to fully clean up if desired.\necho \"OK Phase-G teardown done for $NAME (dscl record kept as tombstone)\"\n`\n}\n\nexport function buildDestroyTeardownScript(input: DestroyTeardownScriptInput): string {\n const { name, homeDir, adminUser } = input\n return `#!/bin/bash\n# Best-effort teardown. set -u catches typos; we deliberately do NOT use -e\n# because pkill / launchctl are allowed to fail when the user has no live\n# sessions.\nset -u\n\nNAME=${shQuote(name)}\nHOME_DIR=${shQuote(homeDir)}\nADMIN_USER=${shQuote(adminUser)}\n\n# Read the admin password from stdin (line 1). The caller pipes it in.\n# We never accept it as an argv element so it can't show up in process\n# listings or escapes' audit log.\nread -r ADMIN_PASSWORD\nif [ -z \"$ADMIN_PASSWORD\" ]; then\n echo \"ERROR: no admin password on stdin (expected one line).\" >&2\n exit 2\nfi\n\nUID_OF=$(dscl . -read \"/Users/$NAME\" UniqueID 2>/dev/null | awk '/UniqueID:/ {print $2}')\n\nif [ -n \"$UID_OF\" ]; then\n launchctl bootout \"user/$UID_OF\" 2>/dev/null || true\n pkill -9 -u \"$UID_OF\" 2>/dev/null || true\nfi\n\n# Per-agent system LaunchDaemon written by spawn (unless --no-bridge). Bootout +\n# delete must come BEFORE we delete the user, otherwise launchd keeps a\n# zombie reference. No-op if the plist isn't there.\nBRIDGE_LABEL=\"eco.hofmann.apes.bridge.$NAME\"\nBRIDGE_PLIST=\"/Library/LaunchDaemons/$BRIDGE_LABEL.plist\"\nif [ -f \"$BRIDGE_PLIST\" ]; then\n launchctl bootout \"system/$BRIDGE_LABEL\" 2>/dev/null || true\n rm -f \"$BRIDGE_PLIST\"\nfi\n\nif [ -d \"$HOME_DIR\" ] && [ \"$HOME_DIR\" != \"/\" ] && [ \"$HOME_DIR\" != \"\" ]; then\n rm -rf \"$HOME_DIR\"\nfi\n\n# \\`escapes\\` is a plain setuid binary — opendirectoryd sees no audit/PAM\n# session attached (AUDIT_SESSION_ID=unset) and rejects DirectoryService\n# writes from this context: a bare \\`sysadminctl -deleteUser\\` or\n# \\`dscl . -delete\\` hangs ~5 minutes and exits with eUndefinedError -14987\n# at DSRecord.m:563. Passing explicit -adminUser/-adminPassword bypasses\n# opendirectoryd's implicit \"is current session admin?\" check and\n# authenticates against DirectoryService directly — the delete then\n# completes in ~1 second.\nif ! command -v sysadminctl >/dev/null 2>&1; then\n echo \"ERROR: sysadminctl not available; cannot delete user record.\" >&2\n exit 1\nfi\n\nsysadminctl \\\\\n -deleteUser \"$NAME\" \\\\\n -adminUser \"$ADMIN_USER\" \\\\\n -adminPassword \"$ADMIN_PASSWORD\"\nSYSAD_EC=$?\nunset ADMIN_PASSWORD\n\nif [ $SYSAD_EC -ne 0 ]; then\n echo \"ERROR: sysadminctl -deleteUser failed (exit=$SYSAD_EC).\" >&2\n echo \" Common causes: wrong admin password, admin user '$ADMIN_USER'\" >&2\n echo \" not in admin group, or target user '$NAME' is the last secure\" >&2\n echo \" token holder (run \\\\\\`sysadminctl -secureTokenStatus $NAME\\\\\\`).\" >&2\n exit 1\nfi\n\n# Verify the record is actually gone.\nif dscl . -read \"/Users/$NAME\" >/dev/null 2>&1; then\n echo \"ERROR: user record /Users/$NAME still exists after teardown\" >&2\n exit 1\nfi\n\necho \"OK destroyed $NAME\"\n`\n}\n\n/**\n * Quote a string for safe use as a single bash argument.\n * Wraps in single quotes and escapes embedded single quotes.\n */\nexport function shQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`\n}\n\nexport interface AuthJsonInput {\n idp: string\n accessToken: string\n email: string\n expiresAt: number\n /**\n * Absolute path to the agent's Ed25519 private key on its own home\n * directory. Lets `@openape/cli-auth` refresh the access token in\n * process via challenge-response — see #259. Spawn writes the key\n * to `${homeDir}/.ssh/id_ed25519` so the path is deterministic.\n */\n keyPath: string\n /**\n * Email of the human owner who spawned this agent. Persisted so the\n * bridge daemon can (a) send the initial contact request to the right\n * person and (b) seed its allowlist with the only peer it should\n * trust by default. Other peers go through `apes agents allow`.\n */\n ownerEmail: string\n}\n\nexport function buildAgentAuthJson(input: AuthJsonInput): string {\n return `${JSON.stringify({\n idp: input.idp,\n access_token: input.accessToken,\n email: input.email,\n expires_at: input.expiresAt,\n key_path: input.keyPath,\n owner_email: input.ownerEmail,\n }, null, 2)}\\n`\n}\n\nexport const CLAUDE_SETTINGS_JSON: string = `${JSON.stringify({\n hooks: {\n PreToolUse: [\n {\n matcher: 'Bash',\n hooks: [\n { type: 'command', command: '$HOME/.claude/hooks/bash-via-ape-shell.sh' },\n ],\n },\n ],\n },\n}, null, 2)}\\n`\n\n/**\n * Inlined source of `packages/apes/scripts/bash-via-ape-shell.sh`.\n * Kept identical to the .sh file via the bundled-hook-source.test.ts\n * drift check; resolving the file at runtime is unreliable across\n * dev/built/installed layouts, so we embed once at build time.\n */\nexport const BASH_VIA_APE_SHELL_HOOK_SOURCE = `#!/bin/bash\n# PreToolUse hook for the Bash tool: rewrite the tool input so the\n# original command runs via \\`ape-shell -c <cmd>\\`. That re-routes every\n# Bash invocation through the apes grant flow, so the agent cannot\n# execute shell commands without an approved grant.\nexec python3 -c '\nimport json, shlex, sys\ndata = json.load(sys.stdin)\ncmd = data[\"tool_input\"][\"command\"]\nwrapped = \"ape-shell -c \" + shlex.quote(cmd)\nout = {\"hookSpecificOutput\": {\"hookEventName\": \"PreToolUse\", \"updatedToolInput\": {\"command\": wrapped}}}\nprint(json.dumps(out))\n'\n`\n","import { execFileSync } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\n\nexport interface MacOSUserSummary {\n name: string\n uid: number | null\n shell: string | null\n /** Resolved NFSHomeDirectory — varies between /Users/<name> for\n * legacy agents and /var/openape/homes/<name> for Phase G+ agents. */\n homeDir: string | null\n}\n\nexport function isDarwin(): boolean {\n return process.platform === 'darwin'\n}\n\n/**\n * Prefix every spawned macOS service user with this string so\n * `cleanup-orphans`, operator tooling, and any future `dscl . -list\n * /Users` audit can identify OpenApe-managed accounts at a glance\n * without scanning the full UID range. Agent-facing surfaces (email,\n * troop UI, bridge data dir, `apes agents list`) keep the bare agent\n * name — the prefix lives only at the macOS layer.\n */\nexport const MACOS_USER_PREFIX = 'openape-agent-'\n\nexport function macOSUsernameForAgent(agentName: string): string {\n return `${MACOS_USER_PREFIX}${agentName}`\n}\n\n/**\n * Resolve the macOS user record for an agent, trying the prefixed\n * name first (new spawns) and falling back to the bare agent name\n * (pre-prefix agents). Returns null when neither exists. Used by\n * destroy / run --as / list so legacy agents keep working\n * transparently.\n */\nexport function lookupMacOSUserForAgent(agentName: string): MacOSUserSummary | null {\n return readMacOSUser(macOSUsernameForAgent(agentName)) ?? readMacOSUser(agentName)\n}\n\nexport interface OrphanRecord {\n /** dscl record name (e.g. `openape-agent-igor`). */\n name: string\n uid: number | null\n /** The NFSHomeDirectory the record points at — already verified to be missing. */\n homeDir: string\n}\n\n/**\n * Enumerate dscl user records that look like OpenApe agent tombstones:\n * either prefixed with `openape-agent-`, or whose home dir is under\n * `/var/openape/homes/` (legacy agents pre-prefix). A record counts as\n * orphaned when its NFSHomeDirectory does not exist on disk anymore —\n * matching the post-destroy state that opendirectoryd refuses to clean\n * up from escapes' setuid-root audit-session.\n *\n * Caller invariant: process is running with admin audit-session\n * (i.e. invoked under interactive `sudo`). The dscl/readFile calls\n * themselves don't strictly need root, but the cleanup pass that\n * consumes this list does.\n */\nexport function listOrphanedAgentRecords(): OrphanRecord[] {\n if (!isDarwin()) return []\n let output: string\n try {\n output = execFileSync('dscl', ['.', '-list', '/Users', 'NFSHomeDirectory'], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n }\n catch { return [] }\n\n const orphans: OrphanRecord[] = []\n for (const line of output.split('\\n')) {\n // dscl emits \"<name>\\t<homeDir>\" — but the separator can collapse\n // to runs of whitespace, so split on /\\s+/ and take first + last.\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 2) continue\n const name = parts[0]!\n const homeDir = parts.slice(1).join(' ')\n const looksLikeAgent = name.startsWith(MACOS_USER_PREFIX) || homeDir.startsWith('/var/openape/homes/')\n if (!looksLikeAgent) continue\n if (existsSync(homeDir)) continue\n const record = readMacOSUser(name)\n orphans.push({ name, uid: record?.uid ?? null, homeDir })\n }\n return orphans\n}\n\n/**\n * Read a single user via `dscl . -read /Users/<name>`.\n * Returns null when the user doesn't exist (dscl exits non-zero with a\n * `eDSRecordNotFound`-style error). Any other error propagates.\n */\nexport function readMacOSUser(name: string): MacOSUserSummary | null {\n let output: string\n try {\n output = execFileSync('dscl', ['.', '-read', `/Users/${name}`], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n }\n catch {\n return null\n }\n\n const uidMatch = output.match(/UniqueID:\\s*(\\d+)/)\n const shellMatch = output.match(/UserShell:\\s*(\\S.*)$/m)\n const homeMatch = output.match(/NFSHomeDirectory:\\s*(\\S.*)$/m)\n return {\n name,\n uid: uidMatch ? Number.parseInt(uidMatch[1]!, 10) : null,\n shell: shellMatch ? shellMatch[1]!.trim() : null,\n homeDir: homeMatch ? homeMatch[1]!.trim() : null,\n }\n}\n\n/**\n * List all macOS user names via `dscl . -list /Users`.\n * Returns the raw set of names (no filtering), one per line.\n */\nexport function listMacOSUserNames(): Set<string> {\n let output: string\n try {\n output = execFileSync('dscl', ['.', '-list', '/Users'], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n }\n catch {\n return new Set()\n }\n return new Set(\n output\n .split('\\n')\n .map(line => line.trim())\n .filter(line => line.length > 0),\n )\n}\n\n/**\n * Resolve a binary on PATH using `which`. Returns the absolute path or null.\n */\nexport function whichBinary(name: string): string | null {\n try {\n const out = execFileSync('which', [name], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim()\n return out || null\n }\n catch {\n return null\n }\n}\n\n/**\n * Check whether the given shell path is registered in /etc/shells. macOS\n * (and chsh on most Unixes) refuses to set a login shell that isn't listed.\n */\nexport function isShellRegistered(shellPath: string): boolean {\n if (!existsSync('/etc/shells')) return false\n const content = readFileSync('/etc/shells', 'utf-8')\n return content\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l && !l.startsWith('#'))\n .includes(shellPath)\n}\n","import { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { isDarwin, listOrphanedAgentRecords } from '../../lib/macos-user'\n\n/**\n * Sweep accumulated agent-user tombstones left behind by\n * `apes agents destroy`. opendirectoryd refuses `dscl . -delete` from\n * escapes' setuid-root context (the audit-session is unset, so it\n * cannot verify admin authorisation), but accepts `sysadminctl\n * -deleteUser` when invoked under an interactive `sudo` session\n * because that inherits the operator's admin audit-session.\n *\n * Detection rule: any dscl user record whose NFSHomeDirectory is\n * under `/var/openape/homes/` OR whose name starts with\n * `openape-agent-`, AND whose home dir is missing on disk. The\n * combination is unambiguous — Phase G+ agents always put homes\n * under that path, and the prefix narrows it further once all\n * agents are migrated.\n *\n * Run as: `sudo apes agents cleanup-orphans` (interactive admin\n * session required). The command refuses to proceed when not root.\n */\nexport const cleanupOrphansCommand = defineCommand({\n meta: {\n name: 'cleanup-orphans',\n description: 'Delete tombstoned macOS user records left behind by `apes agents destroy` (run with sudo).',\n },\n args: {\n 'dry-run': {\n type: 'boolean',\n description: 'List orphans without deleting.',\n },\n 'force': {\n type: 'boolean',\n description: 'Skip the interactive confirmation. Required when stdin is not a TTY.',\n },\n },\n async run({ args }) {\n if (!isDarwin()) {\n throw new CliError(`\\`apes agents cleanup-orphans\\` is macOS-only. Detected platform: ${process.platform}.`)\n }\n\n const orphans = listOrphanedAgentRecords()\n if (orphans.length === 0) {\n consola.success('No agent tombstones found — dscl is clean.')\n return\n }\n\n consola.info(`Found ${orphans.length} agent tombstone${orphans.length === 1 ? '' : 's'}:`)\n for (const o of orphans) {\n console.log(` • ${o.name}${o.uid !== null ? ` (uid=${o.uid})` : ''} — was ${o.homeDir}`)\n }\n\n if (args['dry-run']) {\n consola.info('Dry-run — no records deleted. Re-run without --dry-run to clean up.')\n return\n }\n\n if (process.geteuid?.() !== 0) {\n throw new CliError(\n 'Must run as root so opendirectoryd accepts the sysadminctl-deleteUser calls. '\n + 'Re-run with `sudo apes agents cleanup-orphans` from a shell login (the sudo '\n + 'session inherits your admin audit-session, which opendirectoryd verifies).',\n )\n }\n\n if (!args.force) {\n if (!process.stdin.isTTY) {\n throw new CliError(\n 'No TTY available for the interactive confirmation. Re-run with --force '\n + '(this is the same flag CI / scripted callers use).',\n )\n }\n const confirmed = await consola.prompt(`Delete ${orphans.length} tombstone${orphans.length === 1 ? '' : 's'}?`, {\n type: 'confirm',\n initial: false,\n })\n if (typeof confirmed === 'symbol' || !confirmed) {\n consola.info('Aborted — no records deleted.')\n return\n }\n }\n\n let deleted = 0\n let failed = 0\n for (const o of orphans) {\n try {\n execFileSync('/usr/sbin/sysadminctl', ['-deleteUser', o.name], {\n stdio: ['ignore', 'inherit', 'inherit'],\n })\n consola.success(`Deleted ${o.name}`)\n deleted++\n }\n catch (err) {\n consola.warn(`Failed to delete ${o.name}: ${err instanceof Error ? err.message : String(err)}`)\n failed++\n }\n }\n\n if (failed > 0) {\n throw new CliError(`Cleanup finished with errors: ${deleted} deleted, ${failed} failed.`)\n }\n consola.success(`Cleanup complete — ${deleted} tombstone${deleted === 1 ? '' : 's'} removed.`)\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\nimport { consola } from 'consola'\nimport type { RuntimeConfig } from '../../lib/agent-runtime'\nimport { taskTools } from '../../lib/agent-tools'\nimport { runApeShell } from '../../lib/agent-tools/ape-shell-exec'\nimport { materializeSecrets } from '../../lib/agent-secrets-runtime'\nimport { runCodingTask } from '../../lib/coding/coding-loop'\nimport { buildIssueGet, detectForge } from '../../lib/coding/forge'\nimport type { Forge } from '../../lib/coding/forge'\nimport type { IssueRef } from '../../lib/coding/issue-task'\nimport { createLlmReviewer, createLlmRiskAssessor } from '../../lib/coding/llm-review'\nimport { resolveMergePolicy } from '../../lib/coding/derive-policy'\n\nclass CliError extends Error {}\n\n// The LLM toolset for coding — file.*/bash/verify + read-only forge.\n// Deliberately NO forge.pr.merge (the orchestrator owns merge).\nconst CODING_TOOLS = ['file.read', 'file.write', 'file.edit', 'bash', 'git.worktree', 'verify', 'forge.issue.get', 'forge.pr.status']\n\nconst DEFAULT_PERSONA = [\n 'You are an autonomous coding agent. You implement an assigned issue in',\n 'the provided git worktree: read the relevant code, make small targeted',\n 'edits with file.edit, and make the repo verification command pass via',\n 'the verify tool. Do not open or merge PRs — the orchestrator does that.',\n 'No change is done until verify is green.',\n].join(' ')\n\nfunction readLitellmConfig(model?: string): RuntimeConfig {\n const env: Record<string, string> = {}\n const envPath = join(homedir(), 'litellm', '.env')\n if (existsSync(envPath)) {\n for (const raw of readFileSync(envPath, 'utf8').split('\\n')) {\n const line = raw.trim()\n const m = /^([A-Z_][A-Z0-9_]*)=(.*)$/.exec(line)\n if (m) env[m[1]!] = m[2]!.trim().replace(/^[\"']|[\"']$/g, '')\n }\n }\n for (const k of ['LITELLM_API_KEY', 'LITELLM_MASTER_KEY', 'LITELLM_BASE_URL']) {\n if (process.env[k]) env[k] = process.env[k]!\n }\n const apiKey = env.LITELLM_API_KEY || env.LITELLM_MASTER_KEY\n const apiBase = (env.LITELLM_BASE_URL || 'http://127.0.0.1:4000/v1').replace(/\\/$/, '')\n if (!apiKey) throw new CliError('No LITELLM_API_KEY / LITELLM_MASTER_KEY in ~/litellm/.env or env.')\n return { apiBase, apiKey, model: model || process.env.APE_CHAT_BRIDGE_MODEL || 'claude-haiku-4-5' }\n}\n\nfunction readPersona(file?: string): string {\n if (file && existsSync(file)) return readFileSync(file, 'utf8')\n const agentJson = join(homedir(), '.openape', 'agent', 'agent.json')\n if (existsSync(agentJson)) {\n try {\n const p = JSON.parse(readFileSync(agentJson, 'utf8')) as { systemPrompt?: string }\n if (p.systemPrompt?.trim()) return p.systemPrompt\n }\n catch { /* fall through */ }\n }\n return DEFAULT_PERSONA\n}\n\nasync function fetchIssue(forge: Forge, ref: string, repo: string): Promise<IssueRef> {\n // Pass repo explicitly: fetchIssue runs before the clone, so the CWD is\n // not the target repo and `gh issue view` would otherwise fail.\n const res = await runApeShell(buildIssueGet(forge, ref, repo))\n if (res.exit_code !== 0) throw new CliError(`could not fetch issue ${ref}: ${(res.stderr || res.stdout).slice(0, 200)}`)\n const j = JSON.parse(res.stdout) as { number?: number, id?: number, title?: string, fields?: { 'System.Title'?: string }, body?: string }\n const number = j.number ?? j.id ?? Number(ref)\n const title = j.title ?? j.fields?.['System.Title'] ?? `issue ${ref}`\n return { number, title, body: j.body }\n}\n\nexport const codeAgentCommand = defineCommand({\n meta: {\n name: 'code',\n description: 'Run a coding task: issue to worktree to edit to verify to PR (policy-gated merge). The agent never self-merges.',\n },\n args: {\n 'issue': { type: 'string', description: 'Issue / work-item ref to work on.' },\n 'repo': { type: 'string', description: 'Git remote URL of the target repo.', required: true },\n 'forge': { type: 'string', description: 'github | azure | registered forge. Auto-detected from --repo if omitted.' },\n 'model': { type: 'string', description: 'Override LLM model.' },\n 'max-steps': { type: 'string', description: 'Max tool-call rounds (default 40).' },\n 'persona-file': { type: 'string', description: 'File with the agent persona/system prompt.' },\n 'poll-label': { type: 'string', description: 'Poll mode: work all open issues with this label.' },\n },\n async run({ args }) {\n const repo = args.repo as string\n const forge: Forge = (args.forge as string) || detectForge(repo)\n\n // Inject sealed capability secrets (e.g. GH_TOKEN / AZ_PAT) into this\n // process's env so the forge CLIs we shell out to are authenticated.\n // The cron-runner invokes us as the agent user, so the blobs + the\n // X25519 key in ~/.config/openape are readable. Best-effort: no key /\n // no blobs just means nothing to inject. Without this, `gh` runs\n // unauthenticated and silently returns an empty issue list.\n try {\n const { applied } = materializeSecrets()\n if (applied.length > 0) consola.info(`Capabilities available: ${applied.join(', ')}`)\n }\n catch { /* no secrets to materialize */ }\n const config = readLitellmConfig(args.model as string | undefined)\n const persona = readPersona(args['persona-file'] as string | undefined)\n const maxSteps = Number(args['max-steps']) > 0 ? Number(args['max-steps']) : 40\n const tools = taskTools(CODING_TOOLS)\n\n const deps = {\n runtimeConfig: config,\n tools,\n persona,\n maxSteps,\n resolvePolicy: (worktree: string) => resolveMergePolicy(worktree),\n reviewer: createLlmReviewer(config),\n riskAssessor: createLlmRiskAssessor(config),\n log: (l: string) => consola.info(l),\n }\n\n // Determine the issue list (single or poll).\n const refs: string[] = []\n if (args['poll-label']) {\n const slug = repo.replace(/^https:\\/\\/github\\.com\\//, '').replace(/\\.git$/, '')\n const list = await runApeShell(`gh issue list --repo ${slug} --label '${args['poll-label']}' --state open --json number --jq '.[].number'`)\n if (list.exit_code !== 0) {\n throw new CliError(`gh issue list failed (exit ${list.exit_code}): ${(list.stderr || list.stdout).slice(0, 300)}`)\n }\n // `gh` exits 0 with empty stdout when it is unauthenticated, which\n // would otherwise look identical to \"no matching issues\". Detect that\n // explicitly so a missing GH_TOKEN is a loud error, not a silent no-op.\n if (list.stdout.trim() === '' && /gh auth login|GH_TOKEN/i.test(list.stderr)) {\n throw new CliError('gh is not authenticated (no GH_TOKEN). The agent\\'s GH_TOKEN capability is not materialized — bind it via the deploy/secrets flow.')\n }\n // Keep only numeric issue ids — defensive against any stray line.\n refs.push(...list.stdout.split('\\n').map(s => s.trim()).filter(s => /^\\d+$/.test(s)))\n if (refs.length === 0) { consola.info('no open issues with that label'); return }\n }\n else if (args.issue) {\n refs.push(args.issue as string)\n }\n else {\n throw new CliError('provide --issue <ref> or --poll-label <label>')\n }\n\n for (const ref of refs) {\n const issue = await fetchIssue(forge, ref, repo)\n consola.start(`coding issue #${issue.number}: ${issue.title}`)\n const result = await runCodingTask({ issue, repo, forge }, deps)\n consola.box(`#${issue.number} -> ${result.outcome}\\nPR: ${result.prRef ?? '(none)'}\\n${result.reason}`)\n }\n },\n})\n","import type { SealedBox } from '@openape/core'\nimport { existsSync, readdirSync, readFileSync, watch } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { openString } from '@openape/core'\n\n// Agent-side of the capability broker. troop seals a secret to this\n// agent's X25519 pubkey (M2a/M2c); nest drops the opaque blob into\n// ~/.config/openape/secrets.d/<ENV>.blob (M2d). Here the agent — the\n// ONLY place plaintext exists — opens it with its private key and\n// injects it into process.env so its tools (bash etc.) see it. Revoke\n// = blob removed → the env var is dropped on the next materialize.\n// See plans.openape.ai 01KRTAE8 (M2e).\n\nconst CONFIG_DIR = join(homedir(), '.config', 'openape')\nexport const SECRETS_DIR = join(CONFIG_DIR, 'secrets.d')\nexport const X25519_KEY_PATH = join(CONFIG_DIR, 'agent-x25519.key')\n// Public half written alongside the private key at spawn (agent-bootstrap).\n// Reported to troop on sync so the capability broker can seal secrets to it.\nexport const X25519_PUBKEY_PATH = `${X25519_KEY_PATH}.pub`\n\nfunction envNameFromFile(file: string): string | null {\n if (!file.endsWith('.blob')) return null\n const env = file.slice(0, -'.blob'.length)\n return /^[A-Z][A-Z0-9_]*$/.test(env) ? env : null\n}\n\nexport function readAgentEncryptionKey(keyPath = X25519_KEY_PATH): string | null {\n if (!existsSync(keyPath)) return null\n const k = readFileSync(keyPath, 'utf8').trim()\n return k.length > 0 ? k : null\n}\n\nexport function readAgentEncryptionPublicKey(pubPath = X25519_PUBKEY_PATH): string | null {\n if (!existsSync(pubPath)) return null\n const k = readFileSync(pubPath, 'utf8').trim()\n return k.length > 0 ? k : null\n}\n\nexport interface MaterializeOptions {\n dir?: string\n keyPath?: string\n /** Target env map (defaults to process.env). Injected in tests. */\n env?: NodeJS.ProcessEnv\n /** Env names applied by a previous materialize, to drop on revoke. */\n previouslyApplied?: Iterable<string>\n log?: (line: string) => void\n}\n\nexport interface MaterializeResult {\n applied: string[]\n failed: string[]\n}\n\n/**\n * Open every sealed blob in the secrets dir and set the corresponding\n * env var. Any env that was applied before but whose blob is now gone\n * (revoke) is deleted. Best-effort per blob — a corrupt/foreign blob\n * is logged and skipped, never throws.\n */\nexport function materializeSecrets(opts: MaterializeOptions = {}): MaterializeResult {\n const dir = opts.dir ?? SECRETS_DIR\n const env = opts.env ?? process.env\n const log = opts.log ?? (() => {})\n const applied: string[] = []\n const failed: string[] = []\n\n const key = readAgentEncryptionKey(opts.keyPath)\n const files = key && existsSync(dir) ? readdirSync(dir) : []\n\n for (const file of files) {\n const name = envNameFromFile(file)\n if (!name) continue\n try {\n const box = JSON.parse(readFileSync(join(dir, file), 'utf8')) as SealedBox\n env[name] = openString(box, key!)\n applied.push(name)\n }\n catch (e) {\n failed.push(file)\n log(`secrets: failed to open ${file}: ${(e as Error).message}`)\n }\n }\n\n // Revoke: env names we set last time but that have no blob now.\n const live = new Set(applied)\n for (const prev of opts.previouslyApplied ?? []) {\n if (!live.has(prev)) {\n delete env[prev]\n log(`secrets: revoked ${prev}`)\n }\n }\n\n return { applied, failed }\n}\n\n/**\n * Materialize once, then fs.watch the secrets dir and re-materialize\n * on any change (rotate/revoke take effect live — the user's M2 v1\n * choice). Returns a stop function. Safe to call when the dir doesn't\n * exist yet (watch attaches once it appears on the next agent start).\n */\nexport function startSecretsWatcher(opts: MaterializeOptions = {}): () => void {\n const dir = opts.dir ?? SECRETS_DIR\n const log = opts.log ?? (() => {})\n let appliedNames = new Set<string>()\n\n const run = () => {\n const r = materializeSecrets({ ...opts, previouslyApplied: appliedNames })\n appliedNames = new Set(r.applied)\n }\n\n run()\n if (!existsSync(dir)) return () => {}\n\n let timer: NodeJS.Timeout | null = null\n const watcher = watch(dir, () => {\n // Debounce — a single rotate is several fs events (create, write).\n if (timer) clearTimeout(timer)\n timer = setTimeout(run, 150)\n })\n watcher.on('error', err => log(`secrets: watcher error: ${err.message}`))\n\n return () => {\n if (timer) clearTimeout(timer)\n watcher.close()\n }\n}\n","// Issue → task mapping (M4). Pure helpers that turn a fetched issue /\n// work-item into the branch name + run prompt the coding loop uses.\n//\n// Neither the branch convention nor the prompt/persona is hard-coded\n// policy: the branch name is a configurable TEMPLATE and the prompt is\n// composed from a recipe-supplied PERSONA. The fallbacks are neutral\n// (overridable), not team-specific opinions baked into the library.\n\nexport interface IssueRef {\n number: number | string\n title: string\n body?: string\n // 'fix' | 'feat' | 'chore' … used by the {type} placeholder.\n type?: string\n}\n\nexport interface BranchNaming {\n // Template with {type} {number} {slug} placeholders. Repo/recipe-\n // supplied; the fallback is a neutral convention, not a mandate.\n template?: string\n // Fallback type when the issue carries none.\n defaultType?: string\n // Max slug length (forge/CI branch-length limits vary).\n slugMax?: number\n}\n\nexport interface TaskFraming {\n // The agent's persona/instructions from its recipe — prepended so the\n // task prompt reflects THIS agent, not a hard-coded English script.\n persona?: string\n // Override the default closing instructions entirely.\n instructions?: string\n}\n\nconst DEFAULT_TEMPLATE = '{type}/issue-{number}-{slug}'\nconst DEFAULT_TYPE = 'fix'\nconst DEFAULT_SLUG_MAX = 48\n\n// Minimal, provider-neutral closing instructions. Overridable via\n// TaskFraming.instructions; the recipe persona carries the real voice.\nconst DEFAULT_INSTRUCTIONS = [\n 'Work in the provided worktree. When done:',\n '- ensure the verification command passes (no PR on red)',\n '- open a PR that references this issue',\n '- leave risk-path / agent-judged-risky changes for human approval',\n].join('\\n')\n\nconst TYPE_RE = /^[a-z]{2,12}$/\n\nexport function slugify(title: string, max: number = DEFAULT_SLUG_MAX): string {\n return title\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/[\\s_]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, max)\n .replace(/-$/, '')\n}\n\nexport function buildBranchName(issue: IssueRef, naming: BranchNaming = {}): string {\n const num = String(issue.number).replace(/\\D/g, '')\n if (!num) throw new Error('issue number required')\n const type = issue.type && TYPE_RE.test(issue.type)\n ? issue.type\n : (naming.defaultType ?? DEFAULT_TYPE)\n const slug = slugify(issue.title, naming.slugMax ?? DEFAULT_SLUG_MAX) || 'task'\n return (naming.template ?? DEFAULT_TEMPLATE)\n .replace(/\\{type\\}/g, type)\n .replace(/\\{number\\}/g, num)\n .replace(/\\{slug\\}/g, slug)\n}\n\nexport function buildTaskPrompt(issue: IssueRef, framing: TaskFraming = {}): string {\n const num = String(issue.number)\n const parts: string[] = []\n if (framing.persona?.trim()) parts.push(framing.persona.trim())\n parts.push(`Issue #${num}: ${issue.title}`)\n parts.push(issue.body?.trim() ? issue.body.trim() : '(no description provided)')\n parts.push(framing.instructions?.trim() ? framing.instructions.trim() : DEFAULT_INSTRUCTIONS)\n return parts.join('\\n\\n')\n}\n","// Merge policy (M5): classify a PR's changed files and decide how it\n// may be merged, per the B+C-Overlay policy:\n// - chore → auto-merge on green CI\n// - code → auto-merge after reviewer-agent approval\n// - risk → human approval required, never auto\n//\n// IMPORTANT: this library hard-codes ZERO risk knowledge — no example\n// paths, no `auth`/`proxy`/`migrations` opinions, nothing. A change is\n// \"risk\" only when one of these says so:\n// 1. the AGENT judges it risky (semantic — catches what no glob can),\n// 2. the repo's own config declares it (`.openape/coding.json`),\n// 3. it's derived from signals the repo already has (deploy-workflow\n// `paths:` filters, CODEOWNERS — see derive-policy.ts).\n// The `riskPaths`/`autoPaths` globs are repo-supplied config, never\n// shipped defaults. Hand-maintained parallel lists rot; baked-in lists\n// are worse (wrong for every repo but ours).\n//\n// Secure by default: `autoMergeEnabled` is false → nothing auto-merges\n// until a repo opts in. Auto-merge is opt-in, declared per-repo.\n//\n// Pure + unit-tested. CI-green is enforced server-side by branch\n// protection; this layer only governs whether the agent may ARM the\n// merge and which review/human gate applies.\n\nexport type ChangeClass = 'chore' | 'code' | 'risk'\n\nexport interface MergePolicy {\n // Master switch. False (default) = secure: never auto-merge, every\n // change is handed to a human until the repo opts in.\n autoMergeEnabled: boolean\n // Repo-supplied globs marking low-risk chore paths (auto-merge candidate).\n autoPaths: string[]\n // Repo-supplied + derived globs marking risk paths. NOT a shipped\n // default — empty unless the repo declares them or they're derived.\n riskPaths: string[]\n}\n\n// The agent's own semantic risk judgment on a diff. Injected by the\n// orchestration (LLM-backed); pure decision code just consumes the\n// boolean. This is the PRIMARY risk source — globs are the fallback.\nexport interface AgentRiskAssessment {\n risky: boolean\n reason?: string\n}\n\nexport type RiskAssessorFn = (input: { paths: string[], diff: string }) => Promise<AgentRiskAssessment>\n\n// Secure fallback used when a repo has no `.openape/coding.json`. No\n// path opinions; auto-merge disabled.\nexport const SECURE_DEFAULT_POLICY: MergePolicy = {\n autoMergeEnabled: false,\n autoPaths: [],\n riskPaths: [],\n}\n\n// Minimal glob → RegExp. Supports `**` (any chars incl. `/`), `*` (any\n// chars except `/`), and `?` (single non-`/`). Everything else literal.\nexport function globToRegExp(glob: string): RegExp {\n let re = ''\n for (let i = 0; i < glob.length; i++) {\n const c = glob[i]!\n if (c === '*') {\n if (glob[i + 1] === '*') {\n re += '.*'\n i++\n // consume an immediately following slash so `**/x` also matches `x`\n if (glob[i + 1] === '/') i++\n }\n else {\n re += '[^/]*'\n }\n }\n else if (c === '?') {\n re += '[^/]'\n }\n else if ('.+^${}()|[]\\\\'.includes(c)) {\n re += `\\\\${c}`\n }\n else {\n re += c\n }\n }\n return new RegExp(`^${re}$`)\n}\n\nexport function matchesAny(path: string, globs: string[]): boolean {\n return globs.some(g => globToRegExp(g).test(path))\n}\n\n// Classify a set of changed file paths (repo-relative).\n// - any risk-path match → 'risk'\n// - else all paths are auto-paths → 'chore'\n// - else → 'code'\nexport function classifyChange(paths: string[], policy: MergePolicy = SECURE_DEFAULT_POLICY): ChangeClass {\n if (paths.length === 0) return 'code' // empty/unknown diff is treated conservatively\n if (paths.some(p => matchesAny(p, policy.riskPaths))) return 'risk'\n if (policy.autoPaths.length > 0 && paths.every(p => matchesAny(p, policy.autoPaths))) return 'chore'\n return 'code'\n}\n\nexport interface MergeDecision {\n classification: ChangeClass\n // May the agent arm a merge at all (CI-green still enforced by branch protection)?\n autoMerge: boolean\n // Does a reviewer-agent approval gate the auto-merge?\n needsReview: boolean\n // Must a human approve (agent only opens the PR, then stops)?\n needsHuman: boolean\n reason: string\n}\n\n// Decide how a PR may be merged. Risk comes from EITHER the agent's\n// semantic judgment (`agentRisk`, the primary source) OR the repo's\n// config/derived globs — whichever flags risk wins. The library itself\n// contributes no risk opinion.\nexport function decideMerge(\n paths: string[],\n policy: MergePolicy = SECURE_DEFAULT_POLICY,\n agentRisk?: AgentRiskAssessment,\n): MergeDecision {\n const globClass = classifyChange(paths, policy)\n // Effective risk = repo/derived globs OR the agent's judgment.\n const isRisk = globClass === 'risk' || agentRisk?.risky === true\n const classification: ChangeClass = isRisk ? 'risk' : globClass\n\n // Master switch off → secure default: nothing auto-merges, hand to a\n // human. The repo must opt in via `.openape/coding.json`.\n if (!policy.autoMergeEnabled) {\n return { classification, autoMerge: false, needsReview: false, needsHuman: true, reason: 'auto-merge not enabled for this repo — human approval required (set autoMergeEnabled in .openape/coding.json to opt in)' }\n }\n if (isRisk) {\n const why = agentRisk?.risky\n ? `agent judged this risky${agentRisk.reason ? `: ${agentRisk.reason}` : ''}`\n : 'matches a repo/derived risk path'\n return { classification, autoMerge: false, needsReview: false, needsHuman: true, reason: `${why} — human approval required` }\n }\n if (classification === 'chore') {\n return { classification, autoMerge: true, needsReview: false, needsHuman: false, reason: 'chore/docs only — auto-merge on green CI' }\n }\n return { classification, autoMerge: true, needsReview: true, needsHuman: false, reason: 'code change — auto-merge after reviewer-agent approval' }\n}\n\n// Load the merge policy for a worktree from `<dir>/.openape/coding.json`\n// (the `mergePolicy` key). Missing/invalid → secure default. This keeps\n// the policy with the repo it governs, never in this package. A future\n// step derives sensible globs from existing signals (deploy-workflow\n// `paths:` filters, CODEOWNERS) when the file is absent — see plan.\nexport async function loadMergePolicy(worktreeDir: string): Promise<MergePolicy> {\n const { readFile } = await import('node:fs/promises')\n const { join } = await import('node:path')\n try {\n const raw = await readFile(join(worktreeDir, '.openape', 'coding.json'), 'utf8')\n const parsed = JSON.parse(raw) as { mergePolicy?: Partial<MergePolicy> }\n const mp = parsed.mergePolicy\n if (!mp) return SECURE_DEFAULT_POLICY\n return {\n autoMergeEnabled: mp.autoMergeEnabled === true,\n autoPaths: Array.isArray(mp.autoPaths) ? mp.autoPaths.filter(g => typeof g === 'string') : [],\n riskPaths: Array.isArray(mp.riskPaths) ? mp.riskPaths.filter(g => typeof g === 'string') : [],\n }\n }\n catch {\n return SECURE_DEFAULT_POLICY\n }\n}\n","// Reviewer-agent gate (M7). Sits between \"verify passed\" and \"arm the\n// merge\". For code-class changes a second agent reviews the diff and\n// must approve; risk-class changes never auto-merge (human only);\n// chore-class skips review.\n//\n// The actual reviewer-agent dispatch is injected as a `ReviewerFn` so\n// this module stays pure + testable and the heavy second-agent spawn\n// lives in the integration layer.\n\nimport type { MergeDecision } from './merge-policy'\n\nexport interface ReviewVerdict {\n approved: boolean\n reason?: string\n}\n\nexport interface ReviewRequest {\n prRef: string | number\n diff: string\n classification: MergeDecision['classification']\n}\n\nexport type ReviewerFn = (req: ReviewRequest) => Promise<ReviewVerdict>\n\nexport interface GateOutcome {\n // May the agent now arm the (auto-)merge?\n armMerge: boolean\n // Did we stop and hand off to a human?\n awaitingHuman: boolean\n reason: string\n}\n\n// Decide + (when needed) run the reviewer. Branch protection still\n// enforces CI-green server-side regardless of this outcome.\nexport async function gateMerge(\n decision: MergeDecision,\n req: Omit<ReviewRequest, 'classification'>,\n reviewer: ReviewerFn,\n): Promise<GateOutcome> {\n if (decision.needsHuman) {\n return { armMerge: false, awaitingHuman: true, reason: 'risk-path change — handed off to human reviewer' }\n }\n if (!decision.needsReview) {\n // chore/docs — straight to arm-merge (CI still gates server-side).\n return { armMerge: true, awaitingHuman: false, reason: 'chore change — no reviewer gate' }\n }\n // code — require reviewer-agent approval.\n const verdict = await reviewer({ ...req, classification: decision.classification })\n if (verdict.approved) {\n return { armMerge: true, awaitingHuman: false, reason: `reviewer approved${verdict.reason ? `: ${verdict.reason}` : ''}` }\n }\n return { armMerge: false, awaitingHuman: false, reason: `reviewer blocked${verdict.reason ? `: ${verdict.reason}` : ''}` }\n}\n","// Coding-task orchestrator (INT-1). Ties the M1–M7 pieces into one run:\n// issue → worktree → LLM coding loop → verify → PR → merge gate.\n//\n// Division of responsibility (deliberate):\n// - The LLM does the CODING (edit files, run the verify command). It\n// gets file.* / bash / verify tools — NOT forge.pr.merge. Even if it\n// shells `gh pr merge`, that's a high-risk grant the agent doesn't\n// hold a YOLO scope for, so it can't self-merge.\n// - The ORCHESTRATOR owns everything policy-critical: branch + worktree\n// lifecycle, opening the PR, classifying the diff, running the risk\n// assessor + reviewer gate, and arming the merge. The LLM never\n// decides whether to merge.\n//\n// All I/O (shell, runLoop, reviewer, riskAssessor) is injected so the\n// orchestration is unit-testable without a live LLM or git.\n\nimport type { ToolDefinition } from '../agent-tools'\nimport type { RunOptions, RunResult, RuntimeConfig } from '../agent-runtime'\nimport { runLoop } from '../agent-runtime'\nimport { runApeShell } from '../agent-tools/ape-shell-exec'\nimport { buildCreateCommand, worktreePathFor } from '../agent-tools/git-worktree'\nimport { buildPrCreate, buildPrMerge } from './forge'\nimport type { Forge } from './forge'\nimport type { IssueRef, BranchNaming } from './issue-task'\nimport { buildBranchName, buildTaskPrompt } from './issue-task'\nimport { decideMerge, SECURE_DEFAULT_POLICY } from './merge-policy'\nimport type { MergeDecision, MergePolicy, RiskAssessorFn } from './merge-policy'\nimport { gateMerge } from './review-gate'\nimport type { ReviewerFn } from './review-gate'\n\nconst DIFF_CAP = 60 * 1024\n\nexport interface ShellResult { stdout: string, stderr: string, exit_code: number }\nexport type ShellFn = (cmd: string, timeoutMs?: number) => Promise<ShellResult>\n\nexport interface CodingTaskInput {\n issue: IssueRef\n repo: string // URL or $HOME path\n forge: Forge\n}\n\nexport interface CodingTaskDeps {\n runtimeConfig: RuntimeConfig\n // Coding tools given to the LLM (file.*, bash, verify, …) — must NOT\n // include forge.pr.merge.\n tools: ToolDefinition[]\n persona: string\n maxSteps: number\n // Static policy, OR resolvePolicy to load it from the cloned worktree\n // (e.g. the repo's .openape/coding.json + derived signals). When both\n // are absent the secure default applies (auto-merge off).\n policy?: MergePolicy\n resolvePolicy?: (worktree: string) => Promise<MergePolicy>\n reviewer: ReviewerFn\n riskAssessor: RiskAssessorFn\n branchNaming?: BranchNaming\n // Merge strategy + auto behaviour for the PR the orchestrator opens.\n squash?: boolean\n // Injected I/O (defaults wired to production impls).\n shell?: ShellFn\n runLoopImpl?: (opts: RunOptions) => Promise<RunResult>\n log?: (line: string) => void\n}\n\nexport type MergeOutcome = 'auto-armed' | 'awaiting-human' | 'reviewer-blocked' | 'run-failed'\n\nexport interface CodingTaskResult {\n branch: string\n worktree: string\n runStatus: 'ok' | 'error'\n changedFiles: string[]\n decision?: MergeDecision\n outcome: MergeOutcome\n prRef?: string\n reason: string\n}\n\nfunction taskIdFromIssue(issue: IssueRef): string {\n const num = String(issue.number).replace(/\\D/g, '')\n return `issue-${num || 'x'}`\n}\n\nexport async function runCodingTask(input: CodingTaskInput, deps: CodingTaskDeps): Promise<CodingTaskResult> {\n const shell = deps.shell ?? (async (cmd, t) => {\n const r = await runApeShell(cmd, t)\n return { stdout: r.stdout, stderr: r.stderr, exit_code: r.exit_code }\n })\n const loop = deps.runLoopImpl ?? runLoop\n const log = deps.log ?? (() => {})\n\n const branch = buildBranchName(input.issue, deps.branchNaming)\n const taskId = taskIdFromIssue(input.issue)\n const worktree = worktreePathFor(taskId)\n\n // 1. Orchestrator creates the isolated worktree (deterministic path).\n log(`[coding] creating worktree ${worktree} on ${branch}`)\n const wt = await shell(buildCreateCommand(input.repo, taskId, branch))\n if (wt.exit_code !== 0) {\n return { branch, worktree, runStatus: 'error', changedFiles: [], outcome: 'run-failed', reason: `worktree create failed: ${wt.stderr.slice(0, 300)}` }\n }\n\n // Resolve the merge policy from the cloned repo (config + derived\n // signals), or use the static one, or the secure default.\n const policy = deps.resolvePolicy\n ? await deps.resolvePolicy(worktree)\n : (deps.policy ?? SECURE_DEFAULT_POLICY)\n\n // 2. LLM does the coding (it has file.*/bash/verify; NOT pr.merge).\n const prompt = buildTaskPrompt(input.issue, { persona: deps.persona })\n const run = await loop({\n config: deps.runtimeConfig,\n systemPrompt: deps.persona,\n userMessage: `${prompt}\\n\\nWorktree: ${worktree}`,\n tools: deps.tools,\n maxSteps: deps.maxSteps,\n })\n if (run.status !== 'ok') {\n return { branch, worktree, runStatus: 'error', changedFiles: [], outcome: 'run-failed', reason: `coding loop errored after ${run.stepCount} steps` }\n }\n\n // 3. Determine the actual diff (orchestrator, not the LLM's word).\n const namesRes = await shell(`git -C '${worktree}' add -A && git -C '${worktree}' diff --cached --name-only`)\n const changedFiles = namesRes.stdout.split('\\n').map(s => s.trim()).filter(Boolean)\n if (changedFiles.length === 0) {\n return { branch, worktree, runStatus: 'ok', changedFiles: [], outcome: 'run-failed', reason: 'no changes produced — nothing to PR' }\n }\n const diffRes = await shell(`git -C '${worktree}' diff --cached`)\n const diff = diffRes.stdout.slice(0, DIFF_CAP)\n\n // 4. Risk + merge decision (agent judgment ∪ config/derived).\n const agentRisk = await deps.riskAssessor({ paths: changedFiles, diff })\n const decision = decideMerge(changedFiles, policy, agentRisk)\n log(`[coding] decision=${decision.classification} (${decision.reason})`)\n\n // 5. Commit + push + open the PR (orchestrator owns this).\n await shell(`git -C '${worktree}' commit -m ${shqMsg(input.issue)} && git -C '${worktree}' push -u origin '${branch}'`)\n const prCmd = buildPrCreate({ forge: input.forge, title: prTitle(input.issue), body: prBody(input.issue), head: branch })\n const prRes = await shell(`cd '${worktree}' && ${prCmd}`)\n const prRef = (prRes.stdout.match(/\\/pull\\/(\\d+)|!(\\d+)|\\bpr\\/(\\d+)/i)?.slice(1).find(Boolean)) ?? branch\n\n // 6. Merge gate. Human/risk → stop. Code → reviewer. Chore → arm.\n if (decision.needsHuman) {\n return { branch, worktree, runStatus: 'ok', changedFiles, decision, outcome: 'awaiting-human', prRef, reason: decision.reason }\n }\n const gate = await gateMerge(decision, { prRef, diff }, deps.reviewer)\n if (!gate.armMerge) {\n return { branch, worktree, runStatus: 'ok', changedFiles, decision, outcome: 'reviewer-blocked', prRef, reason: gate.reason }\n }\n // Arm merge-when-green (never bypasses required checks — branch protection).\n const mergeCmd = buildPrMerge({ forge: input.forge, ref: prRef, auto: true, squash: deps.squash, deleteBranch: true })\n await shell(`cd '${worktree}' && ${mergeCmd}`)\n return { branch, worktree, runStatus: 'ok', changedFiles, decision, outcome: 'auto-armed', prRef, reason: gate.reason }\n}\n\n// Local helpers (kept here so the file is self-contained).\nfunction prTitle(issue: IssueRef): string {\n return `${issue.type ?? 'fix'}: ${issue.title} (#${String(issue.number).replace(/\\D/g, '')})`\n}\nfunction prBody(issue: IssueRef): string {\n return `Resolves #${String(issue.number).replace(/\\D/g, '')}.\\n\\nAutomated by the OpenApe coding agent.`\n}\nfunction shqMsg(issue: IssueRef): string {\n return `'${prTitle(issue).replace(/'/g, '\\'\\\\\\'\\'')}'`\n}\n","// LLM-backed risk assessor + reviewer (INT-2). These satisfy the\n// injected `RiskAssessorFn` / `ReviewerFn` interfaces with real model\n// calls, so the coding loop's \"is this risky?\" and \"approve this diff?\"\n// decisions are semantic, not glob-only.\n//\n// Fail-safe: if the model errors or returns unparseable output, the\n// assessor treats the change as RISKY and the reviewer BLOCKS — unsure\n// always degrades toward human/no-merge, never toward silent auto-merge.\n\nimport type { RuntimeConfig } from '../agent-runtime'\nimport type { AgentRiskAssessment, RiskAssessorFn } from './merge-policy'\nimport type { ReviewerFn, ReviewVerdict } from './review-gate'\n\nconst DIFF_CAP = 48 * 1024\n\nasync function jsonCompletion(\n config: RuntimeConfig,\n system: string,\n user: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<Record<string, unknown> | null> {\n try {\n const res = await fetchImpl(`${config.apiBase}/chat/completions`, {\n method: 'POST',\n headers: { 'authorization': `Bearer ${config.apiKey}`, 'content-type': 'application/json' },\n body: JSON.stringify({\n model: config.model,\n messages: [{ role: 'system', content: system }, { role: 'user', content: user }],\n response_format: { type: 'json_object' },\n }),\n })\n if (!res.ok) return null\n const data = await res.json() as { choices?: { message?: { content?: string } }[] }\n const content = data.choices?.[0]?.message?.content\n if (!content) return null\n return JSON.parse(content) as Record<string, unknown>\n }\n catch {\n return null\n }\n}\n\nconst RISK_SYSTEM = [\n 'You are a security/risk classifier for an autonomous coding agent.',\n 'Given a diff + changed file paths, decide whether merging it WITHOUT a human is risky.',\n 'Risky = touches authentication, authorization, secrets/credentials, payment, data migrations,',\n 'deploy/release/CI config, cryptography, deletion of data, or anything whose failure is hard to',\n 'reverse in production. Routine code/tests/docs/refactors are NOT risky.',\n 'Respond ONLY as JSON: {\"risky\": boolean, \"reason\": string}.',\n].join(' ')\n\nexport function createLlmRiskAssessor(config: RuntimeConfig, fetchImpl?: typeof fetch): RiskAssessorFn {\n return async ({ paths, diff }): Promise<AgentRiskAssessment> => {\n const user = `Changed files:\\n${paths.join('\\n')}\\n\\nDiff (truncated):\\n${diff.slice(0, DIFF_CAP)}`\n const out = await jsonCompletion(config, RISK_SYSTEM, user, fetchImpl)\n if (!out || typeof out.risky !== 'boolean') {\n return { risky: true, reason: 'risk classifier unavailable/unparseable — treating as risky (fail-safe)' }\n }\n return { risky: out.risky, reason: typeof out.reason === 'string' ? out.reason : undefined }\n }\n}\n\nconst REVIEW_SYSTEM = [\n 'You are a code reviewer for an autonomous coding agent.',\n 'Given a PR diff, decide whether it is correct, safe, and complete enough to auto-merge.',\n 'Approve only if you would be comfortable shipping it without further human review.',\n 'Block if you see bugs, missing tests, security issues, or incomplete work.',\n 'Respond ONLY as JSON: {\"approved\": boolean, \"reason\": string}.',\n].join(' ')\n\nexport function createLlmReviewer(config: RuntimeConfig, fetchImpl?: typeof fetch): ReviewerFn {\n return async ({ prRef, diff }): Promise<ReviewVerdict> => {\n const user = `PR ${String(prRef)} diff (truncated):\\n${diff.slice(0, DIFF_CAP)}`\n const out = await jsonCompletion(config, REVIEW_SYSTEM, user, fetchImpl)\n if (!out || typeof out.approved !== 'boolean') {\n return { approved: false, reason: 'reviewer unavailable/unparseable — blocking (fail-safe)' }\n }\n return { approved: out.approved, reason: typeof out.reason === 'string' ? out.reason : undefined }\n }\n}\n","// Derive risk paths from signals that ALREADY exist in the repo, so\n// nobody maintains a parallel list that rots (M5 follow-up):\n//\n// 1. Deploy-workflow `paths:` filters — the paths whose change ships\n// to prod ARE the real risk surface. You already maintain them.\n// 2. CODEOWNERS — paths with an owner mean \"someone must review\".\n//\n// These AUGMENT (never reduce) the repo's explicit riskPaths and never\n// flip `autoMergeEnabled` on — derivation only makes the risk\n// classification safer, it doesn't enable automation.\n//\n// Parsers are pure + unit-tested. No YAML dependency: we extract just\n// the `paths:` blocks we care about. File reads use node:fs/promises.\n\nimport type { MergePolicy } from './merge-policy'\nimport { loadMergePolicy, SECURE_DEFAULT_POLICY } from './merge-policy'\n\nfunction indentOf(line: string): number {\n return line.length - line.trimStart().length\n}\n\nfunction unquote(s: string): string {\n return s.trim().replace(/^['\"]|['\"]$/g, '').trim()\n}\n\n// Extract globs from `paths:` filters in a GitHub Actions workflow.\n// Handles both block lists and inline arrays. Ignores `paths-ignore:`\n// (that's the inverse of a risk filter).\nexport function extractWorkflowPaths(yamlText: string): string[] {\n const out: string[] = []\n const lines = yamlText.split('\\n')\n let inBlock = false\n let keyIndent = -1\n\n for (const line of lines) {\n if (inBlock) {\n const m = /^\\s*-\\s*(\\S.*)$/.exec(line)\n if (m && indentOf(line) > keyIndent) {\n out.push(unquote(m[1]!))\n continue\n }\n if (line.trim() !== '') inBlock = false // dedented / next key\n }\n // Inline array: `paths: ['a/**', \"b/**\"]`\n const inline = /^\\s*paths:\\s*\\[(.+)\\]\\s*$/.exec(line)\n if (inline) {\n for (const tok of inline[1]!.split(',')) {\n const g = unquote(tok)\n if (g) out.push(g)\n }\n continue\n }\n // Block form: `paths:` then `- glob` lines below.\n if (/^\\s*paths:\\s*$/.test(line)) {\n inBlock = true\n keyIndent = indentOf(line)\n }\n }\n return [...new Set(out)]\n}\n\n// Parse CODEOWNERS path patterns → our glob style. CODEOWNERS lines are\n// `pattern owner...`; we take the pattern. Leading `/` is repo-root\n// anchored (drop it); a trailing `/` means a directory (→ `**`).\nexport function parseCodeowners(text: string): string[] {\n const out: string[] = []\n for (const raw of text.split('\\n')) {\n const line = raw.trim()\n if (!line || line.startsWith('#')) continue\n const pattern = line.split(/\\s+/)[0]\n if (!pattern || pattern.startsWith('@')) continue\n let g = pattern.replace(/^\\//, '')\n if (g.endsWith('/')) g += '**'\n if (g) out.push(g)\n }\n return [...new Set(out)]\n}\n\n// Read the repo's deploy-workflow + CODEOWNERS signals and return the\n// union of derived risk globs. Best-effort: missing files → [].\nexport async function deriveRiskGlobs(worktreeDir: string): Promise<string[]> {\n const { readFile, readdir } = await import('node:fs/promises')\n const { join } = await import('node:path')\n const globs = new Set<string>()\n\n // 1. deploy-*.yml workflows\n try {\n const wfDir = join(worktreeDir, '.github', 'workflows')\n const files = await readdir(wfDir)\n for (const f of files) {\n if (!/deploy.*\\.ya?ml$/i.test(f)) continue\n try {\n const text = await readFile(join(wfDir, f), 'utf8')\n for (const g of extractWorkflowPaths(text)) globs.add(g)\n }\n catch { /* unreadable file — skip */ }\n }\n }\n catch { /* no workflows dir */ }\n\n // 2. CODEOWNERS (common locations)\n for (const loc of ['.github/CODEOWNERS', 'CODEOWNERS', 'docs/CODEOWNERS']) {\n try {\n const text = await readFile(join(worktreeDir, loc), 'utf8')\n for (const g of parseCodeowners(text)) globs.add(g)\n break\n }\n catch { /* try next */ }\n }\n\n return [...globs]\n}\n\n// The main entry the orchestration uses: explicit `.openape/coding.json`\n// policy, with risk paths AUGMENTED by derived signals. autoMergeEnabled\n// + autoPaths come solely from explicit config (derivation never enables\n// automation).\nexport async function resolveMergePolicy(worktreeDir: string): Promise<MergePolicy> {\n const explicit = await loadMergePolicy(worktreeDir).catch(() => SECURE_DEFAULT_POLICY)\n const derived = await deriveRiskGlobs(worktreeDir).catch(() => [])\n return {\n autoMergeEnabled: explicit.autoMergeEnabled,\n autoPaths: explicit.autoPaths,\n riskPaths: [...new Set([...explicit.riskPaths, ...derived])],\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs'\nimport { tmpdir, userInfo } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError, CliExit } from '../../errors'\nimport { apiFetch } from '../../http'\nimport { AGENT_NAME_REGEX, buildDestroyTeardownScript, runPhaseGTeardownInProcess } from '../../lib/agent-bootstrap'\nimport { isDarwin, lookupMacOSUserForAgent, macOSUsernameForAgent, whichBinary } from '../../lib/macos-user'\nimport { removeNestAgent } from '../../lib/nest-registry'\nimport { readPasswordSilent } from '../../lib/silent-password'\n\ninterface IdpUser {\n email: string\n name: string\n owner: string | null\n isActive: boolean\n}\n\nexport const destroyAgentCommand = defineCommand({\n meta: {\n name: 'destroy',\n description: 'Tear down an agent: remove macOS user, hard-delete IdP agent, drop all SSH keys',\n },\n args: {\n name: {\n type: 'positional',\n description: 'Agent name to destroy',\n required: true,\n },\n force: {\n type: 'boolean',\n description: 'Skip the interactive confirmation. Required for CI.',\n },\n soft: {\n type: 'boolean',\n description: 'Soft deactivate at the IdP (PATCH isActive=false) instead of hard-delete',\n },\n 'keep-os-user': {\n type: 'boolean',\n description: 'Skip OS-side teardown. Useful for CI where the agent has no OS user.',\n },\n 'root-stage': {\n type: 'boolean',\n description: 'Internal — 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.',\n },\n },\n async run({ args }) {\n const name = args.name as string\n if (!AGENT_NAME_REGEX.test(name)) {\n throw new CliError(\n `Invalid agent name \"${name}\". Must match /^[a-z][a-z0-9-]{0,23}$/.`,\n )\n }\n\n // Inner re-entry: this process IS root (escapes-setuid'd via the\n // outer `apes run --as root --`). Skip auth + IdP + prompts and\n // just do the privileged ops. The outer pass already removed the\n // IdP record and the nest-registry row by the time it called us.\n if (args['root-stage']) {\n if (process.geteuid?.() !== 0) {\n throw new CliError('--root-stage was passed but this process is not running as root. Refusing to continue.')\n }\n const resolved = lookupMacOSUserForAgent(name)\n const macOSUsername = resolved?.name ?? macOSUsernameForAgent(name)\n const homeDir = resolved?.homeDir ?? `/var/openape/homes/${macOSUsername}`\n consola.start(`Running teardown for ${name} (Phase-G, root-stage)…`)\n runPhaseGTeardownInProcess({ name, homeDir, macOSUsername })\n return\n }\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const owned = await apiFetch<IdpUser[]>('/api/my-agents', { idp })\n const idpAgent = owned.find(u => u.name === name)\n const idpExists = idpAgent !== undefined\n\n const osUser = isDarwin() ? lookupMacOSUserForAgent(name) : null\n const osUserExists = !args['keep-os-user'] && osUser !== null\n\n if (!idpExists && !osUserExists) {\n consola.info(`Nothing to destroy: no IdP agent and no OS user for \"${name}\".`)\n return\n }\n\n if (!args.force) {\n const consequences: string[] = []\n if (osUserExists) {\n const home = osUser?.homeDir ?? `/Users/${name}`\n consequences.push(`• Remove macOS user ${osUser?.name ?? name} and rm -rf ${home}`)\n }\n if (idpExists) {\n consequences.push(args.soft\n ? `• Deactivate IdP agent ${idpAgent!.email} (PATCH isActive=false)`\n : `• Hard-delete IdP agent ${idpAgent!.email} and all its SSH keys`)\n }\n consola.warn(`About to destroy \"${name}\":\\n${consequences.join('\\n')}`)\n // Without a TTY, consola.prompt would crash with `uv_tty_init returned\n // EINVAL` and leave the user with an opaque stack trace. Detect and\n // refuse with a clear hint instead — `--force` is the explicit\n // non-interactive path (CI, subprocess invocations, this script's\n // own caller when piped).\n if (!process.stdin.isTTY) {\n throw new CliError(\n 'No TTY available for the interactive confirmation. Re-run with --force '\n + 'to skip the prompt (this is the same flag CI uses).',\n )\n }\n const confirmed = await consola.prompt('Proceed?', { type: 'confirm', initial: false })\n if (typeof confirmed === 'symbol' || !confirmed) {\n throw new CliExit(0)\n }\n }\n\n // IdP-side first so the parent's bearer is still fresh. The sudo step\n // below blocks for the password prompt, which the user might take a\n // moment to complete — running the IdP DELETE after a stale-token\n // window would leave the agent record orphaned.\n if (idpExists) {\n const id = encodeURIComponent(idpAgent!.email)\n if (args.soft) {\n await apiFetch(`/api/my-agents/${id}`, { method: 'PATCH', body: { isActive: false }, idp })\n consola.success(`Deactivated IdP agent ${idpAgent!.email}`)\n }\n else {\n await apiFetch(`/api/my-agents/${id}`, { method: 'DELETE', idp })\n consola.success(`Deleted IdP agent ${idpAgent!.email}`)\n }\n }\n else {\n consola.info('No IdP agent to remove (skipped).')\n }\n\n if (osUserExists) {\n const macOSUsername = osUser?.name ?? macOSUsernameForAgent(name)\n // Fallback path depends on which dscl record we matched:\n // legacy bare-name records live under /Users/<name>, new\n // prefixed records under /var/openape/homes/<macOSUsername>.\n // The dscl record's NFSHomeDirectory is the source of truth\n // when present; the fallback only fires when it's missing\n // (mostly fixture-driven test paths).\n const fallbackHome = macOSUsername.startsWith('openape-agent-')\n ? `/var/openape/homes/${macOSUsername}`\n : `/Users/${macOSUsername}`\n const homeDir = osUser?.homeDir ?? fallbackHome\n const isPhaseG = homeDir.startsWith('/var/openape/homes/')\n\n if (isPhaseG) {\n // Phase G agents live under /var/openape/homes/ — root via\n // escapes can `rm -rf` the home (no FDA wall on /var/) and\n // bootout the user-domain launchd. The dscl record removal\n // still needs sysadminctl + admin password (escapes' setuid\n // context lacks an audit session, opendirectoryd rejects a\n // plain `dscl . -delete`), so we skip it: the user record\n // becomes a harmless tombstone — uid in the hidden range,\n // IsHidden=1, NFSHomeDirectory pointing at a path that no\n // longer exists. Operators can run `sudo sysadminctl\n // -deleteUser <name>` interactively later if they want full\n // cleanup.\n //\n // Re-enter ourselves as root via `apes run --as root --`\n // instead of writing+executing a temp bash script. The\n // resulting DDISA grant request reads\n // `apes agents destroy <name> --force --root-stage`\n // which is semantic + matches the existing nest YOLO pattern\n // `apes agents destroy *` for zero-prompt auto-approval.\n // The inner re-entry detects --root-stage and runs just the\n // Phase-G teardown ops via runPhaseGTeardownInProcess().\n if (process.geteuid?.() === 0) {\n // Already root (rare — `apes agents destroy` invoked from\n // inside a setuid-root context like a CI runner with\n // sudo). Do the teardown directly, no second escalation.\n consola.start('Running teardown (Phase G — already root, no grant needed)…')\n runPhaseGTeardownInProcess({ name, homeDir, macOSUsername })\n }\n else {\n consola.start('Running teardown (Phase G — no admin password needed)…')\n execFileSync('apes', [\n 'run', '--as', 'root', '--wait', '--',\n 'apes', 'agents', 'destroy', name, '--force', '--root-stage',\n ], { stdio: 'inherit' })\n }\n consola.info(`dscl record /Users/${macOSUsername} kept as tombstone (hidden, no home). Run \\`sudo apes agents cleanup-orphans\\` to sweep accumulated tombstones.`)\n }\n else {\n // Legacy path: home under /Users/, FDA-blocked. Need sudo\n // + admin password to invoke sysadminctl. If we're running\n // headless (no TTY, no APES_ADMIN_PASSWORD) — typical for the\n // troop-WS destroy path from the nest — degrade gracefully:\n // skip the OS-side teardown so the rest of the destroy still\n // proceeds (IdP de-register + nest-registry removal). The\n // dscl record + home dir become orphans; operator cleans up\n // later interactively with `apes agents destroy` from a shell.\n const sudo = whichBinary('sudo')\n if (!sudo) {\n throw new CliError('`sudo` not found on PATH; required for OS teardown.')\n }\n const adminUser = userInfo().username\n let adminPassword: string\n try {\n adminPassword = await collectAdminPassword({ adminUser })\n }\n catch (err) {\n const headless = !process.stdin.isTTY && !process.env.APES_ADMIN_PASSWORD\n if (headless) {\n consola.warn(`Legacy OS teardown for ${name} requires a TTY or APES_ADMIN_PASSWORD; skipping. Run \\`apes agents destroy ${name}\\` from a shell later to fully clean up /Users/${name} + dscl record.`)\n adminPassword = ''\n }\n else {\n throw err\n }\n }\n if (adminPassword) {\n const scratch = mkdtempSync(join(tmpdir(), `apes-destroy-${name}-`))\n const scriptPath = join(scratch, 'teardown.sh')\n try {\n const script = buildDestroyTeardownScript({ name, homeDir, adminUser })\n writeFileSync(scriptPath, script, { mode: 0o700 })\n consola.start('Running teardown via sudo…')\n execFileSync(sudo, ['-S', '--prompt=', '--', 'bash', scriptPath], {\n input: `${adminPassword}\\n${adminPassword}\\n`,\n stdio: ['pipe', 'inherit', 'inherit'],\n })\n }\n finally {\n rmSync(scratch, { recursive: true, force: true })\n }\n }\n }\n }\n else if (!args['keep-os-user'] && isDarwin()) {\n consola.info('No macOS user to remove (skipped).')\n }\n\n // Phase F: drop the entry from the Nest's registry. The Nest's\n // file-watcher reconciles its pm2-supervisor → bridge gets pm2-\n // deleted automatically.\n try { removeNestAgent(name) }\n catch (err) {\n consola.warn(`Could not update nest registry: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n consola.success(`Destroyed ${name}.`)\n },\n})\n\n/**\n * Resolve the local admin password used for sudo + `sysadminctl\n * -deleteUser`. Single secret, single prompt:\n *\n * 1. `APES_ADMIN_PASSWORD` env var (CI / orchestrators)\n * 2. Silent terminal prompt (raw-mode stdin, no echo, no mask)\n * 3. Refuse with a clear hint when neither is available\n */\nasync function collectAdminPassword(opts: { adminUser: string }): Promise<string> {\n const fromEnv = process.env.APES_ADMIN_PASSWORD\n if (fromEnv && fromEnv.length > 0) return fromEnv\n const pw = await readPasswordSilent(`Password for ${opts.adminUser}: `)\n if (pw.length === 0) {\n throw new CliExit(0)\n }\n return pw\n}\n","// Shared \"Nest registry\" helper — Phase F (#sim-arch) lets the\n// apes-cli read+write the Nest's `agents.json` directly instead of\n// going through an intent-channel handler in the Nest. The Nest\n// watches the file and reconciles its pm2-supervisor automatically.\n//\n// The registry is the source of truth for \"which agents live on\n// this computer\" — the Nest reads it at boot and after every fs\n// change, the apes-cli writes to it after every `apes agents\n// spawn|destroy`.\n//\n// Path: `/var/openape/nest/agents.json` (mode 660, owner\n// `_openape_nest:_openape_nest`). Patrick is in the\n// `_openape_nest` group post-`apes nest migrate-to-service-user`,\n// so he can rw the file directly. Pre-migration installs use\n// `~/.openape/nest/agents.json` under the human's home and don't\n// need the group dance — the file is plain Patrick-owned.\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport interface AgentEntry {\n name: string\n uid: number\n home: string\n email: string\n registeredAt: number\n bridge?: {\n baseUrl?: string\n apiKey?: string\n model?: string\n }\n}\n\ninterface RegistryFile {\n version: 1\n agents: AgentEntry[]\n}\n\n/** Resolve the registry path. Prefers the post-migration system\n * location; falls back to the per-user location otherwise. */\nexport function resolveRegistryPath(): string {\n if (existsSync('/var/openape/nest/agents.json')) return '/var/openape/nest/agents.json'\n if (existsSync('/var/openape/nest')) return '/var/openape/nest/agents.json'\n return join(homedir(), '.openape', 'nest', 'agents.json')\n}\n\nfunction emptyRegistry(): RegistryFile {\n return { version: 1, agents: [] }\n}\n\nexport function readNestRegistry(): RegistryFile {\n const path = resolveRegistryPath()\n if (!existsSync(path)) return emptyRegistry()\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as RegistryFile\n if (parsed?.version !== 1 || !Array.isArray(parsed.agents)) return emptyRegistry()\n return parsed\n }\n catch {\n return emptyRegistry()\n }\n}\n\nexport function writeNestRegistry(reg: RegistryFile): void {\n const path = resolveRegistryPath()\n const dir = path.replace(/\\/agents\\.json$/, '')\n try { mkdirSync(dir, { recursive: true }) }\n catch { /* may exist with stricter perms */ }\n writeFileSync(path, `${JSON.stringify(reg, null, 2)}\\n`, { mode: 0o660 })\n}\n\nexport function upsertNestAgent(entry: AgentEntry): void {\n const reg = readNestRegistry()\n const existing = reg.agents.findIndex(a => a.name === entry.name)\n if (existing >= 0) reg.agents[existing] = entry\n else reg.agents.push(entry)\n writeNestRegistry(reg)\n}\n\nexport function removeNestAgent(name: string): boolean {\n const reg = readNestRegistry()\n const before = reg.agents.length\n reg.agents = reg.agents.filter(a => a.name !== name)\n if (reg.agents.length === before) return false\n writeNestRegistry(reg)\n return true\n}\n","// Silent password input using raw-mode stdin. consola.prompt's `mask`\n// option is honoured by some terminals (iTerm, Terminal.app) but ignored\n// by others (Warp, some VT-emulator wrappers) — falling back to plain\n// echoed text. Native readline with raw mode + manual character handling\n// works uniformly: stdin is muted (no echo) and we render exactly what\n// the user has come to expect from `sudo` / `ssh-keygen -p` / etc — the\n// prompt label, no mask, just the trailing newline once Enter is hit.\n\nimport { CliError } from '../errors'\n\n/**\n * Prompt for a password without echoing keystrokes. Resolves with the\n * typed string (without trailing newline). Throws `CliError` on Ctrl-C\n * / Ctrl-D / non-TTY stdin.\n */\nexport function readPasswordSilent(prompt: string): Promise<string> {\n if (!process.stdin.isTTY) {\n return Promise.reject(new CliError(\n 'No TTY available for the silent password prompt. '\n + 'Set APES_ADMIN_PASSWORD in the environment instead.',\n ))\n }\n return new Promise<string>((resolve, reject) => {\n process.stdout.write(prompt)\n const wasRaw = process.stdin.isRaw ?? false\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.setEncoding('utf8')\n\n let buf = ''\n let cleanupFn: (() => void) | undefined\n const cleanup = () => cleanupFn?.()\n const onData = (chunk: string) => {\n for (const ch of chunk) {\n const code = ch.charCodeAt(0)\n if (ch === '\\r' || ch === '\\n') {\n cleanup()\n process.stdout.write('\\n')\n resolve(buf)\n return\n }\n if (code === 3) { // Ctrl-C\n cleanup()\n process.stdout.write('\\n')\n reject(new CliError('Aborted by user (Ctrl-C).'))\n return\n }\n if (code === 4 && buf.length === 0) { // Ctrl-D on empty\n cleanup()\n process.stdout.write('\\n')\n reject(new CliError('Aborted by user (Ctrl-D).'))\n return\n }\n if (code === 0x7F || code === 8) { // DEL / backspace\n if (buf.length > 0) buf = buf.slice(0, -1)\n continue\n }\n if (code < 32) continue // ignore other control chars\n buf += ch\n }\n }\n cleanupFn = () => {\n process.stdin.removeListener('data', onData)\n process.stdin.setRawMode(wasRaw)\n process.stdin.pause()\n }\n process.stdin.on('data', onData)\n })\n}\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport { apiFetch } from '../../http'\nimport { isDarwin, listMacOSUserNames, lookupMacOSUserForAgent, macOSUsernameForAgent } from '../../lib/macos-user'\n\ninterface IdpUser {\n email: string\n name: string\n owner: string | null\n approver: string | null\n type: string | null\n isActive: boolean\n createdAt: number\n}\n\nexport const listAgentsCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List agents owned by the current user, with local OS-user status',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n },\n 'include-inactive': {\n type: 'boolean',\n description: 'Include agents whose IdP record is deactivated (default hides them)',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const all = await apiFetch<IdpUser[]>('/api/my-agents', { idp })\n const filtered = args['include-inactive']\n ? all\n : all.filter(u => u.isActive !== false)\n\n const osUsers = isDarwin() ? listMacOSUserNames() : new Set<string>()\n // Resolve macOS state per agent, checking both the prefixed\n // (`openape-agent-<name>`) and bare (`<name>`) dscl records so\n // legacy pre-prefix agents keep showing up in the table.\n const osStateOf = (agentName: string): { osUser: boolean, home: string | null } => {\n const u = lookupMacOSUserForAgent(agentName)\n if (u) return { osUser: true, home: u.homeDir }\n // listMacOSUserNames covers ad-hoc records that dscl-read can't see\n // (e.g. names with unusual characters) — keep it as a sentinel.\n if (osUsers.has(macOSUsernameForAgent(agentName)) || osUsers.has(agentName)) {\n return { osUser: true, home: null }\n }\n return { osUser: false, home: null }\n }\n\n const rows = filtered.map((u) => {\n const os = osStateOf(u.name)\n return {\n name: u.name,\n email: u.email,\n isActive: u.isActive !== false,\n osUser: os.osUser,\n home: os.home,\n }\n })\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(rows, null, 2)}\\n`)\n return\n }\n\n if (rows.length === 0) {\n consola.info(args['include-inactive'] ? 'No agents found.' : 'No active agents found. Use --include-inactive to show deactivated.')\n return\n }\n\n const nameW = Math.max(4, ...rows.map(r => r.name.length))\n const emailW = Math.max(5, ...rows.map(r => r.email.length))\n const header = `${'NAME'.padEnd(nameW)} ${'EMAIL'.padEnd(emailW)} ACTIVE OS-USER HOME`\n console.log(header)\n console.log('-'.repeat(header.length))\n for (const r of rows) {\n const active = r.isActive ? '✓' : '✗'\n const os = r.osUser ? '✓' : '✗'\n const homeCol = r.home ?? (isDarwin() ? '(missing)' : '(non-darwin)')\n console.log(`${r.name.padEnd(nameW)} ${r.email.padEnd(emailW)} ${active.padEnd(6)} ${os.padEnd(7)} ${homeCol}`)\n }\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport { AGENT_NAME_REGEX, registerAgentAtIdp, SSH_ED25519_PREFIX, SSH_ED25519_REGEX } from '../../lib/agent-bootstrap'\n\nexport const registerAgentCommand = defineCommand({\n meta: {\n name: 'register',\n description: 'Register an agent at the IdP using a supplied public key',\n },\n args: {\n name: {\n type: 'string',\n description: 'Agent name (lowercase, [a-z0-9-], 1–24 chars, must start with a letter)',\n required: true,\n },\n 'public-key': {\n type: 'string',\n description: 'Full ssh-ed25519 public key line (e.g. \"ssh-ed25519 AAAAC3...\")',\n },\n 'public-key-file': {\n type: 'string',\n description: 'Path to a .pub file containing the ssh-ed25519 line',\n },\n json: {\n type: 'boolean',\n description: 'Emit machine-readable JSON instead of a human summary',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n const name = args.name\n if (!AGENT_NAME_REGEX.test(name)) {\n throw new CliError(\n `Invalid agent name \"${name}\". Must match /^[a-z][a-z0-9-]{0,23}$/ — `\n + `lowercase letters, digits and hyphens, 1–24 chars, must start with a letter.`,\n )\n }\n\n let publicKey: string | undefined = args['public-key']\n const keyFile = args['public-key-file']\n\n if (publicKey && keyFile) {\n throw new CliError('Pass either --public-key or --public-key-file, not both.')\n }\n\n if (!publicKey && keyFile) {\n if (!existsSync(keyFile)) {\n throw new CliError(`Public-key file not found: ${keyFile}`)\n }\n publicKey = readFileSync(keyFile, 'utf-8').trim()\n }\n\n if (!publicKey) {\n throw new CliError('Provide --public-key \"<ssh-ed25519 line>\" or --public-key-file <path>.')\n }\n\n if (!publicKey.startsWith(SSH_ED25519_PREFIX) || !SSH_ED25519_REGEX.test(publicKey)) {\n throw new CliError(\n 'Public key must be a full ssh-ed25519 line, e.g. '\n + '\"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... [optional comment]\".',\n )\n }\n\n const result = await registerAgentAtIdp({ name, publicKey, idp })\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify({\n email: result.email,\n name: result.name,\n owner: result.owner,\n approver: result.approver,\n idp,\n })}\\n`)\n return\n }\n\n consola.success('Agent registered.')\n console.log(` Name: ${result.name}`)\n console.log(` Email: ${result.email}`)\n console.log(` IdP: ${idp}`)\n console.log(` Owner: ${result.owner}`)\n console.log(` Approver: ${result.approver}`)\n console.log('')\n console.log('Tell the agent to log in with:')\n console.log(` apes login --idp ${idp} --email ${result.email} --key <path-to-matching-private-key>`)\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { taskTools } from '../../lib/agent-tools'\nimport { runLoop } from '../../lib/agent-runtime'\nimport type { RuntimeConfig } from '../../lib/agent-runtime'\nimport { materializeSecrets } from '../../lib/agent-secrets-runtime'\nimport { resolveTroopUrl, TroopClient } from '../../lib/troop-client'\nimport type { TaskSpec } from '../../lib/troop-client'\n\nconst AUTH_PATH = join(homedir(), '.config', 'apes', 'auth.json')\nconst TASK_CACHE_DIR = join(homedir(), '.openape', 'agent', 'tasks')\n\ninterface AuthJson { access_token: string, email: string, owner_email?: string }\n\nfunction readAuth(): AuthJson {\n if (!existsSync(AUTH_PATH)) {\n throw new CliError(`No agent auth found at ${AUTH_PATH}. Run \\`apes agents spawn <name>\\` first.`)\n }\n const parsed = JSON.parse(readFileSync(AUTH_PATH, 'utf8')) as AuthJson\n if (!parsed.access_token) throw new CliError('auth.json missing access_token')\n return parsed\n}\n\n/**\n * Post the run result as a chat DM from the agent to its owner. Best-\n * effort: any failure (no room yet because owner hasn't accepted the\n * contact request, chat down, network, …) just logs and returns. The\n * run record on troop is still authoritative; the chat DM is the\n * convenience surface so the owner sees the answer in the same\n * conversation thread they'd expect to ask about it.\n */\nasync function postRunResultToChat(opts: {\n authToken: string\n ownerEmail: string\n taskName: string\n status: 'ok' | 'error'\n stepCount: number\n finalMessage: string | null\n endpoint?: string\n}): Promise<void> {\n const endpoint = (opts.endpoint ?? process.env.APE_CHAT_ENDPOINT ?? 'https://chat.openape.ai').replace(/\\/$/, '')\n try {\n // Find the room with the owner. The bridge sets up the contact\n // relationship on first boot — if the owner hasn't accepted yet,\n // there's no room and we silently no-op.\n const contactsRes = await fetch(`${endpoint}/api/contacts`, {\n headers: { Authorization: `Bearer ${opts.authToken}` },\n })\n if (!contactsRes.ok) return\n const contacts = await contactsRes.json() as Array<{ peerEmail: string, roomId: string | null, connected: boolean }>\n const ownerLower = opts.ownerEmail.toLowerCase()\n const ownerRow = contacts.find(c => c.peerEmail.toLowerCase() === ownerLower && c.connected && c.roomId)\n if (!ownerRow?.roomId) {\n consola.info('chat DM skipped — no active room with owner (accept the contact request in chat to enable)')\n return\n }\n const prefix = opts.status === 'ok' ? '✅' : '❌'\n const msg = opts.finalMessage?.trim() || (opts.status === 'ok' ? '(no output)' : '(crashed)')\n const body = `${prefix} *${opts.taskName}* (${opts.stepCount} steps)\\n\\n${msg}`.slice(0, 9000)\n const postRes = await fetch(`${endpoint}/api/rooms/${encodeURIComponent(ownerRow.roomId)}/messages`, {\n method: 'POST',\n headers: { 'Authorization': `Bearer ${opts.authToken}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ body }),\n })\n if (!postRes.ok) {\n consola.warn(`chat DM post failed: ${postRes.status}`)\n }\n }\n catch (err) {\n consola.warn(`chat DM error: ${(err as Error).message}`)\n }\n}\n\nfunction readTaskSpec(taskId: string): TaskSpec {\n const path = join(TASK_CACHE_DIR, `${taskId}.json`)\n if (!existsSync(path)) {\n throw new CliError(`No cached task spec at ${path}. Run \\`apes agents sync\\` first to pull the task list from troop.`)\n }\n return JSON.parse(readFileSync(path, 'utf8')) as TaskSpec\n}\n\ninterface AgentJson { systemPrompt: string }\nconst AGENT_CONFIG_PATH = join(homedir(), '.openape', 'agent', 'agent.json')\n\n/**\n * Read the cached agent-level config (systemPrompt). Falls back to an\n * empty systemPrompt if the file is missing — older agents written\n * before the system-prompt refactor (#346) won't have one yet, and the\n * next sync will create it. Empty systemPrompt is fine: the runtime\n * just sends the user message with no system message.\n */\nfunction readAgentConfig(): AgentJson {\n if (!existsSync(AGENT_CONFIG_PATH)) return { systemPrompt: '' }\n try { return JSON.parse(readFileSync(AGENT_CONFIG_PATH, 'utf8')) as AgentJson }\n catch { return { systemPrompt: '' } }\n}\n\nfunction readLitellmConfig(model?: string): RuntimeConfig {\n // ~/litellm/.env carries LITELLM_API_KEY (or LITELLM_MASTER_KEY) +\n // LITELLM_BASE_URL — same file `apes agents spawn` writes during\n // the bridge bootstrap. The agent's macOS user owns the file.\n const envPath = join(homedir(), 'litellm', '.env')\n const env: Record<string, string> = {}\n if (existsSync(envPath)) {\n for (const line of readFileSync(envPath, 'utf8').split(/\\r?\\n/)) {\n const m = line.match(/^([A-Z_]+)=(.*)$/)\n if (m) env[m[1]!] = m[2]!.replace(/^[\"']|[\"']$/g, '')\n }\n }\n // Allow process.env to override (tests + ad-hoc dev).\n for (const k of ['LITELLM_API_KEY', 'LITELLM_MASTER_KEY', 'LITELLM_BASE_URL']) {\n if (process.env[k]) env[k] = process.env[k]!\n }\n const apiKey = env.LITELLM_API_KEY || env.LITELLM_MASTER_KEY\n const apiBase = (env.LITELLM_BASE_URL || 'http://127.0.0.1:4000/v1').replace(/\\/$/, '')\n if (!apiKey) {\n throw new CliError('No LITELLM_API_KEY / LITELLM_MASTER_KEY in ~/litellm/.env or env.')\n }\n return { apiBase, apiKey, model: model || 'claude-haiku-4-5' }\n}\n\nexport const runAgentCommand = defineCommand({\n meta: {\n name: 'run',\n description: 'Execute one task (typically launchd-invoked). Reports the run record to troop.',\n },\n args: {\n 'task-id': {\n type: 'positional',\n description: 'Task ID (slug) to run. The cached spec at ~/.openape/agent/tasks/<id>.json is used.',\n required: true,\n },\n 'troop-url': {\n type: 'string',\n description: 'Override troop SP base URL.',\n },\n 'model': {\n type: 'string',\n description: 'Override the LLM model name. Default: claude-haiku-4-5.',\n },\n },\n async run({ args }) {\n const taskId = args['task-id'] as string\n const auth = readAuth()\n // Inject any capability secrets troop sealed to this agent before\n // the task runs, so the agent's tools see them in process.env.\n materializeSecrets({ log: l => consola.info(l) })\n const spec = readTaskSpec(taskId)\n const agentCfg = readAgentConfig()\n const config = readLitellmConfig(args.model as string | undefined)\n\n let tools: ReturnType<typeof taskTools>\n try { tools = taskTools(spec.tools) }\n catch (err) {\n // Don't even POST a run record — task is structurally broken.\n // Surfaced via launchd's StandardErrorPath log; the next sync\n // pulls a fresh spec which may have the typo fixed.\n throw new CliError(`task ${taskId}: ${(err as Error).message}`)\n }\n\n const troop = new TroopClient(resolveTroopUrl(args['troop-url'] as string | undefined), auth.access_token)\n const { id: runId } = await troop.startRun(taskId)\n consola.info(`Run ${runId} started for task ${taskId}`)\n\n try {\n const result = await runLoop({\n config,\n // Agent persona/behaviour (\"you are Igor, …\") set at agent level;\n // the task's userPrompt is the imperative job (\"read my mail and\n // summarise\"). The cron firing is the trigger — the message body\n // is the task itself.\n systemPrompt: agentCfg.systemPrompt,\n userMessage: spec.userPrompt,\n tools,\n maxSteps: spec.maxSteps,\n })\n\n await troop.finaliseRun(runId, {\n status: result.status,\n final_message: result.finalMessage,\n step_count: result.stepCount,\n trace: result.trace,\n })\n consola.success(`Run ${runId} ${result.status} (${result.stepCount} steps)`)\n if (auth.owner_email) {\n await postRunResultToChat({\n authToken: auth.access_token,\n ownerEmail: auth.owner_email,\n taskName: spec.name,\n status: result.status,\n stepCount: result.stepCount,\n finalMessage: result.finalMessage,\n })\n }\n if (result.status === 'error') process.exit(1)\n }\n catch (err) {\n const message = (err as Error)?.message ?? String(err)\n await troop.finaliseRun(runId, {\n status: 'error',\n final_message: message.slice(0, 4000),\n step_count: 0,\n trace: [],\n }).catch(() => { /* best-effort */ })\n if (auth.owner_email) {\n await postRunResultToChat({\n authToken: auth.access_token,\n ownerEmail: auth.owner_email,\n taskName: spec.name,\n status: 'error',\n stepCount: 0,\n finalMessage: message,\n })\n }\n throw new CliError(`Run ${runId} crashed: ${message}`)\n }\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { createInterface } from 'node:readline'\nimport { defineCommand } from 'citty'\nimport { CliError } from '../../errors'\nimport { taskTools } from '../../lib/agent-tools'\nimport { runLoop, RpcSessionMap } from '../../lib/agent-runtime'\nimport type { RuntimeConfig } from '../../lib/agent-runtime'\nimport { startSecretsWatcher } from '../../lib/agent-secrets-runtime'\n\n// `apes agents serve --rpc` — long-running stdio JSON server.\n// Replaces `pi --mode rpc` for chat-bridge's per-room subprocesses.\n// Each inbound line is a JSON object describing a single message;\n// outbound is a stream of text_delta / tool_call / tool_result /\n// done / error events. Sessions keyed by `session_id` keep\n// per-conversation memory across messages.\n//\n// The chat-bridge package owns the policy of \"which model, which\n// system prompt, which tools\" — the runtime is purely the executor.\n\ninterface InboundMessage {\n type?: 'message'\n session_id: string\n system_prompt: string\n tools: string[]\n max_steps?: number\n model?: string\n user_msg: string\n}\n\ninterface AuthJson { access_token: string, email: string }\n\nconst AUTH_PATH = join(homedir(), '.config', 'apes', 'auth.json')\n\nfunction readLitellmConfig(model?: string): RuntimeConfig {\n const envPath = join(homedir(), 'litellm', '.env')\n const env: Record<string, string> = {}\n if (existsSync(envPath)) {\n for (const line of readFileSync(envPath, 'utf8').split(/\\r?\\n/)) {\n const m = line.match(/^([A-Z_]+)=(.*)$/)\n if (m) env[m[1]!] = m[2]!.replace(/^[\"']|[\"']$/g, '')\n }\n }\n for (const k of ['LITELLM_API_KEY', 'LITELLM_MASTER_KEY', 'LITELLM_BASE_URL']) {\n if (process.env[k]) env[k] = process.env[k]!\n }\n const apiKey = env.LITELLM_API_KEY || env.LITELLM_MASTER_KEY\n const apiBase = (env.LITELLM_BASE_URL || 'http://127.0.0.1:4000/v1').replace(/\\/$/, '')\n if (!apiKey) throw new CliError('No LITELLM_API_KEY / LITELLM_MASTER_KEY in ~/litellm/.env or env.')\n return { apiBase, apiKey, model: model || 'claude-haiku-4-5' }\n}\n\nfunction emit(event: Record<string, unknown>): void {\n process.stdout.write(`${JSON.stringify(event)}\\n`)\n}\n\nexport const serveAgentCommand = defineCommand({\n meta: {\n name: 'serve',\n description: 'Long-running stdio RPC server for chat-bridge subprocess use.',\n },\n args: {\n rpc: {\n type: 'boolean',\n description: 'Use the line-delimited JSON RPC protocol on stdio (the only mode for now).',\n },\n },\n async run({ args }) {\n if (!args.rpc) {\n throw new CliError('apes agents serve currently only supports --rpc mode')\n }\n if (existsSync(AUTH_PATH)) {\n // We don't actually use the agent JWT in serve mode — the bridge\n // is the only caller and it talks to chat.openape.ai itself —\n // but reading auth.json is a sanity check that we're running\n // as a troop-spawned agent user, not stray.\n try { JSON.parse(readFileSync(AUTH_PATH, 'utf8')) as AuthJson }\n catch { /* tolerate */ }\n }\n\n // Materialize capability secrets and keep them live: troop can\n // rotate/revoke while this long-running process is up (M2 v1\n // live-hotswap). Log to stderr — stdout is the RPC channel.\n const stopSecrets = startSecretsWatcher({ log: l => process.stderr.write(`${l}\\n`) })\n\n const sessions = new RpcSessionMap()\n const evictTimer = setInterval(() => sessions.evictStale(), 5 * 60 * 1000)\n process.on('exit', () => { clearInterval(evictTimer); stopSecrets() })\n\n const rl = createInterface({ input: process.stdin, terminal: false })\n rl.on('line', async (line) => {\n const trimmed = line.trim()\n if (!trimmed) return\n let msg: InboundMessage\n try { msg = JSON.parse(trimmed) as InboundMessage }\n catch (err) {\n emit({ type: 'error', message: `invalid JSON: ${(err as Error).message}` })\n return\n }\n if (!msg.session_id || !msg.user_msg) {\n emit({ type: 'error', message: 'session_id and user_msg are required' })\n return\n }\n try {\n await handleInbound(msg, sessions)\n }\n catch (err) {\n emit({ type: 'error', session_id: msg.session_id, message: (err as Error)?.message ?? String(err) })\n emit({ type: 'done', session_id: msg.session_id, step_count: 0, status: 'error' })\n }\n })\n\n rl.on('close', () => process.exit(0))\n\n // Block forever — readline keeps the loop alive.\n },\n})\n\nasync function handleInbound(msg: InboundMessage, sessions: RpcSessionMap): Promise<void> {\n const config = readLitellmConfig(msg.model)\n const tools = taskTools(msg.tools ?? [])\n const maxSteps = msg.max_steps ?? 10\n\n let session = sessions.get(msg.session_id)\n if (!session) {\n session = {\n systemPrompt: msg.system_prompt,\n tools,\n maxSteps,\n messages: [],\n lastTouched: Date.now(),\n }\n sessions.put(msg.session_id, session)\n }\n\n const result = await runLoop({\n config,\n systemPrompt: session.systemPrompt,\n userMessage: msg.user_msg,\n tools: session.tools,\n maxSteps: session.maxSteps,\n history: session.messages,\n handlers: {\n onTextDelta: delta => emit({ type: 'text_delta', session_id: msg.session_id, delta }),\n onToolCall: ({ name, args }) => emit({ type: 'tool_call', session_id: msg.session_id, name, args }),\n onToolResult: ({ name, result }) => emit({ type: 'tool_result', session_id: msg.session_id, name, result }),\n onToolError: ({ name, error }) => emit({ type: 'tool_error', session_id: msg.session_id, name, error }),\n },\n })\n\n // Persist session memory by appending the user_msg + assistant\n // response so the next inbound message has the full thread.\n session.messages.push({ role: 'user', content: msg.user_msg })\n if (result.finalMessage) {\n session.messages.push({ role: 'assistant', content: result.finalMessage })\n }\n\n emit({\n type: 'done',\n session_id: msg.session_id,\n step_count: result.stepCount,\n status: result.status,\n final_message: result.finalMessage,\n })\n}\n","import { execFileSync } from 'node:child_process'\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport {\n AGENT_NAME_REGEX,\n BASH_VIA_APE_SHELL_HOOK_SOURCE,\n buildAgentAuthJson,\n buildSpawnSetupScript,\n CLAUDE_SETTINGS_JSON,\n issueAgentToken,\n registerAgentAtIdp,\n} from '../../lib/agent-bootstrap'\nimport { buildSyncPlist } from '../../lib/troop-bootstrap'\nimport { generateKeyPairInMemory } from '../../lib/keygen'\nimport {\n bridgePlistLabel,\n bridgePlistPath,\n buildBridgeEnvFile,\n buildBridgePlist,\n buildBridgeStartScript,\n captureHostBinDirs,\n resolveBridgeConfig,\n} from '../../lib/llm-bridge'\nimport { isDarwin, isShellRegistered, macOSUsernameForAgent, readMacOSUser, whichBinary } from '../../lib/macos-user'\nimport { upsertNestAgent } from '../../lib/nest-registry'\n\nfunction readMacOSUidOrNull(name: string): number | null {\n try {\n const u = readMacOSUser(name)\n return u?.uid ?? null\n }\n catch { return null }\n}\n\nexport const spawnAgentCommand = defineCommand({\n meta: {\n name: 'spawn',\n description: 'Provision a local macOS agent end-to-end (OS user, keypair, IdP agent, Claude hook)',\n },\n args: {\n name: {\n type: 'positional',\n description: 'Agent name — also the macOS short username (lowercase, [a-z0-9-], must start with a letter)',\n required: true,\n },\n shell: {\n type: 'string',\n description: 'Login shell for the macOS user. Default: /bin/zsh. Pass $(which ape-shell) to opt into the grant-mediated REPL as login shell.',\n },\n 'no-claude-hook': {\n type: 'boolean',\n description: 'Skip writing ~/.claude/settings.json + the Bash-rewrite hook',\n },\n 'claude-token': {\n type: 'string',\n description: 'Claude Code OAuth token (sk-ant-oat01-…) from `claude setup-token`. Visible to ps — prefer --claude-token-stdin in scripts.',\n },\n 'claude-token-stdin': {\n type: 'boolean',\n description: 'Read the Claude Code OAuth token from stdin (paranoid form of --claude-token).',\n },\n 'no-bridge': {\n type: 'boolean',\n description:\n 'Skip the ape-agent runtime install. Default behaviour installs the runtime so the agent answers chat.openape.ai messages (reads LITELLM_API_KEY/BASE_URL from ~/litellm/.env; override via --bridge-key / --bridge-base-url). Use --no-bridge for headless / CI / IdP-only account provisioning where the agent will not run a chat loop.',\n },\n 'bridge-key': {\n type: 'string',\n description: 'Override LITELLM_API_KEY for the bridge (default: read from ~/litellm/.env).',\n },\n 'bridge-base-url': {\n type: 'string',\n description: 'Override LITELLM_BASE_URL for the bridge (default: read from ~/litellm/.env or http://127.0.0.1:4000/v1).',\n },\n 'bridge-model': {\n type: 'string',\n description: 'Model the bridge sends in chat-completion requests (default: claude-haiku-4-5). Override when fronting a proxy that doesn\\'t route the default — e.g. ChatGPT-only proxy needs `gpt-5.4`.',\n },\n },\n async run({ args }) {\n const name = args.name as string\n if (!AGENT_NAME_REGEX.test(name)) {\n throw new CliError(\n `Invalid agent name \"${name}\". Must match /^[a-z][a-z0-9-]{0,23}$/ — `\n + `lowercase letters, digits and hyphens, 1–24 chars, must start with a letter.`,\n )\n }\n\n if (!isDarwin()) {\n throw new CliError(\n `\\`apes agents spawn\\` is currently macOS-only. Detected platform: ${process.platform}. `\n + `Linux support is a follow-up; for now, use \\`apes agents register\\` plus a manually provisioned user.`,\n )\n }\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n // Default to plain /bin/zsh (macOS modern default) — ape-shell as login\n // shell is opt-in via --shell. Rationale: ape-shell intercepts every\n // command through the grant flow which is the right model for unattended\n // agents but trips on interactive niceties (terminal control sequences\n // sent by tools like Warp, exit semantics, etc.). The Claude\n // bash-rewrite hook still routes Claude-issued commands through\n // ape-shell — that's where grant-mediation actually matters.\n const loginShell = (args.shell ?? '/bin/zsh').toString()\n const apes = whichBinary('apes')\n if (!apes) {\n throw new CliError('`apes` not found on PATH. Install @openape/apes globally first.')\n }\n const escapes = whichBinary('escapes')\n if (!escapes) {\n throw new CliError(\n '`escapes` not found on PATH. spawn delegates the privileged setup phase to escapes; '\n + 'install it before running spawn.',\n )\n }\n if (!isShellRegistered(loginShell)) {\n throw new CliError(\n `${loginShell} is not registered in /etc/shells. macOS refuses to set it as a login shell. Run:\\n`\n + ` echo ${loginShell} | sudo tee -a /etc/shells\\n`\n + 'and try again.',\n )\n }\n\n // macOSUsername is the dscl record name + chown target. Prefixed\n // (`openape-agent-<name>`) so `cleanup-orphans` and any operator\n // running `dscl . -list /Users` can spot OpenApe-managed accounts\n // immediately. Agent-facing surfaces (email, troop UI, bridge data\n // dir, `apes agents list`) stay on the bare `name`. Legacy agents\n // (pre-prefix) keep working via `lookupMacOSUserForAgent` which\n // falls through to the unprefixed lookup.\n const macOSUsername = macOSUsernameForAgent(name)\n const existing = readMacOSUser(macOSUsername) ?? readMacOSUser(name)\n if (existing) {\n throw new CliError(`macOS user \"${existing.name}\" already exists (uid=${existing.uid ?? '?'}). Refusing to overwrite.`)\n }\n\n // Phase G (#sim-arch): hidden service-account agents live under\n // /var/openape/homes/<macOSUsername>, matching macOS convention\n // for hidden services (_www → /var/empty, _postgres → /var/empty,\n // our own _openape_nest → /var/openape/nest). Keeps /Users/ for\n // real human accounts only — Finder, TimeMachine, Migration\n // Assistant stop seeing agents.\n //\n // The dscl record stays at /Users/<macOSUsername> (that's the\n // dscl namespace, not a filesystem path) — only the\n // NFSHomeDirectory attribute changes. setup.sh below interpolates\n // both into the dscl create call.\n const homeDir = `/var/openape/homes/${macOSUsername}`\n const scratch = mkdtempSync(join(tmpdir(), `apes-spawn-${name}-`))\n const scriptPath = join(scratch, 'setup.sh')\n\n try {\n consola.start(`Generating keypair for ${name}…`)\n const { privatePem, publicSshLine, x25519PrivateKey, x25519PublicKey } = generateKeyPairInMemory()\n\n consola.start(`Registering agent at ${idp}…`)\n const registration = await registerAgentAtIdp({ name, publicKey: publicSshLine, idp })\n consola.success(`Registered as ${registration.email}`)\n\n consola.start('Issuing agent access token…')\n const { token, expiresIn } = await issueAgentToken({\n idp,\n agentEmail: registration.email,\n privateKeyPem: privatePem,\n })\n\n const authJson = buildAgentAuthJson({\n idp,\n accessToken: token,\n email: registration.email,\n expiresAt: Math.floor(Date.now() / 1000) + expiresIn,\n keyPath: `${homeDir}/.ssh/id_ed25519`,\n // The IdP resolves the owner transitively (when the caller\n // is itself an agent — e.g. a Nest spawning a child — the\n // human at the top of the chain becomes owner). Use the\n // server-resolved owner, not the local caller's auth.email,\n // otherwise the agent's auth.json will carry the Nest's\n // email and troop will reject sync calls because the\n // encoded owner-domain in the agent email doesn't match\n // the auth.json's owner_email domain.\n ownerEmail: registration.owner,\n })\n\n const includeClaudeHook = !args['no-claude-hook']\n const claudeOauthToken = await resolveClaudeToken({\n flag: typeof args['claude-token'] === 'string' ? args['claude-token'] : undefined,\n fromStdin: !!args['claude-token-stdin'],\n })\n\n // Bridge install is the default — every agent needs the runtime\n // to answer chat or fire cron tasks. `--no-bridge` is the explicit\n // escape for headless / CI / account-only provisioning.\n const withBridge = !args['no-bridge']\n const bridge = withBridge\n ? (() => {\n const cfg = resolveBridgeConfig({\n cliKey: typeof args['bridge-key'] === 'string' ? args['bridge-key'] : undefined,\n cliBaseUrl: typeof args['bridge-base-url'] === 'string' ? args['bridge-base-url'] : undefined,\n cliModel: typeof args['bridge-model'] === 'string' ? args['bridge-model'] : undefined,\n })\n // Capture the host's bin dirs ONCE per spawn — same dirs\n // are baked into both the plist's PATH and start.sh.\n // Throws if node / ape-agent / apes aren't on\n // the host PATH.\n const hostBinDirs = captureHostBinDirs()\n return {\n plistLabel: bridgePlistLabel(name),\n plistPath: bridgePlistPath(name),\n plistContent: buildBridgePlist(name, homeDir, auth.email, hostBinDirs),\n startScript: buildBridgeStartScript(hostBinDirs),\n envFile: buildBridgeEnvFile(cfg),\n }\n })()\n : null\n\n // Troop sync launchd — installed for every agent (no opt-out\n // for v1). The plist runs `apes agents sync` every 5min and\n // RunAtLoad fires it once eagerly so the agent registers at\n // troop.openape.ai within seconds of spawn finishing.\n const troopPlistLabel = `openape.troop.sync.${name}`\n const troopPlistPath = `/Library/LaunchDaemons/${troopPlistLabel}.plist`\n // Reuse the bridge's host-bin-dir capture if a bridge was set\n // up; otherwise capture once for the troop sync alone. The\n // sync daemon needs `node` (apes-cli's shebang) and `apes`\n // (the actual binary it runs) on PATH.\n const troopBinDirs = bridge ? captureHostBinDirs() : captureHostBinDirs()\n const troop = {\n plistLabel: troopPlistLabel,\n plistPath: troopPlistPath,\n plistContent: buildSyncPlist({ agentName: name, apesBin: apes, homeDir, userName: name, hostBinDirs: troopBinDirs }),\n }\n\n const script = buildSpawnSetupScript({\n name,\n macOSUsername,\n homeDir,\n shellPath: loginShell,\n privateKeyPem: privatePem,\n publicKeySshLine: publicSshLine,\n x25519PrivateKey,\n x25519PublicKey,\n authJson,\n claudeSettingsJson: includeClaudeHook ? CLAUDE_SETTINGS_JSON : null,\n hookScriptSource: includeClaudeHook ? BASH_VIA_APE_SHELL_HOOK_SOURCE : null,\n claudeOauthToken,\n bridge,\n troop,\n })\n writeFileSync(scriptPath, script, { mode: 0o700 })\n\n // Skip the second escalation if we're already root. This happens\n // when `apes nest spawn` (or any wrapper) invokes us via\n // `apes run --as root -- apes agents spawn` — the outer `apes\n // run` already obtained Patrick's grant + escapes-setuid us to\n // root, so an inner `apes run --as root` would just request a\n // second redundant grant. Direct call to bash skips that and\n // gets us down to ONE approval per spawn (the outer one).\n const alreadyRoot = process.getuid?.() === 0\n if (alreadyRoot) {\n consola.start('Running privileged setup directly (already root)…')\n execFileSync('bash', [scriptPath], { stdio: 'inherit' })\n }\n else {\n consola.start('Running privileged setup as root via `apes run --as root --wait`…')\n consola.info('You will be asked to approve the as=root grant in your DDISA inbox; this command blocks until you do.')\n // --wait is critical: without it `apes run --as root` returns\n // exit 75 (pending) immediately, which we'd interpret as\n // failure and which would leave a dangling grant referencing\n // a scratch dir we'd cleaned up in the finally below.\n execFileSync(apes, ['run', '--as', 'root', '--wait', '--', 'bash', scriptPath], { stdio: 'inherit' })\n }\n\n // Phase F: register in the Nest's registry directly (replaces\n // the old intent-channel handler in the Nest). The Nest\n // watches agents.json and reconciles its pm2-supervisor when\n // it sees a new entry — bridge starts within a second.\n try {\n const uid = readMacOSUidOrNull(macOSUsername) ?? readMacOSUidOrNull(name)\n upsertNestAgent({\n name,\n uid: uid ?? -1,\n home: homeDir,\n email: registration.email,\n registeredAt: Math.floor(Date.now() / 1000),\n bridge: withBridge\n ? {\n baseUrl: typeof args['bridge-base-url'] === 'string' ? args['bridge-base-url'] : undefined,\n apiKey: typeof args['bridge-key'] === 'string' ? args['bridge-key'] : undefined,\n model: typeof args['bridge-model'] === 'string' ? args['bridge-model'] : undefined,\n }\n : undefined,\n })\n }\n catch (err) {\n // Don't fail the spawn just because the registry write\n // glitched — the agent exists in macOS, the human can\n // manually register later. Log loudly.\n consola.warn(`Could not write to nest registry: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n consola.success(`Agent ${name} spawned.`)\n consola.info(`🔗 Troop: https://troop.openape.ai/agents/${name}`)\n\n if (withBridge) {\n consola.info(`On first boot, the bridge will send you a contact request from ${registration.email}.`)\n consola.info('Open chat.openape.ai and accept it to start chatting with the agent.')\n }\n\n console.log('')\n console.log('Run as the agent with:')\n console.log(` apes run --as ${name} -- claude --session-name ${name} --dangerously-skip-permissions`)\n }\n finally {\n rmSync(scratch, { recursive: true, force: true })\n }\n },\n})\n\n/**\n * Resolve the Claude Code OAuth token from --claude-token, --claude-token-stdin,\n * or neither (returns null = agent will need interactive auth on first claude\n * run). --flag and --stdin together is rejected as ambiguous.\n *\n * Validation: Claude tokens start with `sk-ant-oat01-`. We reject anything\n * else with a clear hint instead of silently writing a useless string.\n */\nasync function resolveClaudeToken(opts: { flag?: string, fromStdin: boolean }): Promise<string | null> {\n if (opts.flag && opts.fromStdin) {\n throw new CliError('Pass --claude-token OR --claude-token-stdin, not both.')\n }\n let raw: string | null = null\n if (typeof opts.flag === 'string') {\n raw = opts.flag.trim()\n }\n else if (opts.fromStdin) {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n raw = Buffer.concat(chunks).toString('utf-8').trim()\n }\n if (!raw) return null\n if (!raw.startsWith('sk-ant-oat01-')) {\n throw new CliError(\n `Claude token doesn't look right (expected sk-ant-oat01-…). Run \\`claude setup-token\\``\n + ` and paste the resulting token.`,\n )\n }\n return raw\n}\n","// Troop-side spawn integration. Installs the periodic sync launchd\n// plist for a freshly spawned agent and bootstraps it into the system\n// domain (run-as the agent via UserName) so it kicks off immediately.\n//\n// Why /Library/LaunchDaemons + system domain (not ~/Library/LaunchAgents\n// + gui/<uid>): spawned agents are hidden service accounts (IsHidden=1)\n// that never log in graphically, so their per-user launchd domain\n// doesn't exist. `launchctl bootstrap gui/<uid>` fails with \"Domain does\n// not support specified action\". The bridge had the same constraint and\n// solved it the same way — system-level plist with UserName key. Keeps\n// the daemon running 24/7 regardless of login state.\n//\n// The sync plist runs `apes agents sync` every 5 minutes (StartInterval).\n// It also fires once on bootstrap (the implicit launchctl bootstrap\n// run) so the agent's first appearance in the troop SP UI doesn't\n// have to wait a full sync cycle after spawn finishes.\n\nconst SYNC_LABEL_PREFIX = 'openape.troop.sync'\nconst SYNC_INTERVAL_SECONDS = 300\n\nexport function syncPlistLabel(agentName: string): string {\n return `${SYNC_LABEL_PREFIX}.${agentName}`\n}\n\nexport function syncPlistPath(_homeDir: string, agentName: string): string {\n return `/Library/LaunchDaemons/${syncPlistLabel(agentName)}.plist`\n}\n\ninterface SyncPlistInput {\n agentName: string\n apesBin: string\n homeDir: string\n /**\n * macOS short username for the agent. The sync daemon itself runs\n * as ROOT (so it can write into /Library/LaunchDaemons/ and\n * `launchctl bootstrap system` task plists — system-domain\n * operations a hidden service-account agent has no permission for).\n * Sync resolves the agent's numeric uid/gid by stat-ing $HOME at\n * runtime, then chowns its writes back to those ids.\n */\n userName: string\n // Optional override for OPENAPE_TROOP_URL — exposed in the plist\n // EnvironmentVariables so the launchd-spawned `apes agents sync`\n // talks to the right SP. Default: https://troop.openape.ai (via\n // the apes binary's resolveTroopUrl). Useful for testing against\n // a staging troop.\n troopUrl?: string\n /**\n * Host bin dirs (e.g. ['/opt/homebrew/bin']) baked into the plist's\n * PATH so the launchd-spawned `apes` binary's `#!/usr/bin/env node`\n * shebang resolves. Captured at spawn time via captureHostBinDirs.\n * Falls back to ['/opt/homebrew/bin','/usr/local/bin'] if not given,\n * for backwards compat with older callers.\n */\n hostBinDirs?: string[]\n}\n\nfunction escape(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')\n}\n\nexport function buildSyncPlist(input: SyncPlistInput): string {\n // launchd defaults PATH to /usr/bin:/bin:/usr/sbin:/sbin — too narrow\n // for the apes binary's `#!/usr/bin/env node` shebang to find node.\n // We bake the host's resolved bin dirs (where node and apes already\n // live, captured via captureHostBinDirs at spawn time) and the\n // standard system path. Per-agent `~/.bun/bin` is gone — agents\n // now share the host's tooling install. See agent-bootstrap M9.\n //\n // HOME is set to the agent's home dir even though the daemon runs as\n // root — Node's `os.homedir()` reads $HOME first, so all of sync's\n // file operations stay scoped under /Users/<agent>/. AGENT_UID/GID\n // tell sync who to chown those files to after writing.\n const pathDirs = (input.hostBinDirs && input.hostBinDirs.length > 0\n ? input.hostBinDirs\n : ['/opt/homebrew/bin', '/usr/local/bin']).join(':')\n const pathLine = ` <key>PATH</key><string>${escape(pathDirs)}:/usr/bin:/bin</string>\\n`\n const agentUserLine = ` <key>AGENT_USER</key><string>${escape(input.userName)}</string>\\n`\n const envBlock = input.troopUrl\n ? ` <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key><string>${escape(input.homeDir)}</string>\n${pathLine}${agentUserLine} <key>OPENAPE_TROOP_URL</key><string>${escape(input.troopUrl)}</string>\n </dict>\n`\n : ` <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key><string>${escape(input.homeDir)}</string>\n${pathLine}${agentUserLine} </dict>\n`\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${escape(syncPlistLabel(input.agentName))}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escape(input.apesBin)}</string>\n <string>agents</string>\n <string>sync</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${escape(input.homeDir)}</string>\n${envBlock} <key>StartInterval</key>\n <integer>${SYNC_INTERVAL_SECONDS}</integer>\n <key>RunAtLoad</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${escape(input.homeDir)}/Library/Logs/openape-troop-sync.log</string>\n <key>StandardErrorPath</key>\n <string>${escape(input.homeDir)}/Library/Logs/openape-troop-sync.log</string>\n</dict>\n</plist>\n`\n}\n\nexport const _internal = { SYNC_INTERVAL_SECONDS, SYNC_LABEL_PREFIX }\n","import { Buffer } from 'node:buffer'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { generateKeyPairSync } from 'node:crypto'\nimport { homedir } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { generateX25519KeyPair } from '@openape/core'\nimport { loadEd25519PrivateKey } from '../ssh-key'\n\nexport function resolveKeyPath(p: string): string {\n return resolve(p.replace(/^~/, homedir()))\n}\n\nfunction buildSshEd25519Line(rawPub: Buffer): string {\n const keyTypeStr = 'ssh-ed25519'\n const keyTypeLen = Buffer.alloc(4)\n keyTypeLen.writeUInt32BE(keyTypeStr.length)\n const pubKeyLen = Buffer.alloc(4)\n pubKeyLen.writeUInt32BE(rawPub.length)\n const blob = Buffer.concat([keyTypeLen, Buffer.from(keyTypeStr), pubKeyLen, rawPub])\n return `ssh-ed25519 ${blob.toString('base64')}`\n}\n\nexport function readPublicKey(keyPath: string): string {\n const pubPath = `${keyPath}.pub`\n if (existsSync(pubPath)) {\n return readFileSync(pubPath, 'utf-8').trim()\n }\n\n const keyContent = readFileSync(keyPath, 'utf-8')\n const privateKey = loadEd25519PrivateKey(keyContent)\n const jwk = privateKey.export({ format: 'jwk' }) as { x: string }\n const pubBytes = Buffer.from(jwk.x, 'base64url')\n return buildSshEd25519Line(pubBytes)\n}\n\nexport function generateAndSaveKey(keyPath: string): string {\n const resolved = resolveKeyPath(keyPath)\n const dir = dirname(resolved)\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n const { publicKey, privateKey } = generateKeyPairSync('ed25519')\n\n const privatePem = privateKey.export({ type: 'pkcs8', format: 'pem' }) as string\n writeFileSync(resolved, privatePem, { mode: 0o600 })\n\n const jwk = publicKey.export({ format: 'jwk' }) as { x: string }\n const pubBytes = Buffer.from(jwk.x, 'base64url')\n const pubKeyStr = buildSshEd25519Line(pubBytes)\n\n writeFileSync(`${resolved}.pub`, `${pubKeyStr}\\n`, { mode: 0o644 })\n\n return pubKeyStr\n}\n\nexport interface GeneratedKeyPair {\n privatePem: string\n publicSshLine: string\n /**\n * Agent encryption keypair (X25519, base64url DER). Separate from the\n * ed25519 auth key on purpose — auth signs, this one decrypts. troop\n * seals capability secrets to `x25519PublicKey`; the agent opens them\n * with `x25519PrivateKey`. See @openape/core sealed-box.\n */\n x25519PrivateKey: string\n x25519PublicKey: string\n}\n\nexport function generateKeyPairInMemory(): GeneratedKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync('ed25519')\n const privatePem = privateKey.export({ type: 'pkcs8', format: 'pem' }) as string\n const jwk = publicKey.export({ format: 'jwk' }) as { x: string }\n const pubBytes = Buffer.from(jwk.x, 'base64url')\n const enc = generateX25519KeyPair()\n return {\n privatePem,\n publicSshLine: buildSshEd25519Line(pubBytes),\n x25519PrivateKey: enc.privateKey,\n x25519PublicKey: enc.publicKey,\n }\n}\n","// Helpers for `apes agents spawn`. The chat-bridge is a daemon\n// that runs as the agent user, listens to chat.openape.ai, and forwards\n// messages to a local LLM CLI (pi). It needs access to a local litellm\n// proxy — set up out-of-band by the spawning user (today: hand-crafted\n// at ~/litellm/.env).\n//\n// As of #236 the daemon is installed as a system-wide LaunchDaemon at\n// /Library/LaunchDaemons/eco.hofmann.apes.bridge.<agent>.plist with the\n// agent set as <UserName>. That makes it boot without anyone being logged\n// in (matters for hidden service accounts in the [200,500) UID range\n// which never get a GUI session).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\nconst PLIST_LABEL_PREFIX = 'eco.hofmann.apes.bridge'\n\nexport interface BridgeConfig {\n /** Where the bridge will POST messages — http://host:port/v1 */\n baseUrl: string\n /** Master key for the litellm proxy */\n apiKey: string\n /**\n * Model the bridge sends in every chat-completion request. Optional:\n * if undefined, the bridge falls back to its built-in default\n * (`claude-haiku-4-5`). Set this when the upstream proxy doesn't\n * route that model — e.g. a LiteLLM proxy fronting only ChatGPT\n * subscription needs `gpt-5.4` or the proxy 404s every request.\n */\n model?: string\n}\n\n/**\n * Read defaults from `~/litellm/.env` (the hand-crafted location patrick\n * uses today). Returns null if no file or no key found.\n */\nexport function readLitellmEnv(envPath: string = join(homedir(), 'litellm', '.env')): { apiKey?: string, baseUrl?: string, model?: string } | null {\n if (!existsSync(envPath)) return null\n try {\n const text = readFileSync(envPath, 'utf8')\n const out: { apiKey?: string, baseUrl?: string, model?: string } = {}\n for (const line of text.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n const eq = trimmed.indexOf('=')\n if (eq < 0) continue\n const key = trimmed.slice(0, eq).trim()\n const value = trimmed.slice(eq + 1).trim()\n if (key === 'LITELLM_MASTER_KEY' || key === 'LITELLM_API_KEY') out.apiKey = value\n if (key === 'LITELLM_BASE_URL') out.baseUrl = value\n if (key === 'APE_CHAT_BRIDGE_MODEL') out.model = value\n }\n return out\n }\n catch {\n return null\n }\n}\n\n/** Resolve config from CLI flags + env defaults. CLI wins. */\nexport function resolveBridgeConfig(opts: {\n cliKey?: string\n cliBaseUrl?: string\n cliModel?: string\n envPath?: string\n}): BridgeConfig {\n const env = readLitellmEnv(opts.envPath)\n const apiKey = opts.cliKey ?? env?.apiKey\n const baseUrl = opts.cliBaseUrl ?? env?.baseUrl ?? 'http://127.0.0.1:4000/v1'\n const model = opts.cliModel ?? env?.model\n if (!apiKey) {\n throw new Error(\n 'No LITELLM_API_KEY resolved. Pass --bridge-key sk-… or write LITELLM_MASTER_KEY into ~/litellm/.env first.',\n )\n }\n return { baseUrl, apiKey, model }\n}\n\n/**\n * Capture the host's bin directories the bridge needs at runtime:\n * `node` (for the `#!/usr/bin/env node` shebang on the bridge binary),\n * `ape-agent` (the bridge itself), and `apes` (for the\n * `apes agents serve --rpc` subprocess the bridge spawns).\n *\n * On Homebrew macOS these all live in /opt/homebrew/bin. Resolved\n * dynamically so the same code works under nvm, volta, asdf, or\n * system Node. Throws if any required binary isn't on the host PATH —\n * that means the operator hasn't installed the OpenApe stack yet\n * (`npm i -g @openape/apes @openape/ape-agent` fixes it). The\n * thrown error is the right surface area: previously the spawn flow\n * silently `bun add -g`'d the missing pieces per agent, costing\n * 30-90s/spawn and ~100MB/agent.\n *\n * `ape-agent` is the canonical binary name (renamed from\n * `openape-chat-bridge` in @openape/ape-agent@2.0.0). The old name\n * is still shipped as an alias by the same package, so existing\n * pm2 ecosystem.config.js that reference `openape-chat-bridge`\n * keep working on hosts that have @openape/ape-agent installed.\n */\nexport function captureHostBinDirs(): string[] {\n const dirs: string[] = []\n const seen = new Set<string>()\n for (const bin of ['node', 'ape-agent', 'apes']) {\n let resolved: string\n try {\n resolved = execFileSync('/usr/bin/which', [bin], { encoding: 'utf8' }).trim()\n }\n catch {\n const installCmd = bin === 'ape-agent'\n ? 'npm i -g @openape/ape-agent'\n : bin === 'apes'\n ? 'npm i -g @openape/apes'\n : 'install Node.js (e.g. brew install node)'\n throw new Error(`'${bin}' not found on host PATH. ${installCmd} before spawning agents — the bridge runtime resolves these at spawn time and bakes the dir into the agent's launchd plist.`)\n }\n const dir = dirname(resolved)\n if (!seen.has(dir)) {\n seen.add(dir)\n dirs.push(dir)\n }\n }\n return dirs\n}\n\nexport function bridgePlistLabel(agentName: string): string {\n return `${PLIST_LABEL_PREFIX}.${agentName}`\n}\n\n/** Path of the system LaunchDaemon plist. Root-owned, writable only by root. */\nexport function bridgePlistPath(agentName: string): string {\n return `/Library/LaunchDaemons/${bridgePlistLabel(agentName)}.plist`\n}\n\nexport function buildBridgeEnvFile(cfg: BridgeConfig): string {\n const modelLine = cfg.model ? `APE_CHAT_BRIDGE_MODEL=${cfg.model}\\n` : ''\n return `# Auto-generated by 'apes agents spawn'.\n# Read by the chat-bridge daemon at boot to talk to the local LLM proxy.\nLITELLM_BASE_URL=${cfg.baseUrl}\nLITELLM_API_KEY=${cfg.apiKey}\n${modelLine}`\n}\n\n/**\n * start.sh content. Slim — assumes the bridge stack (chat-bridge + apes\n * + pi) was already bun-installed during spawn. Each launchd boot only:\n *\n * 1. Drops the litellm pi extension if missing (idempotent).\n * 2. Sources the proxy env + execs the bridge.\n *\n * Boot time goes from ~75s (with installs) to ~3-5s.\n *\n * Token refresh: handled in-process by `@openape/cli-auth`, which\n * does its own Ed25519 challenge-response when the cached IdP token\n * expires (`auth.json.key_path` points at `~/.ssh/id_ed25519`). No\n * `apes login` shell-out needed at boot — the daemon stays connected\n * across the 1h expiry boundary instead of crash-restarting. See #259.\n *\n * To upgrade an agent's bridge after a new release:\n * npm i -g @openape/ape-agent@latest\n * apes run --as <name> -- pm2 reload openape-bridge-<name>\n */\nexport function buildBridgeStartScript(hostBinDirs: string[]): string {\n // PATH is the host's resolved bin dirs (from captureHostBinDirs)\n // followed by the standard system path. The PATH key in the launchd\n // plist already sets this for the exec'd process — start.sh repeats\n // it because some shells reset PATH on `set -a`.\n const pathLine = `export PATH=\"${hostBinDirs.join(':')}:/usr/bin:/bin\"`\n return `#!/usr/bin/env bash\n# Auto-generated by 'apes agents spawn'.\n# Slim launcher — bridge stack lives on the host, no per-agent install.\nset -euo pipefail\n\n${pathLine}\n\n# Token refresh is in-process via @openape/cli-auth's challenge-response\n# path (auth.json.key_path -> ~/.ssh/id_ed25519). No \"apes login\" needed\n# at boot — keeping start.sh slim avoids the rate-limit dance the old\n# refresh hit when KeepAlive crash-restarted the daemon every 1h.\n\nset -a\n. \"$HOME/Library/Application Support/openape/bridge/.env\"\nset +a\nexec ape-agent\n`\n}\n\n/**\n * System LaunchDaemon plist. Lives at /Library/LaunchDaemons/. macOS boots\n * it automatically and respawns on crash via KeepAlive. UserName ensures\n * launchd starts the process as the agent (not root), even though the\n * plist itself is root-owned.\n *\n * `OPENAPE_OWNER_EMAIL` is stamped into the daemon environment as a\n * defense-in-depth fallback for the chat-bridge identity check: the\n * canonical source is `owner_email` in `~/.config/apes/auth.json`\n * (written by spawn), but if a future `apes login` ever clobbers that\n * field the bridge can still resolve its owner from this env var.\n */\nexport function buildBridgePlist(agentName: string, homeDir: string, ownerEmail: string, hostBinDirs: string[]): string {\n const startScript = `${homeDir}/Library/Application Support/openape/bridge/start.sh`\n const stdoutLog = `${homeDir}/Library/Logs/ape-agent.log`\n const stderrLog = `${homeDir}/Library/Logs/ape-agent.err.log`\n // PATH = host's resolved bin dirs (where node, ape-agent,\n // and apes already live) + standard system path. No `~/.bun/bin`\n // entry — the per-agent bun install was retired in favour of host-\n // wide tooling. See captureHostBinDirs for resolution.\n const pathValue = `${hostBinDirs.join(':')}:/usr/bin:/bin`\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${bridgePlistLabel(agentName)}</string>\n <key>UserName</key>\n <string>${agentName}</string>\n <key>ProgramArguments</key>\n <array>\n <string>/bin/bash</string>\n <string>${startScript}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${homeDir}</string>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>StandardOutPath</key>\n <string>${stdoutLog}</string>\n <key>StandardErrorPath</key>\n <string>${stderrLog}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key>\n <string>${homeDir}</string>\n <key>PATH</key>\n <string>${pathValue}</string>\n <key>OPENAPE_OWNER_EMAIL</key>\n <string>${ownerEmail}</string>\n </dict>\n</dict>\n</plist>\n`\n}\n","import { chownSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { readAgentEncryptionPublicKey } from '../../lib/agent-secrets-runtime'\nimport { CliError } from '../../errors'\nimport { getHostId, getHostname } from '../../lib/macos-host'\nimport { resolveTroopUrl, TroopClient } from '../../lib/troop-client'\n\ninterface AuthJson {\n idp: string\n access_token: string\n email: string\n expires_at?: number\n key_path?: string\n owner_email?: string\n}\n\nconst AUTH_PATH = join(homedir(), '.config', 'apes', 'auth.json')\nconst TASK_CACHE_DIR = join(homedir(), '.openape', 'agent', 'tasks')\n\nfunction readAuthJson(): AuthJson {\n if (!existsSync(AUTH_PATH)) {\n throw new CliError(\n `No agent auth found at ${AUTH_PATH}. Run \\`apes agents spawn <name>\\` to provision an agent first.`,\n )\n }\n const raw = readFileSync(AUTH_PATH, 'utf8')\n let parsed: AuthJson\n try { parsed = JSON.parse(raw) as AuthJson }\n catch (err) {\n throw new CliError(`${AUTH_PATH} is not valid JSON: ${(err as Error).message}`)\n }\n if (!parsed.access_token) throw new CliError(`${AUTH_PATH} is missing access_token`)\n if (!parsed.email) throw new CliError(`${AUTH_PATH} is missing email`)\n // Agent addresses derived by deriveAgentEmail() in the IdP's enroll\n // endpoint look like:\n // <safeName>-<ownerHash>+<owner-local>+<owner-domain>@<idp-host>\n // (e.g. \"igor4-cb6bf26a+patrick+hofmann_eco@id.openape.ai\"). The\n // distinguishing feature vs. a human address is the embedded `+` from\n // the subaddressing — humans never have that.\n if (!parsed.email.includes('+')) {\n throw new CliError(\n `${AUTH_PATH} email is \"${parsed.email}\" — expected an agent address (with embedded +owner+domain). Run \\`apes agents spawn\\` rather than calling sync from a human user.`,\n )\n }\n return parsed\n}\n\nfunction agentNameFromEmail(email: string): string {\n // <name>-<ownerHash>+<owner-local>+<owner-domain>@<idp-host>\n // The agent NAME is everything up to the last `-` before the first\n // `+` — the suffix `-<ownerHash>` is appended at registration time\n // to disambiguate same-named agents across owners.\n const before = email.split('+')[0]!\n const dashIdx = before.lastIndexOf('-')\n if (dashIdx <= 0) {\n // Pre-hash format (e.g. \"agenta+patrick+hofmann_eco@…\") — fall back\n // to the local-part as-is so we keep working with older agents.\n return before\n }\n return before.slice(0, dashIdx)\n}\n\nexport const syncAgentCommand = defineCommand({\n meta: {\n name: 'sync',\n description: 'Pull this agent\\'s task list from troop.openape.ai and reconcile launchd plists',\n },\n args: {\n 'troop-url': {\n type: 'string',\n description: 'Override troop SP base URL (default: $OPENAPE_TROOP_URL or https://troop.openape.ai)',\n },\n },\n async run({ args }) {\n const auth = readAuthJson()\n const agentName = agentNameFromEmail(auth.email)\n const troopUrl = resolveTroopUrl(args['troop-url'] as string | undefined)\n const client = new TroopClient(troopUrl, auth.access_token)\n\n const hostId = getHostId()\n const host = getHostname()\n if (!hostId) {\n throw new CliError('Could not read IOPlatformUUID — is this macOS? Troop sync only works on macOS for v1.')\n }\n if (!auth.owner_email) {\n throw new CliError(`${AUTH_PATH} is missing owner_email — re-run \\`apes agents spawn\\` to update.`)\n }\n\n consola.start(`Syncing ${agentName} (${host}, hostId ${hostId.slice(0, 8)}…) with ${troopUrl}`)\n\n // Report the agent's X25519 public key so troop's capability broker\n // can seal secrets to it. Without this every sealed bind 409s with\n // \"no X25519 public key yet\". The keypair is written at spawn; we read\n // the public half from ~/.config/openape/agent-x25519.key.pub.\n const pubkeyX25519 = readAgentEncryptionPublicKey() ?? undefined\n const sync = await client.sync({\n hostname: host,\n hostId,\n ownerEmail: auth.owner_email,\n ...(pubkeyX25519 ? { pubkeyX25519 } : {}),\n })\n consola.info(sync.first_sync ? '✓ first sync — agent registered' : '✓ presence updated')\n if (!pubkeyX25519) consola.warn('No X25519 public key found on disk — sealed capability secrets cannot be bound until the agent is re-spawned.')\n\n const { system_prompt: systemPrompt, tools, skills, tasks } = await client.listTasks()\n consola.info(`Pulled ${tasks.length} task${tasks.length === 1 ? '' : 's'}`)\n consola.info(`Tools enabled: ${tools.length === 0 ? '(none)' : tools.join(', ')}`)\n consola.info(`Skills: ${skills.length === 0 ? '(none)' : skills.map(s => s.name).join(', ')}`)\n\n // Sync runs as ROOT in production (the launchd plist sets\n // UserName=root so it can write /Library/LaunchDaemons/ and\n // bootstrap into the system domain — a hidden service-account\n // agent has no permission for either). Files we write into the\n // agent's home need to be owned by the agent so the bridge daemon\n // and `apes agents run` (both running AS the agent) can read\n // them. Resolve agent's uid/gid by stat-ing $HOME — that's\n // already chown'd to the agent at spawn time.\n let agentUid: number | null = null\n let agentGid: number | null = null\n if (process.geteuid?.() === 0) {\n try {\n const homeStat = statSync(homedir())\n agentUid = homeStat.uid\n agentGid = homeStat.gid\n }\n catch { /* fall through, no chowning */ }\n }\n function chownToAgent(path: string): void {\n if (agentUid !== null && agentGid !== null) {\n try { chownSync(path, agentUid, agentGid) }\n catch { /* best-effort */ }\n }\n }\n\n // Cache full task specs + agent-level config locally so the bridge\n // daemon and `apes agents run <task_id>` can execute without going\n // to network. Cache layout:\n // ~/.openape/agent/agent.json — { systemPrompt }\n // ~/.openape/agent/tasks/<task_id>.json\n const agentDir = join(homedir(), '.openape', 'agent')\n mkdirSync(agentDir, { recursive: true })\n chownToAgent(join(homedir(), '.openape'))\n chownToAgent(agentDir)\n const agentJsonPath = join(agentDir, 'agent.json')\n writeFileSync(\n agentJsonPath,\n `${JSON.stringify({ systemPrompt, tools }, null, 2)}\\n`,\n { mode: 0o600 },\n )\n chownToAgent(agentJsonPath)\n mkdirSync(TASK_CACHE_DIR, { recursive: true })\n chownToAgent(TASK_CACHE_DIR)\n for (const task of tasks) {\n const path = join(TASK_CACHE_DIR, `${task.taskId}.json`)\n writeFileSync(path, `${JSON.stringify(task, null, 2)}\\n`, { mode: 0o600 })\n chownToAgent(path)\n }\n\n // SOUL.md retired — the per-agent persona is now part of\n // `systemPrompt` (above) which the bridge composes into the\n // system message on every turn. Any pre-existing\n // `~/.openape/agent/SOUL.md` file on disk is left in place so a\n // legacy bridge / agent runtime that still reads it keeps\n // working until upgraded; nothing here writes or overwrites it.\n\n // Skills mirror — one-way sync from troop. Anything currently\n // on disk that's not in the response gets pruned, so disabling\n // or deleting a skill in troop UI takes effect on the next sync\n // (instead of leaving stale SKILL.md files behind that the\n // available_skills block would still list).\n const skillsDir = join(agentDir, 'skills')\n mkdirSync(skillsDir, { recursive: true })\n chownToAgent(skillsDir)\n const incomingNames = new Set(skills.map(s => s.name))\n // Prune\n try {\n for (const entry of readdirSync(skillsDir)) {\n if (incomingNames.has(entry)) continue\n try { rmSync(join(skillsDir, entry), { recursive: true, force: true }) }\n catch { /* best-effort prune; next sync retries */ }\n }\n }\n catch { /* directory just created, nothing to prune */ }\n // Write\n for (const skill of skills) {\n const skillDir = join(skillsDir, skill.name)\n mkdirSync(skillDir, { recursive: true })\n chownToAgent(skillDir)\n const skillPath = join(skillDir, 'SKILL.md')\n writeFileSync(skillPath, skill.body.endsWith('\\n') ? skill.body : `${skill.body}\\n`, { mode: 0o600 })\n chownToAgent(skillPath)\n }\n\n // Cron tasks no longer get a per-task launchd plist (#347 was the\n // last attempt — too many failure modes for hidden agents). The\n // chat-bridge daemon's CronRunner ticks every 60s, reads these\n // task specs and fires the ones whose cron matches inside the\n // already-running ApesRpcSession. Sync just keeps the cache fresh.\n\n consola.success('Sync complete.')\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { hostname } from 'node:os'\n\n// Stable hardware-rooted host identifier on macOS. We pull\n// IOPlatformUUID via `ioreg`, which survives hostname changes,\n// disk wipes that preserve hardware (e.g. macOS reinstalls), and\n// most other operator-side reshuffles. Replacing the SoC / logic\n// board changes it; that's the intended \"different host\" signal.\n//\n// Returns a lowercase string with no surrounding whitespace. Empty\n// string on failure (we never throw — the caller decides what to do\n// when the host can't be identified).\nexport function getHostId(): string {\n try {\n const output = execFileSync(\n '/usr/sbin/ioreg',\n ['-d2', '-c', 'IOPlatformExpertDevice'],\n { encoding: 'utf8', timeout: 2000 },\n )\n const match = output.match(/\"IOPlatformUUID\"\\s*=\\s*\"([^\"]+)\"/)\n return match ? match[1]!.trim().toLowerCase() : ''\n }\n catch {\n return ''\n }\n}\n\nexport function getHostname(): string {\n try { return hostname() }\n catch { return '' }\n}\n","import { defineCommand } from 'citty'\nimport { authorizeNestCommand } from './authorize'\nimport { destroyNestCommand } from './destroy'\nimport { enrollNestCommand } from './enroll'\nimport { installNestCommand } from './install'\nimport { listNestCommand } from './list'\nimport { spawnNestCommand } from './spawn'\nimport { uninstallNestCommand } from './uninstall'\n\nexport const nestCommand = defineCommand({\n meta: {\n name: 'nest',\n description: 'Manage the local Nest control-plane daemon. One-time setup: `install` → `enroll` → `authorize`. Day-to-day: `list` / `spawn` / `destroy`. As of Phase D the Nest is a long-running CLIENT — commands talk to it via filesystem intent files in $NEST_HOME/intents (mode 770, group _openape_nest) instead of HTTP.',\n },\n subCommands: {\n install: installNestCommand,\n enroll: enrollNestCommand,\n authorize: authorizeNestCommand,\n list: listNestCommand,\n spawn: spawnNestCommand,\n destroy: destroyNestCommand,\n uninstall: uninstallNestCommand,\n },\n})\n","// `apes nest authorize` — set the YOLO-policy on the local nest's\n// DDISA-agent identity so its grant-creation hits auto-approve.\n//\n// Implementation: shells out to `apes yolo set <nest-email> ...`. The\n// YOLO-management surface is generic (any agent), so it lives in\n// `apes yolo`; this command is just the nest-specific wrapper that\n// fills in the right defaults (mode=allow-list, allow_patterns\n// covering nest-managed agent lifecycle ops).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError } from '../../errors'\nimport { NEST_DATA_DIR } from './enroll'\n\ninterface NestAuth {\n email: string\n}\n\nconst DEFAULT_ALLOW_PATTERNS = [\n // Caller → Nest API gates. The new-style flow: `apes nest <op>`\n // requests a grant with audience='nest' and command=['nest','<op>',\n // ...]. Patrick's YOLO auto-approves these so the local Nest API\n // is gated cryptographically without a per-call human prompt.\n 'nest status',\n 'nest list',\n // spawn uses a wildcard-name grant (one approval, any name)\n 'nest spawn',\n // destroy stays per-name (typed in command), so the YOLO pattern\n // matches the per-name shape `nest destroy igor18`.\n 'nest destroy *',\n // Inner spawn/destroy grants the nest itself triggers via\n // `apes run --as root --wait -- apes agents spawn|destroy`.\n 'apes agents spawn *',\n 'apes agents destroy *',\n 'apes agents sync',\n // Inner setup.sh-grant — `apes agents spawn` itself shells out to\n // `apes run --as root --wait -- bash <tempdir>/setup.sh` to do the\n // dscl/launchctl/heredoc-write work. Path looks like\n // `bash /var/folders/.../apes-spawn-<name>-XXXX/setup.sh`. The narrow\n // glob below limits the auto-approval to that exact lifecycle path\n // — `bash *` would be unsafe.\n 'bash *apes-spawn-*setup.sh',\n // Bridge invocation. The grant request escapes-helper sends to the\n // IdP contains the *inner* command only — `apes run --as <agent> --`\n // is the wrapper that gets unwrapped before grant creation. So the\n // YOLO target string is just the agent-runtime binary name, not\n // the full wrapped invocation. We list both the new canonical\n // name and the legacy alias — pm2 ecosystem.config.js files\n // written before @openape/ape-agent@2.0.0 still use the old name.\n 'ape-agent',\n 'openape-chat-bridge',\n // Phase E: per-agent pm2 management. The Nest shells out\n // `apes run --as <agent> -- bash /var/openape/agents/<agent>/start.sh`\n // (the start.sh sets HOME/PM2_HOME and redirects pm2's stdio so the\n // god-daemon detach doesn't block our exec parent), plus\n // `apes run --as <agent> -- pm2 delete openape-bridge-<agent>` for teardown.\n 'bash /var/openape/agents/*/start.sh',\n 'pm2 delete openape-bridge-*',\n 'pm2 jlist',\n]\n\nexport const authorizeNestCommand = defineCommand({\n meta: {\n name: 'authorize',\n description: 'Set the YOLO-policy that lets the local nest spawn/destroy without per-call DDISA prompts (wraps `apes yolo set`)',\n },\n args: {\n 'allow': {\n type: 'string',\n description: 'Override allow_patterns (comma-separated globs). Default: nest-managed agent lifecycle.',\n },\n 'expires-in': {\n type: 'string',\n description: 'Optional duration like 30d, 6h. Omit for no expiry.',\n },\n },\n async run({ args }) {\n const nestAuthPath = join(NEST_DATA_DIR, '.config', 'apes', 'auth.json')\n if (!existsSync(nestAuthPath)) {\n throw new CliError('Nest not enrolled. Run `apes nest enroll` first.')\n }\n const nestAuth = JSON.parse(readFileSync(nestAuthPath, 'utf8')) as NestAuth\n if (!nestAuth.email) throw new CliError(`${nestAuthPath} has no email`)\n\n const allow = (args.allow as string | undefined) ?? DEFAULT_ALLOW_PATTERNS.join(',')\n\n consola.info(`Configuring YOLO-policy on ${nestAuth.email} via \\`apes yolo set\\`…`)\n\n const cmdArgs = [\n 'yolo', 'set', nestAuth.email,\n '--mode', 'allow-list',\n '--allow', allow,\n ]\n if (typeof args['expires-in'] === 'string' && args['expires-in']) {\n cmdArgs.push('--expires-in', args['expires-in'])\n }\n\n try {\n execFileSync('apes', cmdArgs, { stdio: 'inherit' })\n }\n catch (err) {\n throw new CliError(err instanceof Error ? err.message : String(err))\n }\n consola.success('Nest-driven agent lifecycle is now zero-prompt.')\n consola.info('Test: apes agents spawn <name> via the nest API → no DDISA prompt.')\n },\n})\n","// `apes nest enroll` — create a DDISA agent identity for the local nest.\n//\n// The Nest needs its own identity (separate from the human) so its\n// privileged ops (apes run --as root -- apes agents spawn <name>) hit\n// the IdP grant-creation flow as the *Nest*, where a Nest-scoped\n// YOLO-policy can auto-approve them. Without that, the Nest would have\n// to either re-prompt the human on every spawn (today's Stage 1) or\n// share the human's identity (security regression).\n//\n// Identity layout:\n// ~/.openape/nest/.ssh/id_ed25519 private key\n// ~/.openape/nest/.ssh/id_ed25519.pub public key (ssh-ed25519 …)\n// ~/.openape/nest/.config/apes/auth.json agent-token + email\n//\n// The nest-daemon's launchd plist sets HOME=~/.openape/nest (set by\n// `apes nest install`), so apes-CLI subprocesses spawned by the daemon\n// pick up THIS auth.json automatically — no env-var plumbing needed.\n\nimport { hostname, homedir } from 'node:os'\nimport { existsSync, mkdirSync, writeFileSync, chmodSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\nimport {\n buildAgentAuthJson,\n issueAgentToken,\n registerAgentAtIdp,\n} from '../../lib/agent-bootstrap'\nimport { generateKeyPairInMemory } from '../../lib/keygen'\n\nexport const NEST_DATA_DIR = join(homedir(), '.openape', 'nest')\n\nfunction nestAgentName(): string {\n // Stable + recognisable — lowercase host, dashes only. The IdP-side\n // validateAgentName regex is /^[a-z][a-z0-9-]{0,23}$/ so we keep\n // under that ceiling and skip illegal chars.\n const raw = hostname().toLowerCase()\n // Strip everything after first dot (\"MinivonPatrick.fritz.box\" → \"minivonpatrick\"),\n // map non-alphanum to dashes, collapse runs.\n const head = raw.split('.')[0] ?? raw\n const safe = head.replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-+|-+$/g, '')\n const trimmed = safe.slice(0, 16) // leave room for `nest-` prefix\n return `nest-${trimmed || 'host'}`\n}\n\nexport const enrollNestCommand = defineCommand({\n meta: {\n name: 'enroll',\n description: 'Register the local nest as a DDISA agent at the IdP. One-time per machine. Required before `apes nest authorize` so YOLO-policies have a target identity.',\n },\n args: {\n name: {\n type: 'string',\n description: 'Override the nest agent name (default: nest-<short-hostname>)',\n },\n force: {\n type: 'boolean',\n description: 'Re-enroll even if ~/.openape/nest/.config/apes/auth.json already exists',\n },\n },\n async run({ args }) {\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP configured. Run `apes login <email>` first.')\n }\n const ownerAuth = loadAuth()\n if (!ownerAuth?.email) {\n throw new CliError('Run `apes login <email>` first — nest enroll attaches the new identity to your owner account.')\n }\n\n const name = (args.name as string | undefined) || nestAgentName()\n const authPath = join(NEST_DATA_DIR, '.config', 'apes', 'auth.json')\n if (existsSync(authPath) && !args.force) {\n throw new CliError(`Nest already enrolled at ${authPath}. Pass --force to re-enroll.`)\n }\n\n const sshDir = join(NEST_DATA_DIR, '.ssh')\n const configDir = join(NEST_DATA_DIR, '.config', 'apes')\n mkdirSync(sshDir, { recursive: true })\n mkdirSync(configDir, { recursive: true })\n\n consola.start(`Generating keypair for ${name}…`)\n const { privatePem, publicSshLine } = generateKeyPairInMemory()\n writeFileSync(join(sshDir, 'id_ed25519'), `${privatePem.trimEnd()}\\n`, { mode: 0o600 })\n writeFileSync(join(sshDir, 'id_ed25519.pub'), `${publicSshLine}\\n`, { mode: 0o644 })\n chmodSync(sshDir, 0o700)\n\n consola.start(`Registering nest at ${idp}…`)\n const registration = await registerAgentAtIdp({ name, publicKey: publicSshLine, idp })\n consola.success(`Registered as ${registration.email}`)\n\n consola.start('Issuing nest access token…')\n const { token, expiresIn } = await issueAgentToken({\n idp,\n agentEmail: registration.email,\n privateKeyPem: privatePem,\n })\n\n const authJson = buildAgentAuthJson({\n idp,\n accessToken: token,\n email: registration.email,\n expiresAt: Math.floor(Date.now() / 1000) + expiresIn,\n keyPath: join(sshDir, 'id_ed25519'),\n ownerEmail: ownerAuth.email,\n })\n writeFileSync(authPath, authJson, { mode: 0o600 })\n chmodSync(configDir, 0o700)\n\n consola.success(`Nest enrolled — auth.json at ${authPath}`)\n consola.info('')\n consola.info('Next: configure the YOLO-policy so the nest can spawn/destroy without prompts:')\n consola.info('')\n consola.info(' apes nest authorize')\n },\n})\n","// `apes nest destroy <name>` — Phase F: direct shell-out to\n// `apes run --as root -- apes agents destroy <name>`. The destroy\n// command removes the registry entry; the Nest watches the file\n// and pm2-deletes the bridge automatically.\n\nimport { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliExit } from '../../errors'\n\nexport const destroyNestCommand = defineCommand({\n meta: {\n name: 'destroy',\n 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.',\n },\n args: {\n name: { type: 'positional', required: true, description: 'Agent name to destroy' },\n },\n async run({ args }) {\n const name = String(args.name)\n try {\n execFileSync('apes', ['run', '--as', 'root', '--wait', '--', 'apes', 'agents', 'destroy', name, '--force'], { stdio: 'inherit' })\n consola.success(`Nest will tear down ${name}'s pm2 process on its next reconcile (≤2s).`)\n }\n catch (err: unknown) {\n const status = (err as { status?: number }).status ?? 1\n throw new CliExit(status)\n }\n },\n})\n","// `apes nest install` — bootstrap the local nest-daemon.\n//\n// Stage 1 MVP: the daemon runs as the human user (a future stage will\n// migrate to a dedicated `_openape_nest` service-account). Setup is\n// three things:\n//\n// 1. Write ~/Library/LaunchAgents/ai.openape.nest.plist (user domain\n// — autostarts at login, KeepAlive=true)\n// 2. `launchctl bootstrap` the plist into the user-launchd domain\n// 3. Print instructions for the always-grant the user needs to\n// approve once at id.openape.ai/grant-approval\n//\n// Idempotent — re-running on an already-installed nest just re-bootstraps\n// (effectively a restart).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir, userInfo } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { APES_AGENTS_ADAPTER_TOML } from './apes-agents-adapter'\nimport { NEST_DATA_DIR } from './enroll'\n\nconst PLIST_LABEL = 'ai.openape.nest'\n\nfunction plistPath(): string {\n return join(homedir(), 'Library', 'LaunchAgents', `${PLIST_LABEL}.plist`)\n}\n\nfunction escape(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')\n}\n\ninterface PlistArgs {\n nestBin: string\n apesBin: string\n /** macOS user home — used for log file path + PATH (where bun lives). */\n userHome: string\n /**\n * Nest data dir — `HOME` for the daemon process so apes-cli reads\n * the nest's own auth.json (not the human's) when invoking\n * subprocesses like `apes run --as root -- apes agents spawn`.\n */\n nestHome: string\n port: number\n}\n\nfunction buildPlist(args: PlistArgs): string {\n const logsDir = join(args.userHome, 'Library', 'Logs')\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${escape(PLIST_LABEL)}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escape(args.nestBin)}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${escape(args.nestHome)}</string>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key><string>${escape(args.nestHome)}</string>\n <key>PATH</key><string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n <key>OPENAPE_NEST_PORT</key><string>${args.port}</string>\n <key>OPENAPE_APES_BIN</key><string>${escape(args.apesBin)}</string>\n </dict>\n <key>StandardOutPath</key>\n <string>${escape(logsDir)}/openape-nest.log</string>\n <key>StandardErrorPath</key>\n <string>${escape(logsDir)}/openape-nest.log</string>\n</dict>\n</plist>\n`\n}\n\n/**\n * Bundled `apes-agents` shapes adapter — written into\n * `~/.openape/shapes/adapters/` so a capability-grant with selector\n * `name=*` can cover any agent name (selectorValueMatches glob).\n * Without this adapter, every spawn/destroy hits exact-arg matching\n * and the always-grant doesn't reuse.\n */\nfunction installAdapter(): boolean {\n const target = join(homedir(), '.openape', 'shapes', 'adapters', 'apes-agents.toml')\n mkdirSync(dirname(target), { recursive: true })\n let existing = ''\n try { existing = readFileSync(target, 'utf8') }\n catch { /* not yet */ }\n if (existing === APES_AGENTS_ADAPTER_TOML) return false\n writeFileSync(target, APES_AGENTS_ADAPTER_TOML, { mode: 0o644 })\n consola.success(`Wrote shapes adapter ${target}`)\n return true\n}\n\n/**\n * Write `APE_CHAT_BRIDGE_MODEL=<value>` to `~/litellm/.env` AND to\n * the nest's own `litellm/.env` (under `NEST_DATA_DIR`). The same\n * file resolveBridgeConfig (in lib/llm-bridge.ts) reads at\n * `apes [nest|agents] spawn` time — but it resolves the path via\n * `homedir()`, so:\n *\n * - Patrick-driven spawn (`apes agents spawn …` from a shell)\n * reads `~/litellm/.env`.\n * - Nest-driven spawn (TroopWs handler running as the daemon)\n * reads `~/.openape/nest/litellm/.env` because the launchd plist\n * pins `HOME=NEST_DATA_DIR` for the daemon process.\n *\n * Writing to both keeps the model default consistent between the\n * two entry points — without this, freshly-installed nests had no\n * `APE_CHAT_BRIDGE_MODEL` line and the bridge crash-looped on every\n * spawn-from-troop-UI with `fatal: APE_CHAT_BRIDGE_MODEL is not set`.\n *\n * Idempotent: replaces an existing line in place, appends otherwise.\n */\nfunction writeBridgeModelDefault(model: string): void {\n for (const envDir of [join(homedir(), 'litellm'), join(NEST_DATA_DIR, 'litellm')]) {\n const envFile = join(envDir, '.env')\n mkdirSync(envDir, { recursive: true })\n let lines: string[] = []\n if (existsSync(envFile)) {\n lines = readFileSync(envFile, 'utf8').split('\\n').filter(l => !l.startsWith('APE_CHAT_BRIDGE_MODEL='))\n }\n lines.push(`APE_CHAT_BRIDGE_MODEL=${model}`)\n while (lines.length > 0 && lines.at(-1)!.trim() === '') lines.pop()\n writeFileSync(envFile, `${lines.join('\\n')}\\n`, { mode: 0o600 })\n }\n}\n\nfunction findBinary(name: string): string {\n for (const dir of [\n join(homedir(), '.bun', 'bin'),\n '/opt/homebrew/bin',\n '/usr/local/bin',\n '/usr/bin',\n ]) {\n const p = join(dir, name)\n if (existsSync(p)) return p\n }\n throw new Error(`could not locate ${name} on PATH; install it first`)\n}\n\nexport const installNestCommand = defineCommand({\n meta: {\n name: 'install',\n description: 'Install + start the local nest-daemon (idempotent — re-running just restarts)',\n },\n args: {\n port: {\n type: 'string',\n description: 'Port for the nest HTTP API (default: 9091)',\n },\n 'bridge-model': {\n type: 'string',\n description: 'Default model for ape-agent spawns. Persisted as APE_CHAT_BRIDGE_MODEL in ~/litellm/.env so every `apes [nest|agents] spawn` picks it up automatically. Common values: `gpt-5.4` (ChatGPT-only LiteLLM proxy), `claude-haiku-4-5` (Anthropic-only). Re-run install with a new value to overwrite.',\n },\n },\n async run({ args }) {\n const homeDir = homedir()\n const port = Number(args.port ?? 9091)\n if (!Number.isInteger(port) || port < 1024 || port > 65535) {\n throw new Error(`invalid port ${port}`)\n }\n const nestBin = findBinary('openape-nest')\n const apesBin = findBinary('apes')\n\n consola.info(`Installing nest at ${plistPath()}`)\n consola.info(` nest binary: ${nestBin}`)\n consola.info(` apes binary: ${apesBin}`)\n consola.info(` HTTP port: ${port}`)\n\n if (typeof args['bridge-model'] === 'string' && args['bridge-model']) {\n writeBridgeModelDefault(args['bridge-model'])\n consola.success(`Default bridge model set to ${args['bridge-model']} (in ~/litellm/.env)`)\n }\n\n // Adapter first — capability-grants need it.\n installAdapter()\n\n mkdirSync(join(homeDir, 'Library', 'LaunchAgents'), { recursive: true })\n\n // nest-data-dir is HOME for the daemon — apes-cli subprocesses\n // it spawns (apes run --as root --) read auth.json from the nest's\n // own enrolled identity, not the human's, so YOLO-policy on the\n // nest-agent gates them.\n mkdirSync(NEST_DATA_DIR, { recursive: true })\n const desired = buildPlist({ nestBin, apesBin, userHome: homeDir, nestHome: NEST_DATA_DIR, port })\n let existing = ''\n try { existing = readFileSync(plistPath(), 'utf8') }\n catch { /* not yet installed */ }\n\n if (existing !== desired) {\n writeFileSync(plistPath(), desired, { mode: 0o644 })\n consola.success('Wrote launchd plist')\n }\n else {\n consola.info('plist already up to date')\n }\n\n // Idempotent (re)load. bootout silently no-ops if the job isn't\n // loaded yet; bootstrap fails loud if the plist has a syntax error,\n // which is what we want.\n const uid = userInfo().uid\n try {\n execFileSync('/bin/launchctl', ['bootout', `gui/${uid}/${PLIST_LABEL}`], { stdio: 'ignore' })\n }\n catch { /* not loaded */ }\n execFileSync('/bin/launchctl', ['bootstrap', `gui/${uid}`, plistPath()], { stdio: 'inherit' })\n consola.success(`Nest daemon bootstrapped — http://127.0.0.1:${port}`)\n\n consola.info('')\n consola.info('Next steps for zero-prompt spawn — both one-time:')\n consola.info('')\n consola.info(' 1. apes nest enroll # register nest as DDISA agent (creates own auth.json)')\n consola.info(' 2. apes nest authorize # set YOLO-policy on the nest agent')\n consola.info('')\n consola.info('After that, every `POST http://127.0.0.1:9091/agents` runs without DDISA prompts.')\n },\n})\n","// Bundled `apes-agents` shapes adapter — written into\n// ~/.openape/shapes/adapters/apes-agents.toml by `apes nest install`.\n// Inlined as a TS constant (vs. shipping the .toml file) because tsup\n// only bundles JS/TS — a sibling .toml gets stripped from dist.\n\nexport const APES_AGENTS_ADAPTER_TOML = `schema = \"openape-shapes/v1\"\n\n# Adapter for the \\`apes agents\\` subtree — written by \\`apes nest install\\`.\n# A capability-grant with selector \\`name=*\\` covers any agent name\n# (selectorValueMatches treats '*' as a glob), letting the nest spawn\n# and destroy without per-agent DDISA prompts.\n\n[cli]\nid = \"apes-agents\"\nexecutable = \"apes\"\naudience = \"shapes\"\nversion = \"1\"\n\n# ══════════════════════════════════════════════════════\n# AGENT LIFECYCLE — spawn / destroy / sync\n# ══════════════════════════════════════════════════════\n\n[[operation]]\nid = \"agents.spawn\"\ncommand = [\"agents\", \"spawn\"]\npositionals = [\"name\"]\ndisplay = \"Spawn agent {name}\"\naction = \"create\"\nrisk = \"high\"\nresource_chain = [\"agents:name={name}\"]\n\n[[operation]]\nid = \"agents.destroy\"\ncommand = [\"agents\", \"destroy\"]\npositionals = [\"name\"]\ndisplay = \"Destroy agent {name}\"\naction = \"delete\"\nrisk = \"critical\"\nresource_chain = [\"agents:name={name}\"]\n\n[[operation]]\nid = \"agents.sync\"\ncommand = [\"agents\", \"sync\"]\ndisplay = \"Sync agent state with troop\"\naction = \"edit\"\nrisk = \"low\"\nresource_chain = [\"agents:*\"]\n\n[[operation]]\nid = \"agents.list\"\ncommand = [\"agents\", \"list\"]\ndisplay = \"List agents\"\naction = \"list\"\nrisk = \"low\"\nresource_chain = [\"agents:*\"]\n\n[[operation]]\nid = \"agents.allow\"\ncommand = [\"agents\", \"allow\"]\npositionals = [\"name\", \"peer_email\"]\ndisplay = \"Allow agent {name} to accept contact requests from {peer_email}\"\naction = \"edit\"\nrisk = \"medium\"\nresource_chain = [\"agents:name={name}\", \"allowlist:email={peer_email}\"]\n`\n","// `apes nest list` — Phase F: read the registry directly. No\n// inter-process communication needed; the file is shared between\n// Nest + apes-cli (mode 660 group _openape_nest, Patrick is in the\n// group post-migration).\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { readNestRegistry } from '../../lib/nest-registry'\n\nexport const listNestCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List agents registered with the local nest. Reads /var/openape/nest/agents.json directly.',\n },\n args: {\n json: { type: 'boolean', description: 'JSON output for scripts' },\n },\n async run({ args }) {\n const reg = readNestRegistry()\n if (args.json) {\n console.log(JSON.stringify(reg, null, 2))\n return\n }\n if (reg.agents.length === 0) {\n consola.info('(no agents registered with this nest)')\n return\n }\n consola.info(`${reg.agents.length} agent(s) registered with this nest:`)\n for (const a of reg.agents) {\n const bridge = a.bridge ? ' bridge=on' : ''\n consola.info(` ${a.name.padEnd(16)} uid=${String(a.uid).padEnd(5)} home=${a.home}${bridge}`)\n }\n },\n})\n","// `apes nest spawn <name>` — Phase F (#sim-arch): direct shell-out to\n// `apes run --as root --wait -- apes agents spawn ...`. The spawn\n// command itself writes to the Nest's `agents.json` registry; the\n// Nest watches the file and starts the bridge via pm2 automatically.\n// No intent-channel, no HTTP API — the CLI just does the work.\n\nimport { execFileSync } from 'node:child_process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliExit } from '../../errors'\n\nexport const spawnNestCommand = defineCommand({\n meta: {\n name: 'spawn',\n 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.',\n },\n args: {\n name: { type: 'positional', required: true, description: 'Agent name (lowercase, [a-z0-9-], max 24 chars)' },\n 'no-bridge': { type: 'boolean', description: 'Skip installing the chat-bridge daemon (default: install it)' },\n 'bridge-key': { type: 'string', description: 'Override LITELLM_API_KEY (default: read from ~/litellm/.env)' },\n 'bridge-base-url': { type: 'string', description: 'Override LITELLM_BASE_URL' },\n 'bridge-model': { type: 'string', description: 'Override APE_CHAT_BRIDGE_MODEL' },\n },\n async run({ args }) {\n const name = String(args.name)\n const apesArgs = [\n 'run', '--as', 'root', '--wait', '--', 'apes', 'agents', 'spawn', name,\n ]\n // Inner `apes agents spawn` installs the bridge by default; pass the\n // opt-out through when the user gave us --no-bridge here.\n if (args['no-bridge']) apesArgs.push('--no-bridge')\n if (typeof args['bridge-key'] === 'string') apesArgs.push('--bridge-key', args['bridge-key'])\n if (typeof args['bridge-base-url'] === 'string') apesArgs.push('--bridge-base-url', args['bridge-base-url'])\n if (typeof args['bridge-model'] === 'string') apesArgs.push('--bridge-model', args['bridge-model'])\n\n try {\n execFileSync('apes', apesArgs, { stdio: 'inherit' })\n consola.success(`Nest will pick up ${name} on its next reconcile (≤2s).`)\n }\n catch (err: unknown) {\n const status = (err as { status?: number }).status ?? 1\n throw new CliExit(status)\n }\n },\n})\n","// `apes nest uninstall` — bootout + remove the nest-daemon's launchd\n// plist. Doesn't touch the registered agents or their macOS users —\n// they stay; only the supervisor goes away. After uninstall, agents\n// can still be re-supervised by re-installing later (registry persists\n// at ~/.openape/nest/agents.json).\n\nimport { execFileSync } from 'node:child_process'\nimport { existsSync, unlinkSync } from 'node:fs'\nimport { homedir, userInfo } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nconst PLIST_LABEL = 'ai.openape.nest'\n\nexport const uninstallNestCommand = defineCommand({\n meta: {\n name: 'uninstall',\n description: 'Stop + remove the local nest-daemon (registry + agents preserved)',\n },\n async run() {\n const uid = userInfo().uid\n const path = join(homedir(), 'Library', 'LaunchAgents', `${PLIST_LABEL}.plist`)\n try {\n execFileSync('/bin/launchctl', ['bootout', `gui/${uid}/${PLIST_LABEL}`], { stdio: 'ignore' })\n consola.success('Nest daemon stopped')\n }\n catch {\n consola.info('Nest daemon was not loaded')\n }\n if (existsSync(path)) {\n unlinkSync(path)\n consola.success(`Removed ${path}`)\n }\n consola.info('Registry at ~/.openape/nest/agents.json kept — re-run `apes nest install` to resume supervision.')\n },\n})\n","import { defineCommand } from 'citty'\nimport { yoloClearCommand } from './clear'\nimport { yoloSetCommand } from './set'\nimport { yoloShowCommand } from './show'\n\nexport const yoloCommand = defineCommand({\n meta: {\n name: 'yolo',\n description: 'Manage YOLO-policies on DDISA agents you own — auto-approve grant patterns at the IdP layer (allow-list) or block dangerous ones outright (deny-list).',\n },\n subCommands: {\n set: yoloSetCommand,\n show: yoloShowCommand,\n clear: yoloClearCommand,\n },\n})\n","// `apes yolo clear <agent-email>` — remove the YOLO-policy from a\n// DDISA agent. After clear, every grant request goes through normal\n// human approval. Useful for revocation: drop the policy and the agent\n// can no longer auto-approve anything until you set a new one.\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const yoloClearCommand = defineCommand({\n meta: {\n name: 'clear',\n description: 'Remove the YOLO-policy from a DDISA agent (subsequent grants need human approval)',\n },\n args: {\n email: {\n type: 'positional',\n description: 'Target agent email',\n required: true,\n },\n },\n async run({ args }) {\n const ownerAuth = loadAuth()\n if (!ownerAuth?.access_token) {\n throw new CliError('Run `apes login <email>` first.')\n }\n const idp = getIdpUrl()\n if (!idp) throw new CliError('No IdP configured.')\n\n const email = args.email as string\n const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`\n const res = await fetch(url, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${ownerAuth.access_token}` },\n })\n if (!res.ok && res.status !== 404) {\n const text = await res.text().catch(() => '')\n throw new CliError(`DELETE /yolo-policy failed (${res.status}): ${text}`)\n }\n consola.success(`YOLO-policy cleared on ${email}`)\n },\n})\n","// `apes yolo set <agent-email>` — write a YOLO-policy on a DDISA agent\n// you own. The IdP's grant-creation hook evaluates the agent's policy\n// before opening the human-approval flow; allow_patterns matches mean\n// \"auto-approve, no prompt\" (mode='allow-list') and deny_patterns means\n// \"block without asking\" (mode='deny-list').\n//\n// PUT-shape mirrors the IdP endpoint\n// `/api/users/<email>/yolo-policy` (modules/nuxt-auth-idp). Owner-auth\n// is enforced server-side: only the agent's owner / approver / admin\n// can change the policy, regardless of who's invoking the CLI.\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\nconst VALID_MODES = ['allow-list', 'deny-list'] as const\ntype Mode = typeof VALID_MODES[number]\n\nexport const yoloSetCommand = defineCommand({\n meta: {\n name: 'set',\n description: 'Write a YOLO-policy on a DDISA agent you own',\n },\n args: {\n 'email': {\n type: 'positional',\n description: 'Target agent email (e.g. nest-mac-cb6bf26a+patrick+example_com@id.openape.ai)',\n required: true,\n },\n 'mode': {\n type: 'string',\n description: 'Policy mode (allow-list | deny-list)',\n },\n 'allow': {\n type: 'string',\n description: 'Allow patterns — comma-separated bash globs (e.g. \"apes agents spawn *,apes agents sync\")',\n },\n 'deny': {\n type: 'string',\n description: 'Deny patterns — comma-separated bash globs',\n },\n 'deny-risk': {\n type: 'string',\n description: 'Deny grants at this risk level or above (low|medium|high|critical)',\n },\n 'expires-in': {\n type: 'string',\n description: 'Optional expiry like 30d, 6h, 2w. Omit for no expiry.',\n },\n },\n async run({ args }) {\n const ownerAuth = loadAuth()\n if (!ownerAuth?.access_token) {\n throw new CliError('Run `apes login <email>` first.')\n }\n const idp = getIdpUrl()\n if (!idp) throw new CliError('No IdP configured.')\n\n const email = args.email as string\n const mode = (args.mode as string | undefined) ?? 'allow-list'\n if (!VALID_MODES.includes(mode as Mode)) {\n throw new CliError(`mode must be one of: ${VALID_MODES.join(', ')}`)\n }\n const allowPatterns = parseList(args.allow as string | undefined)\n const denyPatterns = parseList(args.deny as string | undefined)\n const denyRiskThreshold = (args['deny-risk'] as string | undefined) ?? null\n const expiresAt = parseExpiresIn(args['expires-in'] as string | undefined)\n\n consola.info(`Setting YOLO-policy on ${email}`)\n consola.info(` mode: ${mode}`)\n if (allowPatterns.length) consola.info(` allow_patterns: ${allowPatterns.join(', ')}`)\n if (denyPatterns.length) consola.info(` deny_patterns: ${denyPatterns.join(', ')}`)\n if (denyRiskThreshold) consola.info(` deny_risk: ${denyRiskThreshold}`)\n if (expiresAt) consola.info(` expires_at: ${new Date(expiresAt * 1000).toISOString()}`)\n\n const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`\n const res = await fetch(url, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${ownerAuth.access_token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n mode,\n allowPatterns,\n denyPatterns,\n denyRiskThreshold,\n expiresAt: expiresAt ?? null,\n }),\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new CliError(`PUT /yolo-policy failed (${res.status}): ${text}`)\n }\n consola.success(`YOLO-policy applied to ${email}`)\n },\n})\n\nfunction parseList(s: string | undefined): string[] {\n if (!s) return []\n return s.split(',').map(p => p.trim()).filter(Boolean)\n}\n\nfunction parseExpiresIn(s: string | undefined): number | null {\n if (!s) return null\n const m = s.match(/^(\\d+)([hdw])$/)\n if (!m) throw new CliError(`Invalid --expires-in \"${s}\" — expected forms like 30d, 6h, 2w`)\n const n = Number(m[1])\n const unit = m[2]\n const seconds = unit === 'h' ? 3600 : unit === 'd' ? 86400 : 7 * 86400\n return Math.floor(Date.now() / 1000) + n * seconds\n}\n","// `apes yolo show <agent-email>` — print the YOLO-policy currently set\n// on an agent. Returns the empty default (`mode: deny-list`, no patterns)\n// when no policy has been written. JSON output via --json.\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth } from '../../config'\nimport { CliError } from '../../errors'\n\ninterface YoloPolicy {\n mode: string\n allowPatterns: string[]\n denyPatterns: string[]\n denyRiskThreshold: string | null\n expiresAt: number | null\n}\n\nexport const yoloShowCommand = defineCommand({\n meta: {\n name: 'show',\n description: 'Print the YOLO-policy currently set on a DDISA agent',\n },\n args: {\n email: {\n type: 'positional',\n description: 'Target agent email',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'JSON output for scripts',\n },\n },\n async run({ args }) {\n const ownerAuth = loadAuth()\n if (!ownerAuth?.access_token) {\n throw new CliError('Run `apes login <email>` first.')\n }\n const idp = getIdpUrl()\n if (!idp) throw new CliError('No IdP configured.')\n\n const email = args.email as string\n const url = `${idp}/api/users/${encodeURIComponent(email)}/yolo-policy`\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${ownerAuth.access_token}` },\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new CliError(`GET /yolo-policy failed (${res.status}): ${text}`)\n }\n const policy = (await res.json()) as YoloPolicy\n\n if (args.json) {\n console.log(JSON.stringify(policy, null, 2))\n return\n }\n consola.info(`YOLO-policy for ${email}`)\n consola.info(` mode: ${policy.mode}`)\n consola.info(` allow_patterns: ${policy.allowPatterns.length ? policy.allowPatterns.join(', ') : '(none)'}`)\n consola.info(` deny_patterns: ${policy.denyPatterns.length ? policy.denyPatterns.join(', ') : '(none)'}`)\n consola.info(` deny_risk: ${policy.denyRiskThreshold ?? '(none)'}`)\n consola.info(` expires_at: ${policy.expiresAt ? new Date(policy.expiresAt * 1000).toISOString() : '(never)'}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport {\n fetchRegistry,\n findAdapter,\n findConflictingAdapters,\n getInstalledDigest,\n installAdapter,\n isInstalled,\n loadAdapter,\n removeAdapter,\n searchAdapters,\n} from '../../shapes/index.js'\nimport { CliError } from '../../errors'\n\nexport const adapterCommand = defineCommand({\n meta: {\n name: 'adapter',\n description: 'Manage CLI adapters',\n },\n subCommands: {\n list: defineCommand({\n meta: {\n name: 'list',\n description: 'List available adapters',\n },\n args: {\n remote: {\n type: 'boolean',\n description: 'List adapters from the remote registry',\n default: false,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const forceRefresh = Boolean(args.refresh)\n if (args.remote) {\n const index = await fetchRegistry(forceRefresh)\n if (args.json) {\n process.stdout.write(`${JSON.stringify(index.adapters, null, 2)}\\n`)\n return\n }\n consola.info(`Registry: ${index.adapters.length} adapters (${index.generated_at})`)\n for (const a of index.adapters) {\n const installed = isInstalled(a.id, false) ? ' [installed]' : ''\n console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}${installed}`)\n }\n return\n }\n\n const index = await fetchRegistry(forceRefresh)\n const local: { id: string, source: string, digest: string }[] = []\n for (const a of index.adapters) {\n try {\n const loaded = loadAdapter(a.id)\n local.push({ id: a.id, source: loaded.source, digest: loaded.digest })\n }\n catch {\n // not installed locally\n }\n }\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(local, null, 2)}\\n`)\n return\n }\n\n if (local.length === 0) {\n consola.info('No adapters installed. Use `apes adapter list --remote` to see available adapters.')\n return\n }\n\n for (const a of local) {\n console.log(` ${a.id.padEnd(12)} ${a.source}`)\n }\n },\n }),\n\n install: defineCommand({\n meta: {\n name: 'install',\n description: 'Install an adapter from the registry',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID to install',\n required: true,\n },\n local: {\n type: 'boolean',\n description: 'Install to project-local .openape/ instead of ~/.openape/',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const ids = [String(args.id), ...args._].filter(Boolean)\n const local = Boolean(args.local)\n const index = await fetchRegistry(Boolean(args.refresh))\n\n for (const id of ids) {\n const entry = findAdapter(index, id)\n if (!entry) {\n consola.error(`Adapter \"${id}\" not found in registry. Use \\`apes adapter search ${id}\\` to search.`)\n continue\n }\n\n const conflicts = findConflictingAdapters(entry.executable, id)\n if (conflicts.length > 0) {\n for (const c of conflicts) {\n consola.warn(`Conflicting adapter found: ${c.path} (id: ${c.adapterId}, executable: ${c.executable})`)\n consola.warn(` Remove it with: apes adapter remove ${c.adapterId}`)\n }\n }\n\n const result = await installAdapter(entry, { local })\n const verb = result.updated ? 'Updated' : 'Installed'\n consola.success(`${verb} ${result.id} → ${result.path}`)\n consola.info(`Digest: ${result.digest}`)\n }\n },\n }),\n\n remove: defineCommand({\n meta: {\n name: 'remove',\n description: 'Remove an installed adapter',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID to remove',\n required: true,\n },\n local: {\n type: 'boolean',\n description: 'Remove from project-local .openape/',\n default: false,\n },\n },\n async run({ args }) {\n const ids = [String(args.id), ...args._].filter(Boolean)\n const local = Boolean(args.local)\n let failed = false\n\n for (const id of ids) {\n if (removeAdapter(id, local)) {\n consola.success(`Removed adapter: ${id}`)\n }\n else {\n consola.error(`Adapter \"${id}\" is not installed${local ? ' locally' : ''}`)\n failed = true\n }\n }\n\n if (failed)\n throw new CliError('Some adapters could not be removed')\n },\n }),\n\n info: defineCommand({\n meta: {\n name: 'info',\n description: 'Show detailed adapter information',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID',\n required: true,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const id = String(args.id)\n const index = await fetchRegistry(Boolean(args.refresh))\n const entry = findAdapter(index, id)\n if (!entry)\n throw new Error(`Adapter \"${id}\" not found in registry`)\n\n console.log(`ID: ${entry.id}`)\n console.log(`Name: ${entry.name}`)\n console.log(`Description: ${entry.description}`)\n console.log(`Category: ${entry.category}`)\n console.log(`Tags: ${entry.tags.join(', ')}`)\n console.log(`Author: ${entry.author}`)\n console.log(`Executable: ${entry.executable}`)\n console.log(`Digest: ${entry.digest}`)\n console.log(`Min version: ${entry.min_shapes_version}`)\n console.log(`URL: ${entry.download_url}`)\n\n const localDigest = getInstalledDigest(id, false)\n if (localDigest) {\n const upToDate = localDigest === entry.digest\n console.log(`Installed: yes${upToDate ? ' (up to date)' : ' (update available)'}`)\n }\n else {\n console.log(`Installed: no`)\n }\n },\n }),\n\n search: defineCommand({\n meta: {\n name: 'search',\n description: 'Search adapters in the registry',\n },\n args: {\n query: {\n type: 'positional',\n description: 'Search query',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const query = String(args.query)\n const index = await fetchRegistry(Boolean(args.refresh))\n const results = searchAdapters(index, query)\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(results, null, 2)}\\n`)\n return\n }\n\n if (results.length === 0) {\n consola.info(`No adapters matching \"${query}\"`)\n return\n }\n\n for (const a of results) {\n console.log(` ${a.id.padEnd(12)} ${a.name.padEnd(24)} ${a.category}`)\n console.log(` ${a.description}`)\n }\n },\n }),\n\n update: defineCommand({\n meta: {\n name: 'update',\n description: 'Update installed adapters',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID (omit to update all)',\n },\n yes: {\n type: 'boolean',\n description: 'Skip confirmation',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: true,\n },\n },\n async run({ args }) {\n const index = await fetchRegistry(Boolean(args.refresh))\n const targetId = args.id ? String(args.id) : undefined\n const targets = targetId\n ? [targetId]\n : index.adapters.map(a => a.id).filter(id => isInstalled(id, false))\n\n if (targets.length === 0) {\n consola.info('No adapters installed to update.')\n return\n }\n\n for (const id of targets) {\n const entry = findAdapter(index, id)\n if (!entry) {\n consola.warn(`${id}: not found in registry, skipping`)\n continue\n }\n\n const localDigest = getInstalledDigest(id, false)\n if (localDigest === entry.digest) {\n consola.info(`${id}: already up to date`)\n continue\n }\n\n if (localDigest && !args.yes) {\n consola.warn(`${id}: digest will change — existing grants for this adapter will be invalidated`)\n consola.info(` Old: ${localDigest}`)\n consola.info(` New: ${entry.digest}`)\n consola.info(' Use --yes to confirm')\n continue\n }\n\n const result = await installAdapter(entry)\n consola.success(`Updated ${result.id} → ${result.path}`)\n }\n },\n }),\n\n verify: defineCommand({\n meta: {\n name: 'verify',\n description: 'Verify installed adapter against registry digest',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Adapter ID',\n required: true,\n },\n local: {\n type: 'boolean',\n description: 'Check project-local adapter',\n default: false,\n },\n refresh: {\n type: 'boolean',\n description: 'Force refresh the registry cache',\n default: false,\n },\n },\n async run({ args }) {\n const id = String(args.id)\n const local = Boolean(args.local)\n const index = await fetchRegistry(Boolean(args.refresh))\n const entry = findAdapter(index, id)\n if (!entry)\n throw new Error(`Adapter \"${id}\" not found in registry`)\n\n const localDigest = getInstalledDigest(id, local)\n if (!localDigest)\n throw new Error(`Adapter \"${id}\" is not installed${local ? ' locally' : ''}`)\n\n if (localDigest === entry.digest) {\n consola.success(`${id}: digest matches registry`)\n }\n else {\n console.log(` Local: ${localDigest}`)\n console.log(` Registry: ${entry.digest}`)\n throw new CliError(`${id}: digest mismatch`)\n }\n },\n }),\n },\n})\n","import { execFileSync } from 'node:child_process'\nimport { hostname } from 'node:os'\nimport { basename } from 'node:path'\nimport { defineCommand } from 'citty'\nimport {\n createShapesGrant,\n extractOption,\n extractShellCommandString,\n extractWrappedCommand,\n fetchGrantToken,\n findExistingGrant,\n loadAdapter,\n loadOrInstallAdapter,\n parseShellCommand,\n resolveCommand,\n resolveGenericOrReject,\n verifyAndExecute,\n waitForGrantStatus,\n} from '../shapes/index.js'\nimport type { ResolvedCommand } from '../shapes/index.js'\nimport consola from 'consola'\nimport { getIdpUrl, isGenericFallbackEnabled, loadAuth, loadConfig } from '../config'\nimport { getPollMaxMinutes } from '../grant-poll'\nimport { apiFetch, getGrantsEndpoint } from '../http'\nimport { CliError, CliExit } from '../errors'\nimport { notifyGrantPending } from '../notifications'\nimport { checkSudoRejection, isApesSelfDispatch } from '../shell/apes-self-dispatch'\nimport { AGENT_NAME_REGEX } from '../lib/agent-bootstrap'\nimport { isDarwin, macOSUsernameForAgent, readMacOSUser } from '../lib/macos-user'\n\n/**\n * Map an agent name (`igor`) to its macOS username (`openape-agent-igor`)\n * when the prefixed dscl record exists. Returns the input unchanged for:\n * - non-Darwin platforms (escapes-helper isn't macOS-specific in theory)\n * - non-agent values like `root`, `_postgres`, etc.\n * - legacy agents that pre-date the prefix (the prefixed record is\n * absent, so we fall through and let escapes setuid to the plain\n * name — backward-compatible)\n *\n * The mapping is transparent to all callers: nest/troop-ws.ts,\n * pm2-supervisor.ts, allow.ts and operators typing `apes run --as\n * igor` keep working without knowing about the prefix.\n */\nfunction resolveRunAsTarget(runAs: string | undefined): string | undefined {\n if (!runAs) return runAs\n if (!isDarwin()) return runAs\n if (!AGENT_NAME_REGEX.test(runAs)) return runAs\n // Already prefixed (operator typed the full macOS username) — pass through.\n if (runAs.startsWith('openape-agent-')) return runAs\n const prefixed = macOSUsernameForAgent(runAs)\n if (readMacOSUser(prefixed)) return prefixed\n return runAs\n}\n\n/**\n * Returns true when the caller asked for the legacy blocking path via\n * `--wait` or `APE_WAIT=1`. Default is non-blocking (async exit).\n */\nfunction shouldWaitForGrant(args: Record<string, unknown>): boolean {\n return args.wait === true || process.env.APE_WAIT === '1'\n}\n\n/**\n * Audience of the `apes run` async info block. Drives whether the output\n * targets a human reader (short, friendly) or an AI agent (verbose, with\n * explicit polling protocol).\n *\n * Default is `'agent'` — zero-config for agent ecosystems (openclaw, Claude,\n * etc.), and humans who want brevity just set `APES_USER=human` once in\n * their shell rc. Env var wins over config.toml; unknown values fall back\n * to the agent default.\n */\ntype ApesUserMode = 'agent' | 'human'\n\nfunction getUserMode(): ApesUserMode {\n const envValue = process.env.APES_USER\n if (envValue === 'human')\n return 'human'\n if (envValue === 'agent')\n return 'agent'\n const cfg = loadConfig()\n if (cfg.defaults?.user === 'human')\n return 'human'\n return 'agent'\n}\n\n// When apes runs a wrapped command for an agent (ape-shell / `apes run --\n// <cmd>`), the agent captures THIS process's stdout as the command's\n// result. The wrapped command's own output reaches fd 1 directly\n// (execFileSync stdio:'inherit'), but apes's own diagnostics — grant\n// requests, adapter installs, \"Fetching grant token\", etc., emitted via\n// consola and console.log — also write to the JS-level stdout stream and\n// would corrupt that result (e.g. `gh … --jq '.[].number'` returning\n// \"ℹ Requesting grant…\\n473\"). Point JS-level stdout writes at stderr for\n// the duration so the captured result is exactly the wrapped command's\n// output. The wrapped command (fd 1) is unaffected; the grant-token\n// branch keeps its token on real stdout via writeRealStdout. Human mode\n// is untouched — diagnostics stay on stdout for interactive use.\nlet writeRealStdout: (s: string) => void = (s) => { process.stdout.write(s) }\n\nfunction routeDiagnosticsToStderrForWrappedAgentRun(): void {\n const original = process.stdout.write.bind(process.stdout)\n writeRealStdout = (s) => { original(s) }\n process.stdout.write = ((chunk: string | Uint8Array, ...rest: unknown[]) =>\n (process.stderr.write as (c: string | Uint8Array, ...a: unknown[]) => boolean)(chunk, ...rest)\n ) as typeof process.stdout.write\n}\n\n// Poll interval + max-minutes helpers live in `../grant-poll.ts` so they\n// are shared with the CLI-side wait loop in `commands/grants/run.ts --wait`.\n// See that module for the full rationale; in this file we only need the\n// max-minutes value for the agent-facing text block.\n\n/**\n * Exit code for the async-default pending-grant path.\n *\n * Default is **75** (`EX_TEMPFAIL` from `sysexits.h`, semantically \"temporary\n * failure — try again later\"). This is the clearest POSIX-adjacent signal\n * that the command was accepted but the target action has not yet been\n * performed and needs a retry. Unlike exit 1 (general error) or exit 2\n * (usage error), 75 does not collide with common shell conventions, and\n * it happens to be the same code `sendmail` and other mail delivery agents\n * have used for decades to signal \"defer and retry\".\n *\n * The non-zero exit has a very practical effect on AI-agent consumers:\n * openclaw's exec-runtime (and most similar frameworks) maps non-zero\n * exits to a `failed` / `error` tool-result status, which LLMs attend\n * to much more carefully than a `success` result with the same text in\n * stdout. In 0.9.3 we added explicit agent-facing instructions to the\n * async info block; in practice agents still ignored them because the\n * wrapping tool-result looked like a success. The non-zero exit is the\n * structural attention anchor that the text alone couldn't provide.\n *\n * Overridable via `APES_ASYNC_EXIT_CODE` env var or `config.toml`\n * `defaults.async_exit_code`. Set to `0` to restore the legacy exit-0\n * behaviour (for CI scripts that rely on it, or humans who find the\n * non-zero exit noisy). Valid range is 0–255 (POSIX exit code space);\n * bogus values fall back to the default 75.\n */\nfunction getAsyncExitCode(): number {\n const envValue = process.env.APES_ASYNC_EXIT_CODE\n if (envValue !== undefined && envValue !== '') {\n const n = Number(envValue)\n if (Number.isFinite(n) && n >= 0 && n <= 255)\n return Math.floor(n)\n }\n const cfg = loadConfig()\n const cfgValue = cfg.defaults?.async_exit_code\n if (cfgValue !== undefined && cfgValue !== '') {\n const n = Number(cfgValue)\n if (Number.isFinite(n) && n >= 0 && n <= 255)\n return Math.floor(n)\n }\n return 75 // EX_TEMPFAIL\n}\n\n/**\n * Print the async info block for a freshly created pending grant. Two\n * output modes:\n *\n * - **agent** (default): verbose, with an explicit polling protocol so\n * the consuming LLM knows exactly what to do next. Tells the agent to\n * poll `apes grants status <id> --json` every N seconds for up to M\n * minutes, handle each terminal status, and run `apes grants run <id>`\n * once approved. Every agent in every ecosystem sees the same text\n * without needing a per-tool skill integration.\n *\n * - **human** (opt-in via `APES_USER=human` or `config.toml` defaults.user):\n * short, friendly, no polling block. Humans at a terminal know to wait\n * for approval and then come back.\n *\n * Both modes keep the same core Approve / Status / Execute lines so\n * external scripts that grep for those labels keep working.\n */\nfunction printPendingGrantInfo(grant: { id: string }, idp: string): void {\n const mode = getUserMode()\n const approveUrl = `${idp}/grant-approval?grant_id=${grant.id}`\n const statusCmd = `apes grants status ${grant.id}`\n const executeCmd = `apes grants run ${grant.id}`\n\n if (mode === 'human') {\n consola.success(`Grant ${grant.id} created — awaiting your approval`)\n console.log(` Approve in browser: ${approveUrl}`)\n console.log(` Check status: ${statusCmd}`)\n console.log(` Run after approval: ${executeCmd}`)\n console.log('')\n console.log(' Tip: Approve as \"timed\" or \"always\" in the browser to reuse')\n console.log(' this grant without re-approval on the next invocation.')\n return\n }\n\n // agent mode (default)\n const maxMin = getPollMaxMinutes()\n consola.success(`Grant ${grant.id} created (pending approval)`)\n console.log(` Approve: ${approveUrl}`)\n console.log(` Status: ${statusCmd} [--json]`)\n console.log(` Execute: ${executeCmd} --wait`)\n console.log('')\n console.log(' For agents:')\n console.log(` 1. Tell the user about the pending grant and the approve URL above.`)\n console.log(` 2. Run \\`${executeCmd} --wait\\`. This blocks up to ${maxMin} minutes`)\n console.log(` until the user approves (or denies/timeout) and then executes`)\n console.log(` the command in a single step. The CLI handles the polling loop`)\n console.log(` internally — you do not need to poll the status yourself.`)\n console.log(` 3. Exit 0 means approved + executed; stdout is the command output.`)\n console.log(` Exit 75 (pending) only appears if you accidentally call this`)\n console.log(` without --wait. Any other non-zero exit means denied, revoked,`)\n console.log(` used, or timeout — report the reason to the user.`)\n console.log('')\n console.log(' Note: exit code 75 (EX_TEMPFAIL) from this command means \"pending,')\n console.log(' retry later\" — do not abort your workflow, follow the steps above.')\n console.log('')\n console.log(' Tip: Approve as \"timed\" or \"always\" in the browser to let this')\n console.log(' grant be reused on subsequent invocations without re-approval.')\n}\n\nexport const runCommand = defineCommand({\n meta: {\n name: 'run',\n description: 'Execute a grant-secured command',\n },\n args: {\n 'approval': {\n type: 'string',\n description: 'Approval type: once, timed, always',\n default: 'once',\n },\n 'reason': {\n type: 'string',\n description: 'Reason for the grant request',\n },\n 'adapter': {\n type: 'string',\n description: 'Explicit path to adapter TOML file',\n },\n 'as': {\n type: 'string',\n description: 'Execute as this user (delegates to escapes)',\n },\n 'host': {\n type: 'string',\n description: 'Target host (default: system hostname)',\n },\n 'escapes-path': {\n type: 'string',\n description: 'Path to escapes binary',\n default: 'escapes',\n },\n 'idp': {\n type: 'string',\n description: 'IdP URL',\n },\n 'shell': {\n type: 'boolean',\n description: 'Shell mode: use session grant with audience ape-shell',\n default: false,\n },\n 'wait': {\n type: 'boolean',\n description: 'Block until grant is approved (default: async, print grant info and exit 0). Equivalent to APE_WAIT=1.',\n default: false,\n },\n '_': {\n type: 'positional',\n description: 'Command to execute (after --)',\n required: false,\n },\n },\n async run({ rawArgs, args }) {\n const wrappedCommand = extractWrappedCommand(rawArgs ?? [])\n\n // Agent capturing a wrapped command's stdout — keep apes diagnostics\n // off it (see routeDiagnosticsToStderrForWrappedAgentRun).\n if (wrappedCommand.length > 0 && getUserMode() === 'agent') {\n routeDiagnosticsToStderrForWrappedAgentRun()\n }\n\n if (args.shell && wrappedCommand.length > 0) {\n // Shell mode: ape-shell -c \"command\" → apes run --shell -- bash -c \"command\"\n await runShellMode(wrappedCommand, args)\n return\n }\n\n if (wrappedCommand.length > 0) {\n // Adapter mode: apes run [options] -- <cli> <args...>\n await runAdapterMode(wrappedCommand, rawArgs ?? [], args)\n }\n else {\n // Audience mode: apes run <audience> <action>\n // Extract audience and action from rawArgs (before --)\n const positionals = extractPositionals(rawArgs ?? [])\n if (positionals.length < 2)\n throw new Error('Usage: apes run -- <cli> <args...> OR apes run <audience> <action>')\n await runAudienceMode(positionals[0]!, positionals[1]!, args)\n }\n },\n})\n\nasync function runShellMode(\n command: string[],\n args: Record<string, unknown>,\n) {\n const auth = loadAuth()\n if (!auth)\n throw new CliError('Not logged in. Run `apes login` first.')\n\n const idp = getIdpUrl(args.idp as string | undefined)\n if (!idp)\n throw new CliError('No IdP URL configured. Run `apes login` first or pass --idp.')\n\n // --- 0. apes self-dispatch shortcut (pre-adapter) ---\n // If `ape-shell -c \"apes <subcmd>\"` was rewritten into this shell-mode\n // invocation, the inner command is a trusted apes self-call and should\n // bypass the grant flow entirely. Same trust-root reasoning as the\n // interactive REPL path in `shell/grant-dispatch.ts` — see\n // `shell/apes-self-dispatch.ts` for the full rationale. Without this,\n // polling flows like openclaw's `ape-shell -c \"apes grants status <id>\"`\n // cascade infinitely: every poll creates a new pending grant, every\n // grant needs approval, turtles all the way down.\n const innerLine = extractShellCommandString(command)\n if (innerLine) {\n const parsedInner = parseShellCommand(innerLine)\n if (isApesSelfDispatch(parsedInner)) {\n execShellCommand(command)\n return\n }\n // --- 0b. sudo reject ---\n // Parallels the REPL path in `shell/grant-dispatch.ts`. Agents that\n // habitually prefix commands with `sudo` inside `ape-shell -c \"…\"`\n // would otherwise silently fall through to the generic session-grant\n // path and ultimately hit a bash error with no guidance. Short-circuit\n // with an explicit migration hint to `apes run --as root -- <cmd>`.\n const sudoRejection = checkSudoRejection(parsedInner)\n if (sudoRejection)\n throw new CliError(sudoRejection.reason)\n }\n\n // Try to handle this command via the shapes adapter system first.\n // This gives us structured grants with resource chains (e.g. \"rm file:/tmp/foo.txt\")\n // instead of opaque \"bash -c …\" grants.\n const adapterHandled = await tryAdapterModeFromShell(command, idp, args)\n if (adapterHandled) return\n\n const grantsUrl = await getGrantsEndpoint(idp)\n const targetHost = (args.host as string) || hostname()\n\n // Try to find an existing timed/always session grant for ape-shell\n try {\n const grants = await apiFetch<{ data: Array<{ id: string, status: string, request: { audience: string, target_host: string, grant_type: string } }> }>(\n `${grantsUrl}?requester=${encodeURIComponent(auth.email)}&status=approved&limit=20`,\n )\n const sessionGrant = grants.data.find(g =>\n g.request.audience === 'ape-shell'\n && g.request.target_host === targetHost\n && g.request.grant_type !== 'once',\n )\n if (sessionGrant) {\n execShellCommand(command)\n return\n }\n }\n catch {\n // Fall through to creating a new grant\n }\n\n // No session grant found — request one. Default: 'once', but the approver\n // can upgrade to 'timed' or 'always' during approval to enable reuse.\n consola.info(`Requesting ape-shell session grant on ${targetHost}`)\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n body: {\n requester: auth.email,\n target_host: targetHost,\n audience: 'ape-shell',\n grant_type: 'once',\n command: command.slice(0, 3),\n reason: `Shell session: ${command.join(' ').slice(0, 100)}`,\n },\n })\n\n notifyGrantPending({\n grantId: grant.id,\n approveUrl: `${idp}/grant-approval?grant_id=${grant.id}`,\n command: command.join(' ').slice(0, 200),\n audience: 'ape-shell',\n host: targetHost,\n })\n\n if (shouldWaitForGrant(args)) {\n consola.info(`Grant requested: ${grant.id}`)\n consola.info('Waiting for approval...')\n\n const maxWait = 300_000\n const interval = 3_000\n const start = Date.now()\n\n while (Date.now() - start < maxWait) {\n const status = await apiFetch<{ status: string }>(`${grantsUrl}/${grant.id}`)\n if (status.status === 'approved')\n break\n if (status.status === 'denied' || status.status === 'revoked')\n throw new CliError(`Grant ${status.status}.`)\n await new Promise(r => setTimeout(r, interval))\n }\n\n execShellCommand(command)\n return\n }\n\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n}\n\n/**\n * Try to handle a shell command via the shapes adapter system.\n *\n * Flow:\n * 1. Extract the command string from `bash -c \"…\"` argv\n * 2. Parse into executable + argv (bail out on compound commands)\n * 3. Load adapter locally, or auto-install from registry\n * 4. Resolve the command against adapter operations → structured CLI grant detail\n * 5. Reuse an existing matching grant, or request a new one and execute\n *\n * Returns true when the command was handled (executed or failed hard).\n * Returns false for any reason — caller should fall back to the generic session grant.\n */\nasync function tryAdapterModeFromShell(\n command: string[],\n idp: string,\n args: Record<string, unknown>,\n): Promise<boolean> {\n const cmdString = extractShellCommandString(command)\n if (!cmdString) return false\n\n const parsed = parseShellCommand(cmdString)\n if (!parsed) return false\n if (parsed.isCompound) return false\n\n const loaded = await loadOrInstallAdapter(parsed.executable)\n if (!loaded) return false\n\n // resolveCommand does a strict comparison against `adapter.cli.executable`,\n // which is always the bare binary name. When the user typed an absolute\n // path we must pass the basename, not the full path.\n const normalizedExecutable = basename(parsed.executable)\n\n let resolved: ResolvedCommand\n try {\n resolved = await resolveCommand(loaded, [normalizedExecutable, ...parsed.argv])\n }\n catch (err) {\n consola.debug(`ape-shell: adapter resolve failed for \"${parsed.raw}\":`, err)\n return false\n }\n\n // Try to reuse an existing matching grant (with widening support)\n try {\n const existingGrantId = await findExistingGrant(resolved, idp)\n if (existingGrantId) {\n consola.info(`Reusing grant ${existingGrantId} for: ${resolved.detail.display}`)\n const token = await fetchGrantToken(idp, existingGrantId)\n await verifyAndExecute(token, resolved, existingGrantId)\n return true\n }\n }\n catch {\n // Fall through to request a new grant\n }\n\n // Request a new grant for this specific command\n const approval = (args.approval ?? 'once') as 'once' | 'timed' | 'always'\n consola.info(`Requesting grant for: ${resolved.detail.display}`)\n const grant = await createShapesGrant(resolved, {\n idp,\n approval,\n reason: (args.reason as string) || `ape-shell: ${resolved.detail.display}`,\n })\n\n if (grant.similar_grants?.similar_grants?.length) {\n const n = grant.similar_grants.similar_grants.length\n consola.info('')\n consola.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`)\n }\n\n notifyGrantPending({\n grantId: grant.id,\n approveUrl: `${idp}/grant-approval?grant_id=${grant.id}`,\n command: resolved.detail?.display || parsed?.raw || 'unknown',\n audience: resolved.adapter?.cli?.audience ?? 'shapes',\n host: (args.host as string) || hostname(),\n })\n\n if (shouldWaitForGrant(args)) {\n consola.info(`Grant requested: ${grant.id}`)\n consola.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`)\n\n const status = await waitForGrantStatus(idp, grant.id)\n if (status !== 'approved')\n throw new CliError(`Grant ${status}`)\n\n const token = await fetchGrantToken(idp, grant.id)\n await verifyAndExecute(token, resolved, grant.id)\n return true\n }\n\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n}\n\n/**\n * Execute a shell command as [shell, '-c', command_string] via execFileSync.\n *\n * Strips `APES_SHELL_WRAPPER` from the env so any nested `apes` process\n * spawned by the bash child runs in normal citty-dispatch mode instead\n * of self-detecting as ape-shell and rejecting its argv. This mirrors\n * the pty-bridge.ts fix from 0.8.0 (Finding 4) for the one-shot path —\n * openclaw's polling flow `ape-shell -c \"apes grants status <id>\"` would\n * hit this leak on the nested `apes` call inside bash, manifesting as\n * \"ape-shell: unsupported invocation\" and breaking the async-grant loop.\n */\nfunction execShellCommand(command: string[]): void {\n if (command.length === 0)\n throw new CliError('No command to execute')\n try {\n const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env\n execFileSync(command[0]!, command.slice(1), {\n stdio: 'inherit',\n env: inheritedEnv,\n })\n }\n catch (err: unknown) {\n const exitCode = (err as { status?: number }).status || 1\n throw new CliExit(exitCode)\n }\n}\n\nfunction extractPositionals(rawArgs: string[]): string[] {\n const positionals: string[] = []\n const delimiter = rawArgs.indexOf('--')\n const args = delimiter >= 0 ? rawArgs.slice(0, delimiter) : rawArgs\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!\n if (arg === 'run')\n continue\n if (arg.startsWith('--')) {\n i++ // skip flag value\n continue\n }\n positionals.push(arg)\n }\n return positionals\n}\n\n/**\n * Print a stderr warning when an unshaped CLI is being run through the\n * generic-fallback path. Written to stderr (not stdout) so shell pipelines\n * capturing stdout see the command output, not the warning.\n */\nfunction printGenericWarning(cliId: string): void {\n process.stderr.write(`⚠ No shape registered for \\`${cliId}\\`.\\n`)\n process.stderr.write('Generic mode active — single-use grant will be required.\\n')\n}\n\nasync function runAdapterMode(\n command: string[],\n rawArgs: string[],\n args: Record<string, unknown>,\n) {\n const idp = getIdpUrl(args.idp as string | undefined)\n if (!idp)\n throw new Error('No IdP URL configured. Run `apes login` first or pass --idp.')\n\n // If caller wants to run as another user (e.g. root), auto-switch to the escapes audience flow.\n // Adapter mode (Shapes) is user-level and cannot elevate privileges.\n // Pass the argv array through so commands carrying shell metacharacters\n // or spaces (e.g. `sh -c \"mkdir … && cat > …\"` from the nest secret\n // relay) survive intact — joining to a string and re-splitting on spaces\n // would shatter them and escapes would reject the mangled argv (exit 64).\n if (args.as) {\n await runAudienceMode('escapes', command.join(' '), args, command)\n return\n }\n\n const adapterOpt = extractOption(rawArgs, 'adapter')\n const cliId = command[0]!\n let resolved: ResolvedCommand\n try {\n const loaded = loadAdapter(cliId, adapterOpt)\n resolved = await resolveCommand(loaded, command)\n }\n catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const isNoAdapter = message.startsWith('No adapter found for ')\n if (!isNoAdapter)\n throw err\n // Fallback to generic synthetic adapter (opt-out via [generic] enabled = false)\n resolved = await resolveGenericOrReject(cliId, command, {\n genericEnabled: isGenericFallbackEnabled(),\n })\n printGenericWarning(cliId)\n }\n const approval = (args.approval ?? 'once') as 'once' | 'timed' | 'always'\n\n // Try reusing an existing timed/always grant (findExistingGrant skips once grants)\n try {\n const existingGrantId = await findExistingGrant(resolved, idp)\n if (existingGrantId) {\n consola.info(`Reusing existing grant: ${existingGrantId}`)\n const token = await fetchGrantToken(idp, existingGrantId)\n await verifyAndExecute(token, resolved, existingGrantId)\n return\n }\n }\n catch {\n // Fall through to creating a new grant\n }\n\n const grant = await createShapesGrant(resolved, {\n idp,\n approval,\n ...(args.reason ? { reason: args.reason as string } : {}),\n })\n\n if (grant.similar_grants?.similar_grants?.length) {\n const n = grant.similar_grants.similar_grants.length\n consola.info('')\n consola.info(` Similar grant(s) found (${n}). Your approver can extend an existing grant to cover this request.`)\n if (grant.similar_grants.widened_details?.length) {\n const wider = grant.similar_grants.widened_details.map(d => d.permission).join(', ')\n consola.info(` Broader scope: ${wider}`)\n }\n consola.info('')\n }\n\n if (shouldWaitForGrant(args)) {\n consola.info(`Grant requested: ${grant.id}`)\n consola.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`)\n\n const status = await waitForGrantStatus(idp, grant.id)\n if (status !== 'approved')\n throw new Error(`Grant ${status}`)\n\n const token = await fetchGrantToken(idp, grant.id)\n await verifyAndExecute(token, resolved, grant.id)\n return\n }\n\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n}\n\nasync function runAudienceMode(\n audience: string,\n action: string,\n args: Record<string, unknown>,\n // When provided, the exact argv to authorize + execute. Avoids the\n // lossy `action.split(' ')` round-trip for commands whose arguments\n // contain spaces or shell metacharacters (the `--as` wrapped-command\n // path). `action` is still used for the human-readable grant display.\n commandArgv?: string[],\n) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.')\n }\n\n const idp = getIdpUrl(args.idp as string | undefined)!\n const grantsUrl = await getGrantsEndpoint(idp)\n const command = commandArgv ?? action.split(' ')\n const targetHost = (args.host as string) || hostname()\n const runAs = resolveRunAsTarget((args.as as string | undefined) ?? undefined)\n\n // Step 0: Reuse path — look for an existing approved 'timed' /\n // 'always' grant that matches our command exactly, instead of\n // creating a new pending grant every call. The legacy behaviour\n // (always create new) meant `apes run --as root --approval always`\n // re-prompted on every invocation despite the always-grant being\n // designed for reuse. Now: first call creates+approves once,\n // subsequent calls fetch a fresh token off the same grant id.\n const reusableId = await findReusableAudienceGrant({\n grantsUrl, requester: auth.email, audience, command, targetHost, runAs,\n })\n if (reusableId) {\n const { authz_jwt } = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${reusableId}/token`, { method: 'POST' })\n return executeWithGrantToken({ audience, command, args, token: authz_jwt })\n }\n\n // Step 1: Request grant\n consola.info(`Requesting ${audience} grant on ${targetHost}: ${command.join(' ')}`)\n const grant = await apiFetch<{ id: string, status: string }>(grantsUrl, {\n method: 'POST',\n body: {\n requester: auth.email,\n target_host: targetHost,\n audience,\n grant_type: args.approval,\n command,\n reason: (args.reason as string) || command.join(' '),\n ...(runAs ? { run_as: runAs } : {}),\n },\n })\n if (!shouldWaitForGrant(args)) {\n printPendingGrantInfo(grant, idp)\n throw new CliExit(getAsyncExitCode())\n }\n\n consola.success(`Grant requested: ${grant.id}`)\n consola.info(`Approve at: ${idp}/grant-approval?grant_id=${grant.id}`)\n\n // Step 2: Wait for approval. Human-in-the-loop, so the budget is generous\n // (15 min default). The poll loop MUST throw on timeout — if it falls\n // through to the token-fetch below with status='pending', the server\n // rejects with a confusing \"Grant is not approved (status: pending)\"\n // and the user can't tell the timeout from a real auth error.\n consola.info('Waiting for approval...')\n const maxWait = 15 * 60 * 1000\n const interval = 3_000\n const start = Date.now()\n let approved = false\n\n while (Date.now() - start < maxWait) {\n const status = await apiFetch<{ status: string }>(`${grantsUrl}/${grant.id}`)\n if (status.status === 'approved') {\n consola.success('Grant approved!')\n approved = true\n break\n }\n if (status.status === 'denied' || status.status === 'revoked') {\n throw new CliError(`Grant ${status.status}.`)\n }\n await new Promise(r => setTimeout(r, interval))\n }\n\n if (!approved) {\n const minutes = Math.round(maxWait / 60_000)\n throw new CliError(\n `Grant approval timed out after ${minutes} min (still pending). `\n + `Check your DDISA inbox at ${idp}/grant-approval?grant_id=${grant.id} — `\n + `if approved later, re-run the same \\`apes run\\` command and it will reuse the grant.`,\n )\n }\n\n // Step 3: Get grant token\n consola.info('Fetching grant token...')\n const { authz_jwt } = await apiFetch<{ authz_jwt: string }>(`${grantsUrl}/${grant.id}/token`, {\n method: 'POST',\n })\n\n // Step 4: Execute or output token\n return executeWithGrantToken({ audience, command, args, token: authz_jwt })\n}\n\nfunction executeWithGrantToken(opts: {\n audience: string\n command: string[]\n args: Record<string, unknown>\n token: string\n}): void {\n const { audience, command, args, token } = opts\n if (audience === 'escapes') {\n consola.info(`Executing: ${command.join(' ')}`)\n try {\n // Strip APES_SHELL_WRAPPER so nested `apes` invocations inside\n // the escapes pipe don't self-detect as ape-shell mode.\n const { APES_SHELL_WRAPPER: _wrapperMarker, ...inheritedEnv } = process.env\n execFileSync((args['escapes-path'] as string) || 'escapes', ['--grant', token, '--', ...command], {\n stdio: 'inherit',\n env: inheritedEnv,\n })\n }\n catch (err: unknown) {\n const exitCode = (err as { status?: number }).status || 1\n throw new CliExit(exitCode)\n }\n }\n else {\n // The token IS the intended result for non-escapes audiences, so it\n // must reach real stdout even when diagnostics were routed to stderr.\n writeRealStdout(token)\n }\n}\n\n/**\n * Look for an existing approved `timed`/`always` grant matching the\n * current request exactly. Returns the grant id, or null if no\n * reusable grant exists. Network/parse errors fall through to null\n * (the caller then creates a fresh grant).\n *\n * Match criteria (all required):\n * - status === 'approved'\n * - grant_type !== 'once' (once-grants get consumed on use)\n * - audience matches\n * - target_host matches\n * - command array equals exactly\n * - run_as matches (or both undefined)\n * - not expired (if grant_type=timed)\n */\nasync function findReusableAudienceGrant(opts: {\n grantsUrl: string\n requester: string\n audience: string\n command: string[]\n targetHost: string\n runAs?: string\n}): Promise<string | null> {\n try {\n const grants = await apiFetch<{\n data: Array<{\n id: string\n status: string\n expires_at?: number\n request: {\n audience: string\n target_host: string\n grant_type: string\n command?: string[]\n run_as?: string\n }\n }>\n }>(`${opts.grantsUrl}?requester=${encodeURIComponent(opts.requester)}&status=approved&limit=50`)\n const now = Math.floor(Date.now() / 1000)\n const match = grants.data.find((g) => {\n const r = g.request\n if (r.audience !== opts.audience) return false\n if (r.target_host !== opts.targetHost) return false\n if (r.grant_type === 'once') return false\n if (r.grant_type === 'timed' && g.expires_at && g.expires_at <= now) return false\n const cmd = r.command ?? []\n if (cmd.length !== opts.command.length) return false\n if (!cmd.every((c, i) => c === opts.command[i])) return false\n if ((r.run_as ?? undefined) !== opts.runAs) return false\n return true\n })\n return match?.id ?? null\n }\n catch {\n return null\n }\n}\n","import { spawn } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadAuth } from '../config.js'\nimport { CliError } from '../errors.js'\nimport { buildDefaultProxyConfigToml } from '../proxy/config.js'\nimport type { ProxyConfigOptions } from '../proxy/config.js'\nimport { startEphemeralProxy } from '../proxy/local-proxy.js'\nimport { buildTrustBundle, detectSystemCaPath } from '../proxy/trust-bundle.js'\nimport type { TrustBundle } from '../proxy/trust-bundle.js'\nimport { extractWrappedCommand } from '../shapes/index.js'\n\n/**\n * Pull the agent email + IdP URL from the cached `apes login` session and\n * return options for an IdP-mediated proxy. Throws if no valid session is on\n * disk: the proxy needs the user's identity to attribute grant requests\n * (`requester` field) and to find the right YOLO policy row keyed on\n * `(agent_email, audience='ape-proxy')`. Without that we'd silently fall\n * back to permissive transparent mode, which lies to the user about the\n * UI-side YOLO config having an effect — better to fail loudly.\n */\nfunction resolveProxyConfigOptions(): ProxyConfigOptions {\n const auth = loadAuth()\n if (!auth?.email || !auth?.idp) {\n throw new CliError(\n 'apes proxy requires `apes login` first.\\n\\n'\n + 'Without a login the proxy has no agent identity to attribute grant\\n'\n + 'requests to, so the YOLO / Allow / Deny policy on id.openape.ai cannot\\n'\n + 'apply. Run:\\n\\n'\n + ' apes login\\n\\n'\n + 'and re-run `apes proxy -- ...`.',\n // 77 = EX_NOPERM from sysexits.h (\"permission denied\"); fits \"user has\\n'\n // not authenticated to use this command\" better than the default 1.\n 77,\n )\n }\n consola.info(`[apes proxy] IdP-mediated mode — agent=${auth.email}, idp=${auth.idp}`)\n return { agentEmail: auth.email, idpUrl: auth.idp, mediated: true }\n}\n\n/**\n * `apes proxy -- <cmd> [args...]`\n *\n * Run a command with `HTTPS_PROXY` (and `HTTP_PROXY`) routed through the\n * OpenApe egress proxy. Two lifecycle modes:\n *\n * 1. `OPENAPE_PROXY_URL` is set in the environment → reuse that proxy. The\n * wrapped command inherits `HTTPS_PROXY=$OPENAPE_PROXY_URL`. No spawn,\n * no cleanup. This is the path ape-shell takes (M1b) when the user\n * started a long-lived `openape-proxy &` themselves.\n *\n * 2. `OPENAPE_PROXY_URL` is NOT set → spawn an ephemeral `openape-proxy`\n * child process bound to a random free port, exec the wrapped command\n * with `HTTPS_PROXY` pointing at it, kill the proxy on wrapped-command\n * exit. Per-invocation lifecycle, like `time` or `op run`.\n *\n * Mirrors the `apes run --root → escapes` orchestration pattern: this\n * subcommand is a thin shell around an external runnable that owns the\n * actual policy + audit logic.\n */\nexport const proxyCommand = defineCommand({\n meta: {\n name: 'proxy',\n description: 'Run a command with HTTPS_PROXY routed through the OpenApe egress proxy.',\n },\n args: {\n _: {\n type: 'positional',\n description: 'Command to execute (after --)',\n required: false,\n },\n },\n async run({ rawArgs }) {\n const wrapped = extractWrappedCommand(rawArgs ?? [])\n if (wrapped.length === 0) {\n throw new CliError('Usage: apes proxy -- <cmd> [args...]')\n }\n\n // OPENAPE_PROXY (host:port) — long-running daemon path (Phase 6).\n // The system-installed daemon already authenticates via its own\n // auth.json, so we deliberately skip resolveProxyConfigOptions() here\n // (no `apes login` required for the wrapping user). We do, however,\n // need to teach the wrapped subprocess to trust the daemon's local\n // CA so its TLS interception (mitmproxy-style) doesn't break.\n const reuseHostPort = process.env.OPENAPE_PROXY\n const reuseUrl = process.env.OPENAPE_PROXY_URL\n let proxyUrl: string\n let bundle: TrustBundle | null = null\n let close: (() => Promise<void>) | null = null\n\n if (reuseHostPort) {\n proxyUrl = `http://${reuseHostPort}`\n consola.info(`[apes proxy] using long-running daemon at ${proxyUrl}`)\n\n const localCaPath = join(homedir(), '.openape', 'proxy', 'ca.crt')\n if (!existsSync(localCaPath)) {\n throw new CliError(\n `OPENAPE_PROXY is set but no local CA found at ${localCaPath}. `\n + `Start the daemon (sudo -u <agent> apes proxy --global < secrets.toml) first.`,\n )\n }\n bundle = buildTrustBundle({\n systemCaPath: detectSystemCaPath(),\n localCaPath,\n })\n consola.debug(`[apes proxy] trust bundle: ${bundle.path}`)\n }\n else if (reuseUrl) {\n proxyUrl = reuseUrl\n consola.info(`[apes proxy] reusing existing proxy at ${proxyUrl}`)\n }\n else {\n const ephemeral = await startEphemeralProxy(buildDefaultProxyConfigToml(resolveProxyConfigOptions()))\n proxyUrl = ephemeral.url\n close = ephemeral.close\n consola.info(`[apes proxy] started ephemeral proxy at ${proxyUrl}`)\n }\n\n // Forward SIGINT/SIGTERM so the user's Ctrl-C stops the wrapped command\n // gracefully (which then triggers our finally-block cleanup of the proxy).\n //\n // We set every common variant of the proxy env-vars because tools differ:\n // - libcurl / curl honors lowercase `https_proxy` and uppercase\n // `HTTPS_PROXY` (and security advisories caused some distros to ignore\n // uppercase `HTTP_PROXY` for HTTP requests; setting both is safest).\n // - Many Go / Rust / Python tools read uppercase only.\n // - `ALL_PROXY` is honored by curl, rsync, ftp, and others as a fallback\n // when the per-scheme variant is absent.\n // - Node 24+ native `fetch` (undici) honors `NODE_USE_ENV_PROXY=1`. Setting\n // it here means the wrapped command's Node code routes through the proxy\n // without per-app ProxyAgent wiring.\n const noProxy = process.env.NO_PROXY ?? process.env.no_proxy ?? '127.0.0.1,localhost'\n // When a trust bundle is built (OPENAPE_PROXY daemon path), point every\n // common TLS-trust env var at it so the wrapped subprocess accepts the\n // daemon's intercepted-TLS leaf certs without an OS-wide trust install.\n // Each runtime/tooling reads a different variable:\n // NODE_EXTRA_CA_CERTS Node.js (additive to the bundled Mozilla store)\n // SSL_CERT_FILE OpenSSL (Python `requests`, libpq, many CLIs)\n // CURL_CA_BUNDLE libcurl\n // REQUESTS_CA_BUNDLE Python `requests` explicit override\n // GIT_SSL_CAINFO Git's libcurl-backed HTTPS transport\n const childEnv: NodeJS.ProcessEnv = {\n ...process.env,\n HTTPS_PROXY: proxyUrl,\n https_proxy: proxyUrl,\n HTTP_PROXY: proxyUrl,\n http_proxy: proxyUrl,\n ALL_PROXY: proxyUrl,\n all_proxy: proxyUrl,\n NO_PROXY: noProxy,\n no_proxy: noProxy,\n NODE_USE_ENV_PROXY: '1',\n ...(bundle\n ? {\n NODE_EXTRA_CA_CERTS: bundle.path,\n SSL_CERT_FILE: bundle.path,\n CURL_CA_BUNDLE: bundle.path,\n REQUESTS_CA_BUNDLE: bundle.path,\n GIT_SSL_CAINFO: bundle.path,\n }\n : {}),\n }\n\n let exitCode: number\n try {\n exitCode = await new Promise<number>((resolveExit) => {\n const child = spawn(wrapped[0]!, wrapped.slice(1), {\n stdio: 'inherit',\n env: childEnv,\n })\n const forward = (sig: NodeJS.Signals) => () => child.kill(sig)\n const onSigint = forward('SIGINT')\n const onSigterm = forward('SIGTERM')\n process.on('SIGINT', onSigint)\n process.on('SIGTERM', onSigterm)\n child.once('exit', (code, signal) => {\n process.off('SIGINT', onSigint)\n process.off('SIGTERM', onSigterm)\n if (signal) resolveExit(128 + (signalNumber(signal) ?? 0))\n else resolveExit(code ?? 0)\n })\n child.once('error', (err) => {\n consola.error(`[apes proxy] failed to spawn '${wrapped[0]}':`, err.message)\n resolveExit(127)\n })\n })\n }\n finally {\n // Run cleanup on both happy and exception paths so a thrown error\n // (or signal that aborts the await) doesn't leak the temp trust\n // bundle or leave the ephemeral proxy running.\n bundle?.cleanup()\n if (close) await close()\n }\n\n // Propagate the wrapped command's exit code without going through\n // CliExit + citty's runMain. `runMain` catches everything inside its own\n // try/catch and prints `consola.error(error, \"\\n\")` before our top-level\n // handler in cli.ts can intercept — and since CliExit has no message,\n // that surfaces as a bare \"ERROR\" header followed by an internal stack\n // trace, which is misleading on a *successful* deny path (curl exits 56,\n // proxy did its job correctly). process.exit here means the user sees\n // their wrapped command's exit code and nothing else.\n if (exitCode !== 0) process.exit(exitCode)\n },\n})\n\n/**\n * Map a POSIX signal name to its numeric value for the conventional\n * 128+sig exit-code encoding. Returns undefined for unknown names so the\n * caller can fall back to a plain non-zero.\n */\nfunction signalNumber(signal: NodeJS.Signals): number | undefined {\n const map: Record<string, number> = { SIGINT: 2, SIGTERM: 15, SIGHUP: 1, SIGQUIT: 3, SIGKILL: 9 }\n return map[signal]\n}\n","export interface ProxyConfigOptions {\n /**\n * The agent's email (sub-claim of their IdP token). Used as `requester` in\n * grant requests so IdP-side YOLO/allow/deny lookups key on the real user.\n */\n agentEmail: string\n /** IdP base URL the proxy talks to for grant approval + JWKS verify. */\n idpUrl: string\n /**\n * `true` (M3 default when logged in): every unmatched egress goes through an\n * IdP grant request → user's YOLO policy (audience='ape-proxy') applies.\n * `false` (fallback when not logged in): default-allow + local deny-list +\n * audit-log only. No IdP roundtrip. Honest about the trade-off.\n */\n mediated: boolean\n}\n\n/**\n * Build a default TOML config for the ephemeral proxy spawned by `apes proxy --`.\n *\n * Two modes:\n *\n * - **Mediated (`mediated=true`)**: `default_action=\"request\"` so every\n * unmatched host hits the IdP grant flow. The user's YOLO policy on\n * `id.openape.ai/agents/<email>` (Web tab) decides auto-approve vs human.\n * This is the M3 mode and what `apes proxy --` does when the caller is\n * logged in via `apes login`.\n *\n * - **Transparent (`mediated=false`)**: legacy M1a behaviour — `default_action\n * =\"allow\"` plus the cloud-metadata deny-list, no IdP roundtrip. Used when\n * the caller isn't logged in (we can't synthesize an identity for grant\n * lookups, so falling back to permissive-with-audit is the honest default\n * instead of locking everything down).\n *\n * No local audit-log path is written: anything stored on the user's machine\n * is also writable by the user, so it can't function as a tamper-proof trail.\n * The trustworthy audit lives server-side on the IdP for grant decisions; the\n * proxy still emits an operator-readable summary to stderr for live debugging.\n */\nexport function buildDefaultProxyConfigToml(opts: ProxyConfigOptions): string {\n const defaultAction = opts.mediated ? 'request' : 'allow'\n const escEmail = opts.agentEmail.replace(/\"/g, '\\\\\"')\n const escIdp = opts.idpUrl.replace(/\"/g, '\\\\\"')\n return `# Auto-generated by \\`apes proxy --\\`. Do not edit; this file is\n# recreated for every invocation and deleted on exit.\n# Mode: ${opts.mediated ? 'IdP-mediated (every unmatched host → grant flow)' : 'transparent (default-allow + audit-only)'}.\n[proxy]\nlisten = \"127.0.0.1:0\"\nidp_url = \"${escIdp}\"\nagent_email = \"${escEmail}\"\ndefault_action = \"${defaultAction}\"\n\n# Cloud / link-local metadata endpoints — never let agent traffic reach these\n# even if a downstream policy mistake would otherwise allow it.\n[[deny]]\ndomain = \"169.254.169.254\"\nnote = \"AWS / DigitalOcean / Azure metadata endpoint\"\n\n[[deny]]\ndomain = \"metadata.google.internal\"\nnote = \"GCP metadata endpoint\"\n\n[[deny]]\ndomain = \"*.internal\"\nnote = \"VPC-internal hostname suffix\"\n`\n}\n","import type { ChildProcess } from 'node:child_process'\nimport { spawn } from 'node:child_process'\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { tmpdir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\n\nconst require = createRequire(import.meta.url)\n\nexport interface EphemeralProxy {\n url: string\n port: number\n child: ChildProcess\n close: () => Promise<void>\n}\n\n/**\n * Resolve the absolute path to the `openape-proxy` executable shipped by the\n * `@openape/proxy` workspace package. Uses `require.resolve` against the\n * package's `package.json` so it works both in the workspace (where pnpm\n * symlinks the package into `node_modules/@openape/proxy`) and after a\n * regular `npm install -g @openape/apes` global install.\n */\nexport function findProxyBin(): string {\n const pkgPath = require.resolve('@openape/proxy/package.json')\n const pkg = require('@openape/proxy/package.json') as { bin?: Record<string, string> }\n const binRel = pkg.bin?.['openape-proxy']\n if (!binRel) {\n throw new Error('@openape/proxy is missing the openape-proxy bin entry')\n }\n return resolve(dirname(pkgPath), binRel)\n}\n\n/**\n * Spawn an ephemeral `openape-proxy` child process bound to a random free\n * port on 127.0.0.1. Resolves once the child has logged its `Listening on …`\n * line. Caller MUST `close()` to terminate the child + clean up the temp\n * config directory.\n *\n * Why temp file instead of stdin: the proxy binary today only accepts\n * `-c <path>`. Once it grows a stdin/env mode we can drop the temp dir.\n */\nexport async function startEphemeralProxy(configToml: string): Promise<EphemeralProxy> {\n const tmpDir = mkdtempSync(join(tmpdir(), 'openape-proxy-'))\n const configPath = join(tmpDir, 'config.toml')\n writeFileSync(configPath, configToml, { mode: 0o600 })\n\n const binPath = findProxyBin()\n const child = spawn(process.execPath, [binPath, '-c', configPath], {\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: false,\n })\n\n const cleanupTmp = () => {\n try { rmSync(tmpDir, { recursive: true, force: true }) }\n catch { /* best effort */ }\n }\n\n let port: number\n try {\n port = await waitForListenLine(child)\n }\n catch (err) {\n child.kill('SIGTERM')\n cleanupTmp()\n throw err\n }\n\n // Surface unexpected proxy stderr to ours so users can see crashes.\n child.stderr?.on('data', (chunk: Buffer) => process.stderr.write(chunk))\n\n return {\n url: `http://127.0.0.1:${port}`,\n port,\n child,\n close: () => new Promise<void>((resolveClose) => {\n const done = () => {\n cleanupTmp()\n resolveClose()\n }\n if (child.exitCode !== null || child.signalCode !== null) {\n done()\n return\n }\n child.once('exit', done)\n child.kill('SIGTERM')\n // Force-kill if SIGTERM doesn't take within 2s.\n setTimeout(() => {\n if (child.exitCode === null && child.signalCode === null) {\n child.kill('SIGKILL')\n }\n }, 2000).unref()\n }),\n }\n}\n\n/**\n * Read the proxy's stdout until we see the `Listening on http://…:<port>`\n * banner. Rejects if the child exits early or the timeout fires.\n *\n * `setTimeout(...).unref()` so the timer doesn't keep the apes process\n * alive past its natural exit if everything else has finished.\n */\nfunction waitForListenLine(child: ChildProcess): Promise<number> {\n return new Promise<number>((resolveWait, rejectWait) => {\n let buf = ''\n let timer: NodeJS.Timeout\n\n function onData(chunk: Buffer): void {\n buf += chunk.toString('utf8')\n const m = buf.match(/Listening on http:\\/\\/[^:\\s]+:(\\d+)/)\n if (m) {\n cleanup()\n resolveWait(Number(m[1]))\n }\n }\n function onExit(code: number | null): void {\n cleanup()\n rejectWait(new Error(`openape-proxy exited before listening (code=${code}, stderr accumulated above)`))\n }\n function onError(err: Error): void {\n cleanup()\n rejectWait(err)\n }\n function cleanup(): void {\n clearTimeout(timer)\n child.stdout?.off('data', onData)\n child.off('exit', onExit)\n child.off('error', onError)\n }\n\n timer = setTimeout(() => {\n cleanup()\n rejectWait(new Error('openape-proxy startup timeout (5s)'))\n }, 5000)\n timer.unref()\n\n child.stdout?.on('data', onData)\n child.once('exit', onExit)\n child.once('error', onError)\n })\n}\n","import { existsSync, mkdtempSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\n\nconst CANDIDATES = [\n '/etc/ssl/cert.pem', // macOS\n '/etc/ssl/certs/ca-certificates.crt', // Debian / Ubuntu\n '/etc/pki/tls/certs/ca-bundle.crt', // RHEL / Fedora\n '/etc/ssl/ca-bundle.pem', // OpenSUSE\n]\n\nexport function detectSystemCaPath(): string {\n for (const p of CANDIDATES) {\n if (existsSync(p)) return p\n }\n throw new Error(\n `Could not locate a system CA bundle. Tried: ${CANDIDATES.join(', ')}. `\n + `Set NODE_EXTRA_CA_CERTS yourself or pass --allow-no-system-ca.`,\n )\n}\n\nexport interface TrustBundle {\n path: string\n cleanup: () => void\n}\n\nexport function buildTrustBundle(opts: { systemCaPath: string, localCaPath: string }): TrustBundle {\n const dir = mkdtempSync(join(tmpdir(), 'openape-trust-'))\n const path = join(dir, 'bundle.pem')\n const sys = readFileSync(opts.systemCaPath, 'utf-8')\n const local = readFileSync(opts.localCaPath, 'utf-8')\n writeFileSync(path, `${sys.trimEnd()}\\n${local.trimEnd()}\\n`, { mode: 0o600 })\n return {\n path,\n cleanup: () => {\n try { unlinkSync(path) }\n catch { /* ignore */ }\n try { rmdirSync(dir) }\n catch { /* ignore */ }\n },\n }\n}\n","import { defineCommand } from 'citty'\nimport { extractOption, extractWrappedCommand, loadAdapter, resolveCommand } from '../shapes/index.js'\n\nexport const explainCommand = defineCommand({\n meta: {\n name: 'explain',\n description: 'Show what permission a command would need',\n },\n args: {\n adapter: {\n type: 'string',\n description: 'Explicit path to adapter TOML file',\n },\n _: {\n type: 'positional',\n description: 'Wrapped command (after --)',\n required: false,\n },\n },\n async run({ rawArgs }) {\n const command = extractWrappedCommand(rawArgs ?? [])\n if (command.length === 0)\n throw new Error('Missing wrapped command. Usage: apes explain [--adapter <file>] -- <cli> ...')\n\n const adapterOpt = extractOption(rawArgs ?? [], 'adapter')\n const loaded = loadAdapter(command[0]!, adapterOpt)\n const resolved = await resolveCommand(loaded, command)\n\n process.stdout.write(`${JSON.stringify({\n adapter: resolved.adapter.cli.id,\n source: resolved.source,\n operation: resolved.detail.operation_id,\n display: resolved.detail.display,\n permission: resolved.permission,\n resource_chain: resolved.detail.resource_chain,\n exact_command: resolved.detail.constraints?.exact_command ?? false,\n adapter_digest: resolved.digest,\n }, null, 2)}\\n`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { getIdpUrl, loadAuth, loadConfig } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const configGetCommand = defineCommand({\n meta: {\n name: 'get',\n description: 'Get a configuration value',\n },\n args: {\n key: {\n type: 'positional',\n description: 'Config key: idp, email, defaults.idp, defaults.approval, agent.key, agent.email',\n required: true,\n },\n },\n run({ args }) {\n const key = args.key\n\n switch (key) {\n case 'idp': {\n const idp = getIdpUrl()\n if (idp)\n console.log(idp)\n else\n consola.info('No IdP configured.')\n break\n }\n case 'email': {\n const auth = loadAuth()\n if (auth?.email)\n console.log(auth.email)\n else\n consola.info('Not logged in.')\n break\n }\n default: {\n // Dot-notation: defaults.idp, defaults.approval, agent.key, agent.email\n const config = loadConfig()\n const parts = key.split('.')\n if (parts.length === 2) {\n const section = parts[0] as keyof typeof config\n const field = parts[1]!\n const sectionObj = config[section] as Record<string, string> | undefined\n if (sectionObj && field in sectionObj) {\n console.log(sectionObj[field])\n }\n else {\n consola.info(`Key \"${key}\" not set.`)\n }\n }\n else {\n throw new CliError(`Unknown key: \"${key}\". Use: idp, email, defaults.idp, defaults.approval, agent.key, agent.email`)\n }\n }\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadConfig, saveConfig } from '../../config'\nimport { CliError } from '../../errors'\n\nexport const configSetCommand = defineCommand({\n meta: {\n name: 'set',\n description: 'Set a configuration value',\n },\n args: {\n key: {\n type: 'positional',\n description: 'Config key: defaults.idp, defaults.approval, agent.key, agent.email',\n required: true,\n },\n value: {\n type: 'positional',\n description: 'Value to set',\n required: true,\n },\n },\n run({ args }) {\n const key = args.key\n const value = args.value\n const config = loadConfig()\n\n const parts = key.split('.')\n if (parts.length !== 2) {\n throw new CliError(`Invalid key: \"${key}\". Use: defaults.idp, defaults.approval, agent.key, agent.email`)\n }\n\n const [section, field] = parts as [string, string]\n\n if (section === 'defaults') {\n config.defaults = config.defaults || {}\n ;(config.defaults as Record<string, string>)[field] = value\n }\n else if (section === 'agent') {\n config.agent = config.agent || {}\n ;(config.agent as Record<string, string>)[field] = value\n }\n else {\n throw new CliError(`Unknown section: \"${section}\". Use: defaults, agent`)\n }\n\n saveConfig(config)\n consola.success(`Set ${key} = ${value}`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { getAuthToken } from '../../config'\nimport { CliError } from '../../errors'\n\nasync function doRequest(method: string, url: string, body: string | undefined, contentType: string, raw: boolean, showHeaders: boolean) {\n const token = getAuthToken()\n if (!token) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n\n const response = await fetch(url, {\n method,\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': contentType,\n },\n body: body || undefined,\n })\n\n if (showHeaders) {\n console.log(`HTTP ${response.status} ${response.statusText}`)\n for (const [key, value] of response.headers.entries()) {\n console.log(`${key}: ${value}`)\n }\n console.log()\n }\n\n const respContentType = response.headers.get('content-type') || ''\n const text = await response.text()\n\n if (raw || !respContentType.includes('json')) {\n process.stdout.write(text)\n }\n else {\n try {\n console.log(JSON.stringify(JSON.parse(text), null, 2))\n }\n catch {\n process.stdout.write(text)\n }\n }\n\n if (!response.ok) {\n throw new CliError(`HTTP ${response.status} ${response.statusText}`)\n }\n}\n\nexport const fetchCommand = defineCommand({\n meta: {\n name: 'fetch',\n description: 'Make authenticated HTTP requests',\n },\n subCommands: {\n get: defineCommand({\n meta: {\n name: 'get',\n description: 'GET request with auth token',\n },\n args: {\n url: {\n type: 'positional',\n description: 'URL to fetch',\n required: true,\n },\n raw: {\n type: 'boolean',\n description: 'Output raw response body',\n default: false,\n },\n headers: {\n type: 'boolean',\n description: 'Show response headers',\n default: false,\n },\n },\n async run({ args }) {\n await doRequest('GET', String(args.url), undefined, 'application/json', Boolean(args.raw), Boolean(args.headers))\n },\n }),\n\n post: defineCommand({\n meta: {\n name: 'post',\n description: 'POST request with auth token',\n },\n args: {\n url: {\n type: 'positional',\n description: 'URL to fetch',\n required: true,\n },\n body: {\n type: 'string',\n description: 'Request body (JSON string)',\n },\n 'content-type': {\n type: 'string',\n description: 'Content-Type header',\n default: 'application/json',\n },\n raw: {\n type: 'boolean',\n description: 'Output raw response body',\n default: false,\n },\n headers: {\n type: 'boolean',\n description: 'Show response headers',\n default: false,\n },\n },\n async run({ args }) {\n await doRequest('POST', String(args.url), args.body as string | undefined, String(args['content-type'] || 'application/json'), Boolean(args.raw), Boolean(args.headers))\n },\n }),\n },\n})\n","import { defineCommand } from 'citty'\n\nexport const mcpCommand = defineCommand({\n meta: {\n name: 'mcp',\n description: 'Start MCP server for AI agents',\n },\n args: {\n transport: {\n type: 'string',\n description: 'Transport type: stdio or sse',\n default: 'stdio',\n },\n port: {\n type: 'string',\n description: 'Port for SSE transport',\n default: '3001',\n },\n },\n async run({ args }) {\n const transport = (args.transport || 'stdio') as 'stdio' | 'sse'\n const port = Number.parseInt(String(args.port), 10)\n\n if (transport !== 'stdio' && transport !== 'sse') {\n throw new Error('Transport must be \"stdio\" or \"sse\"')\n }\n\n const { startMcpServer } = await import('./server.js')\n await startMcpServer(transport, port)\n },\n})\n","import { existsSync, copyFileSync, writeFileSync } from 'node:fs'\nimport { randomBytes } from 'node:crypto'\nimport { execFileSync } from 'node:child_process'\nimport { join } from 'node:path'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { CliError, CliExit } from '../../errors'\n\nconst DEFAULT_IDP_URL = 'https://id.openape.at'\n\nasync function downloadTemplate(repo: string, targetDir: string) {\n const { downloadTemplate: gigetDownload } = await import('giget')\n await gigetDownload(`gh:${repo}`, { dir: targetDir, force: false })\n}\n\nfunction installDeps(dir: string) {\n const hasLockFile = (name: string) => existsSync(join(dir, name))\n\n if (hasLockFile('pnpm-lock.yaml')) {\n execFileSync('pnpm', ['install'], { cwd: dir, stdio: 'inherit' })\n }\n else if (hasLockFile('bun.lockb')) {\n execFileSync('bun', ['install'], { cwd: dir, stdio: 'inherit' })\n }\n else {\n execFileSync('npm', ['install'], { cwd: dir, stdio: 'inherit' })\n }\n}\n\nasync function promptChoice(message: string, choices: string[]): Promise<string> {\n const result = await consola.prompt(message, { type: 'select', options: choices })\n if (typeof result === 'symbol') {\n throw new CliExit(0)\n }\n return result as string\n}\n\nasync function promptText(message: string, defaultValue?: string): Promise<string> {\n const result = await consola.prompt(message, { type: 'text', default: defaultValue, placeholder: defaultValue })\n if (typeof result === 'symbol') {\n throw new CliExit(0)\n }\n return (result as string) || defaultValue || ''\n}\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'Scaffold a new OpenApe project',\n },\n args: {\n sp: {\n type: 'boolean',\n description: 'Create a Service Provider app',\n },\n idp: {\n type: 'boolean',\n description: 'Create an Identity Provider app',\n },\n dir: {\n type: 'positional',\n description: 'Target directory',\n required: false,\n },\n },\n async run({ args }) {\n let mode: 'sp' | 'idp'\n\n if (args.sp) {\n mode = 'sp'\n }\n else if (args.idp) {\n mode = 'idp'\n }\n else {\n const choice = await promptChoice('What do you want to set up?', [\n 'SP — Add login to my app',\n 'IdP — Run my own Identity Provider',\n ])\n mode = choice.startsWith('SP') ? 'sp' : 'idp'\n }\n\n if (mode === 'sp') {\n await initSP(args.dir)\n }\n else {\n await initIdP(args.dir)\n }\n },\n})\n\nasync function initSP(targetDir?: string) {\n const dir = targetDir || 'my-app'\n\n if (existsSync(join(dir, 'package.json'))) {\n throw new CliError(`Directory \"${dir}\" already contains a project.`)\n }\n\n consola.start('Scaffolding SP starter...')\n await downloadTemplate('openape-ai/openape-sp-starter', dir)\n consola.success('Scaffolded from openape-sp-starter')\n\n consola.start('Installing dependencies...')\n installDeps(dir)\n consola.success('Dependencies installed')\n\n // Create .env from .env.example\n const envExample = join(dir, '.env.example')\n const envFile = join(dir, '.env')\n if (existsSync(envExample) && !existsSync(envFile)) {\n copyFileSync(envExample, envFile)\n consola.success(`\\`.env\\` created (using Free IdP at ${DEFAULT_IDP_URL})`)\n }\n\n console.log('')\n consola.box([\n `cd ${dir}`,\n 'npm run dev',\n '',\n 'Then open http://localhost:3001/login',\n ].join('\\n'))\n}\n\nasync function initIdP(targetDir?: string) {\n const dir = targetDir || 'my-idp'\n\n if (existsSync(join(dir, 'package.json'))) {\n throw new CliError(`Directory \"${dir}\" already contains a project.`)\n }\n\n // Interactive questions\n const domain = await promptText('Domain for the IdP', 'localhost')\n const storage = await promptChoice('Storage backend', [\n 'memory (dev only, data lost on restart)',\n 'fs (local filesystem)',\n 's3 (S3-compatible)',\n ])\n const adminEmail = await promptText('Admin email')\n\n consola.start('Scaffolding IdP starter...')\n await downloadTemplate('openape-ai/openape-idp-starter', dir)\n consola.success('Scaffolded from openape-idp-starter')\n\n consola.start('Installing dependencies...')\n installDeps(dir)\n consola.success('Dependencies installed')\n\n // Generate secrets\n const sessionSecret = randomBytes(32).toString('hex')\n const managementToken = randomBytes(32).toString('hex')\n consola.success('Secrets generated')\n\n // Determine origin/issuer\n const isLocalhost = domain === 'localhost'\n const origin = isLocalhost ? 'http://localhost:3000' : `https://${domain}`\n\n // Write .env\n const envContent = [\n '# Generated by apes init --idp',\n '',\n `NUXT_OPENAPE_SESSION_SECRET=${sessionSecret}`,\n `NUXT_OPENAPE_ADMIN_EMAILS=${adminEmail}`,\n `NUXT_OPENAPE_MANAGEMENT_TOKEN=${managementToken}`,\n `NUXT_OPENAPE_ISSUER=${origin}`,\n `NUXT_OPENAPE_RP_NAME=My Identity Provider`,\n `NUXT_OPENAPE_RP_ID=${domain}`,\n `NUXT_OPENAPE_RP_ORIGIN=${origin}`,\n ].join('\\n')\n\n writeFileSync(join(dir, '.env'), `${envContent}\\n`, { mode: 0o600 })\n consola.success('.env created')\n\n console.log('')\n consola.box([\n `cd ${dir}`,\n 'npm run dev',\n '',\n 'Then open http://localhost:3000/admin',\n '',\n ...(isLocalhost\n ? []\n : [\n 'For production:',\n ` 1. DNS TXT Record: _ddisa.${domain.replace(/^id\\./, '')} → \"v=ddisa1 idp=${origin}\"`,\n ` 2. Storage: switch to ${storage.includes('s3') ? 's3' : 'fs'} in nuxt.config.ts`,\n ' 3. Deploy: vercel deploy',\n ]),\n ].join('\\n'))\n}\n","import { Buffer } from 'node:buffer'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { execFile } from 'node:child_process'\nimport { sign } from 'node:crypto'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadEd25519PrivateKey } from '../ssh-key'\nimport { generateAndSaveKey, readPublicKey, resolveKeyPath } from '../lib/keygen'\nimport { getAgentAuthenticateEndpoint, getAgentChallengeEndpoint } from '../http'\nimport { loadConfig, saveAuth, saveConfig } from '../config'\nimport { CliError, CliExit } from '../errors'\n\nconst DEFAULT_IDP_URL = 'https://id.openape.at'\nconst DEFAULT_KEY_PATH = '~/.ssh/id_ed25519'\nconst POLL_INTERVAL = 3000\nconst POLL_TIMEOUT = 300_000 // 5 minutes\n\nfunction openBrowser(url: string) {\n const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n execFile(cmd, [url], () => {})\n}\n\nasync function pollForEnrollment(\n idp: string,\n agentEmail: string,\n keyPath: string,\n): Promise<{ token: string, expiresIn: number }> {\n const resolvedKey = resolveKeyPath(keyPath)\n const keyContent = readFileSync(resolvedKey, 'utf-8')\n const privateKey = loadEd25519PrivateKey(keyContent)\n\n const challengeUrl = await getAgentChallengeEndpoint(idp)\n const authenticateUrl = await getAgentAuthenticateEndpoint(idp)\n const startTime = Date.now()\n\n while (Date.now() - startTime < POLL_TIMEOUT) {\n try {\n // Try to get a challenge — if it works, agent is enrolled\n const challengeResp = await fetch(challengeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: agentEmail }),\n })\n\n if (challengeResp.ok) {\n const { challenge } = await challengeResp.json() as { challenge: string }\n const signature = sign(null, Buffer.from(challenge), privateKey).toString('base64')\n\n const authResp = await fetch(authenticateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent_id: agentEmail, challenge, signature }),\n })\n\n if (authResp.ok) {\n const result = await authResp.json() as { token: string, expires_in: number }\n return { token: result.token, expiresIn: result.expires_in }\n }\n }\n }\n catch {\n // Ignore network errors during polling\n }\n\n await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL))\n }\n\n throw new Error('Enrollment timed out. Please check the browser and try again.')\n}\n\nexport const enrollCommand = defineCommand({\n meta: {\n name: 'enroll',\n description: 'Enroll an agent with an Identity Provider',\n },\n args: {\n idp: {\n type: 'string',\n description: `IdP URL (default: ${DEFAULT_IDP_URL})`,\n },\n name: {\n type: 'string',\n description: 'Agent name',\n },\n key: {\n type: 'string',\n description: `Path to Ed25519 key (default: ${DEFAULT_KEY_PATH})`,\n },\n },\n async run({ args }) {\n // 1. Gather inputs\n const idp = args.idp\n || await consola.prompt('IdP URL', { type: 'text', default: DEFAULT_IDP_URL, placeholder: DEFAULT_IDP_URL }).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n || DEFAULT_IDP_URL\n\n const agentName = args.name\n || await consola.prompt('Agent name', { type: 'text', placeholder: 'deploy-bot' }).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n\n if (!agentName) {\n throw new CliError('Agent name is required.')\n }\n\n const keyPath = args.key\n || await consola.prompt('Ed25519 key', { type: 'text', default: DEFAULT_KEY_PATH, placeholder: DEFAULT_KEY_PATH }).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n || DEFAULT_KEY_PATH\n\n // 2. Handle key\n const resolvedKey = resolveKeyPath(keyPath)\n let publicKey: string\n\n if (existsSync(resolvedKey)) {\n publicKey = readPublicKey(resolvedKey)\n consola.success(`Using existing key ${keyPath}`)\n }\n else {\n consola.start(`Generating Ed25519 key pair at ${keyPath}...`)\n publicKey = generateAndSaveKey(keyPath)\n consola.success(`Key pair generated at ${keyPath}`)\n }\n\n // 3. Open browser for enrollment\n const encodedKey = encodeURIComponent(publicKey)\n const enrollUrl = `${idp}/enroll?name=${encodeURIComponent(agentName)}&key=${encodedKey}`\n\n consola.info('Opening browser for enrollment...')\n consola.info(`→ ${idp}/enroll`)\n openBrowser(enrollUrl)\n\n // 4. Determine expected agent email\n // For the free IdP, the email format is: {name}+{user_local}+{user_domain}@id.openape.at\n // For custom IdPs, the format varies. We'll try common patterns.\n // The polling will try the challenge endpoint which accepts email as agent_id.\n // We need to guess the email, or poll without knowing it.\n // Best approach: ask the user to confirm the email shown in browser.\n console.log('')\n const agentEmail = await consola.prompt(\n 'Agent email (shown in browser after enrollment)',\n { type: 'text', placeholder: `agent+${agentName}@...` },\n ).then((r) => { if (typeof r === 'symbol') throw new CliExit(0); return r }) as string\n\n if (!agentEmail) {\n throw new CliError('Agent email is required to verify enrollment.')\n }\n\n // 5. Poll for enrollment confirmation via challenge endpoint\n consola.start('Verifying enrollment...')\n const { token, expiresIn } = await pollForEnrollment(idp, agentEmail, keyPath)\n\n // 6. Save auth + config\n saveAuth({\n idp,\n access_token: token,\n email: agentEmail,\n expires_at: Math.floor(Date.now() / 1000) + (expiresIn || 3600),\n })\n\n const config = loadConfig()\n config.defaults = { ...config.defaults, idp }\n config.agent = { key: keyPath, email: agentEmail }\n saveConfig(config)\n\n consola.success(`Agent enrolled as ${agentEmail}`)\n consola.success('Config saved to ~/.config/apes/')\n\n console.log('')\n consola.info('Verify with: apes whoami')\n },\n})\n","import { existsSync, readFileSync } from 'node:fs'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { apiFetch } from '../http'\nimport { loadAuth, getIdpUrl } from '../config'\nimport { CliError } from '../errors'\n\nexport const registerUserCommand = defineCommand({\n meta: {\n name: 'register-user',\n description: 'Register a sub-user with SSH key',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email for the new user',\n required: true,\n },\n name: {\n type: 'string',\n description: 'Name for the new user',\n required: true,\n },\n key: {\n type: 'string',\n description: 'Path to SSH public key file or key string',\n required: true,\n },\n type: {\n type: 'string',\n description: 'User type: human or agent (default: agent)',\n },\n },\n async run({ args }) {\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not authenticated. Run `apes login` first.')\n }\n\n const idp = getIdpUrl()\n if (!idp) {\n throw new CliError('No IdP URL configured. Run `apes login` first.')\n }\n\n // Read key from file or use as string\n let publicKey = args.key\n if (existsSync(args.key)) {\n publicKey = readFileSync(args.key, 'utf-8').trim()\n }\n\n if (!publicKey.startsWith('ssh-ed25519 ')) {\n throw new CliError('Public key must be in ssh-ed25519 format.')\n }\n\n const userType = args.type as 'human' | 'agent' | undefined\n if (userType && userType !== 'human' && userType !== 'agent') {\n throw new CliError('Type must be \"human\" or \"agent\".')\n }\n\n const result = await apiFetch<{\n email: string\n name: string\n owner: string\n type: string\n }>(`${idp}/api/auth/enroll`, {\n method: 'POST',\n body: {\n email: args.email,\n name: args.name,\n publicKey,\n ...(userType ? { type: userType } : {}),\n },\n })\n\n consola.success(`User registered: ${result.email} (type: ${result.type}, owner: ${result.owner})`)\n },\n})\n","import { defineCommand } from 'citty'\nimport { digCommand } from './dig'\n\n/**\n * `apes utils …` — admin/diagnostic utilities. Started with `dig` (DDISA\n * IdP resolution); intended home for future probes (token decoders,\n * config dumpers, version reporters, etc.) that don't fit into the\n * grants/agents/auth namespaces.\n */\nexport const utilsCommand = defineCommand({\n meta: {\n name: 'utils',\n description: 'Admin/diagnostic utilities (dig, …)',\n },\n subCommands: {\n dig: digCommand,\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { resolveDDISA } from '@openape/core'\nimport { CliError } from '../../errors'\n\n/**\n * `apes utils dig <domain|email>` — DDISA-aware DNS lookup.\n *\n * Resolves the IdP for a domain (or strips the local part of an email and\n * resolves the domain). Prints the TXT record, parsed DDISA fields, and a\n * one-shot OIDC discovery probe so you can tell at a glance whether\n * `apes login user@<domain>` will work.\n *\n * Supersedes the older `apes dns-check` which only accepted a bare domain.\n */\nexport const digCommand = defineCommand({\n meta: {\n name: 'dig',\n description: 'Resolve DDISA IdP for a domain or email (admin/diag tool)',\n },\n args: {\n target: {\n type: 'positional',\n description: 'Domain (example.com) or email (alice@example.com)',\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Machine-readable JSON output',\n },\n },\n async run({ args }) {\n const raw = String(args.target).trim()\n const at = raw.indexOf('@')\n const domain = at >= 0 ? raw.slice(at + 1) : raw\n const localPart = at >= 0 ? raw.slice(0, at) : null\n\n if (!domain || !/^[a-z0-9.-]+\\.[a-z]{2,}$/i.test(domain)) {\n throw new CliError(`Invalid domain: ${domain}`)\n }\n\n interface DigResult {\n input: string\n domain: string\n localPart: string | null\n ddisa: { found: boolean, idp?: string, version?: string, mode?: string, priority?: number }\n idpDiscovery?: { ok: boolean, status?: number, issuer?: string, ddisaVersion?: string, authMethods?: string[], grantTypes?: string[] }\n hint?: string\n }\n const result: DigResult = {\n input: raw,\n domain,\n localPart,\n ddisa: { found: false },\n }\n\n const ddisa = await resolveDDISA(domain)\n if (ddisa) {\n result.ddisa = {\n found: true,\n idp: ddisa.idp,\n version: ddisa.version,\n mode: ddisa.mode,\n priority: ddisa.priority,\n }\n\n try {\n const resp = await fetch(`${ddisa.idp}/.well-known/openid-configuration`)\n if (resp.ok) {\n const disco = await resp.json() as Record<string, unknown>\n result.idpDiscovery = {\n ok: true,\n status: resp.status,\n issuer: typeof disco.issuer === 'string' ? disco.issuer : undefined,\n ddisaVersion: typeof disco.ddisa_version === 'string' ? disco.ddisa_version : undefined,\n authMethods: Array.isArray(disco.ddisa_auth_methods_supported) ? disco.ddisa_auth_methods_supported as string[] : undefined,\n grantTypes: Array.isArray(disco.openape_grant_types_supported) ? disco.openape_grant_types_supported as string[] : undefined,\n }\n }\n else {\n result.idpDiscovery = { ok: false, status: resp.status }\n }\n }\n catch (err) {\n result.idpDiscovery = { ok: false }\n result.hint = `IdP at ${ddisa.idp} unreachable: ${err instanceof Error ? err.message : String(err)}`\n }\n }\n else {\n result.hint = `No DDISA record. Add a TXT record:\\n _ddisa.${domain} TXT \"v=ddisa1 idp=https://id.${domain}; mode=open\"`\n }\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n if (!result.ddisa.found || result.idpDiscovery?.ok === false) process.exit(1)\n return\n }\n\n console.log(`Target: ${raw}`)\n if (localPart) console.log(` user: ${localPart}`)\n console.log(` domain: ${domain}`)\n console.log('')\n\n if (!result.ddisa.found) {\n consola.warn(`No DDISA record at _ddisa.${domain}`)\n if (result.hint) console.log(`\\n${result.hint}`)\n throw new CliError(`No DDISA record found for ${domain}`)\n }\n\n consola.success(`_ddisa.${domain} → ${result.ddisa.idp}`)\n console.log(` Version: ${result.ddisa.version || 'ddisa1'}`)\n console.log(` IdP URL: ${result.ddisa.idp}`)\n if (result.ddisa.mode) console.log(` Mode: ${result.ddisa.mode}`)\n if (result.ddisa.priority !== undefined) console.log(` Priority: ${result.ddisa.priority}`)\n console.log('')\n\n if (!result.idpDiscovery) {\n // No discovery attempt happened — shouldn't reach here in practice\n return\n }\n if (result.idpDiscovery.ok) {\n consola.success(`IdP reachable (${result.idpDiscovery.status ?? 200})`)\n if (result.idpDiscovery.issuer) console.log(` Issuer: ${result.idpDiscovery.issuer}`)\n if (result.idpDiscovery.ddisaVersion) console.log(` DDISA: v${result.idpDiscovery.ddisaVersion}`)\n if (result.idpDiscovery.authMethods?.length) console.log(` Auth: ${result.idpDiscovery.authMethods.join(', ')}`)\n if (result.idpDiscovery.grantTypes?.length) console.log(` Grants: ${result.idpDiscovery.grantTypes.join(', ')}`)\n }\n else {\n consola.warn(`IdP discovery failed${result.idpDiscovery.status ? ` (HTTP ${result.idpDiscovery.status})` : ''}`)\n if (result.hint) console.log(`\\n${result.hint}`)\n throw new CliError(`IdP at ${result.ddisa.idp} not reachable`)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { sessionsListCommand } from './list'\nimport { sessionsRemoveCommand } from './remove'\n\n/**\n * `apes sessions …` — manage your own refresh-token families across\n * devices. One family per `apes login`. Use `list` to see what's active,\n * `remove <familyId>` to revoke a stale device.\n */\nexport const sessionsCommand = defineCommand({\n meta: {\n name: 'sessions',\n description: 'Manage your active refresh-token sessions across devices',\n },\n subCommands: {\n list: sessionsListCommand,\n remove: sessionsRemoveCommand,\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { apiFetch } from '../../http'\n\ninterface Family {\n familyId: string\n userId: string\n clientId: string\n createdAt: number\n expiresAt: number\n revoked: boolean\n}\n\ninterface ListResponse {\n data: Family[]\n pagination?: { cursor: string | null, has_more: boolean }\n}\n\nexport const sessionsListCommand = defineCommand({\n meta: {\n name: 'list',\n description: 'List your active refresh-token families (one per logged-in device).',\n },\n args: {\n json: { type: 'boolean', description: 'JSON output' },\n limit: { type: 'string', description: 'Max rows (default 50)' },\n },\n async run({ args }) {\n const path = args.limit ? `/api/me/sessions?limit=${encodeURIComponent(String(args.limit))}` : '/api/me/sessions'\n const result = await apiFetch<ListResponse>(path)\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n return\n }\n\n if (result.data.length === 0) {\n consola.info('No active sessions.')\n return\n }\n\n for (const f of result.data) {\n const created = new Date(f.createdAt).toISOString()\n const expires = new Date(f.expiresAt).toISOString()\n console.log(`${f.familyId} client=${f.clientId} created=${created} expires=${expires}`)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { apiFetch } from '../../http'\nimport { CliError } from '../../errors'\n\nexport const sessionsRemoveCommand = defineCommand({\n meta: {\n name: 'remove',\n description: 'Revoke one of your active refresh-token families by id.',\n },\n args: {\n familyId: {\n type: 'positional',\n required: true,\n description: 'Family id (from `apes sessions list`).',\n },\n },\n async run({ args }) {\n const id = String(args.familyId).trim()\n if (!id) throw new CliError('familyId required')\n await apiFetch(`/api/me/sessions/${encodeURIComponent(id)}`, { method: 'DELETE' })\n consola.success(`Session ${id} revoked. The device using it will need to \\`apes login\\` again on its next refresh.`)\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { resolveDDISA } from '@openape/core'\nimport { CliError } from '../errors'\n\nexport const dnsCheckCommand = defineCommand({\n meta: {\n name: 'dns-check',\n description: 'Validate DDISA DNS TXT records for a domain',\n },\n args: {\n domain: {\n type: 'positional',\n description: 'Domain to check (e.g. example.com)',\n required: true,\n },\n },\n async run({ args }) {\n const domain = args.domain\n\n consola.start(`Checking _ddisa.${domain}...`)\n\n try {\n const result = await resolveDDISA(domain)\n\n if (!result) {\n console.log('')\n console.log('To set up DDISA, add a DNS TXT record:')\n console.log(` _ddisa.${domain} TXT \"v=ddisa1 idp=https://id.${domain}\"`)\n throw new CliError(`No DDISA record found for ${domain}`)\n }\n\n consola.success(`_ddisa.${domain} → ${result.idp}`)\n console.log('')\n console.log(` Version: ${result.version || 'ddisa1'}`)\n console.log(` IdP URL: ${result.idp}`)\n if (result.mode)\n console.log(` Mode: ${result.mode}`)\n if (result.priority !== undefined)\n console.log(` Priority: ${result.priority}`)\n\n // Try OIDC discovery on the IdP\n console.log('')\n consola.start(`Verifying IdP at ${result.idp}...`)\n\n const discoResp = await fetch(`${result.idp}/.well-known/openid-configuration`)\n\n if (!discoResp.ok) {\n consola.warn(`IdP discovery failed (${discoResp.status}). Is the IdP running at ${result.idp}?`)\n return\n }\n\n const disco = await discoResp.json() as Record<string, unknown>\n\n consola.success(`IdP is reachable`)\n console.log(` Issuer: ${disco.issuer}`)\n console.log(` DDISA: v${disco.ddisa_version || '?'}`)\n\n if (disco.ddisa_auth_methods_supported) {\n console.log(` Auth: ${(disco.ddisa_auth_methods_supported as string[]).join(', ')}`)\n }\n\n if (disco.openape_grant_types_supported) {\n console.log(` Grants: ${(disco.openape_grant_types_supported as string[]).join(', ')}`)\n }\n }\n catch (err) {\n throw new CliError(`DNS check failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n },\n})\n","import { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { defineCommand } from 'citty'\nimport { AUTH_FILE, CONFIG_DIR, loadAuth } from '../config'\nimport { apiFetch, getGrantsEndpoint } from '../http'\nimport { CliError } from '../errors'\n\ndeclare const __VERSION__: string\n\ninterface HealthArgs {\n json: boolean\n}\n\ninterface HealthReport {\n version: string\n config: { dir: string }\n auth: {\n file: string\n present: boolean\n email?: string\n type?: 'human' | 'agent'\n idp?: string\n expires_at_iso?: string\n expires_at_local?: string\n expired?: boolean\n }\n idp: { url?: string, reachable: boolean, error?: string }\n grants: { count?: number, error?: string }\n ape_shell_binary: string | null\n ok: boolean\n}\n\nconst execAsync = promisify(exec)\n\nasync function resolveApeShellPath(): Promise<string | null> {\n try {\n const { stdout } = await execAsync('command -v ape-shell', { shell: '/bin/bash' })\n const trimmed = stdout.trim()\n return trimmed.length > 0 ? trimmed : null\n }\n catch {\n return null\n }\n}\n\nasync function probeIdp(url: string): Promise<{ reachable: true } | { reachable: false, error: string }> {\n const ctrl = new AbortController()\n const timeout = setTimeout(() => ctrl.abort(), 3000)\n try {\n // Plain fetch — we don't want apiFetch's bearer token or retry logic.\n // HEAD may not be supported; fall back to GET if needed.\n await fetch(url, { method: 'GET', signal: ctrl.signal })\n return { reachable: true }\n }\n catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { reachable: false, error: message }\n }\n finally {\n clearTimeout(timeout)\n }\n}\n\nasync function bestEffortGrantCount(idp: string): Promise<{ count: number } | { error: string }> {\n try {\n const grantsUrl = await getGrantsEndpoint(idp)\n const res = await apiFetch<{ data: unknown[] }>(`${grantsUrl}?limit=1`)\n const count = Array.isArray(res?.data) ? res.data.length : 0\n return { count }\n }\n catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { error: message }\n }\n}\n\nexport async function runHealth(args: HealthArgs): Promise<void> {\n const version = typeof __VERSION__ === 'string' ? __VERSION__ : '0.0.0'\n\n const auth = loadAuth()\n if (!auth) {\n throw new CliError('Not logged in. Run `apes login` first.', 1)\n }\n\n const isAgent = auth.email.includes('agent+')\n const expiresDate = new Date(auth.expires_at * 1000)\n const isExpired = Date.now() / 1000 > auth.expires_at\n\n if (isExpired) {\n throw new CliError(`Token expired at ${expiresDate.toISOString()}. Run \\`apes login\\`.`, 1)\n }\n\n const idpProbe = await probeIdp(auth.idp)\n const grantInfo = await bestEffortGrantCount(auth.idp)\n const apeShellPath = await resolveApeShellPath()\n\n const report: HealthReport = {\n version,\n config: { dir: CONFIG_DIR },\n auth: {\n file: AUTH_FILE,\n present: true,\n email: auth.email,\n type: isAgent ? 'agent' : 'human',\n idp: auth.idp,\n expires_at_iso: expiresDate.toISOString(),\n expires_at_local: expiresDate.toLocaleString(),\n expired: false,\n },\n idp: {\n url: auth.idp,\n reachable: idpProbe.reachable,\n ...('error' in idpProbe ? { error: idpProbe.error } : {}),\n },\n grants: 'count' in grantInfo\n ? { count: grantInfo.count }\n : { error: grantInfo.error },\n ape_shell_binary: apeShellPath,\n ok: idpProbe.reachable,\n }\n\n if (args.json) {\n console.log(JSON.stringify(report, null, 2))\n }\n else {\n console.log(`apes ${version}`)\n console.log('')\n console.log(`Config: ${CONFIG_DIR}`)\n console.log(`Auth: ${AUTH_FILE}`)\n console.log(` ${auth.email} (${isAgent ? 'agent' : 'human'})`)\n console.log(` IdP: ${auth.idp}`)\n console.log(` Token: valid until ${expiresDate.toISOString()} (local: ${expiresDate.toLocaleString()})`)\n console.log('')\n if (idpProbe.reachable) {\n console.log('IdP: reachable')\n }\n else {\n console.log(`IdP: <unreachable: ${idpProbe.error}>`)\n }\n if ('count' in grantInfo) {\n console.log(`Grants: ${grantInfo.count}`)\n }\n else {\n console.log(`Grants: <unreachable: ${grantInfo.error}>`)\n }\n console.log(`ape-shell: ${apeShellPath ?? '(not on PATH)'}`)\n }\n\n if (!idpProbe.reachable) {\n throw new CliError(`IdP ${auth.idp} unreachable: ${idpProbe.error}`, 1)\n }\n}\n\nexport const healthCommand = defineCommand({\n meta: {\n name: 'health',\n description: 'Report CLI diagnostic state (auth, IdP, grants, binaries)',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Emit a machine-readable JSON report',\n default: false,\n },\n },\n async run({ args }) {\n await runHealth({ json: Boolean(args.json) })\n },\n})\n","import { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { guides } from '../guides'\nimport { CliError } from '../errors'\n\nexport const workflowsCommand = defineCommand({\n meta: {\n name: 'workflows',\n description: 'Discover workflow guides',\n },\n args: {\n id: {\n type: 'positional',\n description: 'Guide ID to show (omit for list)',\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Output as JSON',\n default: false,\n },\n },\n run({ args }) {\n if (args.id) {\n const guide = guides.find(g => g.id === String(args.id))\n if (!guide) {\n consola.info(`Available: ${guides.map(g => g.id).join(', ')}`)\n throw new CliError(`Guide not found: ${args.id}`)\n }\n\n if (args.json) {\n console.log(JSON.stringify(guide, null, 2))\n return\n }\n\n console.log(`\\n ${guide.title}`)\n console.log(` ${guide.description}\\n`)\n for (let i = 0; i < guide.steps.length; i++) {\n const step = guide.steps[i]!\n if (step.note) {\n console.log(` Note: ${step.note}`)\n }\n else {\n console.log(` ${i + 1}. ${step.description}`)\n if (step.command) {\n console.log(` $ ${step.command}`)\n }\n }\n }\n console.log()\n return\n }\n\n // List mode\n if (args.json) {\n console.log(JSON.stringify(guides.map(g => ({ id: g.id, title: g.title, description: g.description })), null, 2))\n return\n }\n\n console.log('\\n Workflow Guides\\n')\n for (const guide of guides) {\n console.log(` ${guide.id.padEnd(24)} ${guide.title}`)\n }\n console.log(`\\n Show a guide: apes workflows <id>\\n`)\n },\n})\n","export interface WorkflowStep {\n description?: string\n command?: string\n note?: string\n}\n\nexport interface WorkflowGuide {\n id: string\n title: string\n description: string\n steps: WorkflowStep[]\n}\n\nexport const guides: WorkflowGuide[] = [\n {\n id: 'timed-session',\n title: 'Timed maintenance session',\n description: 'Request a timed grant for multiple commands without per-command approval.',\n steps: [\n { description: 'Request a timed grant (e.g. 1 hour)', command: 'apes run --approval timed -- <your-command>' },\n { description: 'Approve the grant in the browser (link is printed)' },\n { description: 'Subsequent commands reuse the timed grant until it expires' },\n { note: 'Use --approval always for standing permissions (revoke manually when done)' },\n ],\n },\n {\n id: 'agent-onboarding',\n title: 'Onboard a new agent',\n description: 'Register an AI agent with a DDISA identity in under 3 minutes.',\n steps: [\n { description: 'Initialize a new project (optional)', command: 'apes init --sp my-app' },\n { description: 'Enroll the agent at an IdP', command: 'apes enroll' },\n { description: 'Verify enrollment', command: 'apes whoami' },\n { description: 'Check DNS discovery', command: 'apes dns-check' },\n ],\n },\n {\n id: 'delegation',\n title: 'Delegate permissions',\n description: 'Let an agent act on your behalf at a specific service.',\n steps: [\n { description: 'Create a delegation', command: 'apes grants delegate --to agent@example.com --at api.example.com' },\n { description: 'List active delegations', command: 'apes grants delegations' },\n { description: 'Revoke when no longer needed', command: 'apes grants revoke <delegation-id>' },\n ],\n },\n {\n id: 'privilege-escalation',\n title: 'Run commands as root (escapes)',\n description: 'Execute privileged commands with grant-verified escalation.',\n steps: [\n { description: 'Request a grant to run a command as root', command: 'apes run --as root -- apt-get upgrade' },\n { description: 'Approve the grant in the browser' },\n { description: 'The command executes via escapes with verified authorization' },\n { note: 'escapes must be installed on the target machine (cargo build && sudo make install)' },\n ],\n },\n]\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport consola from 'consola'\n\n/**\n * Compare the running apes version against the latest published on npm\n * and warn the user if they're behind. Skipped silently when:\n * - the env var APES_NO_UPDATE_CHECK is set (CI, scripts that are\n * deliberate about pin)\n * - the cached lookup is fresh (24h TTL — npm registry rate-limit\n * friendly and the warning is annoying if it fires every command)\n * - the network call fails (offline, dns down, npm hiccup) — no\n * warning is more useful than a confusing one\n *\n * Cached state lives at `~/.config/apes/.version-check.json`:\n * { latest: \"0.21.2\", checkedAt: 1714770000 }\n *\n * Called from cli.ts at process start. Async-fire-and-forget — the\n * actual command runs immediately; the warning prints when the lookup\n * completes (usually <100ms, well before any human-in-the-loop step).\n */\n\nconst PACKAGE_NAME = '@openape/apes'\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000\nconst CACHE_FILE = join(homedir(), '.config', 'apes', '.version-check.json')\n\ninterface CacheEntry {\n latest: string\n checkedAt: number\n}\n\nfunction readCache(): CacheEntry | null {\n if (!existsSync(CACHE_FILE)) return null\n try {\n return JSON.parse(readFileSync(CACHE_FILE, 'utf-8')) as CacheEntry\n }\n catch {\n return null\n }\n}\n\nfunction writeCache(entry: CacheEntry): void {\n try {\n const dir = join(homedir(), '.config', 'apes')\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 0o700 })\n writeFileSync(CACHE_FILE, JSON.stringify(entry), { mode: 0o600 })\n }\n catch { /* best effort */ }\n}\n\n/**\n * Tiny semver compare — assumes valid x.y.z (no pre-release suffixes for\n * apes). Returns negative if a < b, 0 if equal, positive if a > b.\n */\nfunction compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number)\n const pb = b.split('.').map(Number)\n for (let i = 0; i < Math.max(pa.length, pb.length); i++) {\n const x = pa[i] ?? 0\n const y = pb[i] ?? 0\n if (x !== y) return x - y\n }\n return 0\n}\n\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n // Plain `application/json` — the vnd.npm.install-v1+json variant is\n // only valid on the full package endpoint, NOT on /latest (returns 406).\n const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(2_000),\n })\n if (!res.ok) return null\n const body = await res.json() as { version?: string }\n return typeof body.version === 'string' ? body.version : null\n }\n catch {\n return null\n }\n}\n\nfunction warnIfBehind(currentVersion: string, latest: string): void {\n if (compareSemver(currentVersion, latest) < 0) {\n consola.warn(\n `apes ${currentVersion} is behind latest @openape/apes@${latest}. `\n + `Run \\`npm i -g @openape/apes@latest\\` to update. `\n + `(Suppress with APES_NO_UPDATE_CHECK=1.)`,\n )\n }\n}\n\n/**\n * Two-phase check so users see the warning immediately when something\n * is known stale, without paying network latency on every command:\n *\n * 1. Synchronous cache read. If the cache is fresh AND says we're\n * behind, warn now. Most calls hit this path with zero latency.\n * 2. Async refresh in the background (fire-and-forget, doesn't\n * block the actual command). Updates cache for the next call.\n * If no cache existed at all (first run), this won't print on\n * this invocation — but the next invocation will see the cache.\n *\n * Bypass with `APES_NO_UPDATE_CHECK=1` (CI, scripts pinning a version).\n */\nexport async function maybeWarnStaleVersion(currentVersion: string): Promise<void> {\n if (process.env.APES_NO_UPDATE_CHECK) return\n if (!currentVersion || currentVersion === 'unknown') return\n\n const cached = readCache()\n const now = Date.now()\n\n if (cached) {\n warnIfBehind(currentVersion, cached.latest)\n }\n\n if (!cached || now - cached.checkedAt >= CACHE_TTL_MS) {\n const latest = await fetchLatestVersion()\n if (latest) {\n writeCache({ latest, checkedAt: now })\n if (!cached) warnIfBehind(currentVersion, latest)\n }\n }\n}\n"],"mappings":"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","names":["consola","defineCommand","Buffer","homedir","consola","consola","resolve","readFileSync","sign","loadEd25519PrivateKey","Buffer","homedir","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","hostname","defineCommand","consola","waitForApproval","consola","resolve","defineCommand","hostname","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","auth","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","consola","defineCommand","consola","existsSync","homedir","defineCommand","consola","getManagementToken","defineCommand","consola","homedir","existsSync","defineCommand","defineCommand","defineCommand","consola","path","defineCommand","consola","defineCommand","defineCommand","execFileSync","defineCommand","consola","Buffer","execFileSync","Buffer","execFileSync","execFileSync","existsSync","readFileSync","defineCommand","shQuote","consola","execFileSync","execFileSync","defineCommand","consola","defineCommand","consola","execFileSync","existsSync","readFileSync","homedir","join","process","defineCommand","consola","existsSync","readFileSync","homedir","join","CONFIG_DIR","path","join","DIFF_CAP","join","CliError","join","homedir","existsSync","readFileSync","process","defineCommand","consola","execFileSync","rmSync","writeFileSync","join","defineCommand","consola","existsSync","readFileSync","homedir","join","path","resolve","defineCommand","consola","execFileSync","join","writeFileSync","rmSync","defineCommand","consola","defineCommand","consola","existsSync","readFileSync","defineCommand","consola","defineCommand","existsSync","readFileSync","consola","existsSync","readFileSync","homedir","join","defineCommand","consola","join","homedir","existsSync","readFileSync","consola","path","readLitellmConfig","defineCommand","existsSync","readFileSync","homedir","join","defineCommand","AUTH_PATH","join","homedir","readLitellmConfig","existsSync","readFileSync","defineCommand","result","execFileSync","mkdtempSync","rmSync","writeFileSync","tmpdir","join","defineCommand","consola","Buffer","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","resolve","resolve","homedir","Buffer","existsSync","readFileSync","mkdirSync","writeFileSync","execFileSync","existsSync","readFileSync","homedir","dirname","join","defineCommand","mkdtempSync","join","tmpdir","consola","writeFileSync","execFileSync","rmSync","existsSync","mkdirSync","readdirSync","readFileSync","rmSync","writeFileSync","homedir","join","defineCommand","consola","execFileSync","hostname","AUTH_PATH","join","homedir","TASK_CACHE_DIR","existsSync","readFileSync","defineCommand","consola","path","mkdirSync","writeFileSync","readdirSync","rmSync","defineCommand","defineCommand","execFileSync","existsSync","readFileSync","join","defineCommand","consola","hostname","homedir","existsSync","mkdirSync","writeFileSync","join","defineCommand","consola","join","homedir","hostname","defineCommand","existsSync","mkdirSync","consola","writeFileSync","defineCommand","join","existsSync","readFileSync","consola","execFileSync","execFileSync","defineCommand","consola","defineCommand","execFileSync","consola","execFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","userInfo","dirname","join","defineCommand","consola","join","homedir","escape","installAdapter","mkdirSync","dirname","readFileSync","writeFileSync","consola","existsSync","defineCommand","userInfo","execFileSync","defineCommand","consola","defineCommand","consola","execFileSync","defineCommand","consola","defineCommand","execFileSync","consola","execFileSync","existsSync","homedir","userInfo","join","defineCommand","consola","PLIST_LABEL","path","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","consola","defineCommand","index","consola","execFileSync","hostname","defineCommand","consola","consola","defineCommand","hostname","execFileSync","authz_jwt","spawn","existsSync","homedir","join","defineCommand","consola","mkdtempSync","rmSync","writeFileSync","tmpdir","dirname","join","resolve","require","existsSync","mkdtempSync","readFileSync","unlinkSync","writeFileSync","tmpdir","join","path","consola","defineCommand","join","homedir","existsSync","spawn","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","defineCommand","existsSync","writeFileSync","execFileSync","join","defineCommand","consola","existsSync","join","execFileSync","consola","defineCommand","writeFileSync","Buffer","existsSync","readFileSync","execFile","sign","defineCommand","consola","DEFAULT_IDP_URL","openBrowser","execFile","readFileSync","sign","Buffer","resolve","defineCommand","consola","existsSync","existsSync","readFileSync","defineCommand","consola","defineCommand","existsSync","readFileSync","consola","defineCommand","defineCommand","consola","resolveDDISA","defineCommand","resolveDDISA","consola","defineCommand","defineCommand","defineCommand","consola","defineCommand","path","consola","defineCommand","consola","defineCommand","consola","defineCommand","defineCommand","consola","resolveDDISA","defineCommand","consola","resolveDDISA","defineCommand","defineCommand","defineCommand","consola","defineCommand","consola","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","consola","defineCommand","loadAuth","consola"]}
|