A Rust CLI tool for orchestrating spec generation workflows with Claude AI. Transform rough feature ideas into structured requirements, designs, and implementation tasks through an automated multi-phase pipeline.
- Multi-Phase Orchestration: Requirements -> Design -> Tasks -> Review -> Fixup -> Final with configurable phase_timeout (default: 600s). Phase execution exceeded timeout results in exit code 10.
- Lockfile System: Reproducibility tracking with
--create-lockand--strict-lockflags. Detects lock_drift when model or CLI versions change between executions. - Fixup System: Secure diff application with Preview Mode (default) and Apply Mode (
--apply-fixups). Path validation prevents directory traversal attacks. - Ecosystem Features:
- Workspace Orchestration: Manage multi-spec projects with
xchecker projectcommands. - Templates: Bootstrap new specs instantly with
xchecker template init(Next.js, Rust, Python support). - Hooks: Customize workflows with pre/post-phase shell hooks.
- Policy Gates: Enforce quality standards in CI/CD with
xchecker gate.
- Workspace Orchestration: Manage multi-spec projects with
- Controlled Execution: Only
controlledstrategy is supported; LLMs propose diffs and xchecker applies them. - Standardized Exit Codes: Process exit codes always match receipt exit_code field for reliable automation and monitoring.
- Versioned JSON Contracts: Stable schemas for receipts, status, and health checks
- Multi-Provider Support:
- CLI: Claude CLI, Gemini CLI
- HTTP: OpenRouter, Anthropic API
- Resilience: Robust fallback logic and budget control for HTTP providers
- Security First: Automatic secret detection and redaction
- Cross-Platform: Linux, macOS, Windows with WSL support
# From crates.io
cargo install xchecker
# From source
git clone https://github.com/EffortlessMetrics/xchecker.git
cd xchecker && cargo install --path .Requirements: Rust 1.89+, and a configured LLM provider (e.g. Claude CLI, Gemini CLI, or API key).
xchecker can be embedded as a library in your Rust applications:
# Cargo.toml
[dependencies]
xchecker = "1"use xchecker::{OrchestratorHandle, PhaseId, Config};
fn main() -> Result<(), xchecker::XcError> {
// Option 1: Use environment-based discovery (like CLI)
let mut handle = OrchestratorHandle::new("my-feature")?;
// Option 2: Use explicit configuration
let config = Config::builder()
.state_dir(".xchecker")
.build()?;
let mut handle = OrchestratorHandle::from_config("my-feature", config)?;
// Run a single phase
handle.run_phase(PhaseId::Requirements)?;
// Check status
let status = handle.status()?;
println!("Artifacts: {:?}", status.artifacts);
Ok(())
}See the examples/ directory for more embedding examples.
# Check your environment
xchecker doctor
# Create a spec from stdin
echo "Build a REST API for user management" | xchecker spec my-feature
# Check status
xchecker status my-feature
# Resume from a specific phase
xchecker resume my-feature --phase design
# Apply code changes
xchecker resume my-feature --phase fixup --apply-fixups| Command | Description |
|---|---|
xchecker spec <id> |
Generate a new spec through the requirements phase |
xchecker resume <id> --phase <phase> |
Resume execution from a specific phase |
xchecker status <id> |
Display spec status and configuration |
xchecker clean <id> |
Clean up spec artifacts and receipts |
xchecker doctor |
Run environment health checks |
xchecker init <id> |
Initialize a new spec with optional lockfile |
xchecker benchmark |
Run performance benchmarks |
--dry-run # Preview without making LLM calls
--json # Output as JSON
--force # Override stale locks
--apply-fixups # Apply file changes (default is preview)
--verbose # Enable structured loggingxchecker uses a hierarchical configuration system: CLI flags > config file > defaults.
# .xchecker/config.toml
[defaults]
model = "haiku"
phase_timeout = 600
[selectors]
include = ["src/**/*.rs", "docs/**/*.md"]
exclude = ["target/**", ".git/**"]Hooks are opt-in and configured under [hooks] for pre/post-phase scripts.
See Configuration Guide for all options.
xchecker stores all state in a directory determined by:
- Thread-local override (used internally for test isolation)
- XCHECKER_HOME environment variable (user/CI override)
- Default:
./.xchecker(relative to current working directory)
Override the default state directory location using the XCHECKER_HOME environment variable:
# Set for your session
export XCHECKER_HOME=/path/to/custom/state
xchecker spec my-feature
# Or inline for a single command
XCHECKER_HOME=/tmp/xchecker-test xchecker status my-feature
# Useful for CI/CD to isolate builds
XCHECKER_HOME=/tmp/build-${BUILD_ID} xchecker spec featureThe state directory contains specs// directories for each specification, with the following structure:
.xchecker/ # State directory (XCHECKER_HOME)
├── config.toml # Configuration file (optional)
└── specs/ # All specs
└── <spec-id>/ # Individual spec directory
├── artifacts/ # Generated artifacts (requirements, design, tasks)
│ ├── 00-requirements.md
│ ├── 10-design.md
│ └── 20-tasks.md
├── receipts/ # Execution receipts with metadata
│ └── <phase>-<timestamp>.json
└── context/ # Context files sent to Claude
└── packet-<hash>.txt
Directory purposes:
- specs//artifacts/: Generated phase outputs (requirements, design, tasks, review, fixup)
- specs//receipts/: Execution audit trails with BLAKE3 hashes and metadata
- specs//context/: Packet previews for debugging (enabled with
--debug-packet)
| Code | Name | Description |
|---|---|---|
| 0 | SUCCESS | Completed successfully |
| 7 | PACKET_OVERFLOW | Packet size exceeded |
| 8 | SECRET_DETECTED | Secret found in content |
| 9 | LOCK_HELD | Lock already held |
| 10 | PHASE_TIMEOUT | Phase timed out |
| 70 | CLAUDE_FAILURE | LLM Provider failure |
| What | Guarantee |
|---|---|
| v1 JSON schemas | Additive-only changes; no breaking changes without version bump |
| Canonical emission | JCS (RFC 8785) for reproducible, diff-friendly JSON |
| Atomic writes | All artifact writes via staging directory; no partial files |
| Secret scanning | Always runs before LLM invocation; blocks on detection |
| Failure modes | Structured exit codes; no silent failures or "best effort" modes |
| State directory layout | artifacts/, receipts/, problem_statement.txt are stable API |
| Area | Limitation |
|---|---|
| LLM provider | Agnostic; supports Claude CLI, Gemini CLI, OpenRouter, Anthropic API |
| Execution strategy | Controlled only; LLMs propose diffs, xchecker applies |
| Fixup engine | Context-based fuzzy matching works for contiguous context; fails on ambiguous patterns, large shifts, or context split by deletions |
| Diff complexity | Best with small, focused changes; large refactors may fail fuzzy matching |
| Windows | Requires WSL or native Claude CLI; some path edge cases |
For fixup limitations and workarounds, see the Debugging Guide.
| Document | Description |
|---|---|
| Configuration | Full configuration reference |
| Testing | Test lanes and profiles |
| Orchestrator | Core engine architecture |
| Contracts | JSON schema versioning |
| Doctor | Health check details |
| LLM Providers | Provider configuration |
| Debugging Guide | Troubleshooting and diagnostics |
- 20-Minute Quickstart - Get running fast
- Spec to PR - Complete workflow guide
- Debugging Guide - Diagnostics and debugging workflows
- Workspace Guide - Workspace setup and TUI usage
- CI Profiles - CI gate configuration
The repo includes a Nix flake for a pinned Rust toolchain (MSRV 1.89) and common dev tools.
# Enter dev shell
nix develop
# Build the CLI
nix build
# Run xchecker
nix run# Run fast tests (~30s)
cargo test --lib --bins
# Run full suite
cargo test
# Check formatting and lints
cargo fmt -- --check
cargo clippy --all-targets --all-features -- -D warningsSee Testing Guide for test profiles and CI configuration.
MIT OR Apache-2.0
- All tests pass:
cargo test - Code formatted:
cargo fmt - No clippy warnings:
cargo clippy -- -D warnings - Documentation updated for new features
See CHANGELOG.md for version history.