Skip to main content

Your code evolves while you sleep. 🦉 Spec-driven autonomous coding loop.

Project description

owloop — Your code evolves while you sleep

MIT License Python 3.10+ CI Agent Skill Website

Your code evolves while you sleep.

Write specs. Start the loop. Wake up to clean commits.

🦉 Ollie is a nocturnal owl.

While you sleep, he reads your specs, spawns a fresh agent iteration for each task, verifies the result with real shell commands, and only commits when they pass.

Quick Start · How It Works · Writing Specs · Compared To · FAQ


You have 20 lint categories to fix, 200 functions missing type annotations, and error handling copy-pasted everywhere. You know what to do — you just don't have the hours. owloop does it while you sleep.

owloop run → pick spec → fresh agent context → verify with shell commands → commit → next spec → 🌅

🌙 Quick Start

# Install from PyPI
uv tool install owloop
# or: pip install owloop

owloop init        # creates specs/ and templates
# edit specs/01-example.md with your task
owloop run         # start the loop
All commands
Command Description
owloop init Initialize project (creates specs/, .gitignore entries)
owloop spec "goal" Turn a vague goal into a concrete spec via agent clarification
owloop check Validate all specs before running the loop (pre-flight linter)
owloop run Start the autonomous loop with TUI
owloop run -n 20 Limit to 20 iterations
owloop run --max-duration 120 Stop after 2 hours
owloop run --max-tokens 200000 Stop after token budget reached
owloop run --idle-timeout 1800 Kill hung agent after 30min silence
owloop plan Generate implementation plan from specs
owloop status Show specs and completion progress
owloop report Generate HTML summary report for the latest run
owloop spec-from-issue 42 Generate a spec draft from a GitHub issue
owloop version Show installed version

Global options

Option Description
--ascii Use ASCII art instead of Unicode glyphs (better on older Windows terminals)
--no-color Disable colored terminal output
--compact Force the compact single-column TUI layout

🦉 How It Works

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#d4a025', 'primaryTextColor': '#0b1026', 'primaryBorderColor': '#3a4270', 'lineColor': '#3a4270', 'secondaryColor': '#121a2e', 'tertiaryColor': '#121a2e', 'fontFamily': 'Inter, system-ui, sans-serif' }}}%%
graph LR
    A["🦉 Pick spec"]:::owl --> B["fresh agent context"]:::neutral
    B --> C{"DONE?"}:::neutral
    C -- yes --> D["✅ Commit"]:::neutral --> E{"More specs?"}:::neutral
    C -- no --> R["🔄 Retry ≤3"]:::retry --> A
    E -- yes --> A
    E -- no --> F["🌅 Complete"]:::done

    classDef owl fill:#d4a025,stroke:#d4a025,color:#0b1026
    classDef done fill:#8fd19e33,stroke:#8fd19e,color:#f2ecd8
    classDef retry fill:#e0777d33,stroke:#e0777d,color:#f2ecd8
    classDef neutral fill:#121a2e,stroke:#3a4270,color:#f2ecd8
Property How
Natural-language specs owloop spec "goal" reads the codebase, asks clarifying questions, drafts a concrete spec.
Pre-flight linting owloop check validates specs before the loop starts — no wasted tokens on bad specs.
Fresh context Each iteration starts a brand-new agent process. No context rot.
Cross-iteration notes run-notes.md carries learnings between iterations — fresh context without repeating mistakes.
Deterministic completion grep for <promise>DONE</promise> — no AI judgment, no surprises.
Worktree isolation Runs in a separate git worktree. Your main checkout stays untouched.
Auto Mode --permission-mode auto: Ollie asks before risky moves, never YOLO.
Fix-loop detection Same files modified 3+ rounds → Ollie warns of a death spiral.
Token budget cap --max-tokens stops the run before costs spiral.
Sleep prevention Keeps your machine awake during overnight runs (macOS / Linux / Windows).

📝 Writing Specs

Specs are constraint-oriented: define what's off-limits, then make every acceptance criterion a shell command.

