lua-cli 3.32.4 → 3.32.6
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 +32 -1
- package/dist/api-exports.js +342 -60
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +1033 -497
- package/dist/index.js.map +1 -1
- package/dist/workflow-builder.d.ts +5 -0
- package/dist/workflow-builder.js +215 -8
- package/dist/workflow-builder.js.map +1 -1
- package/docs/CLI_REFERENCE.md +6 -2
- package/docs/README.md +2 -2
- package/docs/workflows/approvals.md +1 -1
- package/docs/workflows/limits.md +4 -0
- package/docs/workflows/testing-offline.md +1 -1
- package/package.json +3 -3
- package/template/package.json +1 -1
|
@@ -72,6 +72,11 @@ export declare interface ApprovalOptions {
|
|
|
72
72
|
/** default 'continue' (denial is data unless 'fail') */
|
|
73
73
|
onDeny?: WorkflowApprovalOnDeny;
|
|
74
74
|
businessHours?: WorkflowBusinessHours;
|
|
75
|
+
/**
|
|
76
|
+
* Optional — inferred `true` from a non-empty `editablePaths` (LUA-808 / LUA-825: the validator's `approvalEditable`
|
|
77
|
+
* rule, applied by the builder too); an explicit `false` beside paths is refused as contradictory. Absent with no
|
|
78
|
+
* paths ⇒ `false` (the approver decides, never edits).
|
|
79
|
+
*/
|
|
75
80
|
editable?: boolean;
|
|
76
81
|
/** grammar: `drafts`, `drafts[*]`, `drafts[*].body`, `drafts[3].body`, `summary.title` */
|
|
77
82
|
editablePaths?: string[];
|
package/dist/workflow-builder.js
CHANGED
|
@@ -735,6 +735,23 @@ function modelUnresolvedMessage(r) {
|
|
|
735
735
|
}
|
|
736
736
|
__name(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
737
737
|
__name2(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
738
|
+
function providerModelId(code) {
|
|
739
|
+
const requested = typeof code === "string" ? code.trim() : "";
|
|
740
|
+
if (!requested || isModelIdSentinel(requested)) return requested;
|
|
741
|
+
const slash = requested.indexOf("/");
|
|
742
|
+
if (slash <= 0) return requested;
|
|
743
|
+
const provider = requested.slice(0, slash).toLowerCase();
|
|
744
|
+
if (MODEL_ID_BYOK_PROVIDERS.includes(provider)) return requested;
|
|
745
|
+
return requested.slice(slash + 1);
|
|
746
|
+
}
|
|
747
|
+
__name(providerModelId, "providerModelId");
|
|
748
|
+
__name2(providerModelId, "providerModelId");
|
|
749
|
+
var MODEL_SNAPSHOT_SUFFIX = /(?:[-@](?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])|-(?:19|20)\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01]))$/;
|
|
750
|
+
function providerModelFamily(code) {
|
|
751
|
+
return providerModelId(code).toLowerCase().replace(MODEL_SNAPSHOT_SUFFIX, "");
|
|
752
|
+
}
|
|
753
|
+
__name(providerModelFamily, "providerModelFamily");
|
|
754
|
+
__name2(providerModelFamily, "providerModelFamily");
|
|
738
755
|
var IMPLICIT_MODEL_SELECTION_SOURCES = [
|
|
739
756
|
"workspace-default",
|
|
740
757
|
"platform-default"
|
|
@@ -1248,6 +1265,7 @@ var DeviceBindingSchema = z2.object({
|
|
|
1248
1265
|
}
|
|
1249
1266
|
});
|
|
1250
1267
|
var IdSchema = z2.string().min(1).max(256);
|
|
1268
|
+
var SESSION_AUTH_TIME_MAX_S = 4102444800;
|
|
1251
1269
|
var PrincipalDescriptorSchema = z2.object({
|
|
1252
1270
|
subjectType: SubjectTypeSchema,
|
|
1253
1271
|
subjectId: IdSchema
|
|
@@ -1296,7 +1314,8 @@ var GeneralPrincipalContextSchema = z2.object({
|
|
|
1296
1314
|
owner: PrincipalOwnerSchema.optional(),
|
|
1297
1315
|
compatibility: z2.object({
|
|
1298
1316
|
mode: z2.literal("legacy-owner-delegation")
|
|
1299
|
-
}).strict().optional()
|
|
1317
|
+
}).strict().optional(),
|
|
1318
|
+
authTime: z2.number().int().nonnegative().max(SESSION_AUTH_TIME_MAX_S).optional()
|
|
1300
1319
|
}).strict();
|
|
1301
1320
|
var DeviceCredentialPrincipalContextSchema = z2.object({
|
|
1302
1321
|
version: z2.literal(1),
|
|
@@ -1362,6 +1381,13 @@ function hasDeviceCredentialType(value3) {
|
|
|
1362
1381
|
}
|
|
1363
1382
|
__name(hasDeviceCredentialType, "hasDeviceCredentialType");
|
|
1364
1383
|
__name2(hasDeviceCredentialType, "hasDeviceCredentialType");
|
|
1384
|
+
function sessionAuthTime(context) {
|
|
1385
|
+
if (!context || context.credential.type !== "firstPartySession") return void 0;
|
|
1386
|
+
const authTime = context.authTime;
|
|
1387
|
+
return typeof authTime === "number" && Number.isInteger(authTime) && authTime >= 0 && authTime <= SESSION_AUTH_TIME_MAX_S ? authTime : void 0;
|
|
1388
|
+
}
|
|
1389
|
+
__name(sessionAuthTime, "sessionAuthTime");
|
|
1390
|
+
__name2(sessionAuthTime, "sessionAuthTime");
|
|
1365
1391
|
function isTypedApiKeyPrincipal(context) {
|
|
1366
1392
|
return context?.subject.subjectType === "apiKey" && context.credential.type === "apiKey" && !context.compatibility;
|
|
1367
1393
|
}
|
|
@@ -1764,6 +1790,47 @@ function scheduledWorkflowRunId(jobId, scheduledTime) {
|
|
|
1764
1790
|
}
|
|
1765
1791
|
__name(scheduledWorkflowRunId, "scheduledWorkflowRunId");
|
|
1766
1792
|
__name2(scheduledWorkflowRunId, "scheduledWorkflowRunId");
|
|
1793
|
+
var WORKFLOW_SCHEDULE_KEY_MAX = 128;
|
|
1794
|
+
function renderWorkflowScheduleKeyTemplate(template3, ctx) {
|
|
1795
|
+
if (!template3) return void 0;
|
|
1796
|
+
const read = /* @__PURE__ */ __name2((path) => path.split(".").reduce((o, k) => o && typeof o === "object" ? o[k] : void 0, ctx.input), "read");
|
|
1797
|
+
let unresolved = false;
|
|
1798
|
+
const out = template3.replace(/\$\{\s*([a-zA-Z0-9_.]+)\s*\}/g, (_m, expr) => {
|
|
1799
|
+
let v = "";
|
|
1800
|
+
if (expr === "scheduledTime") v = ctx.scheduledTime ?? "";
|
|
1801
|
+
else if (expr.startsWith("input.")) v = read(expr.slice("input.".length));
|
|
1802
|
+
const s = v === void 0 || v === null ? "" : String(v);
|
|
1803
|
+
if (s === "") unresolved = true;
|
|
1804
|
+
return s;
|
|
1805
|
+
});
|
|
1806
|
+
if (unresolved) return void 0;
|
|
1807
|
+
const key = out.slice(0, WORKFLOW_SCHEDULE_KEY_MAX);
|
|
1808
|
+
return key && /^[A-Za-z0-9:_\-.\/]+$/.test(key) ? key : void 0;
|
|
1809
|
+
}
|
|
1810
|
+
__name(renderWorkflowScheduleKeyTemplate, "renderWorkflowScheduleKeyTemplate");
|
|
1811
|
+
__name2(renderWorkflowScheduleKeyTemplate, "renderWorkflowScheduleKeyTemplate");
|
|
1812
|
+
var WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX = "sched:";
|
|
1813
|
+
function scheduledWorkflowIdempotencyKey(jobId, rendered) {
|
|
1814
|
+
const head = `${WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX}${jobId}:`;
|
|
1815
|
+
if (head.length + rendered.length <= WORKFLOW_SCHEDULE_KEY_MAX) return `${head}${rendered}`;
|
|
1816
|
+
const digest = stableKeyDigest(rendered);
|
|
1817
|
+
const room = WORKFLOW_SCHEDULE_KEY_MAX - head.length - digest.length - 1;
|
|
1818
|
+
return `${head}${rendered.slice(0, Math.max(0, room))}~${digest}`;
|
|
1819
|
+
}
|
|
1820
|
+
__name(scheduledWorkflowIdempotencyKey, "scheduledWorkflowIdempotencyKey");
|
|
1821
|
+
__name2(scheduledWorkflowIdempotencyKey, "scheduledWorkflowIdempotencyKey");
|
|
1822
|
+
function stableKeyDigest(s) {
|
|
1823
|
+
let a = 2166136261;
|
|
1824
|
+
let b = 84696351;
|
|
1825
|
+
for (let i = 0; i < s.length; i++) {
|
|
1826
|
+
const c = s.charCodeAt(i);
|
|
1827
|
+
a = Math.imul(a ^ c, 16777619);
|
|
1828
|
+
b = Math.imul(b ^ c, 16777619) ^ b >>> 13;
|
|
1829
|
+
}
|
|
1830
|
+
return (a >>> 0).toString(16).padStart(8, "0") + (b >>> 0).toString(16).padStart(8, "0");
|
|
1831
|
+
}
|
|
1832
|
+
__name(stableKeyDigest, "stableKeyDigest");
|
|
1833
|
+
__name2(stableKeyDigest, "stableKeyDigest");
|
|
1767
1834
|
var WORKFLOW_OPERATION_ID_PREFIX = "wf:";
|
|
1768
1835
|
function workflowOperationId(runId, stepId, billingEpoch) {
|
|
1769
1836
|
return `${WORKFLOW_OPERATION_ID_PREFIX}${runId}:${stepId}:${billingEpoch}`;
|
|
@@ -2512,6 +2579,75 @@ function extractSingleJsonValue(text) {
|
|
|
2512
2579
|
}
|
|
2513
2580
|
__name(extractSingleJsonValue, "extractSingleJsonValue");
|
|
2514
2581
|
__name2(extractSingleJsonValue, "extractSingleJsonValue");
|
|
2582
|
+
var DEFAULT_ON_AGENT_FEATURES = [
|
|
2583
|
+
"workflows",
|
|
2584
|
+
"workflowCompose",
|
|
2585
|
+
"observationalMemory"
|
|
2586
|
+
];
|
|
2587
|
+
function agentFeatureCatalogDefault(featureName) {
|
|
2588
|
+
return DEFAULT_ON_AGENT_FEATURES.includes(featureName);
|
|
2589
|
+
}
|
|
2590
|
+
__name(agentFeatureCatalogDefault, "agentFeatureCatalogDefault");
|
|
2591
|
+
__name2(agentFeatureCatalogDefault, "agentFeatureCatalogDefault");
|
|
2592
|
+
function hasExplicitFeatureActive(row) {
|
|
2593
|
+
return typeof row?.active === "boolean";
|
|
2594
|
+
}
|
|
2595
|
+
__name(hasExplicitFeatureActive, "hasExplicitFeatureActive");
|
|
2596
|
+
__name2(hasExplicitFeatureActive, "hasExplicitFeatureActive");
|
|
2597
|
+
function effectiveFeatureActive(row, catalogDefault) {
|
|
2598
|
+
return hasExplicitFeatureActive(row) ? row.active : catalogDefault;
|
|
2599
|
+
}
|
|
2600
|
+
__name(effectiveFeatureActive, "effectiveFeatureActive");
|
|
2601
|
+
__name2(effectiveFeatureActive, "effectiveFeatureActive");
|
|
2602
|
+
function resolveEffectiveFeature(row, catalogDefault) {
|
|
2603
|
+
return hasExplicitFeatureActive(row) ? {
|
|
2604
|
+
active: row.active,
|
|
2605
|
+
source: "agent",
|
|
2606
|
+
default: catalogDefault
|
|
2607
|
+
} : {
|
|
2608
|
+
active: catalogDefault,
|
|
2609
|
+
source: "default",
|
|
2610
|
+
default: catalogDefault
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2613
|
+
__name(resolveEffectiveFeature, "resolveEffectiveFeature");
|
|
2614
|
+
__name2(resolveEffectiveFeature, "resolveEffectiveFeature");
|
|
2615
|
+
function isFeatureRow(value3) {
|
|
2616
|
+
return typeof value3 === "object" && value3 !== null;
|
|
2617
|
+
}
|
|
2618
|
+
__name(isFeatureRow, "isFeatureRow");
|
|
2619
|
+
__name2(isFeatureRow, "isFeatureRow");
|
|
2620
|
+
function effectiveAgentFeatureRows(base, override) {
|
|
2621
|
+
const merged = /* @__PURE__ */ new Map();
|
|
2622
|
+
for (const [name, row] of Object.entries(base ?? {})) {
|
|
2623
|
+
if (isFeatureRow(row)) merged.set(name, {
|
|
2624
|
+
row,
|
|
2625
|
+
origin: "baseAgent"
|
|
2626
|
+
});
|
|
2627
|
+
}
|
|
2628
|
+
for (const [name, row] of Object.entries(override ?? {})) {
|
|
2629
|
+
if (isFeatureRow(row)) merged.set(name, {
|
|
2630
|
+
row,
|
|
2631
|
+
origin: "subAgent"
|
|
2632
|
+
});
|
|
2633
|
+
}
|
|
2634
|
+
return {
|
|
2635
|
+
rows: Object.fromEntries([
|
|
2636
|
+
...merged
|
|
2637
|
+
].map(([name, e]) => [
|
|
2638
|
+
name,
|
|
2639
|
+
e.row
|
|
2640
|
+
])),
|
|
2641
|
+
origins: Object.fromEntries([
|
|
2642
|
+
...merged
|
|
2643
|
+
].map(([name, e]) => [
|
|
2644
|
+
name,
|
|
2645
|
+
e.origin
|
|
2646
|
+
]))
|
|
2647
|
+
};
|
|
2648
|
+
}
|
|
2649
|
+
__name(effectiveAgentFeatureRows, "effectiveAgentFeatureRows");
|
|
2650
|
+
__name2(effectiveAgentFeatureRows, "effectiveAgentFeatureRows");
|
|
2515
2651
|
|
|
2516
2652
|
// ../workflow-graph/dist/index.mjs
|
|
2517
2653
|
import { createHash } from "crypto";
|
|
@@ -3114,7 +3250,7 @@ function fillHitl(node) {
|
|
|
3114
3250
|
if (a.onTimeout === void 0) a.onTimeout = "deny";
|
|
3115
3251
|
if (a.onDeny === void 0) a.onDeny = "continue";
|
|
3116
3252
|
if (a.excludeInitiator === void 0) a.excludeInitiator = false;
|
|
3117
|
-
if (a.editable === void 0) a.editable =
|
|
3253
|
+
if (a.editable === void 0) a.editable = approvalEditable(a);
|
|
3118
3254
|
return;
|
|
3119
3255
|
}
|
|
3120
3256
|
const w = node;
|
|
@@ -3416,7 +3552,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3416
3552
|
const id = singleId(node);
|
|
3417
3553
|
const unknown = unknownWorkflowRetryMembers(r);
|
|
3418
3554
|
if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path}.retry`, id);
|
|
3419
|
-
if (
|
|
3555
|
+
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
3420
3556
|
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
3421
3557
|
err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path}.retry.maxAttempts`, id);
|
|
3422
3558
|
}
|
|
@@ -3654,7 +3790,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3654
3790
|
}
|
|
3655
3791
|
const a = node;
|
|
3656
3792
|
checkId(a.id, path);
|
|
3657
|
-
if (a.approver === "creator" && a.excludeInitiator === true) {
|
|
3793
|
+
if ((a.approver ?? "creator") === "creator" && a.excludeInitiator === true) {
|
|
3658
3794
|
err("approver-excludes-only-candidate", "approver:'creator' with excludeInitiator:true always excludes the only candidate", path, a.id);
|
|
3659
3795
|
}
|
|
3660
3796
|
const editable = approvalEditable(a);
|
|
@@ -5218,6 +5354,7 @@ __name3(runErrorIssues, "runErrorIssues");
|
|
|
5218
5354
|
function runNextAction(run) {
|
|
5219
5355
|
if (isTerminalRunStatus(run.status)) return "none";
|
|
5220
5356
|
if (run.status === "suspended" && run.gate?.kind === "budget") return "raise_budget";
|
|
5357
|
+
if (run.status === "suspended" && run.gate?.kind === "billing") return "top_up";
|
|
5221
5358
|
if (!run.cancel?.requestedAt) return "none";
|
|
5222
5359
|
const forceAt = run.cancel.forceAfter ?? run.cancel.requestedAt + FORCE_CANCEL_STALE_MS;
|
|
5223
5360
|
return Date.now() >= forceAt ? "force" : "cancel_again";
|
|
@@ -5254,6 +5391,16 @@ function runCountsFromStepStatuses(statuses) {
|
|
|
5254
5391
|
}
|
|
5255
5392
|
__name(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
5256
5393
|
__name3(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
5394
|
+
function isBillingHeldStep(row) {
|
|
5395
|
+
return row.status === "ready" && row.billingHold === true;
|
|
5396
|
+
}
|
|
5397
|
+
__name(isBillingHeldStep, "isBillingHeldStep");
|
|
5398
|
+
__name3(isBillingHeldStep, "isBillingHeldStep");
|
|
5399
|
+
function stepEffectiveStatus(row) {
|
|
5400
|
+
return isBillingHeldStep(row) ? "suspended" : row.status;
|
|
5401
|
+
}
|
|
5402
|
+
__name(stepEffectiveStatus, "stepEffectiveStatus");
|
|
5403
|
+
__name3(stepEffectiveStatus, "stepEffectiveStatus");
|
|
5257
5404
|
var n = /* @__PURE__ */ __name3((v) => typeof v === "number" && Number.isFinite(v) ? v : 0, "n");
|
|
5258
5405
|
function runCounts(counts) {
|
|
5259
5406
|
const c = counts ?? {};
|
|
@@ -6091,6 +6238,63 @@ function rebaseItemPointer(pointer, itemsPath, index) {
|
|
|
6091
6238
|
}
|
|
6092
6239
|
__name(rebaseItemPointer, "rebaseItemPointer");
|
|
6093
6240
|
__name3(rebaseItemPointer, "rebaseItemPointer");
|
|
6241
|
+
var WORKFLOW_SCHEDULE_TYPES = [
|
|
6242
|
+
"cron",
|
|
6243
|
+
"interval",
|
|
6244
|
+
"once"
|
|
6245
|
+
];
|
|
6246
|
+
var WORKFLOW_SCHEDULE_SHAPE_ISSUE = "schedule-shape-invalid";
|
|
6247
|
+
var WORKFLOW_SCHEDULE_SHAPES_HINT = "`schedule` must be one of { type: 'cron', expression: '<5-field cron>', timezone?: '<IANA tz>' } | { type: 'interval', seconds: <n> } | { type: 'once', executeAt: '<ISO-8601>' }";
|
|
6248
|
+
var isObject = /* @__PURE__ */ __name3((v) => typeof v === "object" && v !== null && !Array.isArray(v), "isObject");
|
|
6249
|
+
function validateWorkflowSchedule(schedule, path = "/schedule") {
|
|
6250
|
+
if (schedule === void 0 || schedule === null) return [];
|
|
6251
|
+
const issue = /* @__PURE__ */ __name3((at, detail) => [
|
|
6252
|
+
{
|
|
6253
|
+
code: WORKFLOW_SCHEDULE_SHAPE_ISSUE,
|
|
6254
|
+
severity: "error",
|
|
6255
|
+
path: at,
|
|
6256
|
+
message: `${detail} \u2014 ${WORKFLOW_SCHEDULE_SHAPES_HINT}`
|
|
6257
|
+
}
|
|
6258
|
+
], "issue");
|
|
6259
|
+
if (!isObject(schedule)) {
|
|
6260
|
+
return issue(path, `\`schedule\` is ${Array.isArray(schedule) ? "an array" : `a ${typeof schedule}`}, not a typed schedule object`);
|
|
6261
|
+
}
|
|
6262
|
+
const type = schedule.type;
|
|
6263
|
+
if (type === void 0) {
|
|
6264
|
+
const keys = Object.keys(schedule);
|
|
6265
|
+
const seen = keys.length ? ` (got { ${keys.join(", ")} })` : " (got {})";
|
|
6266
|
+
return issue(path, `\`schedule\` carries no \`type\` discriminator${seen}`);
|
|
6267
|
+
}
|
|
6268
|
+
if (typeof type !== "string" || !WORKFLOW_SCHEDULE_TYPES.includes(type)) {
|
|
6269
|
+
return issue(path, `\`schedule.type\` ${JSON.stringify(type)} is not one of ${WORKFLOW_SCHEDULE_TYPES.map((t) => `'${t}'`).join(" | ")}`);
|
|
6270
|
+
}
|
|
6271
|
+
switch (type) {
|
|
6272
|
+
case "cron": {
|
|
6273
|
+
if (typeof schedule.expression !== "string" || schedule.expression.trim().length === 0) {
|
|
6274
|
+
return issue(`${path}/expression`, "a { type: 'cron' } schedule needs a non-empty string `expression`");
|
|
6275
|
+
}
|
|
6276
|
+
if (schedule.timezone !== void 0 && (typeof schedule.timezone !== "string" || schedule.timezone.length === 0)) {
|
|
6277
|
+
return issue(`${path}/timezone`, "a { type: 'cron' } schedule's `timezone`, when given, is a non-empty IANA string");
|
|
6278
|
+
}
|
|
6279
|
+
return [];
|
|
6280
|
+
}
|
|
6281
|
+
case "interval": {
|
|
6282
|
+
const s = schedule.seconds;
|
|
6283
|
+
if (typeof s !== "number" || !Number.isFinite(s) || s <= 0) {
|
|
6284
|
+
return issue(`${path}/seconds`, "a { type: 'interval' } schedule needs a positive number `seconds`");
|
|
6285
|
+
}
|
|
6286
|
+
return [];
|
|
6287
|
+
}
|
|
6288
|
+
case "once": {
|
|
6289
|
+
if (typeof schedule.executeAt !== "string" || Number.isNaN(Date.parse(schedule.executeAt))) {
|
|
6290
|
+
return issue(`${path}/executeAt`, "a { type: 'once' } schedule needs an ISO-8601 string `executeAt`");
|
|
6291
|
+
}
|
|
6292
|
+
return [];
|
|
6293
|
+
}
|
|
6294
|
+
}
|
|
6295
|
+
}
|
|
6296
|
+
__name(validateWorkflowSchedule, "validateWorkflowSchedule");
|
|
6297
|
+
__name3(validateWorkflowSchedule, "validateWorkflowSchedule");
|
|
6094
6298
|
var WORKFLOW_ENV_OVERLAY_MAX_KEYS = 64;
|
|
6095
6299
|
var WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES = 4096;
|
|
6096
6300
|
var WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE = /(SECRET|TOKEN|KEY|PASSWORD)$/;
|
|
@@ -6532,7 +6736,7 @@ var assertPredicate = /* @__PURE__ */ __name((p, where) => {
|
|
|
6532
6736
|
}, "assertPredicate");
|
|
6533
6737
|
var assertRetry = /* @__PURE__ */ __name((r, id) => {
|
|
6534
6738
|
if (!r) return;
|
|
6535
|
-
if (
|
|
6739
|
+
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
6536
6740
|
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
6537
6741
|
throw new LuaWorkflowBuildError(over ? "cap-exceeded" : "invalid-envelope", `"${id}": ${workflowRetryMaxAttemptsMessage(r.maxAttempts)}`);
|
|
6538
6742
|
}
|
|
@@ -7127,9 +7331,12 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
|
|
|
7127
7331
|
if (opts.approver === "creator" && opts.excludeInitiator === true) {
|
|
7128
7332
|
throw new LuaWorkflowBuildError("approver-excludes-only-candidate", `"${id}": approver:'creator' with excludeInitiator:true always excludes the only candidate`);
|
|
7129
7333
|
}
|
|
7130
|
-
|
|
7131
|
-
if (
|
|
7132
|
-
|
|
7334
|
+
const editable = approvalEditable(opts);
|
|
7335
|
+
if (opts.fourEyes !== void 0 && !editable) throw new LuaWorkflowBuildError("four-eyes-requires-editable", `"${id}": \`fourEyes\` requires editable:true`);
|
|
7336
|
+
if (opts.editable === false && Array.isArray(opts.editablePaths) && opts.editablePaths.length > 0) {
|
|
7337
|
+
throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": \`editablePaths\` beside editable:false is contradictory \u2014 drop the paths or set editable:true`);
|
|
7338
|
+
} else if ((opts.editablePaths !== void 0 || opts.editedPayloadSchema !== void 0) && !editable) {
|
|
7339
|
+
throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": \`editablePaths\` / \`editedPayloadSchema\` require editable:true (a non-empty editablePaths implies it)`);
|
|
7133
7340
|
}
|
|
7134
7341
|
for (const p of opts.editablePaths ?? []) {
|
|
7135
7342
|
if (!EDITABLE_PATH_RE2.test(p)) throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": editablePaths entry "${p}" is outside the grammar seg(.seg)* with [*]/[n] selectors`);
|