agentleFS
launch52-ailaunch52-ai/flutter-template/.claude/skills/presentation/SKILL.md

presentation

Skill2 starsChanged 9 months agoMITView on GitHub

Generate presentation layer code (Freezed states, Riverpod notifiers, screens, widgets) from feature specifications. Creates the UI layer with proper state management. Use after /data to implement screens and state handling.

We split this skill into the rules it gives an agent

13 rules. 0 are common, 7 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 18 edited versions we read keep these.

  • 7

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Never imports data layer (models, repository implementations)

    line 15
  2. Very specific:

    After /data has implemented repositories

    line 23
  3. Distinctive:

    When creating screens from spec requirements

    line 24
  4. Distinctive:

    When adding new screens or actions to existing features

    line 25
  5. Very specific:

    If domain/data layers don't exist, ask user to run /domain and /data first.

    line 52
  6. Very specific:

    Use reference files in reference/ directory as templates:

    line 64
  7. Very specific:

    Sealed unions: - Use Freezed sealed class for exhaustive matching

    line 112
  8. Distinctive:

    Domain entities only: - Never put DTOs in state

    line 113
  9. Distinctive:

    Repository injection: - Read repository from ref, never import data layer

    line 122
  10. Distinctive:

    Before finishing presentation layer:

    line 146
  11. Distinctive:

    No data layer imports: - Only import from domain/

    line 174
  12. Very specific:

    Disposal safety: - Always check _disposed after await

    line 176
  13. Very specific:

    Pattern matching: - Use switch expression on sealed states

    line 177

“Common” is measured: kept by at least 6 in 10 of the 18 edited versions of this file we could read. “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
SKILL.md

Presentation - Presentation Layer Generator

Generate presentation layer components that handle UI state and render screens using domain entities.

Philosophy

The presentation layer is domain-aware, data-blind:

  • Imports domain entities and repository interfaces
  • Never imports data layer (models, repository implementations)
  • Uses Freezed sealed states for exhaustive pattern matching
  • Uses Riverpod AsyncNotifier with disposal safety

This keeps the UI decoupled from data sources and serialization details.

When to Use This Skill

  • After /data has implemented repositories
  • When creating screens from spec requirements
  • When adding new screens or actions to existing features
  • User asks to "create screen", "implement UI", "add presentation layer"

What This Skill Creates

lib/features/{feature}/presentation/
├── providers/
│   ├── {feature}_state.dart         # Freezed sealed state
│   └── {feature}_notifier.dart      # AsyncNotifier with safe state
├── screens/
│   └── {feature}_screen.dart        # ConsumerWidget with pattern matching
└── widgets/
    └── {feature}_item.dart          # Extracted reusable widgets

Workflow

Step 1: Locate Requirements

Check for:

lib/features/{feature}/.spec.md           # Feature specification
lib/features/{feature}/domain/            # Domain entities
lib/features/{feature}/data/              # Repository implementation

If domain/data layers don't exist, ask user to run /domain and /data first.

Step 2: Analyze UI Requirements

From the spec, identify:

  • Screens - Section 4.1 (list, detail, form, etc.)
  • State Fields - What data each screen needs
  • Actions - User interactions (refresh, create, delete, submit)
  • Navigation - How screens connect

Step 3: Generate Code

Use reference files in reference/ directory as templates:

ComponentReference File
List statereference/providers/list_state.dart
Detail statereference/providers/detail_state.dart
Form statereference/providers/form_state.dart
Basic notifierreference/providers/basic_notifier.dart
CRUD notifierreference/providers/crud_notifier.dart
Form notifierreference/providers/form_notifier.dart
List screenreference/screens/list_screen.dart
Detail screenreference/screens/detail_screen.dart
Form screenreference/screens/form_screen.dart
List item widgetreference/widgets/list_item.dart
Form field widgetreference/widgets/form_field.dart

Step 4: Run Code Generation

dart run build_runner build --delete-conflicting-outputs

Step 5: Verify

dart analyze lib/features/{feature}/presentation/

Commands

CommandPurpose
/presentation {feature}Generate full presentation layer
/presentation {feature} --only=providersGenerate only state and notifier
/presentation {feature} --only=screensGenerate only screens
/presentation {feature} --add-screen={Name}Add new screen to existing feature

Screen Types

TypeUse WhenState Complexity
ListDisplaying collectioninitial, loading, loaded(items), error
DetailSingle item viewinitial, loading, loaded(item), error
FormCreate/editForm fields + isSubmitting, validation
ConfirmationDestructive actionsMinimal, action-focused

State Design Principles

  1. Sealed unions - Use Freezed sealed class for exhaustive matching
  2. Domain entities only - Never put DTOs in state
  3. Derived state - Compute isEmpty, hasError from base state
  4. Separate form state - Forms use field-based state, not sealed unions

Core pattern: sealed class with initial, loading, loaded(items), error(message)

Notifier Design Principles

  1. Disposal safety - Track _disposed flag, check after every await
  2. Repository injection - Read repository from ref, never import data layer
  3. Error mapping - Convert exceptions to user-friendly messages (via /i18n)
  4. Action methods - One public method per user action

Core pattern:

bool _disposed = false;
void _safeSetState(State s) { if (!_disposed) state = s; }
// Check _disposed after EVERY await

Screen Pattern

Core pattern:

switch (state) {
  StateInitial() || StateLoading() => CircularProgressIndicator(),
  StateLoaded(:final items) => ListView.builder(/*...*/),
  StateError(:final message) => Text(message),
}

Checklist

Before finishing presentation layer:

  • All screens from spec are created
  • State uses domain entities only
  • Notifier has _disposed flag and _safeSetState
  • Screen uses switch pattern matching on state
  • All user actions have corresponding notifier methods
  • Loading states shown during async operations
  • Error states display user-friendly messages (i18n keys)
  • Empty states handled with helpful messages
  • No data layer imports (no models, no repository implementations)
  • Widgets extracted when screen exceeds 200 lines
  • build_runner executed successfully

Naming Conventions

ElementConventionExample
State class{Feature}StateBookmarksState
State file{feature}_state.dartbookmarks_state.dart
Notifier class{Feature}NotifierBookmarksNotifier
Notifier file{feature}_notifier.dartbookmarks_notifier.dart
Screen class{Feature}ScreenBookmarksScreen
Screen file{feature}_screen.dartbookmarks_screen.dart
Widget{Feature}{Component}BookmarkListItem

Presentation Layer Rules

  1. No data layer imports - Only import from domain/
  2. Freezed for states - Sealed unions for exhaustive matching
  3. Disposal safety - Always check _disposed after await
  4. Pattern matching - Use switch expression on sealed states
  5. Widgets for reuse - Extract when >50 lines or used multiple times

Guides

GuideUse For
patterns-guide.mdState patterns, notifier patterns, screen structures
examples.mdComplete before/after examples
reference/Actual code templates

Related Skills

  • /data - Run first to implement repository
  • /domain - Creates entities used by presentation
  • /feature-init - Initialize feature scaffold
  • /i18n - Localize user-facing strings and error messages
  • /design - Polish UI/UX patterns after basic implementation
  • /a11y - Add accessibility support
  • /testing - Create widget tests

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.

Reviews can't be read right now.

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.