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,843 @@
1
+ # Actions
2
+
3
+ Actions define the behavior triggered by user interactions or lifecycle events in FlutterFlow. Each action is stored as an individual YAML file inside a widget node's `trigger_actions/` directory.
4
+
5
+ ---
6
+
7
+ ## File Location Pattern
8
+
9
+ Actions follow a strict directory hierarchy:
10
+
11
+ ```
12
+ page/id-Scaffold_{id}/
13
+ page-widget-tree-outline/
14
+ node/id-{Widget}_{id}/
15
+ trigger_actions/
16
+ id-{TRIGGER_TYPE}/ # Trigger YAML file (orchestrator)
17
+ action/
18
+ id-{actionKey}.yaml # Individual action files
19
+ ```
20
+
21
+ For components the path mirrors pages:
22
+
23
+ ```
24
+ component/id-Container_{id}/
25
+ component-widget-tree-outline/
26
+ node/id-{Widget}_{id}/
27
+ trigger_actions/
28
+ id-{TRIGGER_TYPE}/
29
+ action/
30
+ id-{actionKey}.yaml
31
+ ```
32
+
33
+ Each trigger directory contains:
34
+ - A **trigger YAML file** (`id-ON_TAP.yaml`) that defines the `rootAction` tree -- the execution order, conditional branching, and references to action keys
35
+ - An **`action/` subdirectory** with one YAML file per action, each keyed by its unique action ID
36
+
37
+ ---
38
+
39
+ ## Trigger Types
40
+
41
+ | Trigger | Directory Name | When It Fires |
42
+ |---|---|---|
43
+ | `ON_TAP` | `id-ON_TAP` | Widget tapped |
44
+ | `ON_INIT_STATE` | `id-ON_INIT_STATE` | Page or component initializes |
45
+ | `ON_TEXTFIELD_CHANGE` | `id-ON_TEXTFIELD_CHANGE` | TextField value changes |
46
+ | `ON_TOGGLE_ON` | `id-ON_TOGGLE_ON` | Switch/toggle turned on |
47
+ | `ON_TOGGLE_OFF` | `id-ON_TOGGLE_OFF` | Switch/toggle turned off |
48
+ | `ON_LONG_PRESS` | `id-ON_LONG_PRESS` | Widget long-pressed |
49
+ | `ON_TIMER_END` | `id-ON_TIMER_END` | Timer widget completes |
50
+ | `CALLBACK-{id}` | `id-CALLBACK-{id}` | Named callback from parent component |
51
+
52
+ ---
53
+
54
+ ## Trigger YAML Structure
55
+
56
+ The trigger file (`id-ON_TAP.yaml`) defines execution order using a `rootAction` tree. Each node in the tree references action files by `key`:
57
+
58
+ ```yaml
59
+ rootAction:
60
+ key: 5ycxygcz
61
+ action:
62
+ key: qsw0br81 # References action/id-qsw0br81.yaml
63
+ followUpAction:
64
+ key: jmvd96i3
65
+ action:
66
+ key: 54wwjscn # Next action in sequence
67
+ trigger:
68
+ triggerType: ON_TAP
69
+ ```
70
+
71
+ Simple trigger (single action, no chaining):
72
+
73
+ ```yaml
74
+ rootAction:
75
+ key: 2xwagsw6
76
+ action:
77
+ key: 2b2dwjgo
78
+ trigger:
79
+ triggerType: ON_TAP
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Action Types
85
+
86
+ ### `navigate` -- Navigate to Page
87
+
88
+ Navigates to another page, optionally passing parameters.
89
+
90
+ ```yaml
91
+ navigate:
92
+ allowBack: true
93
+ replaceRoute: false
94
+ isNavigateBack: false
95
+ pageNodeKeyRef:
96
+ key: Scaffold_r4acaui6
97
+ passedParameters:
98
+ parameterPasses:
99
+ xd2r1k:
100
+ paramIdentifier:
101
+ name: establishment
102
+ key: xd2r1k
103
+ variable:
104
+ source: WIDGET_CLASS_PARAMETER
105
+ baseVariable:
106
+ widgetClass:
107
+ paramIdentifier:
108
+ name: estableshment
109
+ key: 974ngd
110
+ nodeKeyRef:
111
+ key: Container_qsdo2h11
112
+ widgetClassNodeKeyRef:
113
+ key: Scaffold_r4acaui6
114
+ key: udyk1rjj
115
+ ```
116
+
117
+ | Field | Type | Description |
118
+ |---|---|---|
119
+ | `allowBack` | boolean | Whether back navigation is allowed |
120
+ | `replaceRoute` | boolean | Replace current route instead of push |
121
+ | `isNavigateBack` | boolean | Navigate back (pop) instead of forward |
122
+ | `pageNodeKeyRef.key` | string | Scaffold key of the target page |
123
+ | `passedParameters.parameterPasses` | map | Parameters passed to the target page |
124
+
125
+ ### `localStateUpdate` -- Update Widget or App State
126
+
127
+ Updates one or more state variables.
128
+
129
+ ```yaml
130
+ localStateUpdate:
131
+ updates:
132
+ - fieldIdentifier:
133
+ key: gdgw8
134
+ setValue:
135
+ inputValue:
136
+ serializedValue: "1"
137
+ - fieldIdentifier:
138
+ key: ty6re
139
+ setValue:
140
+ variable:
141
+ source: ENUMS
142
+ baseVariable:
143
+ enumVariable:
144
+ enumIdentifier:
145
+ name: subscription
146
+ key: 8a348
147
+ enumElementIdentifier:
148
+ name: monthly
149
+ key: 3lp2p
150
+ updateType: WIDGET
151
+ stateVariableType: WIDGET_CLASS_STATE
152
+ key: ebx7vt69
153
+ ```
154
+
155
+ | Field | Type | Description |
156
+ |---|---|---|
157
+ | `updates` | list | Fields to update |
158
+ | `updates[].fieldIdentifier.key` | string | Key of the state field |
159
+ | `updates[].setValue` | value | New value (literal `inputValue` or `variable`) |
160
+ | `updates[].clearValue` | `{}` | Clear the field instead of setting |
161
+ | `updateType` | enum | `WIDGET` for component state |
162
+ | `stateVariableType` | enum | `WIDGET_CLASS_STATE` or `APP_STATE` |
163
+
164
+ ### `database.firestoreQuery` -- Firestore Query
165
+
166
+ Queries a Firestore collection with filters.
167
+
168
+ ```yaml
169
+ database:
170
+ firestoreQuery:
171
+ collectionIdentifier:
172
+ name: stripe_customer_subscriptions
173
+ key: 94977h9r
174
+ hideOnEmpty: false
175
+ singleTimeQuery: true
176
+ where:
177
+ filters:
178
+ - baseFilter:
179
+ collectionFieldIdentifier:
180
+ name: customer_phone
181
+ relation: EQUAL_TO
182
+ variable:
183
+ source: FIREBASE_AUTH_USER
184
+ baseVariable:
185
+ auth:
186
+ property: PHONE_NUMBER
187
+ - baseFilter:
188
+ collectionFieldIdentifier:
189
+ name: expiration_date
190
+ relation: GREATER_THAN
191
+ variable:
192
+ source: GLOBAL_PROPERTIES
193
+ baseVariable:
194
+ globalProperties:
195
+ property: CURRENT_TIMESTAMP
196
+ isAnd: true
197
+ returnParameter:
198
+ dataType:
199
+ listType:
200
+ scalarType: Document
201
+ subType:
202
+ collectionIdentifier:
203
+ name: stripe_customer_subscriptions
204
+ key: 94977h9r
205
+ outputVariableName: subscribedUser
206
+ key: 30vd1j0o
207
+ ```
208
+
209
+ | Field | Type | Description |
210
+ |---|---|---|
211
+ | `collectionIdentifier` | name+key | Target Firestore collection |
212
+ | `singleTimeQuery` | boolean | Query once (not a stream) |
213
+ | `where.filters` | list | Filter conditions |
214
+ | `where.filters[].baseFilter.relation` | enum | `EQUAL_TO`, `GREATER_THAN`, etc. |
215
+ | `where.isAnd` | boolean | AND vs OR filters |
216
+ | `outputVariableName` | string | Name for the action output variable |
217
+ | `returnParameter.dataType` | type | Return type (usually `listType: Document`) |
218
+
219
+ ### `database.createDocument` -- Create Firestore Document
220
+
221
+ Creates a new document in a Firestore collection.
222
+
223
+ ```yaml
224
+ database:
225
+ createDocument:
226
+ collectionIdentifier:
227
+ name: RedeemedUserDeals
228
+ key: lzo3gj3d
229
+ write:
230
+ updates:
231
+ UserRef:
232
+ fieldIdentifier:
233
+ name: UserRef
234
+ variable:
235
+ source: FIREBASE_AUTH_USER
236
+ baseVariable:
237
+ auth:
238
+ property: USER_REFERENCE
239
+ RedeemedAt:
240
+ fieldIdentifier:
241
+ name: RedeemedAt
242
+ variable:
243
+ source: GLOBAL_PROPERTIES
244
+ baseVariable:
245
+ globalProperties:
246
+ property: CURRENT_TIMESTAMP
247
+ parentReference:
248
+ source: WIDGET_CLASS_PARAMETER
249
+ baseVariable:
250
+ widgetClass:
251
+ paramIdentifier:
252
+ name: establishment
253
+ key: u32pu8
254
+ nodeKeyRef:
255
+ key: Container_p61gj0ld
256
+ key: u00ieh05
257
+ ```
258
+
259
+ | Field | Type | Description |
260
+ |---|---|---|
261
+ | `collectionIdentifier` | name+key | Target collection |
262
+ | `write.updates` | map | Field name to value mappings |
263
+ | `write.updates.{field}.fieldIdentifier.name` | string | Firestore field name |
264
+ | `write.updates.{field}.inputValue` | value | Literal value |
265
+ | `write.updates.{field}.variable` | variable | Dynamic value |
266
+ | `write.updates.{field}.dataStructFieldUpdate` | object | Nested data struct value |
267
+ | `parentReference` | variable | Parent document reference (for subcollections) |
268
+
269
+ ### `database.updateDocument` -- Update Firestore Document
270
+
271
+ Updates fields on an existing document.
272
+
273
+ ```yaml
274
+ database:
275
+ updateDocument:
276
+ write:
277
+ updates:
278
+ push_notifications:
279
+ fieldIdentifier:
280
+ name: push_notifications
281
+ inputValue:
282
+ serializedValue: "true"
283
+ reference:
284
+ source: FIREBASE_AUTH_USER
285
+ baseVariable:
286
+ auth:
287
+ property: USER_REFERENCE
288
+ key: 2d5pxkrp
289
+ ```
290
+
291
+ | Field | Type | Description |
292
+ |---|---|---|
293
+ | `write.updates` | map | Fields to update |
294
+ | `reference` | variable | Document reference to update |
295
+
296
+ ### `database.apiCall` -- Call API Endpoint
297
+
298
+ Calls a configured API endpoint.
299
+
300
+ ```yaml
301
+ database:
302
+ apiCall:
303
+ endpointIdentifier:
304
+ name: SendDiscountEmail
305
+ key: qegob
306
+ variables:
307
+ - variableIdentifier:
308
+ name: token
309
+ key: b7vj02x7
310
+ variable:
311
+ source: FIREBASE_AUTH_USER
312
+ baseVariable:
313
+ auth:
314
+ property: JWT_TOKEN
315
+ outputVariableName: apiResultrla
316
+ key: km9eei8s
317
+ ```
318
+
319
+ | Field | Type | Description |
320
+ |---|---|---|
321
+ | `endpointIdentifier` | name+key | API endpoint identifier |
322
+ | `variables` | list | API call parameters |
323
+ | `outputVariableName` | string | Name for the response output |
324
+
325
+ ### `customAction` -- Execute Custom Action
326
+
327
+ Calls a custom Dart function.
328
+
329
+ ```yaml
330
+ customAction:
331
+ customActionIdentifier:
332
+ name: linkAnonymousUser
333
+ key: nujdl
334
+ argumentValues:
335
+ arguments:
336
+ snaq9d:
337
+ value:
338
+ variable:
339
+ source: WIDGET_STATE
340
+ baseVariable:
341
+ widgetState:
342
+ returnParameter:
343
+ dataType:
344
+ scalarType: String
345
+ nodeKeyRef:
346
+ key: TextField_mxlvp4hj
347
+ outputVariableName: linkUserResult
348
+ key: ww6ook8u
349
+ ```
350
+
351
+ | Field | Type | Description |
352
+ |---|---|---|
353
+ | `customActionIdentifier` | name+key | Custom action reference |
354
+ | `argumentValues.arguments` | map | Argument key to value mappings |
355
+ | `outputVariableName` | string | Name for the return value |
356
+
357
+ ### `snackBar` -- Show Snack Bar Notification
358
+
359
+ Displays a snack bar message.
360
+
361
+ ```yaml
362
+ snackBar:
363
+ textMessage:
364
+ inputValue:
365
+ serializedValue: Code sent!
366
+ textStyle:
367
+ variableColor:
368
+ inputValue:
369
+ color:
370
+ themeColor: PRIMARY_TEXT
371
+ durationMillis: 4000
372
+ subAction:
373
+ action:
374
+ navigate:
375
+ allowBack: true
376
+ shouldHidePreviousSnackbar: false
377
+ backgroundColor:
378
+ inputValue:
379
+ color:
380
+ themeColor: PRIMARY
381
+ key: 72bzwegp
382
+ ```
383
+
384
+ The `textMessage` can also use a `variable` for dynamic text (string interpolation, etc.) instead of a literal `inputValue`.
385
+
386
+ | Field | Type | Description |
387
+ |---|---|---|
388
+ | `textMessage` | value | Message text (literal or variable) |
389
+ | `durationMillis` | integer | Display duration in milliseconds |
390
+ | `backgroundColor` | color | Background color |
391
+ | `textStyle.variableColor` | color | Text color |
392
+ | `shouldHidePreviousSnackbar` | boolean | Dismiss existing snack bar first |
393
+ | `subAction` | action | Action to execute when snack bar is tapped |
394
+
395
+ ### `revenueCat.paywall` -- Show RevenueCat Paywall
396
+
397
+ Displays the RevenueCat paywall for a given entitlement.
398
+
399
+ ```yaml
400
+ revenueCat:
401
+ paywall:
402
+ entitlementId:
403
+ inputValue:
404
+ serializedValue: Pro
405
+ key: erd8m4q2
406
+ ```
407
+
408
+ ### `revenueCat.restore` -- Restore RevenueCat Purchases
409
+
410
+ ```yaml
411
+ revenueCat:
412
+ restore: {}
413
+ key: 81j500xc
414
+ ```
415
+
416
+ ### `pageView` -- Control PageView Widget
417
+
418
+ Programmatically navigates a PageView widget.
419
+
420
+ ```yaml
421
+ pageView:
422
+ type: JUMP_TO
423
+ jumpToIndex:
424
+ inputValue:
425
+ serializedValue: "1"
426
+ pageViewNodeKeyRef:
427
+ key: PageView_txxkvt09
428
+ key: 9u9dws4x
429
+ ```
430
+
431
+ | Field | Type | Description |
432
+ |---|---|---|
433
+ | `type` | enum | `JUMP_TO`, `NEXT`, `PREVIOUS` |
434
+ | `jumpToIndex` | value | Target page index (for `JUMP_TO`) |
435
+ | `pageViewNodeKeyRef.key` | string | Key of the target PageView widget |
436
+
437
+ ### `timer` -- Start or Stop Timer
438
+
439
+ Controls a Timer widget.
440
+
441
+ ```yaml
442
+ timer:
443
+ type: START_TIMER
444
+ key: yfifxw3z
445
+ ```
446
+
447
+ ```yaml
448
+ timer:
449
+ type: STOP_TIMER
450
+ key: ucm9biyi
451
+ ```
452
+
453
+ ### `executeCallbackAction` -- Execute Component Callback
454
+
455
+ Invokes a callback parameter defined on a parent component.
456
+
457
+ ```yaml
458
+ executeCallbackAction:
459
+ parameterIdentifier:
460
+ name: onManage
461
+ key: aulgkx
462
+ argumentValues: {}
463
+ key: 2b2dwjgo
464
+ ```
465
+
466
+ | Field | Type | Description |
467
+ |---|---|---|
468
+ | `parameterIdentifier` | name+key | Callback parameter to invoke |
469
+ | `argumentValues` | map | Arguments to pass to the callback |
470
+
471
+ ### `alertDialog` -- Show Dialog
472
+
473
+ Displays a dialog, either a custom component or dismisses an existing one.
474
+
475
+ Show a custom dialog:
476
+
477
+ ```yaml
478
+ alertDialog:
479
+ customDialog:
480
+ passedParameters:
481
+ parameterPasses:
482
+ t8j0tg:
483
+ paramIdentifier:
484
+ name: dealTitle
485
+ key: t8j0tg
486
+ variable:
487
+ source: GENERATOR_VARIABLE
488
+ baseVariable:
489
+ generatorVariable: {}
490
+ operations:
491
+ - accessDocumentField:
492
+ fieldIdentifier:
493
+ name: Name
494
+ nodeKeyRef:
495
+ key: ListView_8lh3xfe2
496
+ widgetClassNodeKeyRef:
497
+ key: Container_qsdo2h11
498
+ dimensions:
499
+ width:
500
+ percentOfScreenSizeValue:
501
+ inputValue: 80
502
+ barrierColor: {}
503
+ nonDismissible: true
504
+ isGlobal: true
505
+ componentClassNodeKeyRef:
506
+ key: Container_gtqk3kbu
507
+ key: u43n5c2l
508
+ ```
509
+
510
+ Dismiss dialog:
511
+
512
+ ```yaml
513
+ alertDialog:
514
+ dismissDialog: {}
515
+ key: b5f5u42p
516
+ ```
517
+
518
+ ### `waitAction` -- Wait/Delay
519
+
520
+ Pauses execution for a specified duration.
521
+
522
+ ```yaml
523
+ waitAction:
524
+ durationMillisValue:
525
+ inputValue: 4000
526
+ key: pzxnwi4u
527
+ ```
528
+
529
+ ### `requestPermissions` -- Request Device Permissions
530
+
531
+ ```yaml
532
+ requestPermissions:
533
+ permissionType: NOTIFICATIONS
534
+ key: lu5gfw3c
535
+ ```
536
+
537
+ ```yaml
538
+ requestPermissions:
539
+ permissionType: LOCATION
540
+ key: wgmnqfwt
541
+ ```
542
+
543
+ ---
544
+
545
+ ## Conditional Actions
546
+
547
+ Conditional branching is defined in the trigger YAML file (not in individual action files) using `conditionActions`. The structure supports single conditions, multiple conditions, and nested conditions.
548
+
549
+ ### Basic Conditional (true/false branch)
550
+
551
+ ```yaml
552
+ rootAction:
553
+ key: 5ycxygcz
554
+ action:
555
+ key: qsw0br81
556
+ followUpAction:
557
+ key: jmvd96i3
558
+ conditionActions:
559
+ trueActions:
560
+ - condition:
561
+ variable:
562
+ source: FUNCTION_CALL
563
+ functionCall:
564
+ values:
565
+ - variable:
566
+ source: GLOBAL_PROPERTIES
567
+ baseVariable:
568
+ globalProperties:
569
+ property: IS_IOS
570
+ - inputValue:
571
+ serializedValue: "true"
572
+ condition:
573
+ relation: EQUAL_TO
574
+ falseAction:
575
+ key: opj63zwi
576
+ action:
577
+ key: 54wwjscn
578
+ hasMultiConditions: false
579
+ key: ugl3mgen
580
+ trigger:
581
+ triggerType: ON_TAP
582
+ ```
583
+
584
+ ### Multiple Conditions
585
+
586
+ When `hasMultiConditions: true`, the `trueActions` list contains multiple condition branches evaluated in order:
587
+
588
+ ```yaml
589
+ conditionActions:
590
+ trueActions:
591
+ - condition:
592
+ variable:
593
+ source: FUNCTION_CALL
594
+ functionCall:
595
+ values:
596
+ - variable:
597
+ source: ACTION_OUTPUTS
598
+ baseVariable:
599
+ actionOutput:
600
+ outputVariableIdentifier:
601
+ name: updateState
602
+ actionKeyRef:
603
+ key: 00tn7yxo
604
+ - variable:
605
+ source: ENUMS
606
+ baseVariable:
607
+ enumVariable:
608
+ enumIdentifier:
609
+ name: AppUpdateState
610
+ key: fta87
611
+ enumElementIdentifier:
612
+ name: forceUpdate
613
+ key: biqqk
614
+ condition:
615
+ relation: EQUAL_TO
616
+ trueAction:
617
+ key: g4iwdyck
618
+ action:
619
+ key: u43n5c2l
620
+ - condition:
621
+ # Second condition...
622
+ trueAction:
623
+ key: riqztjef
624
+ action:
625
+ key: dkb400cy
626
+ hasMultiConditions: true
627
+ key: 2jfp921u
628
+ ```
629
+
630
+ ### Combined Conditions (AND/OR)
631
+
632
+ Multiple conditions can be combined using `combineConditions`:
633
+
634
+ ```yaml
635
+ conditionActions:
636
+ trueActions:
637
+ - condition:
638
+ variable:
639
+ source: FUNCTION_CALL
640
+ functionCall:
641
+ values:
642
+ - variable:
643
+ source: LOCAL_STATE
644
+ baseVariable:
645
+ localState:
646
+ fieldIdentifier:
647
+ name: isAnonymous
648
+ key: bfu0ivv2
649
+ stateVariableType: APP_STATE
650
+ - variable:
651
+ source: LOCAL_STATE
652
+ baseVariable:
653
+ localState:
654
+ fieldIdentifier:
655
+ name: doneFree
656
+ key: e4yygjed
657
+ stateVariableType: APP_STATE
658
+ combineConditions:
659
+ operator: AND_OP # or OR_OP
660
+ ```
661
+
662
+ ### RevenueCat Entitlement Condition
663
+
664
+ A special condition type for RevenueCat subscription checks:
665
+
666
+ ```yaml
667
+ conditionActions:
668
+ trueActions:
669
+ - condition:
670
+ revenueCatEntitlementResponse: {}
671
+ trueAction:
672
+ key: lewj54wz
673
+ action:
674
+ key: l00bd53j
675
+ falseAction:
676
+ key: p5lhm9f5
677
+ action:
678
+ key: 50132f9w
679
+ ```
680
+
681
+ ---
682
+
683
+ ## Action Chaining
684
+
685
+ Actions execute sequentially using `followUpAction`. Each node in the chain can contain an `action` reference, another `conditionActions` block, or `terminate` to stop execution.
686
+
687
+ ### Sequential Execution
688
+
689
+ ```yaml
690
+ rootAction:
691
+ key: 5dyi3ba5
692
+ action:
693
+ key: first_action
694
+ followUpAction:
695
+ key: abc123
696
+ action:
697
+ key: second_action
698
+ followUpAction:
699
+ key: def456
700
+ action:
701
+ key: third_action
702
+ followUpAction:
703
+ key: ghi789
704
+ action:
705
+ key: fourth_action
706
+ ```
707
+
708
+ ### Terminate Execution
709
+
710
+ `terminate: {}` stops the action chain early, typically used inside conditional branches:
711
+
712
+ ```yaml
713
+ trueAction:
714
+ key: bc1vt0ak
715
+ action:
716
+ navigate:
717
+ allowBack: false
718
+ pageNodeKeyRef:
719
+ key: Scaffold_u52v700s
720
+ followUpAction:
721
+ key: r6wrgnpz
722
+ terminate: {}
723
+ ```
724
+
725
+ ---
726
+
727
+ ## Disabled Actions
728
+
729
+ Actions can be conditionally disabled using a `disableAction` wrapper. When the condition evaluates to true, the wrapped action executes; the chain terminates otherwise.
730
+
731
+ ```yaml
732
+ key: hfzr0kmk
733
+ disableAction:
734
+ actionNode:
735
+ key: 6zoe9nca
736
+ conditionActions:
737
+ trueActions:
738
+ - condition:
739
+ variable:
740
+ source: FUNCTION_CALL
741
+ functionCall:
742
+ values:
743
+ - variable:
744
+ source: FIREBASE_AUTH_USER
745
+ baseVariable:
746
+ auth:
747
+ property: USERS_DATA_FIELD
748
+ usersDataField:
749
+ name: zipCode
750
+ - inputValue:
751
+ serializedValue: "0"
752
+ condition:
753
+ relation: EQUAL_TO
754
+ trueAction:
755
+ key: 664phh8p
756
+ action:
757
+ localStateUpdate:
758
+ # ...action body inline...
759
+ followUpAction:
760
+ key: pqmxin3v
761
+ terminate: {}
762
+ hasMultiConditions: false
763
+ key: xsa3loej
764
+ ```
765
+
766
+ Note: In `disableAction`, the action body can be inlined directly rather than referenced by key.
767
+
768
+ ---
769
+
770
+ ## Action Output Variables
771
+
772
+ Actions that produce results use `outputVariableName` to store the value. Subsequent actions can reference these outputs via the `ACTION_OUTPUTS` variable source:
773
+
774
+ **Producing an output:**
775
+
776
+ ```yaml
777
+ database:
778
+ firestoreQuery:
779
+ collectionIdentifier:
780
+ name: RedeemedUserDeals
781
+ key: lzo3gj3d
782
+ # ...query config...
783
+ outputVariableName: deals
784
+ key: iw14lghd
785
+ ```
786
+
787
+ **Consuming an output:**
788
+
789
+ ```yaml
790
+ variable:
791
+ source: ACTION_OUTPUTS
792
+ baseVariable:
793
+ actionOutput:
794
+ outputVariableIdentifier:
795
+ name: deals
796
+ actionKeyRef:
797
+ key: iw14lghd
798
+ nodeKeyRef:
799
+ key: Scaffold_4qdr9nq8
800
+ actionComponentKeyRef: {}
801
+ ```
802
+
803
+ The `actionKeyRef.key` must match the `key` of the action that produced the output. When the output comes from an action component (reusable action block), `actionComponentKeyRef.key` references the component.
804
+
805
+ ---
806
+
807
+ ## App Action Components
808
+
809
+ Reusable action sequences can be defined as **app action components** and referenced across pages. These live under `app-action-components/`:
810
+
811
+ ```yaml
812
+ identifier:
813
+ name: checkUpdateBlock
814
+ key: ld3jo3
815
+ actions:
816
+ rootAction:
817
+ key: dmm3dw7g
818
+ action:
819
+ customAction:
820
+ customActionIdentifier:
821
+ name: checkAppUpdateStatus
822
+ key: zjg1l
823
+ argumentValues:
824
+ arguments:
825
+ fr6rim:
826
+ value:
827
+ variable:
828
+ source: FIREBASE_AUTH_USER
829
+ baseVariable:
830
+ auth:
831
+ property: USERS_DATA_FIELD
832
+ usersDataField:
833
+ name: app_version
834
+ outputVariableName: updateState
835
+ key: 00tn7yxo
836
+ followUpAction:
837
+ key: isp97zrh
838
+ conditionActions:
839
+ # ...branching logic...
840
+ description: ""
841
+ ```
842
+
843
+ App action components use the same action and chaining structures but are not tied to any specific widget trigger.