Modules
Every entry point of @spunto/build, what it owns, and where to read about it.
@spunto/build is split into subpath entry points, one per contract. Each one answers a single
question two control planes have to answer identically — what a build log marker looks like, what
a worker's container is called, what a project file contains — and nothing else.
| Entry point | Purpose |
|---|---|
@spunto/build/steps | The build-log protocol: ::spunto:step: markers around each block of an image build, and the [build] EXTENSION FAILED: marker for extensions code-server could not install. |
@spunto/build/extensions | Which VS Code extension registry answers (Open VSX or an extensionquery gallery), and how to search it — so the picker and code-server never disagree. |
@spunto/build/naming | Container, volume, network and image names, plus the fixed paths a worker and its control plane agree on. |
@spunto/build/spec | The portable project file (kind: "spunto/project"): zod schemas, builder, parser. |
@spunto/build/script | The shell generators: image build, first-boot setup, every-boot start, the container CMD, the agent-orchestrated setup plan, and organization skills. |
@spunto/build/catalogs | The curated base images, devcontainer features and suggested extensions a project picker offers. |
@spunto/build/types | ProjectFeature, Repository, SetupStatus, and the worker status vocabulary with its transition graph. |
@spunto/build/agent-stream | One adapter per agent-harness dialect, normalising a session's output into a small, stable event vocabulary; plus model context windows. |
@spunto/build/terminal | The string half of a persistent terminal: dtach attach/create/kill scripts, session listing and parsing, the session-name sanitizer. |
The root import
The root @spunto/build re-exports every entry point above:
// Equivalent — pick whichever reads better in your codebase.
import { workerContainerName, BuildStepTracker } from "@spunto/build"
import { workerContainerName } from "@spunto/build/naming"
import { BuildStepTracker } from "@spunto/build/steps"Subpath imports are the normal way in. They make the dependency explicit, and they matter for one entry point in particular:
@spunto/build/spec imports zod, which is an optional peer dependency. Importing the root
@spunto/build pulls ./spec in with everything else, so it needs zod installed. If you only
use ./naming or ./steps, import those subpaths directly and you never need a schema library.
See Installation.
Every module follows the same rule: no ORM schema, no HTTP framework, no React, no process.env,
no platform I/O. Configuration arrives as function parameters. The reasoning is in
Design rules.
Module pages
Build steps
::spunto:step: markers, the tracker that turns them into banners, and the extension-failure marker.
Extensions
One registry for search and install: parseGallery, searchExtensions, codeServerGallery.
Naming
mp-worker-<id>, mp-proj-<slug>:v<n>, and the paths workers write to. Formats, not preferences.
Project spec
The spunto/project file format, validated identically by every product.
Scripts
buildImageScript, buildSetupScript, buildStartScript, buildWorkerScript, buildSkillsScript…
Catalogs
AVAILABLE_IMAGES, AVAILABLE_FEATURES, SUGGESTED_EXTENSIONS.
Types
SetupStatus, ProjectFeature, Repository, and the worker status graph.
Agent stream
Normalised agent-session events, usage summaries and context windows.
Terminal
dtach-based persistent sessions, as strings — sanitizeSessionName is a security boundary.