Agent Folders
A folder with a SYSTEM.md or APPEND_SYSTEM.md is a complete agent. Everything else below is optional — add it as the agent grows. Every supported file uses a pi-native or cross-tool-standard name, and the folder mirrors the layout of pi's own agent dir (~/.pi/agent/), so anything written for a personal pi config drops in unchanged.
* At least one of SYSTEM.md / APPEND_SYSTEM.md is required; a folder may ship both.
SYSTEM.md / APPEND_SYSTEM.md
The agent's role, instructions, and personality in Markdown — pi's system-prompt-file convention, the same names pi discovers in ~/.pi/agent/ and <project>/.pi/. Two variants, mirroring pi:
SYSTEM.mdreplaces pi's default coding-assistant prompt (--system-prompt <path>) — use it when the agent shouldn't carry pi's built-in assistant framing. Context files and skills are still appended by pi.APPEND_SYSTEM.mdappends to pi's default prompt (--append-system-prompt <path>) — use it to layer role and instructions on top of the built-in framing.
pi can't discover either file in an arbitrary folder on its own, so cradle passes the paths explicitly. A folder may ship both: cradle passes both flags, and pi uses SYSTEM.md as the base with APPEND_SYSTEM.md appended. A folder with neither means the directory isn't an agent, and cradle run fails with a pointer to this page.
settings.json
pi's native settings shape. cradle honors the model-selection keys:
These are passed explicitly as --provider/--model/--thinking, so your machine's personal pi defaults never bleed into an agent run.
Keys cradle doesn't map (theme, quietStartup, collapseChangelog, …) have no effect in an agent folder — pi reads them from ~/.pi/agent/settings.json or the project's .pi/settings.json, never from the folder, and cradle warns at start so they don't silently disappear.
settings.json also supports pi's npm-distributed extension mechanism:
Only npm:<name>[@<version>] sources are supported — cradle installs each declared package into a private npm project under the agent's state dir before the sandbox spawns, then resolves the installed package's extensions into explicit -e flags: the pi.extensions entries its package.json declares (files, directories, or globs), else a convention extensions/ directory, else a top-level index.ts/index.js. Other pi source forms (git:, https://, ssh://, local paths) are warned and dropped.
pi's object form picks which of those extensions load:
Omit extensions to load everything the package declares, [] to load none, or list patterns: a plain glob includes, ! excludes, + force-includes an exact path, - force-excludes one — all relative to the package root. "autoload": false flips the default so nothing loads except what a pattern names. The sibling skills, prompts, and themes filters are accepted and warned as ignored: cradle delivers a package's extensions and nothing else.
npmCommand selects the installer, and must be a single-element array naming one of npm, pnpm, yarn, or bun — a bare command name, no paths, no flags, no extra argv. The install runs on the host before the sandbox spawns, so a wider shape would let a folder's settings.json run arbitrary host commands; anything else is warned and dropped, falling back to npm.
models.json
pi's native custom-provider format. Define self-hosted or OpenAI-compatible endpoints (Ollama, vLLM, SGLang) exactly as you would in ~/.pi/agent/models.json; cradle registers each provider at launch via a generated extension.
skills/
Skill directories containing SKILL.md (Agent Skills format), passed to pi via --skill. Loaded only when relevant, so the agent gets focused guidance without carrying it in every prompt.
extensions/
Full pi extensions, passed through verbatim as -e <file>: top-level extensions/*.ts plus each subdirectory's index.ts — the same shapes pi discovers in ~/.pi/agent/extensions/. One mechanism covers everything the runtime can grow: model-callable tools (pi.registerTool), /commands, permission gates, event interception, custom providers, custom rendering.
A model-callable tool is the everyday case:
Load order is load-bearing: cradle's generated providers extension loads first (when the agent declares models.json), then any settings.json packages entries, then the agent's own extensions/ last — they can assume registered providers and any package-provided tools are already available.
An agent folder is code. Extensions execute with the
piprocess's permissions — thenonosandbox contains them at the OS boundary, but inside it they are unrestricted. Treat a third-party agent folder with the same scrutiny as a repo you'd run.
sandbox/nono.json
Sandbox posture — filesystem grants, network policy, and the sandbox opt-out — for the nono host-OS-policy backend. See Sandbox for the full reference.
sandbox/sbx.json
A sibling opt-in for the second backend: an agent runs inside a Docker Sandboxes microVM instead of (or alongside) nono when it declares sandbox/sbx.json — a restricted subset of sandbox/nono.json's schema (no Unix-socket grants, no named network-profile pass-through, no Seatbelt escape hatch). See Sandbox for the full schema and how cradle picks a backend when a folder ships both files.