lua-cli 3.32.3 → 3.32.5
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 +16 -4
- package/dist/api-exports.js +813 -317
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +2258 -1350
- package/dist/index.js.map +1 -1
- package/dist/workflow-builder.d.ts +5 -3
- package/dist/workflow-builder.js +558 -258
- package/dist/workflow-builder.js.map +1 -1
- package/docs/CLI_REFERENCE.md +6 -2
- package/docs/README.md +2 -2
- package/docs/api/LuaWorkflow.md +1 -1
- package/docs/workflows/approvals.md +2 -0
- package/docs/workflows/limits.md +4 -0
- package/docs/workflows/recovery.md +1 -1
- package/docs/workflows/schedules.md +13 -4
- package/docs/workflows/testing-offline.md +1 -1
- package/package.json +4 -4
- package/template/examples/workflows/research-brief.ts +29 -16
- package/template/package.json +1 -1
package/dist/workflow-builder.js
CHANGED
|
@@ -647,6 +647,94 @@ function isDesktopFileSessionId(value3) {
|
|
|
647
647
|
}
|
|
648
648
|
__name(isDesktopFileSessionId, "isDesktopFileSessionId");
|
|
649
649
|
__name2(isDesktopFileSessionId, "isDesktopFileSessionId");
|
|
650
|
+
var MODEL_ID_BYOK_PROVIDERS = [
|
|
651
|
+
"azure",
|
|
652
|
+
"bedrock"
|
|
653
|
+
];
|
|
654
|
+
function isModelIdSentinel(input) {
|
|
655
|
+
const lower = (input ?? "").trim().toLowerCase();
|
|
656
|
+
return lower === "auto" || lower.startsWith("auto/");
|
|
657
|
+
}
|
|
658
|
+
__name(isModelIdSentinel, "isModelIdSentinel");
|
|
659
|
+
__name2(isModelIdSentinel, "isModelIdSentinel");
|
|
660
|
+
function normalizeModelId(input, registry) {
|
|
661
|
+
const requested = typeof input === "string" ? input.trim() : "";
|
|
662
|
+
if (!requested) return {
|
|
663
|
+
ok: false,
|
|
664
|
+
reason: "empty",
|
|
665
|
+
requested,
|
|
666
|
+
candidates: []
|
|
667
|
+
};
|
|
668
|
+
const lower = requested.toLowerCase();
|
|
669
|
+
if (isModelIdSentinel(lower)) return {
|
|
670
|
+
ok: true,
|
|
671
|
+
id: lower,
|
|
672
|
+
form: "sentinel"
|
|
673
|
+
};
|
|
674
|
+
const slash = requested.indexOf("/");
|
|
675
|
+
const malformed = slash === 0;
|
|
676
|
+
const provider = slash > 0 ? lower.slice(0, slash) : void 0;
|
|
677
|
+
if (provider && MODEL_ID_BYOK_PROVIDERS.includes(provider)) {
|
|
678
|
+
return {
|
|
679
|
+
ok: true,
|
|
680
|
+
id: requested,
|
|
681
|
+
form: "byok"
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
const bareId = slash >= 0 ? lower.slice(slash + 1) : lower;
|
|
685
|
+
const lastSegment = bareId.slice(bareId.lastIndexOf("/") + 1);
|
|
686
|
+
const exact = /* @__PURE__ */ new Set();
|
|
687
|
+
const hints = /* @__PURE__ */ new Set();
|
|
688
|
+
for (const code of registry) {
|
|
689
|
+
if (typeof code !== "string" || !code) continue;
|
|
690
|
+
const codeLower = code.toLowerCase();
|
|
691
|
+
if (!malformed && codeLower === lower) return {
|
|
692
|
+
ok: true,
|
|
693
|
+
id: code,
|
|
694
|
+
form: provider ? "canonical" : "bare"
|
|
695
|
+
};
|
|
696
|
+
const i = codeLower.indexOf("/");
|
|
697
|
+
if (i < 0) continue;
|
|
698
|
+
const codeBare = codeLower.slice(i + 1);
|
|
699
|
+
if (bareId && codeBare === bareId) exact.add(code);
|
|
700
|
+
else if (lastSegment && codeBare.slice(codeBare.lastIndexOf("/") + 1) === lastSegment) hints.add(code);
|
|
701
|
+
}
|
|
702
|
+
const sorted = [
|
|
703
|
+
...exact
|
|
704
|
+
].sort();
|
|
705
|
+
if (!provider && !malformed && sorted.length === 1) return {
|
|
706
|
+
ok: true,
|
|
707
|
+
id: sorted[0],
|
|
708
|
+
form: "bare"
|
|
709
|
+
};
|
|
710
|
+
if (!provider && !malformed && sorted.length > 1) {
|
|
711
|
+
return {
|
|
712
|
+
ok: false,
|
|
713
|
+
reason: "ambiguous",
|
|
714
|
+
requested,
|
|
715
|
+
candidates: sorted
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
return {
|
|
719
|
+
ok: false,
|
|
720
|
+
reason: "unknown",
|
|
721
|
+
requested,
|
|
722
|
+
candidates: sorted.length ? sorted : [
|
|
723
|
+
...hints
|
|
724
|
+
].sort()
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
__name(normalizeModelId, "normalizeModelId");
|
|
728
|
+
__name2(normalizeModelId, "normalizeModelId");
|
|
729
|
+
function modelUnresolvedMessage(r) {
|
|
730
|
+
if (r.reason === "empty") return "model pin is empty \u2014 pin an approved model (provider/model) or omit `model`";
|
|
731
|
+
if (r.reason === "ambiguous") {
|
|
732
|
+
return `model "${r.requested}" does not resolve to one approved model \u2014 it names ${r.candidates.length}; pin one of: ${r.candidates.join(", ")}`;
|
|
733
|
+
}
|
|
734
|
+
return r.candidates.length ? `model "${r.requested}" does not resolve to an approved model \u2014 accepted forms: ${r.candidates.join(", ")}` : `model "${r.requested}" does not resolve to an approved model \u2014 accepted forms are the registry's provider-prefixed ids (provider/model) or a bare id that names exactly one of them`;
|
|
735
|
+
}
|
|
736
|
+
__name(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
737
|
+
__name2(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
650
738
|
var IMPLICIT_MODEL_SELECTION_SOURCES = [
|
|
651
739
|
"workspace-default",
|
|
652
740
|
"platform-default"
|
|
@@ -1160,6 +1248,7 @@ var DeviceBindingSchema = z2.object({
|
|
|
1160
1248
|
}
|
|
1161
1249
|
});
|
|
1162
1250
|
var IdSchema = z2.string().min(1).max(256);
|
|
1251
|
+
var SESSION_AUTH_TIME_MAX_S = 4102444800;
|
|
1163
1252
|
var PrincipalDescriptorSchema = z2.object({
|
|
1164
1253
|
subjectType: SubjectTypeSchema,
|
|
1165
1254
|
subjectId: IdSchema
|
|
@@ -1208,7 +1297,8 @@ var GeneralPrincipalContextSchema = z2.object({
|
|
|
1208
1297
|
owner: PrincipalOwnerSchema.optional(),
|
|
1209
1298
|
compatibility: z2.object({
|
|
1210
1299
|
mode: z2.literal("legacy-owner-delegation")
|
|
1211
|
-
}).strict().optional()
|
|
1300
|
+
}).strict().optional(),
|
|
1301
|
+
authTime: z2.number().int().nonnegative().max(SESSION_AUTH_TIME_MAX_S).optional()
|
|
1212
1302
|
}).strict();
|
|
1213
1303
|
var DeviceCredentialPrincipalContextSchema = z2.object({
|
|
1214
1304
|
version: z2.literal(1),
|
|
@@ -1274,6 +1364,13 @@ function hasDeviceCredentialType(value3) {
|
|
|
1274
1364
|
}
|
|
1275
1365
|
__name(hasDeviceCredentialType, "hasDeviceCredentialType");
|
|
1276
1366
|
__name2(hasDeviceCredentialType, "hasDeviceCredentialType");
|
|
1367
|
+
function sessionAuthTime(context) {
|
|
1368
|
+
if (!context || context.credential.type !== "firstPartySession") return void 0;
|
|
1369
|
+
const authTime = context.authTime;
|
|
1370
|
+
return typeof authTime === "number" && Number.isInteger(authTime) && authTime >= 0 && authTime <= SESSION_AUTH_TIME_MAX_S ? authTime : void 0;
|
|
1371
|
+
}
|
|
1372
|
+
__name(sessionAuthTime, "sessionAuthTime");
|
|
1373
|
+
__name2(sessionAuthTime, "sessionAuthTime");
|
|
1277
1374
|
function isTypedApiKeyPrincipal(context) {
|
|
1278
1375
|
return context?.subject.subjectType === "apiKey" && context.credential.type === "apiKey" && !context.compatibility;
|
|
1279
1376
|
}
|
|
@@ -1676,6 +1773,47 @@ function scheduledWorkflowRunId(jobId, scheduledTime) {
|
|
|
1676
1773
|
}
|
|
1677
1774
|
__name(scheduledWorkflowRunId, "scheduledWorkflowRunId");
|
|
1678
1775
|
__name2(scheduledWorkflowRunId, "scheduledWorkflowRunId");
|
|
1776
|
+
var WORKFLOW_SCHEDULE_KEY_MAX = 128;
|
|
1777
|
+
function renderWorkflowScheduleKeyTemplate(template3, ctx) {
|
|
1778
|
+
if (!template3) return void 0;
|
|
1779
|
+
const read = /* @__PURE__ */ __name2((path) => path.split(".").reduce((o, k) => o && typeof o === "object" ? o[k] : void 0, ctx.input), "read");
|
|
1780
|
+
let unresolved = false;
|
|
1781
|
+
const out = template3.replace(/\$\{\s*([a-zA-Z0-9_.]+)\s*\}/g, (_m, expr) => {
|
|
1782
|
+
let v = "";
|
|
1783
|
+
if (expr === "scheduledTime") v = ctx.scheduledTime ?? "";
|
|
1784
|
+
else if (expr.startsWith("input.")) v = read(expr.slice("input.".length));
|
|
1785
|
+
const s = v === void 0 || v === null ? "" : String(v);
|
|
1786
|
+
if (s === "") unresolved = true;
|
|
1787
|
+
return s;
|
|
1788
|
+
});
|
|
1789
|
+
if (unresolved) return void 0;
|
|
1790
|
+
const key = out.slice(0, WORKFLOW_SCHEDULE_KEY_MAX);
|
|
1791
|
+
return key && /^[A-Za-z0-9:_\-.\/]+$/.test(key) ? key : void 0;
|
|
1792
|
+
}
|
|
1793
|
+
__name(renderWorkflowScheduleKeyTemplate, "renderWorkflowScheduleKeyTemplate");
|
|
1794
|
+
__name2(renderWorkflowScheduleKeyTemplate, "renderWorkflowScheduleKeyTemplate");
|
|
1795
|
+
var WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX = "sched:";
|
|
1796
|
+
function scheduledWorkflowIdempotencyKey(jobId, rendered) {
|
|
1797
|
+
const head = `${WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX}${jobId}:`;
|
|
1798
|
+
if (head.length + rendered.length <= WORKFLOW_SCHEDULE_KEY_MAX) return `${head}${rendered}`;
|
|
1799
|
+
const digest = stableKeyDigest(rendered);
|
|
1800
|
+
const room = WORKFLOW_SCHEDULE_KEY_MAX - head.length - digest.length - 1;
|
|
1801
|
+
return `${head}${rendered.slice(0, Math.max(0, room))}~${digest}`;
|
|
1802
|
+
}
|
|
1803
|
+
__name(scheduledWorkflowIdempotencyKey, "scheduledWorkflowIdempotencyKey");
|
|
1804
|
+
__name2(scheduledWorkflowIdempotencyKey, "scheduledWorkflowIdempotencyKey");
|
|
1805
|
+
function stableKeyDigest(s) {
|
|
1806
|
+
let a = 2166136261;
|
|
1807
|
+
let b = 84696351;
|
|
1808
|
+
for (let i = 0; i < s.length; i++) {
|
|
1809
|
+
const c = s.charCodeAt(i);
|
|
1810
|
+
a = Math.imul(a ^ c, 16777619);
|
|
1811
|
+
b = Math.imul(b ^ c, 16777619) ^ b >>> 13;
|
|
1812
|
+
}
|
|
1813
|
+
return (a >>> 0).toString(16).padStart(8, "0") + (b >>> 0).toString(16).padStart(8, "0");
|
|
1814
|
+
}
|
|
1815
|
+
__name(stableKeyDigest, "stableKeyDigest");
|
|
1816
|
+
__name2(stableKeyDigest, "stableKeyDigest");
|
|
1679
1817
|
var WORKFLOW_OPERATION_ID_PREFIX = "wf:";
|
|
1680
1818
|
function workflowOperationId(runId, stepId, billingEpoch) {
|
|
1681
1819
|
return `${WORKFLOW_OPERATION_ID_PREFIX}${runId}:${stepId}:${billingEpoch}`;
|
|
@@ -2424,6 +2562,75 @@ function extractSingleJsonValue(text) {
|
|
|
2424
2562
|
}
|
|
2425
2563
|
__name(extractSingleJsonValue, "extractSingleJsonValue");
|
|
2426
2564
|
__name2(extractSingleJsonValue, "extractSingleJsonValue");
|
|
2565
|
+
var DEFAULT_ON_AGENT_FEATURES = [
|
|
2566
|
+
"workflows",
|
|
2567
|
+
"workflowCompose",
|
|
2568
|
+
"observationalMemory"
|
|
2569
|
+
];
|
|
2570
|
+
function agentFeatureCatalogDefault(featureName) {
|
|
2571
|
+
return DEFAULT_ON_AGENT_FEATURES.includes(featureName);
|
|
2572
|
+
}
|
|
2573
|
+
__name(agentFeatureCatalogDefault, "agentFeatureCatalogDefault");
|
|
2574
|
+
__name2(agentFeatureCatalogDefault, "agentFeatureCatalogDefault");
|
|
2575
|
+
function hasExplicitFeatureActive(row) {
|
|
2576
|
+
return typeof row?.active === "boolean";
|
|
2577
|
+
}
|
|
2578
|
+
__name(hasExplicitFeatureActive, "hasExplicitFeatureActive");
|
|
2579
|
+
__name2(hasExplicitFeatureActive, "hasExplicitFeatureActive");
|
|
2580
|
+
function effectiveFeatureActive(row, catalogDefault) {
|
|
2581
|
+
return hasExplicitFeatureActive(row) ? row.active : catalogDefault;
|
|
2582
|
+
}
|
|
2583
|
+
__name(effectiveFeatureActive, "effectiveFeatureActive");
|
|
2584
|
+
__name2(effectiveFeatureActive, "effectiveFeatureActive");
|
|
2585
|
+
function resolveEffectiveFeature(row, catalogDefault) {
|
|
2586
|
+
return hasExplicitFeatureActive(row) ? {
|
|
2587
|
+
active: row.active,
|
|
2588
|
+
source: "agent",
|
|
2589
|
+
default: catalogDefault
|
|
2590
|
+
} : {
|
|
2591
|
+
active: catalogDefault,
|
|
2592
|
+
source: "default",
|
|
2593
|
+
default: catalogDefault
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
__name(resolveEffectiveFeature, "resolveEffectiveFeature");
|
|
2597
|
+
__name2(resolveEffectiveFeature, "resolveEffectiveFeature");
|
|
2598
|
+
function isFeatureRow(value3) {
|
|
2599
|
+
return typeof value3 === "object" && value3 !== null;
|
|
2600
|
+
}
|
|
2601
|
+
__name(isFeatureRow, "isFeatureRow");
|
|
2602
|
+
__name2(isFeatureRow, "isFeatureRow");
|
|
2603
|
+
function effectiveAgentFeatureRows(base, override) {
|
|
2604
|
+
const merged = /* @__PURE__ */ new Map();
|
|
2605
|
+
for (const [name, row] of Object.entries(base ?? {})) {
|
|
2606
|
+
if (isFeatureRow(row)) merged.set(name, {
|
|
2607
|
+
row,
|
|
2608
|
+
origin: "baseAgent"
|
|
2609
|
+
});
|
|
2610
|
+
}
|
|
2611
|
+
for (const [name, row] of Object.entries(override ?? {})) {
|
|
2612
|
+
if (isFeatureRow(row)) merged.set(name, {
|
|
2613
|
+
row,
|
|
2614
|
+
origin: "subAgent"
|
|
2615
|
+
});
|
|
2616
|
+
}
|
|
2617
|
+
return {
|
|
2618
|
+
rows: Object.fromEntries([
|
|
2619
|
+
...merged
|
|
2620
|
+
].map(([name, e]) => [
|
|
2621
|
+
name,
|
|
2622
|
+
e.row
|
|
2623
|
+
])),
|
|
2624
|
+
origins: Object.fromEntries([
|
|
2625
|
+
...merged
|
|
2626
|
+
].map(([name, e]) => [
|
|
2627
|
+
name,
|
|
2628
|
+
e.origin
|
|
2629
|
+
]))
|
|
2630
|
+
};
|
|
2631
|
+
}
|
|
2632
|
+
__name(effectiveAgentFeatureRows, "effectiveAgentFeatureRows");
|
|
2633
|
+
__name2(effectiveAgentFeatureRows, "effectiveAgentFeatureRows");
|
|
2427
2634
|
|
|
2428
2635
|
// ../workflow-graph/dist/index.mjs
|
|
2429
2636
|
import { createHash } from "crypto";
|
|
@@ -2724,7 +2931,211 @@ var fromKnowledge = /* @__PURE__ */ __name3((k) => ({
|
|
|
2724
2931
|
}), "fromKnowledge");
|
|
2725
2932
|
var SideEffectsSchema = z4.enum(WORKFLOW_SIDE_EFFECTS);
|
|
2726
2933
|
var JobResourcesSchema = z4.enum(WORKFLOW_JOB_RESOURCES);
|
|
2727
|
-
var
|
|
2934
|
+
var APPROVER_SPEC_MAX_USERS = 20;
|
|
2935
|
+
var ESCALATION_MAX_HOPS = 3;
|
|
2936
|
+
var TemplateBindingSchema = z22.object({
|
|
2937
|
+
template: z22.string().min(1).max(2048)
|
|
2938
|
+
}).strict();
|
|
2939
|
+
var ApproverSpecSchema = z22.union([
|
|
2940
|
+
z22.literal("creator"),
|
|
2941
|
+
z22.literal("org-admins"),
|
|
2942
|
+
z22.object({
|
|
2943
|
+
users: z22.union([
|
|
2944
|
+
z22.array(z22.string().min(1).max(128)).min(1).max(APPROVER_SPEC_MAX_USERS),
|
|
2945
|
+
TemplateBindingSchema
|
|
2946
|
+
])
|
|
2947
|
+
}).strict(),
|
|
2948
|
+
z22.object({
|
|
2949
|
+
role: z22.union([
|
|
2950
|
+
z22.string().min(1).max(128),
|
|
2951
|
+
TemplateBindingSchema
|
|
2952
|
+
])
|
|
2953
|
+
}).strict(),
|
|
2954
|
+
z22.object({
|
|
2955
|
+
group: z22.union([
|
|
2956
|
+
z22.string().min(1).max(128),
|
|
2957
|
+
TemplateBindingSchema
|
|
2958
|
+
])
|
|
2959
|
+
}).strict(),
|
|
2960
|
+
z22.object({
|
|
2961
|
+
governance: z22.object({
|
|
2962
|
+
policyId: z22.string().min(1).max(128)
|
|
2963
|
+
}).strict()
|
|
2964
|
+
}).strict()
|
|
2965
|
+
]);
|
|
2966
|
+
var FourEyesSchema = z22.object({
|
|
2967
|
+
edit: ApproverSpecSchema,
|
|
2968
|
+
approve: ApproverSpecSchema
|
|
2969
|
+
}).strict();
|
|
2970
|
+
var EscalationHopSchema = z22.object({
|
|
2971
|
+
escalateTo: ApproverSpecSchema,
|
|
2972
|
+
timeoutHours: z22.number().finite().min(1).max(720)
|
|
2973
|
+
}).strict();
|
|
2974
|
+
var TerminalOutcomeSchema = z22.enum([
|
|
2975
|
+
"deny",
|
|
2976
|
+
"cancel-run",
|
|
2977
|
+
"fail",
|
|
2978
|
+
"continue"
|
|
2979
|
+
]);
|
|
2980
|
+
var ApprovalOnTimeoutSchema = z22.union([
|
|
2981
|
+
TerminalOutcomeSchema,
|
|
2982
|
+
EscalationHopSchema,
|
|
2983
|
+
z22.array(z22.union([
|
|
2984
|
+
TerminalOutcomeSchema,
|
|
2985
|
+
EscalationHopSchema
|
|
2986
|
+
])).min(1).max(ESCALATION_MAX_HOPS + 1)
|
|
2987
|
+
]);
|
|
2988
|
+
var APPROVER_SPEC_SHAPES = [
|
|
2989
|
+
"'creator'",
|
|
2990
|
+
"'org-admins'",
|
|
2991
|
+
"{users:[userId, \u2026]}",
|
|
2992
|
+
"{role:roleName}",
|
|
2993
|
+
"{group:groupName}",
|
|
2994
|
+
"{governance:{policyId}}"
|
|
2995
|
+
];
|
|
2996
|
+
var APPROVER_WRITTEN_MAX = 120;
|
|
2997
|
+
var USER_ID_SHAPED_RE = /^[^\s@]{1,128}$/;
|
|
2998
|
+
function describeApproverSpecRefusal(spec) {
|
|
2999
|
+
const raw = spec === void 0 ? "undefined" : JSON.stringify(spec) ?? String(spec);
|
|
3000
|
+
const written = raw.length > APPROVER_WRITTEN_MAX ? `${raw.slice(0, APPROVER_WRITTEN_MAX - 1)}\u2026` : raw;
|
|
3001
|
+
const users = typeof spec === "object" && spec !== null ? spec.users : void 0;
|
|
3002
|
+
const approver = typeof users === "string" && USER_ID_SHAPED_RE.test(users) ? {
|
|
3003
|
+
users: [
|
|
3004
|
+
users
|
|
3005
|
+
]
|
|
3006
|
+
} : "creator";
|
|
3007
|
+
const message = `approver ${written} is not an approver \u2014 legal: ${APPROVER_SPEC_SHAPES.join(" | ")}. 'creator' is the person who started the run: write approver:'creator' for "ask me" / "I approve"; {users:[\u2026]} takes user ids, never emails, names or {type:'user'}` + (approver === "creator" ? "" : `; here: approver:${JSON.stringify(approver)}`);
|
|
3008
|
+
return {
|
|
3009
|
+
approver,
|
|
3010
|
+
written,
|
|
3011
|
+
message
|
|
3012
|
+
};
|
|
3013
|
+
}
|
|
3014
|
+
__name(describeApproverSpecRefusal, "describeApproverSpecRefusal");
|
|
3015
|
+
__name3(describeApproverSpecRefusal, "describeApproverSpecRefusal");
|
|
3016
|
+
var BINDING_ROOTS = [
|
|
3017
|
+
"initData",
|
|
3018
|
+
"stepResults",
|
|
3019
|
+
"requestContext",
|
|
3020
|
+
"state"
|
|
3021
|
+
];
|
|
3022
|
+
function bindingRootsOk(template22) {
|
|
3023
|
+
const refs = [
|
|
3024
|
+
...template22.matchAll(/\$\{\s*([A-Za-z_$][\w$]*)/g)
|
|
3025
|
+
].map((m) => m[1]);
|
|
3026
|
+
return refs.length > 0 && refs.every((r) => BINDING_ROOTS.includes(r));
|
|
3027
|
+
}
|
|
3028
|
+
__name(bindingRootsOk, "bindingRootsOk");
|
|
3029
|
+
__name3(bindingRootsOk, "bindingRootsOk");
|
|
3030
|
+
function isTemplateBinding(v) {
|
|
3031
|
+
return typeof v === "object" && v !== null && typeof v.template === "string";
|
|
3032
|
+
}
|
|
3033
|
+
__name(isTemplateBinding, "isTemplateBinding");
|
|
3034
|
+
__name3(isTemplateBinding, "isTemplateBinding");
|
|
3035
|
+
function approvalEditable(node) {
|
|
3036
|
+
if (node.editable === true) return true;
|
|
3037
|
+
if (node.editable === false) return false;
|
|
3038
|
+
return Array.isArray(node.editablePaths) && node.editablePaths.length > 0;
|
|
3039
|
+
}
|
|
3040
|
+
__name(approvalEditable, "approvalEditable");
|
|
3041
|
+
__name3(approvalEditable, "approvalEditable");
|
|
3042
|
+
function validateApproverBlock(node, opts = {
|
|
3043
|
+
path: "approval"
|
|
3044
|
+
}) {
|
|
3045
|
+
const issues = [];
|
|
3046
|
+
const push = /* @__PURE__ */ __name3((code, path, message, severity = "error") => issues.push({
|
|
3047
|
+
code,
|
|
3048
|
+
path,
|
|
3049
|
+
severity,
|
|
3050
|
+
message
|
|
3051
|
+
}), "push");
|
|
3052
|
+
const checkSpec = /* @__PURE__ */ __name3((spec, path) => {
|
|
3053
|
+
const r = ApproverSpecSchema.safeParse(spec);
|
|
3054
|
+
if (!r.success) {
|
|
3055
|
+
const users = spec?.users;
|
|
3056
|
+
if (Array.isArray(users) && users.length > APPROVER_SPEC_MAX_USERS) push("cap-exceeded", path, `at most ${APPROVER_SPEC_MAX_USERS} users`);
|
|
3057
|
+
else {
|
|
3058
|
+
const refusal = describeApproverSpecRefusal(spec);
|
|
3059
|
+
issues.push({
|
|
3060
|
+
code: "approver-invalid",
|
|
3061
|
+
path,
|
|
3062
|
+
severity: "error",
|
|
3063
|
+
message: refusal.message,
|
|
3064
|
+
repair: {
|
|
3065
|
+
approver: refusal.approver,
|
|
3066
|
+
written: refusal.written
|
|
3067
|
+
}
|
|
3068
|
+
});
|
|
3069
|
+
}
|
|
3070
|
+
return;
|
|
3071
|
+
}
|
|
3072
|
+
const s = r.data;
|
|
3073
|
+
if (typeof s === "object") {
|
|
3074
|
+
if ("governance" in s && !opts.governanceEnabled) push("approver-governance-unavailable", path, "governance reviewer routing is not enabled for this deployment");
|
|
3075
|
+
if ("group" in s && typeof s.group === "string" && !opts.scimEnabled && opts.idpGroups?.includes(s.group)) push("approver-idp-group-unavailable", path, "IdP-group approvers are not enabled for this deployment");
|
|
3076
|
+
const binding = "users" in s ? s.users : "role" in s ? s.role : "group" in s ? s.group : void 0;
|
|
3077
|
+
if (isTemplateBinding(binding)) {
|
|
3078
|
+
if (!bindingRootsOk(binding.template)) push("approver-binding-invalid", `${path}.template`, "binding root must be initData / stepResults / requestContext / state");
|
|
3079
|
+
if ("users" in s && opts.customerReachable) push("approver-binding-customer-reachable", `${path}.users`, "a customer-reachable workflow may not bind its approver list");
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
}, "checkSpec");
|
|
3083
|
+
if (node.approver !== void 0) checkSpec(node.approver, `${opts.path}.approver`);
|
|
3084
|
+
if (node.fourEyes !== void 0) {
|
|
3085
|
+
const r = FourEyesSchema.safeParse(node.fourEyes);
|
|
3086
|
+
if (!r.success) push("approver-invalid", `${opts.path}.fourEyes`, "fourEyes needs { edit, approve } approver specs");
|
|
3087
|
+
else {
|
|
3088
|
+
checkSpec(r.data.edit, `${opts.path}.fourEyes.edit`);
|
|
3089
|
+
checkSpec(r.data.approve, `${opts.path}.fourEyes.approve`);
|
|
3090
|
+
}
|
|
3091
|
+
if (!approvalEditable(node)) push("four-eyes-requires-editable", `${opts.path}.fourEyes`, "fourEyes requires editable:true");
|
|
3092
|
+
if (node.approver !== void 0) push("four-eyes-overrides-approver", `${opts.path}.approver`, "fourEyes replaces approver", "warning");
|
|
3093
|
+
if (node.itemsPath) push("four-eyes-items-unsupported", `${opts.path}.fourEyes`, "fourEyes cannot combine with itemsPath");
|
|
3094
|
+
}
|
|
3095
|
+
if (node.excludeInitiator && (node.approver === void 0 || node.approver === "creator") && !node.fourEyes) push("approver-excludes-only-candidate", `${opts.path}.excludeInitiator`, "'creator' with excludeInitiator leaves no approver");
|
|
3096
|
+
if (Array.isArray(node.onTimeout)) {
|
|
3097
|
+
const chain = node.onTimeout;
|
|
3098
|
+
const hops = chain.filter((m) => typeof m === "object" && m !== null && "escalateTo" in m);
|
|
3099
|
+
if (hops.length > ESCALATION_MAX_HOPS) push("escalation-chain-too-long", `${opts.path}.onTimeout`, `at most ${ESCALATION_MAX_HOPS} hops`);
|
|
3100
|
+
const last = chain[chain.length - 1];
|
|
3101
|
+
if (typeof last === "object" && last !== null) push("escalation-chain-not-terminal", `${opts.path}.onTimeout`, "a chain must end in deny | cancel-run | fail");
|
|
3102
|
+
hops.forEach((h, i) => checkSpec(h.escalateTo, `${opts.path}.onTimeout[${i}].escalateTo`));
|
|
3103
|
+
} else if (typeof node.onTimeout === "object" && node.onTimeout !== null) {
|
|
3104
|
+
checkSpec(node.onTimeout.escalateTo, `${opts.path}.onTimeout.escalateTo`);
|
|
3105
|
+
}
|
|
3106
|
+
return issues;
|
|
3107
|
+
}
|
|
3108
|
+
__name(validateApproverBlock, "validateApproverBlock");
|
|
3109
|
+
__name3(validateApproverBlock, "validateApproverBlock");
|
|
3110
|
+
function liftRenderedApprover(row, rendered) {
|
|
3111
|
+
const text = (rendered ?? "").trim();
|
|
3112
|
+
if (!text) return null;
|
|
3113
|
+
if (row === "users") {
|
|
3114
|
+
let members = null;
|
|
3115
|
+
if (text.startsWith("[")) {
|
|
3116
|
+
try {
|
|
3117
|
+
members = JSON.parse(text);
|
|
3118
|
+
} catch {
|
|
3119
|
+
return null;
|
|
3120
|
+
}
|
|
3121
|
+
} else members = text.split(",").map((s) => s.trim());
|
|
3122
|
+
if (!Array.isArray(members) || members.length === 0 || members.length > APPROVER_SPEC_MAX_USERS) return null;
|
|
3123
|
+
if (!members.every((m) => typeof m === "string" && m.length > 0 && m.length <= 128)) return null;
|
|
3124
|
+
return {
|
|
3125
|
+
users: [
|
|
3126
|
+
...new Set(members)
|
|
3127
|
+
].sort()
|
|
3128
|
+
};
|
|
3129
|
+
}
|
|
3130
|
+
if (text.length > 128 || text.startsWith("[") || text.startsWith("{")) return null;
|
|
3131
|
+
return row === "role" ? {
|
|
3132
|
+
role: text
|
|
3133
|
+
} : {
|
|
3134
|
+
group: text
|
|
3135
|
+
};
|
|
3136
|
+
}
|
|
3137
|
+
__name(liftRenderedApprover, "liftRenderedApprover");
|
|
3138
|
+
__name3(liftRenderedApprover, "liftRenderedApprover");
|
|
2728
3139
|
var WORKSPACE_TEMPLATE_EXPR_RE = /^\$\{\s*(?:initData|input)\.([^}]+?)\s*\}$/;
|
|
2729
3140
|
function workspaceTemplatePath(template22) {
|
|
2730
3141
|
const key = template22.trim();
|
|
@@ -2752,6 +3163,11 @@ function sleepUntilUnsupportedMessage(id) {
|
|
|
2752
3163
|
}
|
|
2753
3164
|
__name(sleepUntilUnsupportedMessage, "sleepUntilUnsupportedMessage");
|
|
2754
3165
|
__name3(sleepUntilUnsupportedMessage, "sleepUntilUnsupportedMessage");
|
|
3166
|
+
function armSubrunUnsupportedMessage(id, workflowId) {
|
|
3167
|
+
return `the engine does not execute the implicit \`${workflowId}\` arm subrun (node "${id}") \u2014 a [map, step] container arm is the step itself with the map as its \`input\` since lua-cli 3.32.4; re-run \`lua compile\` with the current CLI (a hand-written artifact: put the map on the arm node's \`input\` and drop the \`workflow\` wrapper)`;
|
|
3168
|
+
}
|
|
3169
|
+
__name(armSubrunUnsupportedMessage, "armSubrunUnsupportedMessage");
|
|
3170
|
+
__name3(armSubrunUnsupportedMessage, "armSubrunUnsupportedMessage");
|
|
2755
3171
|
var WORKFLOW_CAPS_DEFAULT = Object.freeze({
|
|
2756
3172
|
maxParallelArms: 16,
|
|
2757
3173
|
maxForeachConcurrency: 16,
|
|
@@ -2804,7 +3220,6 @@ function fillSingle(node) {
|
|
|
2804
3220
|
fillPolicy(node, WORKFLOW_STEP_DEFAULT_TIMEOUT_SECONDS);
|
|
2805
3221
|
return;
|
|
2806
3222
|
case "workflow":
|
|
2807
|
-
if (node.workflowId === WORKFLOW_ARM_SUBRUN_ID && Array.isArray(node.graph) && node.graph[1]) fillSingle(node.graph[1]);
|
|
2808
3223
|
return;
|
|
2809
3224
|
}
|
|
2810
3225
|
}
|
|
@@ -2994,8 +3409,14 @@ function nodeStepRefs(entry) {
|
|
|
2994
3409
|
case "agent": {
|
|
2995
3410
|
const a = entry;
|
|
2996
3411
|
const p = a.promptTemplate;
|
|
2997
|
-
|
|
3412
|
+
const prompt = typeof p === "string" ? templateStepRefs(p) : p && "template" in p ? templateStepRefs(p.template) : [];
|
|
3413
|
+
return [
|
|
3414
|
+
...prompt,
|
|
3415
|
+
...mapConfigStepRefs(a.input)
|
|
3416
|
+
];
|
|
2998
3417
|
}
|
|
3418
|
+
case "step":
|
|
3419
|
+
return mapConfigStepRefs(entry.input);
|
|
2999
3420
|
case "tool":
|
|
3000
3421
|
return mapConfigStepRefs(entry.input);
|
|
3001
3422
|
case "workflow":
|
|
@@ -3114,7 +3535,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3114
3535
|
const id = singleId(node);
|
|
3115
3536
|
const unknown = unknownWorkflowRetryMembers(r);
|
|
3116
3537
|
if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path}.retry`, id);
|
|
3117
|
-
if (
|
|
3538
|
+
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
3118
3539
|
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
3119
3540
|
err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path}.retry.maxAttempts`, id);
|
|
3120
3541
|
}
|
|
@@ -3214,6 +3635,21 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3214
3635
|
err("job-tier-provider-unsupported", `model provider '${provider}' is outside LUA_WF_JOB_PROVIDERS [${opts.policy.jobProviders.join(", ")}]`, `${path}.model`, id);
|
|
3215
3636
|
}
|
|
3216
3637
|
}, "checkTier");
|
|
3638
|
+
const checkModel = /* @__PURE__ */ __name3((node, path) => {
|
|
3639
|
+
if (node.type !== "agent" || typeof node.model !== "string") return;
|
|
3640
|
+
const registry = opts.approvedModels;
|
|
3641
|
+
if (registry === void 0) return;
|
|
3642
|
+
const id = singleId(node);
|
|
3643
|
+
if (registry === "unavailable") {
|
|
3644
|
+
const pin = node.model.trim();
|
|
3645
|
+
if (pin && !normalizeModelId(pin, []).ok) {
|
|
3646
|
+
warn("model-unresolved", `model "${pin}" could not be checked against the approved-model registry (unavailable at push) \u2014 it dispatches only if it resolves there (a provider/model registry code, or a bare id exactly one approved model carries)`, `${path}.model`, id);
|
|
3647
|
+
}
|
|
3648
|
+
return;
|
|
3649
|
+
}
|
|
3650
|
+
const resolved = normalizeModelId(node.model, registry);
|
|
3651
|
+
if (!resolved.ok) err("model-unresolved", modelUnresolvedMessage(resolved), `${path}.model`, id);
|
|
3652
|
+
}, "checkModel");
|
|
3217
3653
|
const checkWorkspace = /* @__PURE__ */ __name3((node, path) => {
|
|
3218
3654
|
const id = singleId(node);
|
|
3219
3655
|
const ws = workspaceOf(node);
|
|
@@ -3266,38 +3702,29 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3266
3702
|
}
|
|
3267
3703
|
}, "checkMapMembers");
|
|
3268
3704
|
const checkInputShape = /* @__PURE__ */ __name3((node, path) => {
|
|
3269
|
-
if (node.type !== "tool" && node.type !== "workflow") return;
|
|
3270
3705
|
const input = node.input;
|
|
3271
3706
|
if (input === void 0) return;
|
|
3707
|
+
const id = singleId(node);
|
|
3272
3708
|
if (input !== null && typeof input === "object" && !Array.isArray(input)) {
|
|
3273
|
-
checkMapMembers(input, `${path}.input`,
|
|
3709
|
+
checkMapMembers(input, `${path}.input`, id);
|
|
3274
3710
|
return;
|
|
3275
3711
|
}
|
|
3276
|
-
err("invalid-envelope", `\`input\` must be an object map \u2014 each member a binding descriptor ({initData:true, path} | {step, path} | {value} | {template} | {requestContextPath}) or a JSON literal (got ${JSON.stringify(input)})`, `${path}.input`,
|
|
3712
|
+
err("invalid-envelope", `\`input\` must be an object map \u2014 each member a binding descriptor ({initData:true, path} | {step, path} | {value} | {template} | {requestContextPath}) or a JSON literal (got ${JSON.stringify(input)})`, `${path}.input`, id);
|
|
3277
3713
|
}, "checkInputShape");
|
|
3714
|
+
const checkBodyInput = /* @__PURE__ */ __name3((body, path, container) => {
|
|
3715
|
+
if (body.type === "workflow" || body.input === void 0) return;
|
|
3716
|
+
err("arm-input-unsupported", container === "foreach" ? `a foreach body receives each item as its input \u2014 drop \`input\` on "${singleId(body)}" and map the items before the foreach instead` : `a loop body receives the previous output as its input \u2014 drop \`input\` on "${singleId(body)}" and put the map before the loop instead`, `${path}.input`, singleId(body));
|
|
3717
|
+
}, "checkBodyInput");
|
|
3278
3718
|
const checkSingle = /* @__PURE__ */ __name3((node, path, depth) => {
|
|
3279
3719
|
recordOutputSchema(node);
|
|
3280
|
-
if (node.type === "workflow" && node.workflowId ===
|
|
3720
|
+
if (node.type === "workflow" && (typeof node.workflowId !== "string" || node.workflowId.length === 0)) {
|
|
3281
3721
|
checkId(node.id, path);
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
err("container-arm-empty", "a bare mapping arm has nothing to run", `${path}.graph.1`, node.id);
|
|
3289
|
-
return;
|
|
3290
|
-
}
|
|
3291
|
-
const inner = body[1];
|
|
3292
|
-
if (isHitlNode(inner)) {
|
|
3293
|
-
err("node-type-unsupported-in-container", workflowHitlArmShapeMessage(inner.type, inner.id, "mapped-arm"), `${path}.graph.1`, inner.id);
|
|
3294
|
-
return;
|
|
3295
|
-
}
|
|
3296
|
-
upstream.add(singleId(body[1]));
|
|
3297
|
-
checkArm(body[0], `${path}.graph.0`, depth, "parallel");
|
|
3298
|
-
checkSingle(body[1], `${path}.graph.1`, depth);
|
|
3299
|
-
upstream.add(body[0].id);
|
|
3300
|
-
upstream.add(singleId(body[1]));
|
|
3722
|
+
err("invalid-envelope", `\`workflowId\` must be a non-empty string naming the workflow to start (got ${JSON.stringify(node.workflowId)})`, `${path}.workflowId`, node.id);
|
|
3723
|
+
return;
|
|
3724
|
+
}
|
|
3725
|
+
if (node.type === "workflow" && (node.workflowId.startsWith("$") || Array.isArray(node.graph))) {
|
|
3726
|
+
checkId(node.id, path);
|
|
3727
|
+
err("node-type-unsupported-by-engine", armSubrunUnsupportedMessage(node.id, node.workflowId), path, node.id);
|
|
3301
3728
|
return;
|
|
3302
3729
|
}
|
|
3303
3730
|
checkId(singleId(node), path);
|
|
@@ -3305,6 +3732,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3305
3732
|
checkInputShape(node, path);
|
|
3306
3733
|
checkTimeout(node, path);
|
|
3307
3734
|
checkTier(node, path);
|
|
3735
|
+
checkModel(node, path);
|
|
3308
3736
|
checkRetry(node, path);
|
|
3309
3737
|
checkWorkspace(node, path);
|
|
3310
3738
|
if (!opts.static) {
|
|
@@ -3327,7 +3755,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3327
3755
|
if (node.type === "workflow" && node.kind === "subrun" && depth > caps.maxNestingDepth) {
|
|
3328
3756
|
err("cap-exceeded", `nesting depth ${depth} exceeds ${caps.maxNestingDepth}`, path, node.id);
|
|
3329
3757
|
}
|
|
3330
|
-
if (node.type === "workflow" &&
|
|
3758
|
+
if (node.type === "workflow" && typeof g.definition?.id === "string" && node.workflowId === g.definition.id) {
|
|
3331
3759
|
err("subrun-cycle", `"${node.id}" starts "${node.workflowId}", which is this workflow itself`, path, node.id);
|
|
3332
3760
|
}
|
|
3333
3761
|
for (const ref of nodeStepRefs(node)) {
|
|
@@ -3348,11 +3776,14 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3348
3776
|
if (a.approver === "creator" && a.excludeInitiator === true) {
|
|
3349
3777
|
err("approver-excludes-only-candidate", "approver:'creator' with excludeInitiator:true always excludes the only candidate", path, a.id);
|
|
3350
3778
|
}
|
|
3351
|
-
|
|
3779
|
+
const editable = approvalEditable(a);
|
|
3780
|
+
if (a.fourEyes !== void 0 && !editable) {
|
|
3352
3781
|
err("four-eyes-requires-editable", "`fourEyes` requires editable:true", `${path}.fourEyes`, a.id);
|
|
3353
3782
|
}
|
|
3354
|
-
if (
|
|
3355
|
-
err("editable-path-invalid", "`editablePaths`
|
|
3783
|
+
if (a.editable === false && Array.isArray(a.editablePaths) && a.editablePaths.length > 0) {
|
|
3784
|
+
err("editable-path-invalid", "`editablePaths` beside editable:false is contradictory \u2014 drop the paths or set editable:true", `${path}.editablePaths`, a.id);
|
|
3785
|
+
} else if ((a.editablePaths !== void 0 || a.editedPayloadSchema !== void 0) && !editable) {
|
|
3786
|
+
err("editable-path-invalid", "`editablePaths` / `editedPayloadSchema` require editable:true (a non-empty editablePaths implies it)", `${path}.editablePaths`, a.id);
|
|
3356
3787
|
}
|
|
3357
3788
|
for (const p of a.editablePaths ?? []) {
|
|
3358
3789
|
if (!EDITABLE_PATH_RE.test(p)) err("editable-path-invalid", `editablePaths entry "${p}" is outside the seg(.seg)*[*]/[n] grammar`, `${path}.editablePaths`, a.id);
|
|
@@ -3533,6 +3964,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3533
3964
|
} else checkHitlArm(f.step, `${path}.step`, "foreach");
|
|
3534
3965
|
declared.push(f.step.id);
|
|
3535
3966
|
} else {
|
|
3967
|
+
checkBodyInput(f.step, `${path}.step`, "foreach");
|
|
3536
3968
|
checkSingle(f.step, `${path}.step`, o.chunk ? 2 : 1);
|
|
3537
3969
|
declared.push(singleId(f.step));
|
|
3538
3970
|
}
|
|
@@ -3553,6 +3985,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3553
3985
|
checkHitlArm(l.step, `${path}.step`, "loop");
|
|
3554
3986
|
declared.push(l.step.id);
|
|
3555
3987
|
} else {
|
|
3988
|
+
checkBodyInput(l.step, `${path}.step`, "loop");
|
|
3556
3989
|
checkSingle(l.step, `${path}.step`, 1);
|
|
3557
3990
|
declared.push(singleId(l.step));
|
|
3558
3991
|
}
|
|
@@ -4220,21 +4653,14 @@ function isContinuedFailureValue(v) {
|
|
|
4220
4653
|
__name(isContinuedFailureValue, "isContinuedFailureValue");
|
|
4221
4654
|
__name3(isContinuedFailureValue, "isContinuedFailureValue");
|
|
4222
4655
|
var isHitlNode2 = /* @__PURE__ */ __name3((n2) => isWorkflowHitlEntryType(n2.type), "isHitlNode");
|
|
4223
|
-
function
|
|
4224
|
-
const stepId = nodeIdOf(step22);
|
|
4656
|
+
function inlineContainerArm(mapping, step22) {
|
|
4225
4657
|
return {
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
workflowId: WORKFLOW_ARM_SUBRUN_ID,
|
|
4229
|
-
kind: "subrun",
|
|
4230
|
-
graph: [
|
|
4231
|
-
mapping,
|
|
4232
|
-
step22
|
|
4233
|
-
]
|
|
4658
|
+
...step22,
|
|
4659
|
+
input: parseMapConfig(mapping.mapConfig, mapping.id)
|
|
4234
4660
|
};
|
|
4235
4661
|
}
|
|
4236
|
-
__name(
|
|
4237
|
-
__name3(
|
|
4662
|
+
__name(inlineContainerArm, "inlineContainerArm");
|
|
4663
|
+
__name3(inlineContainerArm, "inlineContainerArm");
|
|
4238
4664
|
var nodeIdOf = /* @__PURE__ */ __name3((n2) => n2.type === "step" ? n2.step.id : n2.id, "nodeIdOf");
|
|
4239
4665
|
function entryIds(entry) {
|
|
4240
4666
|
switch (entry.type) {
|
|
@@ -4305,6 +4731,27 @@ function resolvePlacements(calls) {
|
|
|
4305
4731
|
break;
|
|
4306
4732
|
}
|
|
4307
4733
|
});
|
|
4734
|
+
const armMapPlacementIssue = /* @__PURE__ */ __name3((node, ref, i, container) => {
|
|
4735
|
+
if (!ref.armMap || node.type === "mapping" || isHitlNode2(node)) return void 0;
|
|
4736
|
+
const id = nodeIdOf(node);
|
|
4737
|
+
if ((container === "foreach" || container === "loop") && node.type !== "workflow") {
|
|
4738
|
+
return {
|
|
4739
|
+
code: "mapping-placement",
|
|
4740
|
+
message: container === "foreach" ? `foreach body "${id}": a [map, step] body is not supported \u2014 the body receives each item as its input; map the items before the foreach instead (foreach(step, { items: \u2026 }) or a .map() before it)` : `loop body "${id}": a [map, step] body is not supported \u2014 the body receives the previous output as its input; put the .map() before the loop instead`,
|
|
4741
|
+
callIndex: i,
|
|
4742
|
+
stepId: id
|
|
4743
|
+
};
|
|
4744
|
+
}
|
|
4745
|
+
if (node.input !== void 0) {
|
|
4746
|
+
return {
|
|
4747
|
+
code: "mapping-placement",
|
|
4748
|
+
message: `"${id}": the [map, step] arm mapping and the node's own input map would both bind its input \u2014 keep one (drop the arm map, or the \`input\` on the declaration)`,
|
|
4749
|
+
callIndex: i,
|
|
4750
|
+
stepId: id
|
|
4751
|
+
};
|
|
4752
|
+
}
|
|
4753
|
+
return void 0;
|
|
4754
|
+
}, "armMapPlacementIssue");
|
|
4308
4755
|
const hitlPlacementIssue = /* @__PURE__ */ __name3((node, ref, i, container) => {
|
|
4309
4756
|
if (!isHitlNode2(node)) return void 0;
|
|
4310
4757
|
const id = node.id;
|
|
@@ -4331,7 +4778,7 @@ function resolvePlacements(calls) {
|
|
|
4331
4778
|
if (ref.node.type === "mapping" && !allowMapping) {
|
|
4332
4779
|
issues.push({
|
|
4333
4780
|
code: "mapping-placement",
|
|
4334
|
-
message: `mapping "${ref.node.id}" cannot be a container arm \u2014 chain it as [map, step]`,
|
|
4781
|
+
message: `mapping "${ref.node.id}" cannot be a container arm \u2014 chain it as [map, step] in a parallel / conditional arm, or place the .map() before the container`,
|
|
4335
4782
|
callIndex: i,
|
|
4336
4783
|
stepId: ref.node.id
|
|
4337
4784
|
});
|
|
@@ -4352,7 +4799,7 @@ function resolvePlacements(calls) {
|
|
|
4352
4799
|
if (d.node.type === "mapping" && !allowMapping) {
|
|
4353
4800
|
issues.push({
|
|
4354
4801
|
code: "mapping-placement",
|
|
4355
|
-
message: `map "${ref.ref}" cannot be a parallel/foreach/loop arm \u2014 chain it as [map, step]`,
|
|
4802
|
+
message: `map "${ref.ref}" cannot be a parallel/foreach/loop arm \u2014 chain it as [map, step] in a parallel arm, or place the .map() before the container`,
|
|
4356
4803
|
callIndex: i,
|
|
4357
4804
|
stepId: ref.ref
|
|
4358
4805
|
});
|
|
@@ -4363,6 +4810,11 @@ function resolvePlacements(calls) {
|
|
|
4363
4810
|
issues.push(hitl);
|
|
4364
4811
|
return void 0;
|
|
4365
4812
|
}
|
|
4813
|
+
const mapped = armMapPlacementIssue(d.node, ref, i, container);
|
|
4814
|
+
if (mapped) {
|
|
4815
|
+
issues.push(mapped);
|
|
4816
|
+
return void 0;
|
|
4817
|
+
}
|
|
4366
4818
|
const prior = placedBy.get(ref.ref);
|
|
4367
4819
|
if (prior !== void 0 && prior !== i) {
|
|
4368
4820
|
issues.push({
|
|
@@ -4383,6 +4835,10 @@ function resolvePlacements(calls) {
|
|
|
4383
4835
|
}
|
|
4384
4836
|
const hitl = hitlPlacementIssue(ref.node, ref, i, container);
|
|
4385
4837
|
if (hitl) issues.push(hitl);
|
|
4838
|
+
else {
|
|
4839
|
+
const mapped = armMapPlacementIssue(ref.node, ref, i, container);
|
|
4840
|
+
if (mapped) issues.push(mapped);
|
|
4841
|
+
}
|
|
4386
4842
|
}, "claim");
|
|
4387
4843
|
calls.forEach((call, i) => {
|
|
4388
4844
|
switch (call.kind) {
|
|
@@ -4410,7 +4866,7 @@ function resolvePlacements(calls) {
|
|
|
4410
4866
|
const lookup = /* @__PURE__ */ __name3((ref) => {
|
|
4411
4867
|
const n2 = "node" in ref ? ref.node : declared.get(ref.ref)?.node;
|
|
4412
4868
|
if (!n2 || !ref.armMap || n2.type === "mapping" || isHitlNode2(n2)) return n2;
|
|
4413
|
-
return
|
|
4869
|
+
return inlineContainerArm(ref.armMap, n2);
|
|
4414
4870
|
}, "lookup");
|
|
4415
4871
|
calls.forEach((call, i) => {
|
|
4416
4872
|
switch (call.kind) {
|
|
@@ -4851,9 +5307,37 @@ function pruneUndefined(o) {
|
|
|
4851
5307
|
}
|
|
4852
5308
|
__name(pruneUndefined, "pruneUndefined");
|
|
4853
5309
|
__name3(pruneUndefined, "pruneUndefined");
|
|
5310
|
+
var WORKFLOW_INLINE_RUN_TAG = "inline";
|
|
5311
|
+
function runOrigin(run) {
|
|
5312
|
+
if (run.goalId) return "goal";
|
|
5313
|
+
if (run.jobId || run.trigger === "schedule") return "schedule";
|
|
5314
|
+
if (run.dynamic === true) return run.tags?.includes(WORKFLOW_INLINE_RUN_TAG) ? "inline" : "compose";
|
|
5315
|
+
return "definition";
|
|
5316
|
+
}
|
|
5317
|
+
__name(runOrigin, "runOrigin");
|
|
5318
|
+
__name3(runOrigin, "runOrigin");
|
|
5319
|
+
var RUN_ERROR_ISSUES_MAX = 20;
|
|
5320
|
+
function runErrorIssues(issues) {
|
|
5321
|
+
if (!Array.isArray(issues)) return void 0;
|
|
5322
|
+
const out = [];
|
|
5323
|
+
for (const raw of issues.slice(0, RUN_ERROR_ISSUES_MAX)) {
|
|
5324
|
+
if (!raw || typeof raw !== "object") continue;
|
|
5325
|
+
const o = raw;
|
|
5326
|
+
if (typeof o.code !== "string" || !o.code) continue;
|
|
5327
|
+
out.push(pruneUndefined({
|
|
5328
|
+
code: o.code,
|
|
5329
|
+
path: typeof o.path === "string" ? o.path : void 0,
|
|
5330
|
+
message: typeof o.message === "string" ? o.message : void 0
|
|
5331
|
+
}));
|
|
5332
|
+
}
|
|
5333
|
+
return out.length ? out : void 0;
|
|
5334
|
+
}
|
|
5335
|
+
__name(runErrorIssues, "runErrorIssues");
|
|
5336
|
+
__name3(runErrorIssues, "runErrorIssues");
|
|
4854
5337
|
function runNextAction(run) {
|
|
4855
5338
|
if (isTerminalRunStatus(run.status)) return "none";
|
|
4856
5339
|
if (run.status === "suspended" && run.gate?.kind === "budget") return "raise_budget";
|
|
5340
|
+
if (run.status === "suspended" && run.gate?.kind === "billing") return "top_up";
|
|
4857
5341
|
if (!run.cancel?.requestedAt) return "none";
|
|
4858
5342
|
const forceAt = run.cancel.forceAfter ?? run.cancel.requestedAt + FORCE_CANCEL_STALE_MS;
|
|
4859
5343
|
return Date.now() >= forceAt ? "force" : "cancel_again";
|
|
@@ -4890,6 +5374,16 @@ function runCountsFromStepStatuses(statuses) {
|
|
|
4890
5374
|
}
|
|
4891
5375
|
__name(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
4892
5376
|
__name3(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
5377
|
+
function isBillingHeldStep(row) {
|
|
5378
|
+
return row.status === "ready" && row.billingHold === true;
|
|
5379
|
+
}
|
|
5380
|
+
__name(isBillingHeldStep, "isBillingHeldStep");
|
|
5381
|
+
__name3(isBillingHeldStep, "isBillingHeldStep");
|
|
5382
|
+
function stepEffectiveStatus(row) {
|
|
5383
|
+
return isBillingHeldStep(row) ? "suspended" : row.status;
|
|
5384
|
+
}
|
|
5385
|
+
__name(stepEffectiveStatus, "stepEffectiveStatus");
|
|
5386
|
+
__name3(stepEffectiveStatus, "stepEffectiveStatus");
|
|
4893
5387
|
var n = /* @__PURE__ */ __name3((v) => typeof v === "number" && Number.isFinite(v) ? v : 0, "n");
|
|
4894
5388
|
function runCounts(counts) {
|
|
4895
5389
|
const c = counts ?? {};
|
|
@@ -5050,6 +5544,7 @@ function toWorkflowRunSummary(run) {
|
|
|
5050
5544
|
repairOf: run.repairOf,
|
|
5051
5545
|
repairRunIds: run.repairRunIds,
|
|
5052
5546
|
trigger: run.trigger ?? "api",
|
|
5547
|
+
origin: runOrigin(run),
|
|
5053
5548
|
createdBy: {
|
|
5054
5549
|
subjectType: principal?.subjectType ?? "system",
|
|
5055
5550
|
subjectId: principal?.subjectId ?? run.userId ?? ""
|
|
@@ -5067,11 +5562,13 @@ function toWorkflowRunSummary(run) {
|
|
|
5067
5562
|
usage: runUsage(run),
|
|
5068
5563
|
// LUA-697: a row persisted before the write seams (#2406 / #2465 / the script tier) leaves scrubbed here too —
|
|
5069
5564
|
// idempotent on a scrubbed message, bounded input; an empty message falls back to the code.
|
|
5070
|
-
error: run.error ? {
|
|
5565
|
+
error: run.error ? pruneUndefined({
|
|
5071
5566
|
code: run.error.code ?? "error",
|
|
5072
5567
|
message: scrubStepErrorMessage(run.error.message) ?? run.error.code ?? "error",
|
|
5073
|
-
stepId: run.error.stepId
|
|
5074
|
-
|
|
5568
|
+
stepId: run.error.stepId,
|
|
5569
|
+
// LUA-784 (item 3): the unattended pre-start failure's refusal rows (`input_schema_invalid` and kin).
|
|
5570
|
+
issues: runErrorIssues(run.error.issues)
|
|
5571
|
+
}) : void 0,
|
|
5075
5572
|
kind: "run",
|
|
5076
5573
|
aclHash: run.aclHash,
|
|
5077
5574
|
migration: run.migration,
|
|
@@ -5724,204 +6221,6 @@ function rebaseItemPointer(pointer, itemsPath, index) {
|
|
|
5724
6221
|
}
|
|
5725
6222
|
__name(rebaseItemPointer, "rebaseItemPointer");
|
|
5726
6223
|
__name3(rebaseItemPointer, "rebaseItemPointer");
|
|
5727
|
-
var APPROVER_SPEC_MAX_USERS = 20;
|
|
5728
|
-
var ESCALATION_MAX_HOPS = 3;
|
|
5729
|
-
var TemplateBindingSchema = z22.object({
|
|
5730
|
-
template: z22.string().min(1).max(2048)
|
|
5731
|
-
}).strict();
|
|
5732
|
-
var ApproverSpecSchema = z22.union([
|
|
5733
|
-
z22.literal("creator"),
|
|
5734
|
-
z22.literal("org-admins"),
|
|
5735
|
-
z22.object({
|
|
5736
|
-
users: z22.union([
|
|
5737
|
-
z22.array(z22.string().min(1).max(128)).min(1).max(APPROVER_SPEC_MAX_USERS),
|
|
5738
|
-
TemplateBindingSchema
|
|
5739
|
-
])
|
|
5740
|
-
}).strict(),
|
|
5741
|
-
z22.object({
|
|
5742
|
-
role: z22.union([
|
|
5743
|
-
z22.string().min(1).max(128),
|
|
5744
|
-
TemplateBindingSchema
|
|
5745
|
-
])
|
|
5746
|
-
}).strict(),
|
|
5747
|
-
z22.object({
|
|
5748
|
-
group: z22.union([
|
|
5749
|
-
z22.string().min(1).max(128),
|
|
5750
|
-
TemplateBindingSchema
|
|
5751
|
-
])
|
|
5752
|
-
}).strict(),
|
|
5753
|
-
z22.object({
|
|
5754
|
-
governance: z22.object({
|
|
5755
|
-
policyId: z22.string().min(1).max(128)
|
|
5756
|
-
}).strict()
|
|
5757
|
-
}).strict()
|
|
5758
|
-
]);
|
|
5759
|
-
var FourEyesSchema = z22.object({
|
|
5760
|
-
edit: ApproverSpecSchema,
|
|
5761
|
-
approve: ApproverSpecSchema
|
|
5762
|
-
}).strict();
|
|
5763
|
-
var EscalationHopSchema = z22.object({
|
|
5764
|
-
escalateTo: ApproverSpecSchema,
|
|
5765
|
-
timeoutHours: z22.number().finite().min(1).max(720)
|
|
5766
|
-
}).strict();
|
|
5767
|
-
var TerminalOutcomeSchema = z22.enum([
|
|
5768
|
-
"deny",
|
|
5769
|
-
"cancel-run",
|
|
5770
|
-
"fail",
|
|
5771
|
-
"continue"
|
|
5772
|
-
]);
|
|
5773
|
-
var ApprovalOnTimeoutSchema = z22.union([
|
|
5774
|
-
TerminalOutcomeSchema,
|
|
5775
|
-
EscalationHopSchema,
|
|
5776
|
-
z22.array(z22.union([
|
|
5777
|
-
TerminalOutcomeSchema,
|
|
5778
|
-
EscalationHopSchema
|
|
5779
|
-
])).min(1).max(ESCALATION_MAX_HOPS + 1)
|
|
5780
|
-
]);
|
|
5781
|
-
var APPROVER_SPEC_SHAPES = [
|
|
5782
|
-
"'creator'",
|
|
5783
|
-
"'org-admins'",
|
|
5784
|
-
"{users:[userId, \u2026]}",
|
|
5785
|
-
"{role:roleName}",
|
|
5786
|
-
"{group:groupName}",
|
|
5787
|
-
"{governance:{policyId}}"
|
|
5788
|
-
];
|
|
5789
|
-
var APPROVER_WRITTEN_MAX = 120;
|
|
5790
|
-
var USER_ID_SHAPED_RE = /^[^\s@]{1,128}$/;
|
|
5791
|
-
function describeApproverSpecRefusal(spec) {
|
|
5792
|
-
const raw = spec === void 0 ? "undefined" : JSON.stringify(spec) ?? String(spec);
|
|
5793
|
-
const written = raw.length > APPROVER_WRITTEN_MAX ? `${raw.slice(0, APPROVER_WRITTEN_MAX - 1)}\u2026` : raw;
|
|
5794
|
-
const users = typeof spec === "object" && spec !== null ? spec.users : void 0;
|
|
5795
|
-
const approver = typeof users === "string" && USER_ID_SHAPED_RE.test(users) ? {
|
|
5796
|
-
users: [
|
|
5797
|
-
users
|
|
5798
|
-
]
|
|
5799
|
-
} : "creator";
|
|
5800
|
-
const message = `approver ${written} is not an approver \u2014 legal: ${APPROVER_SPEC_SHAPES.join(" | ")}. 'creator' is the person who started the run: write approver:'creator' for "ask me" / "I approve"; {users:[\u2026]} takes user ids, never emails, names or {type:'user'}` + (approver === "creator" ? "" : `; here: approver:${JSON.stringify(approver)}`);
|
|
5801
|
-
return {
|
|
5802
|
-
approver,
|
|
5803
|
-
written,
|
|
5804
|
-
message
|
|
5805
|
-
};
|
|
5806
|
-
}
|
|
5807
|
-
__name(describeApproverSpecRefusal, "describeApproverSpecRefusal");
|
|
5808
|
-
__name3(describeApproverSpecRefusal, "describeApproverSpecRefusal");
|
|
5809
|
-
var BINDING_ROOTS = [
|
|
5810
|
-
"initData",
|
|
5811
|
-
"stepResults",
|
|
5812
|
-
"requestContext",
|
|
5813
|
-
"state"
|
|
5814
|
-
];
|
|
5815
|
-
function bindingRootsOk(template22) {
|
|
5816
|
-
const refs = [
|
|
5817
|
-
...template22.matchAll(/\$\{\s*([A-Za-z_$][\w$]*)/g)
|
|
5818
|
-
].map((m) => m[1]);
|
|
5819
|
-
return refs.length > 0 && refs.every((r) => BINDING_ROOTS.includes(r));
|
|
5820
|
-
}
|
|
5821
|
-
__name(bindingRootsOk, "bindingRootsOk");
|
|
5822
|
-
__name3(bindingRootsOk, "bindingRootsOk");
|
|
5823
|
-
function isTemplateBinding(v) {
|
|
5824
|
-
return typeof v === "object" && v !== null && typeof v.template === "string";
|
|
5825
|
-
}
|
|
5826
|
-
__name(isTemplateBinding, "isTemplateBinding");
|
|
5827
|
-
__name3(isTemplateBinding, "isTemplateBinding");
|
|
5828
|
-
function validateApproverBlock(node, opts = {
|
|
5829
|
-
path: "approval"
|
|
5830
|
-
}) {
|
|
5831
|
-
const issues = [];
|
|
5832
|
-
const push = /* @__PURE__ */ __name3((code, path, message, severity = "error") => issues.push({
|
|
5833
|
-
code,
|
|
5834
|
-
path,
|
|
5835
|
-
severity,
|
|
5836
|
-
message
|
|
5837
|
-
}), "push");
|
|
5838
|
-
const checkSpec = /* @__PURE__ */ __name3((spec, path) => {
|
|
5839
|
-
const r = ApproverSpecSchema.safeParse(spec);
|
|
5840
|
-
if (!r.success) {
|
|
5841
|
-
const users = spec?.users;
|
|
5842
|
-
if (Array.isArray(users) && users.length > APPROVER_SPEC_MAX_USERS) push("cap-exceeded", path, `at most ${APPROVER_SPEC_MAX_USERS} users`);
|
|
5843
|
-
else {
|
|
5844
|
-
const refusal = describeApproverSpecRefusal(spec);
|
|
5845
|
-
issues.push({
|
|
5846
|
-
code: "approver-invalid",
|
|
5847
|
-
path,
|
|
5848
|
-
severity: "error",
|
|
5849
|
-
message: refusal.message,
|
|
5850
|
-
repair: {
|
|
5851
|
-
approver: refusal.approver,
|
|
5852
|
-
written: refusal.written
|
|
5853
|
-
}
|
|
5854
|
-
});
|
|
5855
|
-
}
|
|
5856
|
-
return;
|
|
5857
|
-
}
|
|
5858
|
-
const s = r.data;
|
|
5859
|
-
if (typeof s === "object") {
|
|
5860
|
-
if ("governance" in s && !opts.governanceEnabled) push("approver-governance-unavailable", path, "governance reviewer routing is not enabled for this deployment");
|
|
5861
|
-
if ("group" in s && typeof s.group === "string" && !opts.scimEnabled && opts.idpGroups?.includes(s.group)) push("approver-idp-group-unavailable", path, "IdP-group approvers are not enabled for this deployment");
|
|
5862
|
-
const binding = "users" in s ? s.users : "role" in s ? s.role : "group" in s ? s.group : void 0;
|
|
5863
|
-
if (isTemplateBinding(binding)) {
|
|
5864
|
-
if (!bindingRootsOk(binding.template)) push("approver-binding-invalid", `${path}.template`, "binding root must be initData / stepResults / requestContext / state");
|
|
5865
|
-
if ("users" in s && opts.customerReachable) push("approver-binding-customer-reachable", `${path}.users`, "a customer-reachable workflow may not bind its approver list");
|
|
5866
|
-
}
|
|
5867
|
-
}
|
|
5868
|
-
}, "checkSpec");
|
|
5869
|
-
if (node.approver !== void 0) checkSpec(node.approver, `${opts.path}.approver`);
|
|
5870
|
-
if (node.fourEyes !== void 0) {
|
|
5871
|
-
const r = FourEyesSchema.safeParse(node.fourEyes);
|
|
5872
|
-
if (!r.success) push("approver-invalid", `${opts.path}.fourEyes`, "fourEyes needs { edit, approve } approver specs");
|
|
5873
|
-
else {
|
|
5874
|
-
checkSpec(r.data.edit, `${opts.path}.fourEyes.edit`);
|
|
5875
|
-
checkSpec(r.data.approve, `${opts.path}.fourEyes.approve`);
|
|
5876
|
-
}
|
|
5877
|
-
if (!node.editable) push("four-eyes-requires-editable", `${opts.path}.fourEyes`, "fourEyes requires editable:true");
|
|
5878
|
-
if (node.approver !== void 0) push("four-eyes-overrides-approver", `${opts.path}.approver`, "fourEyes replaces approver", "warning");
|
|
5879
|
-
if (node.itemsPath) push("four-eyes-items-unsupported", `${opts.path}.fourEyes`, "fourEyes cannot combine with itemsPath");
|
|
5880
|
-
}
|
|
5881
|
-
if (node.excludeInitiator && (node.approver === void 0 || node.approver === "creator") && !node.fourEyes) push("approver-excludes-only-candidate", `${opts.path}.excludeInitiator`, "'creator' with excludeInitiator leaves no approver");
|
|
5882
|
-
if (Array.isArray(node.onTimeout)) {
|
|
5883
|
-
const chain = node.onTimeout;
|
|
5884
|
-
const hops = chain.filter((m) => typeof m === "object" && m !== null && "escalateTo" in m);
|
|
5885
|
-
if (hops.length > ESCALATION_MAX_HOPS) push("escalation-chain-too-long", `${opts.path}.onTimeout`, `at most ${ESCALATION_MAX_HOPS} hops`);
|
|
5886
|
-
const last = chain[chain.length - 1];
|
|
5887
|
-
if (typeof last === "object" && last !== null) push("escalation-chain-not-terminal", `${opts.path}.onTimeout`, "a chain must end in deny | cancel-run | fail");
|
|
5888
|
-
hops.forEach((h, i) => checkSpec(h.escalateTo, `${opts.path}.onTimeout[${i}].escalateTo`));
|
|
5889
|
-
} else if (typeof node.onTimeout === "object" && node.onTimeout !== null) {
|
|
5890
|
-
checkSpec(node.onTimeout.escalateTo, `${opts.path}.onTimeout.escalateTo`);
|
|
5891
|
-
}
|
|
5892
|
-
return issues;
|
|
5893
|
-
}
|
|
5894
|
-
__name(validateApproverBlock, "validateApproverBlock");
|
|
5895
|
-
__name3(validateApproverBlock, "validateApproverBlock");
|
|
5896
|
-
function liftRenderedApprover(row, rendered) {
|
|
5897
|
-
const text = (rendered ?? "").trim();
|
|
5898
|
-
if (!text) return null;
|
|
5899
|
-
if (row === "users") {
|
|
5900
|
-
let members = null;
|
|
5901
|
-
if (text.startsWith("[")) {
|
|
5902
|
-
try {
|
|
5903
|
-
members = JSON.parse(text);
|
|
5904
|
-
} catch {
|
|
5905
|
-
return null;
|
|
5906
|
-
}
|
|
5907
|
-
} else members = text.split(",").map((s) => s.trim());
|
|
5908
|
-
if (!Array.isArray(members) || members.length === 0 || members.length > APPROVER_SPEC_MAX_USERS) return null;
|
|
5909
|
-
if (!members.every((m) => typeof m === "string" && m.length > 0 && m.length <= 128)) return null;
|
|
5910
|
-
return {
|
|
5911
|
-
users: [
|
|
5912
|
-
...new Set(members)
|
|
5913
|
-
].sort()
|
|
5914
|
-
};
|
|
5915
|
-
}
|
|
5916
|
-
if (text.length > 128 || text.startsWith("[") || text.startsWith("{")) return null;
|
|
5917
|
-
return row === "role" ? {
|
|
5918
|
-
role: text
|
|
5919
|
-
} : {
|
|
5920
|
-
group: text
|
|
5921
|
-
};
|
|
5922
|
-
}
|
|
5923
|
-
__name(liftRenderedApprover, "liftRenderedApprover");
|
|
5924
|
-
__name3(liftRenderedApprover, "liftRenderedApprover");
|
|
5925
6224
|
var WORKFLOW_ENV_OVERLAY_MAX_KEYS = 64;
|
|
5926
6225
|
var WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES = 4096;
|
|
5927
6226
|
var WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE = /(SECRET|TOKEN|KEY|PASSWORD)$/;
|
|
@@ -6205,7 +6504,6 @@ function* singleStepsOf(entry) {
|
|
|
6205
6504
|
return;
|
|
6206
6505
|
case "workflow":
|
|
6207
6506
|
yield entry;
|
|
6208
|
-
if (Array.isArray(entry.graph)) yield* singleStepsOf(entry.graph[1]);
|
|
6209
6507
|
return;
|
|
6210
6508
|
case "parallel":
|
|
6211
6509
|
case "conditional":
|
|
@@ -6364,7 +6662,10 @@ var assertPredicate = /* @__PURE__ */ __name((p, where) => {
|
|
|
6364
6662
|
}, "assertPredicate");
|
|
6365
6663
|
var assertRetry = /* @__PURE__ */ __name((r, id) => {
|
|
6366
6664
|
if (!r) return;
|
|
6367
|
-
if (
|
|
6665
|
+
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
6666
|
+
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
6667
|
+
throw new LuaWorkflowBuildError(over ? "cap-exceeded" : "invalid-envelope", `"${id}": ${workflowRetryMaxAttemptsMessage(r.maxAttempts)}`);
|
|
6668
|
+
}
|
|
6368
6669
|
if (r.backoff !== void 0 && !WORKFLOW_RETRY_BACKOFFS.includes(r.backoff)) throw new LuaWorkflowBuildError("backoff-invalid", `"${id}": retry.backoff must be ${WORKFLOW_RETRY_BACKOFFS.map((b) => `'${b}'`).join(" | ")}`);
|
|
6369
6670
|
if (r.maxBackoffSeconds !== void 0) {
|
|
6370
6671
|
if (r.backoff !== "exponential") throw new LuaWorkflowBuildError("backoff-invalid", `"${id}": retry.maxBackoffSeconds is only meaningful with backoff:'exponential'`);
|
|
@@ -6514,14 +6815,13 @@ function stepNodeOf(s) {
|
|
|
6514
6815
|
__name(stepNodeOf, "stepNodeOf");
|
|
6515
6816
|
function materializeEntry(entry, steps) {
|
|
6516
6817
|
const single = /* @__PURE__ */ __name((n2) => {
|
|
6517
|
-
if (n2.type === "step" && steps[n2.step.id])
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
n2.
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
};
|
|
6818
|
+
if (n2.type === "step" && steps[n2.step.id]) {
|
|
6819
|
+
const node = stepNodeOf(steps[n2.step.id]);
|
|
6820
|
+
return n2.input !== void 0 ? {
|
|
6821
|
+
...node,
|
|
6822
|
+
input: n2.input
|
|
6823
|
+
} : node;
|
|
6824
|
+
}
|
|
6525
6825
|
return n2;
|
|
6526
6826
|
}, "single");
|
|
6527
6827
|
switch (entry.type) {
|