One command. Prompt to pull request.
Reckoner is an AI software factory for your terminal. Point it at any git repo, describe what you want in plain English, and walk away. It fetches the latest code, spins up an isolated worktree, runs Claude (or a PAS pipeline), auto-fixes lint violations, and opens a GitHub PR — all without touching your working directory.
reck task my-project "add user authentication with JWT tokens"
# → fetches latest code
# → creates isolated worktree on a fresh branch
# → runs Claude Code against the worktree
# → formats, lints, and typechecks the result
# → auto-fixes any violations (up to 3 iterations)
# → commits, pushes, opens a PR
# → tears down the worktree, preserves all logs
# → PR: https://github.com/user/my-project/pull/42Name origin: Pascal's mechanical calculator was called "the Reckoner." Reckoner is the machine; PAS is the engine inside it.
Most AI coding tools check out the full repository for every task. Reckoner stores each repo as a single bare clone and creates lightweight git worktrees — branches that share the same object store. A 2GB repo stays 2GB whether you run 1 task or 20 concurrently. Worktrees are torn down after completion; logs are preserved forever.
After Claude generates changes, Reckoner runs your full toolchain — formatter, linter, typechecker — automatically detected per language. When violations are found, it doesn't just report them. It generates a structured remediation prompt and sends Claude back in to fix them. This lint-fix loop runs up to N iterations, with stuck-violation detection that stops early if the same issue persists across rounds instead of looping forever.
Supported toolchains out of the box:
| Language | Format | Lint | Typecheck |
|---|---|---|---|
| Rust | cargo fmt |
cargo clippy |
cargo check |
| Python | ruff format |
ruff check |
ty check |
| TypeScript/JS | biome format |
biome check |
— |
Override any of these per-repo with a .reckoner/toolchain.toml file.
Place any executable in .reckoner/linters/ (per-repo) or ~/.reckoner/linters/ (global). It receives the worktree path as an argument and outputs JSONL LintFinding records. Reckoner discovers and runs it automatically — no configuration, no plugin API. Enforce import boundaries, naming conventions, file organization, or anything else your team cares about.
Set up recurring tasks with a single command. Reckoner generates native macOS launchd agents so your pipelines fire on schedule without a server, a daemon, or Docker running in the background.
reck schedule add --name nightly-cleanup \
--repo my-project --pipeline entropy-gc.dot --cron "0 3 * * *"All output is structured JSONL — Claude's responses, toolchain results, lint findings, fix-loop iterations. Each task gets its own log directory that survives worktree teardown. Query logs locally with hl (auto-detected), or spin up the built-in Grafana + Loki stack with one command:
reck infra up # Loki + Grafana, ready in seconds
reck observe # opens the dashboardReckoner invokes the claude CLI directly, which authenticates through macOS Keychain. Your existing Claude subscription is all you need — no environment variables, no key rotation, no token management.
cargo install --path crates/reckoner-cli
reck init # Create ~/.reckoner/ dirs + config + db
reck add git@github.com:user/my-project.git # Register a repo (bare treeless clone)
reck task my-project "add user authentication" # Prompt → PR, fully automated
reck status # Show active tasks
reck logs <task-id> # View preserved logs| Command | What it does |
|---|---|
reck init |
Create ~/.reckoner/ directories, default config, and SQLite database |
reck add <git-url> |
Register a repo (bare treeless clone, auto-detects default branch) |
reck list |
List all registered repos |
reck remove <name> |
Unregister a repo and remove its bare clone |
reck sync <name> |
Fetch latest changes from origin |
reck task <repo> "<prompt>" |
Full pipeline: fetch, worktree, Claude, lint, fix-loop, PR, cleanup |
reck task <repo> "<prompt>" --pipeline <file.dot> |
Use a PAS pipeline instead of direct Claude |
reck task <repo> "<prompt>" --no-pr |
Run without creating a PR (useful for analysis tasks) |
reck lint <repo> |
Standalone toolchain + architectural lint run |
reck status |
All active tasks in a table |
reck status <task-id> |
Detailed view: branch, PR URL, cost, errors |
reck logs <task-id> |
Summary of all log files for a task |
reck logs <task-id> --app |
View Claude's stdout output |
reck logs <task-id> --lint |
View lint findings |
reck logs <task-id> --filter <str> |
Filter log lines by keyword |
reck doctor |
Health checks: git, gh, pas, Docker, API keys, database |
reck config |
Show current configuration |
reck schedule add/list/remove/run |
Manage background pipelines (macOS launchd) |
reck infra up/down/status |
Manage observability stack (Loki + Grafana) |
reck observe |
Open Grafana dashboard in browser |
All commands support reck --verbose <command> for debug-level tracing output.
A reck task moves through a state machine with full audit trail:
pending → provisioning → running → linting → pr_open → done
↓
(fix loop: up to N iterations)
↓
failed (if unrecoverable)
Every state transition is recorded in the database with a timestamp and detail message, so you can reconstruct exactly what happened and when.
Branch naming: reckoner/feat/reck-<id>-<prompt-slug> — the prompt is slugified and truncated to 5 words. Task IDs look like reck-a3f7c1d2.
PR body: Auto-generated with a summary (your prompt), a diffstat of changes, the task ID, and a note that human review is required.
Two Rust crates, clean separation:
| Crate | Role |
|---|---|
| reckoner-core | All business logic: config, SQLite, repo management, task orchestration, lint-fix loop, toolchain detection, container lifecycle, scheduling, observability |
| reckoner-cli | Thin clap CLI binary (reck) — parses args, delegates to core |
| Decision | Why |
|---|---|
| rusqlite (sync) over sqlx | Matches SQLite's synchronous reality. Faster CLI startup, no async runtime needed for DB ops |
Shell out to git/gh |
Auth is free (SSH keys, credential managers). No C dependencies from git2/gitoxide |
| Bare clones + worktrees | Shared object store. A 2GB repo stored once serves unlimited concurrent tasks |
| JSONL logs on disk | Zero infrastructure. Queryable with hl, jq, or the built-in Grafana stack |
| Host execution for Claude | Uses your existing subscription via macOS Keychain. No API key management |
| bollard for Docker API | Pure Rust Docker client for container-based execution (security-hardened: CAP_DROP ALL, no-new-privileges, memory/CPU/PID limits) |
Everything lives under ~/.reckoner/:
~/.reckoner/
├── config.toml # User configuration
├── reckoner.db # SQLite (WAL mode, 0600 permissions)
├── repos/
│ └── <name>.git # Bare clones (shared object store)
├── worktrees/ # Transient, per-task (cleaned up automatically)
├── logs/
│ └── <task-id>/ # Permanent — survives worktree teardown
│ ├── stdout.jsonl # Claude output
│ ├── stderr.log # Error output
│ ├── toolchain.jsonl # Format/lint/typecheck results
│ ├── linter.jsonl # Architectural lint findings
│ └── fix-loop-summary.jsonl
└── infra/
└── docker-compose.yml # Grafana + Loki stack
Config lives at ~/.reckoner/config.toml. Run reck init to create defaults.
[general]
repos_dir = "~/.reckoner/repos"
worktrees_dir = "~/.reckoner/worktrees"
logs_dir = "~/.reckoner/logs"
[pas]
binary = "pas"
default_model = "sonnet"
default_max_budget_usd = 10.0
[git]
auto_pr = true
pr_prefix = "reckoner"
[linters]
enabled = true
max_fix_iterations = 3
max_file_lines = 500- Claude Code (
claudeon PATH, logged in) - PAS (
pason PATH) — for pipeline mode - Git, GitHub CLI (
gh) - OrbStack, Colima, or Docker — for container-based linting and the observability stack
Licensed under either of Apache License, Version 2.0 or MIT License at your option.