lua-cli 3.40.0 → 3.42.0-beta.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/dist/api-exports.d.ts +62 -18
- package/dist/api-exports.js +192 -21
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +2812 -602
- package/dist/index.js.map +1 -1
- package/dist/workflow-builder.d.ts +19 -3
- package/dist/workflow-builder.js +177 -8
- package/dist/workflow-builder.js.map +1 -1
- package/docs/workflows/reply-channels.md +2 -2
- package/docs/workflows/workspaces-and-long-steps.md +1 -1
- package/package.json +2 -1
- package/template/package.json +1 -1
- package/template/tsconfig.json +1 -1
- package/template-web-app/app.ts +29 -0
- package/template-web-app/web/index.html +12 -0
- package/template-web-app/web/package.json +27 -0
- package/template-web-app/web/src/App.tsx +28 -0
- package/template-web-app/web/src/index.css +3 -0
- package/template-web-app/web/src/lua/client.ts +254 -0
- package/template-web-app/web/src/main.tsx +16 -0
- package/template-web-app/web/tsconfig.json +14 -0
- package/template-web-app/web/vite.config.ts +9 -0
|
@@ -59,10 +59,11 @@ export declare interface AgentStepOptions {
|
|
|
59
59
|
/**
|
|
60
60
|
* EM-WS3: pin a plugin step's Lua-API proxy (and its key) to ANOTHER agent instead of this workflow's own. Legal only
|
|
61
61
|
* beside `plugins`. Refused at run time (`target_not_granted`) unless the platform's plugin-target switch is on AND
|
|
62
|
-
* this workflow's agent holds a `supervision:act` or `supervision:release` grant on the target.
|
|
62
|
+
* this workflow's agent holds a `supervision:act` or `supervision:release` grant on the target. EM-WS3 × EM-WS2: the
|
|
63
|
+
* id may be `template('${initData.<path>}')`, rendered from the run input at dispatch (a per-run target).
|
|
63
64
|
*/
|
|
64
65
|
target?: {
|
|
65
|
-
agentId: string;
|
|
66
|
+
agentId: string | TemplateBinding;
|
|
66
67
|
};
|
|
67
68
|
/**
|
|
68
69
|
* What this step DOES: `classify` | `extract` | `transform` | `draft` | `research` | `reason` | `code` |
|
|
@@ -339,7 +340,7 @@ export declare type LuaWorkflowBuildCode = 'duplicate-step-id' | 'unknown-step-r
|
|
|
339
340
|
*/
|
|
340
341
|
| 'workspace-not-declared' | 'workspace-inherit-without-parent-workspace' | 'workspace-inherit-conflict' | 'harness-requires-job-tier' | 'max-turns-requires-job-tier' | 'max-turns-invalid'
|
|
341
342
|
/** EM-WS3: a step's `plugins` outside the allowlist, repeated, or off the Job tier. */
|
|
342
|
-
| 'plugins-invalid' | 'cap-exceeded' | 'chunk-size-invalid' | 'rate-limit-invalid' | 'backoff-invalid' | 'loop-interval-out-of-range' | 'mapping-placement' | 'container-arm-empty'
|
|
343
|
+
| 'plugins-invalid' | 'target-invalid' | 'lua-api-invalid' | 'cap-exceeded' | 'chunk-size-invalid' | 'rate-limit-invalid' | 'backoff-invalid' | 'loop-interval-out-of-range' | 'mapping-placement' | 'container-arm-empty'
|
|
343
344
|
/**
|
|
344
345
|
* @deprecated LUA-684 — the builder no longer throws it: an `approval` / `waitForSignal` IS a container arm
|
|
345
346
|
* (`parallel(['approve', …])`). Where the engine cannot run one — a `loop` body, the step of a `[map, step]`
|
|
@@ -488,6 +489,21 @@ export declare interface LuaWorkflowStep<TIn extends ZodType = ZodType, TOut ext
|
|
|
488
489
|
workspace?: WorkflowStepWorkspace;
|
|
489
490
|
jobResources?: WorkflowJobResources;
|
|
490
491
|
jobTools?: WorkflowJobToolId[];
|
|
492
|
+
/**
|
|
493
|
+
* EM-WS3 × EM-WS2: let this `tier:'job'` step run `lua` (`ctx.exec('lua', [...])`, `` ctx.$`lua push …` ``) against the
|
|
494
|
+
* Lua API through the platform's staging-only proxy, with a short-lived key for ONE agent: this workflow's agent, or
|
|
495
|
+
* `target`. It is the same proxy and the same deny rules as a plugin agent step: deploy, promote, publish,
|
|
496
|
+
* activate, env, chat and runtime calls are refused.
|
|
497
|
+
*/
|
|
498
|
+
luaApi?: true;
|
|
499
|
+
/**
|
|
500
|
+
* EM-WS3: pin the `luaApi` proxy (and its key) to ANOTHER agent. The id may be static or
|
|
501
|
+
* `template('${initData.<path>}')`, rendered from the run input at dispatch. The same flag and supervision-grant
|
|
502
|
+
* rules apply as on a plugin agent step.
|
|
503
|
+
*/
|
|
504
|
+
target?: {
|
|
505
|
+
agentId: string | TemplateBinding;
|
|
506
|
+
};
|
|
491
507
|
/** default { maxAttempts: 1 } */
|
|
492
508
|
retry?: RetryPolicy;
|
|
493
509
|
/** default 'none'; 'external' ⇒ park on platform-fault reclaim. */
|
package/dist/workflow-builder.js
CHANGED
|
@@ -68,17 +68,125 @@ function workflowJobPluginsProblem(plugins) {
|
|
|
68
68
|
}
|
|
69
69
|
__name(workflowJobPluginsProblem, "workflowJobPluginsProblem");
|
|
70
70
|
__name2(workflowJobPluginsProblem, "workflowJobPluginsProblem");
|
|
71
|
-
|
|
71
|
+
var WORKFLOW_JOB_TARGET_TEMPLATE_RE = /^\$\{\s*initData\.([A-Za-z0-9_.\-[\]]+)\s*\}$/;
|
|
72
|
+
var TARGET_PATH_SEGMENT_RE = /^[A-Za-z0-9_-]+(?:\[(?:0|[1-9]\d*)\])*$/;
|
|
73
|
+
function workflowJobTargetTemplatePath(binding) {
|
|
74
|
+
if (!binding || typeof binding !== "object" || Array.isArray(binding)) return null;
|
|
75
|
+
const keys = Object.keys(binding);
|
|
76
|
+
const tpl = binding.template;
|
|
77
|
+
if (keys.length !== 1 || typeof tpl !== "string" || tpl.length > 512) return null;
|
|
78
|
+
const m = WORKFLOW_JOB_TARGET_TEMPLATE_RE.exec(tpl.trim());
|
|
79
|
+
if (!m) return null;
|
|
80
|
+
const names = m[1].split(".").map((seg) => seg.replace(/\[(?:0|[1-9]\d*)\]/g, ""));
|
|
81
|
+
if (names.some((n2) => n2 === "__proto__" || n2 === "prototype" || n2 === "constructor")) return null;
|
|
82
|
+
return m[1].split(".").every((seg) => TARGET_PATH_SEGMENT_RE.test(seg)) ? m[1] : null;
|
|
83
|
+
}
|
|
84
|
+
__name(workflowJobTargetTemplatePath, "workflowJobTargetTemplatePath");
|
|
85
|
+
__name2(workflowJobTargetTemplatePath, "workflowJobTargetTemplatePath");
|
|
86
|
+
function isWorkflowJobTargetTemplate(target) {
|
|
87
|
+
const agentId = target?.agentId;
|
|
88
|
+
return !!agentId && typeof agentId === "object";
|
|
89
|
+
}
|
|
90
|
+
__name(isWorkflowJobTargetTemplate, "isWorkflowJobTargetTemplate");
|
|
91
|
+
__name2(isWorkflowJobTargetTemplate, "isWorkflowJobTargetTemplate");
|
|
92
|
+
function workflowJobLuaApiProblem(luaApi, nodeType, tier) {
|
|
93
|
+
if (luaApi === void 0) return null;
|
|
94
|
+
if (luaApi !== true) return "`luaApi` must be exactly true";
|
|
95
|
+
if (nodeType !== "code") return "`luaApi` is legal on code steps only (an agent step uses `plugins`)";
|
|
96
|
+
if (tier !== "job") return "`luaApi` requires tier:'job'";
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
__name(workflowJobLuaApiProblem, "workflowJobLuaApiProblem");
|
|
100
|
+
__name2(workflowJobLuaApiProblem, "workflowJobLuaApiProblem");
|
|
101
|
+
function workflowJobUsesLuaApi(step3) {
|
|
102
|
+
return Array.isArray(step3.plugins) && step3.plugins.length > 0 || step3.kind === "code" && step3.luaApi === true;
|
|
103
|
+
}
|
|
104
|
+
__name(workflowJobUsesLuaApi, "workflowJobUsesLuaApi");
|
|
105
|
+
__name2(workflowJobUsesLuaApi, "workflowJobUsesLuaApi");
|
|
106
|
+
function workflowJobTargetProblem(target, plugins, luaApi) {
|
|
72
107
|
if (target === void 0) return null;
|
|
73
108
|
if (!target || typeof target !== "object" || Array.isArray(target)) return "target must be { agentId }";
|
|
74
109
|
const keys = Object.keys(target);
|
|
75
110
|
const agentId = target.agentId;
|
|
76
|
-
if (keys.length !== 1 ||
|
|
77
|
-
if (
|
|
111
|
+
if (keys.length !== 1 || !("agentId" in target)) return "target must be exactly { agentId }";
|
|
112
|
+
if (typeof agentId === "string") {
|
|
113
|
+
if (!agentId.trim() || agentId.length > 256) return "target must be exactly { agentId: <non-empty string> }";
|
|
114
|
+
if (agentId.includes("${")) return "a run-input target is written template('${initData.<path>}'), never a string with ${\u2026}";
|
|
115
|
+
} else if (workflowJobTargetTemplatePath(agentId) === null) {
|
|
116
|
+
return "target.agentId must be a static id or template('${initData.<path>}') \u2014 exactly one initData placeholder, no default";
|
|
117
|
+
}
|
|
118
|
+
const hasPlugins = Array.isArray(plugins) && plugins.length > 0;
|
|
119
|
+
if (!hasPlugins && luaApi !== true) return "`target` is legal only beside `plugins` or `luaApi: true`";
|
|
78
120
|
return null;
|
|
79
121
|
}
|
|
80
122
|
__name(workflowJobTargetProblem, "workflowJobTargetProblem");
|
|
81
123
|
__name2(workflowJobTargetProblem, "workflowJobTargetProblem");
|
|
124
|
+
function readInitDataPath(root, path) {
|
|
125
|
+
let cur = root;
|
|
126
|
+
for (const seg of path.split(".")) {
|
|
127
|
+
const name = seg.replace(/\[(?:0|[1-9]\d*)\]/g, "");
|
|
128
|
+
const indexes = [
|
|
129
|
+
...seg.matchAll(/\[(0|[1-9]\d*)\]/g)
|
|
130
|
+
].map((x) => Number(x[1]));
|
|
131
|
+
if (cur === null || typeof cur !== "object" || !Object.prototype.hasOwnProperty.call(cur, name)) return void 0;
|
|
132
|
+
cur = cur[name];
|
|
133
|
+
for (const i of indexes) {
|
|
134
|
+
if (!Array.isArray(cur) || i >= cur.length) return void 0;
|
|
135
|
+
cur = cur[i];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return cur;
|
|
139
|
+
}
|
|
140
|
+
__name(readInitDataPath, "readInitDataPath");
|
|
141
|
+
__name2(readInitDataPath, "readInitDataPath");
|
|
142
|
+
function renderWorkflowJobTarget(target, initData) {
|
|
143
|
+
const agentId = target?.agentId;
|
|
144
|
+
if (target === void 0 || target === null || agentId === void 0) return {
|
|
145
|
+
ok: true,
|
|
146
|
+
agentId: void 0,
|
|
147
|
+
templated: false
|
|
148
|
+
};
|
|
149
|
+
if (typeof agentId === "string") {
|
|
150
|
+
if (!agentId.trim() || agentId.includes("${")) return {
|
|
151
|
+
ok: false,
|
|
152
|
+
reason: "invalid",
|
|
153
|
+
message: "target.agentId is invalid"
|
|
154
|
+
};
|
|
155
|
+
return {
|
|
156
|
+
ok: true,
|
|
157
|
+
agentId,
|
|
158
|
+
templated: false
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const path = workflowJobTargetTemplatePath(agentId);
|
|
162
|
+
if (path === null) return {
|
|
163
|
+
ok: false,
|
|
164
|
+
reason: "invalid",
|
|
165
|
+
message: "target.agentId is not a valid initData template"
|
|
166
|
+
};
|
|
167
|
+
const value3 = readInitDataPath(initData, path);
|
|
168
|
+
if (value3 === void 0 || value3 === null) {
|
|
169
|
+
return {
|
|
170
|
+
ok: false,
|
|
171
|
+
reason: "unbound",
|
|
172
|
+
message: `target_unresolved: the run input has no initData.${path}`
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (typeof value3 !== "string" || !value3.trim() || value3.length > 256 || /\s/.test(value3.trim())) {
|
|
176
|
+
return {
|
|
177
|
+
ok: false,
|
|
178
|
+
reason: "empty",
|
|
179
|
+
message: `target_unresolved: initData.${path} is not a non-empty agent id`
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
ok: true,
|
|
184
|
+
agentId: value3.trim(),
|
|
185
|
+
templated: true
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
__name(renderWorkflowJobTarget, "renderWorkflowJobTarget");
|
|
189
|
+
__name2(renderWorkflowJobTarget, "renderWorkflowJobTarget");
|
|
82
190
|
|
|
83
191
|
// src/types/workflow.ts
|
|
84
192
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
@@ -244,7 +352,8 @@ var REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST = [
|
|
|
244
352
|
"sendWebchatMessage",
|
|
245
353
|
"sendTeamsMessage",
|
|
246
354
|
"sendInstagramMessage",
|
|
247
|
-
"sendMessengerMessage"
|
|
355
|
+
"sendMessengerMessage",
|
|
356
|
+
"sendSlackMessage"
|
|
248
357
|
];
|
|
249
358
|
function isAllowedReviewableExecuteTool(tool) {
|
|
250
359
|
return REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST.includes(tool);
|
|
@@ -4529,6 +4638,24 @@ var onboardingTemplateSectionSchema = z4.object({
|
|
|
4529
4638
|
label: copy(100),
|
|
4530
4639
|
body: onboardingRichTextSchema
|
|
4531
4640
|
}).strict();
|
|
4641
|
+
var onboardingInstallScreenSchema = z4.object({
|
|
4642
|
+
title: onboardingHeadingSchema,
|
|
4643
|
+
subtitle: copy(240),
|
|
4644
|
+
ctaLabel: copy(80),
|
|
4645
|
+
ctaHelperText: onboardingRichTextSchema
|
|
4646
|
+
}).strict();
|
|
4647
|
+
var onboardingResultScreenSchema = z4.object({
|
|
4648
|
+
title: onboardingHeadingSchema,
|
|
4649
|
+
subheader: copy(240),
|
|
4650
|
+
inputPlaceholder: copy(120)
|
|
4651
|
+
}).strict();
|
|
4652
|
+
var onboardingConnectScreenSchema = z4.object({
|
|
4653
|
+
title: onboardingHeadingSchema,
|
|
4654
|
+
description: onboardingRichTextSchema,
|
|
4655
|
+
ctaLabel: copy(80),
|
|
4656
|
+
neverLine: copy(120),
|
|
4657
|
+
footnote: copy(240)
|
|
4658
|
+
}).strict();
|
|
4532
4659
|
var onboardingTemplateContentSchema = z4.object({
|
|
4533
4660
|
id,
|
|
4534
4661
|
templateId: copy(160),
|
|
@@ -4541,7 +4668,10 @@ var onboardingTemplateContentSchema = z4.object({
|
|
|
4541
4668
|
artwork: onboardingArtworkSchema,
|
|
4542
4669
|
hireButtonLabel: copy(80),
|
|
4543
4670
|
changeRoleButtonLabel: copy(80),
|
|
4544
|
-
nextStepText: onboardingRichTextSchema
|
|
4671
|
+
nextStepText: onboardingRichTextSchema,
|
|
4672
|
+
install: onboardingInstallScreenSchema.optional(),
|
|
4673
|
+
result: onboardingResultScreenSchema.optional(),
|
|
4674
|
+
connect: onboardingConnectScreenSchema.optional()
|
|
4545
4675
|
}).strict();
|
|
4546
4676
|
var onboardingUnavailableOutcomeSchema = z4.object({
|
|
4547
4677
|
id,
|
|
@@ -4762,6 +4892,8 @@ function isWebRouteInput(value3) {
|
|
|
4762
4892
|
}
|
|
4763
4893
|
__name(isWebRouteInput, "isWebRouteInput");
|
|
4764
4894
|
__name3(isWebRouteInput, "isWebRouteInput");
|
|
4895
|
+
var WEB_APP_ENTRY_HTML_MAX_CHARS = 256 * 1024;
|
|
4896
|
+
var WEB_APP_MAX_ASSET_BYTES = 8 * 1024 * 1024;
|
|
4765
4897
|
var EVIDENCE_SESSION_IDLE_MS = 30 * 6e4;
|
|
4766
4898
|
var EVIDENCE_MIN_CONVERSATIONS = 20;
|
|
4767
4899
|
var EVIDENCE_LOW_CONFIDENCE_N = 5;
|
|
@@ -5161,6 +5293,17 @@ function sortVerdictReasons(reasons) {
|
|
|
5161
5293
|
}
|
|
5162
5294
|
__name(sortVerdictReasons, "sortVerdictReasons");
|
|
5163
5295
|
__name3(sortVerdictReasons, "sortVerdictReasons");
|
|
5296
|
+
var ENV_TEMPLATE_SECRET_KEY_RE = /(SECRET|TOKEN|KEY|PASSWORD)$/;
|
|
5297
|
+
function envTemplatePlaceholder(key) {
|
|
5298
|
+
if (ENV_TEMPLATE_SECRET_KEY_RE.test(key)) {
|
|
5299
|
+
throw new Error(`env-template-secret-key: \`${key}\` looks like a secret \u2014 read it with env('${key}') inside execute instead`);
|
|
5300
|
+
}
|
|
5301
|
+
return {
|
|
5302
|
+
__envRef: key
|
|
5303
|
+
};
|
|
5304
|
+
}
|
|
5305
|
+
__name(envTemplatePlaceholder, "envTemplatePlaceholder");
|
|
5306
|
+
__name3(envTemplatePlaceholder, "envTemplatePlaceholder");
|
|
5164
5307
|
|
|
5165
5308
|
// ../workflow-graph/dist/index.mjs
|
|
5166
5309
|
import { createHash } from "crypto";
|
|
@@ -5829,6 +5972,17 @@ function liftRenderedApprover(row, rendered) {
|
|
|
5829
5972
|
}
|
|
5830
5973
|
__name(liftRenderedApprover, "liftRenderedApprover");
|
|
5831
5974
|
__name4(liftRenderedApprover, "liftRenderedApprover");
|
|
5975
|
+
function approverUsersOf(users) {
|
|
5976
|
+
if (Array.isArray(users)) {
|
|
5977
|
+
if (users.length === 0 || users.length > APPROVER_SPEC_MAX_USERS) return null;
|
|
5978
|
+
return users.every((m) => typeof m === "string" && m.length > 0 && m.length <= 128) ? users : null;
|
|
5979
|
+
}
|
|
5980
|
+
if (typeof users !== "string") return null;
|
|
5981
|
+
const lifted = liftRenderedApprover("users", users);
|
|
5982
|
+
return lifted && "users" in lifted ? lifted.users : null;
|
|
5983
|
+
}
|
|
5984
|
+
__name(approverUsersOf, "approverUsersOf");
|
|
5985
|
+
__name4(approverUsersOf, "approverUsersOf");
|
|
5832
5986
|
var WORKSPACE_TEMPLATE_EXPR_RE = /^\$\{\s*(?:initData|input)\.([^}]+?)\s*\}$/;
|
|
5833
5987
|
function workspaceTemplatePath(template22) {
|
|
5834
5988
|
const key = template22.trim();
|
|
@@ -6395,8 +6549,13 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
6395
6549
|
}
|
|
6396
6550
|
const plugins = node.plugins;
|
|
6397
6551
|
const target = node.target;
|
|
6552
|
+
const luaApi = node.luaApi;
|
|
6553
|
+
if (luaApi !== void 0) {
|
|
6554
|
+
const problem = workflowJobLuaApiProblem(luaApi, node.type === "step" ? "code" : node.type, isJobTier(node) ? "job" : node.tier);
|
|
6555
|
+
if (problem) err("lua-api-invalid", problem, `${path}.luaApi`, id2);
|
|
6556
|
+
}
|
|
6398
6557
|
if (target !== void 0) {
|
|
6399
|
-
const problem = workflowJobTargetProblem(target, plugins);
|
|
6558
|
+
const problem = workflowJobTargetProblem(target, plugins, luaApi);
|
|
6400
6559
|
if (problem) err("target-invalid", problem, `${path}.target`, id2);
|
|
6401
6560
|
}
|
|
6402
6561
|
if (plugins !== void 0) {
|
|
@@ -9729,7 +9888,9 @@ function stepNodeOf(s) {
|
|
|
9729
9888
|
tier,
|
|
9730
9889
|
workspace: s.workspace,
|
|
9731
9890
|
jobResources: s.jobResources,
|
|
9732
|
-
jobTools: s.jobTools
|
|
9891
|
+
jobTools: s.jobTools,
|
|
9892
|
+
luaApi: s.luaApi,
|
|
9893
|
+
target: s.target
|
|
9733
9894
|
});
|
|
9734
9895
|
}
|
|
9735
9896
|
__name(stepNodeOf, "stepNodeOf");
|
|
@@ -9814,6 +9975,14 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
|
|
|
9814
9975
|
const tier = s.tier ?? (s.workspace ? "job" : void 0);
|
|
9815
9976
|
if (s.workspace && s.tier !== void 0 && s.tier !== "job") throw new LuaWorkflowBuildError("workspace-requires-job-tier", `"${s.id}": a step mounting a workspace must be tier:'job'`);
|
|
9816
9977
|
if (s.jobTools && tier !== "job") throw new LuaWorkflowBuildError("cap-exceeded", `"${s.id}": jobTools require tier:'job' (job-tools-require-job-tier)`);
|
|
9978
|
+
if (s.luaApi !== void 0) {
|
|
9979
|
+
const problem = workflowJobLuaApiProblem(s.luaApi, "code", tier);
|
|
9980
|
+
if (problem) throw new LuaWorkflowBuildError("lua-api-invalid", `"${s.id}": ${problem}`);
|
|
9981
|
+
}
|
|
9982
|
+
if (s.target !== void 0) {
|
|
9983
|
+
const problem = workflowJobTargetProblem(s.target, void 0, s.luaApi);
|
|
9984
|
+
if (problem) throw new LuaWorkflowBuildError("target-invalid", `"${s.id}": ${problem}`);
|
|
9985
|
+
}
|
|
9817
9986
|
assertTimeout({
|
|
9818
9987
|
id: s.id,
|
|
9819
9988
|
timeoutSeconds: s.timeoutSeconds,
|
|
@@ -10070,7 +10239,7 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
|
|
|
10070
10239
|
}
|
|
10071
10240
|
if (opts.target !== void 0) {
|
|
10072
10241
|
const problem = workflowJobTargetProblem(opts.target, opts.plugins);
|
|
10073
|
-
if (problem) throw new LuaWorkflowBuildError("
|
|
10242
|
+
if (problem) throw new LuaWorkflowBuildError("target-invalid", `"${id2}": ${problem}`);
|
|
10074
10243
|
}
|
|
10075
10244
|
assertTimeout({
|
|
10076
10245
|
id: id2,
|