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…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository20 other files it gives its agents.
- cavecrewSkill
- caveman-commitSkill
- caveman-compressSkill
- caveman-helpSkill
- caveman-reviewSkill
- cavemanSkill
- caveman-statsSkill
- flutter-testerSkill
- owasp-mobile-security-checkerSkill
- release-updaterSkill
- flutter-testerSkill
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-exploreSkill
- openspec-proposeSkill
- owasp-mobile-security-checkerSkill
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-exploreSkill
- openspec-proposeSkill
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
- Distinctive: line 23
Always prefer MCP tools over manual file analysis.
- Very specific: line 27
Always use fvm flutter instead of flutter commands.
- Very specific: line 103
Interface Segregation: All services have I-prefixed interfaces
- Very specific: line 109
All services registered in lib/src/common/di/locator.dart via GetIt.
- Very specific: line 141
Run make codegen after changing models.
- Distinctive: line 168
Never use fallback/default values: when parsing fails
- Very specific: line 169
Always return
null: if parsing, extraction, or validation fails - Very specific: line 205
Inline key-value splitting: When OCR extracts multiple key-value pairs in one text block, _extractInlineValue splits by detecting the next …
- Very specific: line 234
All versions read from pubspec.yaml.
- Very specific: line 239
Test structure mirrors lib/src/:
≈ “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.
Files
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 filesdart_outline- Get file structure (classes, methods, etc)dart_completion- Get code completionsdart_hover- Get hover informationdart_references- Find references to symbolsdart_rename- Rename symbols across codebasedart_format- Format Dart/Flutter codedart_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-ipaDevelopment 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 + PKPassLayer Convention (per feature)
Each feature follows this internal structure:
application/- Services, use cases, business logicdomain/- Models (with@MappableClass())presentation/- Views and widgetsdata/- Repositories, remote/local data sources
Key Design Patterns
- Strategy:
TravelParserServicedispatches 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:
ImportServicecoordinates PDF, OCR, parser, and DB services - Observer:
TicketChangeNotifierfor 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/WebOCRServiceIPDFService→PDFService(Syncfusion + OCR fallback)IHapticService→HapticServiceIWidgetService→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
| Type | Convention | Example |
| Views (pages) | *View | HomeView, CalendarView |
| Widgets (reusable) | *Widget | TicketCardWidget |
| Interfaces | I* prefix | ILogger, ITicketDAO |
| Services | *Service | ImportService, PDFService |
| Providers | *Provider | ThemeProvider, CalendarProvider |
| Models | *Model | TNSTCTicketModel, EventModel |
| Files | snake_case | home_view.dart, locator.dart |
| Classes | PascalCase | TravelParserService |
| Enums | PascalCase | TicketType, AppRoute |
Code Style
- Linting:
very_good_analysis(strict) - Generated files (
*.mapper.dart,*.gen.dart) excluded from lint public_member_api_docsrule 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
nullif 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)→ boolparseTicket(String)→ Ticket (SMS)parseTicketFromBlocks(List<OCRBlock>)→ Ticket (PDF)isSMSFormat(String)→ boolparseUpdate(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| Stage | Android | iOS |
| Beta | make android-beta | make ios-beta |
| RC | make android-release-candidate | make ios-release-candidate |
| Production | make android-production | make 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:
mockitofor service interfaces - Fixtures: Real SMS and PDF layout data
- Coverage:
make coverage(excludes*.g.dart)
Key Dependencies
| Package | Purpose |
get_it | Dependency injection |
go_router | Navigation and deep links |
provider | Theme state management |
sqflite | SQLite database |
dart_mappable | JSON serialization (code-gen) |
syncfusion_flutter_pdf | PDF text extraction |
google_mlkit_text_recognition | OCR (mobile) |
pkpass | Apple Wallet pass parsing |
table_calendar | Calendar widget |
talker_flutter | Logging framework |
home_widget | Home screen widget |
share_handler | Share intent handling |
ai_barcode_scanner | QR/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)
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
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.

