@spunto/build 0.22.0 → 0.24.0

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 CHANGED
@@ -166,8 +166,34 @@ JSON columns at them with `$type<…>()`, instead of a generator having to impor
166
166
  `SetupStatus` is what a shell script writes into a container and a control plane reads back minutes
167
167
  later: changing it is a migration, not an edit.
168
168
 
169
+ ### `@spunto/build/agent-contract` — the Spunto agent contract
170
+
171
+ What an agent app's runner reads on stdin (`user`, `interrupt`, `title`) and prints on stdout:
172
+ **our** vocabulary, one JSON object per line, each event with the harness message it was read from
173
+ as `source`. The runner normalises; the platform has one strict reader for every app:
174
+
175
+ ```ts
176
+ import { readContractLine, runConformance, agentContractSchema } from "@spunto/build/agent-contract"
177
+
178
+ readContractLine('{"type":"message","role":"assistant","text":"done"}') // → [{ type, payload, source }]
179
+ // closed schemas: an unknown field or type is kept as `raw`, with the reason — never half-read
180
+
181
+ const results = await runConformance(start) // start: ({ resume }) => a process you spawned
182
+ ```
183
+
184
+ The JSON Schema is shipped as `@spunto/build/agent-contract/schema.json`, generated from the very
185
+ table the reader validates with. The conformance suite drives a runner like the platform does and
186
+ checks every line and the order of events (simple turn, tool, interrupt, resume, limit, title,
187
+ files). `@spunto/build/agent-contract/fake-agent.mjs` is a whole runner in 46 lines with no SDK
188
+ that passes it. The Claude and Codex runners (`./agent-runners`) carry their adapters next to them
189
+ and are meant to be **bundled** (esbuild, `platform: node`, `format: esm`) before being run.
190
+
169
191
  ### `@spunto/build/agent-stream` — reading an agent session as it happens
170
192
 
193
+ Since the contract (`agent-v1`), what is left here is the writing side of a session and the
194
+ **legacy dialects** — the CLI's `claude-stream`, the runners' former `claude-runner` /
195
+ `codex-runner` — for sessions that began on them.
196
+
171
197
  One adapter per harness dialect, one vocabulary out. A CLI's JSON output is an output format, not
172
198
  an API; adapters normalise into a small set of event types so stored history doesn't date the first
173
199
  time a vendor reshuffles a field.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spunto/build",
3
- "version": "0.22.0",
3
+ "version": "0.24.0",
4
4
  "description": "Spunto's shared Build engine — the devcontainer image protocol and VS Code extension registry clients, with no database, no HTTP framework and no UI.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -63,6 +63,12 @@
63
63
  "types": "./src/agent-stream/index.ts",
64
64
  "import": "./src/agent-stream/index.ts"
65
65
  },
66
+ "./agent-contract": {
67
+ "types": "./src/agent-contract/index.ts",
68
+ "import": "./src/agent-contract/index.ts"
69
+ },
70
+ "./agent-contract/schema.json": "./src/agent-contract/agent-contract.v1.schema.json",
71
+ "./agent-contract/fake-agent.mjs": "./src/agent-contract/examples/fake-agent.mjs",
66
72
  "./agent-protocol": {
67
73
  "types": "./src/agent-protocol/index.ts",
68
74
  "import": "./src/agent-protocol/index.ts"
@@ -104,7 +110,8 @@
104
110
  "typescript": "^5",
105
111
  "vitest": "^4.1.10",
106
112
  "ws": "^8.22.0",
107
- "zod": "^4.6.5"
113
+ "zod": "^4.6.5",
114
+ "esbuild": "^0.25.12"
108
115
  },
109
116
  "peerDependencies": {
110
117
  "zod": "^4"