agentleFS
Namma-FlutterNamma-Flutter/namma_wallet/AGENTS.md

namma_wallet

AGENTS.md59 starsChanged 5 months agoMITView on GitHub

Never run the app. Tell the user to run it. You don't need to listen to logs. Let the user do it. Dart MCP server configured for Flutter/Dart analysis. Use dart_* tools for code analysis, navigation, diagnostics, refactoring. Available tools: Always prefer MCP tools over manual file analysis. Always use fvm flutter instead of flutter commands. Feature-based Clean Architecture with GetIt for DI, GoRouter for navigation, and Provider for theme state. Each feature follows this internal structure: All services registered…

The file

We split this AGENTS.md into the rules it gives an agent

10 rules. About 0 are common, 2 are distinctive, and 8 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    Always prefer MCP tools over manual file analysis.

    line 23
  2. Very specific:

    Always use fvm flutter instead of flutter commands.

    line 27
  3. Very specific:

    Interface Segregation: All services have I-prefixed interfaces

    line 103
  4. Very specific:

    All services registered in lib/src/common/di/locator.dart via GetIt.

    line 109
  5. Very specific:

    Run make codegen after changing models.

    line 141
  6. Distinctive:

    Never use fallback/default values: when parsing fails

    line 168
  7. Very specific:

    Always return null: if parsing, extraction, or validation fails

    line 169
  8. Very specific:

    Inline key-value splitting: When OCR extracts multiple key-value pairs in one text block, _extractInlineValue splits by detecting the next …

    line 205
  9. Very specific:

    All versions read from pubspec.yaml.

    line 234
  10. Very specific:

    Test structure mirrors lib/src/:

    line 239

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Never run the app. Tell the user to run it. You don't need to listen to logs. Let the user do it.

MCP Server

Dart MCP server configured for Flutter/Dart analysis. Use dart_* tools for code analysis, navigation, diagnostics, refactoring.

Available tools:

  • dart_diagnostics - Get errors/warnings for files
  • dart_outline - Get file structure (classes, methods, etc)
  • dart_completion - Get code completions
  • dart_hover - Get hover information
  • dart_references - Find references to symbols
  • dart_rename - Rename symbols across codebase
  • dart_format - Format Dart/Flutter code
  • dart_fix - Apply quick fixes

Always prefer MCP tools over manual file analysis.

Development Commands

Always use fvm flutter instead of flutter commands.

# Install dependencies
fvm flutter pub get

# Analyze code (prefer dart mcp tools)
fvm flutter analyze

# Run tests
fvm flutter test

# Code generation (after changing models)
fvm dart run build_runner build --delete-conflicting-outputs

# Release builds (always use Makefile)
make release-apk
make release-appbundle
make release-ipa

Development Setup

  • Flutter SDK: 3.38.6 (managed via FVM, Dart SDK 3.10.7)
  • Xcode: 16.4.0
  • Minimum requirements: Android Studio / Xcode, FVM

Architecture

Feature-based Clean Architecture with GetIt for DI, GoRouter for navigation, and Provider for theme state.

Project Structure

lib/src/
├── app.dart                     # Main app widget
├── common/                      # Shared code
│   ├── database/                # SQLite DAOs (sqflite)
│   ├── di/locator.dart          # GetIt service registration
│   ├── domain/models/           # Ticket, User, ExtrasModel
│   ├── enums/                   # TicketType, etc.
│   ├── routing/                 # GoRouter + AppRoute enum
│   ├── services/                # Logger, OCR, PDF, Haptic, Widget
│   ├── theme/                   # Material 3 light/dark themes
│   └── widgets/                 # Shared UI components
└── features/
    ├── bottom_navigation/       # Navigation bar
    ├── calendar/                # Calendar view (TableCalendar)
    ├── clipboard/               # Clipboard ticket parsing
    ├── common/generated/        # flutter_gen output
    ├── events/                  # Event ticket support
    ├── export/                  # Export functionality
    ├── home/                    # Home screen + ticket cards
    ├── import/                  # File import (PDF, PKPass)
    ├── irctc/                   # IRCTC train tickets
    ├── receive/                 # Share intent / deep link handling
    ├── settings/                # Settings, DB viewer, OCR debug
    ├── tnstc/                   # TNSTC/SETC bus tickets
    └── travel/                  # Travel parser orchestration + PKPass

Layer Convention (per feature)

Each feature follows this internal structure:

  • application/ - Services, use cases, business logic
  • domain/ - Models (with @MappableClass())
  • presentation/ - Views and widgets
  • data/ - Repositories, remote/local data sources

Key Design Patterns

  • Strategy: TravelParserService dispatches to TNSTC/SETC/IRCTC parsers
  • DAO: Database abstraction (ITicketDAO, IUserDAO)
  • Service Locator: GetIt singleton/lazy-singleton registration
  • Interface Segregation: All services have I-prefixed interfaces
  • Facade: ImportService coordinates PDF, OCR, parser, and DB services
  • Observer: TicketChangeNotifier for reactive ticket list updates

Dependency Injection (locator.dart)

