agentsclimarketplace

Presentation

Skill launch52-ai/flutter-template/.claude/skills/presentation

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.From its SKILL.md

Install
npx -y skills add launch52-ai/flutter-template --skill presentation

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 2 commands, including `dart run build_runner build --delete-conflicting-outputs` and 1 more.

SKILL.md

7.0 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it

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

What ships with it: 14 files

47.0 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.