.cursor/skills/bloc-state-management/SKILL.md
Guides BLoC state management implementation patterns. Use when creating new BLoCs, handling state changes, or managing application state.
npx skillsauth add avra-cadavra/avrai bloc-state-managementInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
All BLoCs must extend Bloc<Event, State> and follow the event/state pattern.
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
// Events
abstract class MyEvent extends Equatable {
@override
List<Object?> get props => [];
}
class LoadData extends MyEvent {}
class UpdateData extends MyEvent {
final String data;
UpdateData(this.data);
@override
List<Object?> get props => [data];
}
// States
abstract class MyState extends Equatable {
@override
List<Object?> get props => [];
}
class MyInitial extends MyState {}
class MyLoading extends MyState {}
class MyLoaded extends MyState {
final String data;
MyLoaded(this.data);
@override
List<Object?> get props => [data];
}
class MyError extends MyState {
final String message;
MyError(this.message);
@override
List<Object?> get props => [message];
}
// BLoC
class MyBloc extends Bloc<MyEvent, MyState> {
final MyUseCase useCase;
MyBloc({required this.useCase}) : super(MyInitial()) {
on<LoadData>(_onLoadData);
on<UpdateData>(_onUpdateData);
}
Future<void> _onLoadData(
LoadData event,
Emitter<MyState> emit,
) async {
emit(MyLoading());
try {
final data = await useCase.getData();
emit(MyLoaded(data));
} catch (e) {
emit(MyError(e.toString()));
}
}
Future<void> _onUpdateData(
UpdateData event,
Emitter<MyState> emit,
) async {
// Handle update
}
}
emit() not yield - Modern BLoC APIon<EventType>()BlocProvider auto-disposal or dispose manually// In widget tree
BlocProvider(
create: (context) => MyBloc(
useCase: sl<MyUseCase>(),
),
child: MyWidget(),
)
// Or with existing instance
BlocProvider.value(
value: existingBloc,
child: MyWidget(),
)
// BlocBuilder - Rebuilds UI on state changes
BlocBuilder<MyBloc, MyState>(
builder: (context, state) {
if (state is MyLoading) return CircularProgressIndicator();
if (state is MyError) return Text(state.message);
if (state is MyLoaded) return Text(state.data);
return Container();
},
)
// BlocListener - Reacts to state changes (side effects)
BlocListener<MyBloc, MyState>(
listener: (context, state) {
if (state is MyError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.message)),
);
}
},
child: MyWidget(),
)
// BlocConsumer - Combines Builder + Listener
BlocConsumer<MyBloc, MyState>(
listener: (context, state) { /* side effects */ },
builder: (context, state) { /* UI */ },
)
Always handle errors in event handlers:
Future<void> _onLoadData(
LoadData event,
Emitter<MyState> emit,
) async {
emit(MyLoading());
try {
final data = await useCase.getData();
emit(MyLoaded(data));
} on NetworkException catch (e) {
emit(MyError('Network error: ${e.message}'));
} catch (e, st) {
developer.log('Unexpected error', error: e, stackTrace: st, name: 'MyBloc');
emit(MyError('Something went wrong'));
}
}
See existing BLoCs in:
lib/presentation/blocs/auth/auth_bloc.dartlib/presentation/blocs/spots/spots_bloc.dartlib/presentation/blocs/search/hybrid_search_bloc.dartdevelopment
--- name: world-model-development description: Guides world model development patterns: state/action encoders, ONNX inference, feature extraction pipeline, latency budgets. Use when implementing world model components, state encoders, action encoders, feature extractors, or ONNX models. Core skill for Phases 3-6. --- # World Model Development Patterns ## Core Principle All world model components follow LeCun's autonomous machine intelligence framework. State observations flow through a percep
tools
Implements base workflow controller patterns for multi-step processes. Use when creating complex workflows that require orchestration of multiple steps with error handling and rollback.
testing
--- name: widget-test-patterns description: Guides widget test patterns: BLoC testing, user interactions, state changes, material app setup. Use when writing widget tests, testing UI components, or validating widget behavior. --- # Widget Test Patterns ## Core Pattern Widget tests verify UI behavior: user interactions, state changes, and visual display. ## Basic Widget Test Setup ```dart testWidgets('widget displays correctly', (WidgetTester tester) async { // Arrange: Create widget awa
testing
--- name: test-template-generation description: Generates test templates: unit, widget, integration, service tests following project patterns. Use when creating new tests or ensuring tests follow project standards. --- # Test Template Generation ## Available Templates Test templates are located in `test/templates/`: - `unit_test_template.dart` - `widget_test_template.dart` - `integration_test_template.dart` - `service_test_template.dart` ## Unit Test Template ```dart /// SPOTS Component Uni