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.

9.8 KiB

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
├── <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
└── ...

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
  • 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 <KEY>).
  • 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.

# 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:

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.

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).

License

All code in this repository is dual-licensed under:

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:

[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.

IMPORTANT: before you do anything else, run the beans prime command and heed its output.

Task Tracking with beans

beans is a CLI tool for managing work tickets (called "beans"), designed for agent workflows.

Initialisation

beans init

Run once in the project root. Creates .beans/. Safe to run multiple times.

Core commands

# Create a new bean
beans create --json "Add OAuth login" --type feature --priority high --status todo

# List all beans
beans list --json

# Show a specific bean
beans show --json <id>

# Update a bean
beans update --json <id> --status in-progress
beans update --json <id> --status completed

Finding what to work on

# All beans that are unblocked and ready to start
beans list --json --ready

# Filter by type or status
beans list --json --type bug --status todo

Workflow

  1. Before starting — create a bean: beans create --json "..." --type task --status todo
  2. When starting — mark it in progress: beans update --json <id> --status in-progress
  3. When done — mark it complete: beans update --json <id> --status completed

Guidelines

  • Always pass --json to every command for structured, unambiguous output.
  • Use jq to parse and transform JSON output when needed.
  • --priority choices: critical, high, normal, low, deferred.
  • --type choices: milestone, epic, feature, task, bug.
  • Use --blocked-by <id> to express blockers — beans that must be done first.
  • Create beans before starting non-trivial tasks, not after.