@uipath/maestro-builder-sdk 5.2.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 (238) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +322 -0
  3. package/dist/bindings-v2.d.ts +37 -0
  4. package/dist/bindings-v2.js +155 -0
  5. package/dist/bindings.d.ts +6 -0
  6. package/dist/bindings.js +6 -0
  7. package/dist/bpmn/bpmn-expr-check.d.ts +41 -0
  8. package/dist/bpmn/bpmn-expr-check.js +218 -0
  9. package/dist/bpmn/bpmn-sdk.d.ts +2257 -0
  10. package/dist/bpmn/bpmn-sdk.js +1476 -0
  11. package/dist/bpmn/check-cli.d.ts +3 -0
  12. package/dist/bpmn/check-cli.js +32 -0
  13. package/dist/bpmn/check.d.ts +25 -0
  14. package/dist/bpmn/check.js +430 -0
  15. package/dist/bpmn/compile-cli.d.ts +3 -0
  16. package/dist/bpmn/compile-cli.js +60 -0
  17. package/dist/bpmn/connector.d.ts +56 -0
  18. package/dist/bpmn/connector.js +199 -0
  19. package/dist/bpmn/decompile-cli.d.ts +8 -0
  20. package/dist/bpmn/decompile-cli.js +54 -0
  21. package/dist/bpmn/decompile.d.ts +6 -0
  22. package/dist/bpmn/decompile.js +1108 -0
  23. package/dist/bpmn/format-profile.d.ts +27 -0
  24. package/dist/bpmn/format-profile.js +11 -0
  25. package/dist/bpmn/intsvc.d.ts +77 -0
  26. package/dist/bpmn/intsvc.js +155 -0
  27. package/dist/bpmn/load.d.ts +4 -0
  28. package/dist/bpmn/load.js +22 -0
  29. package/dist/bpmn/merge-cli.d.ts +3 -0
  30. package/dist/bpmn/merge-cli.js +45 -0
  31. package/dist/bpmn/merge.d.ts +19 -0
  32. package/dist/bpmn/merge.js +293 -0
  33. package/dist/bpmn/registry-types.json +1869 -0
  34. package/dist/bpmn/serialize.d.ts +28 -0
  35. package/dist/bpmn/serialize.js +757 -0
  36. package/dist/bpmn/tidy-cli.d.ts +2 -0
  37. package/dist/bpmn/tidy-cli.js +39 -0
  38. package/dist/bpmn/typed-node.d.ts +382 -0
  39. package/dist/bpmn/typed-node.js +551 -0
  40. package/dist/bpmn/uipath-moddle.v1.json +823 -0
  41. package/dist/bpmn/xml-ranges.d.ts +45 -0
  42. package/dist/bpmn/xml-ranges.js +151 -0
  43. package/dist/case/case-expr-check.d.ts +35 -0
  44. package/dist/case/case-expr-check.js +85 -0
  45. package/dist/case/case-sdk.d.ts +1282 -0
  46. package/dist/case/case-sdk.js +923 -0
  47. package/dist/case/check-cli.d.ts +3 -0
  48. package/dist/case/check-cli.js +31 -0
  49. package/dist/case/check.d.ts +18 -0
  50. package/dist/case/check.js +456 -0
  51. package/dist/case/compile-cli.d.ts +3 -0
  52. package/dist/case/compile-cli.js +291 -0
  53. package/dist/case/decompile-cli.d.ts +9 -0
  54. package/dist/case/decompile-cli.js +117 -0
  55. package/dist/case/decompile.d.ts +187 -0
  56. package/dist/case/decompile.js +1170 -0
  57. package/dist/case/entry-points.d.ts +79 -0
  58. package/dist/case/entry-points.js +118 -0
  59. package/dist/case/format-profile.d.ts +60 -0
  60. package/dist/case/format-profile.js +79 -0
  61. package/dist/case/ids.d.ts +24 -0
  62. package/dist/case/ids.js +76 -0
  63. package/dist/case/load.d.ts +12 -0
  64. package/dist/case/load.js +32 -0
  65. package/dist/case/preserve.d.ts +133 -0
  66. package/dist/case/preserve.js +105 -0
  67. package/dist/case/serialize.d.ts +10 -0
  68. package/dist/case/serialize.js +1414 -0
  69. package/dist/check-cli.d.ts +3 -0
  70. package/dist/check-cli.js +118 -0
  71. package/dist/check.d.ts +146 -0
  72. package/dist/check.js +4898 -0
  73. package/dist/cli/commands/bpmn.d.ts +2 -0
  74. package/dist/cli/commands/bpmn.js +73 -0
  75. package/dist/cli/commands/case.d.ts +2 -0
  76. package/dist/cli/commands/case.js +60 -0
  77. package/dist/cli/commands/flow.d.ts +2 -0
  78. package/dist/cli/commands/flow.js +99 -0
  79. package/dist/cli/commands/registry.d.ts +10 -0
  80. package/dist/cli/commands/registry.js +170 -0
  81. package/dist/cli/common.d.ts +30 -0
  82. package/dist/cli/common.js +92 -0
  83. package/dist/cli/index.d.ts +2 -0
  84. package/dist/cli/index.js +18 -0
  85. package/dist/cli-run.d.ts +2 -0
  86. package/dist/cli-run.js +42 -0
  87. package/dist/compile-cli.d.ts +3 -0
  88. package/dist/compile-cli.js +160 -0
  89. package/dist/config.d.ts +47 -0
  90. package/dist/config.js +201 -0
  91. package/dist/core/actions.d.ts +3244 -0
  92. package/dist/core/actions.js +1062 -0
  93. package/dist/core/binding-messages.d.ts +1 -0
  94. package/dist/core/binding-messages.js +16 -0
  95. package/dist/core/bindings.d.ts +12 -0
  96. package/dist/core/bindings.js +67 -0
  97. package/dist/core/ceql.d.ts +73 -0
  98. package/dist/core/ceql.js +272 -0
  99. package/dist/core/cli-spelling.d.ts +39 -0
  100. package/dist/core/cli-spelling.js +62 -0
  101. package/dist/core/connector-raw-node.d.ts +21 -0
  102. package/dist/core/connector-raw-node.js +47 -0
  103. package/dist/core/connectors.d.ts +184 -0
  104. package/dist/core/connectors.js +128 -0
  105. package/dist/core/expr-check.d.ts +93 -0
  106. package/dist/core/expr-check.js +186 -0
  107. package/dist/core/expr.d.ts +323 -0
  108. package/dist/core/expr.js +400 -0
  109. package/dist/core/index.d.ts +10 -0
  110. package/dist/core/index.js +10 -0
  111. package/dist/core/library.d.ts +440 -0
  112. package/dist/core/library.js +1183 -0
  113. package/dist/core/list-envelope.d.ts +45 -0
  114. package/dist/core/list-envelope.js +97 -0
  115. package/dist/core/lookup-store.d.ts +22 -0
  116. package/dist/core/lookup-store.js +85 -0
  117. package/dist/core/lookups.d.ts +227 -0
  118. package/dist/core/lookups.js +231 -0
  119. package/dist/core/node-classes.d.ts +234 -0
  120. package/dist/core/node-classes.js +158 -0
  121. package/dist/core/script-return.d.ts +68 -0
  122. package/dist/core/script-return.js +197 -0
  123. package/dist/core/stable-id.d.ts +28 -0
  124. package/dist/core/stable-id.js +37 -0
  125. package/dist/core-definitions.json +16249 -0
  126. package/dist/decompile-cli.d.ts +3 -0
  127. package/dist/decompile-cli.js +131 -0
  128. package/dist/decompile.d.ts +138 -0
  129. package/dist/decompile.js +2482 -0
  130. package/dist/emit.d.ts +10 -0
  131. package/dist/emit.js +60 -0
  132. package/dist/event-filters.d.ts +130 -0
  133. package/dist/event-filters.js +137 -0
  134. package/dist/flow-expr-check.d.ts +17 -0
  135. package/dist/flow-expr-check.js +193 -0
  136. package/dist/flow-sdk.d.ts +1341 -0
  137. package/dist/flow-sdk.js +1164 -0
  138. package/dist/flow-variables.d.ts +13 -0
  139. package/dist/flow-variables.js +42 -0
  140. package/dist/format-profile.d.ts +72 -0
  141. package/dist/format-profile.js +97 -0
  142. package/dist/generators/_connections.py +287 -0
  143. package/dist/generators/_events.py +355 -0
  144. package/dist/generators/_lookups.py +114 -0
  145. package/dist/generators/_naming.py +185 -0
  146. package/dist/generators/_objects.py +299 -0
  147. package/dist/generators/_resolve.py +273 -0
  148. package/dist/generators/convert_library_to_md.py +1441 -0
  149. package/dist/generators/extract_library.py +125 -0
  150. package/dist/generators/generate_connectors_ts.py +936 -0
  151. package/dist/generators/generate_library_json.py +2527 -0
  152. package/dist/generators/generate_triggers_ts.py +110 -0
  153. package/dist/generators/materialize_registry.py +155 -0
  154. package/dist/generators/prepare_connector.py +1688 -0
  155. package/dist/index.d.ts +35 -0
  156. package/dist/index.js +35 -0
  157. package/dist/ixp-definition.json +1982 -0
  158. package/dist/library.d.ts +6 -0
  159. package/dist/library.js +6 -0
  160. package/dist/load.d.ts +16 -0
  161. package/dist/load.js +95 -0
  162. package/dist/merge-cli.d.ts +3 -0
  163. package/dist/merge-cli.js +47 -0
  164. package/dist/merge.d.ts +125 -0
  165. package/dist/merge.js +0 -0
  166. package/dist/migrate.d.ts +15 -0
  167. package/dist/migrate.js +245 -0
  168. package/dist/node-runtime.d.ts +3 -0
  169. package/dist/node-runtime.js +22 -0
  170. package/dist/package-name.d.ts +17 -0
  171. package/dist/package-name.js +17 -0
  172. package/dist/ref-resolve.d.ts +77 -0
  173. package/dist/ref-resolve.js +170 -0
  174. package/dist/registry/cache.d.ts +55 -0
  175. package/dist/registry/cache.js +134 -0
  176. package/dist/registry/curated-overlay.d.ts +16 -0
  177. package/dist/registry/curated-overlay.js +62 -0
  178. package/dist/registry/extractor.d.ts +22 -0
  179. package/dist/registry/extractor.js +18 -0
  180. package/dist/registry/materialize-bin.d.ts +2 -0
  181. package/dist/registry/materialize-bin.js +7 -0
  182. package/dist/registry/materialize-cli.d.ts +1 -0
  183. package/dist/registry/materialize-cli.js +46 -0
  184. package/dist/registry/materializer.d.ts +23 -0
  185. package/dist/registry/materializer.js +34 -0
  186. package/dist/registry/path-cli.d.ts +1 -0
  187. package/dist/registry/path-cli.js +56 -0
  188. package/dist/registry/prepare-cli.d.ts +62 -0
  189. package/dist/registry/prepare-cli.js +185 -0
  190. package/dist/registry/pull-cli.d.ts +1 -0
  191. package/dist/registry/pull-cli.js +274 -0
  192. package/dist/registry/python.d.ts +26 -0
  193. package/dist/registry/python.js +46 -0
  194. package/dist/registry/search-cli.d.ts +52 -0
  195. package/dist/registry/search-cli.js +159 -0
  196. package/dist/schema-version.d.ts +165 -0
  197. package/dist/schema-version.js +148 -0
  198. package/dist/serialize.d.ts +64 -0
  199. package/dist/serialize.js +6398 -0
  200. package/lib/README.md +112 -0
  201. package/lib/library-json.samples/index.json +158 -0
  202. package/lib/library-json.samples/invariant-collections.json +83 -0
  203. package/lib/library-json.samples/list-envelopes.json +123 -0
  204. package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.json +131 -0
  205. package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.v1def.json +306 -0
  206. package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.json +86 -0
  207. package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.v1def.json +208 -0
  208. package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.json +2040 -0
  209. package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.v1def.json +195 -0
  210. package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.json +169 -0
  211. package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.v1def.json +209 -0
  212. package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.json +63 -0
  213. package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.v1def.json +262 -0
  214. package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.json +63 -0
  215. package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.v1def.json +213 -0
  216. package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.json +227 -0
  217. package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.v1def.json +373 -0
  218. package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.json +116 -0
  219. package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.v1def.json +369 -0
  220. package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.json +56 -0
  221. package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.v1def.json +256 -0
  222. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.json +116 -0
  223. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.v1def.json +320 -0
  224. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.json +56 -0
  225. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.v1def.json +207 -0
  226. package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.json +107 -0
  227. package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.v1def.json +264 -0
  228. package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.json +142 -0
  229. package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.v1def.json +306 -0
  230. package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.json +107 -0
  231. package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.v1def.json +217 -0
  232. package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.json +85 -0
  233. package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.v1def.json +209 -0
  234. package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.json +755 -0
  235. package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.v1def.json +513 -0
  236. package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.json +122 -0
  237. package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.v1def.json +227 -0
  238. package/package.json +85 -0
