bible-tracker/AGENTS.md
2026-04-20 14:39:49 -04:00

4.2 KiB

Agent Guide

Preferences for AI agents working on this repository. Follow these strictly.

Architecture

State management: Riverpod only

  • Use Riverpod for all state management and dependency injection.
  • The app is wrapped in ProviderScope at the root (lib/main.dart).
  • Use the right provider type:
    • Provider<T> for services.
    • FutureProvider<T> for async loads.
    • StreamProvider<T> for reactive streams.
    • StreamProvider.family<T, Param> for parameterized streams.
    • StateNotifierProvider<N, T> for mutable, persisted state (see trackerServiceProvider).

Services (business logic)

  • All services are instance classes — never static.
  • Accept dependencies via the constructor.
  • Always expose via a Provider.
final myServiceProvider = Provider<MyService>((ref) {
  return MyService(ref.read(repositoryProvider));
});

class MyService {
  final MyRepository _repository;
  MyService(this._repository);
}

Repositories (data access)

Create a repository only when data access meets one of:

  • Complex caching (in-memory + persistence).
  • Stream management for reactive updates.
  • Multiple specialized queries.
  • Multiple consumers.
  • Would otherwise be 100+ lines.

Otherwise, keep simple CRUD inline in the service. Never create thin repository wrappers that just delegate to a service.

Breaking circular dependencies

When two providers reference each other, add explicit types to break inference cycles:

final Provider<ServiceA> serviceAProvider = Provider<ServiceA>((ref) {
  final ServiceB b = ref.read(serviceBProvider);
  return ServiceA(b);
});

Code Quality (mandatory)

After every change, run in this order:

  1. Codegen (if @freezed or @GenerateMocks changed): dart run build_runner build --delete-conflicting-outputs
  2. Format (always, especially after codegen): dart format .
  3. Lints: use the ReadLints tool on modified files — must be clean.
  4. Analyzer: flutter analyze — must show "No issues found!".
  5. Tests: flutter test — 0 failures.
  6. Goldens (if UI changed and golden test exists): flutter test <file> --update-goldens and commit PNGs alongside the UI change.

Never commit unformatted code, lints, analyzer warnings, or UI changes without corresponding golden updates. Never tell the user "it's clean" without running the checks.

Code Style

  • Prefer const constructors everywhere possible.
  • Use final for locals by default.
  • Avoid dynamic — prefer explicit types.
  • Use Freezed for immutable data models; avoid hand-rolled ==/hashCode.
  • No narrative comments. Don't write // increment the counter. Only comment non-obvious intent, trade-offs, or constraints.
  • Keep files focused; mirror lib/ structure in test/.

Testing

  • Mock with mockito + @GenerateMocks + build_runner.
  • Unit tests for services and models; golden tests for screens and widgets.
  • Golden tests must run on macOS for consistent font rendering.
  • Load bundled fonts in test/flutter_test_config.dart.
  • Never skip failing tests to make CI pass — fix the root cause.

UI

  • Define a single theme in lib/widgets/theme.dart and reference design tokens (AppTokens) — no inline magic colors.
  • Keep DESIGN_GUIDE.md documenting color palette, typography, spacing, and component patterns. Reference it before any UI work.
  • Build reusable widgets (TrackerTile, BookTile, ProgressBar, etc.) instead of repeating styling.
  • Support both light and dark modes.
  • Use ListView.separated for lists with dividers.

Commits & PRs

  • Commit messages focus on why, not what.
  • Every commit on an open PR must be production-ready (format + analyze + test
    • lints + goldens).
  • Commit generated files (freezed, mocks, goldens) alongside the source changes that produced them.
  • Don't open/push a PR until the full checklist passes.

General Agent Behavior

  • Read README.md and this file before starting work.
  • Use todos for multi-step tasks; mark them complete promptly.
  • Don't hide verification failures — report honestly and fix.
  • Prefer editing existing files over creating new ones.
  • Never create docs (*.md) proactively unless asked.
  • Use specialized file tools (Read/Edit/Write) instead of cat/sed/echo.