cleanvibe
Website · cleanvibe.emmaleonhart.com
A tiny Python CLI that scaffolds AI-assisted coding projects and launches Claude Code.
cleanvibe is not a coding tool. It's a state initializer -- it removes the friction between "I want to build something" and "Claude is working inside a well-structured environment." The real value is the working contract it installs: a short CLAUDE.md plus six workflow skills in .claude/skills/ that enforce documentation discipline, meaningful commits, and iterative file-based thinking. Repos are private by default, and Claude launches with a first message explaining which mode it is in.
Install
pip install cleanvibe
Developer install (working on cleanvibe itself)
git clone https://github.com/EmmaLeonhart/cleanvibe
cd cleanvibe
pip install . # or use !dev-install.bat on Windows
Use pip install ., not pip install -e .. The repository directory is itself named cleanvibe, which means an editable install collides with Python's namespace-package CWD scanning when you run python from the repo's parent directory — Python finds the repo dir as a namespace package and beats the editable finder, so import cleanvibe returns a module with no __version__. The non-editable install copies the package into site-packages where it always wins. After any source edit, run pip install . again (or !dev-install.bat). The console-script entry point (cleanvibe on PATH) works correctly under both install modes — this quirk only affects programmatic import cleanvibe.
Usage
Create a new project
cleanvibe new my-project
This will:
- Create the directory
my-project/ - Write
CLAUDE.md(a short pointer to the skills + project-specific notes) - Write
README.md(starter documentation) - Write
queue.md(active work queue, pre-seeded with a first-session bootstrap sequence that walks Claude through triaging dropped-in files, inferring the project, interviewing the user, creatingtodo.md, populating the real queue, and pushing to a private GitHub repo) - Write
devlog.md(where "done" lives) and.gitignore(sensible Python defaults) - Create
data_lake/(drop files in before the first session) and, on Windows,!runClaude.bat - Vendor
.claude/skills/(the six workflow skills — see below) - Initialize a git repo on
mainwith an initial commit - Launch Claude Code inside the project, with the
newstarting prompt
Skills (v1.14.0+)
The workflow behaviors that used to be inlined into CLAUDE.md now ship as six
standalone skills, auto-discovered by Claude Code from .claude/skills/:
| Skill | Fires when |
|---|---|
emergency-stop |
you repeatedly say "stop" / demand an immediate halt |
cron-is-local |
you mention "cron" / "schedule" (means local CronCreate) |
autonomous-loop |
starting extensive autonomous work (the three-cron playbook) |
queue-driven-workflow |
any multi-step work (plan into queue.md first; the todo→queue→devlog flow) |
writing-style |
writing any prose (avoid the "honest"/"frank" tic) |
cleanvibe-update-check |
session start, weekly (refresh skills from cleanvibe) |
They're vendored into every new / convert / clone / research / original /
chat project (not replicate, which is a bounded workflow) and
kept current by the cleanvibe-update-check skill (which reads
https://cleanvibe.emmaleonhart.com/updates.md). The single source of truth is
cleanvibe/skills.py; CLAUDE.md keeps only a short ## Skills pointer. To
back-fill these into an existing repo, run migrate_repos_to_skills.py.
Research a question — your own investigation
cleanvibe research reservoiragent
cleanvibe research reservoiragent --question "What is the memory capacity of a reservoir-computing agent?"
cleanvibe new reservoiragent --research # equivalent alias
research is for an original-research project — your own investigation,
not a replication of someone else's paper. It is new
plus the two things that make research legible: an up-front literature
review and a published, themed report. It scaffolds everything new
does (CLAUDE.md, README.md, queue.md, devlog.md, .gitignore,
data_lake/, the three-cron playbook) and adds:
literature/— the literature review, built before any code. The bootstrap queue's distinctive step uses agentic RAG (web search,WebFetch, thedeep-researchskill if present) to survey prior work, collect sources with citations, and synthesizeliterature/REVIEW.md(what's known, the gaps, what this project adds). This grounds the project in the field instead of reinventing it — and is what separatesresearchfromnew.docs/— a published GitHub Pages report site, pre-styled with a warm "paper" light theme + dark-mode variant (the look of latent-space.emmaleonhart.com), plus a transportable PDF built fromFINDINGS.md..github/workflows/pages.ymldeploys it. The agent edits the content; the theme stays.
The bootstrap sequence is literature-review-first: start the crons →
triage data_lake/ → define the research question with you → literature
review (agentic RAG) → write the long-horizon todo.md → push to a
private GitHub repo (going public for Pages is your call) → replace the bootstrap queue with the real
experiment/build queue → work it, keeping FINDINGS.md + the docs/ report
current. Pass --question if you already know the question; otherwise the
bootstrap pins it down with you.
Original research — when you don't have a topic yet
cleanvibe original driftprobe
cleanvibe original driftprobe --area "reservoir computing"
cleanvibe new driftprobe --original # equivalent alias
original is research for an uncertain topic: you don't yet have a fixed
research question. It keeps everything research has — literature/,
data_lake/, the three-cron playbook, the themed docs/ report — and prepends
one distinctive bootstrap step:
topics/— the topic-finding loop, run before the literature review. The bootstrap explores the focus area (agentic search / RAG), drafts a slate of candidate research questions, scores them (novelty, tractability, interest, available data/compute, what a result is worth), confirms the shortlist with you, and converges on ONE — recording the candidates + scoring + the chosen question + rationale intopics/TOPICS.md. Then it proceeds exactly likeresearch.
The seed is --area (a field to explore), not --question — the question is
what the loop discovers. The bootstrap sequence is topic-finding-first: start
the crons → triage data_lake/ → topic-finding loop (pick the question) →
literature review (agentic RAG) → write todo.md → push to a private repo → replace
the bootstrap queue → work it. Use original when you want to investigate some
area but haven't settled on the precise question; use research
when you already know what you're asking.
Chat — a git-tracked conversation
cleanvibe chat # -> chat-YYYY-MM-DD/
cleanvibe chat tea-notes --topic "oolong vs pu-erh"
chat is for a conversation about one topic rather than a software project:
research-heavy, light on code, kept in a private git repo so you can resume,
search and share it. The session opens by asking you what you are trying to do
(AskUserQuestion) before it plans or researches anything. Conclusions and
sources go into notes/, and the README keeps a running "where things stand".
Session logs are git-tracked. The scaffold's .claude/settings.json runs a
small stdlib script (.claude/hooks/save_session_log.py) after every response
and at session end. It copies the transcript into sessions/ as raw .jsonl
plus a readable .md, and commits only sessions/. At session end it also
pushes if the repo has a remote. Transcripts contain everything in the session,
including tool output, which is one reason the repo stays private.
It starts with Remote Control on (claude "<prompt>" --remote-control,
unnamed), so you can pick the conversation up from the Claude app or web.
!runClaude.bat does the same. NAME is optional; without one you get
chat-YYYY-MM-DD in the current directory, auto-suffixed -2/-3 if it exists. Chat mode has no three-cron
playbook and no Pages report.
Every mode: private repo, starting prompt
- Private by default. Every mode that creates a GitHub repo creates it with
gh repo create --private. Going public is your call. On a private repo the research/replication Pages workflows upload the report as a workflow artifact instead of deploying (GitHub's free plan cannot publish Pages from a private repo). Make the repo public, or set the repo variableCLEANVIBE_PAGES=trueon a paid plan, to deploy the site. - Starting prompt. Claude launches with a first message saying the project
was started with cleanvibe, which mode, what that mode is for, and to work
queue.mditem 1, asking you first if the goal is unclear.!runClaude.batrelaunches with the same prompt.
Doctor — audit a project for drift
cleanvibe doctor # audit the current directory
cleanvibe doctor path/to/project
A read-only check of a cleanvibe project for the drift that builds up over
time. It changes nothing, and exits 1 if it finds anything (so it can run in CI):
| Check | Flags |
|---|---|
files |
a missing CLAUDE.md, README.md, queue.md, or devlog.md |
skills |
a vendored skill that is missing or differs from this cleanvibe's copy |
queue-done |
ticked boxes, check marks, DONE, or strikethrough left in queue.md |
version |
queue.md's "Current version" not matching pyproject.toml |
devlog-tags |
a v* git tag with no devlog.md entry |
section-refs |
a reference to a CLAUDE.md section heading that doesn't exist |
ci |
a tests/ directory with no GitHub Actions workflow |
pages-gate |
a pre-v1.18.0 Pages workflow that fails on a private repo |
Clone an existing repo — codebase onboarding
cleanvibe clone https://github.com/user/repo
clone is for onboarding an existing codebase, not bootstrapping a blank
one. It is deliberately different from new:
git clonethe repository- Create and check out a dedicated
cleanvibe-onboardingbranch — the default branch is left untouched - Prepend-or-write an onboarding
CLAUDE.mdandqueue.md: if the repo already has them, the fresh block goes on top (newest first) and the original content is preserved below — re-running just layers another block - Inject
.gitignoreonly if missing. Nodata_lake/(it is a real codebase, nothing was dropped in) and no README overwrite - Commit the onboarding scaffold on the branch
- Launch Claude Code inside the project
The onboarding queue.md is small and focused: read & document the repo,
make existing docs accurate, rewrite CLAUDE.md to the repo's real
development practices, add tests/CI if sparse, then synthesize any existing
planning artifacts and hand off to the repo's own todo.md.
Replicate a paper
cleanvibe replicate takes a clawRxiv reference, an arXiv/alphaxiv
reference, a plain URL to non-arXiv research, or a folder name:
From a clawRxiv paper (skill-first):
cleanvibe replicate https://www.clawrxiv.io/abs/2605.02609
cleanvibe replicate clawrxiv:2605.02609
clawRxiv publishes papers authored autonomously by
AI agents and exposes a JSON API (/api/abs/<id>) that differentiates the
paper content, abstract, and skill file (an agent-runnable replication
recipe). That separation is the purest recipe-first case, so clawRxiv gets its
own dedicated mode. The scaffold fetches all three up front: the paper content
is written locally to replication_target/source/paper.md (gitignored —
the paper is copyrighted and is never committed), and when clawRxiv ships a
separate skill file it lands at replication_skill.md at the root (otherwise
the recipe is embedded in the content and the queue tells the agent to extract
it). A download_paper.py re-fetches the content from the clawRxiv API if
replication_target/ is ever empty (e.g. a fresh clone). The generated
queue.md/SKILL.md are
skill-first: go live early, run the recipe, verify it against the paper,
check all references, then fill only the gaps. clawRxiv ids look arXiv-shaped,
so a bare id stays arXiv — use a clawrxiv.io URL or clawrxiv:<id> to select
clawRxiv mode.
From an arXiv / alphaxiv paper:
cleanvibe replicate https://arxiv.org/abs/1706.03762
cleanvibe replicate https://www.alphaxiv.org/overview/2201.02177
cleanvibe replicate https://doi.org/10.48550/arXiv.1706.03762
cleanvibe replicate 1706.03762v5
Any arXiv/alphaxiv id or URL is accepted — /abs/, /pdf/, /html/,
/src/, alphaxiv's primary /overview/, /audio/, /forum/, the arXiv
DOI form (doi.org/10.48550/arXiv.<id>), arXiv:<id> citation style,
trailing slugs and query strings all resolve. A pinned vN version is
preserved (recorded in paper.json and used for the download), not silently
dropped. This will:
- Fetch the paper's metadata from the arXiv API (with 429-aware
retry/backoff — arXiv rate-limits, so requests honour
Retry-Afterand back off rather than crashing) - Create
replicating-<paper-slug>/(silently-2/-3if it already exists) - Scaffold a standalone replication project: cleanvibe conventions
(
CLAUDE.md,queue.md,data_lake/) plus the replication structure —SKILL.md(the agent-executable replication plan),download_paper.py(fetches the arXiv LaTeX/e-print source and extracts it toreplication_target/source/, with the PDF as a fallback), the paper's homereplication_target/(gitignored — never indata_lake/; the authors' code is cloned here as a git submodule),paper.json, and.github/workflows/that build a GitHub Pages findings site, a transportable PDF report, and a downloadable ZIP replication package - Initialize a git repo with an initial commit
- Launch Claude Code inside the project
The generated scaffold is built around the efficient, recipe-first path:
- Source, not HTML.
download_paper.pydownloads the arXiv e-print source (arxiv.org/src/<id>) and extracts the.textoreplication_target/source/. The.texis far more token-efficient than the rendered HTML, which embeds figures as huge base64 data-URIs you'd otherwise have to strip. The paper is never committed: the wholereplication_target/tree is gitignored (papers are copyrighted), so the download is local context only — runpython download_paper.pyto (re)populate it whenever it's empty. Thecleanvibe replicatecommand runs this download itself before launching Claude, so the agent opens onto an already-extracted paper — but nothing underreplication_target/ever enters a commit. - Consent before running code. Because a replication runs code you didn't
write (the recipe / cloned scripts / a downloaded zip), the generated
queue.md's first step makes the agent stop and get your explicit consent before executing any external/cloned code. Reading the paper, source, and recipe is fine; running third-party code is the gated action. - Find the recipe FIRST. Authors very often ship a reproduction recipe
right in the paper source (usually near the end): a
SKILL.md/AGENTS.md, areproduce.*/replicate.*/run.shscript, a Makefile target, a Dockerfile, or a downloadable replication zip. The generatedqueue.md/SKILL.mdtell the agent to find it (copying a recipe toreplication_skill.md, extracting a zip intoreplication/) and run it first, before any deep paper analysis — then verify its output against the paper, check all the paper's references, and only reimplement the gaps the recipe didn't cover. - Go live early. The agent is told to create a PRIVATE GitHub repo and push near the start, so every commit pushes and CI builds as the work goes — not left local-only. Every mode defaults to private; on a private repo the Pages workflow uploads the report as a workflow artifact instead of deploying it, until you make the repo public.
- Themed report with a status badge. The GitHub Pages findings site is
rendered with the shared cleanvibe report theme (
report-theme.css— the same warm "paper" + dark-mode themecleanvibe researchuses) and topped with a big color-coded replication status badge — 🟢 replicated / 🔴 failed / 🟠 insufficient hardware / 🔵 in progress — driven by astatusfield inpaper.json(defaults to in-progress). A transportable PDF is built too.
From a plain URL (research that isn't on arXiv):
cleanvibe replicate https://some-lab.org/papers/cool-thing.pdf
cleanvibe replicate https://openreview.net/forum?id=XXXX
When the argument is a plain http(s) URL that isn't an arXiv/clawRxiv
reference, cleanvibe downloads it as the replication source — the page or
PDF lands locally in replication_target/source/ (paper.pdf or
paper.html, detected automatically) — gitignored, never committed — and
provenance is recorded in source.json. A download_paper.py re-downloads
from that recorded URL if replication_target/ is ever empty. Same 429-aware
retry/backoff as arXiv mode. Use it for research hosted on lab sites,
OpenReview, journal pages, or anywhere that isn't arXiv/clawRxiv.
From a folder you fill yourself (manual drop-in mode):
cleanvibe replicate my-paper-replication
When the argument is not an arXiv/alphaxiv reference (and not a URL) it is
treated as a folder name and a manual drop-in project is scaffolded — no
metadata
fetch, no download_paper.py, no paper.json, no network. You drop the
paper PDF(s) into replication_target/ and any datasets/notes into
data_lake/ yourself; the scaffolded CLAUDE.md / queue.md / SKILL.md
/ README.md say so up front, and the first queue step makes the agent
stop and ask you for the paper if replication_target/ is empty rather
than invent one. Injection is non-destructive: you can create the folder,
drop your PDF in, then run cleanvibe replicate ./that-folder — nothing
you put there is overwritten.
Every replication produces three compounding artifacts: the runnable
replication, a published findings report, and the reusable SKILL.md
methodology. See docs/replication_framing.md for the full vision.
Options
cleanvibe new my-project --dry-run # Preview what would be created
cleanvibe new my-project --no-claude # Skip launching Claude Code
cleanvibe research my-study --dry-run # Preview the research scaffold
cleanvibe research my-study --no-claude # Scaffold a research project without launching Claude
cleanvibe chat --dry-run # Preview the chat scaffold
cleanvibe doctor # Audit the current project for drift (read-only)
cleanvibe clone REPO path --dry-run # Preview what would be done
cleanvibe replicate URL --dry-run # Preview the arXiv replication scaffold
cleanvibe replicate FOLDER --dry-run # Preview the manual drop-in scaffold
cleanvibe replicate URL --no-claude # Scaffold without launching Claude
cleanvibe --version # Show version
Why?
Most people struggle with blank repo paralysis, poor commit hygiene, and AI assistants that ramble without producing durable artifacts. cleanvibe solves this by injecting a disciplined thinking contract into every project from the start.
The CLAUDE.md template enforces:
- Commit early and often with meaningful messages
- No planning-only modes -- all thinking produces files and commits
- Keep documentation up to date as the project evolves
- Use
planning/directories for exploration instead of internal planning modes
Cross-platform
Works on Windows, Linux, and macOS. Zero dependencies beyond Python 3.9+.
Website
Full walkthrough — what cleanvibe is and what each subcommand does — at the
project site (built from pages/ and deployed by GitHub Actions):
https://cleanvibe.emmaleonhart.com/
Stability
As of v1.0.0, cleanvibe commits to the following contract (semantic versioning from here on):
- Subcommands
new,research,original,chat,clone,convert,replicate, anddoctorare stable. Their core behavior will not change incompatibly within the 1.x line. - Injected files:
newguaranteesCLAUDE.md,README.md,queue.md,.gitignore, anddata_lake/.gitkeep.researchguarantees all of those plusliterature/.gitkeep,docs/index.html(the themed report site), and.github/workflows/pages.yml.chatguaranteesCLAUDE.md,README.md,queue.md,devlog.md,.gitignore,notes/,sessions/,data_lake/,.claude/settings.jsonand.claude/hooks/save_session_log.py.replicatealways guaranteesSKILL.md,CLAUDE.md,queue.md, and a gitignoredreplication_target/(the paper lives here, local-only, and is never committed — papers are copyrighted); in arXiv mode it additionally guaranteespaper.jsonanddownload_paper.py; in clawRxiv mode it guaranteespaper.json, adownload_paper.py(re-fetches the content from the clawRxiv API), and a localreplication_target/source/paper.md(plusreplication_skill.mdwhen clawRxiv ships a separate skill file); URL mode guaranteessource.jsonand adownload_paper.py(re-downloads from the recorded URL).download_paper.pyis absent only in manual drop-in mode — you supply the paper by hand, so there is nothing to fetch. - Non-destructive by contract:
cloneandconvertnever overwrite existing files —cloneprepends;convertonly injects what is missing.replicatein arXiv mode never errors on a name collision (silent-2/-3suffix); in folder mode it injects only what is missing so a pre-dropped paper is never clobbered. - Template wording may evolve (improvements to the workflow contract are not breaking); the set of guaranteed files and the subcommand contracts above are what 1.x holds stable.
- Zero runtime dependencies remains a hard guarantee for the 1.x line.
License
MIT
Metadata
Release files for cleanvibe 1.18.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cleanvibe-1.18.0.tar.gz | 120.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cleanvibe-1.18.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 216.6 kB
Release files / cleanvibe-1.18.0.tar.gz
| Download URL | cleanvibe-1.18.0.tar.gz |
|---|---|
| Size | 120.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12403a281cfda6631dc2a6d2070ef9c78e5b83a7511a513cba6f7af934a6ce08
|
|
BLAKE2b-256 checksum How to use checksums |
6a78aca6ad605d7394635b18b93d25575212b38ef142bb1f2d100c1f5028f36d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency logRelease files / cleanvibe-1.18.0-py3-none-any.whl
| Download URL | cleanvibe-1.18.0-py3-none-any.whl |
|---|---|
| Size | 96.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f158fc9a856b66468fdc016ddc6f66d98f867a1570b84e6ac30f171b79b8331e
|
|
BLAKE2b-256 checksum How to use checksums |
c185e16865630a5e85b47a1be6a5bcef3a94e0b2a9a23a3995fd61c4087be753
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency log