flutterflow-mcp 0.1.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.
Files changed (83) hide show
  1. package/README.md +124 -0
  2. package/build/api/flutterflow.d.ts +11 -0
  3. package/build/api/flutterflow.js +61 -0
  4. package/build/index.d.ts +2 -0
  5. package/build/index.js +54 -0
  6. package/build/prompts/dev-workflow.d.ts +2 -0
  7. package/build/prompts/dev-workflow.js +68 -0
  8. package/build/prompts/generate-page.d.ts +2 -0
  9. package/build/prompts/generate-page.js +36 -0
  10. package/build/prompts/inspect-project.d.ts +2 -0
  11. package/build/prompts/inspect-project.js +30 -0
  12. package/build/prompts/modify-component.d.ts +2 -0
  13. package/build/prompts/modify-component.js +39 -0
  14. package/build/resources/docs.d.ts +2 -0
  15. package/build/resources/docs.js +76 -0
  16. package/build/resources/projects.d.ts +3 -0
  17. package/build/resources/projects.js +60 -0
  18. package/build/tools/find-component-usages.d.ts +7 -0
  19. package/build/tools/find-component-usages.js +225 -0
  20. package/build/tools/find-page-navigations.d.ts +7 -0
  21. package/build/tools/find-page-navigations.js +228 -0
  22. package/build/tools/get-component-summary.d.ts +22 -0
  23. package/build/tools/get-component-summary.js +193 -0
  24. package/build/tools/get-page-by-name.d.ts +3 -0
  25. package/build/tools/get-page-by-name.js +56 -0
  26. package/build/tools/get-page-summary.d.ts +22 -0
  27. package/build/tools/get-page-summary.js +220 -0
  28. package/build/tools/get-yaml-docs.d.ts +6 -0
  29. package/build/tools/get-yaml-docs.js +217 -0
  30. package/build/tools/get-yaml.d.ts +3 -0
  31. package/build/tools/get-yaml.js +47 -0
  32. package/build/tools/list-files.d.ts +3 -0
  33. package/build/tools/list-files.js +30 -0
  34. package/build/tools/list-pages.d.ts +25 -0
  35. package/build/tools/list-pages.js +101 -0
  36. package/build/tools/list-projects.d.ts +3 -0
  37. package/build/tools/list-projects.js +19 -0
  38. package/build/tools/sync-project.d.ts +3 -0
  39. package/build/tools/sync-project.js +144 -0
  40. package/build/tools/update-yaml.d.ts +3 -0
  41. package/build/tools/update-yaml.js +24 -0
  42. package/build/tools/validate-yaml.d.ts +3 -0
  43. package/build/tools/validate-yaml.js +22 -0
  44. package/build/utils/cache.d.ts +48 -0
  45. package/build/utils/cache.js +162 -0
  46. package/build/utils/decode-yaml.d.ts +7 -0
  47. package/build/utils/decode-yaml.js +31 -0
  48. package/build/utils/page-summary/action-summarizer.d.ts +9 -0
  49. package/build/utils/page-summary/action-summarizer.js +291 -0
  50. package/build/utils/page-summary/formatter.d.ts +13 -0
  51. package/build/utils/page-summary/formatter.js +121 -0
  52. package/build/utils/page-summary/node-extractor.d.ts +17 -0
  53. package/build/utils/page-summary/node-extractor.js +207 -0
  54. package/build/utils/page-summary/tree-walker.d.ts +6 -0
  55. package/build/utils/page-summary/tree-walker.js +55 -0
  56. package/build/utils/page-summary/types.d.ts +56 -0
  57. package/build/utils/page-summary/types.js +4 -0
  58. package/build/utils/parse-folders.d.ts +9 -0
  59. package/build/utils/parse-folders.js +29 -0
  60. package/docs/ff-yaml/00-overview.md +137 -0
  61. package/docs/ff-yaml/01-project-files.md +513 -0
  62. package/docs/ff-yaml/02-pages.md +572 -0
  63. package/docs/ff-yaml/03-components.md +413 -0
  64. package/docs/ff-yaml/04-widgets/README.md +122 -0
  65. package/docs/ff-yaml/04-widgets/button.md +444 -0
  66. package/docs/ff-yaml/04-widgets/container.md +358 -0
  67. package/docs/ff-yaml/04-widgets/dropdown.md +579 -0
  68. package/docs/ff-yaml/04-widgets/form.md +256 -0
  69. package/docs/ff-yaml/04-widgets/image.md +276 -0
  70. package/docs/ff-yaml/04-widgets/layout.md +355 -0
  71. package/docs/ff-yaml/04-widgets/misc.md +553 -0
  72. package/docs/ff-yaml/04-widgets/text-field.md +326 -0
  73. package/docs/ff-yaml/04-widgets/text.md +302 -0
  74. package/docs/ff-yaml/05-actions.md +843 -0
  75. package/docs/ff-yaml/06-variables.md +834 -0
  76. package/docs/ff-yaml/07-data.md +591 -0
  77. package/docs/ff-yaml/08-custom-code.md +715 -0
  78. package/docs/ff-yaml/09-theming.md +592 -0
  79. package/docs/ff-yaml/10-editing-guide.md +454 -0
  80. package/docs/ff-yaml/README.md +105 -0
  81. package/package.json +55 -0
  82. package/skills/ff-widget-patterns.md +141 -0
  83. package/skills/ff-yaml-dev.md +58 -0
