Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 60 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ It's repetitive. It's inconsistent. And you haven't written a single line of *re
| **Arrow-key menus** | Every prompt in `spawn create` is arrow-key/spacebar driven, not typed numbers |
| **GitHub publishing** | Connects your project to an existing GitHub repo and pushes the initial commit |
| **spawn doctor** | Scores your project's health out of 100, with per-category breakdowns and a prioritized next step |
| **spawn doctor --fix** | Fixes missing files and config automatically — never overwrites, never installs packages |

---

Expand Down Expand Up @@ -132,7 +133,7 @@ Running `spawn` with no arguments shows the banner, the installed version, and t

```
SPAWN — scaffold your next project
v1.0.6
v1.0.8

Commands
create Scaffold a new project
Expand Down Expand Up @@ -179,7 +180,15 @@ Use the arrow keys to move, Enter to select — the same pattern every prompt in

**Step 3 — Additional prompts** *(template-dependent — framework, provider, project type, and/or extras, depending on what you picked. See [Project Templates](#project-templates) below for each one's exact flow.)*

**Step 4 — Git**
**Step 4 — License**

```
? Choose a license (Use arrow keys)
» MIT
None
```

**Step 5 — Git**

```
Initialize Git? [Y/n]: Y
Expand Down Expand Up @@ -242,9 +251,11 @@ my-api/
● pytest
○ docker
○ github-actions
○ pre-commit
○ mypy
```

**Available extras:** `ruff` `pytest` `docker` `github-actions`
**Available extras:** `ruff` `pytest` `docker` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -295,9 +306,11 @@ my-cli/
● ruff
● pytest
○ github-actions
○ pre-commit
○ mypy
```

**Available extras:** `ruff` `pytest` `github-actions`
**Available extras:** `ruff` `pytest` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -334,9 +347,11 @@ my-automation/
● ruff
● pytest
○ github-actions
○ pre-commit
○ mypy
```

**Available extras:** `ruff` `pytest` `github-actions`
**Available extras:** `ruff` `pytest` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -386,9 +401,11 @@ my-chatbot/
● pytest
○ rich
○ github-actions
○ pre-commit
○ mypy
```

**Available extras:** `ruff` `pytest` `rich` `github-actions`
**Available extras:** `ruff` `pytest` `rich` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -436,11 +453,13 @@ my-agent/
● ruff
● pytest
○ github-actions
○ pre-commit
○ mypy
```

> If you pick `openai-agents`, only `openai` and `openrouter` appear as provider choices — the list is filtered per framework.

**Available extras:** `ruff` `pytest` `github-actions`
**Available extras:** `ruff` `pytest` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -481,11 +500,13 @@ my-rag/
● ruff
● pytest
○ github-actions
○ pre-commit
○ mypy
```

RAG System uses a fixed stack — **LlamaIndex + ChromaDB + OpenAI** — so there's no framework or provider prompt, unlike Chatbot and Agent. On first run, it automatically ingests documents from `data/` into a local ChromaDB index, then lets you ask questions against them. Requires an `OPENAI_API_KEY` (used for both the LLM and embeddings).

**Available extras:** `ruff` `pytest` `github-actions`
**Available extras:** `ruff` `pytest` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -529,9 +550,11 @@ my-data-project/
● ruff
● pytest
○ github-actions
○ pre-commit
○ mypy
```

**Available extras:** `ruff` `pytest` `github-actions`
**Available extras:** `ruff` `pytest` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -575,11 +598,13 @@ my-mcp-server/
● ruff
● pytest
○ github-actions
○ pre-commit
○ mypy
```

MCP Server uses a fixed stack — the official `mcp` Python SDK's `FastMCP` — so there's no framework or provider prompt, the same as RAG System.

**Available extras:** `ruff` `pytest` `github-actions`
**Available extras:** `ruff` `pytest` `github-actions` `pre-commit` `mypy`

**Run it:**

Expand Down Expand Up @@ -630,6 +655,7 @@ Dependencies (comma separated, optional): fastapi, uvicorn
● Pytest
○ Pre-commit
○ Dockerfile
○ Mypy

Additional ignore patterns (optional, comma separated): data/, *.csv

Expand All @@ -643,7 +669,7 @@ Proceed? [Y/n]: Y

**The Dependencies prompt** (shown only when uv is enabled) installs packages immediately via `uv add`.

