lua-cli 3.38.0 → 3.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@ var __export = (target, all) => {
18
18
  import { z } from "zod";
19
19
  import { z as z2 } from "zod";
20
20
  import { z as z3 } from "zod";
21
+ import { z as z4 } from "zod";
21
22
  function isChannelConversationChannel(channel) {
22
23
  return !!channel && CHANNEL_CONVERSATION_CHANNELS.includes(channel);
23
24
  }
@@ -114,9 +115,9 @@ function isMcpDraftCreateTool(tool) {
114
115
  function mcpSendSiblingForDraftTool(tool, availableToolIds) {
115
116
  const candidates = [
116
117
  ...availableToolIds
117
- ].filter((id) => id.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX)).map((id) => ({
118
- id,
119
- serverName: id.slice(0, -REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length)
118
+ ].filter((id2) => id2.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX)).map((id2) => ({
119
+ id: id2,
120
+ serverName: id2.slice(0, -REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length)
120
121
  })).filter(({ serverName }) => tool.startsWith(`${serverName}_`)).sort((a, b) => b.serverName.length - a.serverName.length);
121
122
  return candidates[0]?.id;
122
123
  }
@@ -277,8 +278,8 @@ function transformChatHistoryContentParts(parts) {
277
278
  }
278
279
  return content;
279
280
  }
280
- function isSyntheticSideRow(id) {
281
- return id.startsWith(SCREENSHOT_MESSAGE_ID_PREFIX) || id.startsWith(RICH_PARTS_MESSAGE_ID_PREFIX);
281
+ function isSyntheticSideRow(id2) {
282
+ return id2.startsWith(SCREENSHOT_MESSAGE_ID_PREFIX) || id2.startsWith(RICH_PARTS_MESSAGE_ID_PREFIX);
282
283
  }
283
284
  function mergeRichPartMirrorMessages(messages, sameTurnGroup) {
284
285
  const merged = [];
@@ -359,6 +360,155 @@ function foldRichPartsIntoMessages(messages, records, makeMessage, sameTurnGroup
359
360
  while (next < synthetic.length) combined.push(synthetic[next++].message);
360
361
  return mergeRichPartMirrorMessages(combined, sameTurnGroup);
361
362
  }
363
+ function utf8WidthAt(value3, index) {
364
+ const code = value3.charCodeAt(index);
365
+ if (code < 128) return {
366
+ bytes: 1,
367
+ units: 1
368
+ };
369
+ if (code < 2048) return {
370
+ bytes: 2,
371
+ units: 1
372
+ };
373
+ if (code >= 55296 && code <= 56319) {
374
+ const next = value3.charCodeAt(index + 1);
375
+ if (next >= 56320 && next <= 57343) return {
376
+ bytes: 4,
377
+ units: 2
378
+ };
379
+ }
380
+ return {
381
+ bytes: 3,
382
+ units: 1
383
+ };
384
+ }
385
+ function utf8ByteLength(value3) {
386
+ let bytes = 0;
387
+ for (let i = 0; i < value3.length; ) {
388
+ const width = utf8WidthAt(value3, i);
389
+ bytes += width.bytes;
390
+ i += width.units;
391
+ }
392
+ return bytes;
393
+ }
394
+ function clampUtf8(value3, maxBytes) {
395
+ let bytes = 0;
396
+ for (let i = 0; i < value3.length; ) {
397
+ const width = utf8WidthAt(value3, i);
398
+ if (bytes + width.bytes > maxBytes) return value3.slice(0, i);
399
+ bytes += width.bytes;
400
+ i += width.units;
401
+ }
402
+ return value3;
403
+ }
404
+ function mapBytes(fields, withMark) {
405
+ return utf8ByteLength(JSON.stringify(withMark ? {
406
+ ...fields,
407
+ [LOG_FIELDS_CLAMPED_KEY]: true
408
+ } : fields));
409
+ }
410
+ function withValueCap(fields, capBytes) {
411
+ const out = {};
412
+ for (const [key, value3] of Object.entries(fields)) {
413
+ out[key] = typeof value3 === "string" ? clampUtf8(value3, capBytes) : value3;
414
+ }
415
+ return out;
416
+ }
417
+ function describeValue(value3) {
418
+ if (value3 === null) return "null";
419
+ if (value3 === void 0) return "undefined";
420
+ if (Array.isArray(value3)) return "an array";
421
+ return typeof value3 === "object" ? "an object" : `a ${typeof value3}`;
422
+ }
423
+ function assertValidLogFieldKey(key) {
424
+ if (!LOG_FIELD_KEY_PATTERN.test(key)) {
425
+ throw new LuaLogFieldsError(`log fields: key \`${key}\` is not allowed \u2014 a key must match ${LOG_FIELD_KEY_PATTERN.source} (lower-case, starts with a letter, then letters/digits/underscore, at most 64 characters)`);
426
+ }
427
+ if (LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS.some((pattern) => pattern.test(key))) {
428
+ throw new LuaLogFieldsError(`log fields: key \`${key}\` is not allowed \u2014 it has the shape of a credential that the log-drain scrubber masks in values; a field KEY is never scrubbed, so it may never carry a secret shape`);
429
+ }
430
+ if (key === LOG_FIELDS_CLAMPED_KEY) {
431
+ throw new LuaLogFieldsError(`log fields: key \`${key}\` is reserved \u2014 the platform sets it to mark a field map it had to clamp`);
432
+ }
433
+ }
434
+ function normalizeLogFields(fields) {
435
+ if (fields === void 0 || fields === null) return void 0;
436
+ if (typeof fields !== "object" || Array.isArray(fields)) {
437
+ throw new LuaLogFieldsError(`log fields: expected a plain object of fields, received ${describeValue(fields)}`);
438
+ }
439
+ const entries = Object.entries(fields);
440
+ if (entries.length > LOG_FIELDS_MAX_KEYS) {
441
+ throw new LuaLogFieldsError(`log fields: ${entries.length} keys exceeds the cap of ${LOG_FIELDS_MAX_KEYS} keys per call`);
442
+ }
443
+ const out = {};
444
+ for (const [key, value3] of entries) {
445
+ assertValidLogFieldKey(key);
446
+ if (typeof value3 === "string" || typeof value3 === "boolean") {
447
+ out[key] = value3;
448
+ continue;
449
+ }
450
+ if (typeof value3 === "number") {
451
+ if (!Number.isFinite(value3)) {
452
+ throw new LuaLogFieldsError(`log fields: \`${key}\` must be a finite number \u2014 NaN and Infinity have no JSON form`);
453
+ }
454
+ out[key] = value3;
455
+ continue;
456
+ }
457
+ if (Array.isArray(value3)) {
458
+ const parts = [];
459
+ for (const element of value3) {
460
+ if (typeof element !== "string") {
461
+ throw new LuaLogFieldsError(`log fields: \`${key}\` is an array, so every element must be a string (found ${describeValue(element)})`);
462
+ }
463
+ if (element.includes(",")) {
464
+ throw new LuaLogFieldsError(`log fields: \`${key}\` \u2014 an array element may not contain a comma; elements are comma-joined into one value (with \`${key}${LOG_FIELD_ARRAY_COUNT_SUFFIX}\` beside it), so a comma inside one would be indistinguishable from the separator`);
465
+ }
466
+ parts.push(element);
467
+ }
468
+ out[key] = parts.join(",");
469
+ out[`${key}${LOG_FIELD_ARRAY_COUNT_SUFFIX}`] = parts.length;
470
+ continue;
471
+ }
472
+ throw new LuaLogFieldsError(`log fields: \`${key}\` must be a string, number, boolean or string[] \u2014 received ${describeValue(value3)}` + (value3 !== null && typeof value3 === "object" ? " (nested objects are not supported)" : ""));
473
+ }
474
+ const keys = Object.keys(out);
475
+ if (keys.length === 0) return void 0;
476
+ if (keys.length > LOG_FIELDS_MAX_KEYS) {
477
+ throw new LuaLogFieldsError(`log fields: ${keys.length} keys exceeds the cap of ${LOG_FIELDS_MAX_KEYS} keys per call \u2014 an array field also contributes its \`${LOG_FIELD_ARRAY_COUNT_SUFFIX.slice(1)}\` sibling`);
478
+ }
479
+ if (clampLogFields(out)) out[LOG_FIELDS_CLAMPED_KEY] = true;
480
+ return out;
481
+ }
482
+ function clampLogFields(out) {
483
+ let clamped = false;
484
+ for (const [key, value3] of Object.entries(out)) {
485
+ if (typeof value3 !== "string") continue;
486
+ const capped = clampUtf8(value3, LOG_FIELD_MAX_VALUE_BYTES);
487
+ if (capped !== value3) {
488
+ out[key] = capped;
489
+ clamped = true;
490
+ }
491
+ }
492
+ if (mapBytes(out, clamped) <= LOG_FIELDS_MAX_BYTES) return clamped;
493
+ const base = {
494
+ ...out
495
+ };
496
+ let low = 0;
497
+ let high = LOG_FIELD_MAX_VALUE_BYTES;
498
+ let best = 0;
499
+ while (low <= high) {
500
+ const mid = Math.floor((low + high) / 2);
501
+ if (mapBytes(withValueCap(base, mid), true) <= LOG_FIELDS_MAX_BYTES) {
502
+ best = mid;
503
+ low = mid + 1;
504
+ } else {
505
+ high = mid - 1;
506
+ }
507
+ }
508
+ const fitted = withValueCap(base, best);
509
+ for (const key of Object.keys(out)) out[key] = fitted[key];
510
+ return true;
511
+ }
362
512
  function isDesktopFileCommandName(value3) {
363
513
  return typeof value3 === "string" && DESKTOP_FILE_COMMAND_SET.has(value3);
364
514
  }
@@ -449,12 +599,12 @@ function isWorkflowArmEntryType(type) {
449
599
  function workflowContainerRunsHitlArm(container) {
450
600
  return typeof container === "string" && WORKFLOW_HITL_ARM_CONTAINERS.includes(container);
451
601
  }
452
- function workflowHitlArmUnsupportedMessage(type, id, container) {
602
+ function workflowHitlArmUnsupportedMessage(type, id2, container) {
453
603
  const legal = WORKFLOW_HITL_ARM_CONTAINERS.map((c) => `\`${c}\``).join(" / ");
454
- return `the engine does not run \`${type}\` inside a \`${container}\` yet (node "${id}") \u2014 place it at the top level, as a ${legal} arm, or inside a child \`workflow\``;
604
+ return `the engine does not run \`${type}\` inside a \`${container}\` yet (node "${id2}") \u2014 place it at the top level, as a ${legal} arm, or inside a child \`workflow\``;
455
605
  }
456
- function workflowHitlArmShapeMessage(type, id, shape) {
457
- return shape === "mapped-arm" ? `\`${type}\` arm "${id}" takes the previous output as its payload \u2014 it cannot head a [mapping, step] chain; map before the container instead` : `a chunked foreach hands each child a slice of items, not one \u2014 \`${type}\` body "${id}" takes one item; drop \`chunk\``;
606
+ function workflowHitlArmShapeMessage(type, id2, shape) {
607
+ return shape === "mapped-arm" ? `\`${type}\` arm "${id2}" takes the previous output as its payload \u2014 it cannot head a [mapping, step] chain; map before the container instead` : `a chunked foreach hands each child a slice of items, not one \u2014 \`${type}\` body "${id2}" takes one item; drop \`chunk\``;
458
608
  }
459
609
  function isModelIdSentinel(input) {
460
610
  const lower = (input ?? "").trim().toLowerCase();
@@ -586,6 +736,81 @@ function buildDefaultPersona(agentName) {
586
736
  function buildPersonalSpaceStartingPersona(agentName) {
587
737
  return PERSONAL_SPACE_STARTING_PERSONA.replace(new RegExp(AGENT_NAME_TOKEN.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), () => agentName || "Your assistant");
588
738
  }
739
+ function utf8Bytes(value3) {
740
+ let bytes = 0;
741
+ for (let i = 0; i < value3.length; ) {
742
+ const code = value3.charCodeAt(i);
743
+ if (code < 128) {
744
+ bytes += 1;
745
+ i += 1;
746
+ } else if (code < 2048) {
747
+ bytes += 2;
748
+ i += 1;
749
+ } else if (code >= 55296 && code <= 56319) {
750
+ const next = value3.charCodeAt(i + 1);
751
+ if (next >= 56320 && next <= 57343) {
752
+ bytes += 4;
753
+ i += 2;
754
+ } else {
755
+ bytes += 3;
756
+ i += 1;
757
+ }
758
+ } else {
759
+ bytes += 3;
760
+ i += 1;
761
+ }
762
+ }
763
+ return bytes;
764
+ }
765
+ function isPlainFieldKey(key) {
766
+ if (!LOG_FIELD_KEY_PATTERN.test(key)) return false;
767
+ return !LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS.some((pattern) => pattern.test(key));
768
+ }
769
+ function describeAgentLogFieldsViolation(value3) {
770
+ if (typeof value3 !== "object" || value3 === null || Array.isArray(value3)) {
771
+ return "fields must be an object";
772
+ }
773
+ const entries = Object.entries(value3);
774
+ let userKeys = 0;
775
+ for (const [key, entry] of entries) {
776
+ if (key === LOG_FIELDS_CLAMPED_KEY) {
777
+ if (entry !== true) return `fields.${key} must be true`;
778
+ continue;
779
+ }
780
+ userKeys += 1;
781
+ if (key.endsWith(LOG_FIELD_ARRAY_COUNT_SUFFIX)) {
782
+ const base = key.slice(0, -LOG_FIELD_ARRAY_COUNT_SUFFIX.length);
783
+ if (!isPlainFieldKey(base)) return `fields key \`${key}\` is not a legal field key`;
784
+ if (typeof entry !== "number" || !Number.isFinite(entry)) {
785
+ return `fields.${key} must be a finite number`;
786
+ }
787
+ continue;
788
+ }
789
+ if (!isPlainFieldKey(key)) return `fields key \`${key}\` is not a legal field key`;
790
+ if (typeof entry === "string") {
791
+ if (utf8Bytes(entry) > LOG_FIELD_MAX_VALUE_BYTES) {
792
+ return `fields.${key} exceeds ${LOG_FIELD_MAX_VALUE_BYTES} bytes`;
793
+ }
794
+ continue;
795
+ }
796
+ if (typeof entry === "boolean") continue;
797
+ if (typeof entry === "number") {
798
+ if (!Number.isFinite(entry)) return `fields.${key} must be a finite number`;
799
+ continue;
800
+ }
801
+ return `fields.${key} must be a string, number or boolean`;
802
+ }
803
+ if (userKeys > LOG_FIELDS_MAX_KEYS) {
804
+ return `fields has ${userKeys} keys, over the cap of ${LOG_FIELDS_MAX_KEYS}`;
805
+ }
806
+ if (utf8Bytes(JSON.stringify(value3)) > LOG_FIELDS_MAX_BYTES) {
807
+ return `fields exceeds ${LOG_FIELDS_MAX_BYTES} bytes`;
808
+ }
809
+ return void 0;
810
+ }
811
+ function isAgentLogFields(value3) {
812
+ return describeAgentLogFieldsViolation(value3) === void 0;
813
+ }
589
814
  function maxDrainsForTier(tier) {
590
815
  return tier === "enterprise" ? LOG_DRAIN_MAX_PER_ORG_ENTERPRISE : LOG_DRAIN_MAX_PER_ORG;
591
816
  }
@@ -594,6 +819,148 @@ function resolvePresetEndpoint(type, site) {
594
819
  if (!template3 || !site) return void 0;
595
820
  return template3.replace("{site}", site);
596
821
  }
822
+ function isLogDrainBucketHostAllowed(provider, host) {
823
+ const normalized = host.trim().toLowerCase().replace(/^\[|\]$/g, "");
824
+ if (!normalized) return false;
825
+ return (LOG_DRAIN_BUCKET_HOST_PATTERNS[provider] ?? []).some((pattern) => pattern.test(normalized));
826
+ }
827
+ function resolveDrainBucketEndpoint(bucket) {
828
+ if (!LOG_DRAIN_BUCKET_NAME_PATTERN.test(bucket.bucket)) {
829
+ throw new Error("log drain bucket name is not a valid S3 bucket label");
830
+ }
831
+ if (bucket.provider === "aws") {
832
+ const region = bucket.region.trim().toLowerCase();
833
+ if (!/^[a-z0-9-]{1,32}$/.test(region)) throw new Error("log drain bucket region is not an AWS region");
834
+ return `https://${bucket.bucket}.s3.${region}.amazonaws.com`;
835
+ }
836
+ if (!bucket.endpoint) throw new Error(`log drain '${bucket.provider}' bucket requires an endpoint`);
837
+ let url;
838
+ try {
839
+ url = new URL(bucket.endpoint);
840
+ } catch {
841
+ throw new Error(`log drain '${bucket.provider}' bucket endpoint is not an absolute URL`);
842
+ }
843
+ if (url.protocol !== "https:") throw new Error(`log drain '${bucket.provider}' bucket endpoint must be https`);
844
+ return `https://${url.host}/${bucket.bucket}`;
845
+ }
846
+ function drainBucketUsesPathStyle(provider) {
847
+ return provider !== "aws";
848
+ }
849
+ function presetIntakeHosts(type) {
850
+ const template3 = LOG_DRAIN_ENDPOINT_TEMPLATES[type];
851
+ const sites = LOG_DRAIN_PRESET_SITES[type];
852
+ if (!template3 || !sites) return [];
853
+ const hosts = [];
854
+ for (const site of sites) {
855
+ try {
856
+ hosts.push(new URL(template3.replace("{site}", site)).hostname.toLowerCase());
857
+ } catch {
858
+ }
859
+ }
860
+ return hosts;
861
+ }
862
+ function presetHostAllowlist(type) {
863
+ return [
864
+ ...presetIntakeHosts(type),
865
+ ...LOG_DRAIN_PRESET_HOST_SUFFIXES[type] ?? []
866
+ ];
867
+ }
868
+ function drainHostAllowlistAllows(allowlist, host) {
869
+ const needle = host.toLowerCase();
870
+ return allowlist.some((raw) => {
871
+ const entry = raw.toLowerCase();
872
+ if (entry.startsWith(".")) return needle === entry.slice(1) || needle.endsWith(entry);
873
+ return entry === needle;
874
+ });
875
+ }
876
+ function drainDestinationIsVendorPinned(type) {
877
+ if (LOG_DRAIN_ENDPOINT_TEMPLATES[type]) return true;
878
+ return presetHostAllowlist(type).length > 0;
879
+ }
880
+ function drainVerificationOwnership(input) {
881
+ if (input.proved === true) return "verified";
882
+ if (input.mode === "test-post" && drainDestinationIsVendorPinned(input.type)) return "verified";
883
+ return "reachability-only";
884
+ }
885
+ function drainOwnershipOrDefault(ownership) {
886
+ return ownership === "verified" ? "verified" : "reachability-only";
887
+ }
888
+ function assertDrainContentAck(input) {
889
+ const turningOn = input.next === true && input.was !== true;
890
+ if (!turningOn) return void 0;
891
+ if (input.ack !== true) throw new DrainContentAckRequiredError();
892
+ return {
893
+ by: input.actor,
894
+ source: input.source,
895
+ at: input.at,
896
+ ...input.inheritedFrom ? {
897
+ inheritedFrom: input.inheritedFrom
898
+ } : {}
899
+ };
900
+ }
901
+ function composePresetEndpoint(type, endpoint) {
902
+ const rule = LOG_DRAIN_PRESET_PATHS[type];
903
+ if (!rule) return void 0;
904
+ let url;
905
+ try {
906
+ url = new URL(endpoint);
907
+ } catch {
908
+ return {
909
+ ok: false,
910
+ reason: "invalid_url"
911
+ };
912
+ }
913
+ if (url.protocol !== "https:" || !url.hostname) return {
914
+ ok: false,
915
+ reason: "invalid_url"
916
+ };
917
+ const origin = url.origin;
918
+ const path3 = url.pathname.replace(/\/+$/, "");
919
+ if (!rule.segment) {
920
+ const base2 = path3.endsWith(rule.path) ? path3.slice(0, path3.length - rule.path.length) : path3;
921
+ return {
922
+ ok: true,
923
+ endpoint: `${origin}${base2}${rule.path}`
924
+ };
925
+ }
926
+ const marker = `${rule.path}/`;
927
+ const at = path3.indexOf(marker);
928
+ if (at < 0) {
929
+ return {
930
+ ok: false,
931
+ reason: rule.segment === "dataset" ? "missing_dataset" : "missing_token"
932
+ };
933
+ }
934
+ const base = path3.slice(0, at);
935
+ const afterMarker = path3.slice(at + marker.length);
936
+ const rest = rule.suffix && afterMarker.endsWith(rule.suffix) ? afterMarker.slice(0, afterMarker.length - rule.suffix.length) : afterMarker;
937
+ if (!rest || rest.includes("/")) {
938
+ return {
939
+ ok: false,
940
+ reason: rule.segment === "dataset" ? "missing_dataset" : "missing_token"
941
+ };
942
+ }
943
+ if (!PRESET_SEGMENT_RE.test(rest)) return {
944
+ ok: false,
945
+ reason: "bad_segment"
946
+ };
947
+ if (rule.segment === "dataset") {
948
+ return {
949
+ ok: true,
950
+ endpoint: `${origin}${base}${rule.path}/${rest}${rule.suffix ?? ""}`,
951
+ dataset: rest
952
+ };
953
+ }
954
+ return {
955
+ ok: true,
956
+ endpoint: `${origin}${base}${rule.path}/`,
957
+ token: rest
958
+ };
959
+ }
960
+ function joinPresetEndpointToken(endpoint, token) {
961
+ if (typeof token !== "string" || !PRESET_SEGMENT_RE.test(token)) return endpoint;
962
+ return endpoint.endsWith("/") ? `${endpoint}${token}` : `${endpoint}/${token}`;
963
+ }
597
964
  function nextLogDrainQuotaResetAt(now) {
598
965
  return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1)).toISOString();
599
966
  }
@@ -640,6 +1007,264 @@ function logDrainQuotaDroppedSeverities(degradation) {
640
1007
  return [];
641
1008
  }
642
1009
  }
1010
+ function isLogExportSource(source) {
1011
+ return LOG_EXPORT_SOURCES.includes(source);
1012
+ }
1013
+ function clamp(value3, max) {
1014
+ if (typeof value3 !== "string") return void 0;
1015
+ const trimmed = value3.trim();
1016
+ if (!trimmed) return void 0;
1017
+ return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max - 1)}\u2026`;
1018
+ }
1019
+ function numberOr(value3, fallback) {
1020
+ return typeof value3 === "number" && Number.isFinite(value3) ? value3 : fallback;
1021
+ }
1022
+ function isoOr(value3) {
1023
+ return typeof value3 === "string" && value3.length > 0 ? value3 : void 0;
1024
+ }
1025
+ function logDrainNoticeView(drain, now) {
1026
+ const health = drain.health ?? {};
1027
+ const quota = drain.quota;
1028
+ const view = {
1029
+ id: String(drain.id ?? ""),
1030
+ name: String(drain.name ?? ""),
1031
+ type: drain.type,
1032
+ state: drain.state,
1033
+ deliveredCount24h: numberOr(health.deliveredCount24h, 0),
1034
+ droppedCount24h: numberOr(health.droppedCount24h, 0),
1035
+ rejectedCount24h: numberOr(health.rejectedCount24h, 0),
1036
+ backlog: numberOr(health.backlog, 0),
1037
+ quotaRatio: quota ? logDrainQuotaRatio(quota, now) : 0
1038
+ };
1039
+ if (health.pauseReason) view.pauseReason = health.pauseReason;
1040
+ const lastError = clamp(health.lastError, LOG_DRAIN_NOTICE_ERROR_MAX_CHARS);
1041
+ if (lastError) view.lastError = lastError;
1042
+ if (typeof health.lastStatusCode === "number") view.lastStatusCode = health.lastStatusCode;
1043
+ const lastSuccessAt = isoOr(health.lastSuccessAt);
1044
+ if (lastSuccessAt) view.lastSuccessAt = lastSuccessAt;
1045
+ const lastFailureAt = isoOr(health.lastFailureAt);
1046
+ if (lastFailureAt) view.lastFailureAt = lastFailureAt;
1047
+ const resetsAt = isoOr(quota?.resetsAt);
1048
+ if (resetsAt) view.quotaResetsAt = resetsAt;
1049
+ return view;
1050
+ }
1051
+ function logDrainHealthCardPath(orgId, drainId) {
1052
+ return `/orgs/${encodeURIComponent(orgId)}/log-drains/${encodeURIComponent(drainId)}`;
1053
+ }
1054
+ function percent(ratio) {
1055
+ if (!Number.isFinite(ratio) || ratio <= 0) return "0%";
1056
+ return `${Math.round(ratio * 100)}%`;
1057
+ }
1058
+ function becauseClause(view) {
1059
+ const bits = [];
1060
+ if (view.lastStatusCode) bits.push(`HTTP ${view.lastStatusCode}`);
1061
+ if (view.lastError) bits.push(view.lastError);
1062
+ return bits.length ? ` Last error: ${bits.join(" \u2014 ")}.` : "";
1063
+ }
1064
+ function logDrainNoticeCopy(payload) {
1065
+ const view = payload.drain;
1066
+ const name = view.name || view.id;
1067
+ const backlog = view.backlog > 0 ? ` ${view.backlog.toLocaleString("en-US")} records are buffered.` : "";
1068
+ switch (payload.kind) {
1069
+ case "failing":
1070
+ return {
1071
+ title: name,
1072
+ subject: `Log drain "${name}" is failing`,
1073
+ previewLine: "Failing \u2014 15 minutes without a successful delivery",
1074
+ summary: `The log drain "${name}" (${view.type}) has gone 15 minutes without a successful delivery and is now failing.${becauseClause(view)}${backlog} Records keep buffering; the drain pauses itself after 24 hours without a success.`,
1075
+ status: "failed",
1076
+ priority: "high"
1077
+ };
1078
+ case "paused_auto":
1079
+ return {
1080
+ title: name,
1081
+ subject: `Log drain "${name}" was paused`,
1082
+ previewLine: "Paused \u2014 24 hours without a successful delivery",
1083
+ summary: `The log drain "${name}" (${view.type}) was paused automatically after 24 hours without a successful delivery.${becauseClause(view)}${backlog} Nothing is being sent while it is paused, and the buffer is delivered on resume. Fix the destination, then resume it from the drain's health card or with \`lua drains resume ${view.id}\`.`,
1084
+ status: "failed",
1085
+ priority: "high"
1086
+ };
1087
+ case "paused_quota":
1088
+ return {
1089
+ title: name,
1090
+ subject: `Log drain "${name}" was paused \u2014 daily quota exhausted`,
1091
+ previewLine: `Paused \u2014 ${percent(view.quotaRatio)} of the daily allowance used`,
1092
+ summary: `The log drain "${name}" (${view.type}) reached ${percent(view.quotaRatio)} of its daily allowance and was paused.${backlog} Records keep buffering. The allowance resets${view.quotaResetsAt ? ` at ${view.quotaResetsAt}` : " at 00:00 UTC"}; narrow the drain's sources or raise the plan's limit to stop it happening again, then resume it with \`lua drains resume ${view.id}\`.`,
1093
+ status: "failed",
1094
+ priority: "high"
1095
+ };
1096
+ case "quota_warning":
1097
+ return {
1098
+ title: name,
1099
+ subject: `Log drain "${name}" has used 80% of its daily allowance`,
1100
+ previewLine: `${percent(view.quotaRatio)} of the daily allowance used`,
1101
+ summary: `The log drain "${name}" (${view.type}) has used ${percent(view.quotaRatio)} of today's allowance. Past 100% debug records are dropped, past 125% info records as well, and at 150% the drain pauses. The allowance resets${view.quotaResetsAt ? ` at ${view.quotaResetsAt}` : " at 00:00 UTC"}.`,
1102
+ status: "failed",
1103
+ priority: "normal"
1104
+ };
1105
+ case "dropped": {
1106
+ const dropped = payload.droppedCount ?? view.droppedCount24h;
1107
+ return {
1108
+ title: name,
1109
+ subject: `Log drain "${name}" is dropping records`,
1110
+ previewLine: `${dropped.toLocaleString("en-US")} records dropped`,
1111
+ summary: `The log drain "${name}" (${view.type}) dropped ${dropped.toLocaleString("en-US")} records because its buffer filled up faster than the destination accepted them.${becauseClause(view)} The gap is reported in band on the next successful batch, so the range is recoverable from the destination itself.`,
1112
+ status: "failed",
1113
+ priority: "high"
1114
+ };
1115
+ }
1116
+ case "verification_pending":
1117
+ return {
1118
+ title: name,
1119
+ subject: `Log drain "${name}" is still unverified`,
1120
+ previewLine: "Unverified after 24 hours \u2014 nothing is being delivered",
1121
+ summary: `The log drain "${name}" (${view.type}) was created more than 24 hours ago and has never completed verification, so nothing is being delivered to it.${becauseClause(view)} Run \`lua drains verify ${view.id}\` once the destination echoes the verification token.`,
1122
+ status: "failed",
1123
+ priority: "normal"
1124
+ };
1125
+ default: {
1126
+ const exhaustive = payload.kind;
1127
+ throw new Error(`unhandled log-drain notice kind: ${String(exhaustive)}`);
1128
+ }
1129
+ }
1130
+ }
1131
+ function logDrainNoticeLabel(kind) {
1132
+ switch (kind) {
1133
+ case "failing":
1134
+ return "failing";
1135
+ case "paused_auto":
1136
+ return "paused (no success for 24 h)";
1137
+ case "paused_quota":
1138
+ return "paused (daily allowance exhausted)";
1139
+ case "quota_warning":
1140
+ return "80% of the daily allowance used";
1141
+ case "dropped":
1142
+ return "dropping records";
1143
+ case "verification_pending":
1144
+ return "still unverified";
1145
+ default: {
1146
+ const exhaustive = kind;
1147
+ throw new Error(`unhandled log-drain notice kind: ${String(exhaustive)}`);
1148
+ }
1149
+ }
1150
+ }
1151
+ function logDrainNoticeDigestCopy(payload) {
1152
+ const entries = [
1153
+ ...payload.entries ?? []
1154
+ ].sort((a, b) => a.at < b.at ? -1 : a.at > b.at ? 1 : 0).slice(0, LOG_DRAIN_DIGEST_MAX_ENTRIES);
1155
+ const drains = new Set(entries.map((entry) => entry.drainId));
1156
+ const noun = `${entries.length} notice${entries.length === 1 ? "" : "s"}`;
1157
+ const across = `${drains.size} drain${drains.size === 1 ? "" : "s"}`;
1158
+ const lines = entries.map((entry) => `${entry.drainName || entry.drainId} \u2014 ${logDrainNoticeLabel(entry.kind)}`);
1159
+ return {
1160
+ title: "Log drains \u2014 daily summary",
1161
+ subject: `Log drains \u2014 ${noun} in the last day`,
1162
+ previewLine: `${noun} across ${across}`,
1163
+ summary: `${noun} across ${across} in the last day: ${lines.join("; ")}.`,
1164
+ status: "failed",
1165
+ priority: "normal"
1166
+ };
1167
+ }
1168
+ function finiteNonNegative(value3) {
1169
+ return typeof value3 === "number" && Number.isFinite(value3) && value3 >= 0 ? value3 : void 0;
1170
+ }
1171
+ function mergeLimits(base, stored) {
1172
+ const patch = stored ?? {};
1173
+ return {
1174
+ eventsPerDay: finiteNonNegative(patch.eventsPerDay) ?? base.eventsPerDay,
1175
+ bytesPerDay: finiteNonNegative(patch.bytesPerDay) ?? base.bytesPerDay
1176
+ };
1177
+ }
1178
+ function mergeCard(base, stored) {
1179
+ const patch = stored ?? {};
1180
+ return {
1181
+ includedEventsPerMonth: finiteNonNegative(patch.includedEventsPerMonth) ?? base.includedEventsPerMonth,
1182
+ includedBytesPerMonth: finiteNonNegative(patch.includedBytesPerMonth) ?? base.includedBytesPerMonth,
1183
+ usdPerMillionEvents: finiteNonNegative(patch.usdPerMillionEvents) ?? base.usdPerMillionEvents,
1184
+ usdPerGiB: finiteNonNegative(patch.usdPerGiB) ?? base.usdPerGiB
1185
+ };
1186
+ }
1187
+ function resolveStoredLogDrainPlanConfig(stored) {
1188
+ const values = stored;
1189
+ if (!values || typeof values.version !== "number" || !Number.isFinite(values.version)) {
1190
+ return DEFAULT_LOG_DRAIN_PLAN_CONFIG;
1191
+ }
1192
+ const tiers = {};
1193
+ const pricing = {};
1194
+ for (const tier of TIERS) {
1195
+ tiers[tier] = mergeLimits(DEFAULT_LOG_DRAIN_PLAN_CONFIG.tiers[tier], values.tiers?.[tier]);
1196
+ pricing[tier] = mergeCard(DEFAULT_LOG_DRAIN_PLAN_CONFIG.pricing[tier], values.pricing?.[tier]);
1197
+ }
1198
+ const orgs = {};
1199
+ for (const [orgId, override] of Object.entries(values.orgs ?? {})) {
1200
+ if (!orgId || !override || typeof override !== "object") continue;
1201
+ const row = {};
1202
+ if (override.tier && TIERS.includes(override.tier)) row.tier = override.tier;
1203
+ const events = finiteNonNegative(override.eventsPerDay);
1204
+ const bytes = finiteNonNegative(override.bytesPerDay);
1205
+ if (events !== void 0) row.eventsPerDay = events;
1206
+ if (bytes !== void 0) row.bytesPerDay = bytes;
1207
+ if (override.pricing && typeof override.pricing === "object") row.pricing = {
1208
+ ...override.pricing
1209
+ };
1210
+ if (Object.keys(row).length) orgs[orgId] = row;
1211
+ }
1212
+ return {
1213
+ version: values.version,
1214
+ tiers,
1215
+ pricing,
1216
+ ...Object.keys(orgs).length ? {
1217
+ orgs
1218
+ } : {}
1219
+ };
1220
+ }
1221
+ function logDrainPlanTierOverride(config, orgId) {
1222
+ return orgId ? config.orgs?.[orgId]?.tier : void 0;
1223
+ }
1224
+ function logDrainQuotaLimitsFor(config, orgId, tier) {
1225
+ const base = config.tiers[tier] ?? config.tiers.team ?? LOG_DRAIN_QUOTAS.team;
1226
+ const override = orgId ? config.orgs?.[orgId] : void 0;
1227
+ if (!override) return {
1228
+ ...base
1229
+ };
1230
+ return {
1231
+ eventsPerDay: override.eventsPerDay ?? base.eventsPerDay,
1232
+ bytesPerDay: override.bytesPerDay ?? base.bytesPerDay
1233
+ };
1234
+ }
1235
+ function logDrainPriceCardFor(config, orgId, tier) {
1236
+ const base = config.pricing[tier] ?? config.pricing.team ?? DEFAULT_LOG_DRAIN_PLAN_CONFIG.pricing.team;
1237
+ const override = orgId ? config.orgs?.[orgId]?.pricing : void 0;
1238
+ return override ? mergeCard(base, override) : {
1239
+ ...base
1240
+ };
1241
+ }
1242
+ function priceDrainUsage(totals, card, tier) {
1243
+ const billableRecords = Math.max(0, Math.floor(finiteNonNegative(totals?.billableRecords) ?? 0));
1244
+ const billableBytes = Math.max(0, Math.floor(finiteNonNegative(totals?.billableBytes) ?? 0));
1245
+ const includedEvents = card.includedEventsPerMonth;
1246
+ const includedBytes = card.includedBytesPerMonth;
1247
+ const overageEvents = Math.max(0, billableRecords - includedEvents);
1248
+ const overageBytes = Math.max(0, billableBytes - includedBytes);
1249
+ const eventsUsd = overageEvents / 1e6 * card.usdPerMillionEvents;
1250
+ const bytesUsd = overageBytes / LOG_DRAIN_BYTES_PER_GIB * card.usdPerGiB;
1251
+ const unpriced = card.usdPerMillionEvents === 0 && card.usdPerGiB === 0;
1252
+ const round = /* @__PURE__ */ __name2((usd) => Math.round(usd * 100) / 100, "round");
1253
+ return {
1254
+ lineItem: LOG_DRAIN_USAGE_LINE_ITEM,
1255
+ tier,
1256
+ billableRecords,
1257
+ billableBytes,
1258
+ includedEvents,
1259
+ includedBytes,
1260
+ overageEvents,
1261
+ overageBytes,
1262
+ eventsUsd: round(eventsUsd),
1263
+ bytesUsd: round(bytesUsd),
1264
+ usd: round(Math.max(eventsUsd, bytesUsd)),
1265
+ unpriced
1266
+ };
1267
+ }
643
1268
  function encodeLogCursor(c) {
644
1269
  return Buffer.from(JSON.stringify({
645
1270
  t: c.t,
@@ -657,12 +1282,12 @@ function decodeLogCursor(raw) {
657
1282
  return null;
658
1283
  }
659
1284
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
660
- const { t, id } = parsed;
1285
+ const { t, id: id2 } = parsed;
661
1286
  if (typeof t !== "number" || !Number.isSafeInteger(t) || t < 0) return null;
662
- if (typeof id !== "string" || !id || id.length > LOG_CURSOR_MAX_ID_LENGTH) return null;
1287
+ if (typeof id2 !== "string" || !id2 || id2.length > LOG_CURSOR_MAX_ID_LENGTH) return null;
663
1288
  return {
664
1289
  t,
665
- id
1290
+ id: id2
666
1291
  };
667
1292
  }
668
1293
  function parseLogTimeBound(raw, now = /* @__PURE__ */ new Date()) {
@@ -900,62 +1525,62 @@ function isKnownProfile(profiles, profileId) {
900
1525
  function hasCapability(profiles, profileId, required) {
901
1526
  return capabilitiesFor(profiles, profileId).includes(required);
902
1527
  }
903
- function workflowJobId(id) {
904
- switch (id.kind) {
1528
+ function workflowJobId(id2) {
1529
+ switch (id2.kind) {
905
1530
  case "start":
906
- return `wft_${id.runId}_0`;
1531
+ return `wft_${id2.runId}_0`;
907
1532
  case "start-redrive":
908
- return `wft_${id.runId}_start_r${id.now}`;
1533
+ return `wft_${id2.runId}_start_r${id2.now}`;
909
1534
  case "tick":
910
- return `wft_${id.runId}_${id.seq}`;
1535
+ return `wft_${id2.runId}_${id2.seq}`;
911
1536
  case "timer":
912
- return `wft_${id.runId}_timer_${id.stepId}_${id.attempt}`;
1537
+ return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}`;
913
1538
  case "timer-remainder":
914
- return `wft_${id.runId}_timer_${id.stepId}_${id.attempt}_r${id.now}`;
1539
+ return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}_r${id2.now}`;
915
1540
  case "timer-deferral":
916
- return `wft_${id.runId}_timer_${id.stepId}_${id.attempt}_d${id.now}`;
1541
+ return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}_d${id2.now}`;
917
1542
  case "timer-sibling":
918
- return `wft_${id.runId}_timer_${id.stepId}_${id.attempt}_w${id.now}`;
1543
+ return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}_w${id2.now}`;
919
1544
  case "retry":
920
- return `wft_${id.runId}_retry_${id.stepId}_${id.attempt}`;
1545
+ return `wft_${id2.runId}_retry_${id2.stepId}_${id2.attempt}`;
921
1546
  case "respawn":
922
- return `wft_${id.runId}_respawn_${id.stepId}_${id.attempt}_s${id.segment}_r${id.now}`;
1547
+ return `wft_${id2.runId}_respawn_${id2.stepId}_${id2.attempt}_s${id2.segment}_r${id2.now}`;
923
1548
  case "redrive":
924
- return `wft_${id.runId}_redrive_${id.stepId}_${id.attempt}_r${id.now}`;
1549
+ return `wft_${id2.runId}_redrive_${id2.stepId}_${id2.attempt}_r${id2.now}`;
925
1550
  case "redispatch":
926
- return `wft_${id.runId}_redispatch_${id.stepId}_${id.attempt}_x${id.executionId ?? "none"}_r${id.now}`;
1551
+ return `wft_${id2.runId}_redispatch_${id2.stepId}_${id2.attempt}_x${id2.executionId ?? "none"}_r${id2.now}`;
927
1552
  case "expiry":
928
- return `wft_${id.runId}_expire_${id.stepId}_${id.attempt}_t${id.suspendedAt}${id.hop > 0 ? `_h${id.hop}` : ""}`;
1553
+ return `wft_${id2.runId}_expire_${id2.stepId}_${id2.attempt}_t${id2.suspendedAt}${id2.hop > 0 ? `_h${id2.hop}` : ""}`;
929
1554
  case "step-terminal":
930
- return `wft_${id.runId}_term_${id.stepId}_${id.attempt}_r${id.now}`;
1555
+ return `wft_${id2.runId}_term_${id2.stepId}_${id2.attempt}_r${id2.now}`;
931
1556
  case "handback":
932
- return `wft_${id.runId}_handback_${id.stepId}_${id.attempt}_${id.now}`;
1557
+ return `wft_${id2.runId}_handback_${id2.stepId}_${id2.attempt}_${id2.now}`;
933
1558
  case "foreach-rate":
934
- return `wft_${id.runId}_fe_${id.stepId}_${id.attempt}_${id.bucket}`;
1559
+ return `wft_${id2.runId}_fe_${id2.stepId}_${id2.attempt}_${id2.bucket}`;
935
1560
  case "budget-expiry":
936
- return `wft_${id.runId}_expiry_budget_r${id.now}`;
1561
+ return `wft_${id2.runId}_expiry_budget_r${id2.now}`;
937
1562
  case "budget-resume":
938
- return `wft_${id.runId}_resume_budget_${id.now}`;
1563
+ return `wft_${id2.runId}_resume_budget_${id2.now}`;
939
1564
  case "deadline":
940
- return `wft_${id.runId}_deadline_${id.deadlineAt}`;
1565
+ return `wft_${id2.runId}_deadline_${id2.deadlineAt}`;
941
1566
  case "deadline-remainder":
942
- return `wft_${id.runId}_deadline_${id.deadlineAt}_r${id.now}`;
1567
+ return `wft_${id2.runId}_deadline_${id2.deadlineAt}_r${id2.now}`;
943
1568
  case "readmit":
944
- return `wft_${id.runId}_readmit_${id.now}`;
1569
+ return `wft_${id2.runId}_readmit_${id2.now}`;
945
1570
  case "cancel":
946
- return `wft_${id.runId}_cancel`;
1571
+ return `wft_${id2.runId}_cancel`;
947
1572
  case "reconcile":
948
- return `wft_${id.runId}_reconcile_${id.now}`;
1573
+ return `wft_${id2.runId}_reconcile_${id2.now}`;
949
1574
  case "replay":
950
- return `wft_${id.runId}_replay_g${id.leaseGeneration}`;
1575
+ return `wft_${id2.runId}_replay_g${id2.leaseGeneration}`;
951
1576
  case "migration":
952
- return `wfm_${id.migrationId}`;
1577
+ return `wfm_${id2.migrationId}`;
953
1578
  default:
954
- return assertNever(id);
1579
+ return assertNever(id2);
955
1580
  }
956
1581
  }
957
- function assertNever(id) {
958
- throw new Error(`workflowJobId: unknown wake kind ${JSON.stringify(id)}`);
1582
+ function assertNever(id2) {
1583
+ throw new Error(`workflowJobId: unknown wake kind ${JSON.stringify(id2)}`);
959
1584
  }
960
1585
  function agentStepJobId(msg) {
961
1586
  return `${msg.runId}_${msg.stepId}_${msg.attempt}_x${msg.executionId}`;
@@ -993,11 +1618,11 @@ function isArchiveWindowTooOld(run, retentionDays, now = Date.now(), marginDays
993
1618
  function workflowOrgPurgingKey(orgId) {
994
1619
  return `wf:org:${orgId}:purging`;
995
1620
  }
996
- function isCloudTaskRunId(id) {
997
- return id.startsWith(CLOUD_TASK_RUN_ID_PREFIX);
1621
+ function isCloudTaskRunId(id2) {
1622
+ return id2.startsWith(CLOUD_TASK_RUN_ID_PREFIX);
998
1623
  }
999
- function isScheduledWorkflowRunId(id) {
1000
- return id.startsWith(WORKFLOW_SCHEDULED_RUN_ID_PREFIX);
1624
+ function isScheduledWorkflowRunId(id2) {
1625
+ return id2.startsWith(WORKFLOW_SCHEDULED_RUN_ID_PREFIX);
1001
1626
  }
1002
1627
  function scheduledWorkflowRunId(jobId, scheduledTime) {
1003
1628
  const key = typeof scheduledTime === "number" ? String(scheduledTime) : scheduledTimeKey(scheduledTime);
@@ -1358,7 +1983,13 @@ function effectiveAgentFeatures(base, override, rule) {
1358
1983
  if (rule === "wholesale") return override || base || void 0;
1359
1984
  return effectiveAgentFeatureRows(base, override).rows;
1360
1985
  }
1361
- var __defProp2, __name2, PLUMBING_THREAD_CHANNELS, CHANNEL_CONVERSATION_CHANNELS, HIDDEN_THREAD_CHANNELS, CHANNEL_SEND_CHANNELS, 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, 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_MODEL_CLASSES, WORKFLOW_DEFAULT_TASK_CLASS_MAP, WORKFLOW_MODELS_MAX_CLASS_DEFAULT, WORKFLOW_AUTONOMY_NUMERIC_KEYS, WORKFLOW_AUTONOMY_ENVELOPE_KEYS, WORKFLOW_AUTONOMY_DEFAULTS, WORKFLOW_AUTONOMY_CEILINGS, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING, WORKFLOW_AUTONOMY_FORMS_DEFAULT, WORKFLOW_AUTONOMY_MIN_VALUE, 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, MODEL_ID_BYOK_PROVIDERS, MODEL_CLASS_REF_PREFIX, 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, LOG_DRAIN_SOURCES, LOG_DRAIN_MAX_PER_ORG, LOG_DRAIN_MAX_PER_ORG_ENTERPRISE, LOG_DRAIN_ENDPOINT_TEMPLATES, LOG_DRAIN_QUOTAS, LOG_DRAIN_QUOTA_WARN_RATIO, LOG_DRAIN_QUOTA_DROP_DEBUG_RATIO, LOG_DRAIN_QUOTA_DROP_INFO_RATIO, LOG_DRAIN_QUOTA_PAUSE_RATIO, LOG_CURSOR_MAX_LENGTH, LOG_CURSOR_MAX_ID_LENGTH, LOG_RELATIVE_TIME_PATTERN, LOG_ISO_TIME_PATTERN, RELATIVE_UNIT_MS, 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, 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, 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_CONNECTION_KEY_RE, WORKFLOW_JOB_MODEL_SOURCE_LABELS, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, 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;
1986
+ function parseOnboardingFlow(value3) {
1987
+ return onboardingFlowSchema.parse(value3);
1988
+ }
1989
+ function parsePublishedOnboardingResponse(value3) {
1990
+ return getPublishedOnboardingResponseSchema.parse(value3);
1991
+ }
1992
+ var __defProp2, __name2, PLUMBING_THREAD_CHANNELS, CHANNEL_CONVERSATION_CHANNELS, HIDDEN_THREAD_CHANNELS, CHANNEL_SEND_CHANNELS, 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, LOG_FIELDS_MAX_KEYS, LOG_FIELD_MAX_VALUE_BYTES, LOG_FIELDS_MAX_BYTES, LOG_FIELD_KEY_PATTERN, LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS, LOG_FIELDS_CLAMPED_KEY, LOG_FIELD_ARRAY_COUNT_SUFFIX, LuaLogFieldsError, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, 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_MODEL_CLASSES, WORKFLOW_DEFAULT_TASK_CLASS_MAP, WORKFLOW_MODELS_MAX_CLASS_DEFAULT, WORKFLOW_AUTONOMY_NUMERIC_KEYS, WORKFLOW_AUTONOMY_ENVELOPE_KEYS, WORKFLOW_AUTONOMY_DEFAULTS, WORKFLOW_AUTONOMY_CEILINGS, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING, WORKFLOW_AUTONOMY_FORMS_DEFAULT, WORKFLOW_AUTONOMY_MIN_VALUE, 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, MODEL_ID_BYOK_PROVIDERS, MODEL_CLASS_REF_PREFIX, 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, AGENT_LOG_FIELDS_MAX_WIRE_KEYS, LOG_DRAIN_TYPES_PHASE1, LOG_DRAIN_TYPES_PHASE2, LOG_DRAIN_TYPES_IMPLEMENTED, LOG_DRAIN_SOURCES, LOG_DRAIN_MAX_PER_ORG, LOG_DRAIN_MAX_PER_ORG_ENTERPRISE, LOG_DRAIN_DATADOG_SITES, LOG_DRAIN_NEWRELIC_SITES, LOG_DRAIN_ENDPOINT_TEMPLATES, LOG_DRAIN_PRESET_SITES, LOG_DRAIN_BUCKET_NAME_PATTERN, LOG_DRAIN_BUCKET_HOST_PATTERNS, LOG_DRAIN_PRESET_HOST_SUFFIXES, DRAIN_CONTENT_ACK_ERROR_CODE, DRAIN_CONTENT_ACK_FIELD, DrainContentAckRequiredError, LOG_DRAIN_PRESET_PATHS, PRESET_SEGMENT_RE, LOG_DRAIN_QUOTAS, LOG_DRAIN_QUOTA_WARN_RATIO, LOG_DRAIN_QUOTA_DROP_DEBUG_RATIO, LOG_DRAIN_QUOTA_DROP_INFO_RATIO, LOG_DRAIN_QUOTA_PAUSE_RATIO, LOG_EXPORT_SOURCES, LOG_EXPORT_MAX_WINDOW_DAYS, LOG_EXPORT_MAX_WINDOW_MS, LOG_EXPORT_URL_TTL_SECONDS, LOG_EXPORT_FILE_RETENTION_DAYS, LOG_EXPORT_FILE_RETENTION_MS, LOG_EXPORT_PART_MAX_BYTES, LOG_DRAIN_NOTICE_RATE_LIMIT_MS, LOG_DRAIN_VERIFICATION_STALE_MS, LOG_DRAIN_DIGEST_INTERVAL_MS, LOG_DRAIN_DIGEST_MAX_ENTRIES, LOG_DRAIN_NOTICE_ERROR_MAX_CHARS, LOG_DRAIN_USAGE_LINE_ITEM, LOG_DRAIN_BYTES_PER_GIB, DEFAULT_LOG_DRAIN_PLAN_CONFIG, TIERS, LOG_CURSOR_MAX_LENGTH, LOG_CURSOR_MAX_ID_LENGTH, LOG_RELATIVE_TIME_PATTERN, LOG_ISO_TIME_PATTERN, RELATIVE_UNIT_MS, 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, 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, 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_CONNECTION_KEY_RE, WORKFLOW_JOB_MODEL_SOURCE_LABELS, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, 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, ONBOARDING_FLOW_KEY, ONBOARDING_SCHEMA_VERSION, id, copy, onboardingHeadingSchema, onboardingRichTextInlineSchema, onboardingRichTextSchema, onboardingDestinationSchema, onboardingArtworkSchema, onboardingAnswerSchema, onboardingQuestionSchema, onboardingTemplateSectionSchema, onboardingTemplateContentSchema, onboardingUnavailableOutcomeSchema, onboardingFlowSchema, onboardingActorSchema, onboardingEditorSchema, onboardingPublicationSummarySchema, onboardingValidationIssueSchema, onboardingValidationResponseSchema, onboardingAssetSchema, onboardingPublicAssetSchema, getOnboardingConfigResponseSchema, saveOnboardingDraftRequestSchema, validateOnboardingRequestSchema, publishOnboardingRequestSchema, rollbackOnboardingRequestSchema, onboardingTemplateCatalogItemSchema, getPublishedOnboardingResponseSchema;
1362
1993
  var init_dist = __esm({
1363
1994
  "../shared-types/dist/index.mjs"() {
1364
1995
  "use strict";
@@ -1686,6 +2317,50 @@ var init_dist = __esm({
1686
2317
  }
1687
2318
  ];
1688
2319
  BROWSER_COMMAND_NAMES = BROWSER_COMMANDS.map((c) => c.name);
2320
+ LOG_FIELDS_MAX_KEYS = 32;
2321
+ LOG_FIELD_MAX_VALUE_BYTES = 1024;
2322
+ LOG_FIELDS_MAX_BYTES = 8192;
2323
+ LOG_FIELD_KEY_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
2324
+ LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS = Object.freeze([
2325
+ /^api_[0-9a-f]{24,}$/,
2326
+ /^gh[pousr]_[a-z0-9]{36}$/,
2327
+ /^(?:sk|rk|pk)_(?:live|test)_[a-z0-9]{16,}$/,
2328
+ /^lua_hc_[a-z0-9]{20,}/,
2329
+ /^lua_sk_[a-z0-9]{20,}/
2330
+ ]);
2331
+ LOG_FIELDS_CLAMPED_KEY = "lua_fields_clamped";
2332
+ LOG_FIELD_ARRAY_COUNT_SUFFIX = ".count";
2333
+ LuaLogFieldsError = class _LuaLogFieldsError extends Error {
2334
+ static {
2335
+ __name(this, "_LuaLogFieldsError");
2336
+ }
2337
+ static {
2338
+ __name2(this, "LuaLogFieldsError");
2339
+ }
2340
+ constructor(message) {
2341
+ super(message);
2342
+ this.name = "LuaLogFieldsError";
2343
+ Object.setPrototypeOf(this, _LuaLogFieldsError.prototype);
2344
+ }
2345
+ };
2346
+ __name(utf8WidthAt, "utf8WidthAt");
2347
+ __name2(utf8WidthAt, "utf8WidthAt");
2348
+ __name(utf8ByteLength, "utf8ByteLength");
2349
+ __name2(utf8ByteLength, "utf8ByteLength");
2350
+ __name(clampUtf8, "clampUtf8");
2351
+ __name2(clampUtf8, "clampUtf8");
2352
+ __name(mapBytes, "mapBytes");
2353
+ __name2(mapBytes, "mapBytes");
2354
+ __name(withValueCap, "withValueCap");
2355
+ __name2(withValueCap, "withValueCap");
2356
+ __name(describeValue, "describeValue");
2357
+ __name2(describeValue, "describeValue");
2358
+ __name(assertValidLogFieldKey, "assertValidLogFieldKey");
2359
+ __name2(assertValidLogFieldKey, "assertValidLogFieldKey");
2360
+ __name(normalizeLogFields, "normalizeLogFields");
2361
+ __name2(normalizeLogFields, "normalizeLogFields");
2362
+ __name(clampLogFields, "clampLogFields");
2363
+ __name2(clampLogFields, "clampLogFields");
1689
2364
  DESKTOP_FILE_COMMANDS = [
1690
2365
  "files_roots",
1691
2366
  "files_stat",
@@ -2030,6 +2705,37 @@ This text is who you are for this person. As you learn them, their name, their w
2030
2705
  "workflow-script",
2031
2706
  "workflow"
2032
2707
  ];
2708
+ AGENT_LOG_FIELDS_MAX_WIRE_KEYS = LOG_FIELDS_MAX_KEYS + 1;
2709
+ __name(utf8Bytes, "utf8Bytes");
2710
+ __name2(utf8Bytes, "utf8Bytes");
2711
+ __name(isPlainFieldKey, "isPlainFieldKey");
2712
+ __name2(isPlainFieldKey, "isPlainFieldKey");
2713
+ __name(describeAgentLogFieldsViolation, "describeAgentLogFieldsViolation");
2714
+ __name2(describeAgentLogFieldsViolation, "describeAgentLogFieldsViolation");
2715
+ __name(isAgentLogFields, "isAgentLogFields");
2716
+ __name2(isAgentLogFields, "isAgentLogFields");
2717
+ LOG_DRAIN_TYPES_PHASE1 = [
2718
+ "http",
2719
+ "otlp",
2720
+ "datadog",
2721
+ "betterstack"
2722
+ ];
2723
+ LOG_DRAIN_TYPES_PHASE2 = [
2724
+ "splunk",
2725
+ "loki",
2726
+ "axiom",
2727
+ "newrelic",
2728
+ "sumologic"
2729
+ ];
2730
+ LOG_DRAIN_TYPES_IMPLEMENTED = [
2731
+ ...LOG_DRAIN_TYPES_PHASE1,
2732
+ ...LOG_DRAIN_TYPES_PHASE2,
2733
+ // RECONCILE-4 (W4-4). `s3` is implemented (H4 / PRO-1887) but is NOT in
2734
+ // `LOG_DRAIN_TYPES_PHASE2`, because its own flag opens it and `*` must not. It
2735
+ // belongs here all the same: this list is what a CLIENT may offer, and the server
2736
+ // remains the authority that answers 422 with the live list.
2737
+ "s3"
2738
+ ];
2033
2739
  LOG_DRAIN_SOURCES = [
2034
2740
  ...AGENT_LOG_SOURCES,
2035
2741
  "execution",
@@ -2038,17 +2744,123 @@ This text is who you are for this person. As you learn them, their name, their w
2038
2744
  "trigger-execution",
2039
2745
  "job-execution",
2040
2746
  "workflow-run",
2041
- "workflow-audit"
2747
+ "workflow-audit",
2748
+ // PRO-1884 (H2). Appended AFTER 'workflow-audit' so the enum stays additive and
2749
+ // no existing member changes position.
2750
+ "voice-call"
2042
2751
  ];
2043
2752
  LOG_DRAIN_MAX_PER_ORG = 5;
2044
2753
  LOG_DRAIN_MAX_PER_ORG_ENTERPRISE = 10;
2045
2754
  __name(maxDrainsForTier, "maxDrainsForTier");
2046
2755
  __name2(maxDrainsForTier, "maxDrainsForTier");
2756
+ LOG_DRAIN_DATADOG_SITES = [
2757
+ "datadoghq.com",
2758
+ "datadoghq.eu",
2759
+ "us3.datadoghq.com",
2760
+ "us5.datadoghq.com",
2761
+ "ap1.datadoghq.com",
2762
+ "ddog-gov.com"
2763
+ ];
2764
+ LOG_DRAIN_NEWRELIC_SITES = [
2765
+ "log-api.newrelic.com",
2766
+ "log-api.eu.newrelic.com",
2767
+ "log-api.jp.newrelic.com"
2768
+ ];
2047
2769
  LOG_DRAIN_ENDPOINT_TEMPLATES = {
2048
- datadog: "https://http-intake.logs.{site}/api/v2/logs"
2770
+ datadog: "https://http-intake.logs.{site}/api/v2/logs",
2771
+ newrelic: "https://{site}/log/v1"
2772
+ };
2773
+ LOG_DRAIN_PRESET_SITES = {
2774
+ datadog: LOG_DRAIN_DATADOG_SITES,
2775
+ newrelic: LOG_DRAIN_NEWRELIC_SITES
2049
2776
  };
2050
2777
  __name(resolvePresetEndpoint, "resolvePresetEndpoint");
2051
2778
  __name2(resolvePresetEndpoint, "resolvePresetEndpoint");
2779
+ LOG_DRAIN_BUCKET_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
2780
+ LOG_DRAIN_BUCKET_HOST_PATTERNS = Object.freeze({
2781
+ aws: [
2782
+ // virtual-host style, regional and legacy global
2783
+ /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]\.s3(\.dualstack)?(\.[a-z0-9-]+)?\.amazonaws\.com$/,
2784
+ // path style
2785
+ /^s3(\.dualstack)?(\.[a-z0-9-]+)?\.amazonaws\.com$/
2786
+ ],
2787
+ r2: [
2788
+ /^[a-f0-9]{32}\.r2\.cloudflarestorage\.com$/
2789
+ ],
2790
+ gcs: [
2791
+ /^storage\.googleapis\.com$/
2792
+ ]
2793
+ });
2794
+ __name(isLogDrainBucketHostAllowed, "isLogDrainBucketHostAllowed");
2795
+ __name2(isLogDrainBucketHostAllowed, "isLogDrainBucketHostAllowed");
2796
+ __name(resolveDrainBucketEndpoint, "resolveDrainBucketEndpoint");
2797
+ __name2(resolveDrainBucketEndpoint, "resolveDrainBucketEndpoint");
2798
+ __name(drainBucketUsesPathStyle, "drainBucketUsesPathStyle");
2799
+ __name2(drainBucketUsesPathStyle, "drainBucketUsesPathStyle");
2800
+ __name(presetIntakeHosts, "presetIntakeHosts");
2801
+ __name2(presetIntakeHosts, "presetIntakeHosts");
2802
+ LOG_DRAIN_PRESET_HOST_SUFFIXES = {
2803
+ axiom: [
2804
+ ".axiom.co"
2805
+ ],
2806
+ sumologic: [
2807
+ ".sumologic.com"
2808
+ ]
2809
+ };
2810
+ __name(presetHostAllowlist, "presetHostAllowlist");
2811
+ __name2(presetHostAllowlist, "presetHostAllowlist");
2812
+ __name(drainHostAllowlistAllows, "drainHostAllowlistAllows");
2813
+ __name2(drainHostAllowlistAllows, "drainHostAllowlistAllows");
2814
+ __name(drainDestinationIsVendorPinned, "drainDestinationIsVendorPinned");
2815
+ __name2(drainDestinationIsVendorPinned, "drainDestinationIsVendorPinned");
2816
+ __name(drainVerificationOwnership, "drainVerificationOwnership");
2817
+ __name2(drainVerificationOwnership, "drainVerificationOwnership");
2818
+ __name(drainOwnershipOrDefault, "drainOwnershipOrDefault");
2819
+ __name2(drainOwnershipOrDefault, "drainOwnershipOrDefault");
2820
+ DRAIN_CONTENT_ACK_ERROR_CODE = "DRAIN_CONTENT_ACK_REQUIRED";
2821
+ DRAIN_CONTENT_ACK_FIELD = "includeContentAck";
2822
+ DrainContentAckRequiredError = class extends Error {
2823
+ static {
2824
+ __name(this, "DrainContentAckRequiredError");
2825
+ }
2826
+ static {
2827
+ __name2(this, "DrainContentAckRequiredError");
2828
+ }
2829
+ code = DRAIN_CONTENT_ACK_ERROR_CODE;
2830
+ field = DRAIN_CONTENT_ACK_FIELD;
2831
+ constructor() {
2832
+ super("includeContent ships end-user message content to a third party; set includeContentAck: true to confirm.");
2833
+ this.name = "DrainContentAckRequiredError";
2834
+ }
2835
+ };
2836
+ __name(assertDrainContentAck, "assertDrainContentAck");
2837
+ __name2(assertDrainContentAck, "assertDrainContentAck");
2838
+ LOG_DRAIN_PRESET_PATHS = {
2839
+ // https://docs.splunk.com/Documentation/Splunk/latest/Data/HECExamples
2840
+ splunk: {
2841
+ path: "/services/collector/event"
2842
+ },
2843
+ // https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs
2844
+ loki: {
2845
+ path: "/loki/api/v1/push"
2846
+ },
2847
+ // https://axiom.co/docs/restapi/endpoints/ingestIntoDataset
2848
+ axiom: {
2849
+ path: "/v1/datasets",
2850
+ segment: "dataset",
2851
+ suffix: "/ingest"
2852
+ },
2853
+ // https://help.sumologic.com/docs/send-data/hosted-collectors/http-source/logs-metrics/upload-logs/
2854
+ sumologic: {
2855
+ path: "/receiver/v1/http",
2856
+ segment: "token"
2857
+ }
2858
+ };
2859
+ PRESET_SEGMENT_RE = /^[A-Za-z0-9._~%=+-]{1,512}$/;
2860
+ __name(composePresetEndpoint, "composePresetEndpoint");
2861
+ __name2(composePresetEndpoint, "composePresetEndpoint");
2862
+ __name(joinPresetEndpointToken, "joinPresetEndpointToken");
2863
+ __name2(joinPresetEndpointToken, "joinPresetEndpointToken");
2052
2864
  LOG_DRAIN_QUOTAS = {
2053
2865
  team: {
2054
2866
  eventsPerDay: 1e6,
@@ -2081,6 +2893,100 @@ This text is who you are for this person. As you learn them, their name, their w
2081
2893
  __name2(logDrainQuotaWarned, "logDrainQuotaWarned");
2082
2894
  __name(logDrainQuotaDroppedSeverities, "logDrainQuotaDroppedSeverities");
2083
2895
  __name2(logDrainQuotaDroppedSeverities, "logDrainQuotaDroppedSeverities");
2896
+ LOG_EXPORT_SOURCES = [
2897
+ ...AGENT_LOG_SOURCES,
2898
+ "execution"
2899
+ ];
2900
+ LOG_EXPORT_MAX_WINDOW_DAYS = 31;
2901
+ LOG_EXPORT_MAX_WINDOW_MS = LOG_EXPORT_MAX_WINDOW_DAYS * 24 * 60 * 60 * 1e3;
2902
+ LOG_EXPORT_URL_TTL_SECONDS = 24 * 60 * 60;
2903
+ LOG_EXPORT_FILE_RETENTION_DAYS = 7;
2904
+ LOG_EXPORT_FILE_RETENTION_MS = LOG_EXPORT_FILE_RETENTION_DAYS * 24 * 60 * 60 * 1e3;
2905
+ LOG_EXPORT_PART_MAX_BYTES = 256 * 1024 * 1024;
2906
+ __name(isLogExportSource, "isLogExportSource");
2907
+ __name2(isLogExportSource, "isLogExportSource");
2908
+ LOG_DRAIN_NOTICE_RATE_LIMIT_MS = 60 * 6e4;
2909
+ LOG_DRAIN_VERIFICATION_STALE_MS = 24 * 60 * 6e4;
2910
+ LOG_DRAIN_DIGEST_INTERVAL_MS = 24 * 60 * 6e4;
2911
+ LOG_DRAIN_DIGEST_MAX_ENTRIES = 50;
2912
+ LOG_DRAIN_NOTICE_ERROR_MAX_CHARS = 200;
2913
+ __name(clamp, "clamp");
2914
+ __name2(clamp, "clamp");
2915
+ __name(numberOr, "numberOr");
2916
+ __name2(numberOr, "numberOr");
2917
+ __name(isoOr, "isoOr");
2918
+ __name2(isoOr, "isoOr");
2919
+ __name(logDrainNoticeView, "logDrainNoticeView");
2920
+ __name2(logDrainNoticeView, "logDrainNoticeView");
2921
+ __name(logDrainHealthCardPath, "logDrainHealthCardPath");
2922
+ __name2(logDrainHealthCardPath, "logDrainHealthCardPath");
2923
+ __name(percent, "percent");
2924
+ __name2(percent, "percent");
2925
+ __name(becauseClause, "becauseClause");
2926
+ __name2(becauseClause, "becauseClause");
2927
+ __name(logDrainNoticeCopy, "logDrainNoticeCopy");
2928
+ __name2(logDrainNoticeCopy, "logDrainNoticeCopy");
2929
+ __name(logDrainNoticeLabel, "logDrainNoticeLabel");
2930
+ __name2(logDrainNoticeLabel, "logDrainNoticeLabel");
2931
+ __name(logDrainNoticeDigestCopy, "logDrainNoticeDigestCopy");
2932
+ __name2(logDrainNoticeDigestCopy, "logDrainNoticeDigestCopy");
2933
+ LOG_DRAIN_USAGE_LINE_ITEM = "log_drain_events";
2934
+ LOG_DRAIN_BYTES_PER_GIB = 1024 ** 3;
2935
+ DEFAULT_LOG_DRAIN_PLAN_CONFIG = {
2936
+ version: 1,
2937
+ tiers: {
2938
+ team: {
2939
+ ...LOG_DRAIN_QUOTAS.team
2940
+ },
2941
+ business: {
2942
+ ...LOG_DRAIN_QUOTAS.business
2943
+ },
2944
+ enterprise: {
2945
+ ...LOG_DRAIN_QUOTAS.enterprise
2946
+ }
2947
+ },
2948
+ pricing: {
2949
+ team: {
2950
+ includedEventsPerMonth: 0,
2951
+ includedBytesPerMonth: 0,
2952
+ usdPerMillionEvents: 0,
2953
+ usdPerGiB: 0
2954
+ },
2955
+ business: {
2956
+ includedEventsPerMonth: 0,
2957
+ includedBytesPerMonth: 0,
2958
+ usdPerMillionEvents: 0,
2959
+ usdPerGiB: 0
2960
+ },
2961
+ enterprise: {
2962
+ includedEventsPerMonth: 0,
2963
+ includedBytesPerMonth: 0,
2964
+ usdPerMillionEvents: 0,
2965
+ usdPerGiB: 0
2966
+ }
2967
+ }
2968
+ };
2969
+ TIERS = [
2970
+ "team",
2971
+ "business",
2972
+ "enterprise"
2973
+ ];
2974
+ __name(finiteNonNegative, "finiteNonNegative");
2975
+ __name2(finiteNonNegative, "finiteNonNegative");
2976
+ __name(mergeLimits, "mergeLimits");
2977
+ __name2(mergeLimits, "mergeLimits");
2978
+ __name(mergeCard, "mergeCard");
2979
+ __name2(mergeCard, "mergeCard");
2980
+ __name(resolveStoredLogDrainPlanConfig, "resolveStoredLogDrainPlanConfig");
2981
+ __name2(resolveStoredLogDrainPlanConfig, "resolveStoredLogDrainPlanConfig");
2982
+ __name(logDrainPlanTierOverride, "logDrainPlanTierOverride");
2983
+ __name2(logDrainPlanTierOverride, "logDrainPlanTierOverride");
2984
+ __name(logDrainQuotaLimitsFor, "logDrainQuotaLimitsFor");
2985
+ __name2(logDrainQuotaLimitsFor, "logDrainQuotaLimitsFor");
2986
+ __name(logDrainPriceCardFor, "logDrainPriceCardFor");
2987
+ __name2(logDrainPriceCardFor, "logDrainPriceCardFor");
2988
+ __name(priceDrainUsage, "priceDrainUsage");
2989
+ __name2(priceDrainUsage, "priceDrainUsage");
2084
2990
  LOG_CURSOR_MAX_LENGTH = 512;
2085
2991
  LOG_CURSOR_MAX_ID_LENGTH = 128;
2086
2992
  LOG_RELATIVE_TIME_PATTERN = /^(\d{1,9})([smhd])$/;
@@ -3244,6 +4150,236 @@ listed here; never invent a target.`;
3244
4150
  __name2(agentFeatureMergeRuleFromEnv, "agentFeatureMergeRuleFromEnv");
3245
4151
  __name(effectiveAgentFeatures, "effectiveAgentFeatures");
3246
4152
  __name2(effectiveAgentFeatures, "effectiveAgentFeatures");
4153
+ ONBOARDING_FLOW_KEY = "alpha-choose-meet";
4154
+ ONBOARDING_SCHEMA_VERSION = 1;
4155
+ id = z4.string().min(1).max(80).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/);
4156
+ copy = /* @__PURE__ */ __name2((max) => z4.string().max(max), "copy");
4157
+ onboardingHeadingSchema = z4.discriminatedUnion("kind", [
4158
+ z4.object({
4159
+ kind: z4.literal("plain"),
4160
+ text: copy(240)
4161
+ }).strict(),
4162
+ z4.object({
4163
+ kind: z4.literal("highlighted"),
4164
+ before: copy(240),
4165
+ highlight: copy(240),
4166
+ after: copy(240)
4167
+ }).strict()
4168
+ ]);
4169
+ onboardingRichTextInlineSchema = z4.discriminatedUnion("kind", [
4170
+ z4.object({
4171
+ kind: z4.literal("text"),
4172
+ text: copy(2e3),
4173
+ marks: z4.array(z4.enum([
4174
+ "bold",
4175
+ "italic"
4176
+ ])).max(2).refine((marks) => new Set(marks).size === marks.length, "Text marks must be unique").optional()
4177
+ }).strict(),
4178
+ z4.object({
4179
+ kind: z4.literal("lineBreak")
4180
+ }).strict()
4181
+ ]);
4182
+ onboardingRichTextSchema = z4.object({
4183
+ blocks: z4.array(z4.object({
4184
+ kind: z4.literal("paragraph"),
4185
+ content: z4.array(onboardingRichTextInlineSchema).max(100)
4186
+ }).strict()).max(40)
4187
+ }).strict();
4188
+ onboardingDestinationSchema = z4.discriminatedUnion("kind", [
4189
+ z4.object({
4190
+ kind: z4.literal("question"),
4191
+ questionId: id
4192
+ }).strict(),
4193
+ z4.object({
4194
+ kind: z4.literal("template"),
4195
+ templateContentId: id
4196
+ }).strict(),
4197
+ z4.object({
4198
+ kind: z4.literal("unavailable"),
4199
+ unavailableId: id
4200
+ }).strict()
4201
+ ]);
4202
+ onboardingArtworkSchema = z4.discriminatedUnion("kind", [
4203
+ z4.object({
4204
+ kind: z4.literal("builtinRing")
4205
+ }).strict(),
4206
+ z4.object({
4207
+ kind: z4.literal("uploaded"),
4208
+ assetId: id,
4209
+ accessibility: z4.discriminatedUnion("kind", [
4210
+ z4.object({
4211
+ kind: z4.literal("decorative")
4212
+ }).strict(),
4213
+ z4.object({
4214
+ kind: z4.literal("described"),
4215
+ altText: copy(500)
4216
+ }).strict()
4217
+ ])
4218
+ }).strict()
4219
+ ]);
4220
+ onboardingAnswerSchema = z4.object({
4221
+ id,
4222
+ label: copy(160),
4223
+ supportingText: copy(500).optional(),
4224
+ destination: onboardingDestinationSchema.nullable()
4225
+ }).strict();
4226
+ onboardingQuestionSchema = z4.object({
4227
+ id,
4228
+ heading: onboardingHeadingSchema,
4229
+ helperText: onboardingRichTextSchema.optional(),
4230
+ continueButtonLabel: copy(80),
4231
+ answers: z4.array(onboardingAnswerSchema).max(30)
4232
+ }).strict();
4233
+ onboardingTemplateSectionSchema = z4.object({
4234
+ id,
4235
+ label: copy(100),
4236
+ body: onboardingRichTextSchema
4237
+ }).strict();
4238
+ onboardingTemplateContentSchema = z4.object({
4239
+ id,
4240
+ templateId: copy(160),
4241
+ displayName: copy(100),
4242
+ eyebrow: copy(100).optional(),
4243
+ heading: onboardingHeadingSchema,
4244
+ description: onboardingRichTextSchema,
4245
+ badges: z4.array(copy(80)).max(12),
4246
+ sections: z4.array(onboardingTemplateSectionSchema).max(20),
4247
+ artwork: onboardingArtworkSchema,
4248
+ hireButtonLabel: copy(80),
4249
+ changeRoleButtonLabel: copy(80),
4250
+ nextStepText: onboardingRichTextSchema
4251
+ }).strict();
4252
+ onboardingUnavailableOutcomeSchema = z4.object({
4253
+ id,
4254
+ heading: onboardingHeadingSchema,
4255
+ explanation: onboardingRichTextSchema,
4256
+ backButtonLabel: copy(80),
4257
+ alternative: z4.object({
4258
+ templateContentId: id,
4259
+ introduction: onboardingRichTextSchema,
4260
+ buttonLabel: copy(80)
4261
+ }).strict().optional()
4262
+ }).strict();
4263
+ onboardingFlowSchema = z4.object({
4264
+ key: z4.literal(ONBOARDING_FLOW_KEY),
4265
+ schemaVersion: z4.literal(ONBOARDING_SCHEMA_VERSION),
4266
+ entryQuestionId: id.nullable(),
4267
+ questions: z4.array(onboardingQuestionSchema).max(100),
4268
+ templateContents: z4.array(onboardingTemplateContentSchema).max(100),
4269
+ unavailableOutcomes: z4.array(onboardingUnavailableOutcomeSchema).max(100)
4270
+ }).strict();
4271
+ onboardingActorSchema = z4.object({
4272
+ subjectId: z4.string(),
4273
+ email: z4.string().email()
4274
+ }).strict();
4275
+ onboardingEditorSchema = onboardingActorSchema.extend({
4276
+ editedAt: z4.string().datetime({
4277
+ offset: true
4278
+ })
4279
+ }).strict();
4280
+ onboardingPublicationSummarySchema = z4.object({
4281
+ publicationId: id,
4282
+ revision: z4.number().int().positive(),
4283
+ sourceDraftVersion: z4.number().int().nonnegative(),
4284
+ contentHash: z4.string().regex(/^[a-f0-9]{64}$/),
4285
+ publishedAt: z4.string().datetime({
4286
+ offset: true
4287
+ }),
4288
+ publishedBy: onboardingActorSchema,
4289
+ questionCount: z4.number().int().nonnegative(),
4290
+ templateCount: z4.number().int().nonnegative(),
4291
+ unavailableCount: z4.number().int().nonnegative()
4292
+ }).strict();
4293
+ onboardingValidationIssueSchema = z4.object({
4294
+ code: z4.string(),
4295
+ path: z4.string(),
4296
+ message: z4.string()
4297
+ }).strict();
4298
+ onboardingValidationResponseSchema = z4.discriminatedUnion("valid", [
4299
+ z4.object({
4300
+ valid: z4.literal(true),
4301
+ summary: z4.object({
4302
+ questionCount: z4.number().int().nonnegative(),
4303
+ templateCount: z4.number().int().nonnegative(),
4304
+ unavailableCount: z4.number().int().nonnegative()
4305
+ }).strict()
4306
+ }).strict(),
4307
+ z4.object({
4308
+ valid: z4.literal(false),
4309
+ issues: z4.array(onboardingValidationIssueSchema)
4310
+ }).strict()
4311
+ ]);
4312
+ onboardingAssetSchema = z4.object({
4313
+ assetId: id,
4314
+ url: z4.string().url(),
4315
+ width: z4.number().int().positive(),
4316
+ height: z4.number().int().positive(),
4317
+ contentType: z4.enum([
4318
+ "image/png",
4319
+ "image/jpeg",
4320
+ "image/webp"
4321
+ ]),
4322
+ bytes: z4.number().int().positive(),
4323
+ sha256: z4.string().regex(/^[a-f0-9]{64}$/),
4324
+ createdAt: z4.string().datetime({
4325
+ offset: true
4326
+ }),
4327
+ uploadedBy: onboardingActorSchema
4328
+ }).strict();
4329
+ onboardingPublicAssetSchema = onboardingAssetSchema.pick({
4330
+ assetId: true,
4331
+ url: true,
4332
+ width: true,
4333
+ height: true,
4334
+ contentType: true
4335
+ }).strict();
4336
+ getOnboardingConfigResponseSchema = z4.object({
4337
+ flowKey: z4.literal(ONBOARDING_FLOW_KEY),
4338
+ draftVersion: z4.number().int().nonnegative(),
4339
+ draft: onboardingFlowSchema,
4340
+ assets: z4.array(onboardingAssetSchema),
4341
+ lastEditor: onboardingEditorSchema.nullable(),
4342
+ activePublication: onboardingPublicationSummarySchema.nullable()
4343
+ }).strict();
4344
+ saveOnboardingDraftRequestSchema = z4.object({
4345
+ expectedDraftVersion: z4.number().int().nonnegative(),
4346
+ draft: onboardingFlowSchema
4347
+ }).strict();
4348
+ validateOnboardingRequestSchema = z4.object({
4349
+ draft: onboardingFlowSchema
4350
+ }).strict();
4351
+ publishOnboardingRequestSchema = z4.object({
4352
+ expectedDraftVersion: z4.number().int().nonnegative(),
4353
+ expectedActivePublicationId: id.nullable()
4354
+ }).strict();
4355
+ rollbackOnboardingRequestSchema = z4.object({
4356
+ publicationId: id,
4357
+ expectedActivePublicationId: id.nullable()
4358
+ }).strict();
4359
+ onboardingTemplateCatalogItemSchema = z4.object({
4360
+ templateId: z4.string(),
4361
+ name: z4.string(),
4362
+ description: z4.string().optional()
4363
+ }).strict();
4364
+ getPublishedOnboardingResponseSchema = z4.discriminatedUnion("status", [
4365
+ z4.object({
4366
+ status: z4.literal("available"),
4367
+ publicationId: id,
4368
+ revision: z4.number().int().positive(),
4369
+ contentHash: z4.string().regex(/^[a-f0-9]{64}$/),
4370
+ flow: onboardingFlowSchema,
4371
+ assets: z4.array(onboardingPublicAssetSchema)
4372
+ }).strict(),
4373
+ z4.object({
4374
+ status: z4.literal("unavailable"),
4375
+ reason: z4.literal("not_published"),
4376
+ message: z4.string()
4377
+ }).strict()
4378
+ ]);
4379
+ __name(parseOnboardingFlow, "parseOnboardingFlow");
4380
+ __name2(parseOnboardingFlow, "parseOnboardingFlow");
4381
+ __name(parsePublishedOnboardingResponse, "parsePublishedOnboardingResponse");
4382
+ __name2(parsePublishedOnboardingResponse, "parsePublishedOnboardingResponse");
3247
4383
  }
3248
4384
  });
3249
4385
 
@@ -3251,9 +4387,9 @@ listed here; never invent a target.`;
3251
4387
  function effectiveJobTools(jobTools, readOnly) {
3252
4388
  const base = jobTools?.length ? jobTools : WORKFLOW_JOB_DEFAULT_TOOLS;
3253
4389
  const out = [];
3254
- for (const id of base) {
3255
- if (readOnly && WORKFLOW_JOB_READ_ONLY_DROPPED.includes(id)) continue;
3256
- if (!out.includes(id)) out.push(id);
4390
+ for (const id2 of base) {
4391
+ if (readOnly && WORKFLOW_JOB_READ_ONLY_DROPPED.includes(id2)) continue;
4392
+ if (!out.includes(id2)) out.push(id2);
3257
4393
  }
3258
4394
  return out;
3259
4395
  }
@@ -3297,7 +4433,7 @@ var init_workflow_job_tools = __esm({
3297
4433
 
3298
4434
  // ../workflow-graph/dist/index.mjs
3299
4435
  import { createHash } from "crypto";
3300
- import { z as z4 } from "zod";
4436
+ import { z as z5 } from "zod";
3301
4437
  import { z as z22 } from "zod";
3302
4438
  import { createHash as createHash2 } from "crypto";
3303
4439
  function isMapConfigObject(v) {
@@ -3424,9 +4560,9 @@ function malformedMapMembers(cfg) {
3424
4560
  }
3425
4561
  return out;
3426
4562
  }
3427
- function mapMemberMalformedMessage(id, m) {
4563
+ function mapMemberMalformedMessage(id2, m) {
3428
4564
  const keys = m.keys.map((k) => `\`${k}\``).join(", ");
3429
- return `"${id}".${m.member} carries descriptor key${m.keys.length === 1 ? "" : "s"} ${keys} but is not an exact binding form ({initData:true, path} | {step, path[, rows]} | {value} | {template} | {requestContextPath} | {knowledge}) \u2014 it is passed to the step verbatim as a literal; fix the descriptor, or wrap it in {value: \u2026} if the literal is intended`;
4565
+ return `"${id2}".${m.member} carries descriptor key${m.keys.length === 1 ? "" : "s"} ${keys} but is not an exact binding form ({initData:true, path} | {step, path[, rows]} | {value} | {template} | {requestContextPath} | {knowledge}) \u2014 it is passed to the step verbatim as a literal; fix the descriptor, or wrap it in {value: \u2026} if the literal is intended`;
3430
4566
  }
3431
4567
  function resolveDescriptor(key, m, ctx) {
3432
4568
  if (!isMapDescriptor(m)) return {
@@ -3780,11 +4916,11 @@ function retryBackoffs() {
3780
4916
  }
3781
4917
  return WORKFLOW_RETRY_BACKOFFS;
3782
4918
  }
3783
- function sleepUntilUnsupportedMessage(id) {
3784
- return `the engine does not execute \`sleepUntil\` yet (node "${id}") \u2014 replace it with a \`sleep\` node with a \`duration\` in ms, e.g. { type: 'sleep', id: '${id}', duration: ${SLEEP_UNTIL_REPLACEMENT.duration} }`;
4919
+ function sleepUntilUnsupportedMessage(id2) {
4920
+ return `the engine does not execute \`sleepUntil\` yet (node "${id2}") \u2014 replace it with a \`sleep\` node with a \`duration\` in ms, e.g. { type: 'sleep', id: '${id2}', duration: ${SLEEP_UNTIL_REPLACEMENT.duration} }`;
3785
4921
  }
3786
- function armSubrunUnsupportedMessage(id, workflowId) {
3787
- 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)`;
4922
+ function armSubrunUnsupportedMessage(id2, workflowId) {
4923
+ return `the engine does not execute the implicit \`${workflowId}\` arm subrun (node "${id2}") \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)`;
3788
4924
  }
3789
4925
  function fillPolicy(node, defaultTimeout) {
3790
4926
  if (node.tier === void 0 && node.workspace !== void 0 && node.workspace !== "inherit") node.tier = "job";
@@ -4044,20 +5180,20 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4044
5180
  const seen = /* @__PURE__ */ new Map();
4045
5181
  let nodeCount = 0;
4046
5182
  const upstream = /* @__PURE__ */ new Set();
4047
- const checkId = /* @__PURE__ */ __name4((id, path3) => {
5183
+ const checkId = /* @__PURE__ */ __name4((id2, path3) => {
4048
5184
  nodeCount += 1;
4049
- if (seen.has(id)) {
4050
- err("duplicate-step-id", `step id "${id}" is declared twice (first at ${seen.get(id)})`, path3, id);
5185
+ if (seen.has(id2)) {
5186
+ err("duplicate-step-id", `step id "${id2}" is declared twice (first at ${seen.get(id2)})`, path3, id2);
4051
5187
  } else {
4052
- seen.set(id, path3);
5188
+ seen.set(id2, path3);
4053
5189
  }
4054
5190
  }, "checkId");
4055
5191
  const checkPolicyEnums = /* @__PURE__ */ __name4((node, path3) => {
4056
- const id = singleId(node);
5192
+ const id2 = singleId(node);
4057
5193
  const check = /* @__PURE__ */ __name4((member, allowed) => {
4058
5194
  const value22 = node[member];
4059
5195
  if (value22 === void 0 || typeof value22 === "string" && allowed.includes(value22)) return;
4060
- err("invalid-envelope", `\`${member}\` must be ${allowed.map((a) => `'${a}'`).join(" | ")} (got ${JSON.stringify(value22)})`, `${path3}.${member}`, id);
5196
+ err("invalid-envelope", `\`${member}\` must be ${allowed.map((a) => `'${a}'`).join(" | ")} (got ${JSON.stringify(value22)})`, `${path3}.${member}`, id2);
4061
5197
  }, "check");
4062
5198
  check("sideEffects", WORKFLOW_SIDE_EFFECTS);
4063
5199
  check("jobResources", WORKFLOW_JOB_RESOURCES);
@@ -4065,46 +5201,46 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4065
5201
  const checkRetry = /* @__PURE__ */ __name4((node, path3) => {
4066
5202
  const r = node.retry;
4067
5203
  if (!r) return;
4068
- const id = singleId(node);
5204
+ const id2 = singleId(node);
4069
5205
  const unknown = unknownWorkflowRetryMembers(r);
4070
- if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path3}.retry`, id);
5206
+ if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path3}.retry`, id2);
4071
5207
  if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
4072
5208
  const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
4073
- err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path3}.retry.maxAttempts`, id);
5209
+ err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path3}.retry.maxAttempts`, id2);
4074
5210
  }
4075
5211
  const backoffs = retryBackoffs();
4076
5212
  if (r.backoff !== void 0 && !backoffs.includes(r.backoff)) {
4077
5213
  const list = backoffs.map((b) => `'${b}'`).join(" | ");
4078
- err("backoff-invalid", `retry.backoff must be ${list}`, `${path3}.retry.backoff`, id);
5214
+ err("backoff-invalid", `retry.backoff must be ${list}`, `${path3}.retry.backoff`, id2);
4079
5215
  }
4080
5216
  if (r.backoffSeconds !== void 0 && r.backoffSeconds < 0) {
4081
- err("backoff-invalid", "retry.backoffSeconds must be \u2265 0", `${path3}.retry.backoffSeconds`, id);
5217
+ err("backoff-invalid", "retry.backoffSeconds must be \u2265 0", `${path3}.retry.backoffSeconds`, id2);
4082
5218
  }
4083
5219
  if (r.maxBackoffSeconds !== void 0) {
4084
5220
  if (r.backoff !== "exponential") {
4085
- err("backoff-invalid", "retry.maxBackoffSeconds is only meaningful with backoff:'exponential'", `${path3}.retry`, id);
5221
+ err("backoff-invalid", "retry.maxBackoffSeconds is only meaningful with backoff:'exponential'", `${path3}.retry`, id2);
4086
5222
  } else if (r.maxBackoffSeconds <= 0 || r.backoffSeconds !== void 0 && r.maxBackoffSeconds < r.backoffSeconds) {
4087
- err("backoff-invalid", "retry.maxBackoffSeconds must be > 0 and \u2265 backoffSeconds", `${path3}.retry.maxBackoffSeconds`, id);
5223
+ err("backoff-invalid", "retry.maxBackoffSeconds must be > 0 and \u2265 backoffSeconds", `${path3}.retry.maxBackoffSeconds`, id2);
4088
5224
  }
4089
5225
  }
4090
5226
  }, "checkRetry");
4091
5227
  const checkTimeout = /* @__PURE__ */ __name4((node, path3) => {
4092
5228
  const t = node.timeoutSeconds;
4093
5229
  if (t === void 0) return;
4094
- const id = singleId(node);
5230
+ const id2 = singleId(node);
4095
5231
  if (!Number.isInteger(t) || t < 1) {
4096
- err("timeout-out-of-range", `timeoutSeconds must be an integer \u2265 1 (got ${t})`, `${path3}.timeoutSeconds`, id);
5232
+ err("timeout-out-of-range", `timeoutSeconds must be an integer \u2265 1 (got ${t})`, `${path3}.timeoutSeconds`, id2);
4097
5233
  return;
4098
5234
  }
4099
5235
  if (node.tier === "job") {
4100
5236
  const cap = node.type === "agent" ? caps.maxJobTimeoutSeconds : caps.maxJobSegmentSeconds;
4101
5237
  if (t > cap) {
4102
- err("job-timeout-exceeds-cap", `timeoutSeconds ${t} exceeds the Job-tier cap of ${cap} s`, `${path3}.timeoutSeconds`, id);
5238
+ err("job-timeout-exceeds-cap", `timeoutSeconds ${t} exceeds the Job-tier cap of ${cap} s`, `${path3}.timeoutSeconds`, id2);
4103
5239
  } else if (node.type === "agent" && t > caps.maxJobSegmentSeconds && !node.workspace) {
4104
- err("long-job-requires-workspace", `steps longer than 4 h checkpoint to the run workspace \u2014 add workspace:{mount:'rw'} (and workspace on createWorkflow) or split the step`, `${path3}.timeoutSeconds`, id);
5240
+ err("long-job-requires-workspace", `steps longer than 4 h checkpoint to the run workspace \u2014 add workspace:{mount:'rw'} (and workspace on createWorkflow) or split the step`, `${path3}.timeoutSeconds`, id2);
4105
5241
  }
4106
5242
  } else if (t > caps.maxWorkerTimeoutSeconds) {
4107
- err("timeout-exceeds-tier", `timeoutSeconds ${t} exceeds the worker tier's ${caps.maxWorkerTimeoutSeconds} s \u2014 steps longer than 10 min run on the Job tier: add tier:'job' (up to ${caps.maxJobSegmentSeconds} s)`, `${path3}.timeoutSeconds`, id);
5243
+ err("timeout-exceeds-tier", `timeoutSeconds ${t} exceeds the worker tier's ${caps.maxWorkerTimeoutSeconds} s \u2014 steps longer than 10 min run on the Job tier: add tier:'job' (up to ${caps.maxJobSegmentSeconds} s)`, `${path3}.timeoutSeconds`, id2);
4108
5244
  }
4109
5245
  }, "checkTimeout");
4110
5246
  const checkSpecialistRole = /* @__PURE__ */ __name4((node, path3) => {
@@ -4168,32 +5304,32 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4168
5304
  return void 0;
4169
5305
  }, "jobClassifiablePin");
4170
5306
  const checkTier = /* @__PURE__ */ __name4((node, path3) => {
4171
- const id = singleId(node);
5307
+ const id2 = singleId(node);
4172
5308
  if (node.workspace && node.workspace !== "inherit" && node.tier !== void 0 && node.tier !== "job") {
4173
- err("workspace-requires-job-tier", "a step mounting a workspace must be tier:'job'", `${path3}.workspace`, id);
5309
+ err("workspace-requires-job-tier", "a step mounting a workspace must be tier:'job'", `${path3}.workspace`, id2);
4174
5310
  }
4175
5311
  if (node.harness !== void 0 && node.tier !== "job") {
4176
- err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path3}.harness`, id);
5312
+ err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path3}.harness`, id2);
4177
5313
  }
4178
5314
  const provider = node.type === "agent" ? classifyModelProvider(jobClassifiablePin(node.model)) : null;
4179
5315
  if (node.harness === "claude-code" && provider !== null && provider !== "anthropic") {
4180
- err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path3}.harness`, id);
5316
+ err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path3}.harness`, id2);
4181
5317
  }
4182
5318
  if (isJobTier(node) && provider !== null && opts.policy?.jobProviders && !opts.policy.jobProviders.includes(provider)) {
4183
- err("job-tier-provider-unsupported", `model provider '${provider}' is outside LUA_WF_JOB_PROVIDERS [${opts.policy.jobProviders.join(", ")}]`, `${path3}.model`, id);
5319
+ err("job-tier-provider-unsupported", `model provider '${provider}' is outside LUA_WF_JOB_PROVIDERS [${opts.policy.jobProviders.join(", ")}]`, `${path3}.model`, id2);
4184
5320
  }
4185
5321
  }, "checkTier");
4186
5322
  const checkModel = /* @__PURE__ */ __name4((node, path3) => {
4187
5323
  if (node.type !== "agent" || typeof node.model !== "string") return;
4188
- const id = singleId(node);
5324
+ const id2 = singleId(node);
4189
5325
  const parsed = parseModelTemplate(node.model);
4190
5326
  if (parsed.kind === "invalid") {
4191
- err("model-template-invalid", parsed.message, `${path3}.model`, id);
5327
+ err("model-template-invalid", parsed.message, `${path3}.model`, id2);
4192
5328
  return;
4193
5329
  }
4194
5330
  if (parsed.kind === "template" && parsed.template.default === void 0) {
4195
5331
  if (isJobTier(node)) {
4196
- err("model-template-default-required", modelTemplateDefaultRequiredMessage(node.model), `${path3}.model`, id);
5332
+ err("model-template-default-required", modelTemplateDefaultRequiredMessage(node.model), `${path3}.model`, id2);
4197
5333
  }
4198
5334
  return;
4199
5335
  }
@@ -4206,12 +5342,12 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4206
5342
  if (registry === "unavailable") {
4207
5343
  const trimmed = pin.trim();
4208
5344
  if (trimmed && !normalizeModelId(trimmed, []).ok) {
4209
- 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)`), `${path3}.model`, id);
5345
+ 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)`), `${path3}.model`, id2);
4210
5346
  }
4211
5347
  return;
4212
5348
  }
4213
5349
  const resolved = normalizeModelId(pin, registry);
4214
- if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path3}.model`, id);
5350
+ if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path3}.model`, id2);
4215
5351
  }, "checkModel");
4216
5352
  const checkTaskClass = /* @__PURE__ */ __name4((node, path3) => {
4217
5353
  if (node.type !== "agent" || node.taskClass === void 0) return;
@@ -4220,46 +5356,46 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4220
5356
  err("task-class-without-model", `taskClass '${String(node.taskClass)}' needs a \`model\` on a pushed definition \u2014 write a class (model: 'class/fast' | 'class/balanced' | 'class/strong') or an approved provider/model code; nothing maps a task class to a model at dispatch, so a step with neither would run on the agent\u2019s own model`, `${path3}.taskClass`, singleId(node));
4221
5357
  }, "checkTaskClass");
4222
5358
  const checkWorkspace = /* @__PURE__ */ __name4((node, path3) => {
4223
- const id = singleId(node);
5359
+ const id2 = singleId(node);
4224
5360
  const ws = workspaceOf(node);
4225
5361
  if (isJobTier(node) && opts.policy && opts.policy.jobTier !== true) {
4226
- err("job-tier-disabled", `"${id}" runs on the Job tier but the org's workflowPolicy.jobTier is off \u2014 an org admin enables it (lua features workflows.caps.jobTier true)`, `${path3}.tier`, id);
5362
+ err("job-tier-disabled", `"${id2}" runs on the Job tier but the org's workflowPolicy.jobTier is off \u2014 an org admin enables it (lua features workflows.caps.jobTier true)`, `${path3}.tier`, id2);
4227
5363
  }
4228
5364
  const tools = jobToolsOf(node);
4229
5365
  if (tools !== void 0) {
4230
5366
  if (!isJobTier(node)) {
4231
- err("job-tools-require-job-tier", "`jobTools` needs tier:'job'", `${path3}.jobTools`, id);
5367
+ err("job-tools-require-job-tier", "`jobTools` needs tier:'job'", `${path3}.jobTools`, id2);
4232
5368
  }
4233
5369
  const unknown = (Array.isArray(tools) ? tools : [
4234
5370
  tools
4235
5371
  ]).filter((t) => !WORKFLOW_JOB_TOOLS.includes(t));
4236
5372
  if (unknown.length > 0) {
4237
- err("job-tools-unknown", `jobTools ${JSON.stringify(unknown)} outside WORKFLOW_JOB_TOOLS [${WORKFLOW_JOB_TOOLS.join(", ")}]`, `${path3}.jobTools`, id);
5373
+ err("job-tools-unknown", `jobTools ${JSON.stringify(unknown)} outside WORKFLOW_JOB_TOOLS [${WORKFLOW_JOB_TOOLS.join(", ")}]`, `${path3}.jobTools`, id2);
4238
5374
  }
4239
5375
  if (node.type === "agent" && (Array.isArray(tools) ? tools : [
4240
5376
  tools
4241
5377
  ]).includes("gh")) {
4242
- warn("gh-on-coding-turn", `"${id}" grants the gh tool on a coding turn \u2014 the pod can open/merge PRs on the workspace repo (purpose:'gh' token, pull_requests:write + contents:write)`, `${path3}.jobTools`, id);
5378
+ warn("gh-on-coding-turn", `"${id2}" grants the gh tool on a coding turn \u2014 the pod can open/merge PRs on the workspace repo (purpose:'gh' token, pull_requests:write + contents:write)`, `${path3}.jobTools`, id2);
4243
5379
  }
4244
5380
  }
4245
5381
  if (node.type === "agent" && ws && ws !== "inherit" && ws.mount === "ro" && Array.isArray(tools) && effectiveJobTools(tools, true).length === 0) {
4246
- warn("ro-step-has-no-tools", `"${id}" mounts the workspace read-only and every jobTool it declares (${JSON.stringify(tools)}) is one the ro mount drops [${WORKFLOW_JOB_READ_ONLY_DROPPED.join(", ")}] \u2014 the coding turn would run with no tools at all; keep a read-only tool (read/glob/grep, gh) or mount rw`, `${path3}.jobTools`, id);
5382
+ warn("ro-step-has-no-tools", `"${id2}" mounts the workspace read-only and every jobTool it declares (${JSON.stringify(tools)}) is one the ro mount drops [${WORKFLOW_JOB_READ_ONLY_DROPPED.join(", ")}] \u2014 the coding turn would run with no tools at all; keep a read-only tool (read/glob/grep, gh) or mount rw`, `${path3}.jobTools`, id2);
4247
5383
  }
4248
5384
  if (ws && ws !== "inherit") {
4249
5385
  if (!envelopeWorkspace && !opts.mayInherit) {
4250
- err("workspace-not-declared", `"${id}" mounts a workspace but the workflow declares none \u2014 add workspace:{kind, \u2026} on createWorkflow`, `${path3}.workspace`, id);
5386
+ err("workspace-not-declared", `"${id2}" mounts a workspace but the workflow declares none \u2014 add workspace:{kind, \u2026} on createWorkflow`, `${path3}.workspace`, id2);
4251
5387
  }
4252
5388
  if (ws.isolation === "worktree" && envelopeWorkspace?.kind === "empty") {
4253
- err("worktree-requires-git-workspace", `"${id}": isolation:'worktree' needs a kind:'git' workspace (the envelope declares kind:'empty')`, `${path3}.workspace.isolation`, id);
5389
+ err("worktree-requires-git-workspace", `"${id2}": isolation:'worktree' needs a kind:'git' workspace (the envelope declares kind:'empty')`, `${path3}.workspace.isolation`, id2);
4254
5390
  }
4255
5391
  }
4256
5392
  if (node.type === "workflow" && ws === "inherit") {
4257
5393
  if (!envelopeWorkspace) {
4258
- err("workspace-inherit-without-parent-workspace", `"${id}": workspace:'inherit' but the parent workflow declares no workspace \u2014 there is nothing to inherit`, `${path3}.workspace`, id);
5394
+ err("workspace-inherit-without-parent-workspace", `"${id2}": workspace:'inherit' but the parent workflow declares no workspace \u2014 there is nothing to inherit`, `${path3}.workspace`, id2);
4259
5395
  }
4260
5396
  const child = opts.resolveWorkflow?.(node.workflowId);
4261
5397
  if (child?.workspace) {
4262
- err("workspace-inherit-conflict", `"${id}": workspace:'inherit' on "${node.workflowId}", which declares its own workspace`, `${path3}.workspace`, id);
5398
+ err("workspace-inherit-conflict", `"${id2}": workspace:'inherit' on "${node.workflowId}", which declares its own workspace`, `${path3}.workspace`, id2);
4263
5399
  }
4264
5400
  }
4265
5401
  }, "checkWorkspace");
@@ -4268,20 +5404,20 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4268
5404
  const schema = node.type === "step" ? node.step.outputSchema : node.type === "agent" ? node.outputSchema : void 0;
4269
5405
  if (schema !== void 0) outputSchemas.set(singleId(node), schema);
4270
5406
  }, "recordOutputSchema");
4271
- const checkMapMembers = /* @__PURE__ */ __name4((cfg, basePath, id) => {
5407
+ const checkMapMembers = /* @__PURE__ */ __name4((cfg, basePath, id2) => {
4272
5408
  for (const m of malformedMapMembers(cfg)) {
4273
- warn(MAP_MEMBER_MALFORMED_CODE, mapMemberMalformedMessage(id, m), `${basePath}.${m.member}`, id);
5409
+ warn(MAP_MEMBER_MALFORMED_CODE, mapMemberMalformedMessage(id2, m), `${basePath}.${m.member}`, id2);
4274
5410
  }
4275
5411
  }, "checkMapMembers");
4276
5412
  const checkInputShape = /* @__PURE__ */ __name4((node, path3) => {
4277
5413
  const input = node.input;
4278
5414
  if (input === void 0) return;
4279
- const id = singleId(node);
5415
+ const id2 = singleId(node);
4280
5416
  if (input !== null && typeof input === "object" && !Array.isArray(input)) {
4281
- checkMapMembers(input, `${path3}.input`, id);
5417
+ checkMapMembers(input, `${path3}.input`, id2);
4282
5418
  return;
4283
5419
  }
4284
- 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)})`, `${path3}.input`, id);
5420
+ 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)})`, `${path3}.input`, id2);
4285
5421
  }, "checkInputShape");
4286
5422
  const checkBodyInput = /* @__PURE__ */ __name4((body, path3, container) => {
4287
5423
  if (body.type === "workflow" || body.input === void 0) return;
@@ -4572,7 +5708,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4572
5708
  default:
4573
5709
  err("invalid-envelope", `unknown entry type "${entry.type}"`, path3);
4574
5710
  }
4575
- for (const id of declared) upstream.add(id);
5711
+ for (const id2 of declared) upstream.add(id2);
4576
5712
  });
4577
5713
  if (nodeCount > caps.maxNodes) {
4578
5714
  err("cap-exceeded", `${nodeCount} nodes exceeds the static cap of ${caps.maxNodes}`, "definition.graph");
@@ -4647,19 +5783,19 @@ function hashGraph(g) {
4647
5783
  function compilePlan(g) {
4648
5784
  const steps = {};
4649
5785
  const order = [];
4650
- const addNode = /* @__PURE__ */ __name4((id, node) => {
4651
- if (id in steps) {
4652
- throw new WorkflowPlanError("duplicate-step-id", `Duplicate step id "${id}" in definition.graph`);
5786
+ const addNode = /* @__PURE__ */ __name4((id2, node) => {
5787
+ if (id2 in steps) {
5788
+ throw new WorkflowPlanError("duplicate-step-id", `Duplicate step id "${id2}" in definition.graph`);
4653
5789
  }
4654
- steps[id] = node;
4655
- order.push(id);
5790
+ steps[id2] = node;
5791
+ order.push(id2);
4656
5792
  }, "addNode");
4657
5793
  let prevTails = [];
4658
5794
  const foreachJoinToEntry = /* @__PURE__ */ new Map();
4659
5795
  g.definition.graph.forEach((entry, entryIndex) => {
4660
5796
  if (isArmStep(entry)) {
4661
- const id = armStepId(entry);
4662
- addNode(id, {
5797
+ const id2 = armStepId(entry);
5798
+ addNode(id2, {
4663
5799
  kind: armStepKind(entry),
4664
5800
  dependsOn: prevTails,
4665
5801
  downstream: [],
@@ -4667,7 +5803,7 @@ function compilePlan(g) {
4667
5803
  entry
4668
5804
  });
4669
5805
  prevTails = [
4670
- id
5806
+ id2
4671
5807
  ];
4672
5808
  return;
4673
5809
  }
@@ -4806,10 +5942,10 @@ function compilePlan(g) {
4806
5942
  throw new WorkflowPlanError("unknown-entry-type", `Unknown graph entry type "${entry.type}" at definition.graph[${entryIndex}]`);
4807
5943
  }
4808
5944
  });
4809
- for (const id of order) {
4810
- for (const dep of steps[id].dependsOn) {
5945
+ for (const id2 of order) {
5946
+ for (const dep of steps[id2].dependsOn) {
4811
5947
  const target = steps[dep] ?? (foreachJoinToEntry.has(dep) ? steps[foreachJoinToEntry.get(dep)] : void 0);
4812
- target?.downstream.push(id);
5948
+ target?.downstream.push(id2);
4813
5949
  }
4814
5950
  }
4815
5951
  return {
@@ -4975,15 +6111,15 @@ function renderRef(ref) {
4975
6111
  return ref.path;
4976
6112
  }
4977
6113
  function step(s) {
4978
- const id = stepIdOf(s);
6114
+ const id2 = stepIdOf(s);
4979
6115
  return {
4980
6116
  path: /* @__PURE__ */ __name4((p) => ({
4981
- path: p === "" ? `stepResults.${id}` : `stepResults.${id}.${p}`
6117
+ path: p === "" ? `stepResults.${id2}` : `stepResults.${id2}.${p}`
4982
6118
  }), "path")
4983
6119
  };
4984
6120
  }
4985
- function stepOf(id) {
4986
- return step(id);
6121
+ function stepOf(id2) {
6122
+ return step(id2);
4987
6123
  }
4988
6124
  function init(path3) {
4989
6125
  return {
@@ -5065,18 +6201,18 @@ function resolvePlacements(calls) {
5065
6201
  const declared = /* @__PURE__ */ new Map();
5066
6202
  const placedBy = /* @__PURE__ */ new Map();
5067
6203
  const allIds = /* @__PURE__ */ new Map();
5068
- const claimId = /* @__PURE__ */ __name4((id, callIndex) => {
5069
- const first = allIds.get(id);
6204
+ const claimId = /* @__PURE__ */ __name4((id2, callIndex) => {
6205
+ const first = allIds.get(id2);
5070
6206
  if (first !== void 0 && first !== callIndex) {
5071
6207
  issues.push({
5072
6208
  code: "duplicate-step-id",
5073
- message: `step id "${id}" is declared more than once (calls #${first} and #${callIndex})`,
6209
+ message: `step id "${id2}" is declared more than once (calls #${first} and #${callIndex})`,
5074
6210
  callIndex,
5075
- stepId: id
6211
+ stepId: id2
5076
6212
  });
5077
6213
  return;
5078
6214
  }
5079
- allIds.set(id, callIndex);
6215
+ allIds.set(id2, callIndex);
5080
6216
  }, "claimId");
5081
6217
  calls.forEach((call, i) => {
5082
6218
  switch (call.kind) {
@@ -5088,7 +6224,7 @@ function resolvePlacements(calls) {
5088
6224
  });
5089
6225
  break;
5090
6226
  case "entry":
5091
- for (const id of entryIds(call.entry)) claimId(id, i);
6227
+ for (const id2 of entryIds(call.entry)) claimId(id2, i);
5092
6228
  break;
5093
6229
  case "parallel":
5094
6230
  for (const arm of call.arms) if ("node" in arm) claimId(nodeIdOf(arm.node), i);
@@ -5107,42 +6243,42 @@ function resolvePlacements(calls) {
5107
6243
  });
5108
6244
  const armMapPlacementIssue = /* @__PURE__ */ __name4((node, ref, i, container) => {
5109
6245
  if (!ref.armMap || node.type === "mapping" || isHitlNode2(node)) return void 0;
5110
- const id = nodeIdOf(node);
6246
+ const id2 = nodeIdOf(node);
5111
6247
  if ((container === "foreach" || container === "loop") && node.type !== "workflow") {
5112
6248
  return {
5113
6249
  code: "mapping-placement",
5114
- 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`,
6250
+ message: container === "foreach" ? `foreach body "${id2}": 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 "${id2}": a [map, step] body is not supported \u2014 the body receives the previous output as its input; put the .map() before the loop instead`,
5115
6251
  callIndex: i,
5116
- stepId: id
6252
+ stepId: id2
5117
6253
  };
5118
6254
  }
5119
6255
  if (node.input !== void 0) {
5120
6256
  return {
5121
6257
  code: "mapping-placement",
5122
- 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)`,
6258
+ message: `"${id2}": 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)`,
5123
6259
  callIndex: i,
5124
- stepId: id
6260
+ stepId: id2
5125
6261
  };
5126
6262
  }
5127
6263
  return void 0;
5128
6264
  }, "armMapPlacementIssue");
5129
6265
  const hitlPlacementIssue = /* @__PURE__ */ __name4((node, ref, i, container) => {
5130
6266
  if (!isHitlNode2(node)) return void 0;
5131
- const id = node.id;
6267
+ const id2 = node.id;
5132
6268
  if (ref.armMap) {
5133
6269
  return {
5134
6270
  code: "node-type-unsupported-in-container",
5135
- message: workflowHitlArmShapeMessage(node.type, id, "mapped-arm"),
6271
+ message: workflowHitlArmShapeMessage(node.type, id2, "mapped-arm"),
5136
6272
  callIndex: i,
5137
- stepId: id
6273
+ stepId: id2
5138
6274
  };
5139
6275
  }
5140
6276
  if (container !== "place" && !workflowContainerRunsHitlArm(container)) {
5141
6277
  return {
5142
6278
  code: "node-type-unsupported-in-container",
5143
- message: workflowHitlArmUnsupportedMessage(node.type, id, container),
6279
+ message: workflowHitlArmUnsupportedMessage(node.type, id2, container),
5144
6280
  callIndex: i,
5145
- stepId: id
6281
+ stepId: id2
5146
6282
  };
5147
6283
  }
5148
6284
  return void 0;
@@ -5248,8 +6384,8 @@ function resolvePlacements(calls) {
5248
6384
  graph.push(call.entry);
5249
6385
  return;
5250
6386
  case "declare": {
5251
- const id = nodeIdOf(call.node);
5252
- if (placedBy.has(id)) return;
6387
+ const id2 = nodeIdOf(call.node);
6388
+ if (placedBy.has(id2)) return;
5253
6389
  graph.push(call.node);
5254
6390
  return;
5255
6391
  }
@@ -5380,14 +6516,14 @@ function seedLedgerFromRun(run, steps, targetPlan, opts = {}) {
5380
6516
  const seeded = [];
5381
6517
  const unseeded = [];
5382
6518
  const known = new Set(Object.keys(targetPlan.steps));
5383
- const parentOf = /* @__PURE__ */ __name4((id) => {
5384
- const m = /^(.*)(\[\d+\]|#\d+)$/.exec(id);
6519
+ const parentOf = /* @__PURE__ */ __name4((id2) => {
6520
+ const m = /^(.*)(\[\d+\]|#\d+)$/.exec(id2);
5385
6521
  return m ? m[1] : void 0;
5386
6522
  }, "parentOf");
5387
- const dependsOf = /* @__PURE__ */ __name4((id) => {
5388
- const node = targetPlan.steps[id];
6523
+ const dependsOf = /* @__PURE__ */ __name4((id2) => {
6524
+ const node = targetPlan.steps[id2];
5389
6525
  if (node) return node.dependsOn;
5390
- const parent = parentOf(id);
6526
+ const parent = parentOf(id2);
5391
6527
  return parent && targetPlan.steps[parent] ? [
5392
6528
  parent
5393
6529
  ] : [];
@@ -5400,23 +6536,23 @@ function seedLedgerFromRun(run, steps, targetPlan, opts = {}) {
5400
6536
  walk22.push(s.stepId);
5401
6537
  }
5402
6538
  }
5403
- for (const id of walk22) {
5404
- const row = byId.get(id);
6539
+ for (const id2 of walk22) {
6540
+ const row = byId.get(id2);
5405
6541
  if (!row || row.status !== "completed") continue;
5406
- if (!dependsOf(id).every((d) => seededIds.has(d))) {
5407
- unseeded.push(id);
6542
+ if (!dependsOf(id2).every((d) => seededIds.has(d))) {
6543
+ unseeded.push(id2);
5408
6544
  continue;
5409
6545
  }
5410
- seededIds.add(id);
6546
+ seededIds.add(id2);
5411
6547
  seeded.push({
5412
- stepId: id,
6548
+ stepId: id2,
5413
6549
  output: row.output,
5414
6550
  attempt: row.attempt ?? 1,
5415
6551
  effects: row.effects ?? {}
5416
6552
  });
5417
6553
  }
5418
6554
  const dropped = steps.filter((s) => s.status === "completed" && !known.has(s.stepId) && !(parentOf(s.stepId) && known.has(parentOf(s.stepId)))).map((s) => s.stepId);
5419
- const firstPending = targetPlan.order.find((id) => !seededIds.has(id));
6555
+ const firstPending = targetPlan.order.find((id2) => !seededIds.has(id2));
5420
6556
  const graphChanged = !!(opts.targetGraphHash && run.graphHash && opts.targetGraphHash !== run.graphHash);
5421
6557
  return {
5422
6558
  sourceRunId: run.id,
@@ -5471,37 +6607,37 @@ function replayLedger(g, ledger) {
5471
6607
  startedAt: 0,
5472
6608
  ...ledger.requestContext
5473
6609
  };
5474
- const ctxFor = /* @__PURE__ */ __name4((id) => ({
6610
+ const ctxFor = /* @__PURE__ */ __name4((id2) => ({
5475
6611
  initData: ledger.initData,
5476
- stepResults: ancestorResults(plan, id, rows22),
6612
+ stepResults: ancestorResults(plan, id2, rows22),
5477
6613
  state: ledger.state ?? {},
5478
6614
  requestContext
5479
6615
  }), "ctxFor");
5480
6616
  const verdicts = [];
5481
- for (const id of plan.order) {
5482
- const node = plan.steps[id];
5483
- const recorded = rows22.get(id);
6617
+ for (const id2 of plan.order) {
6618
+ const node = plan.steps[id2];
6619
+ const recorded = rows22.get(id2);
5484
6620
  if (!recorded || recorded.status === "pending" || recorded.status === "skipped") continue;
5485
6621
  if (node.kind === "branch") {
5486
6622
  const entry = node.entry;
5487
- const taken = selectBranchArms(branchSpecFromConditional(entry), ctxFor(id));
6623
+ const taken = selectBranchArms(branchSpecFromConditional(entry), ctxFor(id2));
5488
6624
  const recordedTaken = recorded.taken ?? inferTaken(entry, rows22);
5489
6625
  verdicts.push({
5490
- stepId: id,
6626
+ stepId: id2,
5491
6627
  kind: "branch",
5492
6628
  recorded: recordedTaken,
5493
6629
  local: taken,
5494
6630
  diverged: canonical(recordedTaken) !== canonical(taken)
5495
6631
  });
5496
- } else if (node.kind === "map" && !id.endsWith(".join") && recorded.status === "completed") {
6632
+ } else if (node.kind === "map" && !id2.endsWith(".join") && recorded.status === "completed") {
5497
6633
  const entry = node.entry;
5498
- const resolved = resolveMapping(parseMapConfig(entry.mapConfig, id), ctxFor(id));
6634
+ const resolved = resolveMapping(parseMapConfig(entry.mapConfig, id2), ctxFor(id2));
5499
6635
  const local = "error" in resolved ? {
5500
6636
  error: resolved.error,
5501
6637
  key: resolved.key
5502
6638
  } : resolved.value;
5503
6639
  verdicts.push({
5504
- stepId: id,
6640
+ stepId: id2,
5505
6641
  kind: "map",
5506
6642
  recorded: recorded.output,
5507
6643
  local,
@@ -5510,11 +6646,11 @@ function replayLedger(g, ledger) {
5510
6646
  } else if (node.kind === "foreach") {
5511
6647
  const entry = node.entry;
5512
6648
  const source = node.dependsOn[0];
5513
- const items = source ? ctxFor(id).stepResults[source] : void 0;
6649
+ const items = source ? ctxFor(id2).stepResults[source] : void 0;
5514
6650
  const local = Array.isArray(items) ? items.length : void 0;
5515
6651
  const recordedCount = recorded.itemCount ?? countChildren(entry, rows22);
5516
6652
  verdicts.push({
5517
- stepId: id,
6653
+ stepId: id2,
5518
6654
  kind: "foreach",
5519
6655
  recorded: recordedCount,
5520
6656
  local,
@@ -5523,7 +6659,7 @@ function replayLedger(g, ledger) {
5523
6659
  } else if (node.kind === "subrun" && recorded.status === "completed" && recorded.child) {
5524
6660
  const local = subrunSettledOutput(recorded.child);
5525
6661
  verdicts.push({
5526
- stepId: id,
6662
+ stepId: id2,
5527
6663
  kind: "subrun",
5528
6664
  recorded: recorded.output,
5529
6665
  local,
@@ -5549,7 +6685,7 @@ function replayResultOf(row, node) {
5549
6685
  }
5550
6686
  return void 0;
5551
6687
  }
5552
- function ancestorResults(plan, id, rows22) {
6688
+ function ancestorResults(plan, id2, rows22) {
5553
6689
  const out = {};
5554
6690
  const joinAliased = /* @__PURE__ */ new Set();
5555
6691
  const seen = /* @__PURE__ */ new Set();
@@ -5598,7 +6734,7 @@ function ancestorResults(plan, id, rows22) {
5598
6734
  walk22(node.dependsOn);
5599
6735
  }
5600
6736
  }, "walk");
5601
- walk22(plan.steps[id]?.dependsOn ?? []);
6737
+ walk22(plan.steps[id2]?.dependsOn ?? []);
5602
6738
  return out;
5603
6739
  }
5604
6740
  function inferTaken(entry, rows22) {
@@ -5608,15 +6744,15 @@ function inferTaken(entry, rows22) {
5608
6744
  entry.otherwise
5609
6745
  ] : []
5610
6746
  ];
5611
- return arms.map(branchArmId).filter((id) => {
5612
- const r = rows22.get(id);
6747
+ return arms.map(branchArmId).filter((id2) => {
6748
+ const r = rows22.get(id2);
5613
6749
  return r !== void 0 && r.status !== "skipped" && r.status !== "pending";
5614
6750
  });
5615
6751
  }
5616
6752
  function countChildren(entry, rows22) {
5617
6753
  const body = branchArmId(entry.step);
5618
6754
  let n2 = 0;
5619
- for (const id of rows22.keys()) if (id.startsWith(`${body}[`)) n2 += 1;
6755
+ for (const id2 of rows22.keys()) if (id2.startsWith(`${body}[`)) n2 += 1;
5620
6756
  return n2;
5621
6757
  }
5622
6758
  function isTerminalRunStatus(status) {
@@ -6884,8 +8020,8 @@ var init_dist2 = __esm({
6884
8020
  fromKnowledge = /* @__PURE__ */ __name4((k) => ({
6885
8021
  knowledge: k
6886
8022
  }), "fromKnowledge");
6887
- SideEffectsSchema = z4.enum(WORKFLOW_SIDE_EFFECTS);
6888
- JobResourcesSchema = z4.enum(WORKFLOW_JOB_RESOURCES);
8023
+ SideEffectsSchema = z5.enum(WORKFLOW_SIDE_EFFECTS);
8024
+ JobResourcesSchema = z5.enum(WORKFLOW_JOB_RESOURCES);
6889
8025
  WORKFLOW_MODEL_TEMPLATE_ROOT = "initData";
6890
8026
  WORKFLOW_MODEL_TEMPLATE_RE = /^\$\{\s*initData\.([A-Za-z0-9_.\-[\]]+)\s*(?:\|([^}]*))?\}$/;
6891
8027
  PATH_SEGMENT_RE = /^[A-Za-z0-9_-]+(?:\[(?:0|[1-9]\d*)\])*$/;
@@ -7318,7 +8454,7 @@ var init_dist2 = __esm({
7318
8454
  __name(replayLedger, "replayLedger");
7319
8455
  __name4(replayLedger, "replayLedger");
7320
8456
  JOIN = ".join";
7321
- entryOfJoin = /* @__PURE__ */ __name4((id) => id.endsWith(JOIN) ? id.slice(0, -JOIN.length) : void 0, "entryOfJoin");
8457
+ entryOfJoin = /* @__PURE__ */ __name4((id2) => id2.endsWith(JOIN) ? id2.slice(0, -JOIN.length) : void 0, "entryOfJoin");
7322
8458
  __name(replayResultOf, "replayResultOf");
7323
8459
  __name4(replayResultOf, "replayResultOf");
7324
8460
  __name(ancestorResults, "ancestorResults");
@@ -7607,8 +8743,8 @@ function createStep(s) {
7607
8743
  function step2(s) {
7608
8744
  return step(typeof s === "string" ? s : s.id);
7609
8745
  }
7610
- function stepOf2(id) {
7611
- return stepOf(id);
8746
+ function stepOf2(id2) {
8747
+ return stepOf(id2);
7612
8748
  }
7613
8749
  function schemaToJson(schema) {
7614
8750
  if (schema === void 0 || schema === null) return void 0;
@@ -7812,16 +8948,16 @@ var init_workflow = __esm({
7812
8948
  if (!isPredicate(p)) throw new LuaWorkflowBuildError("closure-predicate", `${where}: not a LuaPredicate`, "build predicates with eq/gt/inSet/exists/and/or/not");
7813
8949
  return p;
7814
8950
  }, "assertPredicate");
7815
- assertRetry = /* @__PURE__ */ __name((r, id) => {
8951
+ assertRetry = /* @__PURE__ */ __name((r, id2) => {
7816
8952
  if (!r) return;
7817
8953
  if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
7818
8954
  const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
7819
- throw new LuaWorkflowBuildError(over ? "cap-exceeded" : "invalid-envelope", `"${id}": ${workflowRetryMaxAttemptsMessage(r.maxAttempts)}`);
8955
+ throw new LuaWorkflowBuildError(over ? "cap-exceeded" : "invalid-envelope", `"${id2}": ${workflowRetryMaxAttemptsMessage(r.maxAttempts)}`);
7820
8956
  }
7821
- 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(" | ")}`);
8957
+ if (r.backoff !== void 0 && !WORKFLOW_RETRY_BACKOFFS.includes(r.backoff)) throw new LuaWorkflowBuildError("backoff-invalid", `"${id2}": retry.backoff must be ${WORKFLOW_RETRY_BACKOFFS.map((b) => `'${b}'`).join(" | ")}`);
7822
8958
  if (r.maxBackoffSeconds !== void 0) {
7823
- if (r.backoff !== "exponential") throw new LuaWorkflowBuildError("backoff-invalid", `"${id}": retry.maxBackoffSeconds is only meaningful with backoff:'exponential'`);
7824
- if (r.maxBackoffSeconds <= 0 || r.backoffSeconds !== void 0 && r.maxBackoffSeconds < r.backoffSeconds) throw new LuaWorkflowBuildError("backoff-invalid", `"${id}": retry.maxBackoffSeconds must be > 0 and \u2265 backoffSeconds`);
8959
+ if (r.backoff !== "exponential") throw new LuaWorkflowBuildError("backoff-invalid", `"${id2}": retry.maxBackoffSeconds is only meaningful with backoff:'exponential'`);
8960
+ if (r.maxBackoffSeconds <= 0 || r.backoffSeconds !== void 0 && r.maxBackoffSeconds < r.backoffSeconds) throw new LuaWorkflowBuildError("backoff-invalid", `"${id2}": retry.maxBackoffSeconds must be > 0 and \u2265 backoffSeconds`);
7825
8961
  }
7826
8962
  }, "assertRetry");
7827
8963
  assertTimeout = /* @__PURE__ */ __name((node) => {
@@ -8019,8 +9155,8 @@ var init_workflow = __esm({
8019
9155
  ref: arm
8020
9156
  };
8021
9157
  if (arm && typeof arm === "object" && isHitlEntry(arm)) {
8022
- const id = arm.id;
8023
- throw new LuaWorkflowBuildError("invalid-step", `${where}: an approval / waitForSignal arm is placed by id \u2014 declare it with .approval(${JSON.stringify(id ?? "id")}, \u2026) / .waitForSignal(\u2026) and pass the id string`);
9158
+ const id2 = arm.id;
9159
+ throw new LuaWorkflowBuildError("invalid-step", `${where}: an approval / waitForSignal arm is placed by id \u2014 declare it with .approval(${JSON.stringify(id2 ?? "id")}, \u2026) / .waitForSignal(\u2026) and pass the id string`);
8024
9160
  }
8025
9161
  return {
8026
9162
  node: this.registerStep(arm, where)
@@ -8140,14 +9276,14 @@ var init_workflow = __esm({
8140
9276
  assertNoClosure(mapping, "map()");
8141
9277
  this.recordEnvRefs(mapping);
8142
9278
  this.mapCount += 1;
8143
- let id = opts?.id;
8144
- if (id === void 0) {
9279
+ let id2 = opts?.id;
9280
+ if (id2 === void 0) {
8145
9281
  this.unnamedMaps += 1;
8146
- id = `map_${this.mapCount}`;
9282
+ id2 = `map_${this.mapCount}`;
8147
9283
  }
8148
9284
  const node = {
8149
9285
  type: "mapping",
8150
- id,
9286
+ id: id2,
8151
9287
  mapConfig: canonicalJson(mapping)
8152
9288
  };
8153
9289
  return this.push({
@@ -8158,12 +9294,12 @@ var init_workflow = __esm({
8158
9294
  sleep(ms, opts) {
8159
9295
  if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) throw new LuaWorkflowBuildError("invalid-envelope", "sleep(ms) takes a literal non-negative number");
8160
9296
  this.sleepCount += 1;
8161
- const id = opts?.id ?? `sleep_${this.sleepCount}`;
9297
+ const id2 = opts?.id ?? `sleep_${this.sleepCount}`;
8162
9298
  return this.push({
8163
9299
  kind: "entry",
8164
9300
  entry: defined({
8165
9301
  type: "sleep",
8166
- id,
9302
+ id: id2,
8167
9303
  duration: ms,
8168
9304
  businessHours: opts?.businessHours
8169
9305
  })
@@ -8171,13 +9307,13 @@ var init_workflow = __esm({
8171
9307
  }
8172
9308
  sleepUntil(iso, opts) {
8173
9309
  this.sleepCount += 1;
8174
- const id = opts?.id ?? `sleep_${this.sleepCount}`;
9310
+ const id2 = opts?.id ?? `sleep_${this.sleepCount}`;
8175
9311
  if (typeof iso === "string") {
8176
9312
  return this.push({
8177
9313
  kind: "entry",
8178
9314
  entry: defined({
8179
9315
  type: "sleepUntil",
8180
- id,
9316
+ id: id2,
8181
9317
  date: iso,
8182
9318
  businessHours: opts?.businessHours,
8183
9319
  round: opts?.round
@@ -8190,7 +9326,7 @@ var init_workflow = __esm({
8190
9326
  kind: "entry",
8191
9327
  entry: {
8192
9328
  type: "mapping",
8193
- id: `${id}_at`,
9329
+ id: `${id2}_at`,
8194
9330
  mapConfig: canonicalJson({
8195
9331
  date: {
8196
9332
  template: iso.template
@@ -8202,9 +9338,9 @@ var init_workflow = __esm({
8202
9338
  kind: "entry",
8203
9339
  entry: defined({
8204
9340
  type: "sleepUntil",
8205
- id,
9341
+ id: id2,
8206
9342
  dateFrom: {
8207
- step: `${id}_at`,
9343
+ step: `${id2}_at`,
8208
9344
  path: "date"
8209
9345
  },
8210
9346
  businessHours: opts?.businessHours,
@@ -8212,35 +9348,35 @@ var init_workflow = __esm({
8212
9348
  })
8213
9349
  });
8214
9350
  }
8215
- agentStep(id, opts) {
8216
- this.assertId(id, "agentStep()");
9351
+ agentStep(id2, opts) {
9352
+ this.assertId(id2, "agentStep()");
8217
9353
  if (!opts || typeof opts.agentId !== "string" && !(opts.agentId && typeof opts.agentId === "object" && "__envRef" in opts.agentId)) {
8218
- throw new LuaWorkflowBuildError("invalid-envelope", `agentStep("${id}") needs an agentId`);
9354
+ throw new LuaWorkflowBuildError("invalid-envelope", `agentStep("${id2}") needs an agentId`);
8219
9355
  }
8220
9356
  const tier = opts.tier ?? (opts.workspace ? "job" : void 0);
8221
- if (opts.workspace && opts.tier !== void 0 && opts.tier !== "job") throw new LuaWorkflowBuildError("workspace-requires-job-tier", `"${id}": a step mounting a workspace must be tier:'job'`);
8222
- if (opts.harness !== void 0 && tier !== "job") throw new LuaWorkflowBuildError("harness-requires-job-tier", `"${id}": harness is only legal on a tier:'job' agent step`);
8223
- if (opts.toolScope?.jobTools && tier !== "job") throw new LuaWorkflowBuildError("cap-exceeded", `"${id}": toolScope.jobTools require tier:'job' (job-tools-require-job-tier)`);
9357
+ if (opts.workspace && opts.tier !== void 0 && opts.tier !== "job") throw new LuaWorkflowBuildError("workspace-requires-job-tier", `"${id2}": a step mounting a workspace must be tier:'job'`);
9358
+ if (opts.harness !== void 0 && tier !== "job") throw new LuaWorkflowBuildError("harness-requires-job-tier", `"${id2}": harness is only legal on a tier:'job' agent step`);
9359
+ if (opts.toolScope?.jobTools && tier !== "job") throw new LuaWorkflowBuildError("cap-exceeded", `"${id2}": toolScope.jobTools require tier:'job' (job-tools-require-job-tier)`);
8224
9360
  for (const m of WORKFLOW_JOB_RANGE_MEMBERS) {
8225
9361
  if (opts[m] === void 0) continue;
8226
- if (tier !== "job") throw new LuaWorkflowBuildError("max-turns-requires-job-tier", `"${id}": ${m} is only legal on a tier:'job' agent step`);
9362
+ if (tier !== "job") throw new LuaWorkflowBuildError("max-turns-requires-job-tier", `"${id2}": ${m} is only legal on a tier:'job' agent step`);
8227
9363
  if (!isWithinWorkflowJobRange(m, opts[m])) {
8228
9364
  const { min, max } = WORKFLOW_JOB_RANGES[m];
8229
- throw new LuaWorkflowBuildError("max-turns-invalid", `"${id}": ${m} must be an integer ${min}..${max}`);
9365
+ throw new LuaWorkflowBuildError("max-turns-invalid", `"${id2}": ${m} must be an integer ${min}..${max}`);
8230
9366
  }
8231
9367
  }
8232
9368
  assertTimeout({
8233
- id,
9369
+ id: id2,
8234
9370
  timeoutSeconds: opts.timeoutSeconds,
8235
9371
  tier,
8236
9372
  workspace: opts.workspace,
8237
9373
  kind: "agent"
8238
9374
  });
8239
- assertRetry(opts.retry, id);
9375
+ assertRetry(opts.retry, id2);
8240
9376
  this.recordEnvRefs(opts.agentId, opts.prompt);
8241
9377
  const node = defined({
8242
9378
  type: "agent",
8243
- id,
9379
+ id: id2,
8244
9380
  agentId: opts.agentId,
8245
9381
  promptTemplate: templateText(opts.prompt),
8246
9382
  outputSchema: schemaToJson(opts.outputSchema),
@@ -8268,30 +9404,30 @@ var init_workflow = __esm({
8268
9404
  node
8269
9405
  });
8270
9406
  }
8271
- specialistStep(id, opts) {
8272
- this.assertId(id, "specialistStep()");
9407
+ specialistStep(id2, opts) {
9408
+ this.assertId(id2, "specialistStep()");
8273
9409
  const role = opts?.role;
8274
- if (!role || typeof role !== "object") throw new LuaWorkflowBuildError("invalid-envelope", `specialistStep("${id}") needs a role`);
9410
+ if (!role || typeof role !== "object") throw new LuaWorkflowBuildError("invalid-envelope", `specialistStep("${id2}") needs a role`);
8275
9411
  if (role.ref !== void 0 && (role.name !== void 0 || role.instructions !== void 0 || role.tools !== void 0)) {
8276
- throw new LuaWorkflowBuildError("role-ref-and-inline", `"${id}": role is EITHER { ref } OR the inline { name, instructions, tools } shape`);
9412
+ throw new LuaWorkflowBuildError("role-ref-and-inline", `"${id2}": role is EITHER { ref } OR the inline { name, instructions, tools } shape`);
8277
9413
  }
8278
9414
  if (role.ref === void 0) {
8279
9415
  if (typeof role.instructions !== "string" || role.instructions.length > WORKFLOW_SPECIALIST_ROLE_MAX_INSTRUCTIONS) {
8280
- throw new LuaWorkflowBuildError("ephemeral-role-too-long", `"${id}": role.instructions must be \u2264 ${WORKFLOW_SPECIALIST_ROLE_MAX_INSTRUCTIONS} chars`);
9416
+ throw new LuaWorkflowBuildError("ephemeral-role-too-long", `"${id2}": role.instructions must be \u2264 ${WORKFLOW_SPECIALIST_ROLE_MAX_INSTRUCTIONS} chars`);
8281
9417
  }
8282
- if (!Array.isArray(role.tools)) throw new LuaWorkflowBuildError("invalid-envelope", `"${id}": role.tools must be an array ([] = no tools)`);
8283
- if (role.tools.length > 64) throw new LuaWorkflowBuildError("cap-exceeded", `"${id}": role.tools exceeds 64 entries`);
9418
+ if (!Array.isArray(role.tools)) throw new LuaWorkflowBuildError("invalid-envelope", `"${id2}": role.tools must be an array ([] = no tools)`);
9419
+ if (role.tools.length > 64) throw new LuaWorkflowBuildError("cap-exceeded", `"${id2}": role.tools exceeds 64 entries`);
8284
9420
  }
8285
9421
  assertTimeout({
8286
- id,
9422
+ id: id2,
8287
9423
  timeoutSeconds: opts.timeoutSeconds,
8288
9424
  kind: "agent"
8289
9425
  });
8290
- assertRetry(opts.retry, id);
9426
+ assertRetry(opts.retry, id2);
8291
9427
  this.recordEnvRefs(opts.prompt);
8292
9428
  const node = defined({
8293
9429
  type: "agent",
8294
- id,
9430
+ id: id2,
8295
9431
  agentId: "$self",
8296
9432
  role: role.ref !== void 0 ? {
8297
9433
  ref: role.ref
@@ -8314,20 +9450,20 @@ var init_workflow = __esm({
8314
9450
  node
8315
9451
  });
8316
9452
  }
8317
- toolStep(id, tool, opts = {}) {
8318
- this.assertId(id, "toolStep()");
8319
- if (!tool || typeof tool !== "object" || typeof tool.name !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `toolStep("${id}") needs a LuaTool`);
8320
- assertNoClosure(opts.input, `toolStep("${id}").input`);
9453
+ toolStep(id2, tool, opts = {}) {
9454
+ this.assertId(id2, "toolStep()");
9455
+ if (!tool || typeof tool !== "object" || typeof tool.name !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `toolStep("${id2}") needs a LuaTool`);
9456
+ assertNoClosure(opts.input, `toolStep("${id2}").input`);
8321
9457
  this.recordEnvRefs(opts.input);
8322
9458
  assertTimeout({
8323
- id,
9459
+ id: id2,
8324
9460
  timeoutSeconds: opts.timeoutSeconds,
8325
9461
  kind: "tool"
8326
9462
  });
8327
- assertRetry(opts.retry, id);
9463
+ assertRetry(opts.retry, id2);
8328
9464
  const node = defined({
8329
9465
  type: "tool",
8330
- id,
9466
+ id: id2,
8331
9467
  toolId: tool.name,
8332
9468
  input: opts.input,
8333
9469
  timeoutSeconds: opts.timeoutSeconds,
@@ -8341,34 +9477,34 @@ var init_workflow = __esm({
8341
9477
  node
8342
9478
  });
8343
9479
  }
8344
- approval(id, opts) {
8345
- this.assertId(id, "approval()");
8346
- if (!opts || typeof opts.title !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `approval("${id}") needs a title`);
9480
+ approval(id2, opts) {
9481
+ this.assertId(id2, "approval()");
9482
+ if (!opts || typeof opts.title !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `approval("${id2}") needs a title`);
8347
9483
  if (opts.approver === "creator" && opts.excludeInitiator === true) {
8348
- throw new LuaWorkflowBuildError("approver-excludes-only-candidate", `"${id}": approver:'creator' with excludeInitiator:true always excludes the only candidate`);
9484
+ throw new LuaWorkflowBuildError("approver-excludes-only-candidate", `"${id2}": approver:'creator' with excludeInitiator:true always excludes the only candidate`);
8349
9485
  }
8350
9486
  const editable = approvalEditable(opts);
8351
- if (opts.fourEyes !== void 0 && !editable) throw new LuaWorkflowBuildError("four-eyes-requires-editable", `"${id}": \`fourEyes\` requires editable:true`);
9487
+ if (opts.fourEyes !== void 0 && !editable) throw new LuaWorkflowBuildError("four-eyes-requires-editable", `"${id2}": \`fourEyes\` requires editable:true`);
8352
9488
  if (opts.editable === false && Array.isArray(opts.editablePaths) && opts.editablePaths.length > 0) {
8353
- throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": \`editablePaths\` beside editable:false is contradictory \u2014 drop the paths or set editable:true`);
9489
+ throw new LuaWorkflowBuildError("editable-path-invalid", `"${id2}": \`editablePaths\` beside editable:false is contradictory \u2014 drop the paths or set editable:true`);
8354
9490
  } else if ((opts.editablePaths !== void 0 || opts.editedPayloadSchema !== void 0) && !editable) {
8355
- throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": \`editablePaths\` / \`editedPayloadSchema\` require editable:true (a non-empty editablePaths implies it)`);
9491
+ throw new LuaWorkflowBuildError("editable-path-invalid", `"${id2}": \`editablePaths\` / \`editedPayloadSchema\` require editable:true (a non-empty editablePaths implies it)`);
8356
9492
  }
8357
9493
  for (const p of opts.editablePaths ?? []) {
8358
- 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`);
9494
+ if (!EDITABLE_PATH_RE2.test(p)) throw new LuaWorkflowBuildError("editable-path-invalid", `"${id2}": editablePaths entry "${p}" is outside the grammar seg(.seg)* with [*]/[n] selectors`);
8359
9495
  }
8360
9496
  if (Array.isArray(opts.onTimeout)) {
8361
9497
  const chain = opts.onTimeout;
8362
9498
  const hops = chain.filter((h) => typeof h === "object");
8363
- if (hops.length > 3) throw new LuaWorkflowBuildError("escalation-chain-too-long", `"${id}": an onTimeout chain carries at most 3 escalation hops`);
9499
+ if (hops.length > 3) throw new LuaWorkflowBuildError("escalation-chain-too-long", `"${id2}": an onTimeout chain carries at most 3 escalation hops`);
8364
9500
  const last = chain[chain.length - 1];
8365
- if (last === void 0 || typeof last === "object") throw new LuaWorkflowBuildError("escalation-chain-not-terminal", `"${id}": an onTimeout chain must end in a terminal member`);
9501
+ if (last === void 0 || typeof last === "object") throw new LuaWorkflowBuildError("escalation-chain-not-terminal", `"${id2}": an onTimeout chain must end in a terminal member`);
8366
9502
  }
8367
- if (typeof opts.details === "function") throw new LuaWorkflowBuildError("closure-binding", `approval("${id}").details must be template(...)`);
9503
+ if (typeof opts.details === "function") throw new LuaWorkflowBuildError("closure-binding", `approval("${id2}").details must be template(...)`);
8368
9504
  this.recordEnvRefs(opts.details, opts.timeoutHours, opts.approver);
8369
9505
  const node = defined({
8370
9506
  type: "approval",
8371
- id,
9507
+ id: id2,
8372
9508
  title: opts.title,
8373
9509
  details: opts.details ? templateText(opts.details) : void 0,
8374
9510
  approver: opts.approver,
@@ -8390,13 +9526,13 @@ var init_workflow = __esm({
8390
9526
  node
8391
9527
  });
8392
9528
  }
8393
- waitForSignal(id, opts) {
8394
- this.assertId(id, "waitForSignal()");
8395
- if (!opts || typeof opts.signal !== "string" || opts.signal.length === 0) throw new LuaWorkflowBuildError("invalid-envelope", `waitForSignal("${id}") needs a signal name`);
9529
+ waitForSignal(id2, opts) {
9530
+ this.assertId(id2, "waitForSignal()");
9531
+ if (!opts || typeof opts.signal !== "string" || opts.signal.length === 0) throw new LuaWorkflowBuildError("invalid-envelope", `waitForSignal("${id2}") needs a signal name`);
8396
9532
  this.recordEnvRefs(opts.timeoutHours);
8397
9533
  const node = defined({
8398
9534
  type: "waitForSignal",
8399
- id,
9535
+ id: id2,
8400
9536
  signal: opts.signal,
8401
9537
  schema: schemaToJson(opts.schema),
8402
9538
  timeoutHours: opts.timeoutHours,
@@ -8409,28 +9545,28 @@ var init_workflow = __esm({
8409
9545
  node
8410
9546
  });
8411
9547
  }
8412
- workflow(id, ref, input, opts) {
8413
- this.assertId(id, "workflow()");
8414
- assertRetry(opts?.retry, id);
9548
+ workflow(id2, ref, input, opts) {
9549
+ this.assertId(id2, "workflow()");
9550
+ assertRetry(opts?.retry, id2);
8415
9551
  const name = typeof ref === "string" ? ref : ref instanceof LuaWorkflow ? ref.getName() : void 0;
8416
- if (!name) throw new LuaWorkflowBuildError("invalid-envelope", `workflow("${id}") needs a LuaWorkflow or a workflow name`);
9552
+ if (!name) throw new LuaWorkflowBuildError("invalid-envelope", `workflow("${id2}") needs a LuaWorkflow or a workflow name`);
8417
9553
  if (opts?.workspace === "inherit") {
8418
- if (!this.config.workspace) throw new LuaWorkflowBuildError("workspace-inherit-without-parent-workspace", `"${id}": workspace:'inherit' but the parent createWorkflow declares no workspace`);
8419
- if (ref instanceof LuaWorkflow && ref.getConfig().workspace) throw new LuaWorkflowBuildError("workspace-inherit-conflict", `"${id}": workspace:'inherit' on a workflow that declares its own workspace`);
9554
+ if (!this.config.workspace) throw new LuaWorkflowBuildError("workspace-inherit-without-parent-workspace", `"${id2}": workspace:'inherit' but the parent createWorkflow declares no workspace`);
9555
+ if (ref instanceof LuaWorkflow && ref.getConfig().workspace) throw new LuaWorkflowBuildError("workspace-inherit-conflict", `"${id2}": workspace:'inherit' on a workflow that declares its own workspace`);
8420
9556
  }
8421
- assertNoClosure(input, `workflow("${id}").input`);
9557
+ assertNoClosure(input, `workflow("${id2}").input`);
8422
9558
  this.recordEnvRefs(input);
8423
9559
  this.nestedRefs.push(opts?.workspace === "inherit" ? {
8424
- id,
9560
+ id: id2,
8425
9561
  name,
8426
9562
  workspace: "inherit"
8427
9563
  } : {
8428
- id,
9564
+ id: id2,
8429
9565
  name
8430
9566
  });
8431
9567
  const node = defined({
8432
9568
  type: "workflow",
8433
- id,
9569
+ id: id2,
8434
9570
  workflowId: name,
8435
9571
  input,
8436
9572
  workspace: opts?.workspace,
@@ -8509,8 +9645,8 @@ var init_workflow = __esm({
8509
9645
  });
8510
9646
  }
8511
9647
  }
8512
- assertId(id, where) {
8513
- if (typeof id !== "string" || !STEP_ID_RE.test(id)) throw new LuaWorkflowBuildError("invalid-step-id", `${where}: id "${String(id)}" must match ${STEP_ID_RE}`);
9648
+ assertId(id2, where) {
9649
+ if (typeof id2 !== "string" || !STEP_ID_RE.test(id2)) throw new LuaWorkflowBuildError("invalid-step-id", `${where}: id "${String(id2)}" must match ${STEP_ID_RE}`);
8514
9650
  }
8515
9651
  };
8516
9652
  EDITABLE_PATH_RE2 = /^[A-Za-z_][A-Za-z0-9_]*(\[(\*|\d+)\])?(\.[A-Za-z_][A-Za-z0-9_]*(\[(\*|\d+)\])?)*$/;
@@ -8688,7 +9824,7 @@ var init_lua_fetch = __esm({
8688
9824
  });
8689
9825
 
8690
9826
  // src/services/firebase-session.ts
8691
- import { z as z5 } from "zod";
9827
+ import { z as z6 } from "zod";
8692
9828
  function rejectedRefreshReason(message) {
8693
9829
  const normalised = message.toUpperCase();
8694
9830
  return REJECTED_REFRESH_REASONS.find((reason) => normalised.includes(reason));
@@ -8834,20 +9970,20 @@ var init_firebase_session = __esm({
8834
9970
  this.name = "FirebaseSessionRejectedError";
8835
9971
  }
8836
9972
  };
8837
- customTokenResponseSchema = z5.object({
8838
- idToken: z5.string().min(1),
8839
- refreshToken: z5.string().min(1),
8840
- expiresIn: z5.coerce.number().positive().finite(),
8841
- localId: z5.string().min(1).optional()
9973
+ customTokenResponseSchema = z6.object({
9974
+ idToken: z6.string().min(1),
9975
+ refreshToken: z6.string().min(1),
9976
+ expiresIn: z6.coerce.number().positive().finite(),
9977
+ localId: z6.string().min(1).optional()
8842
9978
  });
8843
- refreshResponseSchema = z5.object({
8844
- id_token: z5.string().min(1),
8845
- refresh_token: z5.string().min(1),
8846
- expires_in: z5.coerce.number().positive().finite(),
8847
- user_id: z5.string().min(1)
9979
+ refreshResponseSchema = z6.object({
9980
+ id_token: z6.string().min(1),
9981
+ refresh_token: z6.string().min(1),
9982
+ expires_in: z6.coerce.number().positive().finite(),
9983
+ user_id: z6.string().min(1)
8848
9984
  });
8849
- firebaseIdTokenPayloadSchema = z5.object({
8850
- sub: z5.string().min(1)
9985
+ firebaseIdTokenPayloadSchema = z6.object({
9986
+ sub: z6.string().min(1)
8851
9987
  });
8852
9988
  __name(requireFirebaseWebApiKey, "requireFirebaseWebApiKey");
8853
9989
  __name(claimsOfFirebaseIdToken, "claimsOfFirebaseIdToken");
@@ -8864,7 +10000,7 @@ var init_firebase_session = __esm({
8864
10000
  import { createHash as createHash3, randomUUID } from "crypto";
8865
10001
  import { mkdir, open, readFile, rename, rm, stat, unlink, writeFile } from "fs/promises";
8866
10002
  import { join as join3 } from "path";
8867
- import { z as z6 } from "zod";
10003
+ import { z as z7 } from "zod";
8868
10004
  function environmentKey(environment) {
8869
10005
  return createHash3("sha256").update(`${environment.apiUrl}
8870
10006
  ${environment.authUrl}
@@ -8881,15 +10017,15 @@ var init_firebase_session_store = __esm({
8881
10017
  "src/services/firebase-session-store.ts"() {
8882
10018
  "use strict";
8883
10019
  init_constants();
8884
- storedFirebaseSessionSchema = z6.object({
8885
- version: z6.literal(1),
8886
- kind: z6.literal("firebase-session"),
8887
- generation: z6.string().min(1),
8888
- refreshToken: z6.string().min(1),
8889
- firebaseUid: z6.string().min(1),
8890
- apiUrl: z6.string().url(),
8891
- authUrl: z6.string().url(),
8892
- firebaseWebApiKey: z6.string().min(1)
10020
+ storedFirebaseSessionSchema = z7.object({
10021
+ version: z7.literal(1),
10022
+ kind: z7.literal("firebase-session"),
10023
+ generation: z7.string().min(1),
10024
+ refreshToken: z7.string().min(1),
10025
+ firebaseUid: z7.string().min(1),
10026
+ apiUrl: z7.string().url(),
10027
+ authUrl: z7.string().url(),
10028
+ firebaseWebApiKey: z7.string().min(1)
8893
10029
  });
8894
10030
  currentFirebaseSessionEnvironment = /* @__PURE__ */ __name(() => ({
8895
10031
  apiUrl: BASE_URLS.API,
@@ -9560,7 +10696,7 @@ async function* parseSseStream(body, signal) {
9560
10696
  const decoder = new TextDecoder();
9561
10697
  let buffer = "";
9562
10698
  const flush = /* @__PURE__ */ __name((block) => {
9563
- let id;
10699
+ let id2;
9564
10700
  let event = "message";
9565
10701
  const data = [];
9566
10702
  for (const rawLine of block.split("\n")) {
@@ -9570,11 +10706,11 @@ async function* parseSseStream(body, signal) {
9570
10706
  const field = colon === -1 ? line : line.slice(0, colon);
9571
10707
  let value3 = colon === -1 ? "" : line.slice(colon + 1);
9572
10708
  if (value3.startsWith(" ")) value3 = value3.slice(1);
9573
- if (field === "id") id = value3;
10709
+ if (field === "id") id2 = value3;
9574
10710
  else if (field === "event") event = value3;
9575
10711
  else if (field === "data") data.push(value3);
9576
10712
  }
9577
- if (data.length === 0 && id === void 0 && event === "message") return void 0;
10713
+ if (data.length === 0 && id2 === void 0 && event === "message") return void 0;
9578
10714
  const joined = data.join("\n");
9579
10715
  let parsed = joined;
9580
10716
  try {
@@ -9583,7 +10719,7 @@ async function* parseSseStream(body, signal) {
9583
10719
  parsed = joined;
9584
10720
  }
9585
10721
  return {
9586
- id,
10722
+ id: id2,
9587
10723
  event,
9588
10724
  data: parsed
9589
10725
  };
@@ -10975,11 +12111,17 @@ var init_base_handler = __esm({
10975
12111
  /**
10976
12112
  * Phase 2 of parallel sync: apply fetched data to YAML.
10977
12113
  * Optionally creates missing primitives on server if apiKey+agentId provided.
12114
+ *
12115
+ * PRO-2150 — `apiCredentials.registerOnly` drops the two writes that overwrite what the developer
12116
+ * pinned (the server-only orphan stubs in Part 1, and the version reconciliation half of Part 2)
12117
+ * while keeping id linking and create-on-server. `lua chat` uses it: it needs the skills'/processors'
12118
+ * server ids to exist before the sandbox push, and nothing else.
10978
12119
  */
10979
12120
  async applySyncToYaml(serverData, config, manifest, apiCredentials) {
10980
12121
  const messages = [];
10981
12122
  let yamlUpdated = false;
10982
12123
  let orphanedCount = 0;
12124
+ const registerOnly = apiCredentials?.registerOnly === true;
10983
12125
  try {
10984
12126
  if (!serverData.serverItems) {
10985
12127
  if (serverData.fetchError) {
@@ -11007,10 +12149,10 @@ var init_base_handler = __esm({
11007
12149
  messages.push(msg);
11008
12150
  console.log(msg);
11009
12151
  }
11010
- const orphans = serverData.serverItems.filter((item) => {
11011
- const id = item.id;
12152
+ const orphans = registerOnly ? [] : serverData.serverItems.filter((item) => {
12153
+ const id2 = item.id;
11012
12154
  const name = item.name;
11013
- return !yamlById.has(id) && !yamlByName.has(name) && this.isActive(item) && this.shouldConsiderForOrphan(item);
12155
+ return !yamlById.has(id2) && !yamlByName.has(name) && this.isActive(item) && this.shouldConsiderForOrphan(item);
11014
12156
  });
11015
12157
  if (orphans.length > 0) {
11016
12158
  const stubs = orphans.map((item) => this.cleanItem({
@@ -11034,7 +12176,9 @@ var init_base_handler = __esm({
11034
12176
  `);
11035
12177
  orphanedCount = orphans.length;
11036
12178
  }
11037
- const { items: updatedItems, changed, msgs } = this.syncFromServer(yamlItems, serverByName);
12179
+ const { items: updatedItems, changed, msgs } = this.syncFromServer(yamlItems, serverByName, {
12180
+ syncVersions: !registerOnly
12181
+ });
11038
12182
  messages.push(...msgs);
11039
12183
  if (changed) {
11040
12184
  yamlUpdated = true;
@@ -11226,7 +12370,7 @@ var init_base_handler = __esm({
11226
12370
  const result = /* @__PURE__ */ new Map();
11227
12371
  const { serverItems } = await this.fetchServerState(apiKey, agentId);
11228
12372
  if (!serverItems) {
11229
- entityIds.forEach((id) => result.set(id, null));
12373
+ entityIds.forEach((id2) => result.set(id2, null));
11230
12374
  return result;
11231
12375
  }
11232
12376
  for (const entityId of entityIds) {
@@ -11260,8 +12404,8 @@ var init_base_handler = __esm({
11260
12404
  const yamlById = /* @__PURE__ */ new Map();
11261
12405
  const yamlByName = /* @__PURE__ */ new Map();
11262
12406
  for (const item of yamlItems) {
11263
- const id = this.getItemId(item);
11264
- if (id) yamlById.set(id, item);
12407
+ const id2 = this.getItemId(item);
12408
+ if (id2) yamlById.set(id2, item);
11265
12409
  yamlByName.set(item.name, item);
11266
12410
  }
11267
12411
  const serverByName = /* @__PURE__ */ new Map();
@@ -11277,7 +12421,8 @@ var init_base_handler = __esm({
11277
12421
  /**
11278
12422
  * For each YAML item, match to server by name, populate missing IDs, update versions.
11279
12423
  */
11280
- syncFromServer(yamlItems, serverByName) {
12424
+ syncFromServer(yamlItems, serverByName, options) {
12425
+ const syncVersions = options?.syncVersions !== false;
11281
12426
  const msgs = [];
11282
12427
  let changed = false;
11283
12428
  const idField = this.yamlConfig.idField;
@@ -11298,7 +12443,7 @@ var init_base_handler = __esm({
11298
12443
  };
11299
12444
  }
11300
12445
  const versions = serverItem.versions;
11301
- if (Array.isArray(versions) && versions.length > 0) {
12446
+ if (syncVersions && Array.isArray(versions) && versions.length > 0) {
11302
12447
  const activeVersion = this.getActiveVersion(serverItem);
11303
12448
  const currentVersion = item.version;
11304
12449
  if (activeVersion && activeVersion !== currentVersion) {
@@ -15123,7 +16268,7 @@ var init_workflow_api_service = __esm({
15123
16268
  throw new WorkflowApiError("FORBIDDEN", `Workflows.${member}: goals are scoped to the bound agent ${api.agentId}`, 403);
15124
16269
  }
15125
16270
  }, "assertBoundAgent");
15126
- pathId = /* @__PURE__ */ __name((id) => encodeURIComponent(id), "pathId");
16271
+ pathId = /* @__PURE__ */ __name((id2) => encodeURIComponent(id2), "pathId");
15127
16272
  unavailable = /* @__PURE__ */ __name((member, route) => async () => {
15128
16273
  throw new WorkflowApiError("WORKFLOWS_API_UNAVAILABLE", `Workflows.${member} is not available in this runtime yet (${route} lands with a later wave)`, 501);
15129
16274
  }, "unavailable");
@@ -15859,6 +17004,20 @@ var env = Object.assign((key, _opts) => readEnv(key), {
15859
17004
  };
15860
17005
  }, "template")
15861
17006
  });
17007
+ var log = Object.freeze({
17008
+ debug: /* @__PURE__ */ __name((message, fields) => emitLocalLog("debug", message, fields), "debug"),
17009
+ info: /* @__PURE__ */ __name((message, fields) => emitLocalLog("info", message, fields), "info"),
17010
+ warn: /* @__PURE__ */ __name((message, fields) => emitLocalLog("warn", message, fields), "warn"),
17011
+ error: /* @__PURE__ */ __name((message, fields) => emitLocalLog("error", message, fields), "error")
17012
+ });
17013
+ function emitLocalLog(level, message, fields) {
17014
+ const normalized = normalizeLogFields(fields);
17015
+ const text = typeof message === "object" && message !== null ? JSON.stringify(message) : String(message);
17016
+ const write = level === "error" ? console.error : level === "warn" ? console.warn : level === "info" ? console.info : console.debug;
17017
+ if (normalized) write(text, JSON.stringify(normalized));
17018
+ else write(text);
17019
+ }
17020
+ __name(emitLocalLog, "emitLocalLog");
15862
17021
  var ToolFlag = /* @__PURE__ */ (function(ToolFlag2) {
15863
17022
  ToolFlag2["NONE"] = "none";
15864
17023
  ToolFlag2["IGNORE_ON_ENTER"] = "ignore_on_enter";
@@ -16819,9 +17978,9 @@ var Products = {
16819
17978
  * @param id - Product ID
16820
17979
  * @returns Promise resolving when deletion is complete
16821
17980
  */
16822
- async delete(id) {
17981
+ async delete(id2) {
16823
17982
  const instance = await getProductsInstance();
16824
- return instance.delete(id);
17983
+ return instance.delete(id2);
16825
17984
  },
16826
17985
  /**
16827
17986
  * Searches products by query string.
@@ -16839,9 +17998,9 @@ var Products = {
16839
17998
  * @param id - Product ID
16840
17999
  * @returns Promise resolving to product data
16841
18000
  */
16842
- async getById(id) {
18001
+ async getById(id2) {
16843
18002
  const instance = await getProductsInstance();
16844
- return instance.getById(id);
18003
+ return instance.getById(id2);
16845
18004
  }
16846
18005
  };
16847
18006
  var Baskets = {
@@ -17378,6 +18537,7 @@ export {
17378
18537
  inSet2 as inSet,
17379
18538
  init2 as init,
17380
18539
  lit2 as lit,
18540
+ log,
17381
18541
  lt2 as lt,
17382
18542
  lte2 as lte,
17383
18543
  ne2 as ne,