@uipath/skills 1.204.0 → 1.204.1
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/CODEOWNERS +12 -14
- package/package.json +1 -1
- package/skills/uipath-agents/references/coded/embedding-in-flows.md +1 -3
- package/skills/uipath-agents/references/coded/quickstart.md +0 -2
- package/skills/uipath-agents/references/lowcode/capabilities/inline-in-flow/inline-in-flow.md +10 -8
- package/skills/uipath-agents/references/lowcode/prompting/autonomous-agent-prompting-guide.md +1 -1
- package/skills/uipath-human-in-the-loop/SKILL.md +1 -3
- package/skills/uipath-human-in-the-loop/references/hitl-node-apptask.md +0 -2
- package/skills/uipath-human-in-the-loop/references/hitl-node-coded-action-app.md +0 -2
- package/skills/uipath-human-in-the-loop/references/hitl-node-quickform.md +2 -2
- package/skills/uipath-maestro-flow/.maintenance/README.md +265 -0
- package/skills/uipath-maestro-flow/.maintenance/check-all.sh +40 -0
- package/skills/uipath-maestro-flow/.maintenance/check-anchors.sh +101 -0
- package/skills/uipath-maestro-flow/.maintenance/check-depth.sh +132 -0
- package/skills/uipath-maestro-flow/.maintenance/check-link-text.sh +123 -0
- package/skills/uipath-maestro-flow/.maintenance/check-links.sh +73 -0
- package/skills/uipath-maestro-flow/.maintenance/check-orphans.sh +93 -0
- package/skills/uipath-maestro-flow/.maintenance/check-plugin-pairs.sh +39 -0
- package/skills/uipath-maestro-flow/.maintenance/check-template.sh +42 -0
- package/skills/uipath-maestro-flow/.maintenance/check-uip-commands.sh +270 -0
- package/skills/uipath-maestro-flow/.maintenance/check-versions.sh +160 -0
- package/skills/uipath-maestro-flow/SKILL.md +69 -886
- package/skills/uipath-maestro-flow/references/author/CAPABILITY.md +207 -0
- package/skills/uipath-maestro-flow/references/author/brownfield.md +91 -0
- package/skills/uipath-maestro-flow/references/author/editing-operations-cli.md +190 -0
- package/skills/uipath-maestro-flow/references/author/editing-operations-json.md +374 -0
- package/skills/uipath-maestro-flow/references/author/editing-operations.md +104 -0
- package/skills/uipath-maestro-flow/references/author/greenfield.md +420 -0
- package/skills/uipath-maestro-flow/references/author/planning-arch.md +364 -0
- package/skills/uipath-maestro-flow/references/author/planning-impl.md +291 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agent/impl.md +237 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agent/planning.md +97 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agentic-process/impl.md +107 -0
- package/skills/uipath-maestro-flow/references/author/plugins/agentic-process/planning.md +61 -0
- package/skills/uipath-maestro-flow/references/author/plugins/api-workflow/impl.md +108 -0
- package/skills/uipath-maestro-flow/references/author/plugins/api-workflow/planning.md +60 -0
- package/skills/uipath-maestro-flow/references/author/plugins/batch-transform/impl.md +171 -0
- package/skills/uipath-maestro-flow/references/author/plugins/batch-transform/planning.md +72 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector/impl-inline.md +120 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector/impl.md +463 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector/planning.md +186 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector-trigger/impl.md +517 -0
- package/skills/uipath-maestro-flow/references/author/plugins/connector-trigger/planning.md +115 -0
- package/skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md +309 -0
- package/skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md +133 -0
- package/skills/uipath-maestro-flow/references/author/plugins/data-fabric/impl.md +428 -0
- package/skills/uipath-maestro-flow/references/author/plugins/data-fabric/planning.md +188 -0
- package/skills/uipath-maestro-flow/references/author/plugins/decision/impl.md +83 -0
- package/skills/uipath-maestro-flow/references/author/plugins/decision/planning.md +38 -0
- package/skills/uipath-maestro-flow/references/author/plugins/delay/impl.md +38 -0
- package/skills/uipath-maestro-flow/references/author/plugins/delay/planning.md +53 -0
- package/skills/uipath-maestro-flow/references/author/plugins/end/impl.md +56 -0
- package/skills/uipath-maestro-flow/references/author/plugins/end/planning.md +28 -0
- package/skills/uipath-maestro-flow/references/author/plugins/flow/impl.md +107 -0
- package/skills/uipath-maestro-flow/references/author/plugins/flow/planning.md +58 -0
- package/skills/uipath-maestro-flow/references/author/plugins/hitl/impl.md +181 -0
- package/skills/uipath-maestro-flow/references/author/plugins/hitl/planning.md +166 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/impl-connector.md +86 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/impl-manual.md +68 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/impl.md +173 -0
- package/skills/uipath-maestro-flow/references/author/plugins/http/planning.md +107 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-agent/impl.md +540 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-agent/planning.md +115 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-voice-agent/impl.md +269 -0
- package/skills/uipath-maestro-flow/references/author/plugins/inline-voice-agent/planning.md +128 -0
- package/skills/uipath-maestro-flow/references/author/plugins/ixp/impl.md +424 -0
- package/skills/uipath-maestro-flow/references/author/plugins/ixp/planning.md +95 -0
- package/skills/uipath-maestro-flow/references/author/plugins/loop/impl.md +403 -0
- package/skills/uipath-maestro-flow/references/author/plugins/loop/planning.md +60 -0
- package/skills/uipath-maestro-flow/references/author/plugins/merge/impl.md +43 -0
- package/skills/uipath-maestro-flow/references/author/plugins/merge/planning.md +24 -0
- package/skills/uipath-maestro-flow/references/author/plugins/queue/impl.md +82 -0
- package/skills/uipath-maestro-flow/references/author/plugins/queue/planning.md +44 -0
- package/skills/uipath-maestro-flow/references/author/plugins/rpa/impl.md +117 -0
- package/skills/uipath-maestro-flow/references/author/plugins/rpa/planning.md +61 -0
- package/skills/uipath-maestro-flow/references/author/plugins/scheduled-trigger/impl.md +56 -0
- package/skills/uipath-maestro-flow/references/author/plugins/scheduled-trigger/planning.md +93 -0
- package/skills/uipath-maestro-flow/references/author/plugins/script/impl.md +98 -0
- package/skills/uipath-maestro-flow/references/author/plugins/script/planning.md +42 -0
- package/skills/uipath-maestro-flow/references/author/plugins/subflow/impl.md +164 -0
- package/skills/uipath-maestro-flow/references/author/plugins/subflow/planning.md +35 -0
- package/skills/uipath-maestro-flow/references/author/plugins/summarize/impl.md +189 -0
- package/skills/uipath-maestro-flow/references/author/plugins/summarize/planning.md +66 -0
- package/skills/uipath-maestro-flow/references/author/plugins/switch/impl.md +72 -0
- package/skills/uipath-maestro-flow/references/author/plugins/switch/planning.md +34 -0
- package/skills/uipath-maestro-flow/references/author/plugins/terminate/impl.md +48 -0
- package/skills/uipath-maestro-flow/references/author/plugins/terminate/planning.md +29 -0
- package/skills/uipath-maestro-flow/references/author/plugins/transform/impl.md +252 -0
- package/skills/uipath-maestro-flow/references/author/plugins/transform/planning.md +47 -0
- package/skills/uipath-maestro-flow/references/diagnose/CAPABILITY.md +73 -0
- package/skills/uipath-maestro-flow/references/diagnose/failure-modes.md +353 -0
- package/skills/uipath-maestro-flow/references/diagnose/troubleshooting-guide.md +174 -0
- package/skills/uipath-maestro-flow/references/evaluate/CAPABILITY.md +134 -0
- package/skills/uipath-maestro-flow/references/evaluate/commands-reference.md +376 -0
- package/skills/uipath-maestro-flow/references/evaluate/eval-sets-guide.md +227 -0
- package/skills/uipath-maestro-flow/references/evaluate/evaluators-guide.md +143 -0
- package/skills/uipath-maestro-flow/references/evaluate/running-guide.md +215 -0
- package/skills/uipath-maestro-flow/references/evaluate/upload-safety.md +94 -0
- package/skills/uipath-maestro-flow/references/operate/CAPABILITY.md +77 -0
- package/skills/uipath-maestro-flow/references/operate/manage.md +39 -0
- package/skills/uipath-maestro-flow/references/operate/run.md +121 -0
- package/skills/uipath-maestro-flow/references/operate/ship.md +57 -0
- package/skills/uipath-maestro-flow/references/shared/action-nodes.md +100 -0
- package/skills/uipath-maestro-flow/references/shared/cli-commands.md +269 -0
- package/skills/uipath-maestro-flow/references/shared/cli-conventions.md +178 -0
- package/skills/uipath-maestro-flow/references/shared/file-format.md +582 -0
- package/skills/uipath-maestro-flow/references/shared/node-output-wiring.md +86 -0
- package/skills/uipath-maestro-flow/references/shared/ux-narration-and-todos.md +113 -0
- package/skills/uipath-maestro-flow/references/shared/variables-and-expressions.md +787 -0
- package/skills/uipath-platform/references/integration-service/activities.md +2 -2
- package/skills/uipath-platform/references/integration-service/activity-generation.md +8 -1
- package/skills/uipath-platform/references/integration-service/triggers.md +1 -3
- package/version-manifest.json +1 -1
- package/skills/uipath-maestro-flow/examples/AquariumSafetyStop.flow.ts +0 -26
- package/skills/uipath-maestro-flow/examples/ArchiveCardExtract.flow.ts +0 -38
- package/skills/uipath-maestro-flow/examples/BakeOffEntryForm.flow.ts +0 -27
- package/skills/uipath-maestro-flow/examples/BeeHiveLedger.flow.ts +0 -61
- package/skills/uipath-maestro-flow/examples/BeltProgression.flow.ts +0 -53
- package/skills/uipath-maestro-flow/examples/BirdCountLookup.flow.ts +0 -24
- package/skills/uipath-maestro-flow/examples/ClubDirectory.flow.ts +0 -56
- package/skills/uipath-maestro-flow/examples/ConcertSoundcheck.flow.ts +0 -59
- package/skills/uipath-maestro-flow/examples/DoorbellLog.flow.ts +0 -45
- package/skills/uipath-maestro-flow/examples/FestivalMapScaffold.flow.ts +0 -22
- package/skills/uipath-maestro-flow/examples/FieldTripQuickForm.flow.ts +0 -45
- package/skills/uipath-maestro-flow/examples/FossilCatalogEnrich.flow.ts +0 -26
- package/skills/uipath-maestro-flow/examples/GallerySubmission.flow.ts +0 -67
- package/skills/uipath-maestro-flow/examples/GreenhouseWatering.flow.ts +0 -39
- package/skills/uipath-maestro-flow/examples/HarbourRadioLine.flow.ts +0 -31
- package/skills/uipath-maestro-flow/examples/HerbariumDispatch.flow.ts +0 -34
- package/skills/uipath-maestro-flow/examples/KilnReview.flow.ts +0 -38
- package/skills/uipath-maestro-flow/examples/LibraryDeskChat.flow.ts +0 -39
- package/skills/uipath-maestro-flow/examples/LighthouseSignal.flow.ts +0 -30
- package/skills/uipath-maestro-flow/examples/MeteorShowerPages.flow.ts +0 -39
- package/skills/uipath-maestro-flow/examples/NeighborhoodWalkPlanner.flow.ts +0 -27
- package/skills/uipath-maestro-flow/examples/ObservatorySeeing.flow.ts +0 -51
- package/skills/uipath-maestro-flow/examples/OralHistoryDigest.flow.ts +0 -31
- package/skills/uipath-maestro-flow/examples/PlanetariumConfirmation.flow.ts +0 -34
- package/skills/uipath-maestro-flow/examples/PlantNameAdvisor.flow.ts +0 -28
- package/skills/uipath-maestro-flow/examples/PostcardCaption.flow.ts +0 -44
- package/skills/uipath-maestro-flow/examples/PotteryStudioCallback.flow.ts +0 -41
- package/skills/uipath-maestro-flow/examples/RecipeScaler.flow.ts +0 -62
- package/skills/uipath-maestro-flow/examples/SeedPacketReader.flow.ts +0 -49
- package/skills/uipath-maestro-flow/examples/TideTableConverter.flow.ts +0 -35
- package/skills/uipath-maestro-flow/examples/TrailLogSummary.flow.ts +0 -75
- package/skills/uipath-maestro-flow/examples/WorkshopInventory.flow.ts +0 -27
- package/skills/uipath-maestro-flow/examples/bindings.json +0 -85
- package/skills/uipath-maestro-flow/references/CLI-LOOP.md +0 -309
- package/skills/uipath-maestro-flow/references/agent-resources.md +0 -74
- package/skills/uipath-maestro-flow/references/agent.md +0 -175
- package/skills/uipath-maestro-flow/references/agentic-process.md +0 -41
- package/skills/uipath-maestro-flow/references/api-workflow.md +0 -29
- package/skills/uipath-maestro-flow/references/author.md +0 -178
- package/skills/uipath-maestro-flow/references/batch-transform.md +0 -23
- package/skills/uipath-maestro-flow/references/bindings.md +0 -178
- package/skills/uipath-maestro-flow/references/branch.md +0 -18
- package/skills/uipath-maestro-flow/references/brownfield.md +0 -152
- package/skills/uipath-maestro-flow/references/connector-params.md +0 -624
- package/skills/uipath-maestro-flow/references/conversational.md +0 -77
- package/skills/uipath-maestro-flow/references/data-fabric.md +0 -268
- package/skills/uipath-maestro-flow/references/delay.md +0 -26
- package/skills/uipath-maestro-flow/references/diagnose.md +0 -141
- package/skills/uipath-maestro-flow/references/document-pipeline.md +0 -47
- package/skills/uipath-maestro-flow/references/error-handling.md +0 -75
- package/skills/uipath-maestro-flow/references/evaluate.md +0 -168
- package/skills/uipath-maestro-flow/references/event-trigger.md +0 -155
- package/skills/uipath-maestro-flow/references/form-trigger.md +0 -41
- package/skills/uipath-maestro-flow/references/hitl.md +0 -169
- package/skills/uipath-maestro-flow/references/http.md +0 -105
- package/skills/uipath-maestro-flow/references/inline-agent.md +0 -132
- package/skills/uipath-maestro-flow/references/ixp.md +0 -167
- package/skills/uipath-maestro-flow/references/loops.md +0 -77
- package/skills/uipath-maestro-flow/references/manual-trigger.md +0 -39
- package/skills/uipath-maestro-flow/references/operate.md +0 -204
- package/skills/uipath-maestro-flow/references/or-processes.md +0 -91
- package/skills/uipath-maestro-flow/references/parallel-merge.md +0 -21
- package/skills/uipath-maestro-flow/references/placeholder.md +0 -70
- package/skills/uipath-maestro-flow/references/published-function.md +0 -66
- package/skills/uipath-maestro-flow/references/queue.md +0 -53
- package/skills/uipath-maestro-flow/references/return.md +0 -20
- package/skills/uipath-maestro-flow/references/rpa-workflow.md +0 -27
- package/skills/uipath-maestro-flow/references/scheduled-trigger.md +0 -34
- package/skills/uipath-maestro-flow/references/script.md +0 -52
- package/skills/uipath-maestro-flow/references/subflow.md +0 -33
- package/skills/uipath-maestro-flow/references/summarize.md +0 -20
- package/skills/uipath-maestro-flow/references/switch.md +0 -20
- package/skills/uipath-maestro-flow/references/terminate.md +0 -22
- package/skills/uipath-maestro-flow/references/transform.md +0 -32
- package/skills/uipath-maestro-flow/references/voice.md +0 -70
|
@@ -0,0 +1,787 @@
|
|
|
1
|
+
# Variables and Expressions
|
|
2
|
+
|
|
3
|
+
Complete reference for declaring variables, writing expressions, and managing data flow in `.flow` files.
|
|
4
|
+
|
|
5
|
+
> **Read this before** adding variables or writing expressions in any flow.
|
|
6
|
+
>
|
|
7
|
+
> `flow validate` catches the structural expression-reference errors:
|
|
8
|
+
>
|
|
9
|
+
> - Missing `=js:` prefix on `$vars`/`$metadata`/`$self`
|
|
10
|
+
> - Invented `nodes.<id>.output` syntax
|
|
11
|
+
> - References to unknown variables or node IDs
|
|
12
|
+
> - Output-path walks that descend into declared primitives or schemas closed with `additionalProperties: false`
|
|
13
|
+
>
|
|
14
|
+
> Errors against **open output schemas** (HTTP response bodies, script returns, free-text agent output) and **wrong-direction reads** (e.g. reading an `out`-only variable) still slip past validate and surface only at `flow debug` or in production.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Table of contents
|
|
19
|
+
|
|
20
|
+
- [Variables Overview](#variables-overview)
|
|
21
|
+
- [Workflow Variables (`globals`)](#workflow-variables-globals)
|
|
22
|
+
- [Node Variables (`nodes`)](#node-variables-nodes)
|
|
23
|
+
- [Variable Updates (`variableUpdates`)](#variable-updates-variableupdates)
|
|
24
|
+
- [Output Mapping on End Nodes](#output-mapping-on-end-nodes)
|
|
25
|
+
- [Expression System](#expression-system)
|
|
26
|
+
- [Available Globals](#available-globals)
|
|
27
|
+
- [Expression Contexts](#expression-contexts)
|
|
28
|
+
- [Jint Engine Constraints](#jint-engine-constraints)
|
|
29
|
+
- [Scoping Rules](#scoping-rules)
|
|
30
|
+
- [Variable Management via CLI](#variable-management-via-cli)
|
|
31
|
+
- [Complete Example](#complete-example)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Variables Overview
|
|
36
|
+
|
|
37
|
+
Every flow has a `variables` object at the top level of the `.flow` file. It contains three sections:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"variables": {
|
|
42
|
+
"globals": [],
|
|
43
|
+
"nodes": [],
|
|
44
|
+
"variableUpdates": {}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Section | Purpose |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| `globals` | Workflow-level variables: inputs, outputs, and state |
|
|
52
|
+
| `nodes` | Node output variables (auto-generated when using CLI `node add`) |
|
|
53
|
+
| `variableUpdates` | Per-node expressions that update state variables |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Workflow Variables (`globals`)
|
|
58
|
+
|
|
59
|
+
Workflow variables are declared in `variables.globals`. Each has a **direction** that determines its role.
|
|
60
|
+
|
|
61
|
+
### Directions
|
|
62
|
+
|
|
63
|
+
| Direction | Role | Readable | Writable | Use case |
|
|
64
|
+
| --- | --- | --- | --- | --- |
|
|
65
|
+
| `in` | External input | Yes | No | Values passed when the flow is triggered or called |
|
|
66
|
+
| `out` | Workflow output | Yes | Mapped on End node | Values returned when the flow completes |
|
|
67
|
+
| `inout` | Internal state | Yes | Yes (via `variableUpdates`) | Counters, accumulators, flags shared across nodes |
|
|
68
|
+
|
|
69
|
+
### Schema
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
{
|
|
73
|
+
id: string // Unique identifier, used in expressions as $vars.{id}
|
|
74
|
+
direction: "in" | "out" | "inout"
|
|
75
|
+
type?: string // "string" (default), "number", "boolean", "object", "array", "file"
|
|
76
|
+
subType?: string // Item type for arrays (e.g., "object", "string")
|
|
77
|
+
schema?: object // JSON Schema (draft-07) for complex types
|
|
78
|
+
defaultValue?: unknown // Initial value (must match type)
|
|
79
|
+
description?: string // Human-readable description
|
|
80
|
+
triggerNodeId?: string // REQUIRED on `in` globals — see below (works in both root flows and subflows)
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> **Set `triggerNodeId` on every `in` global** — omit it and the input is silently dropped from the packed entry point.
|
|
85
|
+
>
|
|
86
|
+
> - **What to set** — the `id` of the trigger that supplies the value; `"start"` in a single-trigger flow.
|
|
87
|
+
> - **Why** — packaging reads the input contract from the trigger manifest's output schema when it declares one, and otherwise keeps only globals where `direction === "in"` and `triggerNodeId` matches the start node's `id`. Core triggers declare no output schema, so that second branch is the live one.
|
|
88
|
+
> - **Failure mode** — `flow pack` emits an empty `input.properties` while `flow validate` and `flow format` both stay green, so nothing warns you.
|
|
89
|
+
> - **Via CLI** — `uip maestro flow variable add --direction in` sets it for you.
|
|
90
|
+
|
|
91
|
+
### Examples
|
|
92
|
+
|
|
93
|
+
**String input with default:**
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"id": "customerName",
|
|
97
|
+
"direction": "in",
|
|
98
|
+
"type": "string",
|
|
99
|
+
"defaultValue": "Unknown",
|
|
100
|
+
"description": "Name of the customer to process",
|
|
101
|
+
"triggerNodeId": "start"
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Number output:**
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"id": "totalAmount",
|
|
109
|
+
"direction": "out",
|
|
110
|
+
"type": "number"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**State variable (counter):**
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"id": "retryCount",
|
|
118
|
+
"direction": "inout",
|
|
119
|
+
"type": "number",
|
|
120
|
+
"defaultValue": 0
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Object with JSON Schema:**
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"id": "orderData",
|
|
128
|
+
"direction": "in",
|
|
129
|
+
"type": "object",
|
|
130
|
+
"schema": {
|
|
131
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
132
|
+
"type": "object",
|
|
133
|
+
"required": ["orderId", "amount"],
|
|
134
|
+
"properties": {
|
|
135
|
+
"orderId": { "type": "string" },
|
|
136
|
+
"amount": { "type": "number" },
|
|
137
|
+
"items": {
|
|
138
|
+
"type": "array",
|
|
139
|
+
"items": { "type": "object" }
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"additionalProperties": false
|
|
143
|
+
},
|
|
144
|
+
"triggerNodeId": "start"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Array with subType:**
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"id": "emailList",
|
|
152
|
+
"direction": "in",
|
|
153
|
+
"type": "array",
|
|
154
|
+
"subType": "string",
|
|
155
|
+
"defaultValue": ["admin@example.com"],
|
|
156
|
+
"triggerNodeId": "start"
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Input associated with a trigger:**
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"id": "webhookPayload",
|
|
164
|
+
"direction": "in",
|
|
165
|
+
"type": "object",
|
|
166
|
+
"triggerNodeId": "start"
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
Accessed in expressions as `$vars.{triggerNodeId}.output.{id}` (the variable is nested under the trigger node's output — NOT `$vars.{id}`).
|
|
170
|
+
|
|
171
|
+
<a id="file-input"></a>
|
|
172
|
+
**File input (`type: "file"`):**
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"id": "inputDoc",
|
|
176
|
+
"direction": "in",
|
|
177
|
+
"type": "file",
|
|
178
|
+
"description": "Document uploaded at trigger / bound via --attachment",
|
|
179
|
+
"triggerNodeId": "start"
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
> **Runtime shape of a `file` variable.** At runtime a `file` variable is an **object** (the *Flow Attachment* object), not a string. A Script node reading `$vars.start.output.inputDoc` receives:
|
|
184
|
+
>
|
|
185
|
+
> ```json
|
|
186
|
+
> { "ID": "<uuid>", "FullName": "report.pdf", "MimeType": "application/pdf", "Metadata": { "size": "1024" } }
|
|
187
|
+
> ```
|
|
188
|
+
>
|
|
189
|
+
> The uploaded file's name is **`.FullName`**. Property access is **case-sensitive** at runtime — these exact casings resolve, others return `undefined`/`null`: `.ID` (uppercase, not `.Id`), `.FullName`, `.MimeType`, and the **nested `.Metadata.size`** (lowercase `size`, NOT `.Size`). `.name` / `.fileName` do **not** exist. Two layers: the `.flow` *declaration* is camelCase (`type`, `direction`); the *runtime* object carries the casing above. Do NOT write `"FullName"` into the `.flow` source. Bind the file with `uip maestro flow debug --attachment <id>=<path>` — see [cli-commands.md — Pre-flight](cli-commands.md#attachment-preflight).
|
|
190
|
+
|
|
191
|
+
### Type Reference
|
|
192
|
+
|
|
193
|
+
| Type | Default Value | Notes |
|
|
194
|
+
| --- | --- | --- |
|
|
195
|
+
| `string` | `""` | Default type if omitted |
|
|
196
|
+
| `number` | `0` | Integer or float |
|
|
197
|
+
| `boolean` | `false` | |
|
|
198
|
+
| `object` | `{}` | Use `schema` for structured objects |
|
|
199
|
+
| `array` | `[]` | Use `subType` for typed arrays |
|
|
200
|
+
| `file` | — | Bound at runtime via `--attachment`; hydrates as an object — read `.FullName` (see [File input](#file-input) above) |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Node Variables (`nodes`)
|
|
205
|
+
|
|
206
|
+
Node variables represent outputs produced by nodes during execution. They are read-only and referenced via `$vars.{nodeId}.{outputId}`.
|
|
207
|
+
|
|
208
|
+
When you add a node via `uip maestro flow node add`, node variables are created automatically. When using `Edit` against the `.flow` file, add them manually.
|
|
209
|
+
|
|
210
|
+
### Schema
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
{
|
|
214
|
+
id: string // Format: "{nodeId}.{outputId}"
|
|
215
|
+
type?: string // Output type
|
|
216
|
+
subType?: string // For complex types
|
|
217
|
+
schema?: object // JSON Schema for structured outputs
|
|
218
|
+
description?: string // What this output contains
|
|
219
|
+
binding: {
|
|
220
|
+
nodeId: string // Source node ID
|
|
221
|
+
outputId: string // Output port ID (e.g., "output", "error")
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Example
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"variables": {
|
|
231
|
+
"nodes": [
|
|
232
|
+
{
|
|
233
|
+
"id": "fetchData.output",
|
|
234
|
+
"type": "object",
|
|
235
|
+
"description": "HTTP response body",
|
|
236
|
+
"binding": {
|
|
237
|
+
"nodeId": "fetchData",
|
|
238
|
+
"outputId": "output"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"id": "fetchData.error",
|
|
243
|
+
"type": "object",
|
|
244
|
+
"description": "Error details if the request fails",
|
|
245
|
+
"schema": {
|
|
246
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
247
|
+
"type": "object",
|
|
248
|
+
"required": ["code", "message"],
|
|
249
|
+
"properties": {
|
|
250
|
+
"code": { "type": "string" },
|
|
251
|
+
"message": { "type": "string" },
|
|
252
|
+
"detail": { "type": "string" },
|
|
253
|
+
"category": { "type": "string" },
|
|
254
|
+
"status": { "type": "integer" }
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"binding": {
|
|
258
|
+
"nodeId": "fetchData",
|
|
259
|
+
"outputId": "error"
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
]
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Variable Updates (`variableUpdates`)
|
|
270
|
+
|
|
271
|
+
Variable updates assign new values to `inout` (state) variables at specific nodes. They execute when the node completes.
|
|
272
|
+
|
|
273
|
+
### Schema
|
|
274
|
+
|
|
275
|
+
`expression` is an **object**, not a `=js:` string. This is the one expression site in the file format that is strictly typed — `nodes[].inputs`, `nodes[].outputs[].source`, and edge conditions still accept legacy `=js:` strings, but `variableUpdates` does not.
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
{
|
|
279
|
+
"variableUpdates": {
|
|
280
|
+
"{nodeId}": [
|
|
281
|
+
{
|
|
282
|
+
"variableId": string, // ID of the inout variable to update
|
|
283
|
+
"expression": {
|
|
284
|
+
"type": "jsExpression", // or "literal" for a static value
|
|
285
|
+
"expression": string, // BARE JS body — NO "=js:" prefix
|
|
286
|
+
"fieldType": "number" // the target variable's declared type
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
| Field | Value |
|
|
295
|
+
| --- | --- |
|
|
296
|
+
| `type` | `"jsExpression"` for an evaluated expression, `"literal"` for a static value |
|
|
297
|
+
| `expression` | The JS body **without** the `=js:` prefix. For object-form expressions the prefix is *not* stripped, so `"=js:$vars.x"` here leaves `=js:` in the evaluated body. |
|
|
298
|
+
| `fieldType` | Set it to the target variable's `type` from `variables.globals`, mapped `integer` → `number`. One of `array`, `boolean`, `null`, `number`, `object`, `string`. |
|
|
299
|
+
|
|
300
|
+
> **The three keys are structurally required, but their *values* are not cross-checked.** `flow validate` rejects a missing or extra key (the object is strict), and rejects the legacy string form outright — but it accepts a `fieldType` that disagrees with the target variable, and accepts a stray `=js:` inside `expression`. Get these right by construction; validation will not tell you.
|
|
301
|
+
|
|
302
|
+
> **Symptom of the legacy string form:** `uip maestro flow validate` fails with
|
|
303
|
+
> `[MIGRATION] Workflow migration failed at 1.9→1.10 … Offending field(s): variables.variableUpdates.<nodeId>.0.expression`
|
|
304
|
+
> and `"Retry": "RetryWillNotFix"`. The string form was dropped in file-format version 1.3; `uip maestro flow init` scaffolds 1.9.
|
|
305
|
+
|
|
306
|
+
> **There is no CLI command for variable updates.** Write them with `Edit` against the `.flow` file.
|
|
307
|
+
|
|
308
|
+
### Example
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
{
|
|
312
|
+
"variables": {
|
|
313
|
+
"globals": [
|
|
314
|
+
{
|
|
315
|
+
"id": "counter",
|
|
316
|
+
"direction": "inout",
|
|
317
|
+
"type": "number",
|
|
318
|
+
"defaultValue": 0
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"id": "lastStatus",
|
|
322
|
+
"direction": "inout",
|
|
323
|
+
"type": "string",
|
|
324
|
+
"defaultValue": "pending"
|
|
325
|
+
}
|
|
326
|
+
],
|
|
327
|
+
"variableUpdates": {
|
|
328
|
+
"processItem": [
|
|
329
|
+
{
|
|
330
|
+
"variableId": "counter",
|
|
331
|
+
"expression": {
|
|
332
|
+
"type": "jsExpression",
|
|
333
|
+
"expression": "$vars.counter + 1",
|
|
334
|
+
"fieldType": "number"
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"variableId": "lastStatus",
|
|
339
|
+
"expression": {
|
|
340
|
+
"type": "jsExpression",
|
|
341
|
+
"expression": "$vars.processItem.output.status",
|
|
342
|
+
"fieldType": "string"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
> **Only `inout` variables can be updated.** Updating an `in` or `out` variable is invalid.
|
|
352
|
+
|
|
353
|
+
> **Inside loops:** variableUpdate expressions cannot access loop iteration variables like `$vars.<loopId>.currentItem`. Those are only available inside the body node's script. The variableUpdate must reference the body node's output (e.g., `$vars.bodyNode.output` as the object's `expression`).
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## Output Mapping on End Nodes
|
|
358
|
+
|
|
359
|
+
Workflow output variables (`direction: "out"`) must be mapped on End nodes. The End node's `outputs` object maps each output variable ID to a source expression.
|
|
360
|
+
|
|
361
|
+
`inout` variables are mapped the same way — an unmapped `inout` global raises a `MISSING_OUTPUT_MAPPING` warning on every End node, so map accumulators alongside the `out` variables.
|
|
362
|
+
|
|
363
|
+
### Structure
|
|
364
|
+
|
|
365
|
+
```json
|
|
366
|
+
{
|
|
367
|
+
"id": "end1",
|
|
368
|
+
"type": "core.control.end",
|
|
369
|
+
"typeVersion": "1.0",
|
|
370
|
+
"display": { "label": "End" },
|
|
371
|
+
"inputs": {},
|
|
372
|
+
"outputs": {
|
|
373
|
+
"totalAmount": {
|
|
374
|
+
"source": "=js:$vars.calculateTotal.output.amount"
|
|
375
|
+
},
|
|
376
|
+
"summary": {
|
|
377
|
+
"source": "=js:$vars.formatResult.output.text"
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
> **Every `out` variable must have a mapping on every End node** that the flow can reach. Missing mappings cause runtime errors.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Expression System
|
|
388
|
+
|
|
389
|
+
Flow uses a **Jint-based JavaScript engine** (ES2020 subset) for expressions. There are two expression formats.
|
|
390
|
+
|
|
391
|
+
### `=js:` Expressions (Full JavaScript)
|
|
392
|
+
|
|
393
|
+
Used for conditions, input values, variable updates, and output mappings. The `=js:` prefix tells the engine to evaluate the rest as JavaScript.
|
|
394
|
+
|
|
395
|
+
```
|
|
396
|
+
=js:$vars.order.amount > 1000 && $vars.order.status === "approved"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Template Expressions (`{ }`)
|
|
400
|
+
|
|
401
|
+
Used for string interpolation in **native flow string fields** only. Expressions inside single braces are evaluated and converted to strings.
|
|
402
|
+
|
|
403
|
+
```
|
|
404
|
+
Order {$vars.orderId} is {$vars.status} — total: {$vars.amount}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
> **Brace-templates do NOT work in Integration Service activity inputs.** The flow-layer template runner only processes native flow fields (decision expressions, variable updates, end-node output `source`, script bodies, agent prompt text). Fields inside `inputs.detail.bodyParameters` on `core.action.http.v2` or `uipath.connector.*` activity nodes — `url`, `headers`, `body`, `query` — are passed through to the IS runtime unchanged, so `{$vars.article}` ships literally. Observed behavior: the `$` is stripped and the braces survive (`user/{vars.article}` reaches the service). **For any dynamic value in an IS activity input, use `=js:` instead** — e.g., `` "url": "=js:`https://.../user/${$vars.article}`" `` or `"headers": { "Authorization": "=js:'Bearer ' + $vars.token" }`.
|
|
408
|
+
|
|
409
|
+
### IS Activity Inputs Require `=js:` (Critical)
|
|
410
|
+
|
|
411
|
+
Every `$vars` / `$metadata` / `$self` reference inside `inputs.detail.bodyParameters`, `inputs.detail.queryParameters`, or `inputs.detail.pathParameters` on a connector or HTTP activity node MUST be wrapped with `=js:`. Without it the value ships as a literal string at runtime.
|
|
412
|
+
|
|
413
|
+
| Wrong | Right |
|
|
414
|
+
|---|---|
|
|
415
|
+
| `"recordId": "$vars.createEntityRecord1.output.Id"` | `"recordId": "=js:$vars.createEntityRecord1.output.Id"` |
|
|
416
|
+
| `"recordId": "nodes.createEntityRecord1.output.Id"` | `"recordId": "=js:$vars.createEntityRecord1.output.Id"` |
|
|
417
|
+
| `"recordId": "{vars.createEntityRecord1.output.Id}"` | `"recordId": "=js:$vars.createEntityRecord1.output.Id"` |
|
|
418
|
+
| `"recordId": "=js:createEntityRecord1.output.Id"` | `"recordId": "=js:$vars.createEntityRecord1.output.Id"` |
|
|
419
|
+
|
|
420
|
+
The serializer rewrites `$vars` → `vars` whether or not `=js:` is present, so a missing prefix yields a confusing failure: the runtime field is bound to the literal string `"vars.X.output.Id"` (which looks like an unevaluated expression). The last row above is the opposite mistake — `=js:` is present but the `$vars.` prefix on the node reference is missing, so the expression evaluates a bare (undefined) identifier instead of the node's output. `flow validate` catches this (cli-side `expression-prefix-validator`, error with remediation hint) — older cli versions without the validator still let it through to `flow debug`. See [node-output-wiring.md](node-output-wiring.md) for the full per-node-type field reference.
|
|
421
|
+
|
|
422
|
+
### Comparison
|
|
423
|
+
|
|
424
|
+
| Feature | `=js:` | `{ }` template |
|
|
425
|
+
| --- | --- | --- |
|
|
426
|
+
| Return type | Any (boolean, number, object, array) | Always string |
|
|
427
|
+
| Use case | Conditions, inputs, mappings | Native flow text/prompt fields only |
|
|
428
|
+
| Works in IS activity inputs (HTTP URL/headers/body, connector `bodyParameters`) | Yes | **No — use `=js:`** |
|
|
429
|
+
| Full JS | Yes | Expression-only (no statements) |
|
|
430
|
+
| Prefix | `=js:` required | No prefix, braces inline |
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Available Globals
|
|
435
|
+
|
|
436
|
+
These variables are available in all expression contexts:
|
|
437
|
+
|
|
438
|
+
| Global | Description | Access pattern |
|
|
439
|
+
| --- | --- | --- |
|
|
440
|
+
| `$vars` | All workflow and node variables | `$vars.{variableId}` or `$vars.{nodeId}.{outputId}` |
|
|
441
|
+
| `$metadata` | Workflow metadata (instanceId, executionId) | `$metadata.instanceId` |
|
|
442
|
+
| `$self` | Current node's output (HTTP branch conditions only) | `$self.output.statusCode` |
|
|
443
|
+
| `$vars.<loopId>.*` | Loop iteration context (inside loops only) | `$vars.loop1.currentItem`, `$vars.loop1.currentIteration` |
|
|
444
|
+
|
|
445
|
+
### `$vars` Access Patterns
|
|
446
|
+
|
|
447
|
+
```javascript
|
|
448
|
+
// Workflow global
|
|
449
|
+
$vars.customerName
|
|
450
|
+
$vars.counter
|
|
451
|
+
|
|
452
|
+
// Trigger-associated flow input (triggerNodeId set)
|
|
453
|
+
$vars.{triggerNodeId}.output.{id}
|
|
454
|
+
|
|
455
|
+
// File input (type: "file") → object, read .FullName for the name
|
|
456
|
+
$vars.start.output.inputDoc.FullName
|
|
457
|
+
|
|
458
|
+
// Node output (script node)
|
|
459
|
+
$vars.script1.output
|
|
460
|
+
$vars.script1.output.someField
|
|
461
|
+
|
|
462
|
+
// Node output (HTTP node)
|
|
463
|
+
$vars.fetchData.output.body
|
|
464
|
+
$vars.fetchData.output.statusCode
|
|
465
|
+
$vars.fetchData.output.headers
|
|
466
|
+
|
|
467
|
+
// Node error
|
|
468
|
+
$vars.fetchData.error.message
|
|
469
|
+
$vars.fetchData.error.code
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## Expression Contexts
|
|
475
|
+
|
|
476
|
+
Expressions behave differently depending on where they appear.
|
|
477
|
+
|
|
478
|
+
### Script Node Body
|
|
479
|
+
|
|
480
|
+
The `inputs.script` field contains a function body. Full JavaScript statements are allowed (variables, loops, conditionals). The returned value becomes `$vars.{nodeId}.output`.
|
|
481
|
+
|
|
482
|
+
Scripts can return any value — objects, numbers, strings, arrays, or booleans:
|
|
483
|
+
|
|
484
|
+
```javascript
|
|
485
|
+
// Returning an object (multiple fields)
|
|
486
|
+
const items = $vars.fetchData.output.body.items;
|
|
487
|
+
const filtered = items.filter(i => i.active);
|
|
488
|
+
return { count: filtered.length, names: filtered.map(i => i.name) };
|
|
489
|
+
|
|
490
|
+
// Returning a bare value (useful for accumulators in loops)
|
|
491
|
+
return $vars.total + $vars.loop1.currentItem;
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Decision Node (`inputs.expression`)
|
|
495
|
+
|
|
496
|
+
A single boolean expression. Result is coerced to `Boolean()`.
|
|
497
|
+
|
|
498
|
+
```
|
|
499
|
+
=js:$vars.order.amount > 1000 && $vars.order.verified === true
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Determines which port fires: `true` or `false`.
|
|
503
|
+
|
|
504
|
+
### Switch Node (`inputs.cases[].expression`)
|
|
505
|
+
|
|
506
|
+
Each case has an expression evaluated in order. First truthy result wins; otherwise the `default` port fires.
|
|
507
|
+
|
|
508
|
+
```json
|
|
509
|
+
{
|
|
510
|
+
"inputs": {
|
|
511
|
+
"cases": [
|
|
512
|
+
{ "label": "Low", "expression": "$vars.score <= 30" },
|
|
513
|
+
{ "label": "Medium", "expression": "$vars.score <= 70" },
|
|
514
|
+
{ "label": "High", "expression": "$vars.score > 70" }
|
|
515
|
+
]
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### HTTP Branch Condition (`inputs.branches[].conditionExpression`)
|
|
521
|
+
|
|
522
|
+
Uses `$self` to reference the current HTTP node's response.
|
|
523
|
+
|
|
524
|
+
```
|
|
525
|
+
$self.output.statusCode >= 200 && $self.output.statusCode < 300
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Variable Update Expressions
|
|
529
|
+
|
|
530
|
+
Evaluate to the new value for the target variable. **Not a `=js:` string** — this is the one expression site that takes an object. The JS body goes in `expression` without the prefix, and `fieldType` is the target variable's declared type. See [Variable Updates](#variable-updates-variableupdates).
|
|
531
|
+
|
|
532
|
+
```json
|
|
533
|
+
{ "type": "jsExpression", "expression": "$vars.counter + 1", "fieldType": "number" }
|
|
534
|
+
{ "type": "jsExpression", "expression": "$vars.items.concat([$vars.newItem.output])", "fieldType": "array" }
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Loop Collection Expression
|
|
538
|
+
|
|
539
|
+
The `inputs.collection` field on a Loop node resolves to an array to iterate over.
|
|
540
|
+
|
|
541
|
+
```
|
|
542
|
+
=js:$vars.fetchData.output.body.items
|
|
543
|
+
=js:$vars.inputArray.filter(x => x.active)
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Inside the loop body, use `$vars.<loopId>.currentItem` and `$vars.<loopId>.currentIteration` (e.g., `$vars.loop1.currentItem`).
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## Jint Engine Constraints
|
|
551
|
+
|
|
552
|
+
The production runtime uses **Jint** (a .NET JavaScript interpreter, ES2020 subset). Key constraints:
|
|
553
|
+
|
|
554
|
+
### Supported
|
|
555
|
+
|
|
556
|
+
- Arithmetic: `+`, `-`, `*`, `/`, `%`
|
|
557
|
+
- Comparison: `===`, `!==`, `==`, `!=`, `>`, `<`, `>=`, `<=`
|
|
558
|
+
- Logical: `&&`, `||`, `!`
|
|
559
|
+
- Ternary: `condition ? a : b`
|
|
560
|
+
- String methods: `.toUpperCase()`, `.toLowerCase()`, `.trim()`, `.split()`, `.includes()`, `.startsWith()`, `.slice()`, `.substring()`
|
|
561
|
+
- Array methods: `.filter()`, `.map()`, `.reduce()`, `.find()`, `.some()`, `.every()`, `.concat()`, `.length`
|
|
562
|
+
- Object: `Object.keys()`, `Object.values()`, `Object.entries()`
|
|
563
|
+
- Math: `Math.floor()`, `Math.ceil()`, `Math.round()`, `Math.abs()`, `Math.min()`, `Math.max()`, `Math.random()`
|
|
564
|
+
- JSON: `JSON.parse()`, `JSON.stringify()`
|
|
565
|
+
- Template literals: `` `Hello ${name}` ``
|
|
566
|
+
- Destructuring: `const { a, b } = obj` (in script bodies)
|
|
567
|
+
- Spread operator: `[...arr1, ...arr2]` (in script bodies)
|
|
568
|
+
- Arrow functions: `items.filter(x => x.active)` (inline callbacks)
|
|
569
|
+
- Optional chaining / nullish coalescing: `a?.b?.[0]`, `x ?? fallback` (in script bodies)
|
|
570
|
+
|
|
571
|
+
### Not Supported
|
|
572
|
+
|
|
573
|
+
- `fetch`, `XMLHttpRequest`, `setTimeout`, `setInterval` — no network or timers
|
|
574
|
+
- `document`, `window`, `console` — no DOM or browser globals
|
|
575
|
+
- `require`, `import` — no module system
|
|
576
|
+
- `eval`, `Function` constructor — no dynamic code generation
|
|
577
|
+
- `async`/`await`, `Promise` — no async operations
|
|
578
|
+
- `Date` constructor may have limited support — prefer ISO 8601 strings
|
|
579
|
+
|
|
580
|
+
> **When in doubt, keep expressions simple.** Complex data processing should go in Script nodes where you have full statement support, not in one-line expressions.
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## Scoping Rules
|
|
585
|
+
|
|
586
|
+
### Node Output Availability
|
|
587
|
+
|
|
588
|
+
A node's output (`$vars.{nodeId}.output`) is available to **all downstream nodes** connected via edges. If a node has not executed (e.g., on an untaken branch), its `$vars` entry is `undefined`.
|
|
589
|
+
|
|
590
|
+
**Gateways are the exception.** A Decision (`core.logic.decision`) or Switch (`core.logic.switch`) never enters a downstream node's scope, even when it is directly upstream on every path. The registry declares `matchedCase` and `matchedCaseId` on both, but nothing ever assigns them — the branch choice lives on the outgoing edges, not in a variable — so a downstream read is declared, unassigned, and silently `undefined`. To act on which branch ran, recompute the condition from a node upstream of the gateway, or write an `inout` global on each branch — see [decision/impl.md — Outputs](../author/plugins/decision/impl.md#outputs).
|
|
591
|
+
|
|
592
|
+
### Loop Scope
|
|
593
|
+
|
|
594
|
+
Inside a loop body, you have access to:
|
|
595
|
+
- All parent-scope `$vars` (read-only from loop's perspective)
|
|
596
|
+
- `$vars.<loopId>.currentItem` — current array element
|
|
597
|
+
- `$vars.<loopId>.currentIteration` — 1-based iteration number
|
|
598
|
+
- `$vars.<loopId>.collection` — the original array
|
|
599
|
+
|
|
600
|
+
Where `<loopId>` is the loop node's `id` (e.g., `$vars.loop1.currentItem`).
|
|
601
|
+
|
|
602
|
+
> **Important:** Loop body nodes must have `"parentId": "<loopId>"` set in their JSON. Without this, the runtime does not know the node is inside the loop and `$vars.<loopId>.currentItem` will be undefined.
|
|
603
|
+
|
|
604
|
+
After loop completion, `$vars.<loopId>.output` holds one entry per iteration — **each entry keyed by body node id, with that node's outputs nested underneath**, NOT the body node's bare return value. See [loop/impl.md § Aggregated loop output](../author/plugins/loop/impl.md#aggregated-loop-output-varsloopidoutput).
|
|
605
|
+
|
|
606
|
+
### Subflow Scope
|
|
607
|
+
|
|
608
|
+
Subflows have their own variable scope. Parent variables are **not** automatically visible inside a subflow. Pass values explicitly via subflow `inputs` and receive results via subflow `outputs`.
|
|
609
|
+
|
|
610
|
+
---
|
|
611
|
+
|
|
612
|
+
## Variable Management via CLI
|
|
613
|
+
|
|
614
|
+
**Authoring a flow: use `Edit`.** Add, remove, and update `variables.globals` and `variables.variableUpdates` directly in the `.flow` file. `variableUpdates` has no CLI command at all.
|
|
615
|
+
|
|
616
|
+
**Declaring an eval input: use the CLI.** Globals have a narrow CLI surface that the evaluate capability depends on, because `eval add` validates its `--inputs` keys against the flow's declared inputs:
|
|
617
|
+
|
|
618
|
+
| Command | Use |
|
|
619
|
+
| --- | --- |
|
|
620
|
+
| `uip maestro flow variable add <flow> <id> --direction in --type <type>` | Declare an input the eval set will supply |
|
|
621
|
+
| `uip maestro flow variable list <flow> --output json` | Check what the flow already declares |
|
|
622
|
+
| `uip maestro flow variable remove <flow> <id>` | Drop a declared global |
|
|
623
|
+
|
|
624
|
+
See [evaluate/eval-sets-guide.md](../evaluate/eval-sets-guide.md).
|
|
625
|
+
|
|
626
|
+
> **`variable add --direction in` binds the variable to a trigger** by writing `triggerNodeId`. That binding is what puts the input in the packed entry point's contract — without it `flow pack` emits an empty `input.properties` while `validate` and `format` stay green. The CLI infers the flow's single trigger; if a flow has more than one, it fails and asks for `--trigger-node-id <nodeId>` to say which entry point the input belongs to. Hand-authored globals need the same field — see [Workflow Variables](#workflow-variables).
|
|
627
|
+
|
|
628
|
+
### Adding a workflow input variable
|
|
629
|
+
|
|
630
|
+
1. Open `<ProjectName>.flow`
|
|
631
|
+
2. Add the variable object to `variables.globals`
|
|
632
|
+
3. Run `uip maestro flow validate` to check for errors
|
|
633
|
+
|
|
634
|
+
### Adding node variables after manual node insertion
|
|
635
|
+
|
|
636
|
+
When adding nodes via `Edit` (not CLI), you must also add corresponding entries to `variables.nodes`:
|
|
637
|
+
|
|
638
|
+
```json
|
|
639
|
+
{
|
|
640
|
+
"id": "myScript.output",
|
|
641
|
+
"type": "object",
|
|
642
|
+
"binding": { "nodeId": "myScript", "outputId": "output" }
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
"id": "myScript.error",
|
|
646
|
+
"type": "object",
|
|
647
|
+
"binding": { "nodeId": "myScript", "outputId": "error" }
|
|
648
|
+
}
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
> **When using `uip maestro flow node add`**, node variables are handled automatically. Only add them manually when using `Edit` against the `.flow` file.
|
|
652
|
+
|
|
653
|
+
### Mapping outputs on End nodes
|
|
654
|
+
|
|
655
|
+
For every `out` variable, add a mapping in each End node's `outputs`:
|
|
656
|
+
|
|
657
|
+
```json
|
|
658
|
+
"outputs": {
|
|
659
|
+
"result": {
|
|
660
|
+
"source": "=js:$vars.processData.output"
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
667
|
+
## Complete Example
|
|
668
|
+
|
|
669
|
+
A flow with input, state, and output variables:
|
|
670
|
+
|
|
671
|
+
```json
|
|
672
|
+
{
|
|
673
|
+
"variables": {
|
|
674
|
+
"globals": [
|
|
675
|
+
{
|
|
676
|
+
"id": "inputItems",
|
|
677
|
+
"direction": "in",
|
|
678
|
+
"type": "array",
|
|
679
|
+
"subType": "object",
|
|
680
|
+
"defaultValue": [],
|
|
681
|
+
"description": "Items to process",
|
|
682
|
+
"triggerNodeId": "start"
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
"id": "processedCount",
|
|
686
|
+
"direction": "inout",
|
|
687
|
+
"type": "number",
|
|
688
|
+
"defaultValue": 0
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
"id": "result",
|
|
692
|
+
"direction": "out",
|
|
693
|
+
"type": "object",
|
|
694
|
+
"description": "Processing summary"
|
|
695
|
+
}
|
|
696
|
+
],
|
|
697
|
+
"nodes": [
|
|
698
|
+
{
|
|
699
|
+
"id": "transform1.output",
|
|
700
|
+
"type": "object",
|
|
701
|
+
"binding": { "nodeId": "transform1", "outputId": "output" }
|
|
702
|
+
}
|
|
703
|
+
],
|
|
704
|
+
"variableUpdates": {
|
|
705
|
+
"transform1": [
|
|
706
|
+
{
|
|
707
|
+
"variableId": "processedCount",
|
|
708
|
+
"expression": {
|
|
709
|
+
"type": "jsExpression",
|
|
710
|
+
"expression": "$vars.processedCount + $vars.transform1.output.count",
|
|
711
|
+
"fieldType": "number"
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
]
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
"nodes": [
|
|
718
|
+
{
|
|
719
|
+
"id": "start",
|
|
720
|
+
"type": "core.trigger.manual",
|
|
721
|
+
"typeVersion": "1.0",
|
|
722
|
+
"display": { "label": "Manual trigger" },
|
|
723
|
+
"inputs": {
|
|
724
|
+
"entryPointId": "<uuid>"
|
|
725
|
+
},
|
|
726
|
+
"outputs": {
|
|
727
|
+
"output": {
|
|
728
|
+
"type": "object",
|
|
729
|
+
"description": "Data passed when the flow is triggered manually.",
|
|
730
|
+
"source": "null",
|
|
731
|
+
"var": "output"
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
"id": "transform1",
|
|
737
|
+
"type": "core.action.script",
|
|
738
|
+
"typeVersion": "1.0",
|
|
739
|
+
"inputs": {
|
|
740
|
+
"script": "const items = $vars.inputItems.filter(i => i.active);\nreturn { count: items.length, items: items };"
|
|
741
|
+
},
|
|
742
|
+
"outputs": {
|
|
743
|
+
"output": {
|
|
744
|
+
"type": "object",
|
|
745
|
+
"description": "The return value of the script",
|
|
746
|
+
"source": "=result.response",
|
|
747
|
+
"var": "output"
|
|
748
|
+
},
|
|
749
|
+
"error": {
|
|
750
|
+
"type": "object",
|
|
751
|
+
"description": "Error information if the script fails",
|
|
752
|
+
"source": "=Error",
|
|
753
|
+
"var": "error"
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
"id": "end1",
|
|
759
|
+
"type": "core.control.end",
|
|
760
|
+
"typeVersion": "1.0",
|
|
761
|
+
"display": { "label": "End" },
|
|
762
|
+
"inputs": {},
|
|
763
|
+
"outputs": {
|
|
764
|
+
"result": {
|
|
765
|
+
"source": "=js:({ total: $vars.processedCount, data: $vars.transform1.output })"
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
],
|
|
770
|
+
"edges": [
|
|
771
|
+
{
|
|
772
|
+
"id": "e1",
|
|
773
|
+
"sourceNodeId": "start",
|
|
774
|
+
"sourcePort": "output",
|
|
775
|
+
"targetNodeId": "transform1",
|
|
776
|
+
"targetPort": "input"
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
"id": "e2",
|
|
780
|
+
"sourceNodeId": "transform1",
|
|
781
|
+
"sourcePort": "success",
|
|
782
|
+
"targetNodeId": "end1",
|
|
783
|
+
"targetPort": "input"
|
|
784
|
+
}
|
|
785
|
+
]
|
|
786
|
+
}
|
|
787
|
+
```
|