lua-cli 3.44.0 → 3.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -84,8 +84,8 @@ function workflowJobTargetTemplatePath(binding) {
84
84
  __name(workflowJobTargetTemplatePath, "workflowJobTargetTemplatePath");
85
85
  __name2(workflowJobTargetTemplatePath, "workflowJobTargetTemplatePath");
86
86
  function isWorkflowJobTargetTemplate(target) {
87
- const agentId = target?.agentId;
88
- return !!agentId && typeof agentId === "object";
87
+ const agentId2 = target?.agentId;
88
+ return !!agentId2 && typeof agentId2 === "object";
89
89
  }
90
90
  __name(isWorkflowJobTargetTemplate, "isWorkflowJobTargetTemplate");
91
91
  __name2(isWorkflowJobTargetTemplate, "isWorkflowJobTargetTemplate");
@@ -107,12 +107,12 @@ function workflowJobTargetProblem(target, plugins, luaApi) {
107
107
  if (target === void 0) return null;
108
108
  if (!target || typeof target !== "object" || Array.isArray(target)) return "target must be { agentId }";
109
109
  const keys = Object.keys(target);
110
- const agentId = target.agentId;
110
+ const agentId2 = target.agentId;
111
111
  if (keys.length !== 1 || !("agentId" in target)) return "target must be exactly { agentId }";
112
- if (typeof agentId === "string") {
113
- if (!agentId.trim() || agentId.length > 256) return "target must be exactly { agentId: <non-empty string> }";
114
- if (agentId.includes("${")) return "a run-input target is written template('${initData.<path>}'), never a string with ${\u2026}";
115
- } else if (workflowJobTargetTemplatePath(agentId) === null) {
112
+ if (typeof agentId2 === "string") {
113
+ if (!agentId2.trim() || agentId2.length > 256) return "target must be exactly { agentId: <non-empty string> }";
114
+ if (agentId2.includes("${")) return "a run-input target is written template('${initData.<path>}'), never a string with ${\u2026}";
115
+ } else if (workflowJobTargetTemplatePath(agentId2) === null) {
116
116
  return "target.agentId must be a static id or template('${initData.<path>}') \u2014 exactly one initData placeholder, no default";
117
117
  }
118
118
  const hasPlugins = Array.isArray(plugins) && plugins.length > 0;
@@ -140,25 +140,25 @@ function readInitDataPath(root, path) {
140
140
  __name(readInitDataPath, "readInitDataPath");
141
141
  __name2(readInitDataPath, "readInitDataPath");
142
142
  function renderWorkflowJobTarget(target, initData) {
143
- const agentId = target?.agentId;
144
- if (target === void 0 || target === null || agentId === void 0) return {
143
+ const agentId2 = target?.agentId;
144
+ if (target === void 0 || target === null || agentId2 === void 0) return {
145
145
  ok: true,
146
146
  agentId: void 0,
147
147
  templated: false
148
148
  };
149
- if (typeof agentId === "string") {
150
- if (!agentId.trim() || agentId.includes("${")) return {
149
+ if (typeof agentId2 === "string") {
150
+ if (!agentId2.trim() || agentId2.includes("${")) return {
151
151
  ok: false,
152
152
  reason: "invalid",
153
153
  message: "target.agentId is invalid"
154
154
  };
155
155
  return {
156
156
  ok: true,
157
- agentId,
157
+ agentId: agentId2,
158
158
  templated: false
159
159
  };
160
160
  }
161
- const path = workflowJobTargetTemplatePath(agentId);
161
+ const path = workflowJobTargetTemplatePath(agentId2);
162
162
  if (path === null) return {
163
163
  ok: false,
164
164
  reason: "invalid",
@@ -196,6 +196,7 @@ import { z } from "zod";
196
196
  import { z as z2 } from "zod";
197
197
  import { z as z3 } from "zod";
198
198
  import { z as z4 } from "zod";
199
+ import { z as z5 } from "zod";
199
200
  var __defProp3 = Object.defineProperty;
200
201
  var __name3 = /* @__PURE__ */ __name((target, value3) => __defProp3(target, "name", { value: value3, configurable: true }), "__name");
201
202
  var PLUMBING_THREAD_CHANNELS = [
@@ -433,8 +434,8 @@ function isPlatformInvocationCaller(v) {
433
434
  }
434
435
  __name(isPlatformInvocationCaller, "isPlatformInvocationCaller");
435
436
  __name3(isPlatformInvocationCaller, "isPlatformInvocationCaller");
436
- function supervisionSubjectId(agentId) {
437
- return `agent:${agentId}`;
437
+ function supervisionSubjectId(agentId2) {
438
+ return `agent:${agentId2}`;
438
439
  }
439
440
  __name(supervisionSubjectId, "supervisionSubjectId");
440
441
  __name3(supervisionSubjectId, "supervisionSubjectId");
@@ -548,7 +549,27 @@ var SUPERVISION_OPS = {
548
549
  * agentId }`) to its env. `act`, on a turn whose platform-picked user is the target's owner, never overwriting a
549
550
  * key (`LUA_SECRET_ATTACH_EXISTING_ENABLED`).
550
551
  */
551
- "secrets.attach": "act"
552
+ "secrets.attach": "act",
553
+ /**
554
+ * SV (LUA-1080) — `Agents.deployed(id)`: what the target serves RIGHT NOW, read from each primitive's live pointer
555
+ * (skills with their tools, the published persona, pre/postprocessors), with version ids comparable to an agent
556
+ * version snapshot. Works whether or not the target has a promoted agent version. Metadata and hashes only.
557
+ */
558
+ "primitives.deployed": "observe",
559
+ // [WD]
560
+ /**
561
+ * WD (watchdog grant) — `Agents.versions(id).rollback(version, { expectActive })`: restore a version of the target
562
+ * that was ACTIVE before, is OLDER than the active one and was active within the last 7 days. CAS on the active
563
+ * version; only from a workflow step the watchdog grant names. Held only by a watchdog grant.
564
+ */
565
+ "versions.rollback": "rollback",
566
+ // [JR]
567
+ /**
568
+ * JR (BAC-2011) — `Agents.jobs(id).register({ versionId, jobId })`: register a job that is pinned in a STAGED version of
569
+ * the target (`snapshot.jobs[]`) so the promote activates and schedules it. Mongo-only marker write; EventBridge stays
570
+ * on the post-promote reconcile. Release-class: needs `register-job` AND `release` on the grant, from a signed step.
571
+ */
572
+ "jobs.register": "register-job"
552
573
  };
553
574
  function isSupervisionOp(op) {
554
575
  return typeof op === "string" && Object.prototype.hasOwnProperty.call(SUPERVISION_OPS, op);
@@ -729,8 +750,171 @@ var SUPERVISION_OPS_WAVE2 = {
729
750
  gate: "act",
730
751
  targeted: true,
731
752
  item: "SV"
753
+ },
754
+ /** SV (LUA-1080) — `Agents.deployed(id)`: the target's deployed primitives (live pointers, no agent version needed). */
755
+ "primitives.deployed": {
756
+ gate: "observe",
757
+ targeted: true,
758
+ item: "SV"
759
+ },
760
+ /** WD — `Agents.versions(id).rollback(version, { expectActive })` (watchdog grant only). */
761
+ "versions.rollback": {
762
+ gate: "rollback",
763
+ targeted: true,
764
+ item: "WD"
765
+ },
766
+ /** JR (BAC-2011) — `Agents.jobs(id).register({ versionId, jobId })`: a job pinned in a STAGED version (`register-job`). */
767
+ "jobs.register": {
768
+ gate: "register-job",
769
+ targeted: true,
770
+ item: "JR"
732
771
  }
733
772
  };
773
+ var SUPERVISION_WATCHDOG_OPS = {
774
+ logs: "observe",
775
+ "runs.list": "observe",
776
+ "runs.get": "observe",
777
+ "data.get": "observe",
778
+ "data.query": "observe",
779
+ "versions.list": "observe",
780
+ "versions.get": "observe",
781
+ "versions.diff": "observe",
782
+ "versions.rollback": "rollback"
783
+ };
784
+ function isSupervisionWatchdogOp(op) {
785
+ return typeof op === "string" && Object.prototype.hasOwnProperty.call(SUPERVISION_WATCHDOG_OPS, op);
786
+ }
787
+ __name(isSupervisionWatchdogOp, "isSupervisionWatchdogOp");
788
+ __name3(isSupervisionWatchdogOp, "isSupervisionWatchdogOp");
789
+ var SUPERVISION_WATCHDOG_ERRORS = {
790
+ /** A watchdog holder called an op outside {@link SUPERVISION_WATCHDOG_OPS}. */
791
+ OP_REFUSED: "supervision_watchdog_op_refused",
792
+ /** See {@link SupervisionRollbackRefusalReason}. */
793
+ ROLLBACK_NEVER_ACTIVE: "supervision_rollback_never_active",
794
+ ROLLBACK_NOT_OLDER: "supervision_rollback_not_older",
795
+ ROLLBACK_NOT_IN_LINEAGE: "supervision_rollback_not_in_lineage",
796
+ ROLLBACK_AFTER_ROLLBACK: "supervision_rollback_after_rollback",
797
+ ROLLBACK_AFTER_BACKWARD_PROMOTE: "supervision_rollback_after_backward_promote",
798
+ ROLLBACK_TOO_OLD: "supervision_rollback_too_old",
799
+ /** `expectActive` is not the active version (CAS). */
800
+ ROLLBACK_CONFLICT: "supervision_rollback_conflict",
801
+ /** The promote failed part-way and its compensation restored the previous active version. */
802
+ ROLLBACK_INCOMPLETE: "supervision_rollback_incomplete",
803
+ /** The promote failed part-way AND its compensation failed: the Agents DB may have moved (manual triage). */
804
+ ROLLBACK_INCOMPLETE_UNCOMPENSATED: "supervision_rollback_incomplete_uncompensated"
805
+ };
806
+ var SUPERVISION_ROLLBACK_REFUSAL_CODES = {
807
+ never_active: SUPERVISION_WATCHDOG_ERRORS.ROLLBACK_NEVER_ACTIVE,
808
+ not_older: SUPERVISION_WATCHDOG_ERRORS.ROLLBACK_NOT_OLDER,
809
+ not_in_lineage: SUPERVISION_WATCHDOG_ERRORS.ROLLBACK_NOT_IN_LINEAGE,
810
+ after_rollback: SUPERVISION_WATCHDOG_ERRORS.ROLLBACK_AFTER_ROLLBACK,
811
+ after_backward_promote: SUPERVISION_WATCHDOG_ERRORS.ROLLBACK_AFTER_BACKWARD_PROMOTE,
812
+ too_old: SUPERVISION_WATCHDOG_ERRORS.ROLLBACK_TOO_OLD
813
+ };
814
+ function isSupervisionRollbackRefusalReason(v) {
815
+ return typeof v === "string" && Object.prototype.hasOwnProperty.call(SUPERVISION_ROLLBACK_REFUSAL_CODES, v);
816
+ }
817
+ __name(isSupervisionRollbackRefusalReason, "isSupervisionRollbackRefusalReason");
818
+ __name3(isSupervisionRollbackRefusalReason, "isSupervisionRollbackRefusalReason");
819
+ var SUPERVISION_ROLLBACK_LINEAGE_MAX = 25;
820
+ function supervisionRollbackTargetRefusal(target, expectActive, window) {
821
+ if (target.status !== "superseded" || !target.promotedAt || target.compensationFailed === true) {
822
+ return {
823
+ reason: "never_active",
824
+ message: `Version ${target.version} was never fully the active version (status ${target.status ?? "unknown"})`
825
+ };
826
+ }
827
+ if (typeof expectActive !== "number" || !(target.version < expectActive)) {
828
+ return {
829
+ reason: "not_older",
830
+ message: `Version ${target.version} is not older than the active version ${expectActive ?? "none"}`
831
+ };
832
+ }
833
+ if (window) {
834
+ if (target.supersededVia === "rollback" || target.promotedVia === "rollback") {
835
+ return {
836
+ reason: "after_rollback",
837
+ message: `Version ${target.version} was retired or restored by a rollback`
838
+ };
839
+ }
840
+ if (target.supersededVia !== "promote" && target.supersededVia !== "scoped") {
841
+ return {
842
+ reason: "not_in_lineage",
843
+ message: `Version ${target.version} has no forward-promote history`
844
+ };
845
+ }
846
+ const ended = target.supersededAt ? new Date(target.supersededAt).getTime() : NaN;
847
+ if (!Number.isFinite(ended) || ended < window.now - window.windowMs) {
848
+ return {
849
+ reason: "too_old",
850
+ message: `Version ${target.version} was last active outside the ${Math.round(window.windowMs / 864e5)}-day window`
851
+ };
852
+ }
853
+ }
854
+ return null;
855
+ }
856
+ __name(supervisionRollbackTargetRefusal, "supervisionRollbackTargetRefusal");
857
+ __name3(supervisionRollbackTargetRefusal, "supervisionRollbackTargetRefusal");
858
+ function supervisionRollbackRefusal(input) {
859
+ const { target, active, lineage, expectActive, windowMs, now } = input;
860
+ const pre = supervisionRollbackTargetRefusal(target, expectActive);
861
+ if (pre) return pre;
862
+ if (!active || active.version !== expectActive) {
863
+ return {
864
+ reason: "not_older",
865
+ message: `Version ${expectActive ?? "none"} is not the active version`
866
+ };
867
+ }
868
+ if (active.promotedVia === "rollback") {
869
+ return {
870
+ reason: "after_rollback",
871
+ message: `The active version ${active.version} was restored by a rollback; a watchdog does not roll back twice in a row`
872
+ };
873
+ }
874
+ let previous = active;
875
+ for (const step3 of lineage.slice(0, SUPERVISION_ROLLBACK_LINEAGE_MAX)) {
876
+ const label = `version ${step3.version}`;
877
+ if (step3.supersededVia === "rollback" || step3.promotedVia === "rollback") {
878
+ return {
879
+ reason: "after_rollback",
880
+ message: `The rollback lineage crosses ${label}, which a rollback retired or restored`
881
+ };
882
+ }
883
+ if (step3.supersededVia !== "promote" && step3.supersededVia !== "scoped") {
884
+ return {
885
+ reason: "not_in_lineage",
886
+ message: `The rollback lineage stops at ${label} (no forward-promote history)`
887
+ };
888
+ }
889
+ if (step3.compensationFailed === true || step3.status !== "superseded" || !step3.promotedAt) {
890
+ return {
891
+ reason: "not_in_lineage",
892
+ message: `The rollback lineage stops at ${label} (not fully served)`
893
+ };
894
+ }
895
+ if (!(step3.version < previous.version)) {
896
+ return {
897
+ reason: "after_backward_promote",
898
+ message: `Version ${previous.version} was promoted BACK over ${label}; a watchdog never reaches behind that`
899
+ };
900
+ }
901
+ const ended = step3.supersededAt ? new Date(step3.supersededAt).getTime() : NaN;
902
+ if (!Number.isFinite(ended) || ended < now - windowMs) {
903
+ return {
904
+ reason: "too_old",
905
+ message: `The rollback lineage reaches ${label}, last active outside the ${Math.round(windowMs / 864e5)}-day window`
906
+ };
907
+ }
908
+ if (step3.version === target.version && (!target.id || !step3.id || step3.id === target.id)) return null;
909
+ previous = step3;
910
+ }
911
+ return {
912
+ reason: "not_in_lineage",
913
+ message: `Version ${target.version} is not in the active version's recent forward-promote lineage`
914
+ };
915
+ }
916
+ __name(supervisionRollbackRefusal, "supervisionRollbackRefusal");
917
+ __name3(supervisionRollbackRefusal, "supervisionRollbackRefusal");
734
918
  var SUPERVISION_UNTARGETED_OPS = [
735
919
  "agents.list",
736
920
  ...Object.entries(SUPERVISION_OPS_WAVE2).filter(([, contract]) => !contract.targeted).map(([op]) => op)
@@ -1516,9 +1700,9 @@ function isAgentConnectionMountMode(value3) {
1516
1700
  }
1517
1701
  __name(isAgentConnectionMountMode, "isAgentConnectionMountMode");
1518
1702
  __name3(isAgentConnectionMountMode, "isAgentConnectionMountMode");
1519
- function agentConnectionBindingFor(bindings, agentId) {
1520
- if (!Array.isArray(bindings) || !agentId) return void 0;
1521
- return bindings.find((entry) => !!entry && typeof entry === "object" && entry.agentId === agentId);
1703
+ function agentConnectionBindingFor(bindings, agentId2) {
1704
+ if (!Array.isArray(bindings) || !agentId2) return void 0;
1705
+ return bindings.find((entry) => !!entry && typeof entry === "object" && entry.agentId === agentId2);
1522
1706
  }
1523
1707
  __name(agentConnectionBindingFor, "agentConnectionBindingFor");
1524
1708
  __name3(agentConnectionBindingFor, "agentConnectionBindingFor");
@@ -1806,7 +1990,9 @@ var SECRET_REQUEST_ERRORS = {
1806
1990
  /** `secrets.attach` would set an env key the agent already has: never overwritten (remove or rotate it first). */
1807
1991
  KEY_EXISTS: "secret_key_exists",
1808
1992
  /** A request held for an existing agent submitted on the public token page: its owner submits it signed in. */
1809
- OWNER_SUBMIT_REQUIRED: "secret_submit_requires_owner"
1993
+ OWNER_SUBMIT_REQUIRED: "secret_submit_requires_owner",
1994
+ /** LUA-1079 — `requestSecret` with `pendingFor` on a client that did not declare the pending card capability. */
1995
+ PENDING_CARD_UNSUPPORTED: "secret_pending_card_unsupported"
1810
1996
  };
1811
1997
  var SECRET_OUTCOME_STATUSES = [
1812
1998
  ...SECRET_TEST_RESULTS,
@@ -2088,8 +2274,8 @@ function describeConnectionRequest(input) {
2088
2274
  }
2089
2275
  __name(describeConnectionRequest, "describeConnectionRequest");
2090
2276
  __name3(describeConnectionRequest, "describeConnectionRequest");
2091
- function operationDailyCapKey(agentId, connectionId, currency, utcDay) {
2092
- return `opcap:${agentId}:${connectionId}:${currency.toUpperCase()}:${utcDay}`;
2277
+ function operationDailyCapKey(agentId2, connectionId, currency, utcDay) {
2278
+ return `opcap:${agentId2}:${connectionId}:${currency.toUpperCase()}:${utcDay}`;
2093
2279
  }
2094
2280
  __name(operationDailyCapKey, "operationDailyCapKey");
2095
2281
  __name3(operationDailyCapKey, "operationDailyCapKey");
@@ -2146,7 +2332,7 @@ function parseCapAmount(value3) {
2146
2332
  }
2147
2333
  __name(parseCapAmount, "parseCapAmount");
2148
2334
  __name3(parseCapAmount, "parseCapAmount");
2149
- function parseAgentConnectionOperationLimits(agentId, value3) {
2335
+ function parseAgentConnectionOperationLimits(agentId2, value3) {
2150
2336
  if (!isPlainObject(value3)) return {
2151
2337
  ok: false,
2152
2338
  error: "limits must be an object"
@@ -2159,7 +2345,7 @@ function parseAgentConnectionOperationLimits(agentId, value3) {
2159
2345
  };
2160
2346
  }
2161
2347
  const limits = {
2162
- agentId
2348
+ agentId: agentId2
2163
2349
  };
2164
2350
  if (value3.caps !== void 0 && value3.caps !== null) {
2165
2351
  const caps = value3.caps;
@@ -2247,17 +2433,17 @@ function parseAgentConnectionOperationLimits(agentId, value3) {
2247
2433
  }
2248
2434
  __name(parseAgentConnectionOperationLimits, "parseAgentConnectionOperationLimits");
2249
2435
  __name3(parseAgentConnectionOperationLimits, "parseAgentConnectionOperationLimits");
2250
- function findAgentConnectionOperationLimits(stored, agentId) {
2251
- if (!agentId || stored === void 0 || stored === null) return void 0;
2436
+ function findAgentConnectionOperationLimits(stored, agentId2) {
2437
+ if (!agentId2 || stored === void 0 || stored === null) return void 0;
2252
2438
  if (!Array.isArray(stored)) return {
2253
- agentId,
2439
+ agentId: agentId2,
2254
2440
  unreadable: true
2255
2441
  };
2256
- const entry = stored.find((row) => isPlainObject(row) && row.agentId === agentId);
2442
+ const entry = stored.find((row) => isPlainObject(row) && row.agentId === agentId2);
2257
2443
  if (!entry) return void 0;
2258
- const parsed = parseAgentConnectionOperationLimits(agentId, entry);
2444
+ const parsed = parseAgentConnectionOperationLimits(agentId2, entry);
2259
2445
  return parsed.ok ? parsed.limits : {
2260
- agentId,
2446
+ agentId: agentId2,
2261
2447
  unreadable: true
2262
2448
  };
2263
2449
  }
@@ -3034,9 +3220,9 @@ function evalCaseThreadId(runId, caseId) {
3034
3220
  }
3035
3221
  __name(evalCaseThreadId, "evalCaseThreadId");
3036
3222
  __name3(evalCaseThreadId, "evalCaseThreadId");
3037
- function evalMonthlyCapKey(agentId, at = /* @__PURE__ */ new Date()) {
3223
+ function evalMonthlyCapKey(agentId2, at = /* @__PURE__ */ new Date()) {
3038
3224
  const yyyymm = `${at.getUTCFullYear()}${String(at.getUTCMonth() + 1).padStart(2, "0")}`;
3039
- return `evalcap:${agentId}:${yyyymm}`;
3225
+ return `evalcap:${agentId2}:${yyyymm}`;
3040
3226
  }
3041
3227
  __name(evalMonthlyCapKey, "evalMonthlyCapKey");
3042
3228
  __name3(evalMonthlyCapKey, "evalMonthlyCapKey");
@@ -3141,8 +3327,8 @@ function normalizedHandoverName(name) {
3141
3327
  }
3142
3328
  __name(normalizedHandoverName, "normalizedHandoverName");
3143
3329
  __name3(normalizedHandoverName, "normalizedHandoverName");
3144
- function handoverAgentIdSuffix(agentId) {
3145
- return agentId.slice(-6);
3330
+ function handoverAgentIdSuffix(agentId2) {
3331
+ return agentId2.slice(-6);
3146
3332
  }
3147
3333
  __name(handoverAgentIdSuffix, "handoverAgentIdSuffix");
3148
3334
  __name3(handoverAgentIdSuffix, "handoverAgentIdSuffix");
@@ -3589,11 +3775,11 @@ function parseThreadFollowUpInput(input) {
3589
3775
  }
3590
3776
  __name(parseThreadFollowUpInput, "parseThreadFollowUpInput");
3591
3777
  __name3(parseThreadFollowUpInput, "parseThreadFollowUpInput");
3592
- function threadFollowUpRateKeys(agentId, threadId, nowMs) {
3778
+ function threadFollowUpRateKeys(agentId2, threadId, nowMs) {
3593
3779
  const hour = Math.floor(nowMs / 36e5);
3594
3780
  return {
3595
- perThread: `thread-followup:${agentId}:${threadId}:${hour}`,
3596
- perAgent: `thread-followup:${agentId}:${hour}`
3781
+ perThread: `thread-followup:${agentId2}:${threadId}:${hour}`,
3782
+ perAgent: `thread-followup:${agentId2}:${hour}`
3597
3783
  };
3598
3784
  }
3599
3785
  __name(threadFollowUpRateKeys, "threadFollowUpRateKeys");
@@ -4163,6 +4349,26 @@ var CHANNEL_SETTING_GROUPS = {
4163
4349
  welcome: "Welcome and Home page",
4164
4350
  takeover: "Human takeover"
4165
4351
  };
4352
+ var THREAD_SCOPING_NOUN = {
4353
+ front: "Front conversation",
4354
+ messagebird: "MessageBird conversation",
4355
+ imessage: "iMessage chat"
4356
+ };
4357
+ function threadScopingSetting(type) {
4358
+ const noun = THREAD_SCOPING_NOUN[type];
4359
+ return {
4360
+ key: `${type}.threadScoping`,
4361
+ group: "conversations",
4362
+ label: `One conversation per ${noun}`,
4363
+ help: `Each ${noun} is its own conversation with its own history.`,
4364
+ effect: "Off: every message from the same person shares one conversation.",
4365
+ type: "boolean",
4366
+ default: false,
4367
+ confirm: "Changing this starts fresh conversations for ones that are already open. Earlier history isn't carried over."
4368
+ };
4369
+ }
4370
+ __name(threadScopingSetting, "threadScopingSetting");
4371
+ __name3(threadScopingSetting, "threadScopingSetting");
4166
4372
  var TAKEOVER_CHANNEL_TYPES = [
4167
4373
  "whatsapp",
4168
4374
  "instagram",
@@ -4469,7 +4675,10 @@ var SLACK_SETTINGS = [
4469
4675
  var CHANNEL_SETTINGS = {
4470
4676
  ...Object.fromEntries(TAKEOVER_CHANNEL_TYPES.map((type) => [
4471
4677
  type,
4472
- type === "email" ? EMAIL_SETTINGS : takeoverSettings(type)
4678
+ type === "email" ? EMAIL_SETTINGS : type === "front" || type === "messagebird" || type === "imessage" ? [
4679
+ ...takeoverSettings(type),
4680
+ threadScopingSetting(type)
4681
+ ] : takeoverSettings(type)
4473
4682
  ])),
4474
4683
  slack: SLACK_SETTINGS
4475
4684
  };
@@ -8145,6 +8354,12 @@ function workflowOrgSlotKey(orgId, kind) {
8145
8354
  __name(workflowOrgSlotKey, "workflowOrgSlotKey");
8146
8355
  __name3(workflowOrgSlotKey, "workflowOrgSlotKey");
8147
8356
  var WORKFLOW_CONNECTION_KEY_RE = /^[a-z][a-z0-9_-]{0,63}$/;
8357
+ var WORKFLOW_AGENT_APP_CONNECTION_PREFIX = "agentapp_";
8358
+ function isWorkflowAgentAppConnectionId(id2) {
8359
+ return typeof id2 === "string" && id2.startsWith(WORKFLOW_AGENT_APP_CONNECTION_PREFIX) && /^[A-Za-z0-9_-]{1,128}$/.test(id2);
8360
+ }
8361
+ __name(isWorkflowAgentAppConnectionId, "isWorkflowAgentAppConnectionId");
8362
+ __name3(isWorkflowAgentAppConnectionId, "isWorkflowAgentAppConnectionId");
8148
8363
  var WORKFLOW_JOB_MODEL_SOURCE_LABELS = {
8149
8364
  stamp: "lease stamp",
8150
8365
  initData: "run input",
@@ -8179,6 +8394,7 @@ var WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS = [
8179
8394
  ...WORKFLOW_RUN_GATE_KINDS
8180
8395
  ];
8181
8396
  var WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
8397
+ var WORKFLOW_SIGNAL_NAME_RE = /^[a-zA-Z0-9_.-]{1,64}$/;
8182
8398
  var WORKFLOW_SUSPEND_DEFAULT_TIMEOUT_HOURS = 168;
8183
8399
  var WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES = 256 * 1024;
8184
8400
  var SCHEDULE_HEALTH_NOTIFY_CHANNELS = [
@@ -8385,8 +8601,8 @@ function scheduleHealthView(health, state3) {
8385
8601
  }
8386
8602
  __name(scheduleHealthView, "scheduleHealthView");
8387
8603
  __name3(scheduleHealthView, "scheduleHealthView");
8388
- function scheduleHealthSourceId(agentId, jobId) {
8389
- return `schedule-health:${agentId}:${jobId}`;
8604
+ function scheduleHealthSourceId(agentId2, jobId) {
8605
+ return `schedule-health:${agentId2}:${jobId}`;
8390
8606
  }
8391
8607
  __name(scheduleHealthSourceId, "scheduleHealthSourceId");
8392
8608
  __name3(scheduleHealthSourceId, "scheduleHealthSourceId");
@@ -9745,7 +9961,7 @@ function evidenceDays(from, to) {
9745
9961
  __name(evidenceDays, "evidenceDays");
9746
9962
  __name3(evidenceDays, "evidenceDays");
9747
9963
  function summarizeEvidence(input) {
9748
- const { agentId, from, to } = input;
9964
+ const { agentId: agentId2, from, to } = input;
9749
9965
  const windowDays = evidenceDays(from, to);
9750
9966
  const readable = /* @__PURE__ */ __name3((s) => s === "ok" || s === "empty", "readable");
9751
9967
  const covered = /* @__PURE__ */ __name3((d) => readable(d.sources?.messages) && readable(d.sources?.analyses), "covered");
@@ -9819,7 +10035,7 @@ function summarizeEvidence(input) {
9819
10035
  const short = wordRows.reduce((a, h) => a + h.short, 0);
9820
10036
  const long = wordRows.reduce((a, h) => a + h.long, 0);
9821
10037
  return {
9822
- agentId,
10038
+ agentId: agentId2,
9823
10039
  window: {
9824
10040
  from,
9825
10041
  to,
@@ -10577,7 +10793,7 @@ function classifyConnectionOperation(op) {
10577
10793
  __name(classifyConnectionOperation, "classifyConnectionOperation");
10578
10794
  __name3(classifyConnectionOperation, "classifyConnectionOperation");
10579
10795
  function connectionSendPolicyIsActive(policy) {
10580
- return Boolean(policy) && (policy.allowSend === false || Array.isArray(policy.recipientAllowlist));
10796
+ return !!policy && (policy.allowSend === false || Array.isArray(policy.recipientAllowlist));
10581
10797
  }
10582
10798
  __name(connectionSendPolicyIsActive, "connectionSendPolicyIsActive");
10583
10799
  __name3(connectionSendPolicyIsActive, "connectionSendPolicyIsActive");
@@ -10613,8 +10829,9 @@ function evaluateConnectionSendPolicy(policy, op) {
10613
10829
  classification
10614
10830
  };
10615
10831
  }
10616
- if (Array.isArray(policy.recipientAllowlist)) {
10617
- const denied = classification.recipients.filter((email) => !allowlistAdmits(policy.recipientAllowlist, email));
10832
+ const allowlist = policy.recipientAllowlist;
10833
+ if (Array.isArray(allowlist)) {
10834
+ const denied = classification.recipients.filter((email) => !allowlistAdmits(allowlist, email));
10618
10835
  if (denied.length > 0 || classification.recipientsUnknown) {
10619
10836
  return {
10620
10837
  allowed: false,
@@ -10668,10 +10885,605 @@ function isPaymentRequiredChatErrorEnvelope(data) {
10668
10885
  }
10669
10886
  __name(isPaymentRequiredChatErrorEnvelope, "isPaymentRequiredChatErrorEnvelope");
10670
10887
  __name3(isPaymentRequiredChatErrorEnvelope, "isPaymentRequiredChatErrorEnvelope");
10888
+ var CUSTOM_MCP_CONNECTION_ID_PREFIX = "mcp_";
10889
+ var CUSTOM_MCP_SOURCE = "custom";
10890
+ var CUSTOM_MCP_TRANSPORT = "streamable-http";
10891
+ var CUSTOM_MCP_CONNECTION_ID_PATTERN = /^mcp_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
10892
+ function isCustomMcpConnectionId(id2) {
10893
+ return typeof id2 === "string" && id2.startsWith(CUSTOM_MCP_CONNECTION_ID_PREFIX);
10894
+ }
10895
+ __name(isCustomMcpConnectionId, "isCustomMcpConnectionId");
10896
+ __name3(isCustomMcpConnectionId, "isCustomMcpConnectionId");
10897
+ var customMcpConnectionIdSchema = z5.string().regex(CUSTOM_MCP_CONNECTION_ID_PATTERN);
10898
+ var CONNECTION_BACKED_MCP_SOURCES = [
10899
+ "unifiedto",
10900
+ CUSTOM_MCP_SOURCE
10901
+ ];
10902
+ function isConnectionBackedMcpSource(source) {
10903
+ return typeof source === "string" && CONNECTION_BACKED_MCP_SOURCES.includes(source);
10904
+ }
10905
+ __name(isConnectionBackedMcpSource, "isConnectionBackedMcpSource");
10906
+ __name3(isConnectionBackedMcpSource, "isConnectionBackedMcpSource");
10907
+ var CUSTOM_MCP_REFERENCE_ID_PATTERN = /^mcpx_[0-9a-f]{12}$/;
10908
+ var customMcpReferenceIdSchema = z5.string().regex(CUSTOM_MCP_REFERENCE_ID_PATTERN);
10909
+ function newCustomMcpReferenceId() {
10910
+ const bytes = globalThis.crypto.getRandomValues(new Uint8Array(6));
10911
+ return `mcpx_${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
10912
+ }
10913
+ __name(newCustomMcpReferenceId, "newCustomMcpReferenceId");
10914
+ __name3(newCustomMcpReferenceId, "newCustomMcpReferenceId");
10915
+ var CUSTOM_MCP_AUTH_KINDS = [
10916
+ "none",
10917
+ "headers",
10918
+ "oauth"
10919
+ ];
10920
+ var customMcpAuthKindSchema = z5.enum(CUSTOM_MCP_AUTH_KINDS);
10921
+ var CUSTOM_MCP_OAUTH_REGISTRATIONS = [
10922
+ "cimd",
10923
+ "dcr",
10924
+ "manual"
10925
+ ];
10926
+ var customMcpOAuthRegistrationSchema = z5.enum(CUSTOM_MCP_OAUTH_REGISTRATIONS);
10927
+ var CUSTOM_MCP_HEALTH_STATES = [
10928
+ "ok",
10929
+ "failing",
10930
+ "needs_sign_in",
10931
+ "auth_rejected"
10932
+ ];
10933
+ var customMcpHealthStateSchema = z5.enum(CUSTOM_MCP_HEALTH_STATES);
10934
+ var CUSTOM_MCP_FAILURE_STEPS = [
10935
+ "url",
10936
+ "reach",
10937
+ "auth_challenge",
10938
+ "resource_metadata",
10939
+ "authorization_server_metadata",
10940
+ "pkce",
10941
+ "client_registration",
10942
+ "authorize",
10943
+ "token_exchange",
10944
+ "list_tools"
10945
+ ];
10946
+ var customMcpFailureStepSchema = z5.enum(CUSTOM_MCP_FAILURE_STEPS);
10947
+ var CUSTOM_MCP_CONNECT_STEPS = [
10948
+ "url",
10949
+ "reach",
10950
+ "auth_challenge",
10951
+ "list_tools"
10952
+ ];
10953
+ var customMcpConnectStepSchema = z5.enum(CUSTOM_MCP_CONNECT_STEPS);
10954
+ var customMcpFailureCodeSchema = z5.string().regex(/^[a-z0-9_]{1,64}$/);
10955
+ var WORKFLOW_KEY_MAX_LENGTH = 64;
10956
+ function customMcpWorkflowKey(displayName) {
10957
+ const slug = displayName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10958
+ if (!slug) return `s-${fnv1a32(displayName.trim())}`;
10959
+ return (/^[a-z]/.test(slug) ? slug : `s-${slug}`).slice(0, WORKFLOW_KEY_MAX_LENGTH);
10960
+ }
10961
+ __name(customMcpWorkflowKey, "customMcpWorkflowKey");
10962
+ __name3(customMcpWorkflowKey, "customMcpWorkflowKey");
10963
+ function fnv1a32(value3) {
10964
+ let hash = 2166136261;
10965
+ for (const char of value3) {
10966
+ hash ^= char.codePointAt(0) ?? 0;
10967
+ hash = Math.imul(hash, 16777619) >>> 0;
10968
+ }
10969
+ return hash.toString(16).padStart(8, "0");
10970
+ }
10971
+ __name(fnv1a32, "fnv1a32");
10972
+ __name3(fnv1a32, "fnv1a32");
10973
+ var CUSTOM_MCP_URL_MAX_LENGTH = 2048;
10974
+ var CUSTOM_MCP_DISPLAY_NAME_MAX_LENGTH = 120;
10975
+ var CUSTOM_MCP_MAX_HEADERS = 20;
10976
+ var CUSTOM_MCP_HEADER_NAME_MAX_LENGTH = 128;
10977
+ var CUSTOM_MCP_HEADER_VALUE_MAX_LENGTH = 8192;
10978
+ var CUSTOM_MCP_MAX_TOOLS = 500;
10979
+ var CUSTOM_MCP_TOOL_NAME_MAX_LENGTH = 256;
10980
+ var CUSTOM_MCP_TOOL_TEXT_MAX_LENGTH = 1024;
10981
+ var CUSTOM_MCP_MIN_TIMEOUT_MS = 1e3;
10982
+ var CUSTOM_MCP_MAX_TIMEOUT_MS = 12e4;
10983
+ var CUSTOM_MCP_OAUTH_PENDING_TTL_MS = 15 * 6e4;
10984
+ var isoDateTime = z5.string().datetime({
10985
+ offset: true
10986
+ });
10987
+ var agentId = z5.string().min(1).max(128);
10988
+ var nonNegativeInt = z5.number().int().min(0);
10989
+ var customMcpUrlInputSchema = z5.string().trim().min(1).max(CUSTOM_MCP_URL_MAX_LENGTH);
10990
+ var customMcpDisplayNameSchema = z5.string().trim().min(1).max(CUSTOM_MCP_DISPLAY_NAME_MAX_LENGTH);
10991
+ var customMcpTimeoutSchema = z5.number().int().min(CUSTOM_MCP_MIN_TIMEOUT_MS).max(CUSTOM_MCP_MAX_TIMEOUT_MS);
10992
+ var CUSTOM_MCP_RESERVED_HEADER_NAMES = [
10993
+ "accept",
10994
+ "connection",
10995
+ "content-length",
10996
+ "content-type",
10997
+ "host",
10998
+ "keep-alive",
10999
+ "last-event-id",
11000
+ "mcp-protocol-version",
11001
+ "mcp-session-id",
11002
+ "proxy-authorization",
11003
+ "te",
11004
+ "trailer",
11005
+ "transfer-encoding",
11006
+ "upgrade"
11007
+ ];
11008
+ var HEADER_NAME = /^[A-Za-z][A-Za-z0-9!#$%&'*+.^_`|~-]*$/;
11009
+ var HEADER_VALUE_FORBIDDEN = /[\u0000-\u0008\u000a-\u001f\u007f]/;
11010
+ var customMcpHeaderNameSchema = z5.string().min(1).max(CUSTOM_MCP_HEADER_NAME_MAX_LENGTH).regex(HEADER_NAME, "Not a valid HTTP header name").refine((name) => !CUSTOM_MCP_RESERVED_HEADER_NAMES.includes(name.toLowerCase()), "This header is set by Lua");
11011
+ var headerValue = z5.string().min(1).max(CUSTOM_MCP_HEADER_VALUE_MAX_LENGTH).refine((value3) => !HEADER_VALUE_FORBIDDEN.test(value3), "Header values cannot contain line breaks");
11012
+ function addCaseDuplicateIssues(names, ctx, path) {
11013
+ const seen = /* @__PURE__ */ new Set();
11014
+ for (const name of names) {
11015
+ const lower2 = name.toLowerCase();
11016
+ if (seen.has(lower2)) {
11017
+ ctx.addIssue({
11018
+ code: z5.ZodIssueCode.custom,
11019
+ path,
11020
+ message: `Header "${name}" is listed twice`
11021
+ });
11022
+ }
11023
+ seen.add(lower2);
11024
+ }
11025
+ }
11026
+ __name(addCaseDuplicateIssues, "addCaseDuplicateIssues");
11027
+ __name3(addCaseDuplicateIssues, "addCaseDuplicateIssues");
11028
+ var customMcpHeadersSchema = z5.record(customMcpHeaderNameSchema, headerValue).superRefine((headers, ctx) => {
11029
+ const names = Object.keys(headers);
11030
+ if (names.length > CUSTOM_MCP_MAX_HEADERS) {
11031
+ ctx.addIssue({
11032
+ code: z5.ZodIssueCode.custom,
11033
+ message: `At most ${CUSTOM_MCP_MAX_HEADERS} headers`
11034
+ });
11035
+ }
11036
+ addCaseDuplicateIssues(names, ctx, []);
11037
+ });
11038
+ var customMcpHeadersPatchSchema = z5.object({
11039
+ set: customMcpHeadersSchema.optional(),
11040
+ remove: z5.array(customMcpHeaderNameSchema).max(CUSTOM_MCP_MAX_HEADERS).optional()
11041
+ }).strict().superRefine((patch, ctx) => {
11042
+ const set = Object.keys(patch.set ?? {});
11043
+ const remove = patch.remove ?? [];
11044
+ if (!set.length && !remove.length) {
11045
+ ctx.addIssue({
11046
+ code: z5.ZodIssueCode.custom,
11047
+ message: "Nothing to change"
11048
+ });
11049
+ }
11050
+ addCaseDuplicateIssues(remove, ctx, [
11051
+ "remove"
11052
+ ]);
11053
+ const setLower = new Set(set.map((name) => name.toLowerCase()));
11054
+ for (const name of remove) {
11055
+ if (setLower.has(name.toLowerCase())) {
11056
+ ctx.addIssue({
11057
+ code: z5.ZodIssueCode.custom,
11058
+ path: [
11059
+ "remove"
11060
+ ],
11061
+ message: `Header "${name}" is both set and removed`
11062
+ });
11063
+ }
11064
+ }
11065
+ });
11066
+ var customMcpToolNameSchema = z5.string().min(1).max(CUSTOM_MCP_TOOL_NAME_MAX_LENGTH);
11067
+ var customMcpToolSchema = z5.object({
11068
+ name: customMcpToolNameSchema,
11069
+ title: z5.string().max(CUSTOM_MCP_TOOL_TEXT_MAX_LENGTH).optional(),
11070
+ description: z5.string().max(CUSTOM_MCP_TOOL_TEXT_MAX_LENGTH).optional()
11071
+ });
11072
+ var customMcpServerInfoSchema = z5.object({
11073
+ name: z5.string().max(CUSTOM_MCP_TOOL_NAME_MAX_LENGTH),
11074
+ version: z5.string().max(128).optional(),
11075
+ title: z5.string().max(CUSTOM_MCP_TOOL_NAME_MAX_LENGTH).optional()
11076
+ });
11077
+ function toCustomMcpToolSnapshot(tools) {
11078
+ const snapshot = [];
11079
+ const seen = /* @__PURE__ */ new Set();
11080
+ for (const tool of tools) {
11081
+ if (snapshot.length >= CUSTOM_MCP_MAX_TOOLS) break;
11082
+ const name = tool.name;
11083
+ if (typeof name !== "string" || !name || name.length > CUSTOM_MCP_TOOL_NAME_MAX_LENGTH || seen.has(name)) continue;
11084
+ seen.add(name);
11085
+ snapshot.push({
11086
+ name,
11087
+ ...typeof tool.title === "string" && tool.title ? {
11088
+ title: tool.title.slice(0, CUSTOM_MCP_TOOL_TEXT_MAX_LENGTH)
11089
+ } : {},
11090
+ ...typeof tool.description === "string" && tool.description ? {
11091
+ description: tool.description.slice(0, CUSTOM_MCP_TOOL_TEXT_MAX_LENGTH)
11092
+ } : {}
11093
+ });
11094
+ }
11095
+ return snapshot;
11096
+ }
11097
+ __name(toCustomMcpToolSnapshot, "toCustomMcpToolSnapshot");
11098
+ __name3(toCustomMcpToolSnapshot, "toCustomMcpToolSnapshot");
11099
+ var customMcpToolSelectionSchema = z5.object({
11100
+ allowAll: z5.boolean(),
11101
+ enabled: z5.array(customMcpToolNameSchema).max(CUSTOM_MCP_MAX_TOOLS)
11102
+ }).strict().refine((selection) => new Set(selection.enabled).size === selection.enabled.length, {
11103
+ path: [
11104
+ "enabled"
11105
+ ],
11106
+ message: "Tool names must be unique"
11107
+ });
11108
+ function customMcpRuntimeToolFilter(selection) {
11109
+ return selection.allowAll ? void 0 : {
11110
+ allow: [
11111
+ ...selection.enabled
11112
+ ]
11113
+ };
11114
+ }
11115
+ __name(customMcpRuntimeToolFilter, "customMcpRuntimeToolFilter");
11116
+ __name3(customMcpRuntimeToolFilter, "customMcpRuntimeToolFilter");
11117
+ var customMcpToolsResponseSchema = z5.object({
11118
+ allowAll: z5.boolean(),
11119
+ tools: z5.array(customMcpToolSchema.extend({
11120
+ enabled: z5.boolean()
11121
+ })),
11122
+ serverInfo: customMcpServerInfoSchema.optional(),
11123
+ refreshedAt: isoDateTime.optional()
11124
+ });
11125
+ var customMcpFailureSchema = z5.object({
11126
+ step: customMcpFailureStepSchema,
11127
+ code: customMcpFailureCodeSchema,
11128
+ /** Plain words for the person connecting. */
11129
+ message: z5.string().max(500),
11130
+ httpStatus: z5.number().int().min(100).max(599).optional(),
11131
+ referenceId: customMcpReferenceIdSchema
11132
+ });
11133
+ var customMcpHealthSchema = z5.object({
11134
+ state: customMcpHealthStateSchema,
11135
+ checkedAt: isoDateTime.optional(),
11136
+ lastOkAt: isoDateTime.optional(),
11137
+ lastFailureAt: isoDateTime.optional(),
11138
+ consecutiveFailures: nonNegativeInt,
11139
+ lastFailure: customMcpFailureSchema.omit({
11140
+ message: true
11141
+ }).optional()
11142
+ });
11143
+ var customMcpErrorBodySchema = z5.object({
11144
+ code: z5.string(),
11145
+ message: z5.string(),
11146
+ failure: customMcpFailureSchema.optional(),
11147
+ callbackUrl: z5.string().url().optional(),
11148
+ retryAfterSeconds: z5.number().int().positive().optional()
11149
+ });
11150
+ var customMcpConnectionBlockSchema = z5.object({
11151
+ authKind: customMcpAuthKindSchema,
11152
+ /** `URL.host`, port included. */
11153
+ host: z5.string(),
11154
+ /** Host plus a masked path; never the URL. */
11155
+ urlDisplay: z5.string(),
11156
+ /** Names only, for the edit form. Present on `headers` connections. */
11157
+ headerNames: z5.array(z5.string()).optional(),
11158
+ /** The workflow connection key that names this server: {@link customMcpWorkflowKey} of its display name. */
11159
+ workflowKey: z5.string().regex(WORKFLOW_CONNECTION_KEY_RE).optional(),
11160
+ health: customMcpHealthSchema,
11161
+ toolCount: nonNegativeInt,
11162
+ enabledToolCount: nonNegativeInt
11163
+ });
11164
+ var customMcpConnectionViewSchema = z5.object({
11165
+ id: customMcpConnectionIdSchema,
11166
+ displayName: z5.string(),
11167
+ ownerType: z5.enum([
11168
+ "user",
11169
+ "agent"
11170
+ ]),
11171
+ agentId: z5.string().optional(),
11172
+ customMcp: customMcpConnectionBlockSchema
11173
+ });
11174
+ var customMcpConnectionResponseSchema = z5.object({
11175
+ connection: customMcpConnectionViewSchema
11176
+ });
11177
+ var customMcpProbeBodySchema = z5.object({
11178
+ url: customMcpUrlInputSchema,
11179
+ headers: customMcpHeadersSchema.optional()
11180
+ }).strict();
11181
+ var customMcpOAuthDiscoverySchema = z5.object({
11182
+ issuer: z5.string().url(),
11183
+ scopes: z5.array(z5.string()),
11184
+ /** `manual_required`: neither CIMD nor DCR; the person registers a client with `callbackUrl`. */
11185
+ registration: z5.enum([
11186
+ "cimd",
11187
+ "dcr",
11188
+ "manual_required"
11189
+ ]),
11190
+ callbackUrl: z5.string().url()
11191
+ });
11192
+ var customMcpProbeResponseSchema = z5.discriminatedUnion("outcome", [
11193
+ z5.object({
11194
+ outcome: z5.literal("connected"),
11195
+ authKind: z5.enum([
11196
+ "none",
11197
+ "headers"
11198
+ ]),
11199
+ serverInfo: customMcpServerInfoSchema,
11200
+ tools: z5.array(customMcpToolSchema)
11201
+ }),
11202
+ /** The server challenged and publishes usable OAuth metadata. */
11203
+ z5.object({
11204
+ outcome: z5.literal("sign_in_required"),
11205
+ oauth: customMcpOAuthDiscoverySchema
11206
+ }),
11207
+ /** The server challenged without usable OAuth and no headers were sent. */
11208
+ z5.object({
11209
+ outcome: z5.literal("credentials_required"),
11210
+ httpStatus: z5.number().int()
11211
+ })
11212
+ ]);
11213
+ var createFields = {
11214
+ url: customMcpUrlInputSchema,
11215
+ displayName: customMcpDisplayNameSchema,
11216
+ timeout: customMcpTimeoutSchema.optional(),
11217
+ /** Defaults to allow-all. */
11218
+ tools: customMcpToolSelectionSchema.optional()
11219
+ };
11220
+ var mountAgentField = {
11221
+ mountAgentId: agentId.optional()
11222
+ };
11223
+ function createBody(extra) {
11224
+ return z5.discriminatedUnion("authKind", [
11225
+ z5.object({
11226
+ authKind: z5.literal("none"),
11227
+ ...createFields,
11228
+ ...extra
11229
+ }).strict(),
11230
+ z5.object({
11231
+ authKind: z5.literal("headers"),
11232
+ headers: customMcpHeadersSchema.refine((headers) => Object.keys(headers).length > 0, "Add a header"),
11233
+ ...createFields,
11234
+ ...extra
11235
+ }).strict()
11236
+ ]);
11237
+ }
11238
+ __name(createBody, "createBody");
11239
+ __name3(createBody, "createBody");
11240
+ var customMcpCreateAgentBodySchema = createBody({});
11241
+ var customMcpCreateUserBodySchema = createBody(mountAgentField);
11242
+ var customMcpOAuthClientSchema = z5.object({
11243
+ clientId: z5.string().trim().min(1).max(512),
11244
+ clientSecret: z5.string().min(1).max(2048).optional()
11245
+ }).strict();
11246
+ var startFields = {
11247
+ successRedirect: z5.string().max(CUSTOM_MCP_URL_MAX_LENGTH),
11248
+ failureRedirect: z5.string().max(CUSTOM_MCP_URL_MAX_LENGTH),
11249
+ state: z5.string().max(256),
11250
+ client: customMcpOAuthClientSchema.optional()
11251
+ };
11252
+ function startBody(extra) {
11253
+ return z5.union([
11254
+ z5.object({
11255
+ url: customMcpUrlInputSchema,
11256
+ displayName: customMcpDisplayNameSchema,
11257
+ ...startFields,
11258
+ ...extra
11259
+ }).strict(),
11260
+ /** Sign in again. `url` only after `REAUTH_REQUIRED`; otherwise the stored URL is used. */
11261
+ z5.object({
11262
+ targetConnectionId: customMcpConnectionIdSchema,
11263
+ url: customMcpUrlInputSchema.optional(),
11264
+ ...startFields
11265
+ }).strict()
11266
+ ]);
11267
+ }
11268
+ __name(startBody, "startBody");
11269
+ __name3(startBody, "startBody");
11270
+ var customMcpOAuthStartAgentBodySchema = startBody({});
11271
+ var customMcpOAuthStartUserBodySchema = startBody(mountAgentField);
11272
+ var customMcpOAuthStartResponseSchema = z5.object({
11273
+ authUrl: z5.string().url(),
11274
+ pendingId: z5.string().min(1),
11275
+ expiresAt: isoDateTime,
11276
+ registration: customMcpOAuthRegistrationSchema
11277
+ });
11278
+ var nonce = z5.string().regex(/^[A-Za-z0-9_-]{32,128}$/);
11279
+ var customMcpOAuthSuccessRedirectQuerySchema = z5.object({
11280
+ state: z5.string(),
11281
+ id: z5.string().min(1),
11282
+ nonce
11283
+ });
11284
+ var CUSTOM_MCP_OAUTH_CALLBACK_ERRORS = [
11285
+ "access_denied",
11286
+ "authorize",
11287
+ "token_exchange",
11288
+ "expired"
11289
+ ];
11290
+ var customMcpOAuthFailureRedirectQuerySchema = z5.object({
11291
+ state: z5.string(),
11292
+ error: z5.enum(CUSTOM_MCP_OAUTH_CALLBACK_ERRORS),
11293
+ ref: customMcpReferenceIdSchema
11294
+ });
11295
+ var customMcpOAuthFinalizeBodySchema = z5.object({
11296
+ pendingId: z5.string().min(1).max(128),
11297
+ nonce,
11298
+ tools: customMcpToolSelectionSchema.optional()
11299
+ }).strict();
11300
+ var customMcpCimdDocumentSchema = z5.object({
11301
+ client_id: z5.string().url(),
11302
+ client_name: z5.string(),
11303
+ client_uri: z5.string().url().optional(),
11304
+ logo_uri: z5.string().url().optional(),
11305
+ redirect_uris: z5.array(z5.string().url()).min(1),
11306
+ grant_types: z5.array(z5.enum([
11307
+ "authorization_code",
11308
+ "refresh_token"
11309
+ ])),
11310
+ response_types: z5.array(z5.literal("code")),
11311
+ token_endpoint_auth_method: z5.literal("none")
11312
+ });
11313
+ var customMcpPatchBodySchema = z5.object({
11314
+ displayName: customMcpDisplayNameSchema.optional(),
11315
+ url: customMcpUrlInputSchema.optional(),
11316
+ headers: customMcpHeadersPatchSchema.optional(),
11317
+ timeout: customMcpTimeoutSchema.optional()
11318
+ }).strict().refine((body) => Object.values(body).some((value3) => value3 !== void 0), {
11319
+ message: "Nothing to change"
11320
+ });
11321
+ var customMcpCredentialRequestSchema = z5.object({
11322
+ mode: z5.enum([
11323
+ "mount",
11324
+ "room_personal"
11325
+ ]),
11326
+ connectionId: customMcpConnectionIdSchema,
11327
+ agentId,
11328
+ /** The server rejected this token version: refresh unless it is already stale. */
11329
+ rejectedTokenVersion: nonNegativeInt.optional()
11330
+ }).strict();
11331
+ var customMcpCredentialAuthSchema = z5.discriminatedUnion("kind", [
11332
+ z5.object({
11333
+ kind: z5.literal("none")
11334
+ }),
11335
+ z5.object({
11336
+ kind: z5.literal("headers"),
11337
+ headers: z5.record(z5.string(), z5.string())
11338
+ }),
11339
+ z5.object({
11340
+ kind: z5.literal("oauth"),
11341
+ accessToken: z5.string().min(1),
11342
+ tokenVersion: nonNegativeInt,
11343
+ /** At least {@link CUSTOM_MCP_ACCESS_TOKEN_MIN_REMAINING_MS} away. */
11344
+ expiresAt: isoDateTime
11345
+ })
11346
+ ]);
11347
+ var customMcpCredentialResponseSchema = z5.object({
11348
+ connectionId: customMcpConnectionIdSchema,
11349
+ credentialGeneration: nonNegativeInt,
11350
+ url: z5.string().url(),
11351
+ auth: customMcpCredentialAuthSchema
11352
+ });
11353
+ var CUSTOM_MCP_CREDENTIAL_ERRORS = {
11354
+ /** 403. Not mounted on this agent, or the room grant is no longer current. */
11355
+ NOT_MOUNTED: "NOT_MOUNTED",
11356
+ /** 404. */
11357
+ NOT_FOUND: "NOT_FOUND",
11358
+ /** 409. Paused by its owner. */
11359
+ PAUSED: "PAUSED",
11360
+ /** 409. The refresh token is gone or was refused; the owner must sign in again. */
11361
+ NEEDS_SIGN_IN: "NEEDS_SIGN_IN",
11362
+ /** 503. The token endpoint failed; retry later. */
11363
+ REFRESH_UNAVAILABLE: "REFRESH_UNAVAILABLE"
11364
+ };
11365
+ var customMcpCredentialErrorBodySchema = z5.object({
11366
+ code: z5.nativeEnum(CUSTOM_MCP_CREDENTIAL_ERRORS),
11367
+ message: z5.string()
11368
+ });
11369
+ var customMcpHealthReportSchema = z5.object({
11370
+ reports: z5.array(z5.object({
11371
+ connectionId: customMcpConnectionIdSchema,
11372
+ agentId,
11373
+ credentialGeneration: nonNegativeInt,
11374
+ tokenVersion: nonNegativeInt.optional(),
11375
+ outcome: z5.enum([
11376
+ "ok",
11377
+ "failure"
11378
+ ]),
11379
+ failure: z5.object({
11380
+ step: customMcpConnectStepSchema,
11381
+ code: customMcpFailureCodeSchema,
11382
+ httpStatus: z5.number().int().min(100).max(599).optional(),
11383
+ referenceId: customMcpReferenceIdSchema
11384
+ }).strict().optional(),
11385
+ observedAt: isoDateTime
11386
+ }).strict().refine((report) => report.outcome === "failure" === (report.failure !== void 0), {
11387
+ path: [
11388
+ "failure"
11389
+ ],
11390
+ message: "A failure report carries `failure`; an ok report does not"
11391
+ })).min(1).max(50)
11392
+ }).strict();
11393
+ var customMcpProbeRequestSchema = z5.object({
11394
+ url: z5.string().url().max(CUSTOM_MCP_URL_MAX_LENGTH),
11395
+ auth: z5.discriminatedUnion("kind", [
11396
+ z5.object({
11397
+ kind: z5.literal("none")
11398
+ }).strict(),
11399
+ z5.object({
11400
+ kind: z5.literal("headers"),
11401
+ headers: customMcpHeadersSchema
11402
+ }).strict(),
11403
+ z5.object({
11404
+ kind: z5.literal("bearer"),
11405
+ accessToken: z5.string().min(1)
11406
+ }).strict()
11407
+ ]),
11408
+ timeout: customMcpTimeoutSchema.optional(),
11409
+ referenceId: customMcpReferenceIdSchema
11410
+ }).strict();
11411
+ var customMcpProbeResultSchema = z5.discriminatedUnion("ok", [
11412
+ z5.object({
11413
+ ok: z5.literal(true),
11414
+ serverInfo: customMcpServerInfoSchema,
11415
+ tools: z5.array(customMcpToolSchema).max(CUSTOM_MCP_MAX_TOOLS),
11416
+ protocolVersion: z5.string().optional()
11417
+ }),
11418
+ z5.object({
11419
+ ok: z5.literal(false),
11420
+ step: customMcpConnectStepSchema,
11421
+ code: customMcpFailureCodeSchema,
11422
+ httpStatus: z5.number().int().min(100).max(599).optional(),
11423
+ /** The 401/403 challenge, raw, for lua-api's OAuth discovery. */
11424
+ wwwAuthenticate: z5.string().max(4096).optional()
11425
+ })
11426
+ ]);
11427
+ var customMcpOriginUrlSchema = z5.string().url().refine((value3) => {
11428
+ try {
11429
+ const url = new URL(value3);
11430
+ return url.protocol === "https:" && url.pathname === "/" && !url.search && !url.hash && !url.username && !url.password;
11431
+ } catch {
11432
+ return false;
11433
+ }
11434
+ }, "Origin only");
11435
+ var customMcpServerProjectionSchema = z5.object({
11436
+ name: z5.string().min(1),
11437
+ runtimeKey: z5.string().min(1),
11438
+ transport: z5.literal(CUSTOM_MCP_TRANSPORT),
11439
+ source: z5.literal(CUSTOM_MCP_SOURCE),
11440
+ url: customMcpOriginUrlSchema,
11441
+ connectionId: customMcpConnectionIdSchema,
11442
+ connectionLabel: z5.string(),
11443
+ /** The connection's owner kind, for the dashboard's "Personal" label. */
11444
+ ownerType: z5.enum([
11445
+ "user",
11446
+ "agent"
11447
+ ]),
11448
+ authKind: customMcpAuthKindSchema,
11449
+ credentialGeneration: nonNegativeInt,
11450
+ tools: z5.object({
11451
+ allow: z5.array(z5.string())
11452
+ }).optional(),
11453
+ timeout: z5.number().int().positive()
11454
+ });
11455
+ var customMcpMountUpsertBodySchema = z5.object({
11456
+ source: z5.literal(CUSTOM_MCP_SOURCE),
11457
+ transport: z5.literal(CUSTOM_MCP_TRANSPORT),
11458
+ url: customMcpOriginUrlSchema,
11459
+ connectionId: customMcpConnectionIdSchema,
11460
+ connectionLabel: z5.string(),
11461
+ ownerType: z5.enum([
11462
+ "user",
11463
+ "agent"
11464
+ ]),
11465
+ authKind: customMcpAuthKindSchema,
11466
+ credentialGeneration: nonNegativeInt,
11467
+ tools: z5.object({
11468
+ allow: z5.array(customMcpToolNameSchema).max(CUSTOM_MCP_MAX_TOOLS)
11469
+ }).strict().optional(),
11470
+ timeout: customMcpTimeoutSchema.optional()
11471
+ }).strict();
11472
+ function maskMcpServerHeaders(server) {
11473
+ const { headers, ...rest } = server;
11474
+ const headerNames = Object.keys(headers ?? {});
11475
+ return {
11476
+ ...rest,
11477
+ headerNames,
11478
+ headersSet: headerNames.length > 0
11479
+ };
11480
+ }
11481
+ __name(maskMcpServerHeaders, "maskMcpServerHeaders");
11482
+ __name3(maskMcpServerHeaders, "maskMcpServerHeaders");
10671
11483
 
10672
11484
  // ../workflow-graph/dist/index.mjs
10673
11485
  import { createHash } from "crypto";
10674
- import { z as z5 } from "zod";
11486
+ import { z as z6 } from "zod";
10675
11487
  import { z as z22 } from "zod";
10676
11488
  import { createHash as createHash2 } from "crypto";
10677
11489
  var __defProp4 = Object.defineProperty;
@@ -10966,8 +11778,8 @@ var rows = /* @__PURE__ */ __name4((s, path, page) => ({
10966
11778
  var fromKnowledge = /* @__PURE__ */ __name4((k) => ({
10967
11779
  knowledge: k
10968
11780
  }), "fromKnowledge");
10969
- var SideEffectsSchema = z5.enum(WORKFLOW_SIDE_EFFECTS);
10970
- var JobResourcesSchema = z5.enum(WORKFLOW_JOB_RESOURCES);
11781
+ var SideEffectsSchema = z6.enum(WORKFLOW_SIDE_EFFECTS);
11782
+ var JobResourcesSchema = z6.enum(WORKFLOW_JOB_RESOURCES);
10971
11783
  var WORKFLOW_MODEL_TEMPLATE_ROOT = "initData";
10972
11784
  var WORKFLOW_MODEL_TEMPLATE_RE = /^\$\{\s*initData\.([A-Za-z0-9_.\-[\]]+)\s*(?:\|([^}]*))?\}$/;
10973
11785
  var PATH_SEGMENT_RE = /^[A-Za-z0-9_-]+(?:\[(?:0|[1-9]\d*)\])*$/;
@@ -11309,6 +12121,8 @@ __name(validateApproverBlock, "validateApproverBlock");
11309
12121
  __name4(validateApproverBlock, "validateApproverBlock");
11310
12122
  var APPROVAL_REMIND_AFTER_HOURS_MIN = 1;
11311
12123
  var APPROVAL_REMIND_AFTER_HOURS_MAX = 720;
12124
+ var APPROVAL_TIMEOUT_HOURS_MIN = 1;
12125
+ var APPROVAL_TIMEOUT_HOURS_MAX = 720;
11312
12126
  function validateApprovalReminder(node, path) {
11313
12127
  if (node.remindAfterHours === void 0) return [];
11314
12128
  const h = node.remindAfterHours;
@@ -11338,6 +12152,21 @@ function validateApprovalReminder(node, path) {
11338
12152
  }
11339
12153
  __name(validateApprovalReminder, "validateApprovalReminder");
11340
12154
  __name4(validateApprovalReminder, "validateApprovalReminder");
12155
+ function validateHitlTimeoutHours(node, path) {
12156
+ const h = node.timeoutHours;
12157
+ if (typeof h !== "number") return [];
12158
+ if (Number.isFinite(h) && h >= APPROVAL_TIMEOUT_HOURS_MIN && h <= APPROVAL_TIMEOUT_HOURS_MAX) return [];
12159
+ return [
12160
+ {
12161
+ code: "timeout-hours-out-of-range",
12162
+ path: `${path}.timeoutHours`,
12163
+ severity: "error",
12164
+ message: `timeoutHours must be a number of hours in [${APPROVAL_TIMEOUT_HOURS_MIN}, ${APPROVAL_TIMEOUT_HOURS_MAX}] (got ${h})`
12165
+ }
12166
+ ];
12167
+ }
12168
+ __name(validateHitlTimeoutHours, "validateHitlTimeoutHours");
12169
+ __name4(validateHitlTimeoutHours, "validateHitlTimeoutHours");
11341
12170
  function firstAskDeadline(node) {
11342
12171
  const head = Array.isArray(node.onTimeout) ? node.onTimeout[0] : node.onTimeout;
11343
12172
  if (typeof head === "object" && head !== null && "escalateTo" in head) {
@@ -11426,6 +12255,11 @@ function sleepUntilUnsupportedMessage(id2) {
11426
12255
  }
11427
12256
  __name(sleepUntilUnsupportedMessage, "sleepUntilUnsupportedMessage");
11428
12257
  __name4(sleepUntilUnsupportedMessage, "sleepUntilUnsupportedMessage");
12258
+ function signalNameInvalidMessage(id2, name) {
12259
+ return `waitForSignal "${id2}" signal "${name}" must match /${WORKFLOW_SIGNAL_NAME_RE.source}/ (the names a delivery accepts)`;
12260
+ }
12261
+ __name(signalNameInvalidMessage, "signalNameInvalidMessage");
12262
+ __name4(signalNameInvalidMessage, "signalNameInvalidMessage");
11429
12263
  function armSubrunUnsupportedMessage(id2, workflowId) {
11430
12264
  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)`;
11431
12265
  }
@@ -12099,10 +12933,13 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
12099
12933
  const w = node;
12100
12934
  checkId(w.id, path);
12101
12935
  if (typeof w.signal !== "string" || w.signal.length === 0) err("invalid-envelope", "waitForSignal.signal is required", `${path}.signal`, w.id);
12936
+ else if (!WORKFLOW_SIGNAL_NAME_RE.test(w.signal)) err("signal-name-invalid", signalNameInvalidMessage(w.id, w.signal), `${path}.signal`, w.id);
12937
+ for (const r of validateHitlTimeoutHours(w, path)) err(r.code, r.message, r.path, w.id);
12102
12938
  return;
12103
12939
  }
12104
12940
  const a = node;
12105
12941
  checkId(a.id, path);
12942
+ for (const r of validateHitlTimeoutHours(a, path)) err(r.code, r.message, r.path, a.id);
12106
12943
  if ((a.approver ?? "creator") === "creator" && a.excludeInitiator === true) {
12107
12944
  err("approver-excludes-only-candidate", "approver:'creator' with excludeInitiator:true always excludes the only candidate", path, a.id);
12108
12945
  }
@@ -15848,6 +16685,9 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
15848
16685
  for (const r of validateApprovalReminder(opts, `approval("${id2}")`)) {
15849
16686
  if (r.severity === "error") throw new LuaWorkflowBuildError("remind-after-invalid", `"${id2}": ${r.message}`);
15850
16687
  }
16688
+ for (const r of validateHitlTimeoutHours(opts, `approval("${id2}")`)) {
16689
+ throw new LuaWorkflowBuildError("timeout-hours-out-of-range", `"${id2}": ${r.message}`);
16690
+ }
15851
16691
  if (typeof opts.details === "function") throw new LuaWorkflowBuildError("closure-binding", `approval("${id2}").details must be template(...)`);
15852
16692
  this.recordEnvRefs(opts.details, opts.timeoutHours, opts.approver);
15853
16693
  const node = defined({
@@ -15878,6 +16718,10 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
15878
16718
  waitForSignal(id2, opts) {
15879
16719
  this.assertId(id2, "waitForSignal()");
15880
16720
  if (!opts || typeof opts.signal !== "string" || opts.signal.length === 0) throw new LuaWorkflowBuildError("invalid-envelope", `waitForSignal("${id2}") needs a signal name`);
16721
+ if (!WORKFLOW_SIGNAL_NAME_RE.test(opts.signal)) throw new LuaWorkflowBuildError("signal-name-invalid", signalNameInvalidMessage(id2, opts.signal));
16722
+ for (const r of validateHitlTimeoutHours(opts, `waitForSignal("${id2}")`)) {
16723
+ throw new LuaWorkflowBuildError("timeout-hours-out-of-range", `"${id2}": ${r.message}`);
16724
+ }
15881
16725
  this.recordEnvRefs(opts.timeoutHours);
15882
16726
  const node = defined({
15883
16727
  type: "waitForSignal",
@@ -15940,7 +16784,7 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
15940
16784
  if (this.mapCount >= 2 && this.unnamedMaps > 0) {
15941
16785
  this.warnings.push({
15942
16786
  code: "map-id-required",
15943
- message: `${this.unnamedMaps} of ${this.mapCount} map() calls have no explicit id \u2014 positional ids renumber on insert; pass { id } (error at push)`
16787
+ message: `${this.unnamedMaps} of ${this.mapCount} map() calls have no explicit id \u2014 positional ids renumber on insert; pass { id } to every map() to keep step ids stable`
15944
16788
  });
15945
16789
  }
15946
16790
  if (graphHasHitl(graph, this.steps) && this.config.budget?.maxDurationSeconds === void 0) {