spawnfile
v0.1.1
Published
Canonical source compiler for autonomous agents and teams.
Readme
Spawnfile
Canonical source for autonomous agents. Write once. Compile to any runtime.
What Spawnfile Is
Spawnfile is a spec and source format for declaring autonomous agents and teams independently of the runtime that will host them.
A Spawnfile source project is a directory you own and version. It describes the portable parts of an agent: markdown identity docs, skills, MCP connections, runtime binding, execution intent, and team structure.
spawnfile compile lowers that canonical source into runtime-specific config and workspace files. It is not a runtime-to-runtime translator. The compiler starts from the canonical source and emits each declared adapter's output.
It also emits runnable container artifacts for the compiled output: Dockerfile, entrypoint.sh, .env.example, and a prebuilt container/rootfs/ tree.
spawnfile build turns that output into a Docker image using the pinned compiled runtime artifacts from runtimes.yaml, and spawnfile run is the auth-aware wrapper over docker run.
V0.1 Scope
Spawnfile v0.1 targets autonomous agent runtimes — systems that host agents as long-lived services with markdown workspace identity. It focuses on the portable surface shared across compatible runtimes:
- identity and personality docs (SOUL.md, IDENTITY.md, AGENTS.md)
- memory and heartbeat intent docs
- skills with SKILL.md
- MCP declarations
- runtime binding
- execution intent (model, workspace, sandbox)
- team structure (members, hierarchy, shared surfaces)
- agent-level Discord, Telegram, WhatsApp, and Slack surfaces
v0.1 does not try to standardize every runtime-native feature. Beyond the initial Discord, Telegram, WhatsApp, and Slack surfaces, communication surfaces, memory engines, task schedulers, UI surfaces, and other runtime-specific features stay adapter-defined for now.
Companion Docs
specs/INDEX.md- map of all specs with status and relationshipsspecs/SPEC.md- canonical Spawnfile source specspecs/COMPILER.md- v0.1 compiler architecture, graph resolution, and adapter contractspecs/CONTAINERS.md- container compilation specspecs/RUNTIMES.md- runtime registry, version pinning, and adapter lifecyclespecs/research/- per-runtime research notes and adapter strategiesfixtures/- canonical v0.1 source projects for compiler validation
Technology
Spawnfile v0.1 is implemented as a Node.js CLI in TypeScript.
- runtime: Node.js 22+
- CLI:
commander - manifest parsing:
yaml+zod - tests:
vitest
That gives us fast iteration and a conventional bin-based CLI published to npm.
Install
npm install -g spawnfileVerify:
spawnfile --helpFrom source
git clone https://github.com/noopolis/spawnfile.git
cd spawnfile
nvm use
npm install
npm run build
npm linkTo clone the target runtimes and generate reference blueprints:
npm run runtimes:syncThis clones each runtime at the version pinned in runtimes.yaml and generates blueprints showing the expected config and workspace layout. See blueprints/ for the output.
These clones are for local research, blueprint generation, and adapter work. spawnfile compile itself does not need local runtime clones.
For local development without linking globally:
npm run dev -- validate fixtures/single-agentWhy
The autonomous agent runtimes are different, but they already share a meaningful core: markdown workspace identity, skill folders, MCP, model selection, and workspace isolation. Today that core is re-authored by hand for each runtime. Spawnfile makes it canonical.
How It Works
You write a source project once. Then you compile it:
spawnfile init
spawnfile init --runtime tinyclaw
spawnfile validate
spawnfile compile
spawnfile auth sync --profile dev --env-file .env
spawnfile build
spawnfile run --auth-profile devFor a single agent, the compiler uses that manifest's declared runtime. For a team, it walks the member graph and compiles each member using that member's declared runtime.
Each adapter maps the canonical project into runtime-native forms. If a runtime cannot preserve a declaration, the compiler reports supported, degraded, or unsupported according to the project's compile policy.
Each compile also produces a machine-readable report describing the resolved graph, chosen runtimes, output locations, and capability outcomes.
The portable model stays intentionally small:
runtimenames the host runtime and may carry runtime-specific optionsexecutioncarries portable intent like model, workspace, and sandboxagentmay hold internalsubagentsteamis for first-class agents that coordinate as a group
Project Structure
A source project has a kind - either agent or team.
Agent
my-agent/
├── Spawnfile
├── IDENTITY.md
├── SOUL.md
├── AGENTS.md
├── MEMORY.md
├── HEARTBEAT.md
├── subagents/
│ └── researcher/
│ └── Spawnfile
└── skills/
├── web_search/
│ └── SKILL.md
└── memory_store/
└── SKILL.mdNot every file is required. Spawnfile names portable document roles; adapters decide how to lower them into target-native surfaces.
Team
my-team/
├── Spawnfile
├── TEAM.md
├── shared/
│ └── skills/
│ └── web_search/
│ └── SKILL.md
└── agents/
├── orchestrator/
│ ├── Spawnfile
│ └── AGENTS.md
├── researcher/
│ ├── Spawnfile
│ └── SOUL.md
└── writer/
├── Spawnfile
└── SOUL.mdTeams can reference agents or other teams. Team structure (hierarchy, leadership) is part of the canonical model, but preservation is target-dependent and explicitly reported by the compiler. Team members may be on the same runtime or on different runtimes depending on what each member declares.
An agent may also declare internal subagents. Those are not the same as a team: they are helper agents owned by a parent agent and lowered according to that runtime's own delegation or subagent model.
Policy
Not every target supports every declared capability. Spawnfile makes that explicit:
policy:
mode: strict
on_degrade: errorThe compiler reports one of three outcomes per declared capability: supported, degraded, or unsupported.
The CLI
spawnfile init
spawnfile init --runtime tinyclaw
spawnfile init --team
spawnfile add agent writer
spawnfile add subagent critic
spawnfile add team platform
spawnfile validate
spawnfile compile
spawnfile auth
spawnfile build
spawnfile runFor example:
spawnfile init --runtime picoclaw ./agents/researcher
spawnfile add agent writer ./my-team --runtime tinyclaw
spawnfile add subagent critic ./my-agent
spawnfile add team platform ./my-team
spawnfile validate fixtures/single-agent
spawnfile compile fixtures/single-agent --out ./bundle/example
spawnfile auth sync fixtures/single-agent --profile dev --env-file ./.env
spawnfile build fixtures/single-agent --out ./bundle/example --tag example-agent
spawnfile run fixtures/single-agent --tag example-agent --auth-profile devWithout --out, the compiler writes generated artifacts under .spawn/. spawnfile init also ensures .spawn/ is ignored in the project .gitignore.
The compiler emits runtime-specific artifacts under .spawn/runtimes/... by default and writes a machine-readable spawnfile-report.json.
spawnfile init defaults agent scaffolds to openclaw. Use spawnfile init --runtime <name> to scaffold an agent for a different bundled runtime. spawnfile init --team stays runtime-neutral.
spawnfile add grows an existing manifest graph in place. The target [path] is optional and defaults to the current directory. It must point to the parent project directory (or its Spawnfile):
spawnfile add agent <id> [path]addsagents/<id>/under a team If--runtimeis omitted, it uses the same default agent runtime asspawnfile init.spawnfile add subagent <id> [path]addssubagents/<id>/under an agentspawnfile add team <id> [path]addsteams/<id>/under a team
The CLI rejects invalid parent kinds: add agent and add team only work on team projects, and add subagent only works on agent projects.
spawnfile model edits model intent in place and rewrites touched manifests to the canonical inline shape:
spawnfile model set <provider> <name> [path]sets the primary modelspawnfile model add-fallback <provider> <name> [path]appends a fallback modelspawnfile model clear-fallbacks [path]removes fallback models- if
[path]points to a team project,--recursiveis required and only descendant agent manifests are updated; the team manifest itself is left unchanged - the first positional argument is always the model provider, not the auth method
Team manifests should not declare execution. Model, sandbox, and workspace intent belong to agent manifests, not teams.
Agent manifests may declare portable communication surfaces under surfaces. The first standardized surfaces are Discord, Telegram, WhatsApp, and Slack:
surfaces:
discord:
access:
users:
- "987654321098765432"
bot_token_secret: DISCORD_BOT_TOKEN
telegram:
access:
users:
- "123456789"
chats:
- "-1001234567890"
bot_token_secret: TELEGRAM_BOT_TOKEN
whatsapp:
access:
users:
- "15551234567"
groups:
- "[email protected]"
slack:
access:
users:
- "U1234567890"
channels:
- "C1234567890"
bot_token_secret: SLACK_BOT_TOKEN
app_token_secret: SLACK_APP_TOKENDiscord access may declare:
mode: pairing | allowlist | openusersguildschannels
Telegram access may declare:
mode: pairing | allowlist | openuserschats
WhatsApp access may declare:
mode: pairing | allowlist | openusersgroups
Slack access may declare:
mode: pairing | allowlist | openuserschannels
If mode is omitted and any allowlist fields are present, Spawnfile infers allowlist.
If you want portable runtime behavior, set access.mode explicitly. Leaving access unset delegates to runtime defaults, which are not identical across runtimes.
If bot_token_secret is omitted, Spawnfile defaults to DISCORD_BOT_TOKEN for Discord, TELEGRAM_BOT_TOKEN for Telegram, and SLACK_BOT_TOKEN for Slack. If app_token_secret is omitted on Slack, Spawnfile defaults to SLACK_APP_TOKEN.
WhatsApp has no portable token-secret field in v0.1; session or QR-style auth remains runtime-defined.
spawnfile auth sync ... --env-file .env will collect that env name into the selected auth profile, and spawnfile run --auth-profile ... will validate it before container startup.
Runtime support is narrower than the portable schema:
openclawsupportspairing,allowlist, andopenfor Discord, Telegram, WhatsApp, and Slackpicoclawsupportsopenand user allowlists for Discord, Telegram, WhatsApp, and Slacktinyclawsupportspairingonly for Discord, Telegram, and WhatsApp, and does not support Slack in Spawnfile v0.1
Practical notes from the current live smoke matrix:
- Discord was verified end to end on OpenClaw and PicoClaw, and as a paired DM surface on TinyClaw
- Telegram was verified end to end on all three runtimes
tinyclawrequired first-contact pairing on Telegramopenclawandpicoclawboth worked on Telegram withaccess.mode: open- WhatsApp was verified end to end on OpenClaw
picoclawWhatsApp remains blocked in the pinned artifact becausewhatsapp_nativeis not compiled into the shipped binarytinyclawWhatsApp remains blocked in the shipped container because the upstream client needs a browser runtime- Slack was verified end to end on OpenClaw
- Slack was verified end to end on PicoClaw
picoclawreplies to channel messages in a Slack thread; direct messages reply inline
Useful options:
--auth <api_key|claude-code|codex|none>sets the auth method on the edited model target--key <ENV_NAME>sets the env var name used byapi_keyauth for custom/local models--compat <openai|anthropic>and--base-url <url>configure local/custom endpoint targets--recursiveupdates the target project and every descendant manifest in the graph
Examples:
spawnfile model set anthropic claude-opus-4-6 --auth claude-code
spawnfile model set openai gpt-5.4 --auth codex
spawnfile model set local qwen2.5:14b --auth none --compat openai --base-url http://host.docker.internal:11434/v1
spawnfile model set anthropic claude-opus-4-6 . --auth claude-code --recursivespawnfile compile also emits under the output root:
- final container filesystem output under
.spawn/container/rootfs/...by default Dockerfile,entrypoint.sh,.env.example
spawnfile build is the happy path for compile + Docker image build. It compiles the project, then runs docker build against the emitted output directory. The generated Dockerfile installs the pinned compiled runtime artifacts for the resolved runtimes; it does not rebuild runtime sources during image build.
spawnfile build remains secrets-free by default. Runtime and model auth should be prepared locally, then applied at spawnfile run time.
Model auth can be imported into a local Spawnfile auth profile:
spawnfile auth sync fixtures/single-agent --profile dev --env-file ./.env
spawnfile auth show --profile devProjects declare model auth on each model entry in the Spawnfile, for example:
execution:
model:
primary:
provider: anthropic
name: claude-opus-4-6
auth:
method: claude-codeFor local and custom endpoints, the model entry can also declare endpoint:
execution:
model:
primary:
provider: local
name: qwen2.5:14b
auth:
method: none
endpoint:
compatibility: openai
base_url: http://host.docker.internal:11434/v1spawnfile auth sync reads that declared intent and imports the matching local auth material into the selected profile. The lower-level spawnfile auth import env, spawnfile auth import claude-code, and spawnfile auth import codex commands remain available for manual profile editing. The older top-level execution.model.auth form is still accepted for compatibility, but inline per-model auth is the canonical shape.
env auth is the primary path for provider API keys. claude-code and codex imports mount existing local CLI credential stores into runtime homes at spawnfile run time.
Then run the built image with that profile:
spawnfile run fixtures/single-agent --tag example-agent --auth-profile devManual Docker remains valid against the compile output:
spawnfile build fixtures/single-agent --out ./bundle/example --tag example-agent
cp ./bundle/example/.env.example ./bundle/example/.env
docker run --env-file ./bundle/example/.env -p 18789:18789 example-agentEquivalent manual flow:
spawnfile compile fixtures/single-agent --out ./bundle/example
cd ./bundle/example
docker build -t example-agent .
docker run --env-file .env -p 18789:18789 example-agentDocker E2E
The repo also includes an opt-in Docker auth E2E harness. It builds compiled images, starts them with a local Spawnfile auth profile, waits for runtime readiness, sends real prompts, and fails unless the expected sentinel reply comes back.
Examples:
npm run test:e2e:docker-auth -- --scenario openclaw-codex
npm run test:e2e:docker-auth -- --scenario team-multi-runtime --env-file ../headhunter/.envThis is intentionally separate from npm test.
It requires Docker, network access, and real model credentials.
The Builder
spawnfile.ai is a web-based authoring surface for the canonical format. It walks through docs, skills, MCP, runtime binding, execution intent, and team composition, then produces a source project you own and can edit by hand.
The Name
Spawn - in computing, you spawn a process. In games, you spawn a character. In biology, you spawn life. Deliberate creation. Independent existence from that point forward.
File - the atomic unit of software. Something you can read, version, fork, check into git, and own completely. It anchors a project - a directory, a complete picture of what something is.
Together: a canonical source project that spawns an agent and can be compiled into the runtimes that can host it.
One source format. Many runtimes. Manifest-driven compilation.
spawnfile.ai · github.com/noopolis/spawnfile
