lua-cli 3.33.0 → 3.34.0

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/index.js CHANGED
@@ -906,6 +906,9 @@ function aiGenerateInputFromSimplified(prompt, content) {
906
906
  function isAllowedReviewableExecuteTool(tool) {
907
907
  return REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST.includes(tool);
908
908
  }
909
+ function isReviewableStandingStartTool(tool) {
910
+ return REVIEWABLE_STANDING_START_TOOLS.includes(tool);
911
+ }
909
912
  function isReviewableMcpSendTool(tool) {
910
913
  return tool.length > REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length && tool.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX);
911
914
  }
@@ -935,7 +938,7 @@ function mcpSendSiblingForDraftTool(tool, availableToolIds) {
935
938
  return candidates[0]?.id;
936
939
  }
937
940
  function isReviewableExecuteTool(tool) {
938
- return isAllowedReviewableExecuteTool(tool) || isReviewableMcpSendTool(tool);
941
+ return isAllowedReviewableExecuteTool(tool) || isReviewableMcpSendTool(tool) || isReviewableStandingStartTool(tool);
939
942
  }
940
943
  function isInteractiveChannel(channel) {
941
944
  if (!channel) return true;
@@ -1081,7 +1084,10 @@ function transformChatHistoryContentParts(parts) {
1081
1084
  content.push({
1082
1085
  type: "file",
1083
1086
  data: part.data,
1084
- mediaType
1087
+ mediaType,
1088
+ ...part.filename && {
1089
+ filename: part.filename
1090
+ }
1085
1091
  });
1086
1092
  }
1087
1093
  }
@@ -1360,6 +1366,55 @@ function normalizeLuaJobExecutionTimeoutSeconds(timeout) {
1360
1366
  }
1361
1367
  return Math.min(Math.max(timeout, LUA_JOB_MIN_TIMEOUT_SECONDS), LUA_JOB_MAX_TIMEOUT_SECONDS);
1362
1368
  }
