Generate runnable AI agent projects from markdown specs in the agent-deployments repo.
Project description
agent-scaffold
agent-scaffold generates runnable AI agent projects from markdown specs. It ships with bundled knowledge from agent-deployments — pick a recipe, target language, and framework, and the CLI assembles the relevant docs, asks Claude to emit a complete project, validates the response, and writes the files atomically into your destination of choice.
The three-repo ecosystem
This repo is one of three that work together as a single pipeline:
agent-blueprints → agent-deployments → agent-scaffold
(architecture) (specs) (generator)
"how to think" "what to build" "build it for me"
patterns + tradeoffs 9 production-shaped reads spec, asks LLM,
framework-agnostic markdown blueprints writes runnable project
- agent-blueprints — framework-agnostic patterns, tradeoffs, and design guidance. Start here if you want to design before you build.
- agent-deployments — opinionated, production-shaped markdown specs for nine concrete agents (Python + TypeScript tracks).
- agent-scaffold (this repo) — a CLI that consumes a deployment spec, asks Claude to emit a complete project, and writes the files atomically to disk.
Install
The package is published on PyPI as agent-scaffold-cli (the CLI command itself is still agent-scaffold).
pipx install agent-scaffold-cli
# or
uv tool install agent-scaffold-cli
# or, for one-off use:
uvx --from agent-scaffold-cli agent-scaffold --help
Local development
git clone https://github.com/jagguvarma15/agent-scaffold
cd agent-scaffold
uv sync
Quickstart
export ANTHROPIC_API_KEY=sk-ant-...
agent-scaffold scaffold # interactive shell — recommended
# or, one-shot:
agent-scaffold new
Interactive shell
agent-scaffold scaffold opens a persistent REPL. Make selections with
slash commands, refine the plan with free text, see the cost estimate,
generate when you're ready, then start the next project — all without
re-launching the CLI.
scaffold › /recipe restaurant-rebooking
scaffold › /language python
scaffold › /framework langgraph
scaffold › /name demo
scaffold › /plan
[renders the generation plan with token + cost estimate]
scaffold › swap to sonnet and skip the smoke test
✓ applied refinement
Δ model: claude-opus-4-7 → claude-sonnet-4-6
Δ steps: -smoke_test
scaffold › /go
[runs the generation pipeline]
scaffold › /exit
Type /help inside the shell for the full command list. Free-text
input ("use Sonnet, add Redis") is interpreted by a tiny Haiku call
(~$0.002) into a typed patch over the plan.
By default, the CLI auto-fetches the latest main commit from
agent-deployments and
agent-blueprints,
caches each by commit SHA under ~/.cache/agent-scaffold/, and rewrites
blueprint URLs in deployments docs so the LLM actually reads the
canonical pattern content. Falls back to the bundled deployments copy
when offline; blueprint links are silently skipped if blueprints can't
be fetched.
To use a local checkout instead (typical for repo development):
export AGENT_SCAFFOLD_DEPLOYMENTS_PATH=/path/to/agent-deployments
export AGENT_SCAFFOLD_BLUEPRINTS_PATH=/path/to/agent-blueprints
agent-scaffold new
# or per-invocation:
agent-scaffold new --deployments-path . --blueprints-path ../agent-blueprints
The interactive new flow walks you through:
- A recipe from
docs/recipes/*.md. - A target language (Python or TypeScript).
- A framework (e.g.
pydantic_ai,langgraph,vercel_ai_sdk, ornone). - A project name and destination directory.
You'll see the resolved source labels, a context summary, a generation step, a static validation pass, and a "next steps" footer with the smoke-check command.
Configuration
| Source | Variable / key | Purpose |
|---|---|---|
| Env | ANTHROPIC_API_KEY |
Required. The Anthropic API key used by the generator. |
| Env | AGENT_SCAFFOLD_DEPLOYMENTS_PATH |
Local-checkout override for agent-deployments (defaults to auto-fetch from GitHub). |
| Env | AGENT_SCAFFOLD_BLUEPRINTS_PATH |
Local-checkout override for agent-blueprints (defaults to auto-fetch from GitHub). |
| Env | AGENT_SCAFFOLD_DEPLOYMENTS_SOURCE |
auto (default, GitHub fetch + bundled fallback) or bundled (skip network). |
| Env | AGENT_SCAFFOLD_BLUEPRINTS_SOURCE |
auto (default) or skip (no fetch; drop blueprint URLs from context). |
| Env | AGENT_SCAFFOLD_MODEL |
Override the model (default claude-opus-4-7). |
| Env | AGENT_SCAFFOLD_THINKING_BUDGET |
Extended-thinking token budget. Omit to disable. |
| Env | AGENT_SCAFFOLD_EFFORT |
Default effort preset (low / medium / high). |
| Env | AGENT_SCAFFOLD_CACHE_DIR |
Override the cache root (default ~/.cache/agent-scaffold). |
| Env | AGENT_SCAFFOLD_CONFIG_PATH |
Override the TOML fallback location. |
| TOML | ~/.config/agent-scaffold/config.toml |
Fallback for deployments_path, model, and thinking_budget. |
Run uv run agent-scaffold config to print the resolved configuration (the API key is masked).
A typical config file:
deployments_path = "/Users/me/code/agent-deployments"
model = "claude-opus-4-7"
Generation effort
--effort picks a preset bundle of model + token budget + extended-thinking budget + prompt strictness:
| Effort | Model | max_tokens | Thinking | Strict prompt |
|---|---|---|---|---|
| low | Haiku 4.5 | 16,000 | off | no |
| medium | Sonnet 4.6 | 32,000 | 8,000 | no |
| high | Opus 4.7 | 64,000 | 16,000 | yes |
Explicit --model, --max-tokens, --thinking, and --strict override preset values. Precedence: preset → explicit flag → env / TOML.
Strict mode (--strict or --effort high) loads system_strict.md, which instructs the LLM to emit Docker / docker-compose / GitHub Actions / structured-logging / three-tier tests when the spec references those components.
Where docs come from
The CLI resolves two sources before assembling the LLM context:
- agent-deployments — recipes + cross-cutting / framework / pattern / stack docs.
- agent-blueprints — canonical pattern overviews referenced by deployments docs.
Resolution order for each repo (highest priority first):
--deployments-path/--blueprints-pathflag onagent-scaffold new.AGENT_SCAFFOLD_DEPLOYMENTS_PATH/AGENT_SCAFFOLD_BLUEPRINTS_PATHenv var.deployments_path/blueprints_pathin~/.config/agent-scaffold/config.toml.- Auto-fetch from GitHub (default) — pulls the latest
maincommit, caches by SHA under~/.cache/agent-scaffold/{deployments,blueprints}/<sha>/. Uses ETag-conditional GET so unchanged refs don't consume rate-limit quota. - Offline fallback — deployments uses the bundled copy (frozen at install time); blueprints is skipped with a warning (blueprint URLs in deployments docs drop out of context).
Override the auto-fetch behavior per-invocation:
# Skip network entirely; use bundled deployments + drop blueprint URLs.
agent-scaffold new --deployments-source bundled --blueprints-source skip
# Use my local fork of deployments, auto-fetch blueprints.
agent-scaffold new --deployments-path ~/code/my-deployments
Recipe frontmatter
Recipes are markdown files with optional YAML frontmatter:
---
status: blueprint
languages: [python, typescript]
required_files:
- Dockerfile
- docker-compose.yml
- .github/workflows/ci.yml
---
status— free-form label shown in the recipe picker (e.g.validated,blueprint).languages— supported target languages; intersected with the available language hints.required_files— additional paths that the generated project MUST contain. These are enforced by the contract validator on top of the built-in four (manifest, entry point,README.md,.env.example). Paths follow the same safety rules as generated files (relative, no.., no leading/); unsafe entries are warned about and dropped during discovery.
recipe_dependencies (optional)
Per-language extra dependencies the recipe needs. Merged into pinned_dependencies from the language hints before being shown to the LLM. Use when a recipe references infrastructure clients (Redis, Postgres drivers), observability (structlog, langfuse), or framework adjuncts not in the default language profile.
---
recipe_dependencies:
python:
redis: ">=5.0.0"
structlog: ">=24.1.0"
typescript:
ioredis: "^5.4.0"
pino: "^9.0.0"
---
Recipe-declared versions win over language-default versions on conflict. Malformed entries (non-mapping shape) are warned about and ignored during discovery.
external_services (optional)
The infrastructure the recipe depends on. agent-scaffold doctor --recipe <slug> probes each entry; agent-scaffold new --plan renders a per-service ✓/✗ readiness row before the LLM call.
---
external_services:
- id: anthropic
env_vars: [ANTHROPIC_API_KEY]
probe: anthropic_list_models
explain: anthropic
- id: redis
required: true
env_vars: [REDIS_URL]
default_local: redis://localhost:6379
docker_service: redis
probe: redis_ping
explain: redis
- id: langfuse
required: false
env_vars: [LANGFUSE_HOST]
probe: langfuse_health
explain: langfuse
---
Per-entry fields:
| Field | Default | Meaning |
|---|---|---|
id |
— | Short stable slug (anthropic, redis, postgres, ...). Required. |
required |
true |
Whether the service must be present for the recipe to work. |
env_vars |
[] |
Env vars that may carry the connection URL / credentials, in priority order. |
default_local |
none | Used when no env_vars entry is set. |
docker_service |
none | Name of the matching service in a bundled docker-compose.yml (consumed by the upcoming up orchestrator). |
probe |
none | Registered probe name. See the table below. |
migrations |
none | Migration tool (alembic, prisma, ...). |
explain |
none | Slug under docs/getting-started/<slug>.md for --explain. |
mock_available |
false |
A fallback mock adapter exists if the real service is unreachable. |
Bundled probes:
probe value |
What it does | Address from |
|---|---|---|
anthropic_list_models |
models.list(limit=1) via the resolved key |
auth resolution (env → keyring → file) |
redis_ping |
Raw-socket Redis PING/PONG |
first env var, else default_local |
postgres_select_one |
psycopg.connect(...).cursor().execute("SELECT 1") (TCP-only fallback if psycopg not installed) |
first env var, else default_local |
langfuse_health |
GET {host}/api/public/health |
first env var, else default_local |
kafka_metadata |
TCP connect + kafka-python metadata (TCP-only fallback if not installed) |
first env var, else default_local |
Unknown probe names log a warning and produce a SKIP at runtime instead of crashing the audit.
Adding a new target language
Drop a YAML file into src/agent_scaffold/languages/ modeled after python.yaml or typescript.yaml. Required keys:
language,package_manager,project_layout,entry_point,manifestrequired_tools(formatter / type_checker / test)pinned_dependencies,framework_dependenciesforbidden,smoke_check
The CLI reads them on demand; no code changes needed unless you also want a language-specific static-validation tier (see src/agent_scaffold/validator.py).
Troubleshooting
Contract parse failures
If Claude returns malformed JSON, agent-scaffold:
- Saves the raw response to
~/.cache/agent-scaffold/failures/<timestamp>.json. - Prints a warning and asks Claude to repair the response.
- If the repair still fails, saves that raw response too and aborts with file pointers.
You can re-run agent-scaffold new with AGENT_SCAFFOLD_CACHE_DIR set to inspect failures elsewhere.
--write-mode choices
| Mode | Behavior |
|---|---|
abort (default) |
Refuse to write into a non-empty destination. |
skip |
Keep existing files, write only new ones. |
diff |
Show a unified diff per file and prompt before overwriting. |
overwrite |
Replace everything. |
All writes stage to a sibling temp directory and os.replace into place, so a failure mid-generation leaves the destination untouched.
Re-running validation
agent-scaffold validate /path/to/generated --tier static|build|smoke reruns one of the post-generation tiers without re-invoking the LLM.
CLI commands
| Command | Purpose |
|---|---|
agent-scaffold new |
Interactive project generator. |
agent-scaffold up [project_dir] |
Provision a generated project: install deps, start docker services, prompt for missing API keys, run alembic migrations, seed dev data, run smoke tests, and (opt-in) commit/push + open $EDITOR. --plan to preview, --yes for CI, --resume / --retry / --skip / --force / --only for re-runs, --yes --confirm-commit-push to fully automate the opt-in commit step. |
agent-scaffold update [project_dir] |
Re-run the recipe and 3-way-merge template changes against your edits. Copier-style: snapshots the generated tree on new, uses it as the merge base, writes <<<<<<< user / ======= / >>>>>>> template markers on conflicts. --dry-run previews the plan, --continue finalises after manual resolution. |
agent-scaffold regenerate <project> <file> |
Re-prompt the model for a single file in an existing project. |
agent-scaffold validate <project> --tier ... |
Re-run a post-generation validation tier. |
agent-scaffold doctor |
Read-only audit of local tools (python, uv, docker, ruff). --recipe <slug> adds Authentication + per-external_services rows. --no-probes skips network probes. --timeout N (1–30s) caps each probe. --json for machine-readable output. --explain <topic> opens the matching getting-started doc. |
agent-scaffold auth login |
Capture an Anthropic key (browser or paste), validate it via models.list(), and store it. |
agent-scaffold auth status |
Show the active credential backend, stored credentials (masked), and the resolution order. --json for machine-readable output. |
agent-scaffold auth logout |
Remove a stored credential from every backend it lives in (--all to wipe everything). |
agent-scaffold auth setup-token <name> |
Store a long-lived CI token in the mode-0600 file backend (--stdin for piped input). |
agent-scaffold secrets list |
Inventory every credential the CLI knows about, masked. --json for machine output. |
agent-scaffold secrets purge |
Survey + wipe every stored credential (keyring + file + ./.env.local). --yes for CI; --keep-env-local to preserve project secrets. |
agent-scaffold config |
Print the resolved configuration. |
Step orchestrator
Provisioning verbs (up, update) plug into a state-tracked step framework: each step has a detect() (read-only) and an apply() (idempotent), with progress recorded in <project>/.scaffold/state.json. From that one design, the flag set --only / --skip / --force / --retry / --resume and --plan-before-build all fall out naturally.
See docs/design/orchestrator.md for the contract, state-file shape, decision table, and the anti-patterns to avoid when authoring new steps.
Credentials
agent-scaffold resolves the Anthropic API key in this order:
ANTHROPIC_API_KEYenvironment variablepython-keyring(macOS Keychain / Windows Credential Manager / Linux Secret Service / KDE Wallet)- INI file at
$XDG_CONFIG_HOME/agent-scaffold/credentials(mode0600)
The plaintext keyring backend is refused: if keyring.get_keyring() reports PlaintextKeyring (or any non-OS-native backend), auth login falls back to the mode-0600 file backend with a warning. Pass --use-file or --use-env to override the default.
agent-scaffold auth login # browser flow
agent-scaffold auth login --no-browser # paste flow (headless / SSH)
agent-scaffold auth status # show what's stored where
agent-scaffold auth logout --all # nuke every stored credential
echo "$TOKEN" | agent-scaffold auth setup-token ci-prod --stdin
# Cross-backend revocation (keyring + file + ./.env.local in one go)
agent-scaffold secrets list
agent-scaffold secrets purge --yes
Security model
The CLI follows a nine-point hardening checklist for secret handling:
no secrets in argv, getpass instead of input, SecretStr typing,
shell=False, mode-0600 credential files, plaintext-keyring refusal,
output redaction, enforced .gitignore, and first-class revocation via
secrets purge. Each rule is locked in by an audit test under
tests/security/ so regressions block CI.
See docs/design/security.md for the full
rationale and per-rule references.
License
MIT (see LICENSE).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_scaffold_cli-0.2.255.tar.gz.
File metadata
- Download URL: agent_scaffold_cli-0.2.255.tar.gz
- Upload date:
- Size: 539.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebee4f4c7714d79d816ebfa10a6591538900b4327885cc0c0b62c802f9a4bffe
|
|
| MD5 |
a75c91614072eaf5ffec674b4a300b6c
|
|
| BLAKE2b-256 |
94e67b6f2abcc3f616f7152e11910a32c3992a4de55c90399bdd9b0aca2aa515
|
Provenance
The following attestation bundles were made for agent_scaffold_cli-0.2.255.tar.gz:
Publisher:
publish.yml on jagguvarma15/agent-scaffold
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_scaffold_cli-0.2.255.tar.gz -
Subject digest:
ebee4f4c7714d79d816ebfa10a6591538900b4327885cc0c0b62c802f9a4bffe - Sigstore transparency entry: 1660405045
- Sigstore integration time:
-
Permalink:
jagguvarma15/agent-scaffold@2f6a57e51511934b8cd8d61354cdf489e90cb05f -
Branch / Tag:
refs/tags/v0.2.255 - Owner: https://github.com/jagguvarma15
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f6a57e51511934b8cd8d61354cdf489e90cb05f -
Trigger Event:
release
-
Statement type:
File details
Details for the file agent_scaffold_cli-0.2.255-py3-none-any.whl.
File metadata
- Download URL: agent_scaffold_cli-0.2.255-py3-none-any.whl
- Upload date:
- Size: 491.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b73dc9e9639cef6ac5785804b37ca76158038d82a106c80b1bb1bf7608433a7
|
|
| MD5 |
ac8f97bfbaae1635b0b7bfed848e6d1b
|
|
| BLAKE2b-256 |
40ba5499be2e978dc17341138926764a49a88868fa09dc5adfa6ad2672a08482
|
Provenance
The following attestation bundles were made for agent_scaffold_cli-0.2.255-py3-none-any.whl:
Publisher:
publish.yml on jagguvarma15/agent-scaffold
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_scaffold_cli-0.2.255-py3-none-any.whl -
Subject digest:
7b73dc9e9639cef6ac5785804b37ca76158038d82a106c80b1bb1bf7608433a7 - Sigstore transparency entry: 1660405372
- Sigstore integration time:
-
Permalink:
jagguvarma15/agent-scaffold@2f6a57e51511934b8cd8d61354cdf489e90cb05f -
Branch / Tag:
refs/tags/v0.2.255 - Owner: https://github.com/jagguvarma15
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f6a57e51511934b8cd8d61354cdf489e90cb05f -
Trigger Event:
release
-
Statement type: