agents — the agent-profile registry (caveman wrap data)
Profiles for every AI coding agent caveman wrap can route through byte-safe gateway. The
keystone is a collapse toward data, not an absolute: for
most agents, adding one is a data change (one JSON file here) and the CLI's injection appliers
- the proxy's wire-protocol adapters are the only code. But routing sits on a three-tier honesty
scale (
injection_completeness), because several agents genuinely need code:
- declarative — the profile's
injectionblock alone routes it (claude's default env, gemini, aider, opencode, qwen). A true data-only add. - builder-assisted — the profile is the base, but the CLI augments it in code: an
overlayBuilders.<id>config-overlay builder (openclaw), or an auth/bedrock short-circuit (applyClaudeBedrockWrapfor claude,applyHermesAuthEnvfor hermes). - code-only — the declared
injectionis inert and all routing is code (codex shipsinjection.env: {};buildCodexEphemeralWrapEnv+codexCavemanProviderTomldo the real work).
compile.mjs DERIVES the true tier from the CLI (overlayBuilders.<id> + named wrap builders
scanned from index.ts) plus the inert-injection rule, and fails closed when a profile's
declared injection_completeness claims more data-purity than reality (e.g. declarative for an
agent that needs a builder). Separately, buildWrapEnv first sprays a generic base-URL union
(WRAP_BASE_URL_ENV_VARS in ../../packages/cli/src/index.ts) as a fail-open fallback that any SDK subprocess
children inherit; each agent reads only its own subset, and the profile's injection then layers on
top.
Layout
../../agents/profiles/*.json— one profile per agent (claude,codex,gemini,aider,kilo,qwen,opencode,hermes,openclaw,pi).../../agents/profiles/schema.json— profile contract (JSON Schema, draft-07).../../agents/reserved-verbs.json— command tokens no profile id or binary name may shadow; compiled into the CLI and tested against dispatcher reality.../../agents/compile.mjs— zero-dep compiler: validates every profile (fail-closed) and emits../../agents/agents.json+ CLI's embedded../../packages/cli/src/{agents,reserved-verbs}.generated.ts. It also fails closed on four honesty invariants: any model id pinned in the injection config must be priced by provider catalog (../../shared/provider-catalog/catalog/current.yaml); a declaredinjection_completenessmust match the CLI's real routing; theagent-conformance.ymlCI pins are derived fromtested_agent_versionand must equal it; and a declaredlast_verified_atmust be inside the staleness budget.../../agents/agents.json— generated published registry (do not hand-edit).../../agents/probe-installed.mjs— isolated--version+--helpgate for installed profile binaries;--require <id>and--allfail on missing, broken, or version-drifted binaries.--allow-newerreclassifies a working binary newer than the pin asdrift(notbroken) — used by the non-blocking @latest lane.../../agents/drift-report.mjs— turns aprobe --allow-newer --jsonresult into one GitHub issue per drifted or broken (@latest fails the probe) agent (idempotent; opens or updates). Runs only in the non-blocking CI lane.../../.github/workflows/agent-conformance.yml— daily/manual real-engine compression contract for all profiles plus one clean pinned upstream-binary probe per profile, and a separate non-blocking@latestdrift-report lane that files drift issues.
tested_agent_version is evidence, not compatibility theater. Doctor compares
installed version, downgrades unknown/newer/older hosts to safe inactive subsets,
and reports binary-present-but-unlaunchable separately. Claude 2.1.226 is current
locally grounded pin. Qwen Code 0.22.3 has pinned real-CLI local and managed
OpenAI-compatible route proof; other pins remain unchanged until equivalent proof exists.
How a profile points an agent at the gateway
injection.method is one of:
env— set literal env vars; values may use{{cave_base_url}}/{{cave_api_key}}/{{cave_proxy_url}}/{{cave_org_id}}templates. A var that renders empty is omitted (so we never set an empty auth token). Base-URL/API-base keys may append a compiler-validated safe path such as/openai/v1; secret keys cannot.config-env-content— render a mode-selected inline JSON config (config_content.localfor BYOKcaveman start;config_content.managedwhenCAVE_GATEWAY_URLis off-loopback) and set it as one env var. This is how opencode (OPENCODE_CONFIG_CONTENT) and Kilo Code (KILO_CONFIG_CONTENT) are wrapped without touching user config. An agent's own{env:VAR}tokens are left untouched.config-file— merge a mode-selected config overlay into a temporary file and point the agent at it through the declared environment variable. OpenClaw uses a builder-assisted overlay. Qwen Code is declarative:QWEN_CODE_SYSTEM_SETTINGS_PATHselects an explicit source first, otherwise the CLI reads Qwen's macOS/Linux/Windows enterprise platform default, deep-merges the route, and preserves the source policy, sibling providers, and~/.qwen/settings.json.
How a profile auto-shrinks command output (command_hook, optional)
command_hook declares how caveman wrap/caveman hooks route the agent's noisy
shell-command output through caveman shrink (RTK parity, byte-exact recoverable).
Three honest tiers — never claim a rewrite an agent can't do:
claude-pretooluse/codex-pretooluse/gemini-beforetool/opencode-plugin/hermes-plugin/openclaw-plugin— hard rewrite: aBashPreToolUse hook (Claude), aBeforeToolhook onrun_shell_command(Gemini), or atool.execute.before-style plugin (opencode/hermes/openclaw) deterministically reroutes the command before it runs. Claude + Gemini share oneinstallSettingsHook(same settings.json shape, different event/matcher); every hard-rewrite method routes the command throughcaveman shrink-hook.codex-pretooluseis declared but inert (#1037): Codex matches a saved approval against the command text, so rewriting it re-prompts the user for a command they had already allowed, and the rewritten command leads with the resolved caveman/node path that noprefix_rulecan cover.shrinkHooktherefore declines every Codex tool event andhooks install codexinstalls nothing. Retiring the method outright is still open: the samecommand_hookentry carries codex's directives instructions-file, andnativeHooksDocumentwould need to migrate the entrycaveman enable codexalready wrote into existing installs.instruction-note(+file) — soft model-nudge: append a delimited "prefercaveman shrink" note to a file the agent auto-reads. Best-effort, idempotent, install→uninstall is a byte-exact round-trip. Retained only for hosts without a current hard hook surface. (Codex was moved off this tier to its nativePreToolUsehook; see thecodex-pretoolusenote above for why that hook no longer rewrites anything.)- absent — manual-only: no installable surface (e.g. Aider);
hooksjust prints thecaveman shrink -- <cmd>guidance.
How a profile declares a skill surface (skills, optional)
skills declares where the agent keeps on-disk skills so caveman convert can
pixel-compress their bodies (SKILL.md frontmatter stays text — it drives skill
discovery; only the body becomes PNG pages). format is a closed enum (only
skill-md: <root>/<name>/SKILL.md with YAML frontmatter — the Claude Code /
Codex convention); user_dirs are ~-resolved roots, project_dirs are
repo-relative and scanned only with --project. Absent = no verified skill
convention — convert skips the agent with an honest note, never guesses a path.
- Source format is JSON, not YAML — deliberately, to keep the CLI zero-runtime-dep (the compiler needs no parser; the CLI imports the generated TS, never reads a file at runtime).
- fail-closed: unknown fields/enums/templates, command collisions, unsafe env keys/values, and paths outside the profile's own hidden home directory fail compile — never a guessed protocol, redirect, loader override, or arbitrary file read/write.
- The compiler runs in the CLI build and test (
node ../agents/compile.mjs); the generatedagents.generated.tsis committed and must stay in sync. wire_protocolmust be one the proxy speaks natively (anthropic-messages · openai-chat · openai-responses · gemini-generatecontent) — we don't translate protocols in the wrap path.
See ../../CLAUDE.md (root) · ../../packages/cli/CLAUDE.md