All services registered in lib/src/common/di/locator.dart via GetIt. Platform-specific implementations selected with kIsWeb:

  • ILogger → NammaLogger (Talker)
  • IWalletDatabase → WalletDatabase (sqflite)
  • IOCRService → GoogleMLKitOCR / WebOCRService
  • IPDFService → PDFService (Syncfusion + OCR fallback)
  • IHapticService → HapticService
  • IWidgetService → HomeWidgetService / WebWidgetService
  • Parsers: ITravelParser, IPKPassParser, IIRCTCParser

Database

SQLite via sqflite. Database: namma_wallet.db, version 4.

tickets table: id, ticket_id (unique), primary_text, secondary_text, type, start_time, end_time (nullable), location, tags (JSON), extras (JSON), image_path, directions_url, created_at, updated_at.

DAO methods: handleTicket() (upsert), getAllTickets(), getTicketById(), updateTicket(), deleteTicket().

Routing

GoRouter with AppRoute enum. Deep link scheme: nammawallet://. Shell route wraps Home, Import, Calendar with bottom navigation.

Serialization

dart_mappable with @MappableClass(). Generated .mapper.dart files provide toMap(), toJson(), fromMap(), fromJson(). Run make codegen after changing models.

Naming Conventions

TypeConventionExample
Views (pages)*ViewHomeView, CalendarView
Widgets (reusable)*WidgetTicketCardWidget
InterfacesI* prefixILogger, ITicketDAO
Services*ServiceImportService, PDFService
Providers*ProviderThemeProvider, CalendarProvider
Models*ModelTNSTCTicketModel, EventModel
Filessnake_casehome_view.dart, locator.dart
ClassesPascalCaseTravelParserService
EnumsPascalCaseTicketType, AppRoute

Code Style

  • Linting: very_good_analysis (strict)
  • Generated files (*.mapper.dart, *.gen.dart) excluded from lint
  • public_member_api_docs rule is disabled
  • Logging: Talker in debug, disabled in production (no PII)

Error Handling

CRITICAL: Never Fall Back to Default Values

  • Never use fallback/default values when parsing fails
  • Always return null if parsing, extraction, or validation fails
  • Never silently substitute with current date, empty strings, or placeholder values
  • Explicit failure is better than implicit incorrect data

Examples:

  • Bad: Date parsing fails → fallback to DateTime.now()
  • Good: Date parsing fails → return null
  • Bad: PNR extraction fails → use "Unknown"
  • Good: PNR extraction fails → return null

Parser System

Travel Parser Strategy

TravelParserService routes to the correct parser based on input:

Input (SMS/PDF/QR)
  → TravelParserService.canParse() / isSMSFormat()
    → TNSTCBusParser   (TNSTC + SETC buses)
    → IRCTCTrainParser (Indian Railways)
    → PKPassParser     (Apple Wallet .pkpass files)

Each parser implements:

  • canParse(String) → bool
  • parseTicket(String) → Ticket (SMS)
  • parseTicketFromBlocks(List<OCRBlock>) → Ticket (PDF)
  • isSMSFormat(String) → bool
  • parseUpdate(String) → TicketUpdateInfo? (updates)

OCR and Layout-Based Extraction

Inline key-value splitting: When OCR extracts multiple key-value pairs in one text block, _extractInlineValue splits by detecting the next key (pattern: words followed by :).

Column-aligned table parsing: Passenger tables with missing columns use header X-coordinate positions instead of array indexing to avoid column misalignment.

OCR error correction: Seat number patterns like 120B are auto-corrected to 12UB (OCR misreads U as 0). Patterns: \d+0B$ → UB, \d+0L$ → UL.

Deployment

Three-stage pipeline via Makefile + Fastlane:

Beta → Release Candidate → Production
StageAndroidiOS
Betamake android-betamake ios-beta
RCmake android-release-candidatemake ios-release-candidate
Productionmake android-productionmake ios-production

Combined: make deploy-beta, make deploy-release-candidate, make deploy-production.

All versions read from pubspec.yaml. Never build directly with flutter build — always use Makefile targets.

Testing

Test structure mirrors lib/src/:

test/
├── src/features/          # Feature tests
├── fixtures/              # SMS/layout test data
└── helpers/               # Test utilities
  • Unit tests: Parser logic, service methods
  • Widget tests: Provider state, UI interactions
  • Mocking: mockito for service interfaces
  • Fixtures: Real SMS and PDF layout data
  • Coverage: make coverage (excludes *.g.dart)

Key Dependencies

PackagePurpose
get_itDependency injection
go_routerNavigation and deep links
providerTheme state management
sqfliteSQLite database
dart_mappableJSON serialization (code-gen)
syncfusion_flutter_pdfPDF text extraction
google_mlkit_text_recognitionOCR (mobile)
pkpassApple Wallet pass parsing
table_calendarCalendar widget
talker_flutterLogging framework
home_widgetHome screen widget
share_handlerShare intent handling
ai_barcode_scannerQR/barcode scanning

Platform-Specific Notes

iOS

  • Deep links via AppDelegate.swift (MethodChannel)
  • Home widget via WidgetKit (iOS 17+)
  • App group: group.com.nammaflutter.nammawallet
  • Share extension for .pkpass files

Android

  • Home screen widget (TicketListWidgetProvider)
  • Background tasks via WorkManager
  • App shortcuts support
  • Signing via keystore (managed by Fastlane)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.