lua-cli 3.32.4 → 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 +11 -1
- package/dist/api-exports.js +208 -49
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +869 -481
- package/dist/index.js.map +1 -1
- package/dist/workflow-builder.js +133 -3
- package/dist/workflow-builder.js.map +1 -1
- package/docs/CLI_REFERENCE.md +6 -2
- package/docs/README.md +2 -2
- 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
package/dist/api-exports.d.ts
CHANGED
|
@@ -7314,11 +7314,21 @@ declare interface WorkflowRun {
|
|
|
7314
7314
|
parentRunId?: string;
|
|
7315
7315
|
correlationKey?: string;
|
|
7316
7316
|
tags?: string[];
|
|
7317
|
+
/** R4 `gate` (02 §2.4). LUA-788: a `kind:'billing'` gate names the wallet's refusal (`code`), the held step and its expiry. */
|
|
7317
7318
|
gate?: {
|
|
7318
7319
|
kind: string;
|
|
7319
7320
|
reason?: string;
|
|
7320
|
-
since?: string;
|
|
7321
|
+
since?: string | number;
|
|
7322
|
+
code?: string;
|
|
7323
|
+
stepId?: string;
|
|
7324
|
+
expiresAt?: number;
|
|
7321
7325
|
};
|
|
7326
|
+
/**
|
|
7327
|
+
* Server-decided (09 §9.6): `raise_budget` on a budget gate (LUA-665), `top_up` on a billing gate (LUA-788 — the
|
|
7328
|
+
* wallet clears it; the engine re-checks and resumes on its own), `cancel_again` / `force` under a pending cancel,
|
|
7329
|
+
* else `none`. Absent on an older server.
|
|
7330
|
+
*/
|
|
7331
|
+
nextAction?: 'cancel_again' | 'force' | 'none' | 'raise_budget' | 'top_up';
|
|
7322
7332
|
/**
|
|
7323
7333
|
* The pending / audited cancel request (`runCancelView`): who asked and when; `wall` when it was the run wall's
|
|
7324
7334
|
* own (LUA-686); LUA-704: `forcedBy` / `forcedAt` / `forceReason` on a forced terminal (`abandoned`, or
|
package/dist/api-exports.js
CHANGED
|
@@ -544,6 +544,11 @@ function isDeviceCredentialPrincipal(context) {
|
|
|
544
544
|
function hasDeviceCredentialType(value3) {
|
|
545
545
|
return DeviceCredentialClaimSchema.safeParse(value3).success;
|
|
546
546
|
}
|
|
547
|
+
function sessionAuthTime(context) {
|
|
548
|
+
if (!context || context.credential.type !== "firstPartySession") return void 0;
|
|
549
|
+
const authTime = context.authTime;
|
|
550
|
+
return typeof authTime === "number" && Number.isInteger(authTime) && authTime >= 0 && authTime <= SESSION_AUTH_TIME_MAX_S ? authTime : void 0;
|
|
551
|
+
}
|
|
547
552
|
function isTypedApiKeyPrincipal(context) {
|
|
548
553
|
return context?.subject.subjectType === "apiKey" && context.credential.type === "apiKey" && !context.compatibility;
|
|
549
554
|
}
|
|
@@ -716,6 +721,39 @@ function scheduledWorkflowRunId(jobId, scheduledTime) {
|
|
|
716
721
|
const key = typeof scheduledTime === "number" ? String(scheduledTime) : scheduledTimeKey(scheduledTime);
|
|
717
722
|
return `${WORKFLOW_SCHEDULED_RUN_ID_PREFIX}${jobId}_${key}`;
|
|
718
723
|
}
|
|
724
|
+
function renderWorkflowScheduleKeyTemplate(template3, ctx) {
|
|
725
|
+
if (!template3) return void 0;
|
|
726
|
+
const read = /* @__PURE__ */ __name2((path3) => path3.split(".").reduce((o, k) => o && typeof o === "object" ? o[k] : void 0, ctx.input), "read");
|
|
727
|
+
let unresolved = false;
|
|
728
|
+
const out = template3.replace(/\$\{\s*([a-zA-Z0-9_.]+)\s*\}/g, (_m, expr) => {
|
|
729
|
+
let v = "";
|
|
730
|
+
if (expr === "scheduledTime") v = ctx.scheduledTime ?? "";
|
|
731
|
+
else if (expr.startsWith("input.")) v = read(expr.slice("input.".length));
|
|
732
|
+
const s = v === void 0 || v === null ? "" : String(v);
|
|
733
|
+
if (s === "") unresolved = true;
|
|
734
|
+
return s;
|
|
735
|
+
});
|
|
736
|
+
if (unresolved) return void 0;
|
|
737
|
+
const key = out.slice(0, WORKFLOW_SCHEDULE_KEY_MAX);
|
|
738
|
+
return key && /^[A-Za-z0-9:_\-.\/]+$/.test(key) ? key : void 0;
|
|
739
|
+
}
|
|
740
|
+
function scheduledWorkflowIdempotencyKey(jobId, rendered) {
|
|
741
|
+
const head = `${WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX}${jobId}:`;
|
|
742
|
+
if (head.length + rendered.length <= WORKFLOW_SCHEDULE_KEY_MAX) return `${head}${rendered}`;
|
|
743
|
+
const digest = stableKeyDigest(rendered);
|
|
744
|
+
const room = WORKFLOW_SCHEDULE_KEY_MAX - head.length - digest.length - 1;
|
|
745
|
+
return `${head}${rendered.slice(0, Math.max(0, room))}~${digest}`;
|
|
746
|
+
}
|
|
747
|
+
function stableKeyDigest(s) {
|
|
748
|
+
let a = 2166136261;
|
|
749
|
+
let b = 84696351;
|
|
750
|
+
for (let i = 0; i < s.length; i++) {
|
|
751
|
+
const c = s.charCodeAt(i);
|
|
752
|
+
a = Math.imul(a ^ c, 16777619);
|
|
753
|
+
b = Math.imul(b ^ c, 16777619) ^ b >>> 13;
|
|
754
|
+
}
|
|
755
|
+
return (a >>> 0).toString(16).padStart(8, "0") + (b >>> 0).toString(16).padStart(8, "0");
|
|
756
|
+
}
|
|
719
757
|
function workflowOperationId(runId, stepId, billingEpoch) {
|
|
720
758
|
return `${WORKFLOW_OPERATION_ID_PREFIX}${runId}:${stepId}:${billingEpoch}`;
|
|
721
759
|
}
|
|
@@ -1019,7 +1057,59 @@ function extractSingleJsonValue(text) {
|
|
|
1019
1057
|
};
|
|
1020
1058
|
}
|
|
1021
1059
|
}
|
|
1022
|
-
|
|
1060
|
+
function agentFeatureCatalogDefault(featureName) {
|
|
1061
|
+
return DEFAULT_ON_AGENT_FEATURES.includes(featureName);
|
|
1062
|
+
}
|
|
1063
|
+
function hasExplicitFeatureActive(row) {
|
|
1064
|
+
return typeof row?.active === "boolean";
|
|
1065
|
+
}
|
|
1066
|
+
function effectiveFeatureActive(row, catalogDefault) {
|
|
1067
|
+
return hasExplicitFeatureActive(row) ? row.active : catalogDefault;
|
|
1068
|
+
}
|
|
1069
|
+
function resolveEffectiveFeature(row, catalogDefault) {
|
|
1070
|
+
return hasExplicitFeatureActive(row) ? {
|
|
1071
|
+
active: row.active,
|
|
1072
|
+
source: "agent",
|
|
1073
|
+
default: catalogDefault
|
|
1074
|
+
} : {
|
|
1075
|
+
active: catalogDefault,
|
|
1076
|
+
source: "default",
|
|
1077
|
+
default: catalogDefault
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
function isFeatureRow(value3) {
|
|
1081
|
+
return typeof value3 === "object" && value3 !== null;
|
|
1082
|
+
}
|
|
1083
|
+
function effectiveAgentFeatureRows(base, override) {
|
|
1084
|
+
const merged = /* @__PURE__ */ new Map();
|
|
1085
|
+
for (const [name, row] of Object.entries(base ?? {})) {
|
|
1086
|
+
if (isFeatureRow(row)) merged.set(name, {
|
|
1087
|
+
row,
|
|
1088
|
+
origin: "baseAgent"
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
for (const [name, row] of Object.entries(override ?? {})) {
|
|
1092
|
+
if (isFeatureRow(row)) merged.set(name, {
|
|
1093
|
+
row,
|
|
1094
|
+
origin: "subAgent"
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
return {
|
|
1098
|
+
rows: Object.fromEntries([
|
|
1099
|
+
...merged
|
|
1100
|
+
].map(([name, e]) => [
|
|
1101
|
+
name,
|
|
1102
|
+
e.row
|
|
1103
|
+
])),
|
|
1104
|
+
origins: Object.fromEntries([
|
|
1105
|
+
...merged
|
|
1106
|
+
].map(([name, e]) => [
|
|
1107
|
+
name,
|
|
1108
|
+
e.origin
|
|
1109
|
+
]))
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
var __defProp2, __name2, CHANNEL_SEND_CHANNELS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, MODEL_ID_BYOK_PROVIDERS, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, TEMPLATE_TRIGGER_URL_ENV_PREFIX, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, IdSchema, SESSION_AUTH_TIME_MAX_S, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema, SYSTEM_USER_PREFIX, WORKFLOW_RUN_IN_FLIGHT, WORKFLOW_RUN_IDLE, WORKFLOW_RUN_TERMINAL, WORKFLOW_RUN_STATUSES, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, ARCHIVE_WINDOW_MARGIN_DAYS, WORKFLOW_ORG_PURGING_TTL_S, WORKFLOW_ORG_PURGE_FORCE_AFTER_MS, IDEMPOTENCY_HOLDING_STATUSES, WORKFLOW_SCHEDULED_RUN_ID_PREFIX, CLOUD_TASK_RUN_ID_PREFIX, WORKFLOW_SCHEDULE_KEY_MAX, WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, WORKFLOW_RETRY_BACKOFFS, WORKFLOW_RETRY_MIN_ATTEMPTS, WORKFLOW_RETRY_POLICY_KEYS, WORKFLOW_RETRY_MAX_ATTEMPTS, WORKFLOW_RETRY_ENGINE_KEYS, WORKFLOW_JOB_RESOURCES, WORKFLOW_SIDE_EFFECTS, WORKFLOW_JOB_RANGES, WORKFLOW_JOB_RANGE_MEMBERS, WORKFLOW_SINGLE_STEP_TYPES, WORKFLOW_HITL_ENTRY_TYPES, WORKFLOW_ARM_ENTRY_TYPES, WORKFLOW_HITL_ARM_CONTAINERS, WORKFLOW_GRAPH_ENTRY_STEP_KINDS, WORKFLOW_ARM_ENTRY_STEP_KINDS, WORKFLOW_BUDGET_MAX_DURATION_SECONDS, REDACTED_PLACEHOLDER, PROVIDER_MESSAGE_MAX_CHARS, ERROR_MESSAGE_MAX_CHARS, SECRET_LITERAL_PATTERNS, SECRET_NAME, SECRET_PAIR_PATTERNS, GROUP_COUNT, WORKFLOW_SECRET_KEY_RE, WORKFLOW_RESERVED_SECRET_KEYS, SCRUB_INPUT_MAX_CHARS, SCRUB_CUT_BACKOFF_CHARS, WORKFLOW_AUDIT_EVENTS, WORKFLOW_AUDIT_METADATA_MAX_BYTES, INDENT, WRAP_WIDTH, NOUNS, GET_TOOL_NAMES, PREAMBLE, WORKFLOW_APPROVAL_OUTPUT_DECISIONS, WORKFLOW_APPROVAL_OUTPUT_SCHEMA, JSON_FENCE_RE, DEFAULT_ON_AGENT_FEATURES;
|
|
1023
1113
|
var init_dist = __esm({
|
|
1024
1114
|
"../shared-types/dist/index.mjs"() {
|
|
1025
1115
|
"use strict";
|
|
@@ -1764,6 +1854,7 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
1764
1854
|
}
|
|
1765
1855
|
});
|
|
1766
1856
|
IdSchema = z2.string().min(1).max(256);
|
|
1857
|
+
SESSION_AUTH_TIME_MAX_S = 4102444800;
|
|
1767
1858
|
PrincipalDescriptorSchema = z2.object({
|
|
1768
1859
|
subjectType: SubjectTypeSchema,
|
|
1769
1860
|
subjectId: IdSchema
|
|
@@ -1812,7 +1903,8 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
1812
1903
|
owner: PrincipalOwnerSchema.optional(),
|
|
1813
1904
|
compatibility: z2.object({
|
|
1814
1905
|
mode: z2.literal("legacy-owner-delegation")
|
|
1815
|
-
}).strict().optional()
|
|
1906
|
+
}).strict().optional(),
|
|
1907
|
+
authTime: z2.number().int().nonnegative().max(SESSION_AUTH_TIME_MAX_S).optional()
|
|
1816
1908
|
}).strict();
|
|
1817
1909
|
DeviceCredentialPrincipalContextSchema = z2.object({
|
|
1818
1910
|
version: z2.literal(1),
|
|
@@ -1868,6 +1960,8 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
1868
1960
|
}).passthrough();
|
|
1869
1961
|
__name(hasDeviceCredentialType, "hasDeviceCredentialType");
|
|
1870
1962
|
__name2(hasDeviceCredentialType, "hasDeviceCredentialType");
|
|
1963
|
+
__name(sessionAuthTime, "sessionAuthTime");
|
|
1964
|
+
__name2(sessionAuthTime, "sessionAuthTime");
|
|
1871
1965
|
__name(isTypedApiKeyPrincipal, "isTypedApiKeyPrincipal");
|
|
1872
1966
|
__name2(isTypedApiKeyPrincipal, "isTypedApiKeyPrincipal");
|
|
1873
1967
|
__name(typedApiKeyPrincipalId, "typedApiKeyPrincipalId");
|
|
@@ -2099,6 +2193,14 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
2099
2193
|
__name2(isScheduledWorkflowRunId, "isScheduledWorkflowRunId");
|
|
2100
2194
|
__name(scheduledWorkflowRunId, "scheduledWorkflowRunId");
|
|
2101
2195
|
__name2(scheduledWorkflowRunId, "scheduledWorkflowRunId");
|
|
2196
|
+
WORKFLOW_SCHEDULE_KEY_MAX = 128;
|
|
2197
|
+
__name(renderWorkflowScheduleKeyTemplate, "renderWorkflowScheduleKeyTemplate");
|
|
2198
|
+
__name2(renderWorkflowScheduleKeyTemplate, "renderWorkflowScheduleKeyTemplate");
|
|
2199
|
+
WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX = "sched:";
|
|
2200
|
+
__name(scheduledWorkflowIdempotencyKey, "scheduledWorkflowIdempotencyKey");
|
|
2201
|
+
__name2(scheduledWorkflowIdempotencyKey, "scheduledWorkflowIdempotencyKey");
|
|
2202
|
+
__name(stableKeyDigest, "stableKeyDigest");
|
|
2203
|
+
__name2(stableKeyDigest, "stableKeyDigest");
|
|
2102
2204
|
WORKFLOW_OPERATION_ID_PREFIX = "wf:";
|
|
2103
2205
|
__name(workflowOperationId, "workflowOperationId");
|
|
2104
2206
|
__name2(workflowOperationId, "workflowOperationId");
|
|
@@ -2544,6 +2646,23 @@ listed here; never invent a target.`;
|
|
|
2544
2646
|
JSON_FENCE_RE = /```(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n?```/g;
|
|
2545
2647
|
__name(extractSingleJsonValue, "extractSingleJsonValue");
|
|
2546
2648
|
__name2(extractSingleJsonValue, "extractSingleJsonValue");
|
|
2649
|
+
DEFAULT_ON_AGENT_FEATURES = [
|
|
2650
|
+
"workflows",
|
|
2651
|
+
"workflowCompose",
|
|
2652
|
+
"observationalMemory"
|
|
2653
|
+
];
|
|
2654
|
+
__name(agentFeatureCatalogDefault, "agentFeatureCatalogDefault");
|
|
2655
|
+
__name2(agentFeatureCatalogDefault, "agentFeatureCatalogDefault");
|
|
2656
|
+
__name(hasExplicitFeatureActive, "hasExplicitFeatureActive");
|
|
2657
|
+
__name2(hasExplicitFeatureActive, "hasExplicitFeatureActive");
|
|
2658
|
+
__name(effectiveFeatureActive, "effectiveFeatureActive");
|
|
2659
|
+
__name2(effectiveFeatureActive, "effectiveFeatureActive");
|
|
2660
|
+
__name(resolveEffectiveFeature, "resolveEffectiveFeature");
|
|
2661
|
+
__name2(resolveEffectiveFeature, "resolveEffectiveFeature");
|
|
2662
|
+
__name(isFeatureRow, "isFeatureRow");
|
|
2663
|
+
__name2(isFeatureRow, "isFeatureRow");
|
|
2664
|
+
__name(effectiveAgentFeatureRows, "effectiveAgentFeatureRows");
|
|
2665
|
+
__name2(effectiveAgentFeatureRows, "effectiveAgentFeatureRows");
|
|
2547
2666
|
}
|
|
2548
2667
|
});
|
|
2549
2668
|
|
|
@@ -3176,7 +3295,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3176
3295
|
const id = singleId(node);
|
|
3177
3296
|
const unknown = unknownWorkflowRetryMembers(r);
|
|
3178
3297
|
if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path3}.retry`, id);
|
|
3179
|
-
if (
|
|
3298
|
+
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
3180
3299
|
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
3181
3300
|
err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path3}.retry.maxAttempts`, id);
|
|
3182
3301
|
}
|
|
@@ -4717,6 +4836,7 @@ function runErrorIssues(issues) {
|
|
|
4717
4836
|
function runNextAction(run) {
|
|
4718
4837
|
if (isTerminalRunStatus(run.status)) return "none";
|
|
4719
4838
|
if (run.status === "suspended" && run.gate?.kind === "budget") return "raise_budget";
|
|
4839
|
+
if (run.status === "suspended" && run.gate?.kind === "billing") return "top_up";
|
|
4720
4840
|
if (!run.cancel?.requestedAt) return "none";
|
|
4721
4841
|
const forceAt = run.cancel.forceAfter ?? run.cancel.requestedAt + FORCE_CANCEL_STALE_MS;
|
|
4722
4842
|
return Date.now() >= forceAt ? "force" : "cancel_again";
|
|
@@ -4744,6 +4864,12 @@ function runCountsFromStepStatuses(statuses) {
|
|
|
4744
4864
|
for (const s of statuses) tally[s] = (tally[s] ?? 0) + 1;
|
|
4745
4865
|
return runCountsFromStatusTally(tally);
|
|
4746
4866
|
}
|
|
4867
|
+
function isBillingHeldStep(row) {
|
|
4868
|
+
return row.status === "ready" && row.billingHold === true;
|
|
4869
|
+
}
|
|
4870
|
+
function stepEffectiveStatus(row) {
|
|
4871
|
+
return isBillingHeldStep(row) ? "suspended" : row.status;
|
|
4872
|
+
}
|
|
4747
4873
|
function runCounts(counts) {
|
|
4748
4874
|
const c = counts ?? {};
|
|
4749
4875
|
const rawInFlight = c.dispatched !== void 0 || c.claimed !== void 0 || c.running !== void 0 || c.cancellation_requested !== void 0;
|
|
@@ -6274,6 +6400,10 @@ var init_dist2 = __esm({
|
|
|
6274
6400
|
__name3(runCountsFromStatusTally, "runCountsFromStatusTally");
|
|
6275
6401
|
__name(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
6276
6402
|
__name3(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
6403
|
+
__name(isBillingHeldStep, "isBillingHeldStep");
|
|
6404
|
+
__name3(isBillingHeldStep, "isBillingHeldStep");
|
|
6405
|
+
__name(stepEffectiveStatus, "stepEffectiveStatus");
|
|
6406
|
+
__name3(stepEffectiveStatus, "stepEffectiveStatus");
|
|
6277
6407
|
n = /* @__PURE__ */ __name3((v) => typeof v === "number" && Number.isFinite(v) ? v : 0, "n");
|
|
6278
6408
|
__name(runCounts, "runCounts");
|
|
6279
6409
|
__name3(runCounts, "runCounts");
|
|
@@ -6691,7 +6821,7 @@ var init_workflow = __esm({
|
|
|
6691
6821
|
}, "assertPredicate");
|
|
6692
6822
|
assertRetry = /* @__PURE__ */ __name((r, id) => {
|
|
6693
6823
|
if (!r) return;
|
|
6694
|
-
if (
|
|
6824
|
+
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
6695
6825
|
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
6696
6826
|
throw new LuaWorkflowBuildError(over ? "cap-exceeded" : "invalid-envelope", `"${id}": ${workflowRetryMaxAttemptsMessage(r.maxAttempts)}`);
|
|
6697
6827
|
}
|
|
@@ -7492,7 +7622,10 @@ function classifyCliError(error) {
|
|
|
7492
7622
|
code: error.code,
|
|
7493
7623
|
exitCode: error.exitCode,
|
|
7494
7624
|
message: error.message,
|
|
7495
|
-
hint: error.hint
|
|
7625
|
+
hint: error.hint,
|
|
7626
|
+
statusCode: error.statusCode,
|
|
7627
|
+
serverCode: error.serverCode,
|
|
7628
|
+
issues: error.issues
|
|
7496
7629
|
};
|
|
7497
7630
|
}
|
|
7498
7631
|
if (AuthenticationError.isAuthenticationError(error)) {
|
|
@@ -7514,30 +7647,36 @@ function classifyCliError(error) {
|
|
|
7514
7647
|
}
|
|
7515
7648
|
const status = numericStatus(e);
|
|
7516
7649
|
if (status !== void 0) {
|
|
7650
|
+
const statusCode = status;
|
|
7517
7651
|
if (status === 401) return {
|
|
7518
7652
|
code: "auth",
|
|
7519
7653
|
exitCode: CLI_EXIT.AUTH,
|
|
7520
|
-
message
|
|
7654
|
+
message,
|
|
7655
|
+
statusCode
|
|
7521
7656
|
};
|
|
7522
7657
|
if (status === 403) return {
|
|
7523
7658
|
code: "forbidden",
|
|
7524
7659
|
exitCode: CLI_EXIT.FORBIDDEN,
|
|
7525
|
-
message
|
|
7660
|
+
message,
|
|
7661
|
+
statusCode
|
|
7526
7662
|
};
|
|
7527
7663
|
if (status === 404) return {
|
|
7528
7664
|
code: "not_found",
|
|
7529
7665
|
exitCode: CLI_EXIT.NOT_FOUND,
|
|
7530
|
-
message
|
|
7666
|
+
message,
|
|
7667
|
+
statusCode
|
|
7531
7668
|
};
|
|
7532
7669
|
if (status >= 400 && status < 500) return {
|
|
7533
7670
|
code: `http_${status}`,
|
|
7534
7671
|
exitCode: CLI_EXIT.FORBIDDEN,
|
|
7535
|
-
message
|
|
7672
|
+
message,
|
|
7673
|
+
statusCode
|
|
7536
7674
|
};
|
|
7537
7675
|
if (status >= 500 || status === 0) return {
|
|
7538
7676
|
code: "unavailable",
|
|
7539
7677
|
exitCode: CLI_EXIT.UNAVAILABLE,
|
|
7540
|
-
message
|
|
7678
|
+
message,
|
|
7679
|
+
statusCode
|
|
7541
7680
|
};
|
|
7542
7681
|
}
|
|
7543
7682
|
const causeCode = e.cause?.code;
|
|
@@ -7578,6 +7717,8 @@ var init_cli_error = __esm({
|
|
|
7578
7717
|
exitCode;
|
|
7579
7718
|
hint;
|
|
7580
7719
|
statusCode;
|
|
7720
|
+
serverCode;
|
|
7721
|
+
issues;
|
|
7581
7722
|
constructor(code, message, options = {}) {
|
|
7582
7723
|
super(message);
|
|
7583
7724
|
this.name = "CliError";
|
|
@@ -7585,6 +7726,8 @@ var init_cli_error = __esm({
|
|
|
7585
7726
|
this.exitCode = options.exitCode ?? CLI_EXIT.ERROR;
|
|
7586
7727
|
this.hint = options.hint;
|
|
7587
7728
|
this.statusCode = options.statusCode;
|
|
7729
|
+
this.serverCode = options.serverCode;
|
|
7730
|
+
this.issues = options.issues?.length ? options.issues : void 0;
|
|
7588
7731
|
if (Error.captureStackTrace) Error.captureStackTrace(this, _CliError);
|
|
7589
7732
|
}
|
|
7590
7733
|
/** Bad arguments, an unknown action, no project — exit 2. */
|
|
@@ -7617,7 +7760,7 @@ var init_cli_error = __esm({
|
|
|
7617
7760
|
* A command that reads `response.error.statusCode` throws through here, so `lua logs` on a 503 exits 11 like
|
|
7618
7761
|
* every other verb instead of printing the message itself and then throwing an exit-1 `Error`.
|
|
7619
7762
|
*/
|
|
7620
|
-
static fromStatus(statusCode, message, hint) {
|
|
7763
|
+
static fromStatus(statusCode, message, hint, detail = {}) {
|
|
7621
7764
|
const reported = classifyCliError(Object.assign(new Error(message), {
|
|
7622
7765
|
statusCode
|
|
7623
7766
|
}));
|
|
@@ -7625,7 +7768,9 @@ var init_cli_error = __esm({
|
|
|
7625
7768
|
return new _CliError(reported.code, message, {
|
|
7626
7769
|
exitCode: reported.exitCode,
|
|
7627
7770
|
hint: hint ?? classHint,
|
|
7628
|
-
statusCode
|
|
7771
|
+
statusCode,
|
|
7772
|
+
serverCode: detail.serverCode,
|
|
7773
|
+
issues: detail.issues
|
|
7629
7774
|
});
|
|
7630
7775
|
}
|
|
7631
7776
|
static isCliError(error) {
|
|
@@ -8126,6 +8271,52 @@ var init_request_credential = __esm({
|
|
|
8126
8271
|
|
|
8127
8272
|
// src/api/http.client.ts
|
|
8128
8273
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
8274
|
+
async function classifyErrorResponse(response) {
|
|
8275
|
+
let errorData;
|
|
8276
|
+
try {
|
|
8277
|
+
errorData = await response.json();
|
|
8278
|
+
} catch (jsonError) {
|
|
8279
|
+
errorData = {};
|
|
8280
|
+
}
|
|
8281
|
+
if (response.status === 401) {
|
|
8282
|
+
const serverMessage = typeof errorData.message === "string" ? errorData.message : void 0;
|
|
8283
|
+
if (serverMessage && /not an admin/i.test(serverMessage)) {
|
|
8284
|
+
throw new AuthenticationError(`Access denied for this agent: ${serverMessage}`, "no_agent_access", serverMessage);
|
|
8285
|
+
}
|
|
8286
|
+
const isExplicitCredential = !!serverMessage && /(invalid|expired|missing|no)\s+(api[\s_-]?key|token|credential)/i.test(serverMessage);
|
|
8287
|
+
const isBareAuthRejection = !serverMessage || /^unauthorized$/i.test(serverMessage);
|
|
8288
|
+
if (isExplicitCredential || isBareAuthRejection) {
|
|
8289
|
+
throw new AuthenticationError("Authentication failed. Your Lua credential may be invalid or expired.", "invalid_credentials", serverMessage);
|
|
8290
|
+
}
|
|
8291
|
+
throw new AuthenticationError(`Authentication failed: ${serverMessage}`, "unknown", serverMessage);
|
|
8292
|
+
}
|
|
8293
|
+
if (response.status === 403) {
|
|
8294
|
+
const detail = errorData.message || "You do not have permission to access this resource.";
|
|
8295
|
+
const serverCode = serverCodeOf(errorData.code, errorData.error);
|
|
8296
|
+
throw new CliError("forbidden", `Access denied (403): ${detail}${serverCode ? ` (${serverCode})` : ""}`, {
|
|
8297
|
+
exitCode: CLI_EXIT.FORBIDDEN,
|
|
8298
|
+
statusCode: 403,
|
|
8299
|
+
serverCode,
|
|
8300
|
+
issues: Array.isArray(errorData.issues) ? errorData.issues : void 0,
|
|
8301
|
+
hint: "Check that your Lua login has access to this agent or organization."
|
|
8302
|
+
});
|
|
8303
|
+
}
|
|
8304
|
+
return {
|
|
8305
|
+
success: false,
|
|
8306
|
+
error: {
|
|
8307
|
+
message: errorData.message || `HTTP ${response.status}: ${response.statusText}`,
|
|
8308
|
+
statusCode: response.status,
|
|
8309
|
+
error: errorData.error,
|
|
8310
|
+
retryAfterSeconds: parseRetryAfter(response.headers.get("retry-after")),
|
|
8311
|
+
...errorData
|
|
8312
|
+
}
|
|
8313
|
+
};
|
|
8314
|
+
}
|
|
8315
|
+
function serverCodeOf(code, error) {
|
|
8316
|
+
if (typeof code === "string" && code.length > 0) return code;
|
|
8317
|
+
if (typeof error === "string" && /^[A-Z0-9][A-Z0-9_]*$/.test(error)) return error;
|
|
8318
|
+
return void 0;
|
|
8319
|
+
}
|
|
8129
8320
|
async function* parseSseStream(body, signal) {
|
|
8130
8321
|
const reader = body.getReader();
|
|
8131
8322
|
const decoder = new TextDecoder();
|
|
@@ -8306,42 +8497,7 @@ var init_http_client = __esm({
|
|
|
8306
8497
|
* @private
|
|
8307
8498
|
*/
|
|
8308
8499
|
async classifyErrorResponse(response) {
|
|
8309
|
-
|
|
8310
|
-
try {
|
|
8311
|
-
errorData = await response.json();
|
|
8312
|
-
} catch (jsonError) {
|
|
8313
|
-
errorData = {};
|
|
8314
|
-
}
|
|
8315
|
-
if (response.status === 401) {
|
|
8316
|
-
const serverMessage = typeof errorData.message === "string" ? errorData.message : void 0;
|
|
8317
|
-
if (serverMessage && /not an admin/i.test(serverMessage)) {
|
|
8318
|
-
throw new AuthenticationError(`Access denied for this agent: ${serverMessage}`, "no_agent_access", serverMessage);
|
|
8319
|
-
}
|
|
8320
|
-
const isExplicitCredential = !!serverMessage && /(invalid|expired|missing|no)\s+(api[\s_-]?key|token|credential)/i.test(serverMessage);
|
|
8321
|
-
const isBareAuthRejection = !serverMessage || /^unauthorized$/i.test(serverMessage);
|
|
8322
|
-
if (isExplicitCredential || isBareAuthRejection) {
|
|
8323
|
-
throw new AuthenticationError("Authentication failed. Your Lua credential may be invalid or expired.", "invalid_credentials", serverMessage);
|
|
8324
|
-
}
|
|
8325
|
-
throw new AuthenticationError(`Authentication failed: ${serverMessage}`, "unknown", serverMessage);
|
|
8326
|
-
}
|
|
8327
|
-
if (response.status === 403) {
|
|
8328
|
-
const detail = errorData.message || "You do not have permission to access this resource.";
|
|
8329
|
-
throw new CliError("forbidden", `Access denied (403): ${detail}`, {
|
|
8330
|
-
exitCode: CLI_EXIT.FORBIDDEN,
|
|
8331
|
-
statusCode: 403,
|
|
8332
|
-
hint: "Check that your Lua login has access to this agent or organization."
|
|
8333
|
-
});
|
|
8334
|
-
}
|
|
8335
|
-
return {
|
|
8336
|
-
success: false,
|
|
8337
|
-
error: {
|
|
8338
|
-
message: errorData.message || `HTTP ${response.status}: ${response.statusText}`,
|
|
8339
|
-
statusCode: response.status,
|
|
8340
|
-
error: errorData.error,
|
|
8341
|
-
retryAfterSeconds: parseRetryAfter(response.headers.get("retry-after")),
|
|
8342
|
-
...errorData
|
|
8343
|
-
}
|
|
8344
|
-
};
|
|
8500
|
+
return classifyErrorResponse(response);
|
|
8345
8501
|
}
|
|
8346
8502
|
/**
|
|
8347
8503
|
* Checks if an HTTP status code is retryable
|
|
@@ -8549,6 +8705,8 @@ var init_http_client = __esm({
|
|
|
8549
8705
|
};
|
|
8550
8706
|
}
|
|
8551
8707
|
};
|
|
8708
|
+
__name(classifyErrorResponse, "classifyErrorResponse");
|
|
8709
|
+
__name(serverCodeOf, "serverCodeOf");
|
|
8552
8710
|
__name(parseSseStream, "parseSseStream");
|
|
8553
8711
|
__name(parseRetryAfter, "parseRetryAfter");
|
|
8554
8712
|
__name(isCoreDrainApiError, "isCoreDrainApiError");
|
|
@@ -12607,6 +12765,7 @@ var init_job_api_service = __esm({
|
|
|
12607
12765
|
"src/api/job.api.service.ts"() {
|
|
12608
12766
|
"use strict";
|
|
12609
12767
|
init_http_client();
|
|
12768
|
+
init_cli_error();
|
|
12610
12769
|
init_job_instance();
|
|
12611
12770
|
JobApi = class extends HttpClient {
|
|
12612
12771
|
static {
|
|
@@ -12663,7 +12822,7 @@ var init_job_api_service = __esm({
|
|
|
12663
12822
|
if (response.success && response.data) {
|
|
12664
12823
|
return new JobInstance(this, response.data);
|
|
12665
12824
|
}
|
|
12666
|
-
throw
|
|
12825
|
+
throw CliError.fromStatus(response.error?.statusCode, response.error?.message || "Failed to get job");
|
|
12667
12826
|
}
|
|
12668
12827
|
/**
|
|
12669
12828
|
* Creates a new job for the agent.
|