project-builder.json
project-builder.json sits at the project root and anchors the workspace. builder init writes it; builder execute and builder new schematic read it.
Editor validation
Section titled “Editor validation”builder init writes a $schema pointer to the schema that @pbuilder/sdk ships:
{ "$schema": "./node_modules/@pbuilder/sdk/schemas/project-builder.schema.json"}Once @pbuilder/sdk is installed, editors with JSON schema support (VS Code, JetBrains IDEs, and any editor running a JSON language server) validate the file and autocomplete its keys. The schema ships with @pbuilder/sdk 0.5.0 and later. With an external SDK root, node_modules/@pbuilder/sdk is a link to that root, so the same path still resolves.
Example
Section titled “Example”{ "$schema": "./node_modules/@pbuilder/sdk/schemas/project-builder.schema.json", "version": "1", "collections": { "widgets": { "path": "./libs/widgets/collection.json" }, "default": { "api-endpoint": { "path": "./schematics/api-endpoint" } } }, "dependencies": {}, "settings": { "autoInstall": true, "conflictPolicy": "child-wins", "depValidation": "dev", "schematicCollections": ["default"] }, "skill": { "enabled": true, "path": ".claude/skills/pbuilder/SKILL.md" }, "sdk": { "version": "0.5.0" }}Top-level keys
Section titled “Top-level keys”| Key | Type | Written by init |
Purpose |
|---|---|---|---|
$schema |
string | the path above | Points editors at the schema. The CLI does not read it. |
version |
string | "1" |
Config format version. |
collections |
object | {} |
Collections by name. See collections. |
dependencies |
object | {} |
Package names mapped to semver ranges. The CLI does not read it: SDK selection uses package.json and sdk.version. |
settings |
object | the defaults below | See settings. |
skill |
object | { "enabled": true, "path": ".claude/skills/pbuilder/SKILL.md" } |
The agent skill init installs. enabled is false after init --no-skill. |
sdk |
object | not written | See sdk. |
Keys the CLI does not know are kept as they are, including on init --force, so you can store your own data at the top level.
collections
Section titled “collections”Each entry under collections takes one of two shapes.
In collection mode, the entry points at a collection.json:
{ "collections": { "widgets": { "path": "./libs/widgets/collection.json" } }}An entry with a path string is always read as collection mode.
A schematic container maps schematic names to their directories. builder new schematic writes this shape into default:
{ "collections": { "default": { "api-endpoint": { "path": "./schematics/api-endpoint" } } }}Inside a schematic container, the key schematics is reserved for inline registrations ({ "schematics": { "<name>": { "factory": "<module>#<export>" } } }). builder execute rejects a schematic registered only inline with execute_unsupported_registration, and a name registered both ways with execute_ambiguous_registration. See CLI output and errors.
All paths are relative to the workspace and must stay inside it.
settings
Section titled “settings”| Key | Type | Default | Values |
|---|---|---|---|
autoInstall |
boolean | true |
|
conflictPolicy |
string | "child-wins" |
child-wins, strict |
depValidation |
string | "dev" |
dev, strict |
schematicCollections |
string[] | ["default"] |
Collection names, in order |
schematicCollections is the ordered list of collections searched for a schematic given without a collection, and its first entry is the collection builder new schematic writes to. An absent or empty list means ["default"].
The CLI does not act on autoInstall, conflictPolicy or depValidation yet, and it does not check their values. The schema lists the documented values so editors can flag a typo.
A missing or null settings means all defaults. Unknown keys inside settings are dropped when init --force rewrites the file.
| Key | Type | Purpose |
|---|---|---|
version |
string | Minimum @pbuilder/sdk version, used when package.json declares none. See SDK requirement. |
root |
string | Absolute or config-relative path to an external @pbuilder/sdk package directory. See External SDK root. |
Both keys are optional and independent. init never writes sdk.
init --force
Section titled “init --force”Re-running builder init --force on an existing workspace rewrites the file:
$schema,versionandskillare reset to the valuesinitwrites.collections,dependenciesandsettingskeep your values.sdkand every unknown top-level key are kept as they are.- Unknown keys inside
settingsare dropped.