@appiq/flutter-workflow 1.2.0 โ†’ 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -54,7 +54,8 @@ const AGENTS = [
54
54
  'domain-agent',
55
55
  'data-agent',
56
56
  'security-agent',
57
- 'test-agent'
57
+ 'test-agent',
58
+ 'initial-flow-agent'
58
59
  ];
59
60
 
60
61
  program
@@ -144,6 +145,27 @@ program
144
145
  const featuresDir = path.join(docsDir, 'features');
145
146
  await fs.ensureDir(featuresDir);
146
147
 
148
+ // Copy additional requirement templates
149
+ const templatesDir = path.join(__dirname, '../templates');
150
+ const targetTemplatesDir = path.join(currentDir, 'docs', 'additional_requirements');
151
+ await fs.ensureDir(targetTemplatesDir);
152
+
153
+ const additionalTemplates = [
154
+ 'additional_ui_req.md',
155
+ 'additional_cubit_req.md',
156
+ 'additional_domain_req.md',
157
+ 'additional_data_req.md'
158
+ ];
159
+
160
+ for (const template of additionalTemplates) {
161
+ const sourceTemplate = path.join(templatesDir, template);
162
+ const targetTemplate = path.join(targetTemplatesDir, template);
163
+
164
+ if (await fs.pathExists(sourceTemplate)) {
165
+ await fs.copy(sourceTemplate, targetTemplate);
166
+ }
167
+ }
168
+
147
169
  // Create sample feature documentation
148
170
  const sampleFeatureContent = `---
149
171
  name: SampleFeature
@@ -152,6 +174,7 @@ domain: open
152
174
  data: open
153
175
  security: open
154
176
  test: open
177
+ initial_flow: open
155
178
  status: open
156
179
  ---
157
180
 
@@ -168,6 +191,20 @@ Describe your feature here. This will be analyzed by the PO Agent to create deta
168
191
  - Any technical considerations
169
192
  - Dependencies
170
193
  - Performance requirements
194
+
195
+ ## Additional Requirements
196
+ After basic implementation, you can use additional requirement templates:
197
+ - docs/additional_requirements/additional_ui_req.md - Role-based UI and access control
198
+ - docs/additional_requirements/additional_cubit_req.md - Advanced state management and provider setup
199
+ - docs/additional_requirements/additional_domain_req.md - Complex business rules and domain logic
200
+ - docs/additional_requirements/additional_data_req.md - Supabase MCP integration and advanced data patterns
201
+
202
+ ## Integration Setup
203
+ Use the Initial Flow Agent for:
204
+ - Dependency injection configuration
205
+ - Provider setup and initialization
206
+ - Integration testing and validation
207
+ - Error prevention and troubleshooting
171
208
  `;
172
209
 
