@uipath/maestro-builder-sdk 6.16.14 → 6.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/api-index.md +115 -114
- 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-cli.js +2 -30
- package/dist/check.js +278 -55
- package/dist/cli-library.d.ts +18 -4
- package/dist/cli-library.js +24 -6
- package/dist/cli-result.d.ts +9 -0
- package/dist/cli-result.js +12 -0
- package/dist/compile-cli.js +82 -86
- package/dist/core/actions.d.ts +71 -17
- 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/cli-library.d.ts +16 -7
- package/dist/core/cli-library.js +53 -19
- package/dist/core/comment-text.d.ts +29 -0
- package/dist/core/comment-text.js +40 -0
- package/dist/core/connector-checks.d.ts +18 -2
- package/dist/core/connector-checks.js +15 -5
- package/dist/core/contribution-bindings.d.ts +73 -0
- package/dist/core/contribution-bindings.js +105 -0
- package/dist/core/error-port.d.ts +25 -0
- package/dist/core/error-port.js +36 -0
- package/dist/core/expr-check.js +7 -2
- package/dist/core/expr.d.ts +11 -5
- package/dist/core/expr.js +9 -3
- package/dist/core/json-file.d.ts +1 -0
- package/dist/core/json-file.js +12 -0
- package/dist/core/library.d.ts +19 -0
- package/dist/core/library.js +22 -6
- 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 +18 -12
- package/dist/flow-sdk.js +19 -8
- 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 +414 -277
- package/dist/workdir.js +1 -1
- package/package.json +3 -3
package/dist/core/library.js
CHANGED
|
@@ -9,10 +9,26 @@
|
|
|
9
9
|
import { readFileSync, existsSync } from 'node:fs';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { prepareCommand } from './cli-spelling.js';
|
|
12
|
+
import { PULL_COMMAND } from './library-cache.js';
|
|
12
13
|
import { editDistance } from './edit-distance.js';
|
|
13
14
|
import { loadListEnvelopes, lookupListEnvelope } from './list-envelope.js';
|
|
14
15
|
import { lookupSpecOf } from './lookups.js';
|
|
15
16
|
import { loadByoaLedger, loadInvariantCollections, loadLookupResolutions } from './lookup-store.js';
|
|
17
|
+
/**
|
|
18
|
+
* The refusal {@link Library.resolve} throws, with a `code` for each reason.
|
|
19
|
+
*
|
|
20
|
+
* Typed so a caller can tell a refusal from a bug without matching on message
|
|
21
|
+
* text: `check` reports it under this code with this message, and a compile
|
|
22
|
+
* that throws it carries the same code into its `--json` diagnostics (#948).
|
|
23
|
+
*/
|
|
24
|
+
export class ConnectorResolveError extends Error {
|
|
25
|
+
code;
|
|
26
|
+
constructor(code, message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'ConnectorResolveError';
|
|
29
|
+
this.code = code;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
16
32
|
export class Library {
|
|
17
33
|
layers = [];
|
|
18
34
|
/** The LIST-ENVELOPE LEDGER, overlay first so a prepared entry can add a row. */
|
|
@@ -582,7 +598,7 @@ export class Library {
|
|
|
582
598
|
+ `the library index (\`index.json\`), and remember the two namespaces: `
|
|
583
599
|
+ `\`…connector.trigger.…\` starts a flow, \`…connector.event.…\` waits mid-flow.`
|
|
584
600
|
: '';
|
|
585
|
-
throw new
|
|
601
|
+
throw new ConnectorResolveError('CONNECTOR_NOT_IN_LIBRARY', `connector not in library: ${nodeType}${version ? '@' + version : ''}.${hint}`
|
|
586
602
|
+ this.describeMiss(nodeType, version, objectName));
|
|
587
603
|
}
|
|
588
604
|
/**
|
|
@@ -622,7 +638,7 @@ export class Library {
|
|
|
622
638
|
+ where
|
|
623
639
|
+ ' Note the operation slug is the nodeType segment, NOT the tenant\'s `objectName`'
|
|
624
640
|
+ ' — `uip maestro case spec` reports the latter, and the two can differ.'
|
|
625
|
-
+
|
|
641
|
+
+ ` If the operation is newer than the library, refresh it with \`${PULL_COMMAND}\`.`;
|
|
626
642
|
}
|
|
627
643
|
/** Every direct operation id under `prefix` (no further dot), across layers, sorted and de-duplicated. */
|
|
628
644
|
opsUnder(prefix) {
|
|
@@ -646,7 +662,7 @@ export class Library {
|
|
|
646
662
|
return ` No connector "${key}" in the library (${keys.length} indexed).`
|
|
647
663
|
+ (near && near !== key ? ` Closest: ${near}.` : '')
|
|
648
664
|
+ where
|
|
649
|
-
+
|
|
665
|
+
+ ` If the connector is newer than the library, refresh it with \`${PULL_COMMAND}\`.`;
|
|
650
666
|
}
|
|
651
667
|
/**
|
|
652
668
|
* The event half of {@link describeMiss}: which of the connector's EVENTS the
|
|
@@ -666,7 +682,7 @@ export class Library {
|
|
|
666
682
|
const waits = this.opsUnder(`uipath.connector.event.${key}.`);
|
|
667
683
|
// A start trigger resolves from either form; a mid-flow wait needs the `.event.` form itself.
|
|
668
684
|
const usable = kind === 'trigger' ? [...new Set([...starts, ...waits])].sort() : waits;
|
|
669
|
-
const refresh =
|
|
685
|
+
const refresh = ` If the event is newer than the library, refresh it with \`${PULL_COMMAND}\`.`;
|
|
670
686
|
if (usable.length) {
|
|
671
687
|
if (usable.includes(asked)) {
|
|
672
688
|
// Only a version can make a carried event miss here: every other refusal
|
|
@@ -755,7 +771,7 @@ export class Library {
|
|
|
755
771
|
+ `dispatch. If it is a typo, compile will not catch it.\n`);
|
|
756
772
|
return this.build(layer.dir, { ...only, objectName }, nodeType, { objectNameUnverified: true });
|
|
757
773
|
}
|
|
758
|
-
throw new
|
|
774
|
+
throw new ConnectorResolveError('CONNECTOR_OBJECT_NOT_GENERIC', `connector ${nodeType} does not have an object "${objectName}": it is a single, `
|
|
759
775
|
+ `non-generic operation addressing ${only.objectName ? `"${only.objectName}"` : 'no object'}. `
|
|
760
776
|
+ `Drop the \`object\` option (it is only for generic operations, whose node type covers many objects).`);
|
|
761
777
|
}
|
|
@@ -769,7 +785,7 @@ export class Library {
|
|
|
769
785
|
.filter((o) => typeof o === 'string' && o.length > 0)
|
|
770
786
|
.sort();
|
|
771
787
|
if (objectName === undefined) {
|
|
772
|
-
throw new
|
|
788
|
+
throw new ConnectorResolveError('CONNECTOR_OBJECT_REQUIRED', `connector ${nodeType} is a GENERIC operation covering ${matches.length} objects — `
|
|
773
789
|
+ `say which one with the \`object\` option, e.g. `
|
|
774
790
|
+ `connector('${nodeType.split('.').slice(2, 3)[0]}', '${nodeType.split('.').slice(3).join('.')}', `
|
|
775
791
|
+ `{ … }, { object: '${objects[0] ?? '<object>'}' }). ${describeObjects(objects)}`);
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* into a designer error — the exact defect this file exists to remove, pointed
|
|
29
29
|
* the other way.
|
|
30
30
|
*/
|
|
31
|
-
import
|
|
31
|
+
import { typescript } from './typescript-module.js';
|
|
32
32
|
/** Normalize whatever the author wrote into the emitted shape. */
|
|
33
33
|
export function declaredScriptShape(returns) {
|
|
34
34
|
if (typeof returns === 'string')
|
|
@@ -59,6 +59,7 @@ export function declaredScriptShape(returns) {
|
|
|
59
59
|
* fields written down says so with `returns: {…}`.
|
|
60
60
|
*/
|
|
61
61
|
export function inferScriptShape(code) {
|
|
62
|
+
const ts = typescript();
|
|
62
63
|
// Wrap so a top-level `return` parses — this is how the runtime executes it.
|
|
63
64
|
const sf = ts.createSourceFile('script.ts', `function __block() {\n${code}\n}`, ts.ScriptTarget.ES2020, true);
|
|
64
65
|
// `var d = Math.floor(...); return { days: d }` is how these bodies are
|
|
@@ -99,6 +100,7 @@ export function inferScriptShape(code) {
|
|
|
99
100
|
}
|
|
100
101
|
/** The type of one expression, or undefined when it is not written down. */
|
|
101
102
|
function typeOf(expr, locals, depth) {
|
|
103
|
+
const ts = typescript();
|
|
102
104
|
// Bounded: a local initialized from another local is followed, a cycle is not.
|
|
103
105
|
if (depth > 8)
|
|
104
106
|
return undefined;
|
|
@@ -163,6 +165,7 @@ function typeOf(expr, locals, depth) {
|
|
|
163
165
|
}
|
|
164
166
|
/** `a + b`, comparisons, and the short-circuit operators. */
|
|
165
167
|
function binaryShape(e, locals, depth) {
|
|
168
|
+
const ts = typescript();
|
|
166
169
|
const op = e.operatorToken.kind;
|
|
167
170
|
// A comparison is a boolean whatever its operands are.
|
|
168
171
|
if (op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsEqualsToken
|
|
@@ -55,6 +55,7 @@ export const TYPED_FACTORIES = {
|
|
|
55
55
|
'core.logic.switch': { factory: '.switch()', bundled: ['1.0.0', '1.1'] },
|
|
56
56
|
'core.logic.terminate': { factory: '.terminate()', bundled: ['1.0.0', '1.0'] },
|
|
57
57
|
'core.subflow': { factory: 'subflow(child, inputs)', bundled: ['1.0.0', '1.0'] },
|
|
58
|
+
'uipath.agent.autonomous': { factory: 'inlineAgent()', bundled: ['1.2', '1.3', '1.4'] },
|
|
58
59
|
'uipath.agent.conversational': { factory: 'conversationalAgent()', bundled: ['1.6', '1.7'] },
|
|
59
60
|
'uipath.agent.voice': { factory: 'voiceAgent()', bundled: ['1.0', '1.1'] },
|
|
60
61
|
'uipath.conversational.get-conversation-context': { factory: 'conversationContext()', bundled: ['1.0'] },
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/**
|
|
3
|
+
* The TypeScript compiler, loaded on first use.
|
|
4
|
+
*
|
|
5
|
+
* Every builder entry reaches the expression and script checkers, and loading the compiler
|
|
6
|
+
* costs ~120 ms that a flow which never runs those checks should not pay (FB009). The
|
|
7
|
+
* specifier stays a literal at the call so the architecture lint sees the edge (as a lazy
|
|
8
|
+
* one); FB005 keeps this the only definition.
|
|
9
|
+
*
|
|
10
|
+
* The triple-slash reference: tests type-check generated code against `flow-sdk.ts`'s
|
|
11
|
+
* import graph without `@types/node` in scope, and this is the one `node:` import in that
|
|
12
|
+
* graph. Without it they fail with TS2307 on 'node:module'. It is not emitted into the .d.ts.
|
|
13
|
+
*/
|
|
14
|
+
import { createRequire } from 'node:module';
|
|
15
|
+
let typescriptModule;
|
|
16
|
+
export function typescript() {
|
|
17
|
+
return (typescriptModule ??= createRequire(import.meta.url)('typescript'));
|
|
18
|
+
}
|
|
@@ -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
|
}
|