# CLAUDE.md — Vibed Mono-Repo **Always run commands from the root of the project you are working on** — not from the repository root. Each project is self-contained and its commands (`cargo`, `mdbook`, `trunk`, `tofu`, etc.) must be run from within that project's directory. ## Repository Structure This is a mono-repo of independent projects. Each project lives in its own top-level folder. Projects may be Rust HTTP services, CLI tools, static sites, frontends, or anything else — there is no single template. Projects do not communicate with each other. ``` vibed/ ├── CLAUDE.md ├── README.md # repo-wide overview with descriptions of each project ├── LICENSE-APACHE ├── LICENSE-MIT ├── flake.nix # base Nix flake — projects may inherit or extend this ├── flake.lock ├── common/ # shared library crate (types, utilities, etc.) │ ├── Cargo.toml │ └── src/ │ └── lib.rs ├── / │ ├── CLAUDE.md # project-specific instructions (starts with @../CLAUDE.md) │ ├── docs/ │ │ ├── PLANNING.md # development phases and work logs │ │ └── ARCHITECTURE.md # component overview and interactions │ ├── README.md # what, how, run, test, license, disclaimer │ └── ... # project-specific files └── ... ``` ## Project CLAUDE.md Inheritance Each project-level `CLAUDE.md` should begin with: ``` @../CLAUDE.md ``` This imports the root conventions (validation, git, code style, license, task tracking) so they don't need to be duplicated. Project files should only contain project-specific overrides or additions. ## Common Patterns These are defaults that apply **when relevant** — not every project uses all of them. Rust CLI tools don't need Axum; static sites don't need SQLx. Apply the patterns that fit the project. ### Language & Tooling - **Language:** Rust (preferred; exceptions are documented per-project) - **Local development:** Nix with Nix Flakes for dependency management - **Infrastructure:** OpenTofu with the Cloudflare provider (stored in each project's `infra/` subfolder) - **Formatting:** Default `rustfmt` conventions (no custom `rustfmt.toml`) ### Backend - **Framework:** Tower + Axum - **Runtime:** Tokio - **Target:** Cloudflare Workers via [workers-rs](https://github.com/cloudflare/workers-rs) - **Deployment:** OpenTofu with the Cloudflare provider (prefer over wrangler for infrastructure management) - **API format:** JSON-encoded request and response payloads - **API spec:** Each backend service must have an auto-generated OpenAPI spec. _TODO: choose tooling crate._ ### Frontend - **Framework:** Yew (Rust compiled to Wasm) - **Build tool:** Trunk (`trunk serve` for local dev) - **Compile target:** `wasm32-unknown-unknown` (included in the Nix dev shell via rust-overlay) - **Hosting:** Cloudflare Pages ### Infrastructure - **Provider:** OpenTofu with the Cloudflare provider - **Location:** `infra/` subfolder in each project ### Data - **Production database:** Cloudflare D1 (SQLite-compatible) - **Local database:** Turso (file-backed SQLite) - **Query layer:** SQLx ### Chosen Crates When a crate is chosen to solve a problem, it becomes the standard for that purpose across all projects. Add new entries here as decisions are made. | Purpose | Crate | Notes | |---|---|---| | | | | _This table is intentionally empty. Populate it as crate decisions are made during development._ ### Shell & Scripting - **Never use `python3`** in CLI commands — use shell-native tools or Rust instead. - **Always use `jq`** when processing JSON in shell commands or scripts. ## Secrets & Configuration - **Local:** `.env` files for local secrets. **Never commit `.env` files to the repository.** - **Production:** Wrangler secrets (`wrangler secret put `). - Add `.env` to `.gitignore` at both the repo root and project level. ## Running Projects Locally Commands vary by project type. Run all commands from within the project directory. ```sh # Rust backend cargo run # Rust frontend trunk serve # Static site (mdBook) mdbook serve ``` ## Validation Run these commands **in order** from the **project directory** before committing changes: ```sh cargo fmt # 1. consistent formatting cargo check # 2. code is syntactically correct cargo clippy # 3. code follows best practices cargo test # 4. code is logically valid ``` Projects that are not Rust crates have their own validation steps documented in their `CLAUDE.md`. ## Git Conventions This repository follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary). Commit messages must use the format: ``` [optional scope]: [optional body] [optional footer(s)] ``` Common types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `ci`, `build`. Use the project name as the scope when the change is scoped to a single project (e.g., `feat(my-project): add user endpoint`). ## License All code in this repository is dual-licensed under: - [Apache License, Version 2.0](LICENSE-APACHE) - [MIT License](LICENSE-MIT) This follows standard Rust ecosystem convention. Each project README should reference this dual license. ## Code Style & Documentation ### Rust - All public functions, structs, enums, and modules must have rustdoc comments describing how they work. - Include doc-examples where applicable — these double as doctests. - Unit tests live in a `tests` module (`tests.rs` file) within the crate's root module or relevant submodules. - Each project has a `tests/` directory for integration-style tests. ### Release Builds Release builds must be compiled with settings to minimize binary size. Add this to each project's `Cargo.toml`: ```toml [profile.release] opt-level = "z" lto = true strip = true codegen-units = 1 ``` ### Infrastructure - Every OpenTofu `resource` and `data` block must have a comment explaining its purpose. ## Testing ### Structure - **Unit tests:** `src/tests.rs` module (or submodule-local `tests` modules) - **Integration tests:** `tests/` directory at the project root ### Coverage - Target 80%+ code coverage; higher is better. - _TODO: determine coverage tooling (e.g., `cargo-tarpaulin`, `cargo-llvm-cov`)._ ## Project Documentation Each project must maintain the following: ### README.md Covers: - What the project is - How it works - How to run it - How to test it - License (Apache-2.0 + MIT dual license) - Disclaimer that the software was written with Claude Code (include the specific model used) ### docs/PLANNING.md - Development phases - Work logs - Kept up to date as work progresses ### docs/ARCHITECTURE.md - Component overview - How components interact ## Repo-Wide Files | File | Purpose | |---|---| | `CLAUDE.md` | This file — conventions and instructions for Claude Code | | `README.md` | Repo overview with a description of each project | | `LICENSE-APACHE` | Apache 2.0 license text | | `LICENSE-MIT` | MIT license text | | `flake.nix` | Base Nix flake — projects may inherit or extend this | | `common/` | Shared library crate for cross-project types and utilities | ## Nix - All local development uses Nix. - Dependencies are managed with Nix Flakes. - The repo root has a base `flake.nix` that projects should either use directly or inherit and extend with their own `flake.nix`. ## Task Tracking with nbd `nbd` is a CLI tool for managing work tickets, designed for agent workflows. ### Initialisation ```sh nbd init ``` Run once in the project root. Creates `.nbd/tickets/`. Safe to run multiple times. ### Core commands ```sh # Create a new ticket (use --ftype md for a human-readable body) nbd create --title "Add OAuth login" --type feature --priority 7 --ftype md --json # List all open tickets (sorted by priority) nbd list --json # Read a specific ticket nbd read --json # Update a ticket nbd update --status in_progress --json nbd update --status done --json ``` ### Finding what to work on ```sh # All tickets that are unblocked and ready to start nbd ready --json # The single highest-priority unblocked ticket nbd next --json ``` ### Workflow 1. **Before starting** — create a ticket: `nbd create --title "..." --ftype md --json` 2. **When starting** — mark it in progress: `nbd update --status in_progress --json` 3. **When done** — mark it complete: `nbd update --status done --json` ### Guidelines - **Always pass `--json`** to every command for structured, unambiguous output. - **Always pass `--ftype md`** when creating tickets — markdown format keeps the body human-readable. - Use `jq` to parse and transform JSON output when needed. - Priority scale 0–10: use **7–9** for bugs, **5** for normal tasks, **3** for nice-to-haves. - `--type` choices: `project`, `feature`, `task`, `bug`. - Use `--deps id1,id2` to express blockers — tickets that must be done first. - Create tickets *before* starting non-trivial tasks, not after.