greenfield-monorepo
Stand up a new polyglot monorepo: interview → plan → confirm → scaffold a runnable skeleton with the
harness, lint, tests, pre-commit, a Docker Compose dev stack (+ seed), dev scripts, and root + per-app
AGENTS.md. Two stacks are pinned and curated; any other stack is researched live and scaffolded.
When to use
- "Start a new project / monorepo", "scaffold a greenfield repo", "iniciar um projeto do zero", "criar o
monorepo", "montar o esqueleto hello-world", "configurar lint/test/pre-commit/docker do projeto novo".
- The user hands over an
architecture.md (or describes the apps) and wants the repo built from it.
When NOT to use
- Adding a feature/module to an existing app → no skill; just build it.
- Writing one isolated artifact (a single Dockerfile, one CI file) → do it directly.
- Validating a product idea or designing system boundaries from scratch → chain to
product-brainstorming
/ tech-discovery first, then come back here to scaffold.
Interaction
Be a thinking partner, not a form. Ask one question at a time, each with a recommended default
(mark it "(Recomendado)") and a one-line why tied to their context. Calibrate to expertise — educate a
less-experienced user with a brief analogy and fewer options; go straight to trade-offs with an expert.
Never make them choose blind. Use AskUserQuestion for the discrete forks. Prefer the user's language
(Portuguese if they write in Portuguese).
Process
0. Detect ground truth (read before asking)
- Run
ls -la and git status in the target dir. Confirm it's empty / greenfield — if it already has
a project, STOP and confirm intent before writing anything (this skill assumes a fresh repo).
- Look for an existing
architecture.md / docs/architecture.md (or ask if they have one). If present,
read it and let it answer the interview — open references/architecture.md.
- Note what's installed (
docker compose version, node, uv, go, flutter) so the plan flags
missing toolchains instead of failing mid-build.
1. Interview (settle the shape)
Open references/architecture.md and resolve, one question at a time:
- Architecture — consume their
architecture.md, or ask the style (modular monolith / frontend+backend
/ microservices / event-driven). Recommend the simplest that fits. For non-trivial systems, offer to
chain to tech-discovery. Generate docs/architecture.md from the answers if none exists.
- Which apps — which of
frontend-app, backend-app, mobile, extra services/* exist.
- Stack per app — for each, pick the stack. Map to a reference:
- frontend React SPA on Cloudflare Workers →
references/stack-react-cloudflare.md (pinned)
- backend FastAPI async →
references/stack-fastapi-async.md (pinned)
- anything else (LangGraph, Go realtime, Flutter, Node, …) →
references/stack-research-recipe.md
(research live via context7/web; chain to a technical skill when one fits).
- Conventions — task runner (default go-task), pre-commit (default on), Conventional Commits hook
(default ON — pairs with the
commit-message skill), tests at pre-push (not per-commit),
.gitleaks.toml secret-scan (default ruleset + our rules), CI (default GitHub Actions).
2. Resolve stacks → references
For each chosen app, open its stack reference. For pinned stacks, re-verify the version pins (the
references say how). For generic stacks, run the A.1–A.11 method in stack-research-recipe.md and capture
the concrete versions before planning. Assign each app a distinct dev port (keep a port table).
3. Plan → confirm (one gate)
Present the plan and get a single confirmation before writing. Use this skeleton:
## Monorepo plan — <name>
Architecture: <style> (source: <their architecture.md | generated docs/architecture.md>)
Apps:
- apps/frontend-app — <stack> (port <p>)
- apps/backend-app — <stack> (port <p>)
- <service/app> — <stack> (port <p>)
Shared: packages/proto (<contract format>)
Root: Taskfile.yml · AGENTS.md (+CLAUDE.md @import) · .editorconfig/.gitignore/.gitattributes/.tool-versions
· .pre-commit-config.yaml · .github/workflows/ci.yml · infra/docker/compose.yaml · scripts/dev_*.sh
Dev loop: task up / down / restart / seed (compose + idempotent seed)
Missing toolchains to install: <... or none>
File tree:
<the tree you will create>
Flag anything you could not verify as "(a confirmar)". Only proceed on explicit confirmation.
4. Build (scaffold everything)
Lay down, in this order — keep each app a self-contained package:
- Root:
git init (if needed); the layout + root config from references/monorepo-and-agents.md
(.editorconfig, layered .gitignore, .gitattributes, .tool-versions, README.md, LICENSE,
CODEOWNERS, Taskfile.yml with only the includes for apps that exist).
- AGENTS.md: root from
assets/templates/AGENTS.root.md.tpl; CLAUDE.md = one @AGENTS.md line;
per-app from assets/templates/AGENTS.app.md.tpl. Each per-app file holds only its delta.
- Each app: hello-world + a passing test, lint/format config, Dockerfile,
pyproject.toml/package.json/
etc., and a per-app Taskfile.yml (install/lint/test/fmt/dev). Use the exact snippets in the stack
reference; don't invent versions.
- Dev loop:
infra/docker/compose.yaml, apps/*/scripts/{migrate,seed}.sh, and scripts/_common.sh
dev_{up,down,restart,seed,logs}.sh from references/docker-and-scripts.md; chmod +x scripts/*.sh.
- Harness:
.pre-commit-config.yaml + .gitleaks.toml (from assets/templates/gitleaks.toml.tpl) +
renovate.json5 (from assets/templates/renovate.json5.tpl) + .github/workflows/ci.yml from
references/precommit-and-ci.md — include only the language blocks/jobs for apps that exist; path-scope
every hook and CI filter. pre-commit stays fast (format/lint/secrets/msg); tests run at pre-push; the
message hook (Conventional Commits) is on by default. Supply chain born locked: commit the
lockfile, install from it (npm ci/--frozen-lockfile/uv sync --frozen), a 10-day cooldown
(minimumReleaseAge), and the osv-scanner CI job.
docs/architecture.md if you generated it (step 1).
5. Validate
- Run
python3 scripts/validate_scaffold.py <repo> (structure + AGENTS.md + port-collision + script-exec checks).
- Best-effort smoke per available toolchain:
task <app>:install then task <app>:lint/test (or the app's
native commands). Run pre-commit install && pre-commit run --all-files if pre-commit is available.
- Report honestly what passed, what was skipped (missing toolchain), and what failed with the output.
6. Report
Summarize: the tree created, the dev-loop commands (task up / dev_up.sh --seed), per-app run commands,
any toolchains the user must install, validation results, and the obvious next steps (first feature, fill
the seed, set compatibility_date/secrets). Do not commit unless the user asks.
Reference routing
| Open when you need to… |
Read |
| lay out the repo, AGENTS.md (root+per-app), task runner, root config |
references/monorepo-and-agents.md |
| scaffold the pinned frontend (Vite+React → Cloudflare Workers) |
references/stack-react-cloudflare.md |
| scaffold the pinned backend (FastAPI async) |
references/stack-fastapi-async.md |
| scaffold any other stack (research live; LangGraph/Go/Flutter seeds) |
references/stack-research-recipe.md |
| settle the architecture, or consume the user's architecture.md |
references/architecture.md |
| wire the Compose dev stack, seed, and dev_*.sh scripts |
references/docker-and-scripts.md |
| wire pre-commit + CI (path-filtered, polyglot) |
references/precommit-and-ci.md |
Cross-cutting gotchas
- Greenfield only — never overwrite an existing project without explicit confirmation.
- Pin real versions — re-verify before emitting; never write a floating "latest" into a manifest.
- One source of truth for agent context —
AGENTS.md canonical; CLAUDE.md is a thin @AGENTS.md.
- Secrets never in chat or
vars — use .dev.vars/wrangler secret/.env (gitignored), .env.example committed.
- Per-app everything — own manifest, own
.gitignore rules, own dev port (no collisions), own Taskfile.
- Idempotent seed, profile-gated — so it never wipes data or re-runs on every
up.
- Only scaffold what exists — don't emit Go/Flutter/mobile blocks for apps the user didn't choose.
1---2name: greenfield-monorepo3description: Bootstrap a brand-new polyglot monorepo from zero — interview for the apps and stacks, then scaffold a runnable hello-world per app with current best-practice harness, lint, tests, pre-commit, Docker Compose dev stack with seed data, dev scripts (up/down/restart/seed), root + per-app AGENTS.md, and CI. Use when the user wants to "start a new project/monorepo", "scaffold a greenfield repo", "set up frontend + backend + mobile", "iniciar um projeto do zero", "criar o monorepo", "montar o esqueleto", "configurar lint/test/pre-commit/docker do projeto novo", or hands over an architecture.md to build from. Ships two pinned stacks (Vite+React→Cloudflare Workers, FastAPI async) and a generic research-and-scaffold path (context7/web) for any other stack (LangGraph, Go realtime, Flutter, …). Do not use to add a feature to an existing app, to write a single Dockerfile/CI file in isolation, or to design product/architecture from scratch (chain to product-brainstorming / tech-discovery for that).4---56# greenfield-monorepo78Stand up a new polyglot monorepo: interview → plan → confirm → scaffold a runnable skeleton with the9harness, lint, tests, pre-commit, a Docker Compose dev stack (+ seed), dev scripts, and root + per-app10`AGENTS.md`. Two stacks are pinned and curated; any other stack is researched live and scaffolded.1112## When to use13- "Start a new project / monorepo", "scaffold a greenfield repo", "iniciar um projeto do zero", "criar o14 monorepo", "montar o esqueleto hello-world", "configurar lint/test/pre-commit/docker do projeto novo".15- The user hands over an `architecture.md` (or describes the apps) and wants the repo built from it.1617## When NOT to use18- Adding a feature/module to an **existing** app → no skill; just build it.19- Writing one isolated artifact (a single Dockerfile, one CI file) → do it directly.20- Validating a product idea or designing system boundaries from scratch → chain to `product-brainstorming`21 / `tech-discovery` first, then come back here to scaffold.2223## Interaction24Be a thinking partner, not a form. Ask **one question at a time**, each with a **recommended default**25(mark it "(Recomendado)") and a one-line why tied to their context. Calibrate to expertise — educate a26less-experienced user with a brief analogy and fewer options; go straight to trade-offs with an expert.27Never make them choose blind. Use `AskUserQuestion` for the discrete forks. Prefer the user's language28(Portuguese if they write in Portuguese).2930## Process3132### 0. Detect ground truth (read before asking)33- Run `ls -la` and `git status` in the target dir. Confirm it's **empty / greenfield** — if it already has34 a project, STOP and confirm intent before writing anything (this skill assumes a fresh repo).35- Look for an existing `architecture.md` / `docs/architecture.md` (or ask if they have one). If present,36 read it and let it answer the interview — open `references/architecture.md`.37- Note what's installed (`docker compose version`, `node`, `uv`, `go`, `flutter`) so the plan flags38 missing toolchains instead of failing mid-build.3940### 1. Interview (settle the shape)41Open `references/architecture.md` and resolve, one question at a time:421. **Architecture** — consume their `architecture.md`, or ask the style (modular monolith / frontend+backend43 / microservices / event-driven). Recommend the simplest that fits. For non-trivial systems, offer to44 chain to `tech-discovery`. Generate `docs/architecture.md` from the answers if none exists.452. **Which apps** — which of `frontend-app`, `backend-app`, `mobile`, extra `services/*` exist.463. **Stack per app** — for each, pick the stack. Map to a reference:47 - frontend React SPA on Cloudflare Workers → `references/stack-react-cloudflare.md` (pinned)48 - backend FastAPI async → `references/stack-fastapi-async.md` (pinned)49 - anything else (LangGraph, Go realtime, Flutter, Node, …) → `references/stack-research-recipe.md`50 (research live via context7/web; chain to a technical skill when one fits).514. **Conventions** — task runner (default go-task), pre-commit (default on), Conventional Commits hook52 (**default ON** — pairs with the `commit-message` skill), tests at **pre-push** (not per-commit),53 `.gitleaks.toml` secret-scan (default ruleset + our rules), CI (default GitHub Actions).5455### 2. Resolve stacks → references56For each chosen app, open its stack reference. For pinned stacks, **re-verify the version pins** (the57references say how). For generic stacks, run the A.1–A.11 method in `stack-research-recipe.md` and capture58the concrete versions before planning. Assign each app a **distinct dev port** (keep a port table).5960### 3. Plan → confirm (one gate)61Present the plan and get a single confirmation before writing. Use this skeleton:6263```64## Monorepo plan — <name>65Architecture: <style> (source: <their architecture.md | generated docs/architecture.md>)66Apps:67 - apps/frontend-app — <stack> (port <p>)68 - apps/backend-app — <stack> (port <p>)69 - <service/app> — <stack> (port <p>)70Shared: packages/proto (<contract format>)71Root: Taskfile.yml · AGENTS.md (+CLAUDE.md @import) · .editorconfig/.gitignore/.gitattributes/.tool-versions72 · .pre-commit-config.yaml · .github/workflows/ci.yml · infra/docker/compose.yaml · scripts/dev_*.sh73Dev loop: task up / down / restart / seed (compose + idempotent seed)74Missing toolchains to install: <... or none>7576File tree:77<the tree you will create>78```79Flag anything you could not verify as "(a confirmar)". Only proceed on explicit confirmation.8081### 4. Build (scaffold everything)82Lay down, in this order — keep each app a self-contained package:831. **Root**: `git init` (if needed); the layout + root config from `references/monorepo-and-agents.md`84 (`.editorconfig`, layered `.gitignore`, `.gitattributes`, `.tool-versions`, `README.md`, `LICENSE`,85 `CODEOWNERS`, `Taskfile.yml` with only the includes for apps that exist).862. **AGENTS.md**: root from `assets/templates/AGENTS.root.md.tpl`; `CLAUDE.md` = one `@AGENTS.md` line;87 per-app from `assets/templates/AGENTS.app.md.tpl`. Each per-app file holds only its delta.883. **Each app**: hello-world + a passing test, lint/format config, Dockerfile, `pyproject.toml`/`package.json`/89 etc., and a per-app `Taskfile.yml` (`install/lint/test/fmt/dev`). Use the exact snippets in the stack90 reference; don't invent versions.914. **Dev loop**: `infra/docker/compose.yaml`, `apps/*/scripts/{migrate,seed}.sh`, and `scripts/_common.sh`92 + `dev_{up,down,restart,seed,logs}.sh` from `references/docker-and-scripts.md`; `chmod +x scripts/*.sh`.935. **Harness**: `.pre-commit-config.yaml` + `.gitleaks.toml` (from `assets/templates/gitleaks.toml.tpl`) +94 `renovate.json5` (from `assets/templates/renovate.json5.tpl`) + `.github/workflows/ci.yml` from95 `references/precommit-and-ci.md` — include only the language blocks/jobs for apps that exist; path-scope96 every hook and CI filter. pre-commit stays fast (format/lint/secrets/msg); tests run at **pre-push**; the97 message hook (Conventional Commits) is **on by default**. **Supply chain born locked:** commit the98 lockfile, install from it (`npm ci`/`--frozen-lockfile`/`uv sync --frozen`), a **10-day cooldown**99 (`minimumReleaseAge`), and the **osv-scanner** CI job.1006. **`docs/architecture.md`** if you generated it (step 1).101102### 5. Validate103- Run `python3 scripts/validate_scaffold.py <repo>` (structure + AGENTS.md + port-collision + script-exec checks).104- Best-effort smoke per available toolchain: `task <app>:install` then `task <app>:lint`/`test` (or the app's105 native commands). Run `pre-commit install && pre-commit run --all-files` if pre-commit is available.106- Report honestly what passed, what was skipped (missing toolchain), and what failed with the output.107108### 6. Report109Summarize: the tree created, the dev-loop commands (`task up` / `dev_up.sh --seed`), per-app run commands,110any toolchains the user must install, validation results, and the obvious next steps (first feature, fill111the seed, set `compatibility_date`/secrets). Do not commit unless the user asks.112113## Reference routing114| Open when you need to… | Read |115|---|---|116| lay out the repo, AGENTS.md (root+per-app), task runner, root config | `references/monorepo-and-agents.md` |117| scaffold the pinned frontend (Vite+React → Cloudflare Workers) | `references/stack-react-cloudflare.md` |118| scaffold the pinned backend (FastAPI async) | `references/stack-fastapi-async.md` |119| scaffold any other stack (research live; LangGraph/Go/Flutter seeds) | `references/stack-research-recipe.md` |120| settle the architecture, or consume the user's architecture.md | `references/architecture.md` |121| wire the Compose dev stack, seed, and dev_*.sh scripts | `references/docker-and-scripts.md` |122| wire pre-commit + CI (path-filtered, polyglot) | `references/precommit-and-ci.md` |123124## Cross-cutting gotchas125- **Greenfield only** — never overwrite an existing project without explicit confirmation.126- **Pin real versions** — re-verify before emitting; never write a floating "latest" into a manifest.127- **One source of truth for agent context** — `AGENTS.md` canonical; `CLAUDE.md` is a thin `@AGENTS.md`.128- **Secrets never in chat or `vars`** — use `.dev.vars`/`wrangler secret`/`.env` (gitignored), `.env.example` committed.129- **Per-app everything** — own manifest, own `.gitignore` rules, own dev port (no collisions), own Taskfile.130- **Idempotent seed, profile-gated** — so it never wipes data or re-runs on every `up`.131- **Only scaffold what exists** — don't emit Go/Flutter/mobile blocks for apps the user didn't choose.132133<!-- PORTABILITY: portable body — no load-time shell preprocessing, no skill-dir template variable;134bundled files are referenced by relative path. allowed-tools is Claude-only (inert elsewhere). Codex135sidecar in agents/openai.yaml; opencode/Codex setup in PORTABILITY.md. -->