You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

377 lines
9.7 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# CLAUDE.md — Vibed Mono-Repo
<working-directory-rule>
**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.
</working-directory-rule>
<repository-structure>
## 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
├── <project>/
│ ├── 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
└── ...
```
</repository-structure>
<inheritance>
## 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.
</inheritance>
<common-patterns>
## 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-and-tooling>
### 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`)
</language-and-tooling>
<backend-pattern>
### 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._
</backend-pattern>
<frontend-pattern>
### 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
</frontend-pattern>
<infrastructure-pattern>
### Infrastructure
- **Provider:** OpenTofu with the Cloudflare provider
- **Location:** `infra/` subfolder in each project
</infrastructure-pattern>
<data-pattern>
### Data
- **Production database:** Cloudflare D1 (SQLite-compatible)
- **Local database:** Turso (file-backed SQLite)
- **Query layer:** SQLx
</data-pattern>
<chosen-crates>
### 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._
</chosen-crates>
</common-patterns>
<secrets-and-configuration>
## Secrets & Configuration
- **Local:** `.env` files for local secrets. **Never commit `.env` files to the repository.**
- **Production:** Wrangler secrets (`wrangler secret put <KEY>`).
- Add `.env` to `.gitignore` at both the repo root and project level.
</secrets-and-configuration>
<running-projects>
## 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
```
</running-projects>
<validation>
## 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`.
</validation>
<git-conventions>
## Git Conventions
This repository follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary).
Commit messages must use the format:
```
<type>[optional scope]: <description>
[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`).
</git-conventions>
<license>
## 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.
</license>
<code-style>
## Code Style & Documentation
<rust-style>
### 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.
</rust-style>
<release-builds>
### 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
```
</release-builds>
<infrastructure-style>
### Infrastructure
- Every OpenTofu `resource` and `data` block must have a comment explaining its purpose.
</infrastructure-style>
</code-style>
<testing>
## 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`)._
</testing>
<project-documentation>
## 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
</project-documentation>
<repo-wide-files>
## 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 |
</repo-wide-files>
<nix>
## 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`.
</nix>
<task-tracking>
## 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 <id> --json
# Update a ticket
nbd update <id> --status in_progress --json
nbd update <id> --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 <id> --status in_progress --json`
3. **When done** — mark it complete: `nbd update <id> --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 010: use **79** 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.
</task-tracking>