OSS-first docs
These docs teach the open system first: contracts, generated surfaces, runtimes, governance, and incremental adoption. Studio shows up as the operating layer on top, not as the source of truth.
Host the Builder workbench
Use the reusable Builder workbench as the desktop control surface for snapshot loading, guided authoring, preview, readiness, export, and mobile review handoff.
What you'll build
- A workspace snapshot fetch path.
- A `BuilderWorkbench` host with action callbacks.
- Runtime-mode aware preview/export controls plus mobile review links.
1) Fetch the workspace snapshot
The web shell already exposes a query path for the current Builder workspace snapshot. Your host should load it first, then refresh it after each successful command.
export async function fetchBuilderSnapshot(workspaceId: string) {
const response = await fetch(
`/api/operate/builder/queries/builder.workspace.snapshot?workspaceId=${encodeURIComponent(workspaceId)}`,
{ cache: "no-store" }
);
if (!response.ok) {
throw new Error("Failed to fetch Builder workspace snapshot.");
}
const payload = await response.json() as {
ok: boolean;
result: BuilderWorkspaceSnapshot;
};
if (!payload.ok) {
throw new Error("Builder workspace snapshot query returned an error.");
}
return payload.result;
}Expected output: one `BuilderWorkspaceSnapshot` containing workspace, plan, providers, runtime targets, preview, export, mobile review state, and the operator posture needed for local trust, lease, and comparison status.
2) Host the workbench and refresh on action
The simplest host pattern is local state plus a small action wrapper that executes one Builder command and then refreshes the snapshot.
import {
BuilderWorkbench,
useBuilderWorkbenchState,
} from "@contractspec/module.builder-workbench/presentation";
const { snapshot, setSnapshot, promptDraft, setPromptDraft } =
useBuilderWorkbenchState({
workspace: initialSnapshot.workspace,
initialSnapshot,
});
async function runAction(commandKey: string, payload?: Record<string, unknown>) {
await executeBuilderCommand({ commandKey, workspaceId, payload });
setSnapshot(await fetchBuilderSnapshot(workspaceId));
}
<BuilderWorkbench
snapshot={snapshot}
promptDraft={promptDraft}
onPromptDraftChange={setPromptDraft}
onCapturePrompt={() =>
runAction("builder.channel.receiveInbound", createPromptEnvelope(workspaceId, promptDraft))
}
onGenerateBlueprint={() => runAction("builder.blueprint.generate")}
onCompilePlan={() => runAction("builder.plan.compile")}
onCreatePreview={() => runAction("builder.preview.create", { runtimeMode: "hybrid" })}
onRunReadiness={() => runAction("builder.preview.runHarness")}
onPrepareExport={() => runAction("builder.export.prepare", { runtimeMode: "hybrid" })}
onApproveExport={() => runAction("builder.export.approve")}
onExecuteExport={() => runAction("builder.export.execute")}
selectedExportRuntimeMode="hybrid"
/>;Expected output: each successful action leaves the host with a fresh snapshot and keeps the workbench tabs aligned with current runtime state.
3) Persist Builder defaults in workspace config
The host should agree with the CLI and setup flows on the same control-plane defaults. For local or hybrid setups, keep the Builder API base URL, token env var, and local runtime metadata in `.contractsrc.json`.
{
"builder": {
"enabled": true,
"runtimeMode": "local",
"bootstrapPreset": "local_daemon_mvp",
"api": {
"baseUrl": "https://api.contractspec.io",
"controlPlaneTokenEnvVar": "CONTROL_PLANE_API_TOKEN"
},
"localRuntime": {
"runtimeId": "rt_local_daemon",
"grantedTo": "local:operator",
"providerIds": ["provider.codex", "provider.local.model"]
}
}
}4) Bootstrap providers and routing policy explicitly
Builder v3 treats provider routing as policy, not heuristic. Use the workspace bootstrap command as the single managed-first setup path instead of orchestrating provider registration in the app shell.
await executeBuilderCommand({
commandKey: "builder.workspace.bootstrap",
workspaceId,
payload: {
preset: "managed_mvp",
includeLocalHelperProvider: true,
},
});Common command keys
builder.workspace.bootstrapbuilder.channel.receiveInboundbuilder.blueprint.generatebuilder.plan.compilebuilder.preview.createbuilder.preview.runHarnessbuilder.export.preparebuilder.export.approvebuilder.export.execute
Snapshot-backed operator details
- local runtime trust and lease details
- channel-action posture for mobile/operator follow-up
- comparison posture and export readiness from the shared snapshot
5) Keep runtime mode explicit
Preview and export flows are runtime-mode aware. The host chooses between `managed`, `local`, and `hybrid` and passes that choice into preview or export commands instead of hiding it behind provider selection heuristics.
const [selectedExportRuntimeMode, setSelectedExportRuntimeMode] =
React.useState(resolveBuilderExportRuntimeMode(initialSnapshot));
await executeBuilderCommand({
commandKey: "builder.preview.create",
workspaceId,
payload: {
runtimeMode: selectedExportRuntimeMode,
},
});6) Link mobile review flows
When a patch proposal, approval ticket, or incident needs operator follow-up away from the desktop workbench, deep-link into the mobile review route instead of inventing a separate data model.
export function buildBuilderMobileReviewPath(
workspaceId: string,
cardId: string
) {
return `/operate/builder/workspaces/${encodeURIComponent(workspaceId)}/mobile-review/${encodeURIComponent(cardId)}`;
}Expected output: the same Builder workspace state stays visible from desktop workbench and mobile review surfaces.
7) Keep Connect adjacent, not embedded
Builder owns the authoring control plane. When Builder delegates into coding repositories, enable Connect in those target workspaces for context packs, mutation verification, replay, and review packets, but do not replace Builder contracts with Connect artifacts.
contractspec connect init --scope workspaceBuild a first module bundle
Define one bundle spec, resolve a personalized surface plan, and render it through the React host layer.
Use Connect in a repo
Enable Connect in workspace config, verify agent actions, and inspect local review and replay artifacts.
Why ContractSpec
Keep educational and comparison content reachable without letting it define the primary OSS learning path.