**The Optional Setup menu** installs dev tools via `uv add --dev` and generates their config files: `ruff.toml`, `tests/__init__.py`, `.pre-commit-config.yaml`, and/or `Dockerfile`.
**The Optional Setup menu** installs dev tools via `uv add --dev` and generates their config files: `ruff.toml`, `tests/__init__.py`, `.pre-commit-config.yaml`, `Dockerfile`, and/or `[tool.mypy]` in `pyproject.toml`.

### Non-Interactive Mode

Expand All @@ -652,7 +678,7 @@ Skip all prompts by passing flags directly or pointing to a JSON config file.
**Using flags:**

```bash
spawn create --name my-api --template backend-api --framework fastapi --extras ruff,pytest --git
spawn create --name my-api --template backend-api --framework fastapi --extras ruff,pytest --license mit --git
```

**Using a config file:**
Expand All @@ -663,6 +689,7 @@ spawn create --name my-api --template backend-api --framework fastapi --extras r
"template": "backend-api",
"framework": "fastapi",
"extras": ["ruff", "pytest"],
"license": "mit",
"git": true,
"uv": true
}
Expand Down Expand Up @@ -730,11 +757,30 @@ spawn doctor ./path/to/project

Checks span six categories — Documentation, Version Control, Configuration, Testing, Automation, and Code Quality (Ruff, type checking, pre-commit) — all filesystem-based, nothing is executed or sent over the network.

#### Automatic Remediation with `--fix`

`spawn doctor --fix` creates missing files and config automatically. It **never overwrites** pre-existing files and **never installs packages** directly (instead printing `uv add` commands for optional tools).

```bash
# Automatically create missing files and config
spawn doctor --fix
spawn doctor ./path/to/project --fix

# Preview what would be created without touching disk
spawn doctor --fix --dry-run

# Run non-interactively without the confirmation prompt
spawn doctor --fix --yes

# Also add an MIT license if missing
spawn doctor --fix --license mit
```

### `spawn version`

```bash
spawn version
# → Spawn v1.0.7
# → Spawn v1.0.8
```

### Publish to GitHub
Expand Down Expand Up @@ -768,6 +814,7 @@ All tests should pass. If they don't, please [open an issue](https://github.com/

