Files
Marcos Paulo 6fcbe3ed94
ci / ci (macos-latest) (push) Has been cancelled
ci / ci (ubuntu-latest) (push) Has been cancelled
ci / ci (windows-latest) (push) Has been cancelled
docs: build hygiene rules (disk is shared and finite)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 19:49:50 -03:00

67 lines
6.1 KiB
Markdown

# AGENTS.md: guide for AI agents and contributors
NotesCraft is a native, Obsidian-compatible notes app written in **Rust only** (egui/eframe, no JavaScript, no Tauri/Electron/webview). It is a Craft-suite sibling of PhotoCraft and VectorCraft and follows their conventions. Product name is always **NotesCraft** in user-facing text; machine names are lowercase (`notescraft-*`). Read this file, then `SPEC.md` (the contract), `ROADMAP.md` (status) and `docs/ARCHITECTURE.md` (crate map and APIs).
## Orientation
| Read | Why |
|---|---|
| `SPEC.md` | Authoritative requirements, formats, contracts and acceptance table |
| `ROADMAP.md` | Phase status, what is done, what is next |
| `docs/ARCHITECTURE.md` | Layers, per-crate public API and status, design decisions |
## Workspace rules
- Edition 2024, resolver 3, `rust-version = "1.95"`. Use rustup stable (`PATH="$HOME/.cargo/bin:$PATH"`), not an older system cargo.
- One crate per concern in `crates/<name>`, package `notescraft-<name>`, `[lints] workspace = true`, registered in the root `[workspace.dependencies]` and in `xtask/src/layers.rs`.
- **Layering is enforced** by `cargo xtask layers`: a crate may depend only on strictly lower layers; nothing below L5 may use egui, eframe, winit or rfd. Layers: L0 `vault` `markdown`; L1 `index` `canvas` `diagrams` `whiteboard`; L2 `backlinks` `graph` `templates`; L3 `plugins` `themes`; L4 `engine`; L5 `editor` `mcp` `i18n`; L6 `ui-egui`.
- Shared crates come from craft-libs (`craft-atomic`, `craft-settings`, `craft-ui`, `craft-quit`, `craft-print`), pinned by git rev in the root `Cargo.toml`. Do not change their API; ask first.
- A new third-party dependency needs a written reason and owner approval. Already approved: `notify`, `pulldown-cmark`, `toml`, `wasmi`, `wat` (dev), `thiserror`, `serde`, `serde_json`, and for sync (2026-10-19): `sha2`, `axum`, `tokio`, `ureq` (rustls), `rusqlite`, and for paste (2026-10-20): `arboard` (image-data), `image` (png feature only), and for the registry (2026-10-21): `ring` (ed25519 verify, already linked through rustls).
## Never crash (outranks features)
- No `unwrap()`, `expect()`, `panic!`, `todo!`, `unreachable!`, `unimplemented!` in non-test code. Every crate keeps `#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]`. `unsafe` is forbidden.
- Input-derived numbers are hostile: use `get()` / `split_at_checked`, never `[i]` or `[a..b]` (even when guarded); `checked_*` / `saturating_*`; cap allocations; bound recursion (depth limits or iteration).
- Invalid input returns `Err`. Never silently clamp, truncate or "fix" it.
- Reserved vault paths `.obsidian/` and `.notescraft/` are never written through public APIs (except the explicit `write_private` for `.notescraft/`).
- No silent panics across the plugin boundary: traps, fuel exhaustion and memory limits become `Error`s.
## Code style
- One `thiserror` enum `Error` and `pub type Result<T>` per crate. Libraries do not use `anyhow`.
- Every public item has rustdoc, every module has a `//!` comment. `clippy::pedantic` must be clean; no blanket allows.
- Files stay under about 400 lines; split by concern. Smallest design that works; no speculative abstractions.
- **Source folders stay shallow and grouped**: no directory under a crate's `src/` (or an app's) holds more than 12 loose `.rs` files (`mod.rs` and `lib.rs` do not count). Group files into sub-folders by concern (`foo.rs` + `foo/`), and nest a group inside a parent folder when it grows. Moving files must not change public paths: re-export from `lib.rs`. Enforced by `cargo xtask tree` (part of `cargo xtask ci`); directories still waiting for their restructure are listed in `xtask/src/tree.rs` and in ROADMAP.md.
- Named exports, `import type`-style discipline, no magic numbers (named constants), `get` = derived, `fetch` = IO, `is`/`has`/`can` = predicate.
- Tests: unit in `src`, integration in `tests/`, benches/perf in `perf/` or `#[ignore]`d tests, examples in `examples/`. Write the failing test first. Every crate has at least one.
- Every write to disk goes through `craft-atomic`.
## Before you finish a task
```sh
export PATH="$HOME/.cargo/bin:$PATH"
cargo test -p notescraft-<crate>
cargo clippy -p notescraft-<crate> --all-targets -- -D warnings
cargo fmt -p notescraft-<crate>
cargo xtask ci # fmt --check, clippy -D warnings, test, layers: must be green
```
run `cargo xtask i18n` and do not add hardcoded user strings.
Check that every module is declared in `lib.rs` and that its tests actually run. After finishing, update `ROADMAP.md` and `docs/ARCHITECTURE.md` (status, public API, numbers). Commit only when the owner asks.
## Build hygiene (disk is shared and finite)
- Build only in an absolute `target/agent-<name>` dir, keep one scratch copy per agent with anchored excludes (`target*/` for directories), and delete both when you finish; the full rules are in `.claude/rules/build-hygiene.md`. `scripts/clean-agent-builds.sh --check` reports free space; without `--check` it deletes `target/agent-*`, stray `crates/*/target` and scratch copies (`--keep name` to spare a running agent).
- Under 20 GiB free on the system volume or `/Volumes/Storage`: stop and clean before building. A full system volume stops every agent and the harness.
## Everything is a command
User-visible behaviour is an engine command (id, label, params, `enabled`, `run`) so the UI, CLI, control channel, MCP and plugins share one surface (SPEC 10). The `engine` crate does not exist yet; until it does, keep logic in pure library crates that a command can call.
## Design
Check UI changes visually: `cargo run -p notescraft-ui-egui --example snapshot -- --vault <vault> --out ui.png --size 1440x900 --open "folder/note.md"` renders offscreen; read the PNG and compare with the PaperCraft design (also `--theme catppuccin-latte`, `--scale 2`).
Design reference: PaperCraft project `NotesCraft` (tokens, workspace, graph, palette, settings, whiteboard screens). Panels are rounded floating cards on the `canvas` colour and separate by tone, not borders; Catppuccin Mocha/Latte are the default themes (SPEC 8, 8.1, 8.2).