@@ -0,0 +1,1341 @@
1
+ /**
2
+ * flow-sdk — a small fluent builder for UiPath Flow workflows.
3
+ *
4
+ * You author a workflow as TypeScript code that *constructs* a graph of nodes
5
+ * and edges. Calling `.build()` returns a plain description of that graph; the
6
+ * `compile` tool serializes it into a real `.flow` JSON file.
7
+ *
8
+ * This is deliberately a builder, not a program: control flow (branch/loop) is
9
+ * expressed by calling `.branch()` / `.loop()`, not with native `if`/`for`.
10
+ * Data references are expressed with the expression helpers (`input`, `out`,
11
+ * `v`, `js`, `tmpl`) rather than by reading real values — nothing actually runs
12
+ * at build time except the graph construction.
13
+ *
14
+ * The expression helpers and action specs are shared across all builder SDKs
15
+ * and live in `core/`; this module re-exports them so the historical
16
+ * `flow-sdk.js` authoring surface is unchanged, and adds the Flow-specific
17
+ * builder (steps, branches, loops, return).
18
+ */
19
+ export * from './core/expr.js';
20
+ export * from './core/actions.js';
21
+ export { resolveFlowRefs, resolveRefPath, hasFileRefs } from './ref-resolve.js';
22
+ export type { RefReader, ResolveRefsOptions } from './ref-resolve.js';
23
+ export * from './core/connectors.js';
24
+ export * from './core/lookups.js';
25
+ export * from './core/node-classes.js';
26
+ import { Expr } from './core/expr.js';
27
+ import type { ErrorEnvelopeField, TypeDesc } from './core/expr.js';
28
+ import type { ActionSpec, EventSubscription, TriggerOptions } from './core/actions.js';
29
+ import type { FlowAction, FlowTrigger } from './core/node-classes.js';
30
+ import type { TriggerDescriptor } from './core/connectors.js';
31
+ export { FlowBuildError, checkFlowExpressions } from './flow-expr-check.js';
32
+ export type { LocatedDiagnostic } from './flow-expr-check.js';
33
+ /** A step that runs a child flow. Built by `subflow(child, inputs)`. */
34
+ export interface SubflowSpec {
35
+ kind: 'subflow';
36
+ /** The child flow's built description — its own inputs, outputs and steps. */
37
+ child: BuiltFlow;
38
+ /** One value per child input, keyed by the child's declared input name. */
39
+ inputs: Record<string, Expr>;
40
+ }
41
+ /** What `.step()` accepts here: the shared actions plus this SDK's subflow. */
42
+ export type FlowActionSpec = ActionSpec | SubflowSpec;
43
+ /** Anything `subflow()` accepts as the child: a builder, or an already-built flow. */
44
+ export type ChildFlow = BuiltFlow | {
45
+ build(): BuiltFlow;
46
+ };
47
+ export interface VarDecl {
48
+ name: string;
49
+ type: TypeDesc;
50
+ default?: unknown;
51
+ /** Human-readable description, persisted on the variable. */
52
+ description?: string;
53
+ /** Sub-type for complex types (e.g. an array's item type). */
54
+ subType?: string;
55
+ /** JSON schema for complex type validation (object/array shapes). */
56
+ schema?: Record<string, unknown>;
57
+ }
58
+ /**
59
+ * The rich spelling of a variable declaration: pass it instead of a bare
60
+ * `types.*` descriptor wherever `.input()` / `.output()` / `.var()` take one,
61
+ * to carry the metadata the `.flow` format persists on a global — a
62
+ * description, a `subType`, a JSON `schema` for object/array shapes, and (for
63
+ * inputs and vars) a `default`.
64
+ */
65
+ export interface VarSpec {
66
+ /** The variable's type, one of the `types.*` descriptors. */
67
+ type: TypeDesc;
68
+ /** Human-readable description, persisted on the variable. */
69
+ description?: string;
70
+ /** Sub-type for complex types (e.g. an array's item type). */
71
+ subType?: string;
72
+ /** JSON schema for complex type validation (object/array shapes). */
73
+ schema?: Record<string, unknown>;
74
+ /** Default value — inputs and vars only; the format forbids it on outputs. */
75
+ default?: unknown;
76
+ }
77
+ /**
78
+ * The eight intervals the designer offers in its Frequency dropdown. Any other
79
+ * valid
80
+ * {@link https://docs.digi.com/resources/documentation/digidocs/90001488-13/reference/r_iso_8601_duration_format.htm | ISO-8601 repeating interval}
81
+ * works too (see `ScheduleEvery`) — these are
82
+ * just the ones that round-trip as a named preset rather than as "custom".
83
+ */
84
+ export declare const SCHEDULE_PRESETS: readonly ["R/PT5M", "R/PT15M", "R/PT30M", "R/PT1H", "R/PT6H", "R/PT12H", "R/P1D", "R/P1W"];
85
+ export type SchedulePreset = (typeof SCHEDULE_PRESETS)[number];
86
+ /**
87
+ * How often a scheduled flow runs, as an
88
+ * {@link https://docs.digi.com/resources/documentation/digidocs/90001488-13/reference/r_iso_8601_duration_format.htm | ISO-8601 repeating interval}:
89
+ * `R/` followed by a duration. `R/PT1H` = every hour, `R/PT30M` = every half
90
+ * hour, `R/P1D` = daily, `R/P1W` = weekly.
91
+ *
92
+ * @remarks
93
+ * The union with `string` is deliberate — a preset autocompletes, and any other
94
+ * valid interval (`R/PT45M`, `R/P3D`, `R/2026-05-14T09:00:00Z/P1W`) is accepted.
95
+ * `check` validates the format and rejects a schedule that can never fire.
96
+ */
97
+ export type ScheduleEvery = SchedulePreset | (string & {});
98
+ export interface ScheduledInputs {
99
+ /**
100
+ * The recurring interval, e.g. `'R/PT1H'` for hourly.
101
+ *
102
+ * @remarks
103
+ * ONE field, deliberately, where the emitted `.flow` has two: the platform
104
+ * encodes a preset in `timerPreset` and anything else as
105
+ * `timerPreset: 'custom'` + `timerValue`. That split is a designer-form
106
+ * artifact — the runtime collapses it right back to a single interval — so
107
+ * the serializer does the encoding and there is nothing here to get wrong.
108
+ */
109
+ every: ScheduleEvery;
110
+ }
111
+ /**
112
+ * What starts the flow. Three options: the manual trigger (the default — omit
113
+ * `.trigger()`), a schedule, or a CONNECTOR EVENT.
114
+ */
115
+ export type TriggerSpec = {
116
+ kind: 'manual';
117
+ } | {
118
+ kind: 'scheduled';
119
+ inputs: ScheduledInputs;
120
+ } | {
121
+ kind: 'event';
122
+ subscription: EventSubscription;
123
+ } | {
124
+ kind: 'form';
125
+ } | {
126
+ kind: 'conversation';
127
+ } | {
128
+ kind: 'voice';
129
+ };
130
+ /**
131
+ * The manual trigger, explicitly. Omitting `.trigger(...)` means exactly this —
132
+ * the factory exists so decompiled source can carry the trigger's exact
133
+ * definition version (`.trigger(manual(), { version: '1.0.0' })`) instead of
134
+ * leaving the default implicit, and so hand-written flows can opt into the
135
+ * same explicitness.
136
+ *
137
+ * @returns A trigger spec to pass to `.trigger(...)`.
138
+ */
139
+ export declare function manual(): TriggerSpec;
140
+ /**
141
+ * Start the flow when a connector event fires — e.g. an email arriving in a
142
+ * mailbox folder.
143
+ *
144
+ * @remarks
145
+ * ```ts
146
+ * export default flow('intake')
147
+ * .trigger(onEvent({
148
+ * connector: 'uipath-microsoft-outlook365',
149
+ * event: 'email-received',
150
+ * where: { parentFolderId: inboxId },
151
+ * }))
152
+ * .step('extract', script({ code: 'return { subject: $vars.start.output.subject };' }))
153
+ * .build();
154
+ * ```
155
+ *
156
+ * A generated {@link TriggerDescriptor} can supply the connector/event instead —
157
+ * `.trigger(onEvent(EmailReceived, { where: { parentFolderId: inboxId } }))` —
158
+ * see `sdk/connectors/<key>.triggers.ts`.
159
+ *
160
+ * The trigger's payload is read like any step output — `out('start', 'subject')`
161
+ * — and locally it is supplied as flow input (`--input`), because a start trigger
162
+ * produces no dispatch record. **No local rung fires a real event**: what a green
163
+ * ladder proves is the right trigger type, the right subscription, and that the
164
+ * graph runs. See `references/event-trigger.md`.
165
+ *
166
+ * To pause an already-running flow instead, use `waitForEvent(...)` as a step —
167
+ * the same subscription, the sibling node type.
168
+ *
169
+ * This is the TYPED form — a generated trigger descriptor identifies the event,
170
+ * as in `onEvent(EmailReceived, { where: { … } })`.
171
+ *
172
+ * @param descriptor - The generated trigger, from a prepared connector module.
173
+ * @param opts - The event's `where` scope, `filters`, and symbolic
174
+ * `connection` / `folder`.
175
+ * @returns A trigger spec to pass to `.trigger(...)`.
176
+ */
177
+ export declare function onEvent<W>(descriptor: TriggerDescriptor<W, unknown>, opts?: TriggerOptions<W>): TriggerSpec;
178
+ /**
179
+ * Stringly form, for an event with no prepared module.
180
+ *
181
+ * @param subscription - The event to start on: `connector`, `event`, its `where`
182
+ * scope, and optional `filters`.
183
+ * @returns A trigger spec to pass to `.trigger(...)`.
184
+ */
185
+ export declare function onEvent(subscription: EventSubscription): TriggerSpec;
186
+ /**
187
+ * Start the flow on a recurring schedule instead of on demand.
188
+ *
189
+ * @remarks
190
+ * Field shapes, the interval format, and what a local run does and does not
191
+ * prove: `references/scheduled-trigger.md`.
192
+ *
193
+ * @example
194
+ * **Run a flow daily**
195
+ * ```ts
196
+ * export default flow('nightly-rollup')
197
+ * .trigger(scheduled({ every: 'R/P1D' }))
198
+ * .step('rollup', script({ code: 'return { ok: true };' }))
199
+ * .build();
200
+ * ```
201
+ *
202
+ * @param inputs - The recurring interval, e.g. `{ every: 'R/PT1H' }`.
203
+ * @returns A trigger spec to pass to `.trigger(...)`.
204
+ */
205
+ export declare function scheduled(inputs: ScheduledInputs): TriggerSpec;
206
+ /**
207
+ * Start the flow from a FORM a person fills in (`core.trigger.form`) — the
208
+ * platform renders one field per flow input and the submitted values ARE the
209
+ * flow's inputs.
210
+ *
211
+ * ```ts
212
+ * export default flow('expense-request')
213
+ * .input({ amount: types.number, reason: types.string })
214
+ * .trigger(formTrigger())
215
+ * .step('review', hitl({ … }))
216
+ * .build();
217
+ * ```
218
+ *
219
+ * The form's fields are DERIVED from `.input()` — one per input, the same rule
220
+ * the designer's own form-trigger editor applies to a flow's arguments: the
221
+ * field id is the input's name (so submitted values line up by name), the label
222
+ * is the name sentence-cased, the field type follows the input's type, and a
223
+ * field is required exactly when its input declares no default.
224
+ *
225
+ * The definition is BUNDLED from the workbench manifest — the tenant registry
226
+ * does not serve the family (same availability note as do-while).
227
+ *
228
+ * No local rung renders a form: `--input` supplies the values locally, and a
229
+ * green ladder proves the trigger type, the derived schema, and that the graph
230
+ * runs — not that a person saw a form.
231
+ *
232
+ * @returns A trigger spec to pass to `.trigger(...)`.
233
+ */
234
+ export declare function formTrigger(): TriggerSpec;
235
+ /**
236
+ * Start the flow when a new CONVERSATION is created
237
+ * (`core.trigger.conversation`) — the entry point for a chat-driven process.
238
+ *
239
+ * ```ts
240
+ * export default flow('support-chat')
241
+ * .trigger(conversationTrigger())
242
+ * .step('listen', waitForMessage({ conversationId: out('start', 'conversationId') }))
243
+ * .step('answer', sendMessage({
244
+ * conversationId: out('start', 'conversationId'),
245
+ * exchangeId: out('listen', 'conversationContext.latestExchangeId'),
246
+ * content: 'Looking into it.',
247
+ * }))
248
+ * .build();
249
+ * ```
250
+ *
251
+ * The trigger publishes the conversation it started —
252
+ * `out('start', 'conversationId')` — which is what every conversational step
253
+ * is keyed by. Nothing else is authored on it.
254
+ *
255
+ * The definition is BUNDLED from the workbench manifest: the family is
256
+ * `AvailableOnTenant: false` today, so a flow compiles and validates offline
257
+ * while the platform catches up (the do-while precedent).
258
+ *
259
+ * @returns A trigger spec to pass to `.trigger(...)`.
260
+ */
261
+ export declare function conversationTrigger(): TriggerSpec;
262
+ /**
263
+ * Start the flow when a phone call comes IN (`core.trigger.voice`).
264
+ *
265
+ * ```ts
266
+ * export default flow('support-line')
267
+ * .trigger(voiceTrigger())
268
+ * .step('greet', voiceAgent({
269
+ * systemPrompt: 'Greet {{input.customerName}} and find out why they called.',
270
+ * inputs: { customerName: input('customerName') },
271
+ * callContext: out('start', 'callContext'),
272
+ * }))
273
+ * .step('hangUp', endCall({ callContext: out('start', 'callContext') }))
274
+ * .build();
275
+ * ```
276
+ *
277
+ * The trigger publishes the live call as `out('start', 'callContext')` — the
278
+ * object (`{ type, id, conversationId, … }`) every voice step is keyed by.
279
+ * Nothing else is authored on it.
280
+ *
281
+ * The definition is BUNDLED from the workbench manifest: the family is
282
+ * `AvailableOnTenant: false` today (the do-while precedent).
283
+ *
284
+ * @returns A trigger spec to pass to `.trigger(...)`.
285
+ */
286
+ export declare function voiceTrigger(): TriggerSpec;
287
+ /** A value a `.switch` case compares the discriminant against. */
288
+ export type CaseValue = string | number | boolean;
289
+ /** One arm of a built `.switch` (the serializer's view: body already collected). */
290
+ export interface SwitchArm {
291
+ value: CaseValue;
292
+ label?: string;
293
+ body: Step[];
294
+ }
295
+ /**
296
+ * Options shared by every builder method that creates a definition-backed node:
297
+ * `version` selects the exact node definition to compile against, and `updates`
298
+ * assigns flow variables when the node completes.
299
+ */
300
+ export interface NodeOptions {
301
+ /**
302
+ * The EXACT `definitions[].version` (and node `typeVersion`) this node must
303
+ * compile against — a request and a constraint, never a "latest" selector.
304
+ * Omit it and the SDK uses its pinned default for the node family; name a
305
+ * version the SDK cannot resolve exactly and compilation fails rather than
306
+ * substituting another version.
307
+ */
308
+ version?: string;
309
+ /**
310
+ * Flow-variable assignments applied when this node completes — the format's
311
+ * `variables.variableUpdates[nodeId]`, attached to the real node exactly as
312
+ * Flow JSON stores it. Keys name declared `.var()` variables (or flow
313
+ * outputs); values are `Expr`s or raw literals.
314
+ *
315
+ * @remarks
316
+ * Not accepted on `.branch()`, `.switch()`, `.parallel()`, or `.trigger()` —
317
+ * the platform strips updates from decision/switch/merge nodes on save, and a
318
+ * trigger has not run anything to assign from.
319
+ */
320
+ updates?: Record<string, Expr | unknown>;
321
+ /**
322
+ * What the canvas shows on this node (`display.label`). Defaults to the step
323
+ * name.
324
+ *
325
+ * @remarks
326
+ * Purely cosmetic, and deliberately separate from the step name: the NAME is
327
+ * the node's identity — it becomes the node id and every `out('<step>', …)`
328
+ * reads through it — so renaming what a reviewer sees must not move the node
329
+ * or rewrite its expressions. Use a step name you want to write code against
330
+ * and a label you want to read on the canvas.
331
+ *
332
+ * ```ts
333
+ * .step('fetchInv', http({ url, managed: true }), { label: 'Fetch invoice' })
334
+ * ```
335
+ *
336
+ * `.branch()`, `.switch()`, `.loop()`, `.doWhile()`, `.parallel()` and
337
+ * `.terminate()` take their label as a positional argument instead.
338
+ */
339
+ label?: string;
340
+ }
341
+ /**
342
+ * `.return(...)`-specific options.
343
+ *
344
+ * @remarks
345
+ * An End is the one node the builder used to give no way to name: every other
346
+ * construct takes its id positionally (`.step('<name>', …)`, `.terminate('<name>')`),
347
+ * but a `.return()` always minted `end`, `end2`, … and labelled the node `End`.
348
+ * That made a decompile → compile round trip impossible for any flow whose Ends
349
+ * carry designer-chosen ids — the normal case, since the canvas names an End
350
+ * after the branch arm that reaches it, so `endNiceDay` / `endBringJacket` rather
351
+ * than `end` / `end2`. Decompile emitted a `.layout({ nodes: { endNiceDay: … } })`
352
+ * block naming ids the recompile then failed to produce, and compile rejected its
353
+ * own round trip with `layout: "endNiceDay" names no step or node in this flow`.
354
+ */
355
+ export interface ReturnOptions extends NodeOptions {
356
+ /**
357
+ * The End node's id — what `layout` keys on and what `nodes[].id` becomes.
358
+ * Defaults to `end`, then `end2`, `end3`, … in emission order.
359
+ *
360
+ * @remarks
361
+ * Like a step name this is identity, not decoration: use {@link NodeOptions.label}
362
+ * for what the canvas shows. Ids are de-duplicated, so two Ends both asking for
363
+ * `done` become `done` and `done2`.
364
+ *
365
+ * ```ts
366
+ * .branch('checkTemperature', js`$vars.tempF > 60`,
367
+ * (t) => t.return({}, { name: 'endNiceDay', label: 'Nice Day' }),
368
+ * (e) => e.return({}, { name: 'endBringJacket', label: 'Bring a Jacket' }))
369
+ * ```
370
+ */
371
+ name?: string;
372
+ }
373
+ /**
374
+ * Loop-specific options. Any of these — or a `b.break()` in the
375
+ * body — selects the loop's v2.4 definition (the current Workbench contract,
376
+ * with inner `start`/`continue`/`break` handles); a plain `.loop()` keeps the
377
+ * SDK's long-pinned 1.0.0 emission unchanged. An explicit `{ version: '1.0.0' }`
378
+ * combined with any of these fails compilation: that definition cannot express
379
+ * them.
380
+ */
381
+ export interface LoopOptions extends NodeOptions {
382
+ /** Run iterations in parallel instead of sequentially. */
383
+ parallel?: boolean;
384
+ /**
385
+ * Stop early when this condition (evaluated after each iteration) is true —
386
+ * e.g. `js`$vars.hits.output.length >= 10``.
387
+ */
388
+ completionCondition?: Expr;
389
+ /**
390
+ * Show the loop's break handle without wiring one — set automatically when
391
+ * the body calls `b.break()`.
392
+ */
393
+ breakEnabled?: boolean;
394
+ }
395
+ /**
396
+ * Do-while options. `limit` caps iterations; the platform
397
+ * defaults a blank limit to 10,000 and rejects values outside 1–10,000.
398
+ */
399
+ export interface DoWhileOptions extends NodeOptions {
400
+ /** Maximum iterations, 1–10,000. Blank means the platform default (10,000). */
401
+ limit?: number;
402
+ /** Show the break handle without wiring one — set automatically by `b.break()`. */
403
+ breakEnabled?: boolean;
404
+ }
405
+ export type Step = {
406
+ kind: 'action';
407
+ name: string;
408
+ spec: FlowActionSpec;
409
+ options?: NodeOptions;
410
+ } | {
411
+ kind: 'branch';
412
+ name: string;
413
+ label?: string;
414
+ trueLabel?: string;
415
+ falseLabel?: string;
416
+ cond: Expr;
417
+ then: Step[];
418
+ otherwise: Step[];
419
+ options?: NodeOptions;
420
+ } | {
421
+ kind: 'switch';
422
+ name: string;
423
+ label?: string;
424
+ on: Expr;
425
+ cases: SwitchArm[];
426
+ default?: Step[];
427
+ options?: NodeOptions;
428
+ } | {
429
+ kind: 'loop';
430
+ name: string;
431
+ label?: string;
432
+ collection: Expr;
433
+ body: Step[];
434
+ options?: LoopOptions;
435
+ }
436
+ /**
437
+ * A do-while container (`core.logic.dowhile`): run the body, then repeat
438
+ * while `condition` is true, up to `options.limit` iterations.
439
+ */
440
+ | {
441
+ kind: 'doWhile';
442
+ name: string;
443
+ label?: string;
444
+ condition: Expr;
445
+ body: Step[];
446
+ options?: DoWhileOptions;
447
+ }
448
+ /**
449
+ * Exit the enclosing loop/do-while through its break handle. Terminal on its
450
+ * path — nothing after it can run. Only valid inside a container body.
451
+ */
452
+ | {
453
+ kind: 'break';
454
+ }
455
+ /**
456
+ * A fan-out and its join. `arms` is one step list per arm — an ARRAY, because
457
+ * arms are positional and carry no author-supplied keys — and `name` names the
458
+ * Merge node the arms converge on (the only node this step creates; the fork
459
+ * itself is just N edges out of one port).
460
+ */
461
+ | {
462
+ kind: 'parallel';
463
+ name: string;
464
+ label?: string;
465
+ arms: Step[][];
466
+ options?: NodeOptions;
467
+ }
468
+ /**
469
+ * A hard stop: `core.logic.terminate`, a BPMN End event carrying a
470
+ * TerminateEventDefinition. Ends the whole RUN, not just this path — which is
471
+ * the only difference from `return`, and the reason it needs a node id.
472
+ */
473
+ | {
474
+ kind: 'terminate';
475
+ name: string;
476
+ label?: string;
477
+ options?: NodeOptions;
478
+ }
479
+ /**
480
+ * An edge to another step, by name. Creates no node of its own: it is ONE
481
+ * EDGE, added after the whole flow is emitted, because the target is often
482
+ * declared later in the file than the step that names it.
483
+ *
484
+ * `port` is the port of the step this leaves — `'output'` (the default) hands
485
+ * the path off, so nothing may follow it in the same list; any other port is a
486
+ * side exit and the chain continues. See `StepList.stepToRef`.
487
+ */
488
+ | {
489
+ kind: 'stepToRef';
490
+ port: string;
491
+ target: string;
492
+ }
493
+ /**
494
+ * A step list wired from a named PORT of the step this follows — the general
495
+ * form of an error handler. The body is its own path: it either ends in a
496
+ * terminal of its own or hands control back with a `stepToRef`.
497
+ *
498
+ * `.onError(...)` is this with `port: 'error'`, which is the case nearly every
499
+ * flow uses. See `StepList.stepToList`.
500
+ */
501
+ | {
502
+ kind: 'stepToList';
503
+ port: string;
504
+ body: Step[];
505
+ } | {
506
+ kind: 'return';
507
+ name: string;
508
+ values: Record<string, Expr>;
509
+ options?: ReturnOptions;
510
+ };
511
+ /** One node's designer layout: canvas position, and optionally size and collapsed state. */
512
+ export interface NodeLayout {
513
+ /** Absolute canvas position. */
514
+ position: {
515
+ x: number;
516
+ y: number;
517
+ };
518
+ /** Node size; omit for the designer default. */
519
+ size?: {
520
+ width: number;
521
+ height: number;
522
+ };
523
+ /** Whether the node renders collapsed. */
524
+ collapsed?: boolean;
525
+ }
526
+ /** One edge's route: user-dragged bends and/or the auto-router's waypoints. */
527
+ export interface EdgeRoute {
528
+ /** Manually placed bends, in canvas coordinates. Win over the routed set. */
529
+ waypoints?: {
530
+ x: number;
531
+ y: number;
532
+ id?: string;
533
+ }[];
534
+ /** The layout engine's obstacle-avoiding route. */
535
+ routedWaypoints?: {
536
+ x: number;
537
+ y: number;
538
+ id?: string;
539
+ }[];
540
+ }
541
+ /**
542
+ * The designer's sticky-note palette. Any other string is passed through — the
543
+ * `.flow` format stores `inputs.color` unvalidated — but these five are what the
544
+ * canvas offers and what round-trips as a named swatch.
545
+ */
546
+ export declare const STICKY_NOTE_COLORS: readonly ["yellow", "pink", "blue", "green", "white"];
547
+ /**
548
+ * A sticky note's swatch. One of {@link STICKY_NOTE_COLORS} autocompletes; any
549
+ * other string is accepted and passed straight through, because the format
550
+ * stores `inputs.color` without validating it.
551
+ */
552
+ export type StickyNoteColor = (typeof STICKY_NOTE_COLORS)[number] | (string & {});
553
+ /**
554
+ * A canvas sticky note — free text pinned to the diagram, for the humans reading
555
+ * it.
556
+ *
557
+ * @remarks
558
+ * A note is a real entry in the file's `nodes[]` (type `stickyNote`), not a
559
+ * layout entry, which is why it carries an `id` and its own geometry. It has no
560
+ * manifest and no definition: the platform skips it during validation and
561
+ * conversion, and drops any edge touching it. So it is inert — it annotates the
562
+ * diagram and can never change what the flow does.
563
+ */
564
+ export interface StickyNote {
565
+ /**
566
+ * The note's node id. Defaults to `stickyNote_1`, `stickyNote_2`, … in
567
+ * declaration order.
568
+ *
569
+ * @remarks
570
+ * Name it when the flow is round-tripped (decompile → edit → compile): the id
571
+ * is what makes a note the SAME note across compiles, so an unnamed note in an
572
+ * edited file can renumber and read as delete-plus-create.
573
+ */
574
+ id?: string;
575
+ /** The note's text. */
576
+ content: string;
577
+ /** Swatch; defaults to `'yellow'`. */
578
+ color?: StickyNoteColor;
579
+ /** Canvas x of the note's top-left corner. */
580
+ x: number;
581
+ /** Canvas y of the note's top-left corner. */
582
+ y: number;
583
+ /** Note width. Pass it with `height` or not at all; omit for the designer default. */
584
+ width?: number;
585
+ /** Note height. Pass it with `width` or not at all; omit for the designer default. */
586
+ height?: number;
587
+ }
588
+ /**
589
+ * Designer layout for a flow, keyed by AUTHOR-level ids: node
590
+ * entries by step name (plus the trigger id and `end`), edge entries by
591
+ * `"<fromStep>-><toStep>"`. Serialization resolves the keys after node ids are
592
+ * finalized; an unknown key is a compile error, an omitted node simply stays
593
+ * where the serializer's default puts it. Layout is metadata — it never
594
+ * affects semantic checks.
595
+ */
596
+ export interface FlowLayout {
597
+ /** Per-node layout, keyed by step name / trigger id / `end`. */
598
+ nodes?: Record<string, NodeLayout>;
599
+ /** Per-edge routes, keyed by `"<fromStep>-><toStep>"`. */
600
+ edges?: Record<string, EdgeRoute>;
601
+ }
602
+ /** One additional flow root, built by `.entryPoint()`. */
603
+ export interface BuiltEntryPoint {
604
+ /** The trigger node's id — also the root expressions read (`$vars.<id>.output.x`). */
605
+ id: string;
606
+ /** What fires this root: `manual()`, `scheduled(...)`, or `onEvent(...)`. */
607
+ trigger: TriggerSpec;
608
+ /** Node options for the trigger node — exact `version` selection. */
609
+ options?: NodeOptions;
610
+ /** Inputs scoped to this root (globals bound to it via `triggerNodeId`). */
611
+ inputs: VarDecl[];
612
+ /** The root's prefix steps, run before it joins the shared body. */
613
+ steps: Step[];
614
+ }
615
+ export interface BuiltFlow {
616
+ id: string;
617
+ name: string;
618
+ /** Human-readable description, persisted at the top of the .flow file. */
619
+ description?: string;
620
+ version: string;
621
+ /**
622
+ * The FILE-FORMAT version the emitted `.flow` declares, from
623
+ * `.schemaVersion()`. Absent means "the SDK's default write floor"
624
+ * (`FLOW_FORMAT_PROFILE.version`), which is what every flow authored before
625
+ * the method existed means too — so an absent value changes nothing.
626
+ */
627
+ schemaVersion?: string;
628
+ inputs: VarDecl[];
629
+ outputs: VarDecl[];
630
+ vars: VarDecl[];
631
+ steps: Step[];
632
+ /** Omitted for the manual trigger (the default), so an existing flow's built
633
+ * description — and the `.flow` it serializes to — is unchanged. */
634
+ trigger?: TriggerSpec;
635
+ /** Node options given on `.trigger(spec, options)` — exact version selection. */
636
+ triggerOptions?: NodeOptions;
637
+ /** Designer layout from `.layout()`, resolved at serialization. */
638
+ layout?: FlowLayout;
639
+ /** Canvas sticky notes from `.stickyNotes()`. Inert annotations. */
640
+ stickyNotes?: StickyNote[];
641
+ /** Additional roots from `.entryPoint()`. The default root stays `.trigger()`/`.input()`. */
642
+ entryPoints?: BuiltEntryPoint[];
643
+ /**
644
+ * The trigger node's id. Defaults to `start`. It matters because a flow's
645
+ * declared inputs are published as this node's output, so `input('x')` reads
646
+ * `$vars.<triggerId>.output.x` — rename the node and every such reference
647
+ * follows.
648
+ */
649
+ triggerId?: string;
650
+ }
651
+ /** Collects a sequence of steps. Used for the flow body and each branch/loop arm. */
652
+ declare class StepList {
653
+ steps: Step[];
654
+ /**
655
+ * The step whose failure led here, set only on the sub-builder `.onError(...)`
656
+ * hands its callback. `err()` on this builder needs no step name because of it.
657
+ */
658
+ private errorSource?;
659
+ /**
660
+ * Read the failure that led into this handler → `err('<the failed step>', field)`.
661
+ *
662
+ * @remarks
663
+ * Only available on the sub-builder `.onError(...)` / `.stepToList('error', …)`
664
+ * passes to its callback, because only there is "the step that failed" a fact
665
+ * rather than a guess.
666
+ *
667
+ * Prefer it over the free `err('<step>', field)` inside a handler. It cannot
668
+ * name the wrong step, it cannot drift when the step is renamed, and — the
669
+ * reason it exists — it keeps the envelope's LOCATION out of author-visible
670
+ * code entirely. Which variable carries the envelope is per node family
671
+ * (measured: `<step>.error` on connectors, script, deep-rag, subflow and
672
+ * queue; `<step>.output` on managed http), and the compiler resolves it.
673
+ *
674
+ * ```ts
675
+ * .step('load', script({ code: 'return JSON.parse($vars.start.output.raw);' }))
676
+ * .onError((h) => h.return({ note: tmpl`bad payload: ${h.err('message')}` }))
677
+ * ```
678
+ *
679
+ * @param field - One of the envelope's fields. Omit it to test WHETHER the
680
+ * step failed (the boolean the platform sets when the boundary fires).
681
+ * @returns An {@link Expr} reading the failure of the step this handler guards.
682
+ * @see err
683
+ */
684
+ err(field?: ErrorEnvelopeField): Expr;
685
+ /**
686
+ * Add an action node (see `http` / `script` / `subflow`).
687
+ *
688
+ * @param name - The step's id. Read its result downstream with `out('<name>')`,
689
+ * so it must be unique within the flow.
690
+ * @param spec - What the node does, from an action factory.
691
+ * @param options - Node options; `version` selects the exact definition
692
+ * version (see {@link NodeOptions}).
693
+ * @returns This builder, so calls chain.
694
+ */
695
+ step(name: string, spec: FlowActionSpec | FlowAction, options?: NodeOptions): this;
696
+ /**
697
+ * Handle the PREVIOUS step's failure: if it fails, the flow runs `bodyFn`'s
698
+ * steps instead of continuing.
699
+ *
700
+ * @remarks
701
+ * ```ts
702
+ * .step('fetch', http({ url: apiUrl, managed: true, returns: { items: 'array' } }))
703
+ * .onError((h) => h.return({ result: lit('Article not found') }))
704
+ * .step('total', transform({ … })) // runs only when `fetch` SUCCEEDED
705
+ * .return({ result: out('total') })
706
+ * ```
707
+ *
708
+ * The handler is its own path — anything chained after `.onError(...)` belongs
709
+ * to the SUCCESS path only. Inside it, read the failure with
710
+ * {@link StepList.err} — `h.err('message')` — or with the free
711
+ * `err('<step>', 'message')` if you prefer to name the step. The envelope
712
+ * carries `code`, `message`, `detail`, `category` and `status` (`code` is a
713
+ * string even for an HTTP status, `status` a number), plus an undeclared
714
+ * `response` and `element` the runtime adds.
715
+ *
716
+ * Do NOT reach for `out('<step>', …)` in here. That reads the step's SUCCESS
717
+ * output, which was never written — the handler runs precisely because the
718
+ * step failed — and `check` refuses it (ERROR_ENVELOPE_VIA_OUTPUT). This doc
719
+ * line used to recommend `out('<step>', 'error', 'message')`, which is not
720
+ * even a legal call: `out(step, path?)` takes two arguments.
721
+ *
722
+ * **Three ways the handler can end**: `.return(...)` answers the flow,
723
+ * `.terminate(...)` stops the run, and `h.rejoin('<step>')` compensates and
724
+ * hands control back to a step the success path also reaches — the shape most
725
+ * deployed flows use. A handler that just runs out of steps still gets its own
726
+ * End: rejoining is something the author SAYS, never something wiring infers.
727
+ * See {@link StepList.stepToRef}.
728
+ *
729
+ * Two things this does for you, by construction: it sets
730
+ * `errorHandlingEnabled` on the node in the same write as the edge (without
731
+ * it the platform routes but Studio Web HIDES the handle, so no human can see
732
+ * your handler), and it refuses at build time on a step whose node type has no
733
+ * error port.
734
+ *
735
+ * **A `.loop()` container takes one too.** `core.logic.loop` declares the
736
+ * handle, and a body step's failure routes to it: the container's envelope
737
+ * carries the body's message in `detail` and the failing body step's id in
738
+ * `element`, and the instance completes rather than faulting. `.doWhile()` does
739
+ * NOT — it declares an error variable and no error handle — so that one is
740
+ * refused by name, and its failures belong to the body step that can fail.
741
+ *
742
+ * **A plain `http()` step is the trap worth knowing**: a 404 there is a
743
+ * SUCCESS with `statusCode: 404`, so the handler never runs — use
744
+ * `http({ …, managed: true })` when failures must route. `check` says so
745
+ * (HTTP_ONERROR_V1).
746
+ *
747
+ * Which node types can fail, what the envelope carries, and what a local run
748
+ * does and does not prove: `references/error-handling.md`.
749
+ *
750
+ * @param bodyFn - Receives a sub-builder for the handler's own path. Read the
751
+ * failure inside it with `h.err('message')` ({@link StepList.err}).
752
+ * @returns This builder, positioned on the SUCCESS path — anything chained after
753
+ * this call runs only when the step succeeded.
754
+ * @enforcedBy HTTP_ONERROR_V1 On an http step this needs `managed: true`; on the
755
+ * standalone node a 4xx arrives on the SUCCESS path and no handler runs.
756
+ */
757
+ onError(bodyFn: (b: StepList) => void): this;
758
+ /**
759
+ * The step a port-scoped edge leaves, and the guard that it is allowed to.
760
+ *
761
+ * Scans BACK past edges already attached to the same step: after
762
+ * `.onError(...)` the last entry in the list is that handler, not the action it
763
+ * guards, so `steps.at(-1)` would refuse a second port-edge on the same step —
764
+ * and would attach `.stepToRef('error', …)` to the wrong thing.
765
+ *
766
+ * A port takes exactly one outgoing edge (the definitions say so:
767
+ * `maxConnections: 1`), so a second edge from the same port is refused here
768
+ * rather than emitted and silently dropped downstream.
769
+ */
770
+ private portSource;
771
+ /**
772
+ * Run a step list from a named PORT of the step this follows — the general form
773
+ * of an error handler, and the reason `.onError()` needs no machinery of its own.
774
+ *
775
+ * @remarks
776
+ * The body is its own path. It ends by answering (`.return`), stopping the run
777
+ * (`.terminate`), or handing control back with `.stepToRef(...)`; a body that
778
+ * simply runs out of steps gets its own End, exactly as an error handler does.
779
+ *
780
+ * The main path is untouched — an edge out of a NON-default port is a side exit,
781
+ * so whatever you chain after this call still belongs to the step's normal
782
+ * continuation.
783
+ *
784
+ * ```ts
785
+ * .step('fetch', http({ … , managed: true }))
786
+ * .stepToList('error', (h) => h.step('log', script({ … })).stepToRef('settle'))
787
+ * .step('parse', script({ … })) // ← still the SUCCESS path
788
+ * ```
789
+ *
790
+ * @param port - The port of the preceding step to leave from, e.g. `'error'`.
791
+ * @param bodyFn - Receives a sub-builder for the path that port leads to.
792
+ * @returns This builder, so calls chain.
793
+ * @see stepToRef
794
+ */
795
+ stepToList(port: string, bodyFn: (b: StepList) => void): this;
796
+ /**
797
+ * The shared body of `.stepToList()` and `.onError()`.
798
+ *
799
+ * Private because `called` and `noun` exist only so a refusal names the method
800
+ * the author actually called — they are not part of the surface, and a public
801
+ * parameter nobody should pass is a worse trade than one extra hop.
802
+ */
803
+ private addPortList;
804
+ /**
805
+ * Branch on a condition. `thenFn`/`elseFn` receive a sub-builder for each arm.
806
+ *
807
+ * @remarks
808
+ * Each arm can name itself with `.label(...)` — the then-arm's label becomes the
809
+ * node's `trueLabel`, the else-arm's its `falseLabel` (the text the designer
810
+ * shows on the two outgoing edges). Omit it and the arms keep the default
811
+ * `"True"` / `"False"`.
812
+ *
813
+ * @param name - The decision node's id.
814
+ * @param cond - The condition, as an expression — typically `js\`…\``.
815
+ * @param thenFn - Receives a sub-builder for the TRUE arm.
816
+ * @param elseFn - Receives a sub-builder for the FALSE arm. Omit it for a
817
+ * decision whose false path simply continues.
818
+ * @param options - Node options; `version` selects the exact definition
819
+ * version (see {@link NodeOptions}).
820
+ * @returns This builder, after both arms have rejoined.
821
+ */
822
+ branch(name: string, cond: Expr, thenFn: (b: ArmBuilder) => void, elseFn?: (b: ArmBuilder) => void, options?: NodeOptions): this;
823
+ /**
824
+ * N-way branch on the value of `on` — one arm per case, plus an optional
825
+ * default arm. Each arm gets its own sub-builder, exactly like `.branch`.
826
+ *
827
+ * @remarks
828
+ * A case matches when `on === case.value`, compared the way JavaScript's own
829
+ * `switch` compares: **strictly, so the type counts**. `value: 2` matches a
830
+ * `types.number` input carrying `2`; `value: '2'` does not. Cases are
831
+ * evaluated top to bottom and the first match wins.
832
+ *
833
+ * @example
834
+ * **Route on a value, with a default arm**
835
+ * ```ts
836
+ * .switch('routeQuarter', input('quarter'), [
837
+ * { value: 1, body: (b) => b.step('spring', script({ code: 'return "Spring";' })) },
838
+ * { value: 2, body: (b) => b.step('summer', script({ code: 'return "Summer";' })) },
839
+ * ], (other) => other.step('unknown', script({ code: 'return "Unknown";' })))
840
+ * ```
841
+ *
842
+ * @param name - The switch node's id.
843
+ * @param on - The value to compare each case against.
844
+ * @param cases - One entry per arm, evaluated top to bottom; the first strict
845
+ * match wins. `label` names the arm's outgoing edge.
846
+ * @param defaultFn - Receives a sub-builder for the arm taken when nothing
847
+ * matches. Omit it and an unmatched value simply continues.
848
+ * @param options - Node options; `version` selects the exact definition
849
+ * version (see {@link NodeOptions}).
850
+ * @returns This builder, after every arm has rejoined.
851
+ */
852
+ switch(name: string, on: Expr, cases: {
853
+ value: CaseValue;
854
+ body: (b: ArmBuilder) => void;
855
+ label?: string;
856
+ }[], defaultFn?: (b: StepList) => void, options?: NodeOptions): this;
857
+ /**
858
+ * Run two or more arms **in parallel** from this point and join them back
859
+ * together on a Merge node — the one place the builder stops being a straight
860
+ * chain.
861
+ *
862
+ * @remarks
863
+ * `name` names the **Merge** node (the join). Each arm is a sub-builder, just
864
+ * like a `.branch` arm, and every arm starts from the same place the chain had
865
+ * reached, so the graph forks there and reconverges on the Merge.
866
+ *
867
+ * Anything you chain afterwards continues from the Merge, so it can read every
868
+ * arm's output. The Merge itself computes nothing and publishes nothing — read
869
+ * the steps inside the arms, never `$vars.<merge>`.
870
+ *
871
+ * Arm semantics, what a local run does and does not prove, and the rules
872
+ * `check` enforces: `references/parallel-merge.md`.
873
+ *
874
+ * @example
875
+ * **Fetch two things at once, then combine them after the join**
876
+ * ```ts
877
+ * .parallel('sync', [
878
+ * (a) => a.step('fetchWeather', script({ code: 'return "sunny";' })),
879
+ * (b) => b.step('fetchNews', script({ code: 'return "quiet";' })),
880
+ * ])
881
+ * .step('combine', script({ code: 'return $vars.fetchWeather.output + $vars.fetchNews.output;' }))
882
+ * ```
883
+ *
884
+ * @param name - The split node's id. The Merge node is derived from it.
885
+ * @param arms - One callback per parallel arm, each receiving its own
886
+ * sub-builder. Two or more.
887
+ * @param options - Node options; `version` selects the exact definition
888
+ * version (see {@link NodeOptions}).
889
+ * @returns This builder, positioned after the Merge — so what you chain next
890
+ * runs once, when every arm has finished.
891
+ */
892
+ parallel(name: string, arms: ((b: StepList) => void)[], options?: NodeOptions): this;
893
+ /**
894
+ * Iterate `collection`; `bodyFn` receives a sub-builder for the loop body.
895
+ *
896
+ * @param name - The loop node's id.
897
+ * @param collection - The array to iterate, as a reference — `v('items')` or
898
+ * `out('fetch', 'body.items')`.
899
+ * @param bodyFn - Receives a sub-builder for the body, run once per element.
900
+ * @param options - Node options; `version` selects the exact definition
901
+ * version (see {@link NodeOptions}).
902
+ * @returns This builder, positioned after the loop.
903
+ */
904
+ loop(name: string, collection: Expr, bodyFn: (b: StepList) => void, options?: LoopOptions): this;
905
+ /**
906
+ * Run the body, then repeat **while `condition` is true** — the condition is
907
+ * checked AFTER each iteration, so the body always runs at least once
908
+ * (`core.logic.dowhile`). The container publishes no data output; write
909
+ * results to a `.var()` from inside the body (`{ updates }`), and read the
910
+ * loop's progress nowhere — unlike `.loop()` there is no `currentItem`.
911
+ *
912
+ * @example
913
+ * **Paginate until the API says stop**
914
+ * ```ts
915
+ * .var('page', types.number, 1)
916
+ * .doWhile('paginate', js`$vars.fetch.output.hasNextPage === true`, (b) => b
917
+ * .step('fetch', http({ url: tmpl`https://api.example.test/items?page=${v('page')}`, method: 'GET', managed: false, returns: { hasNextPage: 'boolean' } }), {
918
+ * updates: { page: js`$vars.page + 1` },
919
+ * }), { limit: 50 })
920
+ * ```
921
+ *
922
+ * @param name - The container node's id.
923
+ * @param condition - Repeat while this is true, checked after each pass.
924
+ * @param bodyFn - Receives a sub-builder for the body, run once per pass.
925
+ * @param options - `limit` (1–10,000; blank = platform default 10,000),
926
+ * `breakEnabled`, and the common node options (see {@link DoWhileOptions}).
927
+ * @returns This builder, positioned after the loop.
928
+ */
929
+ doWhile(name: string, condition: Expr, bodyFn: (b: StepList) => void, options?: DoWhileOptions): this;
930
+ /**
931
+ * Exit the enclosing `.loop()` / `.doWhile()` through its **break handle**,
932
+ * ending the whole loop now — not just this iteration. Terminal on its path:
933
+ * nothing may follow it, exactly like `.terminate()`. Using it enables the
934
+ * container's break handle automatically. Compilation fails when there is no
935
+ * enclosing container.
936
+ *
937
+ * @returns This builder. Nothing after this call on the same path can run.
938
+ */
939
+ break(): this;
940
+ /**
941
+ * Stop the **whole run**, here and now — not just this path.
942
+ *
943
+ * @remarks
944
+ * That is the only difference from `.return()`, and it is a big one: inside a
945
+ * `.parallel` arm a terminate **aborts the sibling arms**, whatever they were
946
+ * in the middle of. A `.return()` in the same place would only end its own
947
+ * path and leave the others running.
948
+ *
949
+ * Nothing may follow a terminate: it publishes no value, and no step after it
950
+ * — in its arm or chained behind it — can ever run.
951
+ *
952
+ * What aborts, what the run reports, and what each local rung can prove:
953
+ * `references/terminate.md`.
954
+ *
955
+ * @example
956
+ * **Abort the sibling arm from inside a parallel**
957
+ * ```ts
958
+ * .parallel('branches', [
959
+ * (a) => a.terminate('stopEverything'),
960
+ * (b) => b.step('wait', delay({ duration: 'PT10S' })).return({ message: 'done' }),
961
+ * ])
962
+ * ```
963
+ *
964
+ * @param name - The terminate node's id.
965
+ * @param label - Text the designer shows on the node. Omit it for the default.
966
+ * @param options - Node options; `version` selects the exact definition
967
+ * version (see {@link NodeOptions}).
968
+ * @returns This builder. Nothing after this call on the same path can run.
969
+ */
970
+ terminate(name: string, label?: string, options?: NodeOptions): this;
971
+ /**
972
+ * Go to another step, by name — an edge, not a node.
973
+ *
974
+ * @remarks
975
+ * With one argument it leaves the step's default `output` port, which HANDS THE
976
+ * PATH OFF: nothing may follow it in this list, because the flow continues at
977
+ * the target. With a port it is a side exit — the main path is untouched and
978
+ * chaining continues, which is how an error port reaches an existing step
979
+ * without a handler body.
980
+ *
981
+ * ```ts
982
+ * .step('fetch', http({ … }))
983
+ * .stepToRef('settle') // continue at "settle"
984
+ *
985
+ * .step('charge', http({ … , managed: true }))
986
+ * .stepToRef('error', 'refund') // its failure goes to "refund"
987
+ * .step('receipt', script({ … })) // ← still the SUCCESS path
988
+ * ```
989
+ *
990
+ * The target may be declared later in the file, and may be BACKWARD of this
991
+ * step: Flow JSON can express either, so this can author either. What `check`
992
+ * can prove it refuses; what depends on the runtime it warns about and leaves to
993
+ * `uip maestro flow validate`.
994
+ *
995
+ * @param target - The step to continue at, named as it was in `.step(...)`.
996
+ * @returns This builder. Nothing may follow: the path has been handed off.
997
+ * @see stepToList
998
+ */
999
+ stepToRef(target: string): this;
1000
+ /**
1001
+ * Go to another step from a NAMED PORT — a side exit.
1002
+ *
1003
+ * @remarks
1004
+ * The main path is untouched, so whatever you chain after this call still
1005
+ * belongs to the step's normal continuation. This is how a failure reaches an
1006
+ * existing step without a handler body of its own.
1007
+ *
1008
+ * ```ts
1009
+ * .step('charge', http({ … , managed: true }))
1010
+ * .stepToRef('error', 'refund') // its failure goes to "refund"
1011
+ * .step('receipt', script({ … })) // ← still the SUCCESS path
1012
+ * ```
1013
+ *
1014
+ * @param port - The port of this step to leave, e.g. `'error'`.
1015
+ * @param target - The step to continue at, named as it was in `.step(...)`.
1016
+ * @returns This builder, so calls chain — a side exit ends nothing.
1017
+ * @see stepToList
1018
+ */
1019
+ stepToRef(port: string, target: string): this;
1020
+ /**
1021
+ * Terminate this path, binding flow outputs to expressions.
1022
+ *
1023
+ * @param values - One entry per declared flow output. A raw value is wrapped as
1024
+ * a literal; an {@link Expr} is emitted as a reference.
1025
+ * @param options - Node options; `version` selects the exact definition
1026
+ * version (see {@link NodeOptions}).
1027
+ * @returns This builder. This path has answered, so nothing after it runs.
1028
+ */
1029
+ return(values?: Record<string, Expr | unknown>, options?: ReturnOptions): this;
1030
+ }
1031
+ /**
1032
+ * The sub-builder an ARM callback receives — a `StepList` that can also name
1033
+ * itself with `.label(...)`.
1034
+ *
1035
+ * @remarks
1036
+ * It exists so `.label()` is available exactly where it means something (a
1037
+ * `.branch` or `.switch` arm) and NOT on the top-level flow, which names itself
1038
+ * with `.name(...)`. The parent's `branch`/`switch` reads `armLabel` back after
1039
+ * running the callback and lowers it to the node's arm label (`trueLabel` /
1040
+ * `falseLabel` for a decision, the case `label` for a switch).
1041
+ */
1042
+ declare class ArmBuilder extends StepList {
1043
+ armLabel?: string;
1044
+ /**
1045
+ * Name this arm. The label is what the designer shows on the arm's outgoing
1046
+ * edge; it also survives a round-trip through Flow JSON, where a bare
1047
+ * `"True"` / `"False"` / `Case "<value>"` would not carry the author's intent.
1048
+ * Order-independent — call it anywhere in the arm's chain.
1049
+ *
1050
+ * @param text - The label the designer shows on this arm's outgoing edge.
1051
+ * @returns This builder, so calls chain.
1052
+ */
1053
+ label(text: string): this;
1054
+ }
1055
+ declare class FlowBuilder extends StepList {
1056
+ private readonly _id;
1057
+ private _name;
1058
+ private _description?;
1059
+ private _layout?;
1060
+ private _stickyNotes?;
1061
+ private _version;
1062
+ private _schemaVersion?;
1063
+ private _inputs;
1064
+ private _outputs;
1065
+ private _vars;
1066
+ private _trigger?;
1067
+ private _triggerOptions?;
1068
+ private _entryPoints;
1069
+ private _triggerId?;
1070
+ constructor(_id: string);
1071
+ /**
1072
+ * Set the flow's display name.
1073
+ *
1074
+ * @param n - The name the designer shows. Defaults to the flow's id.
1075
+ * @returns This builder, so calls chain.
1076
+ * @defaultValue the flow's id
1077
+ */
1078
+ name(n: string): this;
1079
+ /**
1080
+ * Set the flow's description — persisted as the top-level `description`
1081
+ * field of the emitted `.flow`, shown in the designer's flow header.
1082
+ *
1083
+ * @param text - What this flow does, for humans.
1084
+ * @returns This builder, so calls chain.
1085
+ */
1086
+ description(text: string): this;
1087
+ /**
1088
+ * Set designer layout — node positions/sizes and edge routes — keyed by the
1089
+ * flow's own logical ids (step names, the trigger id, `end`). Optional pure
1090
+ * metadata: nothing here changes what the flow does, and omitting it leaves
1091
+ * the serializer's default arrangement. Unknown keys fail compilation rather
1092
+ * than being dropped.
1093
+ *
1094
+ * @param layout - Node layout by step name, edge routes by `"from->to"`.
1095
+ * @returns This builder, so calls chain.
1096
+ */
1097
+ layout(layout: FlowLayout): this;
1098
+ /**
1099
+ * Pin free-text notes to the canvas, for whoever reads the diagram.
1100
+ *
1101
+ * @remarks
1102
+ * Sticky notes are the only annotation `.flow` has. Each becomes a real
1103
+ * `stickyNote` node, which the platform skips during validation and
1104
+ * conversion and whose edges it drops — so a note can never change what the
1105
+ * flow does, and `check` treats it as inert.
1106
+ *
1107
+ * Calling this twice REPLACES the set rather than appending, matching
1108
+ * `.layout()`.
1109
+ *
1110
+ * @example
1111
+ * ```ts
1112
+ * .stickyNotes([
1113
+ * { content: 'Rates refresh at 02:00 UTC', x: 240, y: 40 },
1114
+ * { id: 'why-retry', content: 'The vendor 502s under load.', color: 'pink',
1115
+ * x: 240, y: 320, width: 220, height: 120 },
1116
+ * ])
1117
+ * ```
1118
+ *
1119
+ * @param notes - The notes to pin. Position is required; `id`, `color` and
1120
+ * size have defaults.
1121
+ * @returns This builder, so calls chain.
1122
+ */
1123
+ stickyNotes(notes: StickyNote[]): this;
1124
+ /**
1125
+ * Set what starts the flow. Omit this call for the **manual** trigger (a
1126
+ * caller starts the flow on demand) — that is the default and what most
1127
+ * flows want.
1128
+ *
1129
+ * @example
1130
+ * **Run the flow hourly instead of on demand**
1131
+ * ```ts
1132
+ * .trigger(scheduled({ every: 'R/PT1H' }))
1133
+ * ```
1134
+ *
1135
+ * @param spec - What starts the flow, from `scheduled(...)` or `onEvent(...)`.
1136
+ * @param options - Node options; `version` selects the exact definition
1137
+ * version (see {@link NodeOptions}).
1138
+ * @returns This builder, so calls chain.
1139
+ * @defaultValue the manual trigger
1140
+ */
1141
+ trigger(spec: TriggerSpec | FlowTrigger, options?: NodeOptions): this;
1142
+ /**
1143
+ * Add an ADDITIONAL flow root: its own trigger node, its own
1144
+ * scoped inputs (read them with `entryInput('<id>', '<name>')`), and an
1145
+ * optional prefix that runs before the root joins the shared body. Without a
1146
+ * prefix the root connects straight to the first shared step; a prefix that
1147
+ * ends terminally (or hands off with `.stepToRef()`) joins nothing.
1148
+ *
1149
+ * @remarks
1150
+ * The DEFAULT root stays `.trigger()` / `.input()` — one flow, one default
1151
+ * entry point, marked `isDefaultEntryPoint` in the emitted file. Every root
1152
+ * (default included) gets its platform entry-point identity when a flow has
1153
+ * more than one.
1154
+ *
1155
+ * @example
1156
+ * **A manual flow with a second, nightly-scheduled root**
1157
+ * ```ts
1158
+ * flow('order-intake')
1159
+ * .input({ order: types.object }) // the default (manual) root
1160
+ * .entryPoint('nightly', scheduled({ every: 'R/P1D' }), {
1161
+ * inputs: { batchDate: types.string },
1162
+ * }, (b) => b.step('loadBatch', script({ code: 'return { order: { id: $vars.nightly.output.batchDate } };', returns: 'object' })))
1163
+ * .step('normalize', script({ code: 'return 1;' })) // shared body
1164
+ * ```
1165
+ *
1166
+ * @param id - The root's trigger-node id — unique among entry points, steps,
1167
+ * and the default trigger id. Expressions read it as `$vars.<id>.output.*`.
1168
+ * @param trigger - What fires this root: `manual()`, `scheduled(...)`, or
1169
+ * `onEvent(...)`.
1170
+ * @param options - `version` (exact trigger definition version) and `inputs`
1171
+ * — this root's scoped inputs, declared like `.input()`.
1172
+ * @param prefixFn - Optional sub-builder for the root's prefix steps.
1173
+ * @returns This builder, so calls chain.
1174
+ */
1175
+ entryPoint(id: string, trigger: TriggerSpec | FlowTrigger, options?: {
1176
+ version?: string;
1177
+ inputs?: Record<string, TypeDesc | VarSpec>;
1178
+ }, prefixFn?: (b: StepList) => void): this;
1179
+ /**
1180
+ * Rename the trigger node. The designer can rename it, so the SDK can too.
1181
+ *
1182
+ * @remarks
1183
+ * The id is not cosmetic: a flow's declared inputs are published as the trigger
1184
+ * node's output, so `input('amount')` reads `$vars.<triggerId>.output.amount`.
1185
+ * Renaming the node rewrites every such reference with it.
1186
+ *
1187
+ * @example
1188
+ * **Rename the trigger; input reads follow**
1189
+ * ```ts
1190
+ * .triggerId('intake') // input('amount') → $vars.intake.output.amount
1191
+ * ```
1192
+ *
1193
+ * @param id - The trigger node's new id. Every `input(...)` reference is
1194
+ * rewritten to read through it.
1195
+ * @returns This builder, so calls chain.
1196
+ * @defaultValue `'start'`
1197
+ */
1198
+ triggerId(id: string): this;
1199
+ /**
1200
+ * Set the flow's version.
1201
+ *
1202
+ * @param vsn - The version string. It does NOT reach the emitted `.flow`.
1203
+ * @returns This builder, so calls chain.
1204
+ * @deprecated Top-level `version` in a `.flow` file is the FILE-FORMAT
1205
+ * version, owned by the serializer's format profile (design §5.4) — it was
1206
+ * never an author-controlled artifact version, and the serializer has always
1207
+ * overwritten this value. The call is kept for source compatibility and
1208
+ * ignored. To target a specific file-format version, use
1209
+ * {@link FlowBuilder.schemaVersion}; there is no author-controlled artifact
1210
+ * version in the format for this to have meant.
1211
+ */
1212
+ version(vsn: string): this;
1213
+ /**
1214
+ * Declare the `.flow` FILE-FORMAT (schema) version this flow targets.
1215
+ *
1216
+ * @remarks
1217
+ * This is the document's grammar version — the top-level `version` a `.flow`
1218
+ * carries — and it is the one version concept that IS the author's to set,
1219
+ * which is exactly what {@link FlowBuilder.version} is not. Omit it and the
1220
+ * flow declares the SDK's default (the fleet write floor, `1.9`), which is
1221
+ * what every flow authored before this method existed already did.
1222
+ *
1223
+ * Its real job is BROWNFIELD PRESERVATION. `flow-decompile` emits this call
1224
+ * with the version it read, so a decompile → edit → compile round-trip
1225
+ * re-declares the file's own version instead of silently rewriting a `1.10`
1226
+ * file as `1.9`. Migrating a document BETWEEN versions stays
1227
+ * `uip maestro flow migrate`'s job: a hop can carry data repairs (the
1228
+ * 1.9 → 1.10 hop repairs connector binding names) that this SDK has no way to
1229
+ * reproduce from the source alone.
1230
+ *
1231
+ * Only versions this build can actually write are accepted — `1.6` through
1232
+ * `1.10`, the band whose schemas are the same shape as what the serializer
1233
+ * emits. A version is a CLAIM that the whole document matches that schema,
1234
+ * not a switch that reshapes it, so declaring one the serializer cannot emit
1235
+ * would write a false claim; the call throws instead. Both directions off the
1236
+ * floor cost something — above it, a reader pinned lower (an older CLI, an
1237
+ * Automation Suite ring) refuses the file; below it, every reader migrates
1238
+ * forward on open — so `check()` reports `SCHEMA_VERSION_ABOVE_FLOOR` /
1239
+ * `SCHEMA_VERSION_BELOW_FLOOR` rather than deciding for you.
1240
+ *
1241
+ * @example
1242
+ * **Round-trip a 1.10 flow without downgrading it**
1243
+ * ```ts
1244
+ * flow('claims').schemaVersion('1.10')
1245
+ * ```
1246
+ *
1247
+ * @param version - A writable file-format version, e.g. `'1.9'` or `'1.10'`.
1248
+ * @returns This builder, so calls chain.
1249
+ * @throws Error when this SDK build cannot write `version`.
1250
+ * @defaultValue `'1.9'` — `FLOW_FORMAT_PROFILE.version`, the fleet write floor.
1251
+ */
1252
+ schemaVersion(version: string): this;
1253
+ /**
1254
+ * Declare the flow's inputs. Read them with `input('<name>')`.
1255
+ *
1256
+ * @param shape - Input names to type descriptors, e.g. `{ amount: types.number }`.
1257
+ * @returns This builder, so calls chain.
1258
+ * @see input
1259
+ */
1260
+ input(shape: Record<string, TypeDesc | VarSpec>): this;
1261
+ /**
1262
+ * Declare the flow's outputs — what `.return(...)` binds values to.
1263
+ *
1264
+ * @param shape - Output names to type descriptors, e.g. `{ total: types.number }`.
1265
+ * @returns This builder, so calls chain.
1266
+ */
1267
+ output(shape: Record<string, TypeDesc | VarSpec>): this;
1268
+ /**
1269
+ * Declare a flow-level variable. Read it with `v('<name>')`.
1270
+ *
1271
+ * @param name - The variable's name.
1272
+ * @param type - One of the `types.*` descriptors.
1273
+ * @param defaultValue - Its initial value. Omit it to start undeclared.
1274
+ * @returns This builder, so calls chain.
1275
+ * @see v
1276
+ */
1277
+ var(name: string, type: TypeDesc | VarSpec, defaultValue?: unknown): this;
1278
+ /**
1279
+ * Finish the flow and return the graph the compiler serializes.
1280
+ *
1281
+ * @returns The built description — inputs, outputs, variables, trigger and steps.
1282
+ * @throws FlowBuildError when an expression references something undeclared.
1283
+ */
1284
+ build(): BuiltFlow;
1285
+ }
1286
+ /**
1287
+ * Start building a flow with the given id.
1288
+ *
1289
+ * @param id - The flow's stable identifier, and its display name until
1290
+ * `.name(...)` says otherwise.
1291
+ * @returns A {@link FlowBuilder} to declare inputs and chain steps onto.
1292
+ * @example
1293
+ * ```ts
1294
+ * export default flow('hello').name('Hello')
1295
+ * .output({ greeting: types.string })
1296
+ * .step('greet', script({ code: 'return "hi";', returns: 'string' }))
1297
+ * .return({ greeting: out('greet') })
1298
+ * .build();
1299
+ * ```
1300
+ */
1301
+ export declare function flow(id: string): FlowBuilder;
1302
+ /**
1303
+ * Run another flow as one step, and read back what it returns.
1304
+ *
1305
+ * @remarks
1306
+ * The child is an ordinary `flow()` in the same file — its own inputs, steps
1307
+ * and `.return()`. Don't call `.build()` on it; the parent's `.build()` collects
1308
+ * it. Two scopes, joined only by this call: the child sees NOTHING of the
1309
+ * parent's variables except the values passed in here.
1310
+ *
1311
+ * `inputs` keys are the CHILD's declared input names; the values are
1312
+ * parent-scope expressions. A subflow's output is an OBJECT of the child's
1313
+ * declared outputs, so read it with the output's name —
1314
+ * `out('callReverse', 'reversed')`, never a bare `out('callReverse')`.
1315
+ *
1316
+ * Scopes, reuse, nesting, and what a local run does and does not prove:
1317
+ * `references/subflow.md`.
1318
+ *
1319
+ * @example
1320
+ * **Call a child flow and read its named output**
1321
+ * ```ts
1322
+ * const reverse = flow('reverse-text')
1323
+ * .input({ text: types.string })
1324
+ * .output({ reversed: types.string })
1325
+ * .step('rev', script({ code: 'return $vars.text.split("").reverse().join("");' }))
1326
+ * .return({ reversed: out('rev') });
1327
+ *
1328
+ * export default flow('reverse-outer')
1329
+ * .input({ text: types.string })
1330
+ * .output({ result: types.string })
1331
+ * .step('callReverse', subflow(reverse, { text: input('text') }))
1332
+ * .return({ result: out('callReverse', 'reversed') }) // NAME the child output
1333
+ * .build();
1334
+ * ```
1335
+ *
1336
+ * @param child - The child flow — a `flow()` builder or an already-built flow.
1337
+ * @param inputs - One value per the CHILD's declared input names, as parent-scope
1338
+ * expressions.
1339
+ * @returns An action spec for `.step(...)`.
1340
+ */
1341
+ export declare function subflow(child: ChildFlow, inputs?: Record<string, Expr | unknown>): SubflowSpec;