Skip to content

Latest commit

 

History

History
189 lines (135 loc) · 8.02 KB

File metadata and controls

189 lines (135 loc) · 8.02 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

General Interaction Rules for AI Agents:

  • Never make any file changes unprompted. When the user asks a question, investigate and answer the question. Do not automatically assume the user wants you to change any code.
  • Before making any implementation changes, review the implementation plan: What are potentially important code design decisions, implicit in the plan? Spell them out explicitly to the user. If any significant design decisions are being made, first ask the user for explicit confirmation.

Project

The vision for this project is defined in README.vision.md. AI agents should never change this file, unless explicitly requested by the user. The philosophy for this project is defined in MANIFESTO.md. AI agents should never change this file, unless explicitly requested by the user.

Commands

devenv wrapper

⚠️ IMPORTANT: All build, test, and dev commands must run inside Docker using the devenv wrapper. Do not run them directly on the host.

All commands run through Docker via the devenv helper script:

devenv <directory> [options] -c "<command>"

This is done from the project root, any changes of directory can be done inside of the command, .e.g:

devenv . --no-tty -a -c "cd crates && ls"
devenv . --no-tty -a -c "cargo install --path crates/cli"

Where devenv is not available, docker compose can instead be used directly.

Options:

  • -a, --auto-select-service — Auto-select service (use this for CI/automated scripts)
  • -b, --build — Force rebuild image and container
  • -s, --service <name> — Select specific service by name
  • -c, --command <cmd> — Run command in container
  • -v, --verbose — Show debug output
  • -h, --help — Show help

Run / develop

devenv . --no-tty -a -c "cargo run --bin agile"

Test

devenv . --no-tty -a -c  "cargo test"                               # full suite
devenv . --no-tty -a -c  "cargo test --lib [test_name]"             # single unit test
devenv . --no-tty -a -c  'cargo test --test [file] [case] '         # specific test from specific file 

count tests in the project: (don't run)

devenv . --no-tty -a -c 'cargo test -- --list 2>/dev/null | grep -c ": test$"' # count tests

Before every commit, write the current date (format YYYY-MM-DD) and the result of this "count tests command" to a new line of file tests_count.txt at the project root.

Toolchain

Rust nightly (pinned in docker/Dockerfile by digest). Edition 2024.

Architecture

Planned module layout (not all exist yet):

  • src/parser/ — parse .agile.md files into an AST
  • src/checker/ — validate parsed tasks against rules (used by agile check)
  • src/rules/ — business logic; all testable logic lives here, not in components
  • src/ui/ — TUI/GUI components; business-logic-free
  • src/lsp/ — Language Server Protocol implementation

The CLI binary is agile. It reads *.agile.md files at any depth from the project root. The project's own backlog is tasks.agile.md, written in the mdagile syntax defined in README.vision.md.

Project-level configuration (properties, users, groups) lives in mdagile.toml.

Development rules

Sample text in tests

Always write inline file content using the "\ continuation style so the content renders exactly as it would in a real file — indentation and all:

let file_content = "\
- [ ] top task
  - [ ] subtask
    - [ ] nested
";

Never use embedded \n escapes or string concatenation for multi-line file samples. The goal is that a reader can see indentation and structure at a glance, just as they would in an actual .agile.md file. Always use an intermediate explanatory variables called file_content. Where multiple files are written make it mut and reuse it.

Test file structure

Tests — including unit tests — always live in a separate file, never inline in the source file. The source file declares the test module with a #[cfg(test)] attribute and a #[path] pointing to the test file:

// In foo.rs:
#[cfg(test)]
#[path = "foo_tests.rs"]
mod tests;
// In foo_tests.rs:
use super::*;

#[test]
fn it_works() { ... }

Name the test file <source_stem>_tests.rs and place it alongside the source file.

Formatting

After adding or editing any .rs file, run cargo fmt before committing.

TDD — mandatory for all code changes

Follow red-green cycle strictly:

  1. Write the test first — unit test in the relevant *_tests.rs file, or a Cucumber scenario in tests/acceptance/ for behaviour-level changes.
  2. Run it and confirm it failscargo test --lib -- test_name or cargo test --test acceptance-tests -- --name "scenario name". Do not proceed until you see the expected failure.
  3. Write the minimum code to make it pass — no more.
  4. Run the test again and confirm it passes.
  5. Run the full suite (cargo test) to check for regressions before finishing.

Never write production code without a failing test that justifies it.

Exceptions:

  • The GUI physics module does not need unit tests

GUI target

Always confirm the GUI target still compiles after a change

devenv . --no-tty -a -c  "cd crates/gui && dx build --platform web"

Auto-commit

Whenever a prompt results in code changes (modifications to versioned files or new files to be versioned), automatically create a commit

Test requirements:

  • If only .md files are modified: commit directly without running tests.
  • If any .rs or other code files are modified: run cargo test first and ensure all tests pass before committing.
  • Exception: tasks.agile.md must be validated with agile check before committing (it's a .agile.md file, not documentation).

If tests fail, fix them first — do not commit a red suite.

Commit format:

  • Short summary: (Claude) <description> — e.g., (Claude) add confetti animation to Done button
  • Body:
    • Include a detailed explanation of the changes, followed by the verbatim user prompt that triggered the changes
    • Include the total number of tests in the project (c.f. above for how to count). Format: "total tests: "

Example:

(Claude) add confetti animation to Done button

Added CSS confetti animation that plays when the user clicks "Done!" to complete a task.
- Created assets/confetti.css with particle animation (2.5s duration)
- Updated home.rs to trigger animation on button click
- Integrated CSS into app.rs stylesheet list

User prompt:
> add a simple css confetti animation to the "Done" button (when completing a task)

Task Management in tasks.agile.md

Use tasks.agile.md as the authoritative record of work completed and planned:

  • When work is completed: Mark it as done [x] in tasks.agile.md immediately, even if it's already committed.
  • When the user prompts something new: If it's not already in tasks.agile.md, create a new task in a suitable location (under an appropriate section/heading, or create a new section if needed).
  • Keep it current: This file serves as a running history of what's been built and what's planned next. Use it to avoid duplicate work and to understand project momentum.
  • Never modify the user's task text, markers, or structure — the only permitted change is ticking a task to done ([ ][x]) for work you have actually completed. Do not reword tasks, add or remove markers (e.g. #OPT), restructure sections, or make any other edits unless the user explicitly asks.

Terminology

See GLOSSARY.md for precise definitions. Key terms used throughout the codebase and vision docs:

  • Marker — any #word or @word token
  • Property — a user-defined #marker declared in mdagile.toml
  • Assignment — a @marker assigning a task to a user or group
  • Special Marker — an ALL-CAPS built-in keyword (e.g. #OPT, #MILESTONE, #MDAGILE)

Do not use these terms interchangeably.

Known issues / gotchas

...