Babysitter CLI & SDK Examples
June 24, 2026 · View on GitHub
This guide walks through a realistic flow that exercises the babysitter CLI and the deterministic test harness exposed from @a5c-ai/babysitter-sdk/testing. The examples target Babysitter 6.0.0 (edition v6). The end-user CLI is installed from @a5c-ai/babysitter; the programmatic runtime used by the testing harness ships in @a5c-ai/babysitter-sdk:
# Core CLI (end users)
npm install -g @a5c-ai/babysitter
# Programmatic runtime / testing harness (process authors)
npm install @a5c-ai/babysitter-sdk
The examples assume you are standing in the repo root (or a project that already installed the CLI + SDK) and that ~/.a5c/runs is the default runs directory. Set BABYSITTER_RUNS_SCOPE=repo if you want repo-local <repo>/.a5c/runs instead.
Tip: All CLI paths in this document are rendered with POSIX separators (matching the CLI output convention) even when running on Windows.
Related references: For the full
babysittercommand surface see the CLI Reference. For driving a harness directly from your shell (host-side), see the Adapters CLI Reference.
1. Create a run from a process entrypoint
babysitter run:create \
--process-id dev/build \
--entry processes/build/process.mjs#process \
--inputs examples/inputs/build.json \
--prompt "Build all workspace packages"
Typical JSON response (--json):
{
"runId": "run-20260112-130455",
"runDir": "~/.a5c/runs/run-20260112-130455",
"process": {
"processId": "dev/build",
"entry": "processes/build/process.mjs#process"
}
}
1b. Assign a process to a bare run
When a run is created without --entry (a bare run), assign a process before iterating:
babysitter run:assign-process .a5c/runs/run-20260112-130455 \
--entry processes/build/process.mjs#process \
--process-id dev/build \
--json
{
"runId": "run-20260112-130455",
"runDir": ".a5c/runs/run-20260112-130455",
"entry": "processes/build/process.mjs#process",
"processId": "dev/build",
"previousEntrypoint": { "importPath": "bare-run" },
"assigned": true
}
2. Inspect run status
babysitter run:status run-20260112-130455 --json
{
"state": "waiting",
"lastEvent": "RUN_CREATED#0001 2026-01-12T13:04:56.012Z",
"pendingByKind": {
"node": 2
},
"metadata": {
"stateVersion": 1,
"pendingEffectsByKind": {
"node": 2
}
}
}
The CLI prints the same summary in human form when --json is omitted:
[run:status] state=waiting last=RUN_CREATED#0001 2026-01-12T13:04:56.012Z pending[node]=2 pending[total]=2 stateVersion=1
3. Discover pending effects
babysitter task:list run-20260112-130455 --pending
[task:list] pending=2
- ef-build-001 [node requested] build workspace (taskId=build.workspaces)
- ef-lint-001 [node requested] lint sources (taskId=lint.sources)
The JSON variant highlights the run-relative artifact refs (all / even on Windows):
{
"tasks": [
{
"effectId": "ef-build-001",
"status": "requested",
"kind": "node",
"label": "build workspace",
"taskDefRef": "tasks/ef-build-001/task.json",
"resultRef": null,
"stdoutRef": null,
"stderrRef": null
}
]
}
4. Inspect a specific effect
babysitter task:show run-20260112-130455 ef-build-001 --json
Key fields in the response:
{
"effect": {
"effectId": "ef-build-001",
"taskId": "build.workspaces",
"status": "requested",
"stdoutRef": null
},
"task": {
"kind": "node",
"node": {
"entry": "build/scripts/build-workspace.mjs",
"args": ["--workspace", "frontend"]
}
},
"result": null,
"largeResult": null
}
When result.json exceeds 1 MiB the CLI prints result: see tasks/<id>/result.json instead of dumping the payload.
5. Dry-run a task result post
babysitter task:post run-20260112-130455 ef-build-001 --status ok --dry-run
[task:post] status=skipped
Dry runs preview the mutation and exit 0 without changing on-disk state.
6. Drive a run without built-in auto-execution
Instead of run:continue (removed), loop run:iterate, execute pending effects using your own runner (hook/worker/agent), then commit results with task:post.
7. Run a harness directly with the host-side adapters CLI
The babysitter examples above drive an orchestration run. When you just want to invoke a supported harness directly from your shell, use the host-side adapters CLI (@a5c-ai/adapters-cli). It is documented in full in the Adapters CLI Reference:
adapters doctor
adapters run claude "explain this codebase"
adapters doctor runs an environment health check (it confirms the CLI can see your harness binaries and credentials), and adapters run <agent> "<prompt>" runs the named harness with a single prompt.
8. Unit-test a process with the deterministic harness
The SDK now exports runToCompletionWithFakeRunner from @a5c-ai/babysitter-sdk/testing. Use it to exercise process logic without invoking real node runners:
import { runToCompletionWithFakeRunner } from "@a5c-ai/babysitter-sdk/testing";
import { createRun } from "@a5c-ai/babysitter-sdk";
import path from "node:path";
import os from "node:os";
import fs from "node:fs/promises";
test("build pipeline converges", async () => {
const runsDir = await fs.mkdtemp(path.join(os.tmpdir(), "babysitter-tests-"));
const { runDir } = await createRun({
runsDir,
process: {
processId: "dev/build",
importPath: "../processes/build/process.mjs",
exportName: "process",
},
inputs: { branch: "main" },
});
const result = await runToCompletionWithFakeRunner({
runDir,
resolve(action) {
if (action.kind === "node") {
return { status: "ok", value: { value: action.taskDef.metadata?.value ?? 0 } };
}
return undefined;
},
});
expect(result.status).toBe("completed");
expect(result.executed).toHaveLength(2);
});
- Each fake resolution can provide
stdout,stderr, timestamps, and metadata. - If your resolver returns
undefinedfor an action, the harness leaves it pending and returns{ status: "waiting", pending: [...] }. - Use
maxIterations(default100) to catch runaway loops, andonIteration(result)to inspect intermediate states.
9. Cleaning up run artifacts
All examples above write into ~/.a5c/runs/<runId> by default. After a tutorial or test completes, remove the directory (or move it under an archive location) to keep your environment tidy:
rm -rf ~/.a5c/runs/run-20260112-130455
Need another scenario documented? Open an issue with the desired flow (CLI flags, harness behavior, etc.) and the team will extend this file. For the deeper specification refer to babysitter_cli_surface_spec.md.
Appendix A. Regenerating this walkthrough (deterministic workflow)
This walkthrough is anchored to the real smoke harness in packages/babysitter-sdk/scripts/smoke-cli.js and the generated traceability index at docs/generated/cli-examples-verification.md. When you change CLI output, flags, or wording in this file, use the current repo workflow below from a fresh checkout:
- Install dependencies and build the SDK CLI.
npm ci
npm run build --workspace=@a5c-ai/babysitter-sdk
- Regenerate repo docs artifacts, including the CLI traceability index.
npm run docs:prepare
- Run the real CLI smoke harness.
npm run docs:examples:smoke
This delegates to npm run smoke:cli --workspace=@a5c-ai/babysitter-sdk, which stages deterministic fixtures under packages/babysitter-sdk/test-fixtures/cli/runs/smoke/. Add -- --keep to the underlying SDK command when you need to inspect the staged run directory after the smoke run finishes.
- Run the repo docs checks that validate published command surfaces.
npm run docs:snippets
npm run docs:qa
- Keep the harness API docs aligned.
packages/babysitter-sdk/src/testing/README.mdandlibrary/reference/sdk.mdshould be updated in the same change when this walkthrough referencesrunToCompletionWithFakeRunner,captureRunSnapshot, or other deterministic harness APIs.- Run
npm run test --workspace=@a5c-ai/babysitter-sdkafter changing those APIs or their examples.
CLI output intentionally uses POSIX-style paths even on Windows so the published examples stay stable across platforms. Task payloads remain redacted unless BABYSITTER_ALLOW_SECRET_LOGS=1 is set for verbose JSON inspection.