1369
+ function isId(value3) {
1370
+ return typeof value3 === "string" && value3.length > 0 && value3.length <= MAX_ID_LENGTH;
1371
+ }
1372
+ function parseScheduledJobFire(raw) {
1373
+ if (new TextEncoder().encode(raw).byteLength > MAX_BODY_BYTES) {
1374
+ throw new Error("Invalid scheduled job fire: body is too large");
1375
+ }
1376
+ let value3;
1377
+ try {
1378
+ value3 = JSON.parse(raw);
1379
+ } catch {
1380
+ throw new Error("Invalid scheduled job fire: body is not JSON");
1381
+ }
1382
+ if (!value3 || typeof value3 !== "object" || Array.isArray(value3)) {
1383
+ throw new Error("Invalid scheduled job fire: body must be an object");
1384
+ }
1385
+ const record = value3;
1386
+ if (Object.keys(record).some((key) => !KEYS.has(key))) {
1387
+ throw new Error("Invalid scheduled job fire: unknown field");
1388
+ }
1389
+ if (record.v !== 1 || record.kind !== "scheduled-job-fire") {
1390
+ throw new Error("Invalid scheduled job fire: unsupported contract");
1391
+ }
1392
+ if (!isId(record.agentId)) {
1393
+ throw new Error("Invalid scheduled job fire: agentId is required");
1394
+ }
1395
+ if (!isId(record.jobId)) {
1396
+ throw new Error("Invalid scheduled job fire: jobId is required");
1397
+ }
1398
+ if (typeof record.scheduledTime !== "string" || !UTC_ISO.test(record.scheduledTime) || !Number.isFinite(Date.parse(record.scheduledTime)) || ![
1399
+ new Date(record.scheduledTime).toISOString(),
1400
+ new Date(record.scheduledTime).toISOString().replace(".000Z", "Z")
1401
+ ].includes(record.scheduledTime)) {
1402
+ throw new Error("Invalid scheduled job fire: scheduledTime must be ISO 8601");
1403
+ }
1404
+ if (record.triggerId !== void 0 && !isId(record.triggerId)) {
1405
+ throw new Error("Invalid scheduled job fire: triggerId must be a non-empty string");
1406
+ }
1407
+ return {
1408
+ v: 1,
1409
+ kind: "scheduled-job-fire",
1410
+ agentId: record.agentId,
1411
+ jobId: record.jobId,
1412
+ scheduledTime: record.scheduledTime,
1413
+ ...typeof record.triggerId === "string" ? {
1414
+ triggerId: record.triggerId
1415
+ } : {}
1416
+ };
1417
+ }
1363
1418
  function triggerUrlEnvKey(triggerKey) {
1364
1419
  const upper = triggerKey.trim().replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
1365
1420
  return `${TEMPLATE_TRIGGER_URL_ENV_PREFIX}${upper}`;
@@ -1980,7 +2035,7 @@ function effectiveAgentFeatures(base, override, rule) {
1980
2035
  if (rule === "wholesale") return override || base || void 0;
1981
2036
  return effectiveAgentFeatureRows(base, override).rows;
1982
2037
  }
1983
- var __defProp2, __name2, 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, MODEL_SNAPSHOT_SUFFIX, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, 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, EventType, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, TEMPLATE_TRIGGER_URL_ENV_PREFIX, TEMPLATE_INSTALL_POLICY_PER_WORKSPACE_VALUES, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, TYPED_API_KEY, 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, LUA_SESSION_ID_CLAIM, SESSION_REVOKED_CODE, 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_RUN_GATE_KINDS, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, WORKFLOW_SIGNAL_EVENT_SITES, 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_JOURNAL_PROTOCOL_VERSION, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, 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, WORKFLOW_GOAL_JUDGE_SELF, 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, SUBAGENT_PER_KEY_FLAG_ENV, PER_KEY_FLAG_VALUES;
2038
+ var __defProp2, __name2, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_STANDING_START_TOOLS, 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, MODEL_SNAPSHOT_SUFFIX, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, 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, EventType, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, KEYS, MAX_BODY_BYTES, MAX_ID_LENGTH, UTC_ISO, TEMPLATE_TRIGGER_URL_ENV_PREFIX, TEMPLATE_INSTALL_POLICY_PER_WORKSPACE_VALUES, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, TYPED_API_KEY, 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, LUA_SESSION_ID_CLAIM, SESSION_REVOKED_CODE, 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_RUN_GATE_KINDS, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, WORKFLOW_SIGNAL_EVENT_SITES, 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_JOURNAL_PROTOCOL_VERSION, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, 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, WORKFLOW_GOAL_JUDGE_SELF, 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, SUBAGENT_PER_KEY_FLAG_ENV, PER_KEY_FLAG_VALUES;
1984
2039
  var init_dist = __esm({
1985
2040
  "../shared-types/dist/index.mjs"() {
1986
2041
  "use strict";
@@ -2011,6 +2066,11 @@ var init_dist = __esm({
2011
2066
  ];
2012
2067
  __name(isAllowedReviewableExecuteTool, "isAllowedReviewableExecuteTool");
2013
2068
  __name2(isAllowedReviewableExecuteTool, "isAllowedReviewableExecuteTool");
2069
+ REVIEWABLE_STANDING_START_TOOLS = [
2070
+ "scheduleWorkflow"
2071
+ ];
2072
+ __name(isReviewableStandingStartTool, "isReviewableStandingStartTool");
2073
+ __name2(isReviewableStandingStartTool, "isReviewableStandingStartTool");
2014
2074
  REVIEWABLE_MCP_SEND_TOOL_SUFFIX = "_create_messaging_message";
2015
2075
  __name(isReviewableMcpSendTool, "isReviewableMcpSendTool");
2016
2076
  __name2(isReviewableMcpSendTool, "isReviewableMcpSendTool");
@@ -2711,6 +2771,21 @@ This text is who you are for this person. As you learn them, their name, their w
2711
2771
  __name2(resolveLuaJobTimeoutSeconds, "resolveLuaJobTimeoutSeconds");
2712
2772
  __name(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
2713
2773
  __name2(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
2774
+ KEYS = /* @__PURE__ */ new Set([
2775
+ "v",
2776
+ "kind",
2777
+ "agentId",
2778
+ "jobId",
2779
+ "scheduledTime",
2780
+ "triggerId"
2781
+ ]);
2782
+ MAX_BODY_BYTES = 4096;
2783
+ MAX_ID_LENGTH = 512;
2784
+ UTC_ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/;
2785
+ __name(isId, "isId");
2786
+ __name2(isId, "isId");
2787
+ __name(parseScheduledJobFire, "parseScheduledJobFire");
2788
+ __name2(parseScheduledJobFire, "parseScheduledJobFire");
2714
2789
  TEMPLATE_TRIGGER_URL_ENV_PREFIX = "LUA_TRIGGER_URL__";
2715
2790
  __name(triggerUrlEnvKey, "triggerUrlEnvKey");
2716
2791
  __name2(triggerUrlEnvKey, "triggerUrlEnvKey");
@@ -2981,7 +3056,20 @@ This text is who you are for this person. As you learn them, their name, their w
2981
3056
  "platform-allowlist"
2982
3057
  ]),
2983
3058
  /** Product data only. A roster row confers nothing. */
2984
- rostered: z3.boolean()
3059
+ rostered: z3.boolean(),
3060
+ /**
3061
+ * Ownership, product data only (PRO-1754). `createdBy` is the creating
3062
+ * user's id straight off the sub-agent document; `owner` is that id
3063
+ * resolved to a display identity after the list is decided. Both are
3064
+ * absent when the document records no creator or the lookup fails —
3065
+ * they never influence which resources are listed.
3066
+ */
3067
+ createdBy: z3.string().min(1).max(256).optional(),
3068
+ owner: z3.object({
3069
+ id: z3.string().min(1).max(256),
3070
+ name: z3.string().optional(),
3071
+ email: z3.string().optional()
3072
+ }).optional()
2985
3073
  }).passthrough();
2986
3074
  CapabilityProfilesSchema = z3.record(z3.string().min(1).max(64), z3.array(ProjectedScopeSchema));
2987
3075
  RoleCatalogSchema = z3.record(z3.string().min(1).max(128), z3.object({
@@ -4483,6 +4571,148 @@ function resolveMapping(cfg, ctx) {
4483
4571
  value: result
4484
4572
  };
4485
4573
  }
4574
+ function looksLikeModelTemplate(model) {
4575
+ return typeof model === "string" && model.includes("${");
4576
+ }
4577
+ function parseModelTemplate(model) {
4578
+ if (!looksLikeModelTemplate(model)) return {
4579
+ kind: "static"
4580
+ };
4581
+ const trimmed = model.trim();
4582
+ const m = WORKFLOW_MODEL_TEMPLATE_RE.exec(trimmed);
4583
+ if (!m) {
4584
+ const inner = /^\$\{([^}]*)\}$/.exec(trimmed)?.[1];
4585
+ const root = inner?.split(/[.|]/, 1)[0];
4586
+ const why = inner !== void 0 && root !== void 0 && root !== WORKFLOW_MODEL_TEMPLATE_ROOT ? `only the \`${WORKFLOW_MODEL_TEMPLATE_ROOT}\` root is allowed (got \`${root || "(empty)"}\`)` : inner !== void 0 && (inner === WORKFLOW_MODEL_TEMPLATE_ROOT || inner.startsWith(`${WORKFLOW_MODEL_TEMPLATE_ROOT}.`)) ? "the path after `initData.` is empty" : "the whole value must be exactly one placeholder \u2014 no prefix, suffix or second placeholder";
4587
+ return {
4588
+ kind: "invalid",
4589
+ message: modelTemplateInvalidMessage(model, why)
4590
+ };
4591
+ }
4592
+ const path26 = m[1];
4593
+ if (!path26.split(".").every((seg) => PATH_SEGMENT_RE.test(seg))) {
4594
+ return {
4595
+ kind: "invalid",
4596
+ message: modelTemplateInvalidMessage(model, `the path \`${path26}\` is not a dotted path of names and canonical [n] indexes`)
4597
+ };
4598
+ }
4599
+ if (m[2] !== void 0) {
4600
+ const dflt = m[2].trim();
4601
+ if (!dflt) return {
4602
+ kind: "invalid",
4603
+ message: modelTemplateInvalidMessage(model, "the default after `|` is empty")
4604
+ };
4605
+ if (dflt.includes("|")) {
4606
+ return {
4607
+ kind: "invalid",
4608
+ message: modelTemplateInvalidMessage(model, "a placeholder names ONE default \u2014 a second `|` is not a fallback chain")
4609
+ };
4610
+ }
4611
+ return {
4612
+ kind: "template",
4613
+ template: {
4614
+ placeholder: trimmed,
4615
+ path: path26,
4616
+ default: dflt
4617
+ }
4618
+ };
4619
+ }
4620
+ return {
4621
+ kind: "template",
4622
+ template: {
4623
+ placeholder: trimmed,
4624
+ path: path26
4625
+ }
4626
+ };
4627
+ }
4628
+ function modelTemplateInvalidMessage(model, why) {
4629
+ return `model "${model.trim()}" is not a valid run-input-bound model placeholder \u2014 ${why}; the forms are \${initData.<path>} and \${initData.<path>|<provider/model default>}`;
4630
+ }
4631
+ function modelTemplateDefaultRequiredMessage(model) {
4632
+ return `model "${model}" runs on the Job tier, so its placeholder needs a default \u2014 the harness / provider gates (harness:'claude-code' needs an Anthropic model) classify it at push; write ${model.replace(/\}$/, "|<provider/model>}")}`;
4633
+ }
4634
+ function staticModelPin(model) {
4635
+ if (typeof model !== "string") return void 0;
4636
+ const parsed = parseModelTemplate(model);
4637
+ if (parsed.kind === "static") return model;
4638
+ if (parsed.kind === "template") return parsed.template.default;
4639
+ return void 0;
4640
+ }
4641
+ function readPath(root, path26) {
4642
+ let cur = root;
4643
+ for (const seg of path26.split(".")) {
4644
+ const name = seg.replace(/\[(?:0|[1-9]\d*)\]/g, "");
4645
+ const indexes = [
4646
+ ...seg.matchAll(/\[(0|[1-9]\d*)\]/g)
4647
+ ].map((x) => Number(x[1]));
4648
+ if (cur === null || typeof cur !== "object") return void 0;
4649
+ cur = cur[name];
4650
+ for (const i of indexes) {
4651
+ if (!Array.isArray(cur)) return void 0;
4652
+ cur = cur[i];
4653
+ }
4654
+ }
4655
+ return cur;
4656
+ }
4657
+ function renderModelTemplate(model, initData) {
4658
+ if (model === void 0 || !looksLikeModelTemplate(model)) return {
4659
+ ok: true,
4660
+ model,
4661
+ source: "static"
4662
+ };
4663
+ const parsed = parseModelTemplate(model);
4664
+ if (parsed.kind === "invalid") {
4665
+ return {
4666
+ ok: false,
4667
+ placeholder: model.trim(),
4668
+ path: "",
4669
+ reason: "invalid",
4670
+ message: parsed.message
4671
+ };
4672
+ }
4673
+ if (parsed.kind === "static") return {
4674
+ ok: true,
4675
+ model,
4676
+ source: "static"
4677
+ };
4678
+ const { placeholder, path: path26 } = parsed.template;
4679
+ if (initData !== void 0 && initData !== null && (typeof initData !== "object" || Array.isArray(initData))) {
4680
+ return {
4681
+ ok: false,
4682
+ placeholder,
4683
+ path: path26,
4684
+ reason: "input-not-object",
4685
+ message: modelTemplateInputNotObjectMessage(placeholder, initData)
4686
+ };
4687
+ }
4688
+ const value22 = readPath(initData, path26);
4689
+ const reason = value22 === void 0 || value22 === null ? "unbound" : typeof value22 !== "string" ? "not-a-string" : value22.trim() ? null : "empty";
4690
+ if (reason === null) return {
4691
+ ok: true,
4692
+ model: value22.trim(),
4693
+ source: "initData"
4694
+ };
4695
+ if (parsed.template.default !== void 0) return {
4696
+ ok: true,
4697
+ model: parsed.template.default,
4698
+ source: "default"
4699
+ };
4700
+ return {
4701
+ ok: false,
4702
+ placeholder,
4703
+ path: path26,
4704
+ reason,
4705
+ message: modelTemplateUnboundMessage(placeholder, path26, reason)
4706
+ };
4707
+ }
4708
+ function modelTemplateUnboundMessage(placeholder, path26, reason) {
4709
+ const what = reason === "unbound" ? `the run input has no ${WORKFLOW_MODEL_TEMPLATE_ROOT}.${path26}` : reason === "empty" ? `${WORKFLOW_MODEL_TEMPLATE_ROOT}.${path26} is empty on the run input` : `${WORKFLOW_MODEL_TEMPLATE_ROOT}.${path26} on the run input is not a string`;
4710
+ return `model placeholder "${placeholder}" is unbound \u2014 ${what} and the placeholder declares no default; pass one in the run input or write \${${WORKFLOW_MODEL_TEMPLATE_ROOT}.${path26}|<provider/model>}`;
4711
+ }
4712
+ function modelTemplateInputNotObjectMessage(placeholder, initData) {
4713
+ const type = Array.isArray(initData) ? "an array" : `a ${typeof initData}`;
4714
+ return `model placeholder "${placeholder}" cannot be rendered \u2014 the run input is ${type}, not an object; start the run with an object input (a JSON string must be parsed before it is passed)`;
4715
+ }
4486
4716
  function describeApproverSpecRefusal(spec) {
4487
4717
  const raw = spec === void 0 ? "undefined" : JSON.stringify(spec) ?? String(spec);
4488
4718
  const written = raw.length > APPROVER_WRITTEN_MAX ? `${raw.slice(0, APPROVER_WRITTEN_MAX - 1)}\u2026` : raw;
@@ -4852,6 +5082,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4852
5082
  }
4853
5083
  }
4854
5084
  const declaredKeys = new Set(opts.connectionKeys ?? []);
5085
+ const ownKeys = /* @__PURE__ */ new Set();
4855
5086
  if (g.connections !== void 0 && !Array.isArray(g.connections)) {
4856
5087
  err("connection-declaration-invalid", "`connections` must be an array of { key, integrationType }", "connections");
4857
5088
  }
@@ -4863,7 +5094,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4863
5094
  err("connection-declaration-invalid", `connections[${i}].key must match ${WORKFLOW_CONNECTION_KEY_RE}`, `${path26}.key`);
4864
5095
  return;
4865
5096
  }
4866
- if (declaredKeys.has(key)) {
5097
+ if (ownKeys.has(key)) {
4867
5098
  err("connection-declaration-invalid", `connections[${i}].key "${key}" is declared twice`, `${path26}.key`);
4868
5099
  return;
4869
5100
  }
@@ -4871,6 +5102,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4871
5102
  err("connection-declaration-invalid", `connections[${i}] ("${key}") needs an integrationType (the catalog slug, e.g. 'github')`, `${path26}.integrationType`);
4872
5103
  return;
4873
5104
  }
5105
+ ownKeys.add(key);
4874
5106
  declaredKeys.add(key);
4875
5107
  });