173
210
  await fs.writeFile(
@@ -189,6 +226,7 @@ Describe your feature here. This will be analyzed by the PO Agent to create deta
189
226
 
190
227
  console.log(chalk.gray('\\n๐Ÿ“ Created directories:'));
191
228
  console.log(chalk.gray(' ๐Ÿ“„ docs/features/ - Feature documentation and status tracking'));
229
+ console.log(chalk.gray(' ๐Ÿ“‹ docs/additional_requirements/ - Advanced requirement templates'));
192
230
 
193
231
  console.log(chalk.bold.yellow('\\n๐Ÿš€ Next Steps:'));
194
232
  console.log(chalk.gray('1. Create your feature documentation in docs/features/'));
@@ -204,6 +242,7 @@ Describe your feature here. This will be analyzed by the PO Agent to create deta
204
242
  console.log(chalk.gray(' ๐Ÿ—„๏ธ Data Agent - Backend integration specialist'));
205
243
  console.log(chalk.gray(' ๐Ÿ” Security Agent - Security and compliance expert'));
206
244
  console.log(chalk.gray(' ๐Ÿงช Test Agent - Testing pyramid implementation'));
245
+ console.log(chalk.gray(' ๐Ÿš€ Initial Flow Agent - Provider setup and integration specialist'));
207
246
 
208
247
  } catch (error) {
209
248
  console.error(chalk.red('โŒ Installation failed:'), error.message);
@@ -292,6 +331,7 @@ domain: open
292
331
  data: open
293
332
  security: open
294
333
  test: open
334
+ initial_flow: open
295
335
  status: open
296
336
  ---
297
337
 
@@ -322,6 +362,19 @@ As a [user type], I want [functionality] so that [benefit].
322
362
  - UI/UX requirements
323
363
  - Screen designs
324
364
  - User flow
365
+
366
+ ## Additional Requirements (Optional)
367
+ Use these templates after basic implementation for advanced features:
368
+ - docs/additional_requirements/additional_ui_req.md - Role-based access control
369
+ - docs/additional_requirements/additional_cubit_req.md - Advanced state management
370
+ - docs/additional_requirements/additional_domain_req.md - Complex business logic
371
+ - docs/additional_requirements/additional_data_req.md - Supabase MCP integration
372
+
373
+ ## Integration Setup
374
+ After implementation, use Initial Flow Agent for:
375
+ - Complete dependency injection setup
376
+ - Provider hierarchy configuration
377
+ - Integration testing and validation
325
378
  `;
326
379
 
327
380
  const fileName = name.toLowerCase().replace(/[^a-z0-9]/gi, '-');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@appiq/flutter-workflow",
3
- "version": "1.2.0",
4
- "description": "๐Ÿš€ Professional Flutter development with AI-powered agents following Clean Architecture principles - Automated agent-based feature development system by AppIQ Solutions",
3
+ "version": "1.3.0",
4
+ "description": "๐Ÿš€ [BETA] Professional Flutter development with AI-powered agents following Clean Architecture principles - Automated agent-based feature development system by AppIQ Solutions",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
7
7
  "appiq-workflow": "bin/cli.js"
@@ -0,0 +1,357 @@
1
+ # Additional Cubit Requirements - State Management Integration
2
+
3
+ This template defines additional state management requirements, provider setup, and integration patterns for your feature.
4
+
5
+ ## State Management Architecture
6
+
7
+ ### Cubit Integration Pattern
8
+ ```dart
9
+ // Feature-specific state management structure
10
+ lib/features/{feature}/presentation/cubit/
11
+ โ”œโ”€โ”€ {feature}_cubit.dart // Main cubit implementation
12
+ โ”œโ”€โ”€ {feature}_state.dart // State definitions
13
+ โ””โ”€โ”€ {feature}_event.dart // Events (if using BLoC pattern)
14
+ ```
15
+
16
+ ### Global State Dependencies
17
+ - [ ] Authentication state integration
18
+ - [ ] User role state management
19
+ - [ ] Theme/settings state access
20
+ - [ ] Navigation state coordination
21
+ - [ ] Network connectivity state
22
+ - [ ] Offline/online state management
23
+
24
+ ## Provider Setup Requirements
25
+
26
+ ### Main App Provider Configuration
27
+ ```dart
28
+ // Add to main.dart MultiBlocProvider
29
+ MultiBlocProvider(
30
+ providers: [
31
+ // Existing providers...
32
+ BlocProvider<{Feature}Cubit>(
33
+ create: (context) => GetIt.instance<{Feature}Cubit>(),
34
+ ),
35
+ // Additional feature dependencies...
36
+ ],
37
+ child: MyApp(),
38
+ )
39
+ ```
40
+
41
+ ### Dependency Injection Setup
42
+ ```dart
43
+ // Add to dependency injection configuration
44
+ void configureDependencies() {
45
+ // Repository registration
46
+ getIt.registerLazySingleton<{Feature}Repository>(
47
+ () => {Feature}RepositoryImpl(
48
+ remoteDataSource: getIt(),
49
+ localDataSource: getIt(),
50
+ networkInfo: getIt(),
51
+ ),
52
+ );
53
+
54
+ // Use case registration
55
+ getIt.registerLazySingleton(() => Get{Feature}UseCase(getIt()));
56
+ getIt.registerLazySingleton(() => Create{Feature}UseCase(getIt()));
57
+ getIt.registerLazySingleton(() => Update{Feature}UseCase(getIt()));
58
+ getIt.registerLazySingleton(() => Delete{Feature}UseCase(getIt()));
59
+
60
+ // Cubit registration
61
+ getIt.registerFactory<{Feature}Cubit>(
62
+ () => {Feature}Cubit(
63
+ get{Feature}UseCase: getIt(),
64
+ create{Feature}UseCase: getIt(),
65
+ update{Feature}UseCase: getIt(),
66
+ delete{Feature}UseCase: getIt(),
67
+ ),
68
+ );
69
+ }
70
+ ```
71
+
72
+ ## State Initialization Requirements
73
+
74
+ ### Initial State Setup
75
+ ```dart
76
+ class {Feature}Cubit extends Cubit<{Feature}State> {
77
+ {Feature}Cubit({
78
+ required this.get{Feature}UseCase,
79
+ required this.create{Feature}UseCase,
80
+ required this.update{Feature}UseCase,
81
+ required this.delete{Feature}UseCase,
82
+ }) : super(const {Feature}State.initial());
83
+
84
+ // Initialize feature data on cubit creation
85
+ Future<void> initialize() async {
86
+ emit(state.copyWith(status: {Feature}Status.loading));
87
+
88
+ try {
89
+ final result = await get{Feature}UseCase.call(NoParams());
90
+ result.fold(
91
+ (failure) => emit(state.copyWith(
92
+ status: {Feature}Status.error,
93
+ errorMessage: failure.message,
94
+ )),
95
+ (data) => emit(state.copyWith(
96
+ status: {Feature}Status.loaded,
97
+ items: data,
98
+ )),
99
+ );
100
+ } catch (e) {
101
+ emit(state.copyWith(
102
+ status: {Feature}Status.error,
103
+ errorMessage: 'Unexpected error occurred',
104
+ ));
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### Widget Integration Pattern
111
+ ```dart
112
+ class {Feature}Page extends StatefulWidget {
113
+ @override
114
+ _State createState() => _State();
115
+ }
116
+
117
+ class _State extends State<{Feature}Page> {
118
+ late {Feature}Cubit cubit;
119
+
120
+ @override
121
+ void initState() {
122
+ super.initState();
123
+ cubit = context.read<{Feature}Cubit>();
124
+ // Initialize cubit data
125
+ cubit.initialize();
126
+ }
127
+
128
+ @override
129
+ Widget build(BuildContext context) {
130
+ return BlocConsumer<{Feature}Cubit, {Feature}State>(
131
+ listener: (context, state) {
132
+ // Handle side effects (navigation, snackbars, etc.)
133
+ if (state.status == {Feature}Status.error) {
134
+ ScaffoldMessenger.of(context).showSnackBar(
135
+ SnackBar(content: Text(state.errorMessage ?? 'Error occurred')),
136
+ );
137
+ }
138
+ },
139
+ builder: (context, state) {
140
+ return Scaffold(
141
+ body: _buildBody(state),
142
+ );
143
+ },
144
+ );
145
+ }
146
+ }
147
+ ```
148
+
149
+ ## Common Integration Issues & Solutions
150
+
151
+ ### Issue 1: Cubit Not Initialized
152
+ **Problem**: `BlocProvider.of() called with a context that does not contain a Cubit`
153
+ **Solution**:
154
+ ```dart
155
+ // Ensure proper provider hierarchy
156
+ MaterialApp(
157
+ home: MultiBlocProvider(
158
+ providers: [
159
+ BlocProvider<{Feature}Cubit>(
160
+ create: (context) => GetIt.instance<{Feature}Cubit>(),
161
+ ),
162
+ ],
163
+ child: {Feature}Page(),
164
+ ),
165
+ )
166
+ ```
167
+
168
+ ### Issue 2: Duplicate Cubit Registration
169
+ **Problem**: Multiple registrations of the same cubit type
170
+ **Solution**:
171
+ ```dart
172
+ // Use registerFactory for cubits (new instance per request)
173
+ getIt.registerFactory<{Feature}Cubit>(() => {Feature}Cubit(...));
174
+
175
+ // Or check if already registered
176
+ if (!getIt.isRegistered<{Feature}Cubit>()) {
177
+ getIt.registerFactory<{Feature}Cubit>(() => {Feature}Cubit(...));
178
+ }
179
+ ```
180
+
181
+ ### Issue 3: State Not Persisting Across Navigation
182
+ **Problem**: State resets when navigating between screens
183
+ **Solution**:
184
+ ```dart
185
+ // Use singleton registration for state that should persist
186
+ getIt.registerLazySingleton<{Feature}Cubit>(() => {Feature}Cubit(...));
187
+
188
+ // Or use global provider at app level
189
+ class MyApp extends StatelessWidget {
190
+ @override
191
+ Widget build(BuildContext context) {
192
+ return MultiBlocProvider(
193
+ providers: [
194
+ BlocProvider<{Feature}Cubit>(
195
+ create: (context) => GetIt.instance<{Feature}Cubit>(),
196
+ ),
197
+ ],
198
+ child: MaterialApp(...),
199
+ );
200
+ }
201
+ }
202
+ ```
203
+
204
+ ## Cross-Feature State Communication
205
+
206
+ ### Feature-to-Feature State Updates
207
+ ```dart
208
+ class {Feature}Cubit extends Cubit<{Feature}State> {
209
+ final AuthenticationCubit authCubit;
210
+ final UserRoleCubit userRoleCubit;
211
+ late StreamSubscription authSubscription;
212
+
213
+ {Feature}Cubit({
214
+ required this.authCubit,
215
+ required this.userRoleCubit,
216
+ // ... other dependencies
217
+ }) : super(const {Feature}State.initial()) {
218
+ // Listen to authentication changes
219
+ authSubscription = authCubit.stream.listen((authState) {
220
+ if (authState is! AuthenticatedState) {
221
+ // Clear feature data on logout
222
+ emit(const {Feature}State.initial());
223
+ }
224
+ });
225
+ }
226
+
227
+ @override
228
+ Future<void> close() {
229
+ authSubscription.cancel();
230
+ return super.close();
231
+ }
232
+ }
233
+ ```
234
+
235
+ ### Global State Access Pattern
236
+ ```dart
237
+ // Access other cubits from within a cubit
238
+ void updateBasedOnUserRole() {
239
+ final userRole = userRoleCubit.state.role;
240
+
241
+ switch (userRole) {
242
+ case UserRole.admin:
243
+ loadAdminData();
244
+ break;
245
+ case UserRole.manager:
246
+ loadManagerData();
247
+ break;
248
+ case UserRole.user:
249
+ loadUserData();
250
+ break;
251
+ }
252
+ }
253
+ ```
254
+
255
+ ## Performance Optimization
256
+
257
+ ### Selective State Updates
258
+ ```dart
259
+ // Use copyWith efficiently to avoid unnecessary rebuilds
260
+ emit(state.copyWith(
261
+ status: {Feature}Status.loading,
262
+ // Only update changed fields
263
+ ));
264
+
265
+ // Use state comparison to prevent duplicate emissions
266
+ void updateItems(List<{Entity}> newItems) {
267
+ if (!listEquals(state.items, newItems)) {
268
+ emit(state.copyWith(items: newItems));
269
+ }
270
+ }
271
+ ```
272
+
273
+ ### Memory Management
274
+ ```dart
275
+ class {Feature}Cubit extends Cubit<{Feature}State> {
276
+ final List<StreamSubscription> _subscriptions = [];
277
+
278
+ void addSubscription(StreamSubscription subscription) {
279
+ _subscriptions.add(subscription);
280
+ }
281
+
282
+ @override
283
+ Future<void> close() {
284
+ // Cancel all subscriptions
285
+ for (final subscription in _subscriptions) {
286
+ subscription.cancel();
287
+ }
288
+ _subscriptions.clear();
289
+ return super.close();
290
+ }
291
+ }
292
+ ```
293
+
294
+ ## Testing Integration
295
+
296
+ ### Cubit Testing Setup
297
+ ```dart
298
+ // Test setup with proper mocking
299
+ class MockAuthCubit extends MockCubit<AuthState> implements AuthCubit {}
300
+ class MockUserRoleCubit extends MockCubit<UserRoleState> implements UserRoleCubit {}
301
+
302
+ void main() {
303
+ late {Feature}Cubit cubit;
304
+ late MockAuthCubit mockAuthCubit;
305
+ late MockUserRoleCubit mockUserRoleCubit;
306
+
307
+ setUp(() {
308
+ mockAuthCubit = MockAuthCubit();
309
+ mockUserRoleCubit = MockUserRoleCubit();
310
+
311
+ cubit = {Feature}Cubit(
312
+ authCubit: mockAuthCubit,
313
+ userRoleCubit: mockUserRoleCubit,
314
+ // ... other dependencies
315
+ );
316
+ });
317
+
318
+ tearDown(() {
319
+ cubit.close();
320
+ });
321
+ }
322
+ ```
323
+
324
+ ## Integration Checklist
325
+
326
+ ### Provider Setup
327
+ - [ ] Cubit registered in dependency injection
328
+ - [ ] Provider added to MultiBlocProvider
329
+ - [ ] Dependencies properly injected
330
+ - [ ] Initialization logic implemented
331
+
332
+ ### State Management
333
+ - [ ] Initial state properly defined
334
+ - [ ] State transitions implemented
335
+ - [ ] Error handling added
336
+ - [ ] Loading states managed
337
+
338
+ ### Cross-Feature Integration
339
+ - [ ] Authentication state integration
340
+ - [ ] User role state access
341
+ - [ ] Global state dependencies resolved
342
+ - [ ] Navigation state coordination
343
+
344
+ ### Performance & Memory
345
+ - [ ] Efficient state updates implemented
346
+ - [ ] Memory leaks prevented (subscriptions canceled)
347
+ - [ ] Unnecessary rebuilds minimized
348
+ - [ ] State persistence strategy defined
349
+
350
+ ### Testing
351
+ - [ ] Unit tests for cubit logic
352
+ - [ ] Integration tests with providers
353
+ - [ ] Mock implementations for dependencies
354
+ - [ ] Error scenario testing
355
+
356
+ ## Notes
357
+ Add any feature-specific state management requirements, custom integration patterns, or special initialization needs.