spawnfile 0.1.0 → 0.1.2
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/README.md +80 -397
- package/dist/cli/modelCommands.d.ts +3 -0
- package/dist/cli/modelCommands.js +68 -0
- package/dist/cli/runCli.d.ts +6 -1
- package/dist/cli/runCli.js +12 -67
- package/dist/cli/runtimeCommands.d.ts +3 -0
- package/dist/cli/runtimeCommands.js +20 -0
- package/dist/cli/surfaceCommands.d.ts +3 -0
- package/dist/cli/surfaceCommands.js +98 -0
- package/dist/compiler/agentSurfaces.js +51 -5
- package/dist/compiler/buildCompilePlan.js +36 -40
- package/dist/compiler/buildCompilePlanRuntime.d.ts +14 -0
- package/dist/compiler/buildCompilePlanRuntime.js +39 -0
- package/dist/compiler/buildCompilePlanTeams.d.ts +5 -0
- package/dist/compiler/buildCompilePlanTeams.js +38 -0
- package/dist/compiler/compilePlanHelpers.js +4 -1
- package/dist/compiler/compileProject.js +62 -13
- package/dist/compiler/compileProjectSupport.d.ts +17 -0
- package/dist/compiler/compileProjectSupport.js +136 -0
- package/dist/compiler/containerArtifacts.d.ts +6 -1
- package/dist/compiler/containerArtifacts.js +26 -4
- package/dist/compiler/containerArtifactsPlans.js +16 -1
- package/dist/compiler/containerArtifactsRender.d.ts +4 -2
- package/dist/compiler/containerArtifactsRender.js +21 -126
- package/dist/compiler/containerArtifactsTypes.d.ts +7 -0
- package/dist/compiler/containerEntrypointRender.d.ts +12 -0
- package/dist/compiler/containerEntrypointRender.js +186 -0
- package/dist/compiler/index.d.ts +2 -0
- package/dist/compiler/index.js +2 -0
- package/dist/compiler/interactiveSurfaceScopes.d.ts +2 -0
- package/dist/compiler/interactiveSurfaceScopes.js +21 -0
- package/dist/compiler/moltnetArtifacts.d.ts +27 -0
- package/dist/compiler/moltnetArtifacts.js +204 -0
- package/dist/compiler/moltnetBinaries.d.ts +4 -0
- package/dist/compiler/moltnetBinaries.js +103 -0
- package/dist/compiler/moltnetClientConfig.d.ts +11 -0
- package/dist/compiler/moltnetClientConfig.js +89 -0
- package/dist/compiler/moltnetRepresentativeResolution.d.ts +16 -0
- package/dist/compiler/moltnetRepresentativeResolution.js +86 -0
- package/dist/compiler/moltnetResolution.d.ts +3 -0
- package/dist/compiler/moltnetResolution.js +201 -0
- package/dist/compiler/runProject.js +1 -1
- package/dist/compiler/surfaceDefinitions.d.ts +55 -0
- package/dist/compiler/surfaceDefinitions.js +204 -0
- package/dist/compiler/teamContextHelpers.d.ts +18 -0
- package/dist/compiler/teamContextHelpers.js +112 -0
- package/dist/compiler/teamContextSupport.d.ts +4 -0
- package/dist/compiler/teamContextSupport.js +264 -0
- package/dist/compiler/teamContextSupport.testHelpers.d.ts +16 -0
- package/dist/compiler/teamContextSupport.testHelpers.js +68 -0
- package/dist/compiler/teamContextTypes.d.ts +28 -0
- package/dist/compiler/teamRoster.d.ts +12 -0
- package/dist/compiler/teamRoster.js +48 -0
- package/dist/compiler/teamRosterEntries.d.ts +13 -0
- package/dist/compiler/teamRosterEntries.js +230 -0
- package/dist/compiler/teamRosterTypes.d.ts +45 -0
- package/dist/compiler/types.d.ts +72 -6
- package/dist/compiler/updateProjectRuntime.d.ts +9 -0
- package/dist/compiler/updateProjectRuntime.js +67 -0
- package/dist/compiler/updateProjectSurfaces.d.ts +8 -0
- package/dist/compiler/updateProjectSurfaces.js +106 -0
- package/dist/manifest/loadManifest.js +4 -4
- package/dist/manifest/renderSpawnfile.js +74 -8
- package/dist/manifest/scaffold.js +1 -3
- package/dist/manifest/schemas.d.ts +227 -17
- package/dist/manifest/schemas.js +62 -20
- package/dist/manifest/surfaceSchemas.d.ts +154 -0
- package/dist/manifest/surfaceSchemas.js +77 -5
- package/dist/runtime/common.js +3 -0
- package/dist/runtime/openclaw/adapter.js +38 -5
- package/dist/runtime/openclaw/moltnet.d.ts +12 -0
- package/dist/runtime/openclaw/moltnet.js +124 -0
- package/dist/runtime/openclaw/surfaces.js +3 -0
- package/dist/runtime/picoclaw/adapter.js +27 -8
- package/dist/runtime/picoclaw/pico.d.ts +2 -0
- package/dist/runtime/picoclaw/pico.js +2 -0
- package/dist/runtime/picoclaw/surfaces.js +11 -0
- package/dist/runtime/tinyclaw/adapter.js +22 -8
- package/dist/runtime/tinyclaw/runAuth.js +28 -1
- package/dist/runtime/tinyclaw/surfaces.js +8 -0
- package/dist/runtime/types.d.ts +11 -0
- package/package.json +10 -3
- package/runtimes.yaml +4 -4
- package/dist/.env.example +0 -5
- package/dist/Dockerfile +0 -21
- package/dist/compiler/discordSurface.d.ts +0 -4
- package/dist/compiler/discordSurface.js +0 -28
- package/dist/container/rootfs/var/lib/spawnfile/instances/picoclaw/agent-assistant/picoclaw/config.json +0 -16
- package/dist/container/rootfs/var/lib/spawnfile/instances/picoclaw/agent-assistant/picoclaw/workspace/AGENTS.md +0 -1
- package/dist/e2e/cli.js +0 -40
- package/dist/e2e/dockerAuth.d.ts +0 -18
- package/dist/e2e/dockerAuth.js +0 -212
- package/dist/e2e/fixtures.d.ts +0 -2
- package/dist/e2e/fixtures.js +0 -49
- package/dist/e2e/index.d.ts +0 -4
- package/dist/e2e/index.js +0 -4
- package/dist/e2e/runtimePrompts.d.ts +0 -13
- package/dist/e2e/runtimePrompts.js +0 -132
- package/dist/e2e/scenarios.d.ts +0 -3
- package/dist/e2e/scenarios.js +0 -84
- package/dist/e2e/types.d.ts +0 -35
- package/dist/entrypoint.sh +0 -71
- package/dist/runtimes/picoclaw/agents/assistant/config.json +0 -16
- package/dist/runtimes/picoclaw/agents/assistant/workspace/AGENTS.md +0 -1
- package/dist/spawnfile-report.json +0 -71
- /package/dist/{e2e/cli.d.ts → compiler/teamContextTypes.js} +0 -0
- /package/dist/{e2e/types.js → compiler/teamRosterTypes.js} +0 -0
package/README.md
CHANGED
|
@@ -1,464 +1,147 @@
|
|
|
1
1
|
# Spawnfile
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> A spec and compiler for autonomous agent runtimes. Write your agent once, compile for any runtime.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`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.
|
|
14
|
-
It also emits runnable container artifacts for the compiled output: `Dockerfile`, `entrypoint.sh`, `.env.example`, and a prebuilt `container/rootfs/` tree.
|
|
15
|
-
`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`.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## V0.1 Scope
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/spawnfile"><img src="https://img.shields.io/npm/v/spawnfile?style=flat-square&color=d4604a&label=npm" alt="npm"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/spawnfile"><img src="https://img.shields.io/npm/dm/spawnfile?style=flat-square&color=d4604a" alt="downloads"></a>
|
|
8
|
+
<a href="#from-source"><img src="https://img.shields.io/node/v/spawnfile?style=flat-square&color=d4604a" alt="node"></a>
|
|
9
|
+
<a href="LICENSE"><img src="https://img.shields.io/npm/l/spawnfile?style=flat-square&color=d4604a" alt="MIT"></a>
|
|
10
|
+
<a href="https://spawnfile.com"><img src="https://img.shields.io/website?url=https%3A%2F%2Fspawnfile.com&style=flat-square&label=spawnfile.com&color=d4604a" alt="website"></a>
|
|
11
|
+
</p>
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- memory and heartbeat intent docs
|
|
25
|
-
- skills with SKILL.md
|
|
26
|
-
- MCP declarations
|
|
27
|
-
- runtime binding
|
|
28
|
-
- execution intent (model, workspace, sandbox)
|
|
29
|
-
- team structure (members, hierarchy, shared surfaces)
|
|
30
|
-
- agent-level Discord, Telegram, WhatsApp, and Slack surfaces
|
|
31
|
-
|
|
32
|
-
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.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Companion Docs
|
|
37
|
-
|
|
38
|
-
- `specs/INDEX.md` - map of all specs with status and relationships
|
|
39
|
-
- `specs/SPEC.md` - canonical Spawnfile source spec
|
|
40
|
-
- `specs/COMPILER.md` - v0.1 compiler architecture, graph resolution, and adapter contract
|
|
41
|
-
- `specs/CONTAINERS.md` - container compilation spec
|
|
42
|
-
- `specs/RUNTIMES.md` - runtime registry, version pinning, and adapter lifecycle
|
|
43
|
-
- `specs/research/` - per-runtime research notes and adapter strategies
|
|
44
|
-
- `fixtures/` - canonical v0.1 source projects for compiler validation
|
|
45
|
-
|
|
46
|
-
---
|
|
13
|
+
<p align="center">
|
|
14
|
+
<img src="website/public/new-claw-images.png" alt="Spawnfile compiles one agent source into multiple runtimes" width="420" />
|
|
15
|
+
</p>
|
|
47
16
|
|
|
48
|
-
|
|
17
|
+
Spawnfile is a **portable source format** for autonomous agents and teams. You write one canonical project — identity docs, skills, MCP connections, model and sandbox intent, team structure, and declared communication surfaces — and `spawnfile compile` lowers it into the runtime-specific config and workspace each adapter needs.
|
|
49
18
|
|
|
50
|
-
|
|
19
|
+
It's not a runtime-to-runtime translator. The compiler starts from the canonical source, emits each declared adapter's output, and reports per-capability support as `supported`, `degraded`, or `unsupported`.
|
|
51
20
|
|
|
52
|
-
|
|
53
|
-
- CLI: `commander`
|
|
54
|
-
- manifest parsing: `yaml` + `zod`
|
|
55
|
-
- tests: `vitest`
|
|
56
|
-
|
|
57
|
-
That gives us fast iteration, a conventional `bin`-based CLI, and a clean path to future install surfaces such as npm or a shell bootstrapper.
|
|
58
|
-
|
|
59
|
-
---
|
|
21
|
+
Pairs with [**Moltnet**](https://moltnet.dev) as the first provider for `team.networks[]`, letting compiled agents share declared rooms, DMs, and history across runtimes without Spawnfile injecting its own message router.
|
|
60
22
|
|
|
61
23
|
## Install
|
|
62
24
|
|
|
63
|
-
From a repository checkout:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
nvm use
|
|
67
|
-
npm install
|
|
68
|
-
npm run build
|
|
69
|
-
npm link
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Or use the bootstrap script:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
./scripts/install.sh
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Then:
|
|
79
|
-
|
|
80
25
|
```bash
|
|
26
|
+
npm install -g spawnfile
|
|
81
27
|
spawnfile --help
|
|
82
28
|
```
|
|
83
29
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
npm run runtimes:sync
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
This 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.
|
|
30
|
+
Node.js 22+ required. See [source install](#from-source) for local development.
|
|
91
31
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
For local development without linking globally:
|
|
32
|
+
## The happy path
|
|
95
33
|
|
|
96
34
|
```bash
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Why
|
|
103
|
-
|
|
104
|
-
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.
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## How It Works
|
|
109
|
-
|
|
110
|
-
You write a source project once. Then you compile it:
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
spawnfile init
|
|
114
|
-
spawnfile init --runtime tinyclaw
|
|
115
|
-
spawnfile validate
|
|
116
|
-
spawnfile compile
|
|
35
|
+
spawnfile init # scaffold an agent (defaults to openclaw)
|
|
36
|
+
spawnfile validate # check the graph
|
|
37
|
+
spawnfile compile # lower to runtime-native output
|
|
117
38
|
spawnfile auth sync --profile dev --env-file .env
|
|
118
|
-
spawnfile build
|
|
119
|
-
spawnfile run --auth-profile dev
|
|
39
|
+
spawnfile build --tag my-agent # compile + docker build
|
|
40
|
+
spawnfile run --tag my-agent --auth-profile dev
|
|
120
41
|
```
|
|
121
42
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
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.
|
|
43
|
+
Compiled output lands under `.spawn/` by default, including a `Dockerfile`, `entrypoint.sh`, `.env.example`, and a prebuilt `container/rootfs/` tree. `spawnfile build` uses the pinned runtime artifacts from `runtimes.yaml`; it does not rebuild runtimes from source.
|
|
125
44
|
|
|
126
|
-
|
|
45
|
+
## Project structure
|
|
127
46
|
|
|
128
|
-
|
|
47
|
+
A Spawnfile project is either an `agent` or a `team`.
|
|
129
48
|
|
|
130
|
-
|
|
131
|
-
- `execution` carries portable intent like model, workspace, and sandbox
|
|
132
|
-
- `agent` may hold internal `subagents`
|
|
133
|
-
- `team` is for first-class agents that coordinate as a group
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Project Structure
|
|
138
|
-
|
|
139
|
-
A source project has a `kind` - either `agent` or `team`.
|
|
140
|
-
|
|
141
|
-
### Agent
|
|
49
|
+
**Agent**
|
|
142
50
|
|
|
143
51
|
```text
|
|
144
52
|
my-agent/
|
|
145
53
|
├── Spawnfile
|
|
146
|
-
├── IDENTITY.md
|
|
147
|
-
├── SOUL.md
|
|
148
|
-
├── AGENTS.md
|
|
149
|
-
├── MEMORY.md
|
|
150
|
-
├── HEARTBEAT.md
|
|
151
|
-
├──
|
|
152
|
-
│ └──
|
|
153
|
-
|
|
154
|
-
└──
|
|
155
|
-
├── web_search/
|
|
156
|
-
│ └── SKILL.md
|
|
157
|
-
└── memory_store/
|
|
158
|
-
└── SKILL.md
|
|
54
|
+
├── IDENTITY.md # who the agent is
|
|
55
|
+
├── SOUL.md # tone and personality
|
|
56
|
+
├── AGENTS.md # system prompt
|
|
57
|
+
├── MEMORY.md # long-lived memory
|
|
58
|
+
├── HEARTBEAT.md # periodic prompt for scheduled wakes
|
|
59
|
+
├── skills/
|
|
60
|
+
│ └── web_search/SKILL.md
|
|
61
|
+
└── subagents/
|
|
62
|
+
└── researcher/Spawnfile
|
|
159
63
|
```
|
|
160
64
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
### Team
|
|
65
|
+
**Team**
|
|
164
66
|
|
|
165
67
|
```text
|
|
166
68
|
my-team/
|
|
167
69
|
├── Spawnfile
|
|
168
70
|
├── TEAM.md
|
|
169
|
-
├── shared/
|
|
170
|
-
│ └── skills/
|
|
171
|
-
│ └── web_search/
|
|
172
|
-
│ └── SKILL.md
|
|
71
|
+
├── shared/skills/...
|
|
173
72
|
└── agents/
|
|
174
|
-
├── orchestrator/
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
├── researcher/
|
|
178
|
-
│ ├── Spawnfile
|
|
179
|
-
│ └── SOUL.md
|
|
180
|
-
└── writer/
|
|
181
|
-
├── Spawnfile
|
|
182
|
-
└── SOUL.md
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Teams 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.
|
|
186
|
-
Team members may be on the same runtime or on different runtimes depending on what each member declares.
|
|
187
|
-
|
|
188
|
-
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.
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Policy
|
|
193
|
-
|
|
194
|
-
Not every target supports every declared capability. Spawnfile makes that explicit:
|
|
195
|
-
|
|
196
|
-
```yaml
|
|
197
|
-
policy:
|
|
198
|
-
mode: strict
|
|
199
|
-
on_degrade: error
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
The compiler reports one of three outcomes per declared capability: `supported`, `degraded`, or `unsupported`.
|
|
203
|
-
|
|
204
|
-
---
|
|
205
|
-
|
|
206
|
-
## The CLI
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
spawnfile init
|
|
210
|
-
spawnfile init --runtime tinyclaw
|
|
211
|
-
spawnfile init --team
|
|
212
|
-
spawnfile add agent writer
|
|
213
|
-
spawnfile add subagent critic
|
|
214
|
-
spawnfile add team platform
|
|
215
|
-
spawnfile validate
|
|
216
|
-
spawnfile compile
|
|
217
|
-
spawnfile auth
|
|
218
|
-
spawnfile build
|
|
219
|
-
spawnfile run
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
For example:
|
|
223
|
-
|
|
224
|
-
```bash
|
|
225
|
-
spawnfile init --runtime picoclaw ./agents/researcher
|
|
226
|
-
spawnfile add agent writer ./my-team --runtime tinyclaw
|
|
227
|
-
spawnfile add subagent critic ./my-agent
|
|
228
|
-
spawnfile add team platform ./my-team
|
|
229
|
-
spawnfile validate fixtures/single-agent
|
|
230
|
-
spawnfile compile fixtures/single-agent --out ./bundle/example
|
|
231
|
-
spawnfile auth sync fixtures/single-agent --profile dev --env-file ./.env
|
|
232
|
-
spawnfile build fixtures/single-agent --out ./bundle/example --tag example-agent
|
|
233
|
-
spawnfile run fixtures/single-agent --tag example-agent --auth-profile dev
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
Without `--out`, the compiler writes generated artifacts under `.spawn/`. `spawnfile init` also ensures `.spawn/` is ignored in the project `.gitignore`.
|
|
237
|
-
|
|
238
|
-
The compiler emits runtime-specific artifacts under `.spawn/runtimes/...` by default and writes a machine-readable `spawnfile-report.json`.
|
|
239
|
-
|
|
240
|
-
`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.
|
|
241
|
-
|
|
242
|
-
`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`):
|
|
243
|
-
|
|
244
|
-
- `spawnfile add agent <id> [path]` adds `agents/<id>/` under a team
|
|
245
|
-
If `--runtime` is omitted, it uses the same default agent runtime as `spawnfile init`.
|
|
246
|
-
- `spawnfile add subagent <id> [path]` adds `subagents/<id>/` under an agent
|
|
247
|
-
- `spawnfile add team <id> [path]` adds `teams/<id>/` under a team
|
|
248
|
-
|
|
249
|
-
The CLI rejects invalid parent kinds: `add agent` and `add team` only work on team projects, and `add subagent` only works on agent projects.
|
|
250
|
-
|
|
251
|
-
`spawnfile model` edits model intent in place and rewrites touched manifests to the canonical inline shape:
|
|
252
|
-
|
|
253
|
-
- `spawnfile model set <provider> <name> [path]` sets the primary model
|
|
254
|
-
- `spawnfile model add-fallback <provider> <name> [path]` appends a fallback model
|
|
255
|
-
- `spawnfile model clear-fallbacks [path]` removes fallback models
|
|
256
|
-
- if `[path]` points to a team project, `--recursive` is required and only descendant agent manifests are updated; the team manifest itself is left unchanged
|
|
257
|
-
- the first positional argument is always the model provider, not the auth method
|
|
258
|
-
|
|
259
|
-
Team manifests should not declare `execution`. Model, sandbox, and workspace intent belong to agent manifests, not teams.
|
|
260
|
-
|
|
261
|
-
Agent manifests may declare portable communication surfaces under `surfaces`. The first standardized surfaces are Discord, Telegram, WhatsApp, and Slack:
|
|
262
|
-
|
|
263
|
-
```yaml
|
|
264
|
-
surfaces:
|
|
265
|
-
discord:
|
|
266
|
-
access:
|
|
267
|
-
users:
|
|
268
|
-
- "987654321098765432"
|
|
269
|
-
bot_token_secret: DISCORD_BOT_TOKEN
|
|
270
|
-
telegram:
|
|
271
|
-
access:
|
|
272
|
-
users:
|
|
273
|
-
- "123456789"
|
|
274
|
-
chats:
|
|
275
|
-
- "-1001234567890"
|
|
276
|
-
bot_token_secret: TELEGRAM_BOT_TOKEN
|
|
277
|
-
whatsapp:
|
|
278
|
-
access:
|
|
279
|
-
users:
|
|
280
|
-
- "15551234567"
|
|
281
|
-
groups:
|
|
282
|
-
- "120363400000000000@g.us"
|
|
283
|
-
slack:
|
|
284
|
-
access:
|
|
285
|
-
users:
|
|
286
|
-
- "U1234567890"
|
|
287
|
-
channels:
|
|
288
|
-
- "C1234567890"
|
|
289
|
-
bot_token_secret: SLACK_BOT_TOKEN
|
|
290
|
-
app_token_secret: SLACK_APP_TOKEN
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
Discord access may declare:
|
|
294
|
-
|
|
295
|
-
- `mode: pairing | allowlist | open`
|
|
296
|
-
- `users`
|
|
297
|
-
- `guilds`
|
|
298
|
-
- `channels`
|
|
299
|
-
|
|
300
|
-
Telegram access may declare:
|
|
301
|
-
|
|
302
|
-
- `mode: pairing | allowlist | open`
|
|
303
|
-
- `users`
|
|
304
|
-
- `chats`
|
|
305
|
-
|
|
306
|
-
WhatsApp access may declare:
|
|
307
|
-
|
|
308
|
-
- `mode: pairing | allowlist | open`
|
|
309
|
-
- `users`
|
|
310
|
-
- `groups`
|
|
311
|
-
|
|
312
|
-
Slack access may declare:
|
|
313
|
-
|
|
314
|
-
- `mode: pairing | allowlist | open`
|
|
315
|
-
- `users`
|
|
316
|
-
- `channels`
|
|
317
|
-
|
|
318
|
-
If `mode` is omitted and any allowlist fields are present, Spawnfile infers `allowlist`.
|
|
319
|
-
If you want portable runtime behavior, set `access.mode` explicitly. Leaving `access` unset delegates to runtime defaults, which are not identical across runtimes.
|
|
320
|
-
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`.
|
|
321
|
-
WhatsApp has no portable token-secret field in v0.1; session or QR-style auth remains runtime-defined.
|
|
322
|
-
`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.
|
|
323
|
-
|
|
324
|
-
Runtime support is narrower than the portable schema:
|
|
325
|
-
|
|
326
|
-
- `openclaw` supports `pairing`, `allowlist`, and `open` for Discord, Telegram, WhatsApp, and Slack
|
|
327
|
-
- `picoclaw` supports `open` and user allowlists for Discord, Telegram, WhatsApp, and Slack
|
|
328
|
-
- `tinyclaw` supports `pairing` only for Discord, Telegram, and WhatsApp, and does not support Slack in Spawnfile v0.1
|
|
329
|
-
|
|
330
|
-
Practical notes from the current live smoke matrix:
|
|
331
|
-
|
|
332
|
-
- Discord was verified end to end on OpenClaw and PicoClaw, and as a paired DM surface on TinyClaw
|
|
333
|
-
- Telegram was verified end to end on all three runtimes
|
|
334
|
-
- `tinyclaw` required first-contact pairing on Telegram
|
|
335
|
-
- `openclaw` and `picoclaw` both worked on Telegram with `access.mode: open`
|
|
336
|
-
- WhatsApp was verified end to end on OpenClaw
|
|
337
|
-
- `picoclaw` WhatsApp remains blocked in the pinned artifact because `whatsapp_native` is not compiled into the shipped binary
|
|
338
|
-
- `tinyclaw` WhatsApp remains blocked in the shipped container because the upstream client needs a browser runtime
|
|
339
|
-
- Slack was verified end to end on OpenClaw
|
|
340
|
-
- Slack was verified end to end on PicoClaw
|
|
341
|
-
- `picoclaw` replies to channel messages in a Slack thread; direct messages reply inline
|
|
342
|
-
|
|
343
|
-
Useful options:
|
|
344
|
-
|
|
345
|
-
- `--auth <api_key|claude-code|codex|none>` sets the auth method on the edited model target
|
|
346
|
-
- `--key <ENV_NAME>` sets the env var name used by `api_key` auth for custom/local models
|
|
347
|
-
- `--compat <openai|anthropic>` and `--base-url <url>` configure local/custom endpoint targets
|
|
348
|
-
- `--recursive` updates the target project and every descendant manifest in the graph
|
|
349
|
-
|
|
350
|
-
Examples:
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
spawnfile model set anthropic claude-opus-4-6 --auth claude-code
|
|
354
|
-
spawnfile model set openai gpt-5.4 --auth codex
|
|
355
|
-
spawnfile model set local qwen2.5:14b --auth none --compat openai --base-url http://host.docker.internal:11434/v1
|
|
356
|
-
spawnfile model set anthropic claude-opus-4-6 . --auth claude-code --recursive
|
|
73
|
+
├── orchestrator/Spawnfile
|
|
74
|
+
├── researcher/Spawnfile
|
|
75
|
+
└── writer/Spawnfile
|
|
357
76
|
```
|
|
358
77
|
|
|
359
|
-
|
|
78
|
+
Team members may target different runtimes; the compiler resolves each member independently. Subagents are internal helpers owned by a parent agent — not the same thing as team members. Team coordination is through shared declared agent surfaces and declared team networks, not a Spawnfile-owned router.
|
|
360
79
|
|
|
361
|
-
|
|
362
|
-
- `Dockerfile`, `entrypoint.sh`, `.env.example`
|
|
80
|
+
Not every file is required. Spawnfile names the portable roles; adapters decide how to lower them into runtime-native surfaces. See [`specs/SPEC.md`](specs/SPEC.md) for the full shape.
|
|
363
81
|
|
|
364
|
-
|
|
82
|
+
## Runtime support
|
|
365
83
|
|
|
366
|
-
|
|
84
|
+
v0.1 targets autonomous agent runtimes that share a markdown workspace identity model.
|
|
367
85
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
86
|
+
| Runtime | Status | Default | Surfaces |
|
|
87
|
+
|-----------|---------------|---------|-----------------------------------------------|
|
|
88
|
+
| OpenClaw | active | ✅ | Discord, Telegram, WhatsApp, Slack |
|
|
89
|
+
| PicoClaw | active | | Discord, Telegram, Slack (WhatsApp blocked) |
|
|
90
|
+
| TinyClaw | active | | Discord, Telegram, WhatsApp (pairing-gated) |
|
|
91
|
+
| NullClaw | exploratory | | No active adapter yet |
|
|
92
|
+
| ZeroClaw | exploratory | | No active adapter yet |
|
|
374
93
|
|
|
375
|
-
|
|
94
|
+
Each adapter maps the portable schema into its native forms. The compiler reports a machine-readable `spawnfile-report.json` with the resolved graph, chosen runtimes, and capability outcomes (`supported`, `degraded`, `unsupported`). See [`specs/RUNTIMES.md`](specs/RUNTIMES.md) for the live matrix and pinned versions, or [`runtimes.yaml`](runtimes.yaml) for the registry source of truth.
|
|
376
95
|
|
|
377
|
-
|
|
378
|
-
execution:
|
|
379
|
-
model:
|
|
380
|
-
primary:
|
|
381
|
-
provider: anthropic
|
|
382
|
-
name: claude-opus-4-6
|
|
383
|
-
auth:
|
|
384
|
-
method: claude-code
|
|
385
|
-
```
|
|
96
|
+
## Why
|
|
386
97
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
```yaml
|
|
390
|
-
execution:
|
|
391
|
-
model:
|
|
392
|
-
primary:
|
|
393
|
-
provider: local
|
|
394
|
-
name: qwen2.5:14b
|
|
395
|
-
auth:
|
|
396
|
-
method: none
|
|
397
|
-
endpoint:
|
|
398
|
-
compatibility: openai
|
|
399
|
-
base_url: http://host.docker.internal:11434/v1
|
|
400
|
-
```
|
|
98
|
+
Autonomous agent runtimes already share a meaningful core: markdown workspace identity, skill folders, MCP, model selection, sandboxing. Today that core is re-authored by hand for each runtime. Spawnfile makes it canonical so one source project can ship to any compatible runtime.
|
|
401
99
|
|
|
402
|
-
|
|
100
|
+
## Docs
|
|
403
101
|
|
|
404
|
-
|
|
102
|
+
Hosted docs with rendered specs, runtime guides, and a capability matrix: **[spawnfile.com](https://spawnfile.com)** — start at [Introduction](https://spawnfile.com/introduction/), [Quickstart](https://spawnfile.com/quickstart/), or the [Runtimes overview](https://spawnfile.com/runtimes/overview/).
|
|
405
103
|
|
|
406
|
-
|
|
104
|
+
The source-of-truth specs live in this repo:
|
|
407
105
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
106
|
+
- [`specs/INDEX.md`](specs/INDEX.md) — map of all specs
|
|
107
|
+
- [`specs/SPEC.md`](specs/SPEC.md) — canonical source format
|
|
108
|
+
- [`specs/COMPILER.md`](specs/COMPILER.md) — compiler architecture and adapter contract
|
|
109
|
+
- [`specs/CONTAINERS.md`](specs/CONTAINERS.md) — container compilation
|
|
110
|
+
- [`specs/RUNTIMES.md`](specs/RUNTIMES.md) — runtime registry and version pinning
|
|
111
|
+
- [`specs/SURFACES.md`](specs/SURFACES.md) — messaging surface model
|
|
112
|
+
- [`fixtures/`](fixtures/) — canonical example projects
|
|
411
113
|
|
|
412
|
-
|
|
114
|
+
## From source
|
|
413
115
|
|
|
414
116
|
```bash
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
117
|
+
git clone https://github.com/noopolis/spawnfile.git
|
|
118
|
+
cd spawnfile
|
|
119
|
+
nvm use
|
|
120
|
+
npm install
|
|
121
|
+
npm run build
|
|
122
|
+
npm link
|
|
418
123
|
```
|
|
419
124
|
|
|
420
|
-
|
|
125
|
+
To clone pinned runtimes and generate reference blueprints:
|
|
421
126
|
|
|
422
127
|
```bash
|
|
423
|
-
|
|
424
|
-
cd ./bundle/example
|
|
425
|
-
docker build -t example-agent .
|
|
426
|
-
docker run --env-file .env -p 18789:18789 example-agent
|
|
128
|
+
npm run runtimes:sync
|
|
427
129
|
```
|
|
428
130
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
The repo also includes an opt-in Docker auth E2E harness.
|
|
432
|
-
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.
|
|
433
|
-
|
|
434
|
-
Examples:
|
|
131
|
+
For local development without linking globally:
|
|
435
132
|
|
|
436
133
|
```bash
|
|
437
|
-
npm run
|
|
438
|
-
npm run test:e2e:docker-auth -- --scenario team-multi-runtime --env-file ../headhunter/.env
|
|
134
|
+
npm run dev -- validate fixtures/single-agent
|
|
439
135
|
```
|
|
440
136
|
|
|
441
|
-
|
|
442
|
-
It requires Docker, network access, and real model credentials.
|
|
137
|
+
## Contributing
|
|
443
138
|
|
|
444
|
-
|
|
139
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup, tests, and the runtime adapter contract.
|
|
445
140
|
|
|
446
|
-
##
|
|
141
|
+
## License
|
|
447
142
|
|
|
448
|
-
|
|
143
|
+
MIT — see [LICENSE](LICENSE).
|
|
449
144
|
|
|
450
145
|
---
|
|
451
146
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
**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.
|
|
455
|
-
|
|
456
|
-
**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.
|
|
457
|
-
|
|
458
|
-
Together: *a canonical source project that spawns an agent and can be compiled into the runtimes that can host it.*
|
|
459
|
-
|
|
460
|
-
---
|
|
461
|
-
|
|
462
|
-
*One source format. Many runtimes. Manifest-driven compilation.*
|
|
463
|
-
|
|
464
|
-
**spawnfile.ai** · **github.com/noopolis/spawnfile**
|
|
147
|
+
**[spawnfile.com](https://spawnfile.com)** · **[github.com/noopolis/spawnfile](https://github.com/noopolis/spawnfile)**
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const registerModelCommands = (program, handlers, streams) => {
|
|
2
|
+
const modelCommand = program
|
|
3
|
+
.command("model")
|
|
4
|
+
.description("Edit primary and fallback model declarations");
|
|
5
|
+
modelCommand
|
|
6
|
+
.command("set")
|
|
7
|
+
.argument("<provider>", "Model provider")
|
|
8
|
+
.argument("<name>", "Model name")
|
|
9
|
+
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
10
|
+
.option("--auth <method>", "Model auth method")
|
|
11
|
+
.option("--key <env>", "Environment variable for api_key auth")
|
|
12
|
+
.option("--compat <compatibility>", "Endpoint compatibility for custom/local models")
|
|
13
|
+
.option("--base-url <url>", "Endpoint base URL for custom/local models")
|
|
14
|
+
.option("--recursive", "Update the target project and its descendants")
|
|
15
|
+
.action(async (provider, name, inputPath, options) => {
|
|
16
|
+
const result = await handlers.setProjectPrimaryModel({
|
|
17
|
+
authKey: options.key,
|
|
18
|
+
authMethod: options.auth,
|
|
19
|
+
endpointBaseUrl: options.baseUrl,
|
|
20
|
+
endpointCompatibility: options.compat,
|
|
21
|
+
name,
|
|
22
|
+
path: inputPath,
|
|
23
|
+
provider,
|
|
24
|
+
recursive: options.recursive
|
|
25
|
+
});
|
|
26
|
+
for (const filePath of result.updatedFiles) {
|
|
27
|
+
streams.stdout(`updated ${filePath}`);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
modelCommand
|
|
31
|
+
.command("add-fallback")
|
|
32
|
+
.argument("<provider>", "Model provider")
|
|
33
|
+
.argument("<name>", "Model name")
|
|
34
|
+
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
35
|
+
.option("--auth <method>", "Model auth method")
|
|
36
|
+
.option("--key <env>", "Environment variable for api_key auth")
|
|
37
|
+
.option("--compat <compatibility>", "Endpoint compatibility for custom/local models")
|
|
38
|
+
.option("--base-url <url>", "Endpoint base URL for custom/local models")
|
|
39
|
+
.option("--recursive", "Update the target project and its descendants")
|
|
40
|
+
.action(async (provider, name, inputPath, options) => {
|
|
41
|
+
const result = await handlers.addProjectModelFallback({
|
|
42
|
+
authKey: options.key,
|
|
43
|
+
authMethod: options.auth,
|
|
44
|
+
endpointBaseUrl: options.baseUrl,
|
|
45
|
+
endpointCompatibility: options.compat,
|
|
46
|
+
name,
|
|
47
|
+
path: inputPath,
|
|
48
|
+
provider,
|
|
49
|
+
recursive: options.recursive
|
|
50
|
+
});
|
|
51
|
+
for (const filePath of result.updatedFiles) {
|
|
52
|
+
streams.stdout(`updated ${filePath}`);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
modelCommand
|
|
56
|
+
.command("clear-fallbacks")
|
|
57
|
+
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
58
|
+
.option("--recursive", "Update the target project and its descendants")
|
|
59
|
+
.action(async (inputPath, options) => {
|
|
60
|
+
const result = await handlers.clearProjectModelFallbacks({
|
|
61
|
+
path: inputPath,
|
|
62
|
+
recursive: options.recursive
|
|
63
|
+
});
|
|
64
|
+
for (const filePath of result.updatedFiles) {
|
|
65
|
+
streams.stdout(`updated ${filePath}`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
};
|
package/dist/cli/runCli.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { importClaudeCodeAuth, importCodexAuth, importEnvFile, requireAuthProfile } from "../auth/index.js";
|
|
2
|
-
import { addAgentProject, addProjectModelFallback, addSubagentProject, addTeamProject, buildCompilePlan, buildProject, clearProjectModelFallbacks, compileProject, initProject, runProject, setProjectPrimaryModel, syncProjectAuth } from "../compiler/index.js";
|
|
2
|
+
import { addAgentProject, addProjectSurface, addProjectModelFallback, addSubagentProject, addTeamProject, buildCompilePlan, buildProject, clearProjectModelFallbacks, compileProject, initProject, removeProjectSurface, runProject, setProjectPrimaryModel, setProjectRuntime, setProjectSurfaceAccess, showProjectSurfaces, syncProjectAuth } from "../compiler/index.js";
|
|
3
3
|
import { listRuntimeAdapters } from "../runtime/index.js";
|
|
4
4
|
export interface CliStreams {
|
|
5
5
|
stderr: (message: string) => void;
|
|
@@ -11,6 +11,7 @@ export interface CliHandlers {
|
|
|
11
11
|
compileProject: typeof compileProject;
|
|
12
12
|
addAgentProject: typeof addAgentProject;
|
|
13
13
|
addProjectModelFallback: typeof addProjectModelFallback;
|
|
14
|
+
addProjectSurface: typeof addProjectSurface;
|
|
14
15
|
addSubagentProject: typeof addSubagentProject;
|
|
15
16
|
addTeamProject: typeof addTeamProject;
|
|
16
17
|
clearProjectModelFallbacks: typeof clearProjectModelFallbacks;
|
|
@@ -19,9 +20,13 @@ export interface CliHandlers {
|
|
|
19
20
|
importEnvFile: typeof importEnvFile;
|
|
20
21
|
initProject: typeof initProject;
|
|
21
22
|
listRuntimeAdapters: typeof listRuntimeAdapters;
|
|
23
|
+
removeProjectSurface: typeof removeProjectSurface;
|
|
22
24
|
requireAuthProfile: typeof requireAuthProfile;
|
|
23
25
|
runProject: typeof runProject;
|
|
24
26
|
setProjectPrimaryModel: typeof setProjectPrimaryModel;
|
|
27
|
+
setProjectRuntime: typeof setProjectRuntime;
|
|
28
|
+
setProjectSurfaceAccess: typeof setProjectSurfaceAccess;
|
|
29
|
+
showProjectSurfaces: typeof showProjectSurfaces;
|
|
25
30
|
syncProjectAuth: typeof syncProjectAuth;
|
|
26
31
|
}
|
|
27
32
|
export declare const runCli: (argv: string[], streams?: CliStreams, handlerOverrides?: Partial<CliHandlers>) => Promise<number>;
|