export { install } from './install.js'; export { UninstallOptions, uninstall } from './uninstall.js'; export { status } from './status.js'; import { A as AgenticMailAccount } from './config-FrDqSkD0.js'; export { C as CodexIntegrationConfig, I as InstallResult, a as InstallStatus, R as ResolveConfigOptions, U as UninstallResult, r as resolveCodexHome, b as resolveConfig } from './config-FrDqSkD0.js'; export { createIntegrationRoutes } from './http-routes.js'; export { Dispatcher, DispatcherOptions, QueryFn } from './dispatcher.js'; export { DispatcherTuning, defaultDispatcherConfigPath, resolveDispatcherTuning, writeDispatcherTuning } from './dispatcher-tuning.js'; import 'express'; /** * Thin client for the AgenticMail master API. * * We talk to ONE endpoint family — `/api/agenticmail/accounts` — to discover * and provision agents. The MCP server itself handles every other call once * Claude Code is wired up, so this client deliberately stays tiny. */ declare class AgenticMailApiError extends Error { status: number; constructor(status: number, message: string); } /** * Confirm the master API is reachable. * * The `/health` route is intentionally unauthenticated upstream — we use it * here precisely *because* it doesn't require the master key, so an early * misconfiguration shows the user "API is down" rather than "key is wrong". * Returns the version string from the response. */ declare function checkApiHealth(apiUrl: string): Promise<{ ok: true; version?: string; }>; /** List every AgenticMail account (agents). Requires the master key. */ declare function listAccounts(apiUrl: string, masterKey: string): Promise; /** Look up a single account by name. Returns null if not found. */ declare function getAccountByName(apiUrl: string, masterKey: string, name: string): Promise; /** * Create an AgenticMail account. Idempotent at the call site: if the name * already exists, returns the existing record instead of throwing. */ declare function ensureAccount(apiUrl: string, masterKey: string, name: string, role?: string): Promise; /** Delete an account by id. */ declare function deleteAccount(apiUrl: string, masterKey: string, id: string): Promise; /** * Render one AgenticMail account as a Codex subagent TOML file. * * # Codex agent file shape (verbatim from `codex-rs/core/src/config/agent_roles.rs` * and the builtin example at `codex-rs/core/src/agent/builtins/awaiter.toml`) * * name = "agenticmail-vesper" * description = "AgenticMail agent Vesper..." * developer_instructions = """ * You are Vesper, an AgenticMail agent. ... * """ * model = "gpt-5" # optional * model_reasoning_effort = "high" # optional * * Required fields: `name`, `description`, `developer_instructions`. * Entries missing `developer_instructions` are dropped by Codex with a * warning at startup — confirmed in `codex-rs/core/src/config/config_tests.rs`. * * # Difference vs Claude Code * * Claude Code uses markdown files (`~/.claude/agents/.md`) with YAML * frontmatter — `name` and `description` in the frontmatter, the persona * body as plain markdown after the `---` block. * * Codex uses TOML files (`~/.codex/agents/.toml`) with everything * as TOML keys, and the persona body stuffed into a `developer_instructions` * TOML multi-line string (triple-quoted literal). * * The persona content itself is host-agnostic — it describes how an * AgenticMail agent should think about its inbox + the MCP toolbelt. The * only host-specific bit is the sentence that names Codex (vs Claude Code) * as the "brain" running the agent. We thread the host name through as a * template input so the same generator works for both hosts in the future * if we factor out a shared `@agenticmail/host-toolkit`. */ /** Configuration shape used when building one subagent's TOML content. */ interface SubagentTemplateInput { /** Subagent name (already includes the prefix, e.g. "agenticmail-vesper"). */ name: string; /** The AgenticMail agent this subagent embodies. */ agent: AgenticMailAccount; /** MCP server key as configured in [mcp_servers.*] (e.g. "agenticmail"). */ mcpServerName: string; } /** Marker we embed in the description so uninstall can be sure a file is ours. */ declare const MANAGED_BY_MARKER = "@agenticmail/codex"; /** * Render JUST the persona body — no TOML framing. * * Used in two places: * - `renderSubagentToml` wraps this body in TOML's `developer_instructions` * for the on-disk file Codex's `spawn_agent` reads. * - The dispatcher passes this body to the Codex SDK's `Thread.run(prompt)` * directly when waking a worker — Codex doesn't have a separate system- * prompt channel for one-off `run()` calls, so the persona becomes part * of the prompt itself. * * Mostly host-agnostic. The one host-specific sentence ("Codex is your * brain") is parameterised — same generator can serve a future Claude Code * factoring if we extract a shared toolkit. */ declare function renderPersonaBody(input: SubagentTemplateInput, hostName?: string): string; /** * Produce the full text for one Codex agent TOML file. * * The body is a "you are " persona that drives the subagent (when * spawned via `spawn_agent`) to do real work using MCP tools scoped to * its own AgenticMail account. * * We use `@iarna/toml`'s stringify so multi-line strings escape correctly — * the persona body contains backticks, code blocks, double quotes, and * other characters that would break naive heredoc concatenation. */ declare function renderSubagentToml(input: SubagentTemplateInput, hostName?: string): string; /** * Resolves a persona prompt for an AgenticMail agent, with three * sources tried in order: * * 1. The host CLI's per-agent subagent file on disk (if present). * For Codex installs this is typically under `~/.codex/agents/`; * the caller passes the directory + filename prefix. Lets the * operator customise an agent's behaviour by hand-editing its * file. * * 2. `~/.agenticmail/agents//persona.md` — the canonical * "soul file" introduced in v0.9.85. Same file the voice * runtime and the Telegram bridge read, so the agent's identity * stays consistent across email, Telegram, and live phone * calls. Auto-created with a sensible default on first read. * When present, the dispatcher prepends it to the generated * body so the operator's edits to the canonical file flow * through to every spawn path including the email worker. * * 3. In-memory render from live AgenticMail account metadata via * `renderPersonaBody`. This is the path for agents that were * just `create_account`-ed and have no file yet — they become * wake-able immediately, no install step required. * * Returns the persona BODY (no YAML frontmatter). That's what the * host CLI's spawn surface consumes as a system prompt. */ interface LoadPersonaOptions { agent: AgenticMailAccount; /** Directory holding per-agent files (e.g. ~/.codex/agents). */ agentsDir: string; /** Prefix for filenames. Default: "agenticmail-". */ subagentPrefix: string; /** MCP server name used inside tool examples in the prose. */ mcpServerName: string; } interface LoadedPersona { /** The persona body — system prompt for the worker. */ body: string; /** Where the body came from (for logs / debugging). */ source: 'file' | 'generated'; /** Resolved file path if source === 'file'. */ filePath?: string; } /** * Try the disk file; otherwise generate from live account metadata * with the canonical persona prepended. * * v0.9.86 — canonical-persona overlay. If the host-specific subagent * file is missing OR contains only frontmatter, we still fall back * to a generated body — but we PREPEND `~/.agenticmail/agents// * persona.md` so the dispatcher worker shares identity with the * voice runtime and the Telegram bridge. The operator edits ONE * file, the change reaches every spawn path. */ declare function loadPersonaForAgent(opts: LoadPersonaOptions): LoadedPersona; /** * Passive, idempotent OpenCrater hook registration — safe to call from * ANY entry point that runs on an already-installed machine (the mail * hook, the dispatcher boot, npm postinstall). Exists because hook * registration used to happen ONLY inside the codex installer: users * who merely updated the package never got the sponsor hooks. * * Same contract as the claudecode twin: never creates ~/.codex on * machines without Codex, respects the user's opt-out (`npx opencrater * off` / OPENCRATER_DISABLE=1), revision-stamped so settings rewrite at * most once per OPENCRATER_HOOKS_REV, and never throws. */ declare function ensureOpenCraterHooks(hooksPath?: string): boolean; /** Register the OpenCrater sponsor hook on SessionStart + Stop. Returns true if changed. */ declare function upsertOpenCraterHook(path: string): boolean; /** Remove the OpenCrater sponsor hook (only our rules). Returns true if changed. */ declare function removeOpenCraterHook(path: string): boolean; export { AgenticMailAccount, AgenticMailApiError, type LoadPersonaOptions, type LoadedPersona, MANAGED_BY_MARKER, checkApiHealth, deleteAccount, ensureAccount, ensureOpenCraterHooks, getAccountByName, listAccounts, loadPersonaForAgent, removeOpenCraterHook, renderPersonaBody, renderSubagentToml, upsertOpenCraterHook };