|
1 | | -@AGENTS.md |
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +@AGENTS.md |
| 6 | + |
| 7 | +## Repository Shape |
| 8 | + |
| 9 | +Vespera is a **hybrid monorepo** with two workspaces living side-by-side at the repo root: |
| 10 | + |
| 11 | +| Workspace | Manager | Members | Purpose | |
| 12 | +|-----------|---------|---------|---------| |
| 13 | +| Cargo (`Cargo.toml`) | cargo | `crates/*`, `examples/*` (excluding `examples/java-jni-demo`) | OpenAPI engine, proc-macros, JNI bridge | |
| 14 | +| Bun (`package.json`) | bun | `apps/*` | Marketing/docs site + admin panel (Next.js) | |
| 15 | + |
| 16 | +Both live at the root — `bun run ...` operates on the Node side; `cargo ...` on the Rust side. Many root scripts deliberately cross the boundary (e.g., `prelint` runs `cargo clippy/fmt/check` **before** oxlint runs on JS). See `AGENTS.md` for crate-level detail. |
| 17 | + |
| 18 | +## Common Commands (Root) |
| 19 | + |
| 20 | +```bash |
| 21 | +# Rust side |
| 22 | +cargo build # Build all crates |
| 23 | +cargo test --workspace # All Rust tests |
| 24 | +cargo test -p vespera_macro # One crate |
| 25 | +cargo test --test <name> -- <filter> # Single integration test |
| 26 | +cargo tarpaulin --out stdout # Coverage (run via `bun run posttest`) |
| 27 | + |
| 28 | +# Lint / format (order matters — `prelint` hook runs Rust FIRST) |
| 29 | +bun run lint # oxlint over JS/TS (runs after prelint → cargo clippy+fmt+check) |
| 30 | +bun run lint:fix # oxlint --fix (prelint:fix runs cargo clippy --fix + fmt first) |
| 31 | + |
| 32 | +# Front-end workspace |
| 33 | +bun run dev # Runs `dev` in every apps/* (Next.js dev servers) |
| 34 | +bun run build # Builds apps/front and apps/admin |
| 35 | +cd apps/front && bun dev # Single-app dev (preferred over -F flag, per devfive-frontend skill) |
| 36 | + |
| 37 | +# Tests (Bun side) |
| 38 | +bun test # Root runs bun test + tarpaulin via posttest hook |
| 39 | + |
| 40 | +# Release tooling |
| 41 | +bun run changepacks # Version bumps via @changepacks/cli |
| 42 | +``` |
| 43 | + |
| 44 | +> **`prelint` gotcha:** `bun run lint` triggers `cargo clippy -- -D warnings && cargo fmt --check && cargo check` first. Any Rust warning fails the JS lint. Run `bun run lint:fix` (which chains `cargo clippy --fix && cargo fmt`) to auto-resolve both sides. |
| 45 | +
|
| 46 | +## Frontend (`apps/front`) |
| 47 | + |
| 48 | +Next.js 16 App Router + React 19 + @devup-ui/react (build-time CSS-in-JS). Theme tokens live in `apps/front/devup.json` and use the `$token` syntax in JSX props only. |
| 49 | + |
| 50 | +- `apps/front/src/app/` contains **only** `layout.tsx` and `page.tsx` — all other components belong in `src/components/` (per devfive-frontend conventions). |
| 51 | +- `src/api.ts` is generated/edited via `@devup-api/fetch`; it currently contains a placeholder `/users/users` call that fails typecheck — a known scaffolding leftover, not a regression. |
| 52 | +- Styling: use devup-ui shorthand props (`bg`, `p`, `w`, `_hover`, `[mobile,null,pc]` responsive arrays). Never `style={{...}}` or Tailwind. See `~/.claude/skills/devup-ui/SKILL.md` via the `/devup-ui` skill. |
| 53 | + |
| 54 | +## Rust × Java Boundary |
| 55 | + |
| 56 | +The JNI integration (`crates/vespera_jni` → `libs/vespera-bridge/` Java lib) is load-bearing for `examples/rust-jni-demo`. When touching: |
| 57 | + |
| 58 | +- `vespera_inprocess` owns transport-agnostic dispatch (no JNI deps). |
| 59 | +- `vespera_jni` is a thin layer depending on `vespera_inprocess` + `jni` + `tokio/rt-multi-thread`. |
| 60 | +- User code depends on `vespera` only, with `features = ["jni"]` — never `vespera_jni` directly. Breaking this invariant is an AGENTS.md-listed anti-pattern. |
| 61 | + |
| 62 | +The Java package `com.devfive.vespera.bridge` is **fixed** because the JNI symbol name is derived from it. Renaming it breaks the native load. |
| 63 | + |
| 64 | +## Pre-Commit (Husky) |
| 65 | + |
| 66 | +`bun run prepare` installs husky. Commits trigger whatever lives in `.husky/` — typically a `lint` pass. Never bypass with `--no-verify`; fix the underlying Rust or oxlint finding. |
| 67 | + |
| 68 | +## Where Tests Live |
| 69 | + |
| 70 | +| Concern | Location | |
| 71 | +|---------|----------| |
| 72 | +| Macro integration tests | `crates/vespera_macro/tests/` (+ `insta` snapshots) | |
| 73 | +| Core unit tests | `crates/vespera_core/src/**` inline `#[cfg(test)]` | |
| 74 | +| JNI end-to-end | `examples/rust-jni-demo` (Rust + Java + Gradle) | |
| 75 | +| Front tests | `apps/front/src/__tests__/` (bun test + bun-test-env-dom) | |
| 76 | + |
| 77 | +Snapshot tests use `insta` — run `cargo insta review` to accept drifts. |
0 commit comments