4876
5108
  const undeclaredKey = /* @__PURE__ */ __name4((ref) => typeof ref === "string" && !declaredKeys.has(ref) && isConnectionKeyShaped(ref) && opts.connectionIds?.has(ref) !== true, "undeclaredKey");
@@ -4997,7 +5229,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4997
5229
  if (node.harness !== void 0 && node.tier !== "job") {
4998
5230
  err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path26}.harness`, id);
4999
5231
  }
5000
- const provider = node.type === "agent" ? classifyModelProvider(node.model) : null;
5232
+ const provider = node.type === "agent" ? classifyModelProvider(staticModelPin(node.model)) : null;
5001
5233
  if (node.harness === "claude-code" && provider !== null && provider !== "anthropic") {
5002
5234
  err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path26}.harness`, id);
5003
5235
  }
@@ -5007,18 +5239,32 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
5007
5239
  }, "checkTier");
5008
5240
  const checkModel = /* @__PURE__ */ __name4((node, path26) => {
5009
5241
  if (node.type !== "agent" || typeof node.model !== "string") return;
5242
+ const id = singleId(node);
5243
+ const parsed = parseModelTemplate(node.model);
5244
+ if (parsed.kind === "invalid") {
5245
+ err("model-template-invalid", parsed.message, `${path26}.model`, id);
5246
+ return;
5247
+ }
5248
+ if (parsed.kind === "template" && parsed.template.default === void 0) {
5249
+ if (isJobTier(node)) {
5250
+ err("model-template-default-required", modelTemplateDefaultRequiredMessage(node.model), `${path26}.model`, id);
5251
+ }
5252
+ return;
5253
+ }
5254
+ const pin = parsed.kind === "template" ? parsed.template.default : node.model;
5255
+ if (pin === void 0) return;
5256
+ const inContext = /* @__PURE__ */ __name4((message) => parsed.kind === "template" ? `${message} (the default of ${parsed.template.placeholder})` : message, "inContext");
5010
5257
  const registry = opts.approvedModels;
5011
5258
  if (registry === void 0) return;
5012
- const id = singleId(node);
5013
5259
  if (registry === "unavailable") {
5014
- const pin = node.model.trim();
5015
- if (pin && !normalizeModelId(pin, []).ok) {
5016
- 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)`, `${path26}.model`, id);
5260
+ const trimmed = pin.trim();
5261
+ if (trimmed && !normalizeModelId(trimmed, []).ok) {
5262
+ warn("model-unresolved", inContext(`model "${trimmed}" 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)`), `${path26}.model`, id);
5017
5263
  }
5018
5264
  return;
5019
5265
  }
5020
- const resolved = normalizeModelId(node.model, registry);
5021
- if (!resolved.ok) err("model-unresolved", modelUnresolvedMessage(resolved), `${path26}.model`, id);
5266
+ const resolved = normalizeModelId(pin, registry);
5267
+ if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path26}.model`, id);
5022
5268
  }, "checkModel");