@@ -0,0 +1,715 @@
1
+ # Custom Code
2
+
3
+ FlutterFlow supports four types of custom code: **Custom Actions** (async Dart functions with side effects), **Custom Functions** (pure synchronous Dart functions), **Custom Widgets** (Flutter widgets with parameters), and **AI Agents** (LLM-powered processing pipelines). Additionally, **App Action Components** provide reusable action chains that can be invoked from any page.
4
+
5
+ ---
6
+
7
+ ## Custom Actions
8
+
9
+ Custom Actions are async Dart functions that can perform side effects (network calls, database writes, navigation, etc.). Each action has a YAML definition file and a companion Dart code file.
10
+
11
+ ### File layout
12
+
13
+ ```
14
+ custom-actions/
15
+ id-2qajc.yaml # Action definition (metadata, arguments, return type)
16
+ id-2qajc/
17
+ action-code.dart.yaml # Dart implementation code
18
+ ```
19
+
20
+ ### YAML definition
21
+
22
+ ```yaml
23
+ identifier:
24
+ name: getSymptomsForDay
25
+ key: 2qajc
26
+ arguments:
27
+ - identifier:
28
+ name: date
29
+ key: m0t714
30
+ dataType:
31
+ scalarType: DateTime
32
+ nonNullable: true
33
+ returnParameter:
34
+ identifier:
35
+ key: taftyf
36
+ dataType:
37
+ listType:
38
+ scalarType: String
39
+ nonNullable: true
40
+ includeContext: false
41
+ description: ""
42
+ ```
43
+
44
+ ### Definition fields
45
+
46
+ | Field | Required | Description |
47
+ |-------|----------|-------------|
48
+ | `identifier` | Yes | `name` (function name in Dart) and `key` (unique ID) |
49
+ | `arguments` | No | List of typed parameters passed to the action |
50
+ | `returnParameter` | No | Return type definition. Omit for void actions |
51
+ | `includeContext` | Yes | Whether `BuildContext` is passed as the first argument |
52
+ | `description` | No | Human-readable description |
53
+
54
+ ### Arguments format
55
+
56
+ Each argument has:
57
+
58
+ ```yaml
59
+ arguments:
60
+ - identifier:
61
+ name: email # Parameter name in Dart
62
+ key: 46tdix # Unique key
63
+ dataType:
64
+ scalarType: String # Type (any scalar type)
65
+ nonNullable: true # Whether the parameter is required
66
+ ```
67
+
68
+ ### Return parameter
69
+
70
+ The return parameter defines the action's return type:
71
+
72
+ ```yaml
73
+ returnParameter:
74
+ identifier:
75
+ key: taftyf # Unique key for the return value
76
+ dataType:
77
+ listType:
78
+ scalarType: String # Can be scalar, list, or complex type
79
+ nonNullable: true
80
+ ```
81
+
82
+ ### Dart code file
83
+
84
+ The companion file at `id-<key>/action-code.dart.yaml` contains the raw Dart implementation. The function signature matches the YAML definition:
85
+
86
+ ```dart
87
+ Future<List<String>> getSymptomsForDay(DateTime date) async {
88
+ try {
89
+ final userId = SupaFlow.client.auth.currentUser?.id;
90
+ if (userId == null) {
91
+ return [];
92
+ }
93
+
94
+ final dateStr =
95
+ '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
96
+
97
+ final response = await SupaFlow.client
98
+ .from('symptoms')
99
+ .select('name')
100
+ .eq('user_id', userId)
101
+ .eq('date', dateStr);
102
+
103
+ final List<dynamic> data = response ?? [];
104
+ final List<String> symptoms = [];
105
+
106
+ for (var row in data) {
107
+ if (row is Map<String, dynamic>) {
108
+ final name = row['name']?.toString();
109
+ if (name != null && name.isNotEmpty) {
110
+ symptoms.add(name);
111
+ }
112
+ }
113
+ }
114
+
115
+ return symptoms;
116
+ } catch (e) {
117
+ print('Error fetching symptoms for day: $e');
118
+ return [];
119
+ }
120
+ }
121
+ ```
122
+
123
+ ### Minimal action (no arguments, no return)
124
+
125
+ An action can have no arguments and no return value:
126
+
127
+ ```yaml
128
+ identifier:
129
+ name: revCatLogout
130
+ key: 97vdi
131
+ includeContext: false
132
+ description: ""
133
+ ```
134
+
135
+ ### Action with BuildContext
136
+
137
+ When `includeContext: true`, the Dart function receives `BuildContext` as its first parameter, enabling navigation, showing dialogs, and accessing inherited widgets:
138
+
139
+ ```yaml
140
+ identifier:
141
+ name: selectMediaWithSourceBottomSheetCustom
142
+ key: ho9d3
143
+ returnParameter:
144
+ identifier:
145
+ key: gquf0a
146
+ dataType:
147
+ scalarType: UploadedFile
148
+ nonNullable: false
149
+ includeContext: true
150
+ description: ""
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Custom Functions
156
+
157
+ Custom Functions are pure, synchronous Dart functions with no side effects. They are used for data transformation, formatting, and computation. Like actions, each function has a YAML definition and a Dart code file.
158
+
159
+ ### File layout
160
+
161
+ ```
162
+ custom-functions/
163
+ id-006vd.yaml # Function definition
164
+ id-006vd/
165
+ function-code.dart.yaml # Dart implementation code
166
+ ```
167
+
168
+ ### YAML definition
169
+
170
+ ```yaml
171
+ identifier:
172
+ name: getDateOnly
173
+ key: 006vd
174
+ arguments:
175
+ - identifier:
176
+ name: fullDateTime
177
+ key: zebhey
178
+ dataType:
179
+ scalarType: DateTime
180
+ nonNullable: false
181
+ returnParameter:
182
+ dataType:
183
+ scalarType: DateTime
184
+ nonNullable: false
185
+ ```
186
+
187
+ ### Key differences from Custom Actions
188
+
189
+ | Aspect | Custom Actions | Custom Functions |
190
+ |--------|---------------|-----------------|
191
+ | Async | Yes (`Future<T>`) | No (synchronous) |
192
+ | Side effects | Allowed | Not allowed (pure) |
193
+ | `includeContext` | Available | Not available |
194
+ | Dart code file | `action-code.dart.yaml` | `function-code.dart.yaml` |
195
+ | Return type identifier | Has `identifier.key` | No identifier on return |
196
+ | Use case | API calls, DB writes, navigation | Data transforms, formatting |
197
+
198
+ ### Return parameter (functions vs actions)
199
+
200
+ Functions have a simpler `returnParameter` without an `identifier` block:
201
+
202
+ ```yaml
203
+ # Custom Function return (no identifier)
204
+ returnParameter:
205
+ dataType:
206
+ scalarType: DateTime
207
+ nonNullable: false
208
+
209
+ # Custom Action return (has identifier with key)
210
+ returnParameter:
211
+ identifier:
212
+ key: taftyf
213
+ dataType:
214
+ listType:
215
+ scalarType: String
216
+ nonNullable: true
217
+ ```
218
+
219
+ ### Dart code file
220
+
221
+ The function code at `id-<key>/function-code.dart.yaml` contains only the function body (no signature wrapper):
222
+
223
+ ```dart
224
+
225
+ if (fullDateTime == null) {
226
+ return null;
227
+ }
228
+
229
+ return DateTime(
230
+ fullDateTime.year,
231
+ fullDateTime.month,
232
+ fullDateTime.day,
233
+ );
234
+ ```
235
+
236
+ Note: The function signature is generated from the YAML definition. The code file contains only the body.
237
+
238
+ ### Special scalar types in functions
239
+
240
+ Functions can use Supabase-specific types via `subType`:
241
+
242
+ ```yaml
243
+ identifier:
244
+ name: supabaseRowAsString
245
+ key: 1y1zx
246
+ arguments:
247
+ - identifier:
248
+ name: row
249
+ key: vy5lc3
250
+ dataType:
251
+ scalarType: PostgresRow
252
+ nonNullable: true
253
+ subType:
254
+ tableIdentifier:
255
+ name: food
256
+ returnParameter:
257
+ dataType:
258
+ scalarType: String
259
+ nonNullable: true
260
+ description: // Convert all values to strings and join with commas
261
+ ```
262
+
263
+ The `PostgresRow` scalar type uses `subType.tableIdentifier` to specify which Supabase table the row comes from.
264
+
265
+ ### List arguments and returns
266
+
267
+ Functions can accept and return lists:
268
+
269
+ ```yaml
270
+ identifier:
271
+ name: getFlexes
272
+ key: puab3
273
+ arguments:
274
+ - identifier:
275
+ name: ts
276
+ key: u4k7gx
277
+ dataType:
278
+ listType:
279
+ scalarType: Integer
280
+ nonNullable: true
281
+ returnParameter:
282
+ dataType:
283
+ listType:
284
+ scalarType: Integer
285
+ nonNullable: true
286
+ ```
287
+
288
+ ### Test definitions
289
+
290
+ Functions can include test cases for the FlutterFlow test runner:
291
+
292
+ ```yaml
293
+ identifier:
294
+ name: getIngredientsAsJson
295
+ key: 489er
296
+ arguments:
297
+ - identifier:
298
+ name: ingredients
299
+ key: x6twxl
300
+ dataType:
301
+ listType:
302
+ scalarType: String
303
+ nonNullable: false
304
+ returnParameter:
305
+ dataType:
306
+ scalarType: JSON
307
+ tests:
308
+ - parameterValues:
309
+ values:
310
+ x6twxl: "[\"apple\",\"sugar\",\"water\"]"
311
+ ```
312
+
313
+ Each test entry contains `parameterValues.values` mapping argument keys to serialized test values.
314
+
315
+ ---
316
+
317
+ ## Custom Widgets
318
+
319
+ Custom Widgets are Flutter widgets defined with typed parameters. They live under `custom-widgets/id-<key>.yaml`.
320
+
321
+ ### YAML definition
322
+
323
+ ```yaml
324
+ identifier:
325
+ name: SmartDateXAxis
326
+ key: exs5d
327
+ parameters:
328
+ - identifier:
329
+ name: dimensions
330
+ key: k4tdyl
331
+ dataType:
332
+ scalarType: WidgetProperty
333
+ subType:
334
+ widgetPropertyType: DIMENSIONS
335
+ - identifier:
336
+ name: timestamps
337
+ key: g66qo8
338
+ dataType:
339
+ listType:
340
+ scalarType: Integer
341
+ nonNullable: true
342
+ - identifier:
343
+ name: maxLabels
344
+ key: c1b1qp
345
+ dataType:
346
+ scalarType: Integer
347
+ nonNullable: true
348
+ description: ""
349
+ ```
350
+
351
+ ### Parameters
352
+
353
+ Widget parameters use the same `dataType` system as other definitions, plus widget-specific types:
354
+
355
+ | Type | Description |
356
+ |------|-------------|
357
+ | `WidgetProperty` with `widgetPropertyType: DIMENSIONS` | Width/height constraints from the parent |
358
+ | `Action` | Callback that triggers a FlutterFlow action chain |
359
+ | Standard scalars | `String`, `Integer`, `Boolean`, `DateTime`, `Double`, etc. |
360
+ | List types | `listType` with any scalar |
361
+
362
+ ### Callback parameters with nested params
363
+
364
+ The `Action` scalar type supports `nestedParams` -- values that the widget passes back to the action chain when the callback fires:
365
+
366
+ ```yaml
367
+ identifier:
368
+ name: VerticalCalendar
369
+ key: 7svm8
370
+ parameters:
371
+ - identifier:
372
+ name: dimensions
373
+ key: 5f7c90
374
+ dataType:
375
+ scalarType: WidgetProperty
376
+ nonNullable: true
377
+ subType:
378
+ widgetPropertyType: DIMENSIONS
379
+ - identifier:
380
+ name: startDate
381
+ key: bw48jf
382
+ dataType:
383
+ scalarType: DateTime
384
+ nonNullable: true
385
+ - identifier:
386
+ name: endDate
387
+ key: 0u8o42
388
+ dataType:
389
+ scalarType: DateTime
390
+ nonNullable: true
391
+ - identifier:
392
+ name: onAddButtonTapped
393
+ key: bins86
394
+ dataType:
395
+ scalarType: Action
396
+ nonNullable: true
397
+ nestedParams:
398
+ - identifier:
399
+ name: date
400
+ key: rr2oy1
401
+ dataType:
402
+ scalarType: DateTime
403
+ nonNullable: true
404
+ - identifier:
405
+ name: symptoms
406
+ key: 0fkgnr
407
+ dataType:
408
+ listType:
409
+ scalarType: String
410
+ nonNullable: true
411
+ - identifier:
412
+ name: onSymptomTapped
413
+ key: oxwyhs
414
+ dataType:
415
+ scalarType: Action
416
+ nonNullable: false
417
+ nestedParams:
418
+ - identifier:
419
+ name: symptomName
420
+ dataType:
421
+ scalarType: String
422
+ nonNullable: true
423
+ - identifier:
424
+ name: date
425
+ key: 1nn0ds
426
+ dataType:
427
+ scalarType: DateTime
428
+ nonNullable: true
429
+ previewValues: {}
430
+ description: ""
431
+ ```
432
+
433
+ ### Nested params structure
434
+
435
+ Each nested param in an `Action` callback:
436
+
437
+ | Property | Required | Description |
438
+ |----------|----------|-------------|
439
+ | `identifier.name` | Yes | Parameter name passed back from the widget |
440
+ | `identifier.key` | No | Unique key (sometimes omitted) |
441
+ | `dataType` | Yes | Type of the passed-back value |
442
+
443
+ These nested params are available in the FlutterFlow action editor as callback outputs when wiring up the widget's action.
444
+
445
+ ---
446
+
447
+ ## AI Agents
448
+
449
+ AI Agents define LLM-powered processing pipelines. They live under `agent/id-<key>.yaml`.
450
+
451
+ ### YAML definition
452
+
453
+ ```yaml
454
+ status: LIVE
455
+ identifier:
456
+ name: correlatorFoodSymptoms
457
+ key: pb2xn
458
+ name: CorrelatorFoodSymptoms
459
+ description: Correlates food with symptoms.
460
+ aiModel:
461
+ provider: GOOGLE
462
+ model: gemini-2.0-flash
463
+ parameters:
464
+ temperature:
465
+ inputValue: 1
466
+ maxTokens:
467
+ inputValue: 8192
468
+ topP:
469
+ inputValue: 0.95
470
+ messages:
471
+ - role: SYSTEM
472
+ text: "Act as an expert in nutrition..."
473
+ requestOptions:
474
+ requestTypes:
475
+ - PLAINTEXT
476
+ responseOptions:
477
+ responseType: JSON
478
+ ```
479
+
480
+ ### Top-level fields
481
+
482
+ | Field | Required | Description |
483
+ |-------|----------|-------------|
484
+ | `status` | Yes | `LIVE` or `DRAFT` |
485
+ | `identifier` | Yes | Internal `name` and `key` |
486
+ | `name` | Yes | Display name for the agent |
487
+ | `description` | Yes | Human-readable description |
488
+ | `aiModel` | Yes | Model configuration block |
489
+ | `requestOptions` | Yes | Accepted input types |
490
+ | `responseOptions` | Yes | Expected output format |
491
+
492
+ ### AI model configuration
493
+
494
+ ```yaml
495
+ aiModel:
496
+ provider: GOOGLE # Provider: GOOGLE, OPENAI, ANTHROPIC
497
+ model: gemini-2.0-flash # Specific model identifier
498
+ parameters:
499
+ temperature:
500
+ inputValue: 1 # Creativity (0-2)
501
+ maxTokens:
502
+ inputValue: 8192 # Maximum response tokens
503
+ topP:
504
+ inputValue: 0.95 # Nucleus sampling
505
+ messages:
506
+ - role: SYSTEM # SYSTEM or USER
507
+ text: "System prompt text..."
508
+ ```
509
+
510
+ ### Request options
511
+
512
+ Defines what input types the agent accepts:
513
+
514
+ ```yaml
515
+ requestOptions:
516
+ requestTypes:
517
+ - PLAINTEXT # Accept text input
518
+ - IMAGE # Accept image input
519
+ ```
520
+
521
+ ### Response options
522
+
523
+ Defines the expected output format:
524
+
525
+ ```yaml
526
+ responseOptions:
527
+ responseType: JSON # JSON or PLAINTEXT
528
+ ```
529
+
530
+ ### Multi-modal agent example
531
+
532
+ An agent that accepts both text and image input:
533
+
534
+ ```yaml
535
+ status: LIVE
536
+ identifier:
537
+ name: ingredientsExtractor
538
+ key: ysf2z
539
+ name: Ingredients extractor
540
+ description: "Extracts ingredients from a photo."
541
+ aiModel:
542
+ provider: GOOGLE
543
+ model: gemini-2.0-flash
544
+ parameters:
545
+ temperature:
546
+ inputValue: 1
547
+ maxTokens:
548
+ inputValue: 8192
549
+ topP:
550
+ inputValue: 0.95
551
+ messages:
552
+ - role: SYSTEM
553
+ text: "Act as an ingredients extractor..."
554
+ requestOptions:
555
+ requestTypes:
556
+ - PLAINTEXT
557
+ - IMAGE
558
+ responseOptions:
559
+ responseType: JSON
560
+ ```
561
+
562
+ ---
563
+
564
+ ## App Action Components
565
+
566
+ App Action Components are reusable action chains that can be invoked from any page or component. They live under `app-action-components/id-<key>.yaml`.
567
+
568
+ ### YAML definition
569
+
570
+ ```yaml
571
+ identifier:
572
+ name: checkUpdateBlock
573
+ key: ld3jo3
574
+ actions:
575
+ rootAction:
576
+ key: dmm3dw7g
577
+ action:
578
+ customAction:
579
+ customActionIdentifier:
580
+ name: checkAppUpdateStatus
581
+ key: zjg1l
582
+ argumentValues:
583
+ arguments:
584
+ fr6rim:
585
+ value:
586
+ variable:
587
+ source: FIREBASE_AUTH_USER
588
+ baseVariable:
589
+ auth:
590
+ property: USERS_DATA_FIELD
591
+ usersDataField:
592
+ name: app_version
593
+ wmmt5g:
594
+ value:
595
+ variable:
596
+ source: FUNCTION_CALL
597
+ functionCall:
598
+ conditionalValue:
599
+ ifConditionalValues:
600
+ - condition:
601
+ source: GLOBAL_PROPERTIES
602
+ baseVariable:
603
+ globalProperties:
604
+ property: IS_IOS
605
+ value:
606
+ variable:
607
+ source: FIREBASE_REMOTE_CONFIG
608
+ baseVariable:
609
+ firebaseRemoteConfig:
610
+ fieldIdentifier:
611
+ name: newiOSVersion
612
+ elseValue:
613
+ variable:
614
+ source: FIREBASE_REMOTE_CONFIG
615
+ baseVariable:
616
+ firebaseRemoteConfig:
617
+ fieldIdentifier:
618
+ name: newAndroidVersion
619
+ returnParameter:
620
+ identifier:
621
+ name: newVersion
622
+ key: wmmt5g
623
+ dataType:
624
+ scalarType: String
625
+ nonNullable: true
626
+ outputVariableName: updateState
627
+ key: 00tn7yxo
628
+ followUpAction:
629
+ key: isp97zrh
630
+ conditionActions:
631
+ trueActions:
632
+ - condition:
633
+ # ... condition checking action output against enum value
634
+ trueAction:
635
+ key: g4iwdyck
636
+ action:
637
+ alertDialog:
638
+ customDialog:
639
+ passedParameters:
640
+ parameterPasses:
641
+ 3p0j01:
642
+ paramIdentifier:
643
+ name: showIgnore
644
+ key: 3p0j01
645
+ inputValue:
646
+ serializedValue: "false"
647
+ widgetClassNodeKeyRef:
648
+ key: Container_gtqk3kbu
649
+ dimensions:
650
+ width:
651
+ percentOfScreenSizeValue:
652
+ inputValue: 80
653
+ nonDismissible: true
654
+ isGlobal: true
655
+ description: ""
656
+ ```
657
+
658
+ ### Structure
659
+
660
+ | Field | Required | Description |
661
+ |-------|----------|-------------|
662
+ | `identifier` | Yes | `name` and `key` for the reusable action |
663
+ | `actions.rootAction` | Yes | The first action in the chain |
664
+ | `actions.rootAction.followUpAction` | No | Chained actions after the root |
665
+ | `description` | No | Human-readable description |
666
+
667
+ ### Action chain pattern
668
+
669
+ App Action Components follow the same action chain pattern used in page actions:
670
+
671
+ 1. **`rootAction`** -- The entry point action, typically a `customAction` call or built-in action
672
+ 2. **`outputVariableName`** -- Stores the action's return value for use in follow-up conditions
673
+ 3. **`followUpAction`** -- Conditional or sequential actions that run after the root
674
+
675
+ ### Variable sources used in action components
676
+
677
+ Action components can reference values from many sources:
678
+
679
+ | Source | Description | Example |
680
+ |--------|-------------|---------|
681
+ | `FIREBASE_AUTH_USER` | Authenticated user data | `auth.property: USERS_DATA_FIELD` |
682
+ | `FIREBASE_REMOTE_CONFIG` | Remote config values | `firebaseRemoteConfig.fieldIdentifier.name` |
683
+ | `GLOBAL_PROPERTIES` | Platform checks | `globalProperties.property: IS_IOS` |
684
+ | `ACTION_OUTPUTS` | Previous action results | `actionOutput.outputVariableIdentifier` |
685
+ | `ENUMS` | Enum value references | `enumVariable.enumIdentifier` |
686
+ | `FUNCTION_CALL` | Inline function evaluation | `functionCall.conditionalValue` |
687
+
688
+ ### Referencing action components from pages
689
+
690
+ Action components are referenced by their `key` when invoked. The output of a root action within a component is accessed via `actionComponentKeyRef`:
691
+
692
+ ```yaml
693
+ variable:
694
+ source: ACTION_OUTPUTS
695
+ baseVariable:
696
+ actionOutput:
697
+ outputVariableIdentifier:
698
+ name: updateState
699
+ actionKeyRef:
700
+ key: 00tn7yxo
701
+ actionComponentKeyRef:
702
+ key: ld3jo3 # References the app action component
703
+ ```
704
+
705
+ ---
706
+
707
+ ## File Key Patterns Summary
708
+
709
+ | Code type | Definition file | Code file | Directory |
710
+ |-----------|----------------|-----------|-----------|
711
+ | Custom Action | `custom-actions/id-<key>.yaml` | `custom-actions/id-<key>/action-code.dart.yaml` | `custom-actions/` |
712
+ | Custom Function | `custom-functions/id-<key>.yaml` | `custom-functions/id-<key>/function-code.dart.yaml` | `custom-functions/` |
713
+ | Custom Widget | `custom-widgets/id-<key>.yaml` | (code embedded or separate) | `custom-widgets/` |
714
+ | AI Agent | `agent/id-<key>.yaml` | N/A (no code file) | `agent/` |
715
+ | App Action Component | `app-action-components/id-<key>.yaml` | N/A (actions are inline) | `app-action-components/` |