# Spec: Extract ValidationError Handling

## Priority: 1

## Requirements
- Extract ~69 repeated `except ValidationError` blocks into
  a single Flask `@app.errorhandler(ValidationError)`

## Acceptance Criteria
- [ ] grep -c "except ValidationError" backend/app/api/*.py  →  ≤ 5
- [ ] uv run ruff check backend/  →  0 errors
- [ ] grep -c "errorhandler" backend/app/__init__.py  →  ≥ 1

## Exclusions
- Do NOT change API response formats
- Do NOT touch models/, schemas/, services/

## Verification
After each change: uv run ruff check backend/

Output when complete: `<promise>DONE</promise>`

Why this works: Exclusions prevent drift. Shell commands verify "done" — no AI judgment needed. One spec = one concern.

Rule of thumb

If you can write a shell command that verifies "done", it's a good owloop task. If "done" requires a human to look and decide, it's not.

Best fit: lint fixes, type annotations, dead code removal, DRY extraction, import cleanup
Poor fit: feature design, architecture decisions, UI/UX, security-sensitive changes

🔄 Compared To

owloop /goal gnhf
Completion grep (deterministic) Haiku model (probabilistic) grep
Context Fresh per iteration Same session Fresh per iteration
Specs Constraint-oriented Free-form Free-form
Best for Backlog of verifiable tasks One focused task Multi-agent overnight

❓ FAQ

When should I use owloop instead of /goal?

/goal is great for one task in one sitting. owloop is for backlogs — a queue of specs, each run in a fresh context, unattended overnight. If you're clearing twenty lint categories or migrating a whole module, loop engineering scales further than one long session.

Is this safe to run on production code?

owloop runs in a separate git worktree with --permission-mode auto. Your main branch stays clean. That said, treat every overnight run as a PR to review in the morning, not a deploy.

Can I use owloop with Codex or OpenCode?

Not directly — owloop is built around claude -p. For multi-agent support, gnhf is the better fit.

🛠️ Development

owloop uses uv for dependency management and ships with ruff, mypy, and pytest-cov as dev tools.

uv sync --group dev          # install dev dependencies
uv run pytest -q             # run tests with coverage
uv run ruff check src/owloop tests
uv run mypy src/owloop tests

All changes are validated on Linux, macOS, and Windows via GitHub Actions.

🦉 Brand

Ollie the owl

owloop's identity — Ollie the owl, the night/amber palette, and the "your code evolves while you sleep" story — is documented in .github/BRAND.md.

Credits

Built on Geoffrey Huntley's Ralph Wiggum methodology, forked from Florian Standhartinger's implementation.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

owloop-0.2.1.tar.gz (414.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

owloop-0.2.1-py3-none-any.whl (54.9 kB view details)

Uploaded Python 3

File details

Details for the file owloop-0.2.1.tar.gz.

File metadata

  • Download URL: owloop-0.2.1.tar.gz
  • Upload date:
  • Size: 414.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for owloop-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ecc241a3a39897c402c65881dbae2865295f5ff88bc8e9eb410298c1235c49bf
MD5 5b9adc018bc01feae085488cd3e6e2e9
BLAKE2b-256 f2309085285807bb6f9068aad08ce81c1eaf58028166d208bbad15eaf4363e24

See more details on using hashes here.

Provenance

The following attestation bundles were made for owloop-0.2.1.tar.gz:

Publisher: release.yml on caoergou/owloop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file owloop-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: owloop-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 54.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for owloop-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5d1be2de081d90e6ab1f21a90cbeed52fc0a613d06ff6f0c729be9517c7113f8
MD5 c342d73eb5d15af84df03f45520e2bfa
BLAKE2b-256 4151acfa0e0bfd594db6bd135923cc0cf4aef957a0e9327f975e0267aea0c23b

See more details on using hashes here.

Provenance

The following attestation bundles were made for owloop-0.2.1-py3-none-any.whl:

Publisher: release.yml on caoergou/owloop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page