5023
5269
  const checkWorkspace = /* @__PURE__ */ __name4((node, path26) => {
5024
5270
  const id = singleId(node);
@@ -7508,7 +7754,37 @@ function needsInheritedWorkspace(graph) {
7508
7754
  }
7509
7755
  return false;
7510
7756
  }
7511
- var __defProp4, __name4, WorkflowTemplateError, TEMPLATE_PLACEHOLDER, TEMPLATE_NAMESPACES, MAP_DESCRIPTOR_KEYS, MAP_MEMBER_MALFORMED_CODE, fromInit, fromStep, value, template, fromRequest, rows, fromKnowledge, SideEffectsSchema, JobResourcesSchema, APPROVER_SPEC_MAX_USERS, ESCALATION_MAX_HOPS, TemplateBindingSchema, ApproverSpecSchema, FourEyesSchema, EscalationHopSchema, TerminalOutcomeSchema, ApprovalOnTimeoutSchema, APPROVER_SPEC_SHAPES, APPROVER_WRITTEN_MAX, USER_ID_SHAPED_RE, BINDING_ROOTS, WORKSPACE_TEMPLATE_EXPR_RE, SLEEP_UNTIL_REPLACEMENT, WORKFLOW_CAPS_DEFAULT, WORKFLOW_STEP_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_AGENT_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_JOB_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_FOREACH_DEFAULT_CONCURRENCY, WORKFLOW_FOREACH_DEFAULT_MAX_ITEMS, WORKFLOW_LOOP_DEFAULT_MAX_ITERATIONS, WORKFLOW_SUSPEND_DEFAULT_TIMEOUT_HOURS, WORKFLOW_SIGNAL_DEFAULT_SOURCES, clone, CONNECTION_ID_HEX_RE, WORKFLOW_JOB_MAX_WORKTREE_ARMS, workspaceOf, mountsWorkspace, isJobTier, jobToolsOf, schemaIsArray, isHitlNode, isSingleStep, singleId, armId, TEMPLATE_STEP_REF, EDITABLE_PATH_RE, PREDICATE_OPS, isPredicateScalar, GRAPH_HASH_PREFIX, WorkflowPlanError, isArmStep, armStepId, armStepKind, joinIdOf, containerIdOf, PATH_PLACEHOLDER, MISSING, stepIdOf, cmp, eq, ne, gt, gte, lt, lte, inSet, notIn, exists, notExists, truthy, falsy, and, or, not, CONTINUED_FAILURE_TAG, CONTINUED_FAILURE_DEFAULT_CODE, CONTINUED_FAILURE_OUTPUT_SCHEMA, CONTINUED_FAILURE_LEAF_PATHS, isHitlNode2, nodeIdOf, GOAL_JUDGE_STEP_ID, NON_LEAF_KINDS, CONDITIONAL_JOIN_ID, branchArmId, canonical, sortKeys, JOIN, entryOfJoin, FORCE_CANCEL_STALE_MS, TERMINAL, WORKFLOW_INLINE_RUN_TAG, RUN_ERROR_ISSUES_MAX, IN_FLIGHT, n, STEP_ERROR_DETAIL_KEYS, STEP_ERROR_DETAIL_MAX_BYTES, DETAIL_MAX_DEPTH, DETAIL_MAX_ITEMS, MAX_HOLIDAYS, MAX_WALK_DAYS, HHMM, YMD, MS_PER_MIN, MS_PER_DAY, MON_FRI, supportedTz, fmtCache, WEEKDAYS, JSON_PATCH_OPS, JSON_PATCH_MAX_OPS, JSON_PATCH_MAX_VALUE_BYTES, JSON_PATCH_MAX_TOTAL_BYTES, SEGMENT_RE, WORKFLOW_SCHEDULE_TYPES, WORKFLOW_SCHEDULE_SHAPE_ISSUE, WORKFLOW_SCHEDULE_SHAPES_HINT, WORKFLOW_SCHEDULE_RUN_AS, isObject, WORKFLOW_ENV_OVERLAY_MAX_KEYS, WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES, WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE, isEnvRef, looksLikeEmbeddedJson, ZERO, isRecord2;
7757
+ function armEntry2(arm) {
7758
+ return Array.isArray(arm) ? arm[arm.length - 1] : arm;
7759
+ }
7760
+ function entryHasJobTier(entry) {
7761
+ const n2 = armEntry2(entry);
7762
+ if (!n2 || typeof n2 !== "object") return false;
7763
+ const node = n2;
7764
+ if (node.tier === "job") return true;
7765
+ const ws = node.workspace;
7766
+ if (ws !== void 0 && ws !== "inherit") return true;
7767
+ switch (node.type) {
7768
+ case "parallel":
7769
+ return Array.isArray(node.steps) && node.steps.some(entryHasJobTier);
7770
+ case "conditional":
7771
+ return Array.isArray(node.steps) && node.steps.some(entryHasJobTier) || node.otherwise !== void 0 && entryHasJobTier(node.otherwise);
7772
+ case "foreach":
7773
+ case "loop":
7774
+ return entryHasJobTier(node.step);
7775
+ default:
7776
+ return false;
7777
+ }
7778
+ }
7779
+ function graphHasJobTierStep(envelopeOrGraph) {
7780
+ if (!envelopeOrGraph || typeof envelopeOrGraph !== "object") return false;
7781
+ const env = envelopeOrGraph;
7782
+ const envWorkspace = env.workspace;
7783
+ if (envWorkspace !== void 0 && envWorkspace !== "inherit") return true;
7784
+ const graph = Array.isArray(envelopeOrGraph) ? envelopeOrGraph : env.definition?.graph ?? [];
7785
+ return Array.isArray(graph) && graph.some(entryHasJobTier);
7786
+ }
7787
+ var __defProp4, __name4, WorkflowTemplateError, TEMPLATE_PLACEHOLDER, TEMPLATE_NAMESPACES, MAP_DESCRIPTOR_KEYS, MAP_MEMBER_MALFORMED_CODE, fromInit, fromStep, value, template, fromRequest, rows, fromKnowledge, SideEffectsSchema, JobResourcesSchema, WORKFLOW_MODEL_TEMPLATE_ROOT, WORKFLOW_MODEL_TEMPLATE_RE, PATH_SEGMENT_RE, APPROVER_SPEC_MAX_USERS, ESCALATION_MAX_HOPS, TemplateBindingSchema, ApproverSpecSchema, FourEyesSchema, EscalationHopSchema, TerminalOutcomeSchema, ApprovalOnTimeoutSchema, APPROVER_SPEC_SHAPES, APPROVER_WRITTEN_MAX, USER_ID_SHAPED_RE, BINDING_ROOTS, WORKSPACE_TEMPLATE_EXPR_RE, SLEEP_UNTIL_REPLACEMENT, WORKFLOW_CAPS_DEFAULT, WORKFLOW_STEP_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_AGENT_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_JOB_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_FOREACH_DEFAULT_CONCURRENCY, WORKFLOW_FOREACH_DEFAULT_MAX_ITEMS, WORKFLOW_LOOP_DEFAULT_MAX_ITERATIONS, WORKFLOW_SUSPEND_DEFAULT_TIMEOUT_HOURS, WORKFLOW_SIGNAL_DEFAULT_SOURCES, clone, CONNECTION_ID_HEX_RE, WORKFLOW_JOB_MAX_WORKTREE_ARMS, workspaceOf, mountsWorkspace, isJobTier, jobToolsOf, schemaIsArray, isHitlNode, isSingleStep, singleId, armId, TEMPLATE_STEP_REF, EDITABLE_PATH_RE, PREDICATE_OPS, isPredicateScalar, GRAPH_HASH_PREFIX, WorkflowPlanError, isArmStep, armStepId, armStepKind, joinIdOf, containerIdOf, PATH_PLACEHOLDER, MISSING, stepIdOf, cmp, eq, ne, gt, gte, lt, lte, inSet, notIn, exists, notExists, truthy, falsy, and, or, not, CONTINUED_FAILURE_TAG, CONTINUED_FAILURE_DEFAULT_CODE, CONTINUED_FAILURE_OUTPUT_SCHEMA, CONTINUED_FAILURE_LEAF_PATHS, isHitlNode2, nodeIdOf, GOAL_JUDGE_STEP_ID, NON_LEAF_KINDS, CONDITIONAL_JOIN_ID, branchArmId, canonical, sortKeys, JOIN, entryOfJoin, FORCE_CANCEL_STALE_MS, TERMINAL, WORKFLOW_INLINE_RUN_TAG, RUN_ERROR_ISSUES_MAX, IN_FLIGHT, n, STEP_ERROR_DETAIL_KEYS, STEP_ERROR_DETAIL_MAX_BYTES, DETAIL_MAX_DEPTH, DETAIL_MAX_ITEMS, MAX_HOLIDAYS, MAX_WALK_DAYS, HHMM, YMD, MS_PER_MIN, MS_PER_DAY, MON_FRI, supportedTz, fmtCache, WEEKDAYS, JSON_PATCH_OPS, JSON_PATCH_MAX_OPS, JSON_PATCH_MAX_VALUE_BYTES, JSON_PATCH_MAX_TOTAL_BYTES, SEGMENT_RE, WORKFLOW_SCHEDULE_TYPES, WORKFLOW_SCHEDULE_SHAPE_ISSUE, WORKFLOW_SCHEDULE_SHAPES_HINT, WORKFLOW_SCHEDULE_RUN_AS, isObject, WORKFLOW_ENV_OVERLAY_MAX_KEYS, WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES, WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE, isEnvRef, looksLikeEmbeddedJson, ZERO, isRecord2;
7512
7788
  var init_dist2 = __esm({
7513
7789
  "../workflow-graph/dist/index.mjs"() {
7514
7790
  "use strict";
@@ -7613,6 +7889,27 @@ var init_dist2 = __esm({
7613
7889
  }), "fromKnowledge");
7614
7890
  SideEffectsSchema = z6.enum(WORKFLOW_SIDE_EFFECTS);
7615
7891
  JobResourcesSchema = z6.enum(WORKFLOW_JOB_RESOURCES);
7892
+ WORKFLOW_MODEL_TEMPLATE_ROOT = "initData";
7893
+ WORKFLOW_MODEL_TEMPLATE_RE = /^\$\{\s*initData\.([A-Za-z0-9_.\-[\]]+)\s*(?:\|([^}]*))?\}$/;
7894
+ PATH_SEGMENT_RE = /^[A-Za-z0-9_-]+(?:\[(?:0|[1-9]\d*)\])*$/;
7895
+ __name(looksLikeModelTemplate, "looksLikeModelTemplate");
7896
+ __name4(looksLikeModelTemplate, "looksLikeModelTemplate");
7897
+ __name(parseModelTemplate, "parseModelTemplate");
7898
+ __name4(parseModelTemplate, "parseModelTemplate");
7899
+ __name(modelTemplateInvalidMessage, "modelTemplateInvalidMessage");
7900
+ __name4(modelTemplateInvalidMessage, "modelTemplateInvalidMessage");
7901
+ __name(modelTemplateDefaultRequiredMessage, "modelTemplateDefaultRequiredMessage");
7902
+ __name4(modelTemplateDefaultRequiredMessage, "modelTemplateDefaultRequiredMessage");
7903
+ __name(staticModelPin, "staticModelPin");
7904
+ __name4(staticModelPin, "staticModelPin");
7905
+ __name(readPath, "readPath");
7906
+ __name4(readPath, "readPath");
7907
+ __name(renderModelTemplate, "renderModelTemplate");
7908
+ __name4(renderModelTemplate, "renderModelTemplate");
7909
+ __name(modelTemplateUnboundMessage, "modelTemplateUnboundMessage");
7910
+ __name4(modelTemplateUnboundMessage, "modelTemplateUnboundMessage");
7911
+ __name(modelTemplateInputNotObjectMessage, "modelTemplateInputNotObjectMessage");
7912
+ __name4(modelTemplateInputNotObjectMessage, "modelTemplateInputNotObjectMessage");
7616
7913
  APPROVER_SPEC_MAX_USERS = 20;
7617
7914
  ESCALATION_MAX_HOPS = 3;
7618
7915
  TemplateBindingSchema = z22.object({
@@ -8119,7 +8416,16 @@ var init_dist2 = __esm({
8119
8416
  "secretName",
8120
8417
  "executionId",
8121
8418
  "credentialsExecutionId",
8122
- "expired"
8419
+ "expired",
8420
+ // Run-input-bound model pins (the Principal Engineer stage models): the Job tier's `MODEL_ERROR` refusals name the
8421
+ // pin they judged (`requested`), the declared harness, the provider the classifier read and the precedence leg the
8422
+ // pin came from (`source`: initData / default / node / env / org / stamp), and `provider_unsupported`'s fleet
8423
+ // (`allowed`, the LUA_WF_JOB_PROVIDERS list) — the members the PR body promises.
8424
+ "requested",
8425
+ "harness",
8426
+ "provider",
8427
+ "source",
8428
+ "allowed"
8123
8429
  ];
8124
8430
  STEP_ERROR_DETAIL_MAX_BYTES = 8 * 1024;
8125
8431
  DETAIL_MAX_DEPTH = 4;
@@ -8276,6 +8582,12 @@ var init_dist2 = __esm({
8276
8582
  __name4(inheritTargets, "inheritTargets");
8277
8583
  __name(needsInheritedWorkspace, "needsInheritedWorkspace");
8278
8584
  __name4(needsInheritedWorkspace, "needsInheritedWorkspace");
8585
+ __name(armEntry2, "armEntry2");
8586
+ __name4(armEntry2, "armEntry");
8587
+ __name(entryHasJobTier, "entryHasJobTier");
8588
+ __name4(entryHasJobTier, "entryHasJobTier");
8589
+ __name(graphHasJobTierStep, "graphHasJobTierStep");
8590
+ __name4(graphHasJobTierStep, "graphHasJobTierStep");
8279
8591
  }
8280
8592
  });
8281
8593
 
@@ -20152,7 +20464,8 @@ function computeDeferred(graph, opts = {}) {
20152
20464
  deferred.add("job-tier-disabled");
20153
20465
  deferred.add("job-tier-provider-unsupported");
20154
20466
  }
20155
- if (n2.type === "agent" && typeof n2.model === "string" && !isModelIdSentinel(n2.model)) deferred.add("model-unresolved");
20467
+ const modelPin = n2.type === "agent" ? staticModelPin(n2.model) : void 0;
20468
+ if (modelPin !== void 0 && !isModelIdSentinel(modelPin)) deferred.add("model-unresolved");
20156
20469
  if (Array.isArray(n2.requiredConnections) && n2.requiredConnections.some(serverDecides)) deferred.add("required-connection-unknown");
20157
20470
  if (n2.type === "approval") {
20158
20471
  const a = n2.approver;
@@ -38942,7 +39255,7 @@ async function testPreProcessor(entityName, inputJson, asJson = false) {
38942
39255
  } else if (result.action === "block") {
38943
39256
  console.log(`
38944
39257
  Action: BLOCK`);
38945
- console.log(`Response: ${result.response}`);
39258
+ console.log(`Response: ${result.response || "(none \u2014 the turn ends silently)"}`);
38946
39259
  if (result.metadata) {
38947
39260
  console.log(`Metadata: ${JSON.stringify(result.metadata, null, 2)}`);
38948
39261
  }
@@ -41920,7 +42233,7 @@ var ChatApi = class extends HttpClient {
41920
42233
  } else if (chunk.type === "postprocess-complete" && onPostprocessComplete) {
41921
42234
  onPostprocessComplete(chunk.originalResponse, chunk.modifiedResponse);
41922
42235
  } else if (chunk.type === "preprocessor_blocked" && onPreprocessorBlocked) {
41923
- onPreprocessorBlocked(chunk.message || "Message was blocked by a preprocessor.");
42236
+ onPreprocessorBlocked(chunk.message || void 0);
41924
42237
  } else if (chunk.type === "batch-abort" && onBatchAbort) {
41925
42238
  onBatchAbort(chunk.message || "");
41926
42239
  } else if (chunk.type === "batch-handled" && onBatchHandled) {
@@ -42964,7 +43277,8 @@ async function startChatLoop(chatEnv, probeWindow) {
42964
43277
  onPreprocessorBlocked: /* @__PURE__ */ __name((message) => {
42965
43278
  stopTypingIndicator(typingInterval);
42966
43279
  firstChunk = false;
42967
- console.log(`\u{1F6AB} Message blocked: ${message}
43280
+ console.log(message ? `\u{1F6AB} Message blocked: ${message}
43281
+ ` : `\u{1F6AB} Message blocked \u2014 no reply sent
42968
43282
  `);
42969
43283
  writeNextStep({
42970
43284
  command: buildLogsCommand({
@@ -43154,7 +43468,7 @@ async function sendSingleMessage(chatEnv, message, probeWindow) {
43154
43468
  }, "onPostprocessComplete"),
43155
43469
  onPreprocessorBlocked: /* @__PURE__ */ __name((message2) => {
43156
43470
  preprocessorBlocked = true;
43157
- console.log(`\u{1F6AB} Message blocked: ${message2}`);
43471
+ console.log(message2 ? `\u{1F6AB} Message blocked: ${message2}` : `\u{1F6AB} Message blocked \u2014 no reply sent`);
43158
43472
  writeNextStep({
43159
43473
  command: buildLogsCommand({
43160
43474
  primitiveType: "preprocessor",
@@ -52039,6 +52353,7 @@ async function deployCore(ctx, name, version) {
52039
52353
  emitJson(ctx, res);
52040
52354
  if (!ctx.json) {
52041
52355
  writeSuccess(`\u2705 Version ${target} of "${wf.name}" deployed`);
52356
+ for (const w of res.data?.warnings ?? []) writeInfo(` \u26A0 ${w.message}`);
52042
52357
  if (res.data?.agentVersion) writeInfo(` agentVersion: ${JSON.stringify(res.data.agentVersion)}`);
52043
52358
  writeHintBlock({
52044
52359
  headline: "Workflow is live. Start a run, then watch it:",
@@ -57485,7 +57800,17 @@ async function templatePublishAction(templateApi, config, options) {
57485
57800
  ...options.skipAutoApply === true ? {
57486
57801
  skipAutoApply: true
57487
57802
  } : {},
57488
- ...sectionBody
57803
+ ...sectionBody,
57804
+ // selfAudit is include-ONLY-when-authored, deliberately NOT part of the C12
57805
+ // "always serialize, empty = CLEAR" rule that governs sectionBody above. The
57806
+ // server is inherit-when-omitted for it (agent-template.service.ts:675 +
57807
+ // agent-template.version.schema.ts:654 "inherited from the previous
57808
+ // version"), so an absent block must leave the previous version's config
57809
+ // intact — we omit the key entirely rather than send an empty clear. (Not in
57810
+ // TEMPLATE_SECTION_KEYS / the consequence diff for the same reason.)
57811
+ ...templateSection?.selfAudit !== void 0 ? {
57812
+ selfAudit: templateSection.selfAudit
57813
+ } : {}
57489
57814
  });
57490
57815
  if (options.json) {
57491
57816
  console.log(JSON.stringify(version, null, 2));