| Version | Highlight |
|---|---|
| **v1.0.8** | `spawn doctor --fix` (`--dry-run`, `--yes`, `--license`), `--license` flag and prompt on `create`, `CHANGELOG.md` generated for every project, `pre-commit` and `mypy` extras across all templates, Custom Structure Mypy option |
| **v1.0.7** | Fixed UTF-8 console crash on Windows when stdout is redirected/piped, added Windows reserved device name validation (`CON`, `PRN`, `AUX`, `NUL`, `COM1`–`9`, `LPT1`–`9`), clarified Python 3.12 requirement |
| **v1.0.6** | Removed duplicate banner from `spawn create`; `spawn` alone now shows the banner and command overview |
| **v1.0.5** | Published to PyPI as `spawnio`; arrow-key selection menus, no-args banner, consistent Ctrl+C handling |
Expand Down
27 changes: 16 additions & 11 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,27 @@ Entry point: `spawn.cli.app:main` (defined in `pyproject.toml` as `[project.scri

```
src/spawn/
├── __init__.py # __version__ via importlib.metadata, fallback "1.0.6"
├── __init__.py # __version__ via importlib.metadata, fallback "1.0.8"
├── cli/
│ ├── app.py # Typer app: create, version, doctor commands
│ ├── noninteractive.py # Build config from CLI flags or JSON config file
│ └── prompts.py # Interactive prompts; derives menu from registry
├── core/
│ ├── exceptions.py # SpawnError — base exception
│ ├── models.py # ProjectConfig dataclass (name, template, use_git, framework, extras)
│ ├── models.py # ProjectConfig dataclass (name, template, use_git, framework, extras, license)
│ └── registry.py # TemplateMetadata, TEMPLATES dict, get_template(),
│ # instantiate_template(), get_metadata(), list_templates()
├── generators/
│ ├── custom_structure.py # Custom structure parser and generator
│ ├── project_files.py # Standalone file writers for LICENSE, README, configs, CI
│ └── project_generator.py # Orchestrates generation, dependency install, meta.json write
├── github/
│ ├── exceptions.py # GitHubPublishError
│ ├── publisher.py # GitHubPublisher — stages, commits, pushes
│ └── validators.py # GitHub URL validation
├── templates/
│ ├── base.py # BaseTemplate dataclass
│ ├── shared_content.py # README_CONTENT, GITIGNORE_CONTENT
│ ├── shared_content.py # README_CONTENT, GITIGNORE_CONTENT, CI, and tool configs
│ ├── backend_api/
│ │ ├── __init__.py # BackendAPITemplate (dispatches by framework)
│ │ └── content.py # All FastAPI/Flask/Django/Docker/CI content strings
Expand All @@ -60,8 +63,10 @@ src/spawn/
├── banner.py # show_banner() — ASCII wordmark with ice-fade colours
├── console.py # Shared Rich Console instance
├── doctor.py # ProjectHealthChecker, run_health_check()
├── doctor_fix.py # FixAction, FixResult, plan_fixes(), apply_fixes(), tool_hints()
├── git.py # initialize_git(), run_git_command(), add_all(), commit() etc.
├── success.py # show_success() — renders the success panel
├── theme.py # UI theme colors and styles
├── uv.py # initialize_uv(), install_packages()
└── validators.py # validate_project_name()
```
Expand Down Expand Up @@ -137,14 +142,14 @@ Each template lives in its own subdirectory with an `__init__.py` (class) and `c

| Key | Template class | Frameworks | Extras |
|---|---|---|---|
| `backend-api` | `BackendAPITemplate` | fastapi, flask, django | ruff, pytest, docker, github-actions |
| `cli` | `CLITemplate` | typer, click, argparse | ruff, pytest, github-actions |
| `automation` | `AutomationTemplate` | none | ruff, pytest, github-actions |
| `chatbot` | `ChatbotTemplate` | pydantic-ai, openai-sdk | ruff, pytest, github-actions |
| `agent` | `AgentTemplate` | pydantic-ai, openai-agents | ruff, pytest, github-actions |
| `rag` | `RAGTemplate` | none | ruff, pytest, github-actions |
| `data` | `DataProjectTemplate` | none | ruff, pytest, github-actions |
| `mcp` | `MCPServerTemplate` | none | ruff, pytest, github-actions |
| `backend-api` | `BackendAPITemplate` | fastapi, flask, django | ruff, pytest, docker, github-actions, pre-commit, mypy |
| `cli` | `CLITemplate` | typer, click, argparse | ruff, pytest, github-actions, pre-commit, mypy |
| `automation` | `AutomationTemplate` | none | ruff, pytest, github-actions, pre-commit, mypy |
| `chatbot` | `ChatbotTemplate` | pydantic-ai, openai-sdk, litellm | ruff, pytest, rich, github-actions, pre-commit, mypy |
| `agent` | `AgentTemplate` | pydantic-ai, openai-agents | ruff, pytest, github-actions, pre-commit, mypy |
| `rag` | `RAGTemplate` | none | ruff, pytest, github-actions, pre-commit, mypy |
| `data` | `DataProjectTemplate` | none | ruff, pytest, github-actions, pre-commit, mypy |
| `mcp` | `MCPServerTemplate` | none | ruff, pytest, github-actions, pre-commit, mypy |

`get_template(slug)` returns a default-constructed instance. `instantiate_template(config)` forwards `framework`, `extras`, and `cli_type` from `ProjectConfig` to templates whose constructors accept them, using signature introspection.

Expand Down
14 changes: 14 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
All notable changes to Spawn are documented here.
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## v1.0.8 — 2026

### Added

- **`spawn doctor --fix`** — `spawn doctor <dir> --fix [--dry-run] [--yes] [--license mit]` creates missing files and config, never overwrites, never installs packages.
- **`--license` selection on `spawn create`** — added `--license (mit/none)` CLI option and an interactive license prompt (MIT default).
- **`CHANGELOG.md` generation** — generated for every new project.
- **`pre-commit` and `mypy` extras** — available across all 8 project templates.
- **Custom Structure Mypy option** — added Mypy to optional setup choices in Custom Structure.

### Fixed

- **`--template` help text** — now lists all 8 supported template slugs including `mcp`.

## v1.0.7 — 2026

### Fixed
Expand Down
Loading
Loading