repocraft
Deterministic Python generation from validated input.
repocraft has four paths:
- a short request such as
triangleselects a built-in recipe and writes one.pyfile plus oneunittestfile; - a small YAML spec becomes a complete Python project with packaging metadata,
a
src/layout, tests, lint and type-check configuration, CI, CodeQL, Dependabot, and a JUnit gate that rejects skipped tests; - an optional
askpath where a model only proposes a strict{recipe, parameters}intent, which repocraft validates before writing; - an optional
craftpath where a model writes the snippet and repocraft verifies it through deterministic gates before anything is written.
The first two paths are deterministic: the same input and the same repocraft
version always produce byte-identical output. GitHub repository creation is a
roadmap item.
Status
Version 0.4.0 adds the craft path: a model writes a free-form snippet and
repocraft verifies it — python syntax, that the generated tests import the
module, ruff when it is installed, and the generated tests themselves — before
the confirmation prompt and the no-overwrite rules apply.
Version 0.3.0 adds the optional AI intent layer and three new recipes:
repocraft asksends a free-form request to an OpenAI-compatible endpoint and turns the reply into a strict{recipe, parameters}intent;- the model never writes code or files; the intent is validated against the
recipe catalog with the same rules as
make; - configuration through
OPENAI_API_KEY,OPENAI_BASE_URL,REPOCRAFT_MODEL, or--endpointand--model; - new recipes:
fizzbuzz,pascal, andpassword.
Version 0.2.0 added the deterministic snippet mode:
- strict JSON Schema validation for specs and recipes, plus duplicate-key rejection in YAML;
- four built-in recipes:
fibonacci,factorial,prime_sieve, andtriangle; - deterministic English matching with case, accent, and suffix normalization;
- confirmation before writing,
--dry-run,--param, and refusal to overwrite; - golden snapshots and smoke tests for every generated snippet.
The project mode from 0.1.0 is unchanged: library and CLI scaffolds with golden-tested templates, CI, CodeQL, Dependabot, and coverage/skip gates.
The deterministic commands (validate, render, recipes, make) have no
model or network dependency; only ask uses the network.
Requirements
- Python 3.10 or newer.
Installation
The package is not published on PyPI yet. From this checkout:
python -m pip install .
Snippet mode
List the closed recipe catalog:
repocraft recipes
Ask for a snippet. The command shows the selected recipe, its parameters, and the target files, then asks for confirmation:
repocraft make "triangle" # triangle.py and test_triangle.py
repocraft make "factorial"
repocraft make "prime numbers"
Preview without writing anything:
repocraft make "fibonacci" --dry-run
Override a declared integer parameter. Free-text numbers are not interpreted:
repocraft make "fibonacci" --param count=20 --yes
Rules:
- only the built-in catalog is matched; unknown or ambiguous requests stop without writing anything;
- requests containing standalone digits are refused; use
--paraminstead; - parameters are bounded integers and are validated before rendering;
- existing target files are never overwritten;
--yesskips the confirmation prompt;- generated tests use the standard library:
python test_<recipe>.py.
The matcher normalizes case and accents and matches word prefixes, so
Triangles and draw a triangle both select the triangle recipe. It never
calls a model.
Ask mode (optional)
ask is the only command that calls a model. It turns a free-form request
into a validated intent and then reuses the snippet path end to end:
export OPENAI_API_KEY=sk-... # required
repocraft ask "a tall triangle" # proposes triangle with its default height
repocraft ask "first 20 fibonacci numbers" --yes
Rules:
- the model replies with JSON only: a recipe id and integer parameters, or
nullwith a reason when nothing fits; - repocraft validates the reply against the catalog; unknown recipes, invalid parameters, and malformed replies are rejected;
- the confirmation prompt,
--dry-run,--param, and the refusal to overwrite behave exactly as inmake; --endpointselects any OpenAI-compatible base URL;--modelorREPOCRAFT_MODELselects the model;- without
OPENAI_API_KEYin the environment the command refuses to run.
Craft mode (optional)
craft is the path where the model writes the code and repocraft stays in
control of quality. The model proposes a module, its source, and a unittest
file; repocraft then runs deterministic gates on the proposal before anything
is written:
export OPENAI_API_KEY=sk-... # required
repocraft craft "binary search" # proposes, verifies, asks, writes
Gates, in order:
- python syntax of the code and the test;
- the test must import the proposed module by name;
- ruff on the generated files, when ruff is installed;
- the generated unittest file must run and pass at least one test;
- the confirmation prompt shows the code and every check that passed.
Rules:
--endpoint,--model,REPOCRAFT_MODEL, andOPENAI_BASE_URLconfigure the endpoint exactly as inask;- the module name must be a lowercase snake_case identifier;
- only the standard library is allowed in the prompt, but the gates verify what actually runs;
--dry-runlists the planned files after verification; the no-overwrite rule applies;- without
OPENAI_API_KEYin the environment the command refuses to run.
Unlike the deterministic paths, the written content depends on the model; repocraft guarantees only that every gate passed and that you saw the code before it was written.
Project mode
Write a spec:
schema_version: 1
project:
name: example-cli
package: example_cli
description: An example command-line application.
type: cli
license: Apache-2.0
author: Your Name
version: 0.1.0
python: ">=3.10"
cli:
command: example-cli
repository:
owner: your-user
name: example-cli
private: true
Validate it:
repocraft validate spec.yaml
Plan the output without writing anything:
repocraft render spec.yaml example-cli --dry-run
Render it:
repocraft render spec.yaml example-cli
render refuses an output directory that already contains files. It never
overwrites or merges into existing work.
Spec fields
| Field | Required | Meaning |
|---|---|---|
schema_version |
yes | Must be 1. |
project.name |
yes | Distribution name, lowercase letters, digits, and hyphens. |
project.package |
yes | Import package name, lowercase letters, digits, and underscores. |
project.description |
yes | One-line description, 10 to 200 characters. |
project.type |
yes | library or cli. |
project.license |
yes | MIT or Apache-2.0. |
project.author |
yes | Copyright holder and package author. |
project.version |
no | Semantic version, default 0.1.0. |
project.python |
no | >=3.10 through >=3.14, default >=3.10. |
project.cli.command |
for cli |
Console script name. Forbidden for library. |
project.repository |
no | owner, name, and private (default true). |
Determinism contract
For fixed input and a fixed repocraft version:
- output paths and file contents are byte-identical;
- recipe output depends only on the recipe version and validated parameters;
- recipe matching and error ordering are deterministic;
- entries are rendered in sorted order;
- files use LF line endings and a trailing newline;
- no timestamps, random identifiers, model output, or environment values are embedded;
- the generated MIT copyright line carries the author but no year.
The golden tests in tests/golden/ enforce the contract file by file,
including the built-in recipe snapshots.
The ask command adds a model, but the contract still holds: the model only
proposes an intent, and a confirmed intent renders exactly like make. The
craft command goes further — the model writes the code — so its output is
not part of the contract; its gates, the confirmation prompt, and the
no-overwrite rule are.
Development
python -m venv .venv
. .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -e ".[dev]"
python -m ruff check .
python -m mypy
python -m pytest --cov=repocraft --cov-branch --cov-fail-under=100
The smoke tests install the rendered fixtures into temporary target directories
with --no-deps --no-build-isolation, then run the generated projects' own
quality gates. Hatchling is a dev dependency for exactly that reason.
CI runs the suite on Python 3.10 through 3.14 and rejects skipped tests through
scripts/check_junit.py.
Roadmap
- Interactive wizard for people who do not want to write project YAML.
- Free-form natural language to a full project spec through an OpenAI-compatible endpoint, with a confirmation step before any file is written.
- GitHub repository creation and push, private by default.
- MCP server exposing the same validated core.
License
MIT. See LICENSE.
Metadata
Release files for repocraft 0.4.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 | Provenance | |
|---|---|---|---|---|
| repocraft-0.4.0.tar.gz | 53.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| repocraft-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 99.2 kB
Release files / repocraft-0.4.0.tar.gz
| Download URL | repocraft-0.4.0.tar.gz |
|---|---|
| Size | 53.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d221067ddb5ae85cb00ad36f31fd64c8acee4647313bf1bbb11f850b7378f5ae
|
|
BLAKE2b-256 checksum How to use checksums |
f6d660ae0602b2d5eb92b09d238ac2cd1f5c7fc1af8ff935056b173c9add9a6f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / repocraft-0.4.0-py3-none-any.whl
| Download URL | repocraft-0.4.0-py3-none-any.whl |
|---|---|
| Size | 45.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a0edf3252069908684515d8105058f60abe850eac5af7c6394cd9f7fbb2f2021
|
|
BLAKE2b-256 checksum How to use checksums |
3f0c83e024947e24a4c81c718106f817a1aa4003825bb9a7c31c53148db1e8be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Security for repocraft 0.4.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.