@uipath/maestro-builder-sdk 6.16.13 → 6.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-index.md +108 -107
- package/dist/api-members.md +295 -291
- package/dist/bindings-v2.d.ts +39 -1
- package/dist/bindings-v2.js +289 -9
- package/dist/bpmn/compile-cli.js +11 -2
- package/dist/bpmn/decompile.js +2 -1
- package/dist/bpmn/registry-fallback.js +9 -7
- package/dist/case/compile-cli.js +16 -6
- package/dist/case/decompile-cli.js +2 -1
- package/dist/case/decompile.js +3 -2
- package/dist/case/merge-cli.js +3 -2
- package/dist/check.js +219 -37
- package/dist/cli-result.d.ts +9 -0
- package/dist/cli-result.js +12 -0
- package/dist/compile-cli.js +78 -53
- package/dist/core/actions.d.ts +70 -16
- package/dist/core/agentic-process-forms.d.ts +51 -0
- package/dist/core/agentic-process-forms.js +49 -0
- package/dist/core/binding-messages.d.ts +5 -0
- package/dist/core/comment-text.d.ts +29 -0
- package/dist/core/comment-text.js +40 -0
- package/dist/core/contribution-bindings.d.ts +73 -0
- package/dist/core/contribution-bindings.js +105 -0
- package/dist/core/expr-check.js +7 -2
- package/dist/core/json-file.d.ts +1 -0
- package/dist/core/json-file.js +12 -0
- package/dist/core/script-return.js +4 -1
- package/dist/core/typed-raw-node.js +1 -0
- package/dist/core/typescript-module.d.ts +2 -0
- package/dist/core/typescript-module.js +18 -0
- package/dist/core-definitions.json +210 -0
- package/dist/decompile-cli.js +2 -1
- package/dist/decompile.js +64 -24
- package/dist/emit.js +4 -3
- package/dist/flow-sdk.d.ts +14 -9
- package/dist/flow-sdk.js +14 -4
- package/dist/flow-step-tree.d.ts +2 -3
- package/dist/flow-step-tree.js +2 -3
- package/dist/load.js +1 -1
- package/dist/merge-cli.js +3 -2
- package/dist/merge.d.ts +2 -1
- package/dist/merge.js +0 -0
- package/dist/path-within.d.ts +33 -0
- package/dist/path-within.js +41 -0
- package/dist/registry/archive/extract.js +2 -5
- package/dist/registry/curated-overlay.js +3 -2
- package/dist/registry/generators/descriptors.js +20 -18
- package/dist/registry/generators/triggers.js +4 -4
- package/dist/registry/prepare/messages.js +2 -1
- package/dist/registry/prepare/source-labels.js +60 -1
- package/dist/registry/prepare-cli.js +14 -4
- package/dist/registry/pull-cli.js +3 -2
- package/dist/registry/uip/client.d.ts +28 -3
- package/dist/registry/uip/client.js +95 -34
- package/dist/registry/uip/host.d.ts +41 -0
- package/dist/registry/uip/host.js +312 -0
- package/dist/serialize.d.ts +7 -0
- package/dist/serialize.js +409 -275
- package/dist/workdir.js +1 -1
- package/package.json +3 -3
|
@@ -8852,6 +8852,216 @@
|
|
|
8852
8852
|
]
|
|
8853
8853
|
}
|
|
8854
8854
|
},
|
|
8855
|
+
"uipath.agent.autonomous@1.2": {
|
|
8856
|
+
"nodeType": "uipath.agent.autonomous",
|
|
8857
|
+
"version": "1.2",
|
|
8858
|
+
"category": "agent",
|
|
8859
|
+
"description": "AI agent that completes tasks autonomously",
|
|
8860
|
+
"tags": [
|
|
8861
|
+
"agentic",
|
|
8862
|
+
"ai",
|
|
8863
|
+
"autonomous",
|
|
8864
|
+
"agent"
|
|
8865
|
+
],
|
|
8866
|
+
"sortOrder": 5,
|
|
8867
|
+
"supportsErrorHandling": true,
|
|
8868
|
+
"display": {
|
|
8869
|
+
"label": "Autonomous Agent",
|
|
8870
|
+
"icon": "autonomous-agent",
|
|
8871
|
+
"shape": "rectangle"
|
|
8872
|
+
},
|
|
8873
|
+
"handleConfiguration": [
|
|
8874
|
+
{
|
|
8875
|
+
"position": "top",
|
|
8876
|
+
"handles": [
|
|
8877
|
+
{
|
|
8878
|
+
"id": "escalation",
|
|
8879
|
+
"type": "source",
|
|
8880
|
+
"handleType": "artifact",
|
|
8881
|
+
"label": "Escalations",
|
|
8882
|
+
"showButton": true,
|
|
8883
|
+
"constraints": {
|
|
8884
|
+
"allowedTargets": [
|
|
8885
|
+
{
|
|
8886
|
+
"nodeType": "uipath.agent.resource.escalation"
|
|
8887
|
+
},
|
|
8888
|
+
{
|
|
8889
|
+
"nodeType": "uipath.agent.resource.escalation.*"
|
|
8890
|
+
}
|
|
8891
|
+
],
|
|
8892
|
+
"validationMessage": "Only Agent Escalation nodes can connect here"
|
|
8893
|
+
}
|
|
8894
|
+
}
|
|
8895
|
+
]
|
|
8896
|
+
},
|
|
8897
|
+
{
|
|
8898
|
+
"position": "bottom",
|
|
8899
|
+
"handles": [
|
|
8900
|
+
{
|
|
8901
|
+
"id": "context",
|
|
8902
|
+
"type": "source",
|
|
8903
|
+
"handleType": "artifact",
|
|
8904
|
+
"label": "Context",
|
|
8905
|
+
"showButton": true,
|
|
8906
|
+
"constraints": {
|
|
8907
|
+
"allowedTargets": [
|
|
8908
|
+
{
|
|
8909
|
+
"nodeType": "uipath.agent.resource.context.*"
|
|
8910
|
+
}
|
|
8911
|
+
],
|
|
8912
|
+
"validationMessage": "Only Context resource nodes can connect here"
|
|
8913
|
+
}
|
|
8914
|
+
},
|
|
8915
|
+
{
|
|
8916
|
+
"id": "tool",
|
|
8917
|
+
"type": "source",
|
|
8918
|
+
"handleType": "artifact",
|
|
8919
|
+
"label": "Tools",
|
|
8920
|
+
"showButton": true,
|
|
8921
|
+
"constraints": {
|
|
8922
|
+
"allowedTargets": [
|
|
8923
|
+
{
|
|
8924
|
+
"nodeType": "uipath.agent.resource.tool.*"
|
|
8925
|
+
}
|
|
8926
|
+
],
|
|
8927
|
+
"validationMessage": "Only Tool resource nodes can connect here"
|
|
8928
|
+
}
|
|
8929
|
+
}
|
|
8930
|
+
]
|
|
8931
|
+
},
|
|
8932
|
+
{
|
|
8933
|
+
"position": "left",
|
|
8934
|
+
"handles": [
|
|
8935
|
+
{
|
|
8936
|
+
"id": "input",
|
|
8937
|
+
"type": "target",
|
|
8938
|
+
"handleType": "input"
|
|
8939
|
+
}
|
|
8940
|
+
]
|
|
8941
|
+
},
|
|
8942
|
+
{
|
|
8943
|
+
"position": "right",
|
|
8944
|
+
"handles": [
|
|
8945
|
+
{
|
|
8946
|
+
"id": "success",
|
|
8947
|
+
"type": "source",
|
|
8948
|
+
"handleType": "output",
|
|
8949
|
+
"isDefaultForType": true
|
|
8950
|
+
},
|
|
8951
|
+
{
|
|
8952
|
+
"id": "error",
|
|
8953
|
+
"type": "source",
|
|
8954
|
+
"handleType": "output",
|
|
8955
|
+
"label": "Error",
|
|
8956
|
+
"visible": "{inputs.errorHandlingEnabled}",
|
|
8957
|
+
"constraints": {
|
|
8958
|
+
"maxConnections": 1
|
|
8959
|
+
}
|
|
8960
|
+
}
|
|
8961
|
+
]
|
|
8962
|
+
}
|
|
8963
|
+
],
|
|
8964
|
+
"inputDefinition": {
|
|
8965
|
+
"type": "object",
|
|
8966
|
+
"properties": {
|
|
8967
|
+
"systemPrompt": {
|
|
8968
|
+
"type": "string",
|
|
8969
|
+
"minLength": 1,
|
|
8970
|
+
"errorMessage": {
|
|
8971
|
+
"minLength": "System prompt is required"
|
|
8972
|
+
}
|
|
8973
|
+
},
|
|
8974
|
+
"userPrompt": {
|
|
8975
|
+
"type": "string",
|
|
8976
|
+
"minLength": 1,
|
|
8977
|
+
"errorMessage": {
|
|
8978
|
+
"minLength": "User prompt is required"
|
|
8979
|
+
}
|
|
8980
|
+
},
|
|
8981
|
+
"model": {
|
|
8982
|
+
"type": "string",
|
|
8983
|
+
"minLength": 1,
|
|
8984
|
+
"errorMessage": {
|
|
8985
|
+
"minLength": "Model is required"
|
|
8986
|
+
}
|
|
8987
|
+
},
|
|
8988
|
+
"temperature": {
|
|
8989
|
+
"type": "number",
|
|
8990
|
+
"minimum": 0,
|
|
8991
|
+
"maximum": 1
|
|
8992
|
+
},
|
|
8993
|
+
"maxTokenPerResponse": {
|
|
8994
|
+
"type": "number",
|
|
8995
|
+
"minimum": 0,
|
|
8996
|
+
"maximum": 16384
|
|
8997
|
+
},
|
|
8998
|
+
"modelMaxTokens": {
|
|
8999
|
+
"type": "number",
|
|
9000
|
+
"minimum": 0
|
|
9001
|
+
},
|
|
9002
|
+
"maxIterations": {
|
|
9003
|
+
"type": "number",
|
|
9004
|
+
"minimum": 1,
|
|
9005
|
+
"maximum": 100
|
|
9006
|
+
},
|
|
9007
|
+
"guardrails": {
|
|
9008
|
+
"type": "array"
|
|
9009
|
+
},
|
|
9010
|
+
"agentInputVariables": {
|
|
9011
|
+
"type": "array"
|
|
9012
|
+
},
|
|
9013
|
+
"agentOutputVariables": {
|
|
9014
|
+
"type": "array"
|
|
9015
|
+
}
|
|
9016
|
+
},
|
|
9017
|
+
"required": [
|
|
9018
|
+
"systemPrompt",
|
|
9019
|
+
"userPrompt",
|
|
9020
|
+
"model"
|
|
9021
|
+
]
|
|
9022
|
+
},
|
|
9023
|
+
"inputDefaults": {},
|
|
9024
|
+
"outputDefinition": {
|
|
9025
|
+
"output": {
|
|
9026
|
+
"type": "object",
|
|
9027
|
+
"description": "Agent response",
|
|
9028
|
+
"source": "=result.response",
|
|
9029
|
+
"var": "output"
|
|
9030
|
+
},
|
|
9031
|
+
"error": {
|
|
9032
|
+
"type": "object",
|
|
9033
|
+
"description": "Error information if the node fails",
|
|
9034
|
+
"source": "=Error",
|
|
9035
|
+
"var": "error"
|
|
9036
|
+
}
|
|
9037
|
+
},
|
|
9038
|
+
"model": {
|
|
9039
|
+
"source": true,
|
|
9040
|
+
"type": "bpmn:ServiceTask",
|
|
9041
|
+
"serviceType": "Orchestrator.StartInlineAgentJob",
|
|
9042
|
+
"version": "v2",
|
|
9043
|
+
"context": [
|
|
9044
|
+
{
|
|
9045
|
+
"name": "_label",
|
|
9046
|
+
"type": "string",
|
|
9047
|
+
"value": ""
|
|
9048
|
+
},
|
|
9049
|
+
{
|
|
9050
|
+
"name": "name",
|
|
9051
|
+
"type": "string",
|
|
9052
|
+
"value": ""
|
|
9053
|
+
},
|
|
9054
|
+
{
|
|
9055
|
+
"name": "entryPoint",
|
|
9056
|
+
"type": "string",
|
|
9057
|
+
"value": ""
|
|
9058
|
+
}
|
|
9059
|
+
]
|
|
9060
|
+
},
|
|
9061
|
+
"debug": {
|
|
9062
|
+
"runtime": "bpmnEngine"
|
|
9063
|
+
}
|
|
9064
|
+
},
|
|
8855
9065
|
"uipath.agent.autonomous@1.3": {
|
|
8856
9066
|
"nodeType": "uipath.agent.autonomous",
|
|
8857
9067
|
"version": "1.3",
|
package/dist/decompile-cli.js
CHANGED
|
@@ -25,6 +25,7 @@ import { decompile } from './decompile.js';
|
|
|
25
25
|
import { resolveFlowRefs } from './ref-resolve.js';
|
|
26
26
|
import { flagValue, runWhenInvokedDirectly } from './cli-run.js';
|
|
27
27
|
import { PACKAGE_NAME } from './package-name.js';
|
|
28
|
+
import { commentText } from './core/comment-text.js';
|
|
28
29
|
/** Derive a PascalCase base name from the flow name/id for the default output file. */
|
|
29
30
|
function baseName(flow) {
|
|
30
31
|
const src = flow.name ?? flow.id ?? 'Flow';
|
|
@@ -101,7 +102,7 @@ function pipelineScript(originalPath, tsPath, pipelinePath) {
|
|
|
101
102
|
const base = pipelinePath.replace(/\.pipeline\.mjs$/, '');
|
|
102
103
|
return `#!/usr/bin/env node
|
|
103
104
|
// Generated by flow-decompile — the brownfield read/modify/write pipeline for
|
|
104
|
-
// ${basename(originalPath)}. Run it, edit ${basename(tsPath)}, run it again.
|
|
105
|
+
// ${commentText(basename(originalPath))}. Run it, edit ${commentText(basename(tsPath))}, run it again.
|
|
105
106
|
import { execFileSync, spawnSync } from 'node:child_process';
|
|
106
107
|
import { existsSync } from 'node:fs';
|
|
107
108
|
|
package/dist/decompile.js
CHANGED
|
@@ -35,6 +35,7 @@ import { dirname, join } from 'node:path';
|
|
|
35
35
|
import { fileURLToPath } from 'node:url';
|
|
36
36
|
import { inferScriptShape } from './core/script-return.js';
|
|
37
37
|
import { DEFAULT_TRIGGER_ID } from './core/expr.js';
|
|
38
|
+
import { commentText } from './core/comment-text.js';
|
|
38
39
|
import { parseIxpProjectType } from './core/actions.js';
|
|
39
40
|
import { readFlowGlobals } from './flow-variables.js';
|
|
40
41
|
import { missingBindingLabels } from './core/binding-messages.js';
|
|
@@ -95,7 +96,19 @@ function warnOnce(message) {
|
|
|
95
96
|
* emitted source; saying so here is the difference between a loop that fails
|
|
96
97
|
* at step 2 with a hint and one that fails at step 2 with a puzzle.
|
|
97
98
|
*/
|
|
98
|
-
const
|
|
99
|
+
const CORE_DEFINITIONS = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), 'core-definitions.json'), 'utf8'));
|
|
100
|
+
const CORE_DEFINITION_KEYS = new Set(Object.keys(CORE_DEFINITIONS));
|
|
101
|
+
/**
|
|
102
|
+
* The label the canvas gives a freshly dropped `node`: its definition's
|
|
103
|
+
* `display.label`, from the file's own `definitions[]`, else the bundled core
|
|
104
|
+
* definition. `serialize` uses the same label when the author sets none.
|
|
105
|
+
*/
|
|
106
|
+
function definitionLabel(node) {
|
|
107
|
+
const key = `${node.type}@${node.typeVersion}`;
|
|
108
|
+
const def = runDefs.get(key) ?? CORE_DEFINITIONS[key] ?? runDefs.get(node.type);
|
|
109
|
+
const label = def?.display?.label;
|
|
110
|
+
return typeof label === 'string' ? label : undefined;
|
|
111
|
+
}
|
|
99
112
|
function verClause(node) {
|
|
100
113
|
const tv = node.typeVersion;
|
|
101
114
|
if (!tv) {
|
|
@@ -124,6 +137,25 @@ function verArg(node) {
|
|
|
124
137
|
const clause = verClause(node);
|
|
125
138
|
return clause ? `, { ${clause} }` : '';
|
|
126
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* A trigger node's option clauses: its exact `version`, and its canvas `label`
|
|
142
|
+
* when that differs from the definition's label (`definitionLabel`).
|
|
143
|
+
*/
|
|
144
|
+
function triggerOptParts(node) {
|
|
145
|
+
const parts = [];
|
|
146
|
+
const ver = verClause(node);
|
|
147
|
+
if (ver)
|
|
148
|
+
parts.push(ver);
|
|
149
|
+
const label = node.display?.label;
|
|
150
|
+
if (typeof label === 'string' && label !== definitionLabel(node))
|
|
151
|
+
parts.push(`label: ${str(label)}`);
|
|
152
|
+
return parts;
|
|
153
|
+
}
|
|
154
|
+
/** `triggerOptParts` as the `.trigger(spec, { ... })` options argument. */
|
|
155
|
+
function triggerOptsArg(node) {
|
|
156
|
+
const parts = triggerOptParts(node);
|
|
157
|
+
return parts.length ? `, { ${parts.join(', ')} }` : '';
|
|
158
|
+
}
|
|
127
159
|
/**
|
|
128
160
|
* The full node-options argument for steps that can carry both an exact
|
|
129
161
|
* `version` and mid-flow `updates` (the format's `variableUpdates[nodeId]`,
|
|
@@ -1083,11 +1115,12 @@ function sidecarAgentInputs(node) {
|
|
|
1083
1115
|
? numberUnless(settings.maxIterations, STUDIO_WEB_DEFAULT_MAX_ITERATIONS)
|
|
1084
1116
|
: typeof settings.maxIterations === 'number' ? settings.maxIterations : undefined;
|
|
1085
1117
|
// `mode` is a harness choice on the inline agent only; the conversational and
|
|
1086
|
-
// voice sidecars always carry their family's fixed value.
|
|
1087
|
-
//
|
|
1088
|
-
//
|
|
1118
|
+
// voice sidecars always carry their family's fixed value. `'standard'` is the
|
|
1119
|
+
// sidecar's default, so only another value is the author's. (Naming it no
|
|
1120
|
+
// longer selects a definition version — the node's `{ version }` carries that,
|
|
1121
|
+
// flow-builder-sdk#956.)
|
|
1089
1122
|
const mode = node.type === T.inlineAgent && typeof settings.mode === 'string'
|
|
1090
|
-
&&
|
|
1123
|
+
&& settings.mode !== 'standard'
|
|
1091
1124
|
? settings.mode : undefined;
|
|
1092
1125
|
return {
|
|
1093
1126
|
...(system === undefined ? {} : { systemPrompt: system }),
|
|
@@ -1616,7 +1649,7 @@ function unboundMarker(node, labels, key, action) {
|
|
|
1616
1649
|
+ `The source leaves ${missing.length > 1 ? 'them' : 'it'} out, and compile refuses the node (BINDING_MISSING) `
|
|
1617
1650
|
+ `until it names both labels: run \`${prepareCommand(key, action ?? '<action>')}\`, then pass `
|
|
1618
1651
|
+ `\`connection\` and \`folder\`.`);
|
|
1619
|
-
return ` /* TODO: bind ${names}; compile refuses this node until it has both labels (BINDING_MISSING) */`;
|
|
1652
|
+
return ` /* TODO: bind ${commentText(names)}; compile refuses this node until it has both labels (BINDING_MISSING) */`;
|
|
1620
1653
|
}
|
|
1621
1654
|
function emitEventSubscription(node, imp, inputNames) {
|
|
1622
1655
|
const prefix = node.type.startsWith('uipath.connector.event.') ? 'uipath.connector.event.'
|
|
@@ -1705,6 +1738,13 @@ function emitPublishedResource(node, imp, inputNames) {
|
|
|
1705
1738
|
// definition to read there is nothing to recover it from.
|
|
1706
1739
|
const name = binding('name');
|
|
1707
1740
|
const folderPath = binding('folderPath');
|
|
1741
|
+
// A sibling project of the same solution (#951): the model names its project
|
|
1742
|
+
// instead of a folder. `isInSolution` is flow-core's marker; an in-solution
|
|
1743
|
+
// agent emitted before #951 carries only `projectId`. Read back as
|
|
1744
|
+
// `location: 'in-solution'` so the recompile takes the in-solution path
|
|
1745
|
+
// instead of a published one with an empty folder.
|
|
1746
|
+
const projectId = typeof def?.model?.projectId === 'string' ? def.model.projectId : undefined;
|
|
1747
|
+
const inSolution = def?.model?.isInSolution === true || projectId !== undefined;
|
|
1708
1748
|
const inputs = { ...(node.inputs ?? {}) };
|
|
1709
1749
|
// The design-time fire-and-forget switch is an OPTION on the factory, not a
|
|
1710
1750
|
// process argument — serialize adds it to `inputs` after rendering the
|
|
@@ -1720,7 +1760,9 @@ function emitPublishedResource(node, imp, inputNames) {
|
|
|
1720
1760
|
return `${imp.use(family.factory)}(${opts([
|
|
1721
1761
|
['key', str(key)],
|
|
1722
1762
|
['name', name !== undefined ? str(name) : undefined],
|
|
1723
|
-
['
|
|
1763
|
+
['location', inSolution ? str('in-solution') : undefined],
|
|
1764
|
+
['folderPath', !inSolution && folderPath !== undefined ? str(folderPath) : undefined],
|
|
1765
|
+
['projectId', inSolution && projectId !== undefined ? str(projectId) : undefined],
|
|
1724
1766
|
['inputs', inputRows.length ? objLit(inputRows) : undefined],
|
|
1725
1767
|
['returns', returns],
|
|
1726
1768
|
['form', family.form !== undefined ? str(family.form) : undefined],
|
|
@@ -1792,7 +1834,7 @@ function unsupportedSpec(node, imp, o) {
|
|
|
1792
1834
|
}
|
|
1793
1835
|
// No definition to carry: a mock publishes nothing and takes no inputs, so it
|
|
1794
1836
|
// is a safe structural stand-in, and the marker records what it replaced.
|
|
1795
|
-
return `${imp.use('mock')}() /* TODO: unsupported node type ${node.type} */`;
|
|
1837
|
+
return `${imp.use('mock')}() /* TODO: unsupported node type ${commentText(node.type)} */`;
|
|
1796
1838
|
}
|
|
1797
1839
|
/** `some-node.id` → `someNodeId`, for a hoisted const name. */
|
|
1798
1840
|
function camel(id) {
|
|
@@ -1902,39 +1944,39 @@ function emitTrigger(e, depth, trigger, imp, o, inputNames = new Set()) {
|
|
|
1902
1944
|
// The default trigger, spelled out: decompiled source is deliberately more
|
|
1903
1945
|
// explicit than hand-authored source so the node's exact definition version
|
|
1904
1946
|
// survives recompilation (design §5.3).
|
|
1905
|
-
e.line(depth, `.trigger(${imp.use('manual')}()${
|
|
1947
|
+
e.line(depth, `.trigger(${imp.use('manual')}()${triggerOptsArg(trigger)})`);
|
|
1906
1948
|
return;
|
|
1907
1949
|
}
|
|
1908
1950
|
if (trigger.type === T.triggerScheduled) {
|
|
1909
|
-
e.line(depth, `.trigger(${imp.use('scheduled')}(${opts([['every', str(scheduleEvery(trigger))]])})${
|
|
1951
|
+
e.line(depth, `.trigger(${imp.use('scheduled')}(${opts([['every', str(scheduleEvery(trigger))]])})${triggerOptsArg(trigger)})`);
|
|
1910
1952
|
return;
|
|
1911
1953
|
}
|
|
1912
1954
|
if (trigger.type === T.triggerForm) {
|
|
1913
1955
|
// The schema is DERIVED from the flow's inputs at compile time, so nothing
|
|
1914
1956
|
// of it needs recovering — the factory takes no arguments.
|
|
1915
|
-
e.line(depth, `.trigger(${imp.use('formTrigger')}()${
|
|
1957
|
+
e.line(depth, `.trigger(${imp.use('formTrigger')}()${triggerOptsArg(trigger)})`);
|
|
1916
1958
|
return;
|
|
1917
1959
|
}
|
|
1918
1960
|
if (trigger.type === T.triggerConversation) {
|
|
1919
|
-
e.line(depth, `.trigger(${imp.use('conversationTrigger')}()${
|
|
1961
|
+
e.line(depth, `.trigger(${imp.use('conversationTrigger')}()${triggerOptsArg(trigger)})`);
|
|
1920
1962
|
return;
|
|
1921
1963
|
}
|
|
1922
1964
|
if (trigger.type === T.triggerVoice) {
|
|
1923
|
-
e.line(depth, `.trigger(${imp.use('voiceTrigger')}()${
|
|
1965
|
+
e.line(depth, `.trigger(${imp.use('voiceTrigger')}()${triggerOptsArg(trigger)})`);
|
|
1924
1966
|
return;
|
|
1925
1967
|
}
|
|
1926
1968
|
// A connector EVENT trigger — the same subscription body as a mid-flow wait.
|
|
1927
1969
|
{
|
|
1928
1970
|
const sub = emitEventSubscription(trigger, imp, inputNames);
|
|
1929
1971
|
if (sub !== undefined) {
|
|
1930
|
-
e.line(depth, `.trigger(${imp.use('onEvent')}(${sub})${
|
|
1972
|
+
e.line(depth, `.trigger(${imp.use('onEvent')}(${sub})${triggerOptsArg(trigger)})`);
|
|
1931
1973
|
return;
|
|
1932
1974
|
}
|
|
1933
1975
|
}
|
|
1934
1976
|
if (o.bestEffort === false) {
|
|
1935
1977
|
throw new Error(`decompile: unsupported trigger type "${trigger.type}".`);
|
|
1936
1978
|
}
|
|
1937
|
-
e.line(depth, `/* TODO: unsupported trigger type ${trigger.type} */`);
|
|
1979
|
+
e.line(depth, `/* TODO: unsupported trigger type ${commentText(trigger.type)} */`);
|
|
1938
1980
|
}
|
|
1939
1981
|
// ─── Control-flow reconstruction (Phase 3) ────────────────────────────────────
|
|
1940
1982
|
//
|
|
@@ -2350,7 +2392,7 @@ function region(cursor, stop, scope, ipdom, ctx, refInto) {
|
|
|
2350
2392
|
// Unstructured fan-out we can't fold — best-effort marker.
|
|
2351
2393
|
if (ctx.o.bestEffort === false)
|
|
2352
2394
|
throw new Error(`decompile: unstructured fan-out at "${node.id}".`);
|
|
2353
|
-
segs.push(`/* TODO: unstructured fan-out at ${node.id} (${succ.length} successors) */`);
|
|
2395
|
+
segs.push(`/* TODO: unstructured fan-out at ${commentText(node.id)} (${commentText(succ.length)} successors) */`);
|
|
2354
2396
|
return segs;
|
|
2355
2397
|
}
|
|
2356
2398
|
return segs;
|
|
@@ -2637,7 +2679,7 @@ function emitSubflow(node, ctx) {
|
|
|
2637
2679
|
if (!child) {
|
|
2638
2680
|
if (ctx.o.bestEffort === false)
|
|
2639
2681
|
throw new Error(`decompile: subflow "${node.id}" has no body in subflows[].`);
|
|
2640
|
-
return `${ctx.imp.use('mock')}() /* TODO: subflow ${node.id} body missing */`;
|
|
2682
|
+
return `${ctx.imp.use('mock')}() /* TODO: subflow ${commentText(node.id)} body missing */`;
|
|
2641
2683
|
}
|
|
2642
2684
|
const childName = `${node.id}Child`;
|
|
2643
2685
|
const childSrc = emitChildFlow(childName, child, ctx);
|
|
@@ -2736,7 +2778,7 @@ export function decompile(flow, options = {}) {
|
|
|
2736
2778
|
if (runStrict)
|
|
2737
2779
|
throw new Error(`decompile: ${schema.problem}`);
|
|
2738
2780
|
warnOnce(schema.problem);
|
|
2739
|
-
e.line(d, `// TODO: ${schema.problem}`);
|
|
2781
|
+
e.line(d, `// TODO: ${commentText(schema.problem)}`);
|
|
2740
2782
|
}
|
|
2741
2783
|
if (flow.name !== undefined && flow.name !== flow.id)
|
|
2742
2784
|
e.line(d, `.name(${str(flow.name)})`);
|
|
@@ -2772,7 +2814,7 @@ export function decompile(flow, options = {}) {
|
|
|
2772
2814
|
throw new Error(`decompile: ${message}`);
|
|
2773
2815
|
warnOnce(message);
|
|
2774
2816
|
for (const n of detached) {
|
|
2775
|
-
e.line(d, `// TODO: node ${str(n.id)} (${n.type}) is not reachable from any trigger and is NOT in this source; recompiling drops it. Connect it in the .flow or edit its JSON directly.`);
|
|
2817
|
+
e.line(d, `// TODO: node ${commentText(str(n.id))} (${commentText(n.type)}) is not reachable from any trigger and is NOT in this source; recompiling drops it. Connect it in the .flow or edit its JSON directly.`);
|
|
2776
2818
|
}
|
|
2777
2819
|
}
|
|
2778
2820
|
// `{ shared }` input copies on the roots (#924). Any other trigger-level
|
|
@@ -2786,7 +2828,7 @@ export function decompile(flow, options = {}) {
|
|
|
2786
2828
|
if (runStrict)
|
|
2787
2829
|
throw new Error(`decompile: ${message}`);
|
|
2788
2830
|
warnOnce(message);
|
|
2789
|
-
e.line(d, `// TODO: ${message}`);
|
|
2831
|
+
e.line(d, `// TODO: ${commentText(message)}`);
|
|
2790
2832
|
}
|
|
2791
2833
|
emitVariables(e, d, flow, imp, new Set(triggerNodes.filter((t) => t !== trigger).map((t) => t.id)), shared);
|
|
2792
2834
|
// Reconstruct the body: structured control flow recovered from the graph.
|
|
@@ -2876,7 +2918,7 @@ function entryPointSeg(t, scope, ipdom, ctx) {
|
|
|
2876
2918
|
: (() => {
|
|
2877
2919
|
if (ctx.o.bestEffort === false)
|
|
2878
2920
|
throw new Error(`decompile: unsupported entry-point trigger type "${t.type}".`);
|
|
2879
|
-
return `${ctx.imp.use('manual')}() /* TODO: unsupported trigger type ${t.type} */`;
|
|
2921
|
+
return `${ctx.imp.use('manual')}() /* TODO: unsupported trigger type ${commentText(t.type)} */`;
|
|
2880
2922
|
})();
|
|
2881
2923
|
const scoped = readFlowGlobals(ctx.flow.variables, runStrict)
|
|
2882
2924
|
.filter((g) => g.direction === 'in' && g.triggerNodeId === t.id);
|
|
@@ -2885,9 +2927,7 @@ function entryPointSeg(t, scope, ipdom, ctx) {
|
|
|
2885
2927
|
const sharedOf = (g) => ctx.shared?.byInput.get(`${t.id}\0${g.id}`);
|
|
2886
2928
|
optParts.push(`inputs: { ${scoped.map((g) => `${key(g.name ?? g.id)}: ${declExpr(g, true, ctx.imp, sharedOf(g))}`).join(', ')} }`);
|
|
2887
2929
|
}
|
|
2888
|
-
|
|
2889
|
-
if (ver)
|
|
2890
|
-
optParts.push(ver);
|
|
2930
|
+
optParts.push(...triggerOptParts(t));
|
|
2891
2931
|
const first = scopeSucc(ctx.graph, t.id, scope)[0];
|
|
2892
2932
|
const prefixSegs = first !== undefined ? region(first, EXIT, scope, ipdom, ctx) : [];
|
|
2893
2933
|
const optArgText = optParts.length ? `, { ${optParts.join(', ')} }` : (prefixSegs.length ? ', undefined' : '');
|
package/dist/emit.js
CHANGED
|
@@ -25,13 +25,14 @@
|
|
|
25
25
|
* are the ones `.build()` and `serialize()` raise themselves. Callers who want
|
|
26
26
|
* the static pass should call `check()` — or use `compile-cli`.
|
|
27
27
|
*/
|
|
28
|
-
import {
|
|
28
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
29
29
|
import { dirname, join } from 'node:path';
|
|
30
30
|
import { serialize } from './serialize.js';
|
|
31
31
|
import { Library } from './library.js';
|
|
32
32
|
import { Bindings } from './bindings.js';
|
|
33
33
|
import { resolveLibraryDir } from './core/library-cache.js';
|
|
34
34
|
import { defaultBindingsFile } from './workdir.js';
|
|
35
|
+
import { writeJsonFile } from './core/json-file.js';
|
|
35
36
|
/**
|
|
36
37
|
* Resolve the connector library the same way `compile-cli` does: only load it
|
|
37
38
|
* when it is actually there, so a flow with no connectors emits fine without a
|
|
@@ -51,11 +52,11 @@ export function emitFlow(built, path, opts = {}) {
|
|
|
51
52
|
library: opts.library ?? defaultLibrary(opts.libraryDir),
|
|
52
53
|
bindings: opts.bindings ?? new Bindings(bindFile),
|
|
53
54
|
// Same channel `compile` uses; a host that wants them elsewhere passes `warn`.
|
|
54
|
-
warn: opts.warn ?? ((w) =>
|
|
55
|
+
warn: opts.warn ?? ((w) => process.stderr.write(` ⚠ [${w.code}] ${w.message}\n`)),
|
|
55
56
|
});
|
|
56
57
|
const dir = dirname(path);
|
|
57
58
|
if (dir && dir !== '.' && !existsSync(dir))
|
|
58
59
|
mkdirSync(dir, { recursive: true });
|
|
59
|
-
|
|
60
|
+
writeJsonFile(path, flowJson);
|
|
60
61
|
return flowJson;
|
|
61
62
|
}
|
package/dist/flow-sdk.d.ts
CHANGED
|
@@ -373,7 +373,8 @@ export interface NodeOptions {
|
|
|
373
373
|
updates?: Record<string, Expr | unknown>;
|
|
374
374
|
/**
|
|
375
375
|
* What the canvas shows on this node (`display.label`). Defaults to the step
|
|
376
|
-
* name
|
|
376
|
+
* name; on a trigger (`.trigger()`, `.entryPoint()`) to the trigger
|
|
377
|
+
* definition's label, e.g. `Manual trigger`.
|
|
377
378
|
*
|
|
378
379
|
* @remarks
|
|
379
380
|
* Purely cosmetic, and deliberately separate from the step name: the NAME is
|
|
@@ -386,8 +387,10 @@ export interface NodeOptions {
|
|
|
386
387
|
* .step('fetchInv', http({ url, managed: true }), { label: 'Fetch invoice' })
|
|
387
388
|
* ```
|
|
388
389
|
*
|
|
389
|
-
* `.branch()`, `.switch()`, `.loop()`, `.doWhile()`, `.parallel()
|
|
390
|
-
* `.
|
|
390
|
+
* `.branch()`, `.switch()`, `.loop()`, `.doWhile()`, `.parallel()`,
|
|
391
|
+
* `.trigger()` and `.entryPoint()` take it here too, in their options
|
|
392
|
+
* argument. Only `.terminate()` also has a positional label
|
|
393
|
+
* (`.terminate('stop', 'Stop here')`); when both are given, this option wins.
|
|
391
394
|
*/
|
|
392
395
|
label?: string;
|
|
393
396
|
}
|
|
@@ -663,7 +666,7 @@ export interface BuiltEntryPoint {
|
|
|
663
666
|
id: string;
|
|
664
667
|
/** What fires this root: any built-in trigger factory, or a custom trigger. */
|
|
665
668
|
trigger: TriggerSpec;
|
|
666
|
-
/** Node options for the trigger node — exact `version` selection
|
|
669
|
+
/** Node options for the trigger node — exact `version` selection and canvas `label`. */
|
|
667
670
|
options?: NodeOptions;
|
|
668
671
|
/** Inputs scoped to this root (globals bound to it via `triggerNodeId`). */
|
|
669
672
|
inputs: VarDecl[];
|
|
@@ -1235,7 +1238,8 @@ declare class FlowBuilder extends StepList {
|
|
|
1235
1238
|
*
|
|
1236
1239
|
* @param spec - What starts the flow, from `scheduled(...)` or `onEvent(...)`.
|
|
1237
1240
|
* @param options - Node options; `version` selects the exact definition
|
|
1238
|
-
* version
|
|
1241
|
+
* version and `label` sets what the canvas shows on the trigger node
|
|
1242
|
+
* (default: the trigger definition's label, e.g. `Scheduled trigger`). See {@link NodeOptions}.
|
|
1239
1243
|
* @returns This builder, so calls chain.
|
|
1240
1244
|
* @defaultValue the manual trigger
|
|
1241
1245
|
*/
|
|
@@ -1281,13 +1285,14 @@ declare class FlowBuilder extends StepList {
|
|
|
1281
1285
|
* @param trigger - What fires this root: `manual()`, `scheduled(...)`,
|
|
1282
1286
|
* `onEvent(...)`, `formTrigger()` (one field per scoped input),
|
|
1283
1287
|
* `conversationTrigger()`, or `voiceTrigger()`.
|
|
1284
|
-
* @param options - `version` (exact trigger definition version)
|
|
1285
|
-
*
|
|
1288
|
+
* @param options - `version` (exact trigger definition version), `label`
|
|
1289
|
+
* (what the canvas shows on the trigger node; default: the trigger
|
|
1290
|
+
* definition's label, e.g. `Manual trigger`), and `inputs` — this root's scoped inputs, declared like
|
|
1291
|
+
* `.input()`.
|
|
1286
1292
|
* @param prefixFn - Optional sub-builder for the root's prefix steps.
|
|
1287
1293
|
* @returns This builder, so calls chain.
|
|
1288
1294
|
*/
|
|
1289
|
-
entryPoint(id: string, trigger: TriggerSpec | FlowTrigger, options?: {
|
|
1290
|
-
version?: string;
|
|
1295
|
+
entryPoint(id: string, trigger: TriggerSpec | FlowTrigger, options?: Pick<NodeOptions, 'version' | 'label'> & {
|
|
1291
1296
|
inputs?: Record<string, TypeDesc | VarSpec>;
|
|
1292
1297
|
}, prefixFn?: (b: StepList) => void): this;
|
|
1293
1298
|
/**
|
package/dist/flow-sdk.js
CHANGED
|
@@ -942,7 +942,8 @@ class FlowBuilder extends StepList {
|
|
|
942
942
|
*
|
|
943
943
|
* @param spec - What starts the flow, from `scheduled(...)` or `onEvent(...)`.
|
|
944
944
|
* @param options - Node options; `version` selects the exact definition
|
|
945
|
-
* version
|
|
945
|
+
* version and `label` sets what the canvas shows on the trigger node
|
|
946
|
+
* (default: the trigger definition's label, e.g. `Scheduled trigger`). See {@link NodeOptions}.
|
|
946
947
|
* @returns This builder, so calls chain.
|
|
947
948
|
* @defaultValue the manual trigger
|
|
948
949
|
*/
|
|
@@ -996,8 +997,10 @@ class FlowBuilder extends StepList {
|
|
|
996
997
|
* @param trigger - What fires this root: `manual()`, `scheduled(...)`,
|
|
997
998
|
* `onEvent(...)`, `formTrigger()` (one field per scoped input),
|
|
998
999
|
* `conversationTrigger()`, or `voiceTrigger()`.
|
|
999
|
-
* @param options - `version` (exact trigger definition version)
|
|
1000
|
-
*
|
|
1000
|
+
* @param options - `version` (exact trigger definition version), `label`
|
|
1001
|
+
* (what the canvas shows on the trigger node; default: the trigger
|
|
1002
|
+
* definition's label, e.g. `Manual trigger`), and `inputs` — this root's scoped inputs, declared like
|
|
1003
|
+
* `.input()`.
|
|
1001
1004
|
* @param prefixFn - Optional sub-builder for the root's prefix steps.
|
|
1002
1005
|
* @returns This builder, so calls chain.
|
|
1003
1006
|
*/
|
|
@@ -1011,7 +1014,14 @@ class FlowBuilder extends StepList {
|
|
|
1011
1014
|
this._entryPoints.push({
|
|
1012
1015
|
id,
|
|
1013
1016
|
trigger: trigger,
|
|
1014
|
-
...(options?.version !== undefined
|
|
1017
|
+
...(options?.version !== undefined || options?.label !== undefined
|
|
1018
|
+
? {
|
|
1019
|
+
options: {
|
|
1020
|
+
...(options.version !== undefined ? { version: options.version } : {}),
|
|
1021
|
+
...(options.label !== undefined ? { label: options.label } : {}),
|
|
1022
|
+
},
|
|
1023
|
+
}
|
|
1024
|
+
: {}),
|
|
1015
1025
|
inputs,
|
|
1016
1026
|
steps: b.steps,
|
|
1017
1027
|
});
|
package/dist/flow-step-tree.d.ts
CHANGED
|
@@ -15,9 +15,8 @@ export declare function stopsAtEnd(steps: readonly Step[]): boolean;
|
|
|
15
15
|
* The step lists nested DIRECTLY inside `step` — the bodies a walk over this
|
|
16
16
|
* flow's own tree must descend into. Exhaustive over `Step['kind']`, so a new
|
|
17
17
|
* container kind fails to compile here instead of being silently skipped by
|
|
18
|
-
* every walker. That is how `check`
|
|
19
|
-
* arms and `.stepToList` / `.onError` bodies
|
|
20
|
-
* whose every path ends in `.return()` (UV-16855).
|
|
18
|
+
* every walker. That is how an earlier `check` return scan came to miss
|
|
19
|
+
* `.stepSwitch` arms and `.stepToList` / `.onError` bodies (UV-16855).
|
|
21
20
|
*
|
|
22
21
|
* A subflow's child flow is deliberately NOT a child here: it is another
|
|
23
22
|
* flow's tree, and its returns say nothing about whether THIS flow ends.
|
package/dist/flow-step-tree.js
CHANGED
|
@@ -15,9 +15,8 @@ export function stopsAtEnd(steps) {
|
|
|
15
15
|
* The step lists nested DIRECTLY inside `step` — the bodies a walk over this
|
|
16
16
|
* flow's own tree must descend into. Exhaustive over `Step['kind']`, so a new
|
|
17
17
|
* container kind fails to compile here instead of being silently skipped by
|
|
18
|
-
* every walker. That is how `check`
|
|
19
|
-
* arms and `.stepToList` / `.onError` bodies
|
|
20
|
-
* whose every path ends in `.return()` (UV-16855).
|
|
18
|
+
* every walker. That is how an earlier `check` return scan came to miss
|
|
19
|
+
* `.stepSwitch` arms and `.stepToList` / `.onError` bodies (UV-16855).
|
|
21
20
|
*
|
|
22
21
|
* A subflow's child flow is deliberately NOT a child here: it is another
|
|
23
22
|
* flow's tree, and its returns say nothing about whether THIS flow ends.
|
package/dist/load.js
CHANGED
|
@@ -13,7 +13,7 @@ export function resolveFlowFile(arg) {
|
|
|
13
13
|
if (!statSync(resolvedCandidate, { throwIfNoEntry: false })?.isFile())
|
|
14
14
|
continue;
|
|
15
15
|
if (candidate !== arg && argStat?.isDirectory()) {
|
|
16
|
-
|
|
16
|
+
process.stderr.write(`flow source: "${resolvedArg}" is a directory; using "${resolvedCandidate}"\n`);
|
|
17
17
|
}
|
|
18
18
|
return resolvedCandidate;
|
|
19
19
|
}
|
package/dist/merge-cli.js
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* See merge.ts.
|
|
13
13
|
*/
|
|
14
14
|
import { reportResult } from './cli-result.js';
|
|
15
|
-
import {
|
|
15
|
+
import { writeJsonFile } from './core/json-file.js';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
16
17
|
import { basename, resolve } from 'node:path';
|
|
17
18
|
import { mergeFlow } from './merge.js';
|
|
18
19
|
import { flagValue, runWhenInvokedDirectly } from './cli-run.js';
|
|
@@ -37,7 +38,7 @@ export function run(argv) {
|
|
|
37
38
|
warn: (m) => console.error(`flow-merge: warning: ${m}`),
|
|
38
39
|
});
|
|
39
40
|
const out = flagValue(argv, '-o') ?? 'merged.flow';
|
|
40
|
-
|
|
41
|
+
writeJsonFile(out, merged);
|
|
41
42
|
console.log(`flow-merge: wrote ${basename(out)} (${(merged.nodes ?? []).length} nodes, ${(merged.edges ?? []).length} edges)`);
|
|
42
43
|
reportResult({ path: resolve(out), nodes: (merged.nodes ?? []).length, edges: (merged.edges ?? []).length });
|
|
43
44
|
return 0;
|
package/dist/merge.d.ts
CHANGED
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
* as decompile was faithful for every node (the common case).
|
|
26
26
|
*
|
|
27
27
|
* Layout, `metadata`, `solutionId`, `projectId`, `runtime` and `layout` are
|
|
28
|
-
* preserved from the original; `
|
|
28
|
+
* preserved from the original; `subflows` and edges (with their ids) come from
|
|
29
|
+
* `edited`; `definitions` and `bindings` are unioned
|
|
29
30
|
* (original wins on conflict, since the original's are the tenant-resolved
|
|
30
31
|
* authority). Node ids are stable by construction (decompile names every step by
|
|
31
32
|
* its node id), which is what lets every re-attach key on id.
|
package/dist/merge.js
CHANGED
|
Binary file
|