ZCL helps you build better agentic tools by testing them with real agents and turning each run into structured evidence.
You run a mission through ZCL, record the final result, and get a clear breakdown of what happened:
- how many turns/actions the agent needed
- how many tokens it used (when runner usage is available)
- where retries, timeouts, or friction happened
This makes it easier to improve command design, naming, and defaults so agents complete tasks faster with fewer mistakes.
- Evidence comes from artifacts and traces.
- Scoring is runner-agnostic.
- Artifact shapes are deterministic and versioned.
- Captures are bounded and redacted by default.
- Operator workflows are JSON-first for automation.
skills.sh (agent-first):
npx skills add marcohefti/zero-context-lab@zclCurrent install path (from source):
go build -o bin/zcl ./cmd/zcl
./install.sh --file ./bin/zcl
zcl versionHomebrew:
brew install marcohefti/zero-context-lab/zclnpm:
npm i -g @marcohefti/zclAlternative (Go toolchain install):
go install github.com/marcohefti/zero-context-lab/cmd/zcl@latestskills.sh:
npx skills add marcohefti/zero-context-lab@zclZCL does not auto-update at runtime.
Check update status:
zcl update status --json
zcl update status --cached --jsonUpdate explicitly via your install path:
npm i -g @marcohefti/zcl@latest
brew upgrade marcohefti/zero-context-lab/zcl
go install github.com/marcohefti/zero-context-lab/cmd/zcl@latestAgent harnesses can enforce a minimum installed version via:
export ZCL_MIN_VERSION=0.2.0Interactive shells get at-most-once-per-day update notices by default.
Set ZCL_DISABLE_UPDATE_NOTIFY=1 to silence notices, or ZCL_ENABLE_UPDATE_NOTIFY=1 to force-enable.
zcl on skills.sh is synced via GitHub Actions: .github/workflows/skills-sh.yml.
- Initialize workspace:
zcl init- Allocate attempt:
zcl attempt start \
--suite smoke \
--mission hello-world \
--prompt "Run echo hello and finish with zcl feedback." \
--isolation-model native_spawn \
--json
```
3. Load attempt env (pick one):
```bash
# auto-written per attempt:
source .zcl/runs/<runId>/attempts/<attemptId>/attempt.env.sh
# or explicit export from any attempt dir:
zcl attempt env --format sh <attemptDir>
# optional custom output path:
zcl attempt start --env-file .zcl/current-attempt.env --env-format sh --json ...
source .zcl/current-attempt.env- Run actions through a funnel:
zcl run -- echo "hello"- Finish with canonical outcome:
zcl feedback --ok --result "HELLO=hello"- Compute + validate:
zcl attempt finish --strict --json
zcl attempt explain --jsonNative host orchestration path (preferred when host supports native fresh session spawn):
zcl suite plan --file suite.yaml --jsonProcess-runner fallback path:
zcl suite run \
--file suite.yaml \
--feedback-policy auto_fail \
--campaign-id smoke-campaign \
--progress-jsonl .zcl/progress/smoke.jsonl \
--session-isolation process \
--json \
-- <runner-cmd> [args...]Root: .zcl/
.zcl/
runs/<runId>/
run.json
suite.json (optional snapshot)
suite.run.summary.json (optional)
run.report.json (optional)
attempts/<attemptId>/
attempt.json
attempt.env.sh (ready-to-source env handoff)
prompt.txt (optional snapshot)
tool.calls.jsonl (primary evidence)
feedback.json (primary evidence)
notes.jsonl (optional)
captures.jsonl (optional)
attempt.report.json (computed)
runner.ref.json (optional)
runner.metrics.json (optional)Core commands:
zcl initzcl update status [--cached] [--json]zcl contract --jsonzcl attempt start|env|finish|explain|list|latestzcl suite plan|runzcl runs listzcl runzcl mcp proxyzcl http proxyzcl feedbackzcl notezcl reportzcl validatezcl expectzcl replayzcl doctorzcl gczcl pinzcl enrich
For machine-readable command + artifact contract:
zcl contract --jsonFind latest successful attempt for a mission:
zcl attempt latest --suite <suiteId> --mission <missionId> --status ok --jsonList attempts/runs for automation dashboards:
zcl attempt list --suite <suiteId> --status any --limit 100 --json
zcl runs list --suite <suiteId> --jsonControl missing feedback behavior:
# strict: missing feedback stays a hard failure
zcl suite run --file suite.yaml --feedback-policy strict --json -- <runner>
# auto_fail: synthesize canonical infra-failure feedback when runner exits early
zcl suite run --file suite.yaml --feedback-policy auto_fail --json -- <runner>Stream live machine-readable status:
zcl suite run --file suite.yaml --progress-jsonl .zcl/progress/suite.jsonl --json -- <runner>Canonical campaign continuity state:
zcl suite run --file suite.yaml --campaign-id <campaignId> --json -- <runner>
# writes .zcl/campaigns/<campaignId>/campaign.state.json by defaultSingle repo gate:
./scripts/verify.shThis runs formatting/tests/vet + contract/docs/skills checks.
PLAN.md(execution checklist)CONCEPT.md(why + non-negotiables)ARCHITECTURE.md(system model + command map)SCHEMAS.md(exact v1 schemas and canonical IDs)AGENTS.md(operator workflow + builder index)docs/feedback-evaluation.md(feedback triage and broad-value recommendation routine)
PLAN.md is intentionally local/gitignored for operator in-flight planning.
