[READ ONLY MIRROR] Open Source TikTok alternative built on AT Protocol github.com/sprksocial/client
flutter atproto video dart
client AGENTS.md
5.1 kB

AGENTS.md #

Project at a glance #

  • Root Flutter app: spark
  • Workspace members: widgetbook, fonts, assets
  • Stack: feature-first + Riverpod + GetIt + Freezed + AutoRoute
  • Generated files in use: *.g.dart, *.freezed.dart, *.gr.dart

Setup #

  1. Flutter 3.47.2 (stable, CI-aligned)
  2. touch .env (required before pub get; see .env.example for keys)
  3. flutter pub get --enforce-lockfile
  4. dart run build_runner build --delete-conflicting-outputs

Environment variables #

  • .env is loaded at startup via flutter_dotenv
  • Typical keys: VIDEO_SERVICE_URL, SPRK_APPVIEW_URL, MESSAGES_SERVICE_URL, AIP_BASE_URL
  • Never commit .env or platform credentials

Common commands (repo root) #

  • Deps: flutter pub get --enforce-lockfile
  • Codegen (app): dart run build_runner build --delete-conflicting-outputs
  • Codegen (widgetbook): cd widgetbook && dart run build_runner build --delete-conflicting-outputs
  • Format: dart format .
  • Format check: dart format --set-exit-if-changed .
  • Analyze app only: flutter analyze lib
  • Analyze all (includes widgetbook): flutter analyze .
  • Run tests: flutter test --reporter=expanded
  • Run app: flutter run only when no suitable Flutter process is already running

Code conventions #

  • Use package:material_ui/material_ui.dart for Material UI; SDK Material types are not interchangeable. Use appLocalizationDelegates for app and test localization setup.
  • Prefer package:spark/... imports; avoid deep cross-feature relative imports
  • Import order: Dart SDK, third-party, project; keep part after imports
  • Use strong explicit types; avoid dynamic unless required at boundaries
  • Use Freezed for immutable models and @riverpod for providers
  • Model async state consistently with AsyncValue
  • Naming: types PascalCase, members/providers lowerCamelCase, private _name
  • Keep feature flow: external/API/storage -> repository -> provider -> widget
  • Use GetIt (GetIt.I / sl) for DI-managed services
  • Never hand-edit generated files; regenerate instead

Maintainability bar #

  • Prefer changes that remove concepts, branches, helpers, or state rather than rearranging complexity
  • Keep logic in its owning layer; do not scatter feature checks through shared widgets or repositories
  • Treat ad-hoc conditionals, nullable modes, casts, dynamic, silent fallbacks, and pass-through wrappers as design smells unless they reflect a real external boundary
  • Reuse existing shared seams and canonical helpers before adding feature-local variants; for repeated UI/loading/motion behavior, check shared templates, design-system components, and Widgetbook patterns first
  • Watch file and widget growth; if a change pushes a file toward 1k lines or mixes responsibilities, split a focused helper/subcomponent before adding more flow logic

Review guidance #

  • Prioritize structural regressions over style nits: duplicated owners, scattered special cases, wrong-layer logic, and abstractions that only move complexity around
  • Push for simpler designs that delete branches, helpers, state, or concepts instead of polishing a messy shape
  • Treat unnecessary casts, nullable modes, silent fallbacks, and pass-through wrappers as review findings when they obscure the real contract
  • Flag file growth, feature logic leaking into shared paths, and bespoke helpers where an existing shared seam should be reused

Localization (l10n) #

  • All user-facing strings must go through intl_en.arb (lib/src/core/l10n/intl_en.arb), never hardcoded in widgets
  • Access: AppLocalizations.of(context).someKey
  • Import: package:spark/src/core/l10n/app_localizations.dart
  • Flutter regenerates l10n on build

Reliability and logging #

  • Wrap fallible async work in try/catch
  • After await: check mounted in widgets, ref.mounted in providers
  • Prefer graceful failures over crashes (AsyncValue.error, typed/null fallback)
  • Use LogService / SparkLogger, not print
  • Log context + stack traces; use proper levels (v, d, i, w, e, f)

Agent workflow #

  1. Read nearby feature files for local patterns
  2. Edit source files; run codegen when annotations/models change
  3. Format touched code (dart format .)
  4. Analyze (flutter analyze lib, or flutter analyze . for wider impact)
  5. Run targeted tests first, then broader tests (flutter test)
  6. If you want to run the app, first check whether a Flutter process is already running; if it is, use the Dart MCP to hot reload instead of starting a new flutter run process
  7. Keep comments minimal and only when needed
  8. Only add tests for logic that actually needs verification; avoid trivial or redundant test coverage

References #

  • analysis_options.yaml (strict-casts, strict-raw-types; excludes **/*.g.dart)
  • lib/src/features/README.md
  • lib/src/core/utils/logging/README.md
  • .github/workflows/lint.yml
  • .github/workflows/test.yml
  • .github/workflows/android.yml
  • CONTRIBUTING.md

Safety #

  • Never commit secrets (.env, platform credentials)
  • Do not revert unrelated local changes
  • Keep diffs scoped to the feature/task