--- title: 'build' description: 'Compile the workspace into the bundle your container image serves the agent from.' position: 10 --- # stackbone build > `stackbone build` runs inside a project folder and targets no installation, so > it takes no `--agent`. Its `--json` payload uses the standard > [envelope](/docs/cli/reference/conventions#json-output) and it exits with the > shared [exit codes](/docs/cli/reference/conventions#exit-codes). Compile the project into the **workspace bundle**: the directory your container image serves the agent from. The running image carries no TypeScript and no bundler, so `build` compiles every agent and workflow here, ahead of time. Reach for `build` over [`stackbone package`](/docs/cli/reference/package) when you already own the image and the deployment and only want the workspace bundle. ```sh stackbone build # writes dist/workspace-bundle stackbone build --out-dir out/bundle # anywhere else (relative to the project) ``` | Flag | Type | Description | | ----------- | ------ | -------------------------------------------------------------------------------------------------------- | | `--out-dir` | string | Where to write the bundle. Relative paths resolve against the project. Default: `dist/workspace-bundle`. | What lands in the output directory: ```text dist/workspace-bundle/ .well-known/workspace.json # the manifest the runtime reads first .well-known/config/v1/config-schema.json # your config.schema.ts, as JSON Schema .well-known/workflow/v1/step.mjs # your compiled workflow steps .well-known/workflow/v1/workflow.vm.js # the workflow bundle the VM runs .well-known/workflow/v1/manifest.json # workflow ids, schemas, schedules .well-known/workflow/v1/workflow-schemas.mjs # the live validators `/start` checks input with .well-known/migrations/v1/ # your database migrations, copied verbatim deep-agents//index.mjs # one prebuilt module per deep agent ``` `workflow-schemas.mjs` makes the deployed container reject a bad `POST /api/workflows/:name/start` the same way [`stackbone dev`](/docs/cli/reference/dev) does, instead of starting the run and failing somewhere inside it. The build compiles it from your `inputSchema` / `outputSchema` exports with the same zod your workflows use, and the result is **not** self-contained: it re-imports those packages (`zod`, `@stackbone/sdk`, anything your workflow module pulls in at the top level) from the image's own `node_modules` at boot. If one of them is not there, the container logs a warning naming the file and starts runs **unvalidated**, so production accepts a start your laptop rejects. Grep for that warning after a deploy. `config-schema.json` is your `config.schema.ts`, converted to JSON Schema at build time. The container has no TypeScript, so it reads this file to render the config form in the dashboard and to validate every save. Write no `config.schema.ts` and the build ships no file, which is fine: config stays free-form. Write one the build cannot convert and it warns instead of failing, ships without the file, and the dashboard falls back to a raw JSON field with no validation on save. See [`stackbone.config`](/docs/sdk/platform/config#typed-config). The build bundles each deep agent with its own dependencies inlined, except for the packages that must stay a single copy per process. If one of your dependencies cannot survive bundling, keep it out with `build.external`. See [Keeping a package out of the bundle](/docs/cli/reference/configuration#keeping-a-package-out-of-the-bundle). You install anything you list there into your image by hand, and the build prints the list so you know what to add. If your agent has a database, the build copies `.stackbone/migrations/` into the bundle and the container applies it on the first boot, straight off disk. There is nothing to download, so a container with no outbound network still comes up with your tables in place. Applying is idempotent: a restart adds nothing, and a database that was already migrated logs that it found nothing to do. See [`stackbone.database`](/docs/sdk/data/database#migrations-in-production). A workspace with no schema file, or with a migrations folder you never generated into, ships no migrations and the boot says so. If the project is linked (see [`stackbone link`](/docs/cli/reference/link)), the manifest also records the agent and organization it was built for, so the deployed container needs fewer environment variables. Two workflows always come along, the same two `stackbone dev` gives you: `rag-ingest` (it turns an uploaded document into searchable chunks) and `mapping-suggest` (the dashboard's Auto-map runs it). The build writes the platform version of each into `.stackbone/managed-workflows/` unless you wrote your own at `workflows/rag-ingest.workflow.ts` or `workflows/mapping-suggest.workflow.ts`, in which case yours wins. Leave them out and a document upload fails in the container while it still works on your laptop. A workspace with only agents builds fine, and so does one with only workflows. Anything you did not write stays out of the manifest, and the runtime skips it. A workflow that fails to compile does not fail the build. It ships in the manifest marked degraded, carrying its own compile error, so the deployed box lists it with the reason instead of serving a shorter catalog that explains nothing. The build names each degraded workflow in its summary. An agent that fails to compile still fails the whole build. Copy the directory into your image (the runtime reads it from `/app/workspace`) and deploy. The variables that image boots on are listed at [What you set on the deployed container](/docs/cli/reference/package#what-you-set-on-the-deployed-container). **Requirements**: your project must have `esbuild` installed (for agents) and `@workflow/builders` (for workflows, which every bundle has because of the two above). The build resolves both from your own `node_modules`, so it builds the bundle with the exact versions your agent runs. **JSON payload** ```jsonc { "schema_version": 1, "outDir": "/abs/path/dist/workspace-bundle", "deepAgents": ["support", "billing"], "workflows": ["onboarding", "rag-ingest", "mapping-suggest"], "degradedWorkflows": [], // shipped but not runnable; each entry carries { name, message } "migrations": true, // false when the workspace ships no migrations "external": ["sharp"], // what you must install into the image yourself "manifestVersion": 2, "minImageVersion": "0.3.0", // the oldest runtime image that can read this manifest } ``` **Exit codes**: `0` ok, `1` an agent compile failed (the message names the agent at fault; a failed workflow ships degraded instead, see above), or the build could not resolve `esbuild` or `@workflow/builders` from your project.