@wayai/cli 0.3.131 → 0.3.133

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -441,11 +441,11 @@ function captureException2(error, context) {
441
441
  Sentry.captureException(error);
442
442
  });
443
443
  }
444
- function addApiBreadcrumb(method, path31) {
444
+ function addApiBreadcrumb(method, path30) {
445
445
  if (!initialized) return;
446
446
  Sentry.addBreadcrumb({
447
447
  category: "http",
448
- message: `${method} ${path31}`,
448
+ message: `${method} ${path30}`,
449
449
  level: "info"
450
450
  });
451
451
  }
@@ -899,8 +899,8 @@ var init_parseUtil = __esm({
899
899
  init_errors();
900
900
  init_en();
901
901
  makeIssue = (params) => {
902
- const { data, path: path31, errorMaps, issueData } = params;
903
- const fullPath = [...path31, ...issueData.path || []];
902
+ const { data, path: path30, errorMaps, issueData } = params;
903
+ const fullPath = [...path30, ...issueData.path || []];
904
904
  const fullIssue = {
905
905
  ...issueData,
906
906
  path: fullPath
@@ -1211,11 +1211,11 @@ var init_types = __esm({
1211
1211
  init_parseUtil();
1212
1212
  init_util();
1213
1213
  ParseInputLazyPath = class {
1214
- constructor(parent, value, path31, key) {
1214
+ constructor(parent, value, path30, key) {
1215
1215
  this._cachedPath = [];
1216
1216
  this.parent = parent;
1217
1217
  this.data = value;
1218
- this._path = path31;
1218
+ this._path = path30;
1219
1219
  this._key = key;
1220
1220
  }
1221
1221
  get path() {
@@ -4621,6 +4621,70 @@ function normalizeAuthType(raw) {
4621
4621
  function visibleLength(s) {
4622
4622
  return s.replace(INVISIBLE_NAME_CHARS, "").length;
4623
4623
  }
4624
+ function isEventRelativeFollowupType(type) {
4625
+ return typeof type === "string" && EVENT_RELATIVE_FOLLOWUP_TYPES.includes(type);
4626
+ }
4627
+ function validateFollowupLinks(followups, label, ctx) {
4628
+ const linkTargets = /* @__PURE__ */ new Set();
4629
+ followups.forEach((followup, i) => {
4630
+ const ref = followup?.after_followup_id;
4631
+ const path30 = ["followups", i, "after_followup_id"];
4632
+ if (followup?.type !== "inactivity_after_before_event") {
4633
+ if (ref !== void 0) {
4634
+ ctx.addIssue({
4635
+ code: external_exports.ZodIssueCode.custom,
4636
+ path: path30,
4637
+ message: `kanban status ${label}: after_followup_id is only valid on inactivity_after_before_event followups (this one is ${followup?.type})`
4638
+ });
4639
+ }
4640
+ return;
4641
+ }
4642
+ if (ref === void 0) {
4643
+ ctx.addIssue({
4644
+ code: external_exports.ZodIssueCode.custom,
4645
+ path: path30,
4646
+ message: `kanban status ${label}: inactivity_after_before_event requires after_followup_id naming the id of a before_event followup in the same status`
4647
+ });
4648
+ return;
4649
+ }
4650
+ linkTargets.add(ref);
4651
+ const matches = followups.filter((candidate) => candidate?.id === ref);
4652
+ if (matches.length > 1) {
4653
+ ctx.addIssue({
4654
+ code: external_exports.ZodIssueCode.custom,
4655
+ path: path30,
4656
+ message: `kanban status ${label}: after_followup_id "${ref}" matches ${matches.length} followups \u2014 a link must name exactly one`
4657
+ });
4658
+ return;
4659
+ }
4660
+ const target = matches[0];
4661
+ if (!target) {
4662
+ const hasIdlessBeforeEvent = followups.some(
4663
+ (candidate) => candidate?.type === "before_event" && candidate?.id === void 0
4664
+ );
4665
+ ctx.addIssue({
4666
+ code: external_exports.ZodIssueCode.custom,
4667
+ path: path30,
4668
+ message: hasIdlessBeforeEvent ? `kanban status ${label}: after_followup_id "${ref}" matches no followup \u2014 a link target must declare an explicit id, and this status has before_event followups without one` : `kanban status ${label}: after_followup_id "${ref}" matches no followup in this status`
4669
+ });
4670
+ return;
4671
+ }
4672
+ if (target.type !== "before_event") {
4673
+ ctx.addIssue({
4674
+ code: external_exports.ZodIssueCode.custom,
4675
+ path: path30,
4676
+ message: `kanban status ${label}: after_followup_id "${ref}" points at a ${target.type} followup \u2014 only before_event followups can anchor a chain`
4677
+ });
4678
+ }
4679
+ });
4680
+ if (linkTargets.size > MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS) {
4681
+ ctx.addIssue({
4682
+ code: external_exports.ZodIssueCode.custom,
4683
+ path: ["followups"],
4684
+ message: `kanban status ${label}: at most ${MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS} distinct after_followup_id targets per status (found ${linkTargets.size}) \u2014 each one rebuilds a chain on every inbound message`
4685
+ });
4686
+ }
4687
+ }
4624
4688
  function validateLaneReferences(lanes, statuses) {
4625
4689
  const issues = [];
4626
4690
  if (!Array.isArray(statuses) || statuses.length === 0) return issues;
@@ -4684,12 +4748,12 @@ function typeMatches(typeField, allowed) {
4684
4748
  if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
4685
4749
  return false;
4686
4750
  }
4687
- function validateSchema(schema, path31, errors, opts = {}) {
4751
+ function validateSchema(schema, path30, errors, opts = {}) {
4688
4752
  if (typeof schema === "boolean") return;
4689
4753
  const depth = opts.depth ?? 0;
4690
4754
  if (depth > MAX_SCHEMA_DEPTH) {
4691
4755
  errors.push({
4692
- path: path31 || "<root>",
4756
+ path: path30 || "<root>",
4693
4757
  message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,
4694
4758
  suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
4695
4759
  });
@@ -4697,7 +4761,7 @@ function validateSchema(schema, path31, errors, opts = {}) {
4697
4761
  }
4698
4762
  if (!isRecord(schema)) {
4699
4763
  errors.push({
4700
- path: path31,
4764
+ path: path30,
4701
4765
  message: `expected object, got ${schema === null ? "null" : typeof schema}`
4702
4766
  });
4703
4767
  return;
@@ -4705,14 +4769,14 @@ function validateSchema(schema, path31, errors, opts = {}) {
4705
4769
  if (opts.isRoot) {
4706
4770
  if ("type" in schema && schema.type !== "object") {
4707
4771
  errors.push({
4708
- path: path31 ? `${path31}.type` : "type",
4772
+ path: path30 ? `${path30}.type` : "type",
4709
4773
  message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
4710
4774
  suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
4711
4775
  });
4712
4776
  }
4713
4777
  } else if ("type" in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {
4714
4778
  errors.push({
4715
- path: `${path31}.type`,
4779
+ path: `${path30}.type`,
4716
4780
  message: `type must be one of ${[...ALLOWED_TYPES].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
4717
4781
  });
4718
4782
  }
@@ -4722,25 +4786,25 @@ function validateSchema(schema, path31, errors, opts = {}) {
4722
4786
  const isPlaceholder = PLACEHOLDER_TOKENS.includes(e);
4723
4787
  const isOutcomePlaceholder = e === "[KANBAN_OUTCOME_VALUES]";
4724
4788
  errors.push({
4725
- path: `${path31}.enum`,
4789
+ path: `${path30}.enum`,
4726
4790
  message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
4727
4791
  suggestion: isOutcomePlaceholder ? "Declare `outcomes` on the hub's terminal kanban status so the platform can render the placeholder into a valid array; with none configured the platform drops the parameter instead." : isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
4728
4792
  });
4729
4793
  } else if (!Array.isArray(e)) {
4730
4794
  errors.push({
4731
- path: `${path31}.enum`,
4795
+ path: `${path30}.enum`,
4732
4796
  message: `enum must be a non-empty array of primitives, got ${typeof e}`
4733
4797
  });
4734
4798
  } else if (e.length === 0) {
4735
4799
  errors.push({
4736
- path: `${path31}.enum`,
4800
+ path: `${path30}.enum`,
4737
4801
  message: "enum must not be empty"
4738
4802
  });
4739
4803
  } else {
4740
4804
  for (let i = 0; i < e.length; i++) {
4741
4805
  if (!isPrimitive(e[i])) {
4742
4806
  errors.push({
4743
- path: `${path31}.enum[${i}]`,
4807
+ path: `${path30}.enum[${i}]`,
4744
4808
  message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
4745
4809
  });
4746
4810
  }
@@ -4750,7 +4814,7 @@ function validateSchema(schema, path31, errors, opts = {}) {
4750
4814
  for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
4751
4815
  if (key in schema && typeof schema[key] === "boolean") {
4752
4816
  errors.push({
4753
- path: `${path31}.${key}`,
4817
+ path: `${path30}.${key}`,
4754
4818
  message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
4755
4819
  suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
4756
4820
  });
@@ -4759,45 +4823,45 @@ function validateSchema(schema, path31, errors, opts = {}) {
4759
4823
  if ("properties" in schema) {
4760
4824
  if (!isRecord(schema.properties)) {
4761
4825
  errors.push({
4762
- path: `${path31}.properties`,
4826
+ path: `${path30}.properties`,
4763
4827
  message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
4764
4828
  });
4765
4829
  } else {
4766
4830
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
4767
- validateSchema(propSchema, `${path31}.properties.${propName}`, errors, { depth: depth + 1 });
4831
+ validateSchema(propSchema, `${path30}.properties.${propName}`, errors, { depth: depth + 1 });
4768
4832
  }
4769
4833
  }
4770
4834
  }
4771
4835
  if (schemaTypeIncludes(schema, "array") && "items" in schema) {
4772
4836
  if (Array.isArray(schema.items)) {
4773
- schema.items.forEach((sub, i) => validateSchema(sub, `${path31}.items[${i}]`, errors, { depth: depth + 1 }));
4837
+ schema.items.forEach((sub, i) => validateSchema(sub, `${path30}.items[${i}]`, errors, { depth: depth + 1 }));
4774
4838
  } else {
4775
- validateSchema(schema.items, `${path31}.items`, errors, { depth: depth + 1 });
4839
+ validateSchema(schema.items, `${path30}.items`, errors, { depth: depth + 1 });
4776
4840
  }
4777
4841
  }
4778
4842
  for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
4779
4843
  if (key in schema && isRecord(schema[key])) {
4780
- validateSchema(schema[key], `${path31}.${key}`, errors, { depth: depth + 1 });
4844
+ validateSchema(schema[key], `${path30}.${key}`, errors, { depth: depth + 1 });
4781
4845
  }
4782
4846
  }
4783
4847
  for (const key of SUBSCHEMA_LIST_KEYWORDS) {
4784
4848
  const list = schema[key];
4785
4849
  if (Array.isArray(list)) {
4786
- list.forEach((sub, i) => validateSchema(sub, `${path31}.${key}[${i}]`, errors, { depth: depth + 1 }));
4850
+ list.forEach((sub, i) => validateSchema(sub, `${path30}.${key}[${i}]`, errors, { depth: depth + 1 }));
4787
4851
  }
4788
4852
  }
4789
4853
  for (const key of SUBSCHEMA_MAP_KEYWORDS) {
4790
4854
  const map = schema[key];
4791
4855
  if (isRecord(map)) {
4792
4856
  for (const [name, sub] of Object.entries(map)) {
4793
- validateSchema(sub, `${path31}.${key}.${name}`, errors, { depth: depth + 1 });
4857
+ validateSchema(sub, `${path30}.${key}.${name}`, errors, { depth: depth + 1 });
4794
4858
  }
4795
4859
  }
4796
4860
  }
4797
4861
  const reportedPaths = new Set(errors.map((e) => e.path));
4798
4862
  for (const [k, v] of Object.entries(schema)) {
4799
4863
  if (typeof v !== "string") continue;
4800
- const fieldPath = `${path31}.${k}`;
4864
+ const fieldPath = `${path30}.${k}`;
4801
4865
  if (reportedPaths.has(fieldPath)) continue;
4802
4866
  for (const token of PLACEHOLDER_TOKENS) {
4803
4867
  if (v === token) {
@@ -4942,8 +5006,8 @@ function evalInitialStateError(input) {
4942
5006
  const parsed = evalInitialStateEntry.safeParse(entries[i]);
4943
5007
  if (!parsed.success) {
4944
5008
  const issue = parsed.error.issues[0];
4945
- const path31 = issue?.path.join(".") || "?";
4946
- return `initial_state[${i}].${path31} is invalid: ${issue?.message ?? "malformed"}`;
5009
+ const path30 = issue?.path.join(".") || "?";
5010
+ return `initial_state[${i}].${path30} is invalid: ${issue?.message ?? "malformed"}`;
4947
5011
  }
4948
5012
  if (seenSlugs.has(parsed.data.slug)) {
4949
5013
  return `initial_state[${i}].slug "${parsed.data.slug}" is declared more than once`;
@@ -5131,10 +5195,10 @@ function refineHubAsCodeEvals(config, ctx) {
5131
5195
  function refineHubAsCodeEvalAttachments(config, ctx) {
5132
5196
  const cfg = config;
5133
5197
  const referencedHashes = /* @__PURE__ */ new Set();
5134
- const addTurnIssue = (path31, turn, name) => {
5198
+ const addTurnIssue = (path30, turn, name) => {
5135
5199
  const error = evalTurnAttachmentsError(turn);
5136
5200
  if (error) {
5137
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path31, message: `${name}: ${error}` });
5201
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path30, message: `${name}: ${error}` });
5138
5202
  return;
5139
5203
  }
5140
5204
  for (const hash of collectTurnAttachmentHashes(turn)) referencedHashes.add(hash);
@@ -5280,11 +5344,11 @@ function refineHubAsCodeDelegation(config, ctx) {
5280
5344
  }
5281
5345
  }
5282
5346
  if (del.context_boundary === void 0) return;
5283
- const path31 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
5347
+ const path30 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
5284
5348
  if (del.type !== "hub") {
5285
5349
  ctx.addIssue({
5286
5350
  code: external_exports.ZodIssueCode.custom,
5287
- path: path31,
5351
+ path: path30,
5288
5352
  message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
5289
5353
  });
5290
5354
  return;
@@ -5292,52 +5356,14 @@ function refineHubAsCodeDelegation(config, ctx) {
5292
5356
  if (!CONTEXT_BOUNDARIES.includes(del.context_boundary)) {
5293
5357
  ctx.addIssue({
5294
5358
  code: external_exports.ZodIssueCode.custom,
5295
- path: path31,
5359
+ path: path30,
5296
5360
  message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES.join(", ")}`
5297
5361
  });
5298
5362
  }
5299
5363
  });
5300
5364
  });
5301
5365
  }
5302
- function isSafeTemplatePath(path31) {
5303
- if (path31.length === 0 || path31.length > 300) return false;
5304
- if (path31.startsWith("/") || path31.includes("\\")) return false;
5305
- const segments = path31.split("/");
5306
- return segments.every(
5307
- (seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
5308
- );
5309
- }
5310
- function dropTemplateKeys(value, drop) {
5311
- if (Array.isArray(value)) return value.map((v) => dropTemplateKeys(v, drop));
5312
- if (isPlainObject(value)) {
5313
- const out = {};
5314
- for (const [key, child] of Object.entries(value)) {
5315
- if (drop.has(key)) continue;
5316
- out[key] = TEMPLATE_OPAQUE_BLOB_KEYS.has(key) ? child : dropTemplateKeys(child, drop);
5317
- }
5318
- return out;
5319
- }
5320
- return value;
5321
- }
5322
- function stripTemplateInstanceIds(value) {
5323
- return dropTemplateKeys(value, TEMPLATE_INSTANCE_ID_KEYS);
5324
- }
5325
- function excludeTemplateAuthorData(value) {
5326
- return dropTemplateKeys(value, TEMPLATE_AUTHOR_DATA_KEYS);
5327
- }
5328
- function isPlainObject(value) {
5329
- if (value === null || typeof value !== "object") return false;
5330
- const proto = Object.getPrototypeOf(value);
5331
- return proto === Object.prototype || proto === null;
5332
- }
5333
- function isSanitizableSliceFile(path31) {
5334
- if (!/\.ya?ml$/i.test(path31)) return false;
5335
- return path31 !== "resources" && !path31.startsWith("resources/");
5336
- }
5337
- function distinctUsesBackends(uses) {
5338
- return [...new Set((uses ?? []).map((u) => u.backend))];
5339
- }
5340
- var uuidSchema, paginationSchema, timestampSchema, idParamSchema, clientOptionalString, clientOptionalBoolean, clientOptionalNumber, messageAttachment, MAX_MESSAGE_BODY_BYTES, MAX_ATTACHMENTS_PER_MESSAGE, MAX_AUDIO_FILE_BASE64_BYTES, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, PREVIOUS_CONVERSATIONS_MAX, previousConversationsCountField, summarizationThresholdField, monitorConfigField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_LANES, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupSchema, MAX_OUTCOMES_PER_STATUS, kanbanOutcomeSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, PREVIEW_LABEL_MAX_LENGTH, MAX_ENDED_INDEX_RETENTION_DAYS, previewLabelField, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, updateChannelTestIdentitiesBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, PRODUCTION_DIRECT_FIELDS, setProductionCredentialBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, CONTEXT_BOUNDARIES, contextBoundarySchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, variantAiModeSchema, experimentStatusSchema, overlayUpdateSchema, experimentIdParam, variantIdParam, listExperimentsQuery, listVariantsQuery, listOverridesQuery, deleteOverrideQuery, createExperimentBody, updateExperimentBody, setExperimentStatusBody, createVariantBody, updateVariantBody, upsertOverrideBody, orgTagIdParam, listOrgTagsQuery, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlTable, analyticsSqlSchemaQuery, EVAL_PACING_PRESET_NAMES, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_MAX_RUNS_PER_SCENARIO, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, ISO_UTC_RE, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, evalDateContextSchema, EVAL_FIXTURE_NAME_MAX_LENGTH, evalFixtureOverrideSchema, runSessionQuery, EVAL_INPUT_ROLES, EVAL_INPUT_ROLE_LIST, ROLE_ECHO_MAX, EVAL_INITIAL_STATE_SCOPES, MAX_INITIAL_STATE_ENTRIES, evalInitialStateEntry, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, EVAL_MAX_SELECTED_SCENARIOS, evalScenarioSelectionEntrySchema, evalScenarioSelectionSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, EVAL_ATTACHMENT_HASH_REGEX, evalAttachmentRef, turnMayCarryAttachments, ATTACHMENTS_USER_ONLY_MESSAGE, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, fixtureField, createJourneyBody, updateJourneyBody, evalSessionConfigResponseSchema, evalSessionResponseSchema, seedReleaseStatusSchema, EVAL_SESSION_NOT_QUIESCENT, getConversationsQuery, getMessagesQuery, appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, deleteUserConversationsResponse, sendMessageBody, listConversationsQuery, flagSourceSchema, getConversationsResponse, getConversationDetailParams, getConversationDetailQuery, getConversationDetailResponse, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, copilotSuggestBody, copilotSuggestResponse, CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, MAX_RESOURCE_FILE_SIZE, MAX_10MB_BASE64_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_CARRIERS, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES, MAX_RESOURCE_ENCODED_BYTES, MAX_HUB_AS_CODE_RESOURCES, MAX_HUB_AS_CODE_RESOURCE_FILES, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES, MAX_CI_CONFIG_BODY_BYTES, hubAsCodeStateSchema, hubAsCodeResourceFileSchema, hubAsCodeResourceSchema, uuidPattern, ciUuidSchema, boundedHubAsCodeResourcesSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, CI_APPLY_ENTITY_KINDS, CI_APPLY_OPERATIONS, ciApplyErrorBaseSchema, ciApplyErrorSchema, ciSyncCountSchema, ciSyncChangesSchema, ciSyncWarningSchema, ciSyncResponseSchema, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, adminScopedTargetBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysBody, dataExplorerKvKeyBody, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteBody, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, sandboxEgressPolicy, SANDBOX_EXEC_MAX_CMD_LENGTH, SANDBOX_EXEC_MAX_ALLOWLIST, SANDBOX_EXEC_MAX_TIMEOUT_MS, adminSandboxExecBody, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, passwordLoginBody, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, reportMessageSchema, sentryRefStatusSchema, createReportBody, editReportBody, reporterReportSummarySchema, reporterListResponseSchema, getReportResponseSchema, reporterTransitionResponseSchema, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, discordTier, discordBillingCycle, discordMetadata, discordOAuthStartResponse, discordOAuthFinalizeBody, discordOAuthFinalizeResponse, discordDisconnectResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, templateLocaleSchema, TEMPLATE_SLUG_REGEX, templateSlugSchema, templateStatusSchema, templateFileMapSchema, TEMPLATE_INSTANCE_ID_KEYS, TEMPLATE_OPAQUE_BLOB_KEYS, TEMPLATE_AUTHOR_DATA_KEYS, templateTextSchema, templateUsesEntrySchema, templateUsesSchema, templateYamlLocaleEntry, templateYamlWayaiBlock, templateTagsSchema, templateYamlSchema, templateHeroSchema, templatePushLocaleSchema, templatePushBody, templateListQuery, templateSlugParam, templateDetailQuery, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam;
5366
+ var uuidSchema, paginationSchema, timestampSchema, idParamSchema, clientOptionalString, clientOptionalBoolean, clientOptionalNumber, messageAttachment, MAX_MESSAGE_BODY_BYTES, MAX_ATTACHMENTS_PER_MESSAGE, MAX_AUDIO_FILE_BASE64_BYTES, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, PREVIOUS_CONVERSATIONS_MAX, previousConversationsCountField, summarizationThresholdField, monitorConfigField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_LANES, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupTypeSchema, EVENT_RELATIVE_FOLLOWUP_TYPES, followupTimeUnitSchema, followupIdSchema, SELECTABLE_FOLLOWUP_TYPES, MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS, followupSchema, MAX_OUTCOMES_PER_STATUS, kanbanOutcomeSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, PREVIEW_LABEL_MAX_LENGTH, MAX_ENDED_INDEX_RETENTION_DAYS, previewLabelField, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, updateChannelTestIdentitiesBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, PRODUCTION_DIRECT_FIELDS, setProductionCredentialBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, CONTEXT_BOUNDARIES, contextBoundarySchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, variantAiModeSchema, experimentStatusSchema, overlayUpdateSchema, experimentIdParam, variantIdParam, listExperimentsQuery, listVariantsQuery, listOverridesQuery, deleteOverrideQuery, createExperimentBody, updateExperimentBody, setExperimentStatusBody, createVariantBody, updateVariantBody, upsertOverrideBody, orgTagIdParam, listOrgTagsQuery, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlTable, analyticsSqlSchemaQuery, EVAL_PACING_PRESET_NAMES, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_MAX_RUNS_PER_SCENARIO, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, ISO_UTC_RE, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, evalDateContextSchema, EVAL_FIXTURE_NAME_MAX_LENGTH, evalFixtureOverrideSchema, runSessionQuery, EVAL_INPUT_ROLES, EVAL_INPUT_ROLE_LIST, ROLE_ECHO_MAX, EVAL_INITIAL_STATE_SCOPES, MAX_INITIAL_STATE_ENTRIES, evalInitialStateEntry, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, EVAL_MAX_SELECTED_SCENARIOS, evalScenarioSelectionEntrySchema, evalScenarioSelectionSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, EVAL_ATTACHMENT_HASH_REGEX, evalAttachmentRef, turnMayCarryAttachments, ATTACHMENTS_USER_ONLY_MESSAGE, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, fixtureField, createJourneyBody, updateJourneyBody, evalSessionConfigResponseSchema, evalSessionResponseSchema, seedReleaseStatusSchema, EVAL_SESSION_NOT_QUIESCENT, getConversationsQuery, getMessagesQuery, appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, deleteUserConversationsResponse, sendMessageBody, listConversationsQuery, flagSourceSchema, getConversationsResponse, getConversationDetailParams, getConversationDetailQuery, getConversationDetailResponse, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, copilotSuggestBody, copilotSuggestResponse, CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, MAX_RESOURCE_FILE_SIZE, MAX_10MB_BASE64_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_CARRIERS, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES, MAX_RESOURCE_ENCODED_BYTES, MAX_HUB_AS_CODE_RESOURCES, MAX_HUB_AS_CODE_RESOURCE_FILES, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES, MAX_CI_CONFIG_BODY_BYTES, hubAsCodeStateSchema, hubAsCodeResourceFileSchema, hubAsCodeResourceSchema, uuidPattern, ciUuidSchema, boundedHubAsCodeResourcesSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, CI_APPLY_ENTITY_KINDS, CI_APPLY_OPERATIONS, ciApplyErrorBaseSchema, ciApplyErrorSchema, ciSyncCountSchema, ciSyncChangesSchema, ciSyncWarningSchema, ciSyncResponseSchema, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, adminScopedTargetBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysBody, dataExplorerKvKeyBody, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteBody, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, sandboxEgressPolicy, SANDBOX_EXEC_MAX_CMD_LENGTH, SANDBOX_EXEC_MAX_ALLOWLIST, SANDBOX_EXEC_MAX_TIMEOUT_MS, adminSandboxExecBody, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, passwordLoginBody, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, reportMessageSchema, sentryRefStatusSchema, createReportBody, editReportBody, reporterReportSummarySchema, reporterListResponseSchema, getReportResponseSchema, reporterTransitionResponseSchema, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam;
5341
5367
  var init_contracts = __esm({
5342
5368
  "../../packages/core/dist/contracts/index.js"() {
5343
5369
  "use strict";
@@ -5389,8 +5415,6 @@ var init_contracts = __esm({
5389
5415
  init_zod();
5390
5416
  init_zod();
5391
5417
  init_zod();
5392
- init_zod();
5393
- init_zod();
5394
5418
  uuidSchema = external_exports.string().uuid();
5395
5419
  paginationSchema = external_exports.object({
5396
5420
  limit: external_exports.coerce.number().int().min(1).max(100).default(50),
@@ -5587,12 +5611,28 @@ var init_contracts = __esm({
5587
5611
  MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES = 16384;
5588
5612
  RESERVED_TEMPLATE_DUMP_NAME = "additional_data";
5589
5613
  kanbanStatusSlugSchema = slugSchema;
5614
+ followupTypeSchema = external_exports.enum([
5615
+ "inactivity",
5616
+ "before_event",
5617
+ "inactivity_after_event",
5618
+ "inactivity_after_before_event"
5619
+ ]);
5620
+ EVENT_RELATIVE_FOLLOWUP_TYPES = [
5621
+ "before_event",
5622
+ "inactivity_after_event",
5623
+ "inactivity_after_before_event"
5624
+ ];
5625
+ followupTimeUnitSchema = external_exports.enum(["seconds", "minutes", "hours", "days"]);
5626
+ followupIdSchema = external_exports.string().min(1, "must not be empty").refine((v) => v === v.trim(), "must not have leading or trailing whitespace");
5627
+ SELECTABLE_FOLLOWUP_TYPES = followupTypeSchema.options;
5628
+ MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS = 5;
5590
5629
  followupSchema = external_exports.object({
5591
- id: external_exports.string().optional(),
5630
+ /** Optional author-supplied identifier; also the `after_followup_id` link target. */
5631
+ id: followupIdSchema.optional(),
5592
5632
  order: external_exports.number().int().nonnegative(),
5593
- type: external_exports.enum(["inactivity", "before_event"]),
5633
+ type: followupTypeSchema,
5594
5634
  threshold: external_exports.number().int().positive(),
5595
- timeUnit: external_exports.enum(["seconds", "minutes", "hours", "days"]),
5635
+ timeUnit: followupTimeUnitSchema,
5596
5636
  instructions: external_exports.string().optional(),
5597
5637
  excludedWeekDays: external_exports.array(external_exports.number().int().min(0).max(6)).optional(),
5598
5638
  excludeHolidays: external_exports.boolean().optional(),
@@ -5602,7 +5642,15 @@ var init_contracts = __esm({
5602
5642
  direct_text: external_exports.string().optional(),
5603
5643
  template_whatsapp_id: external_exports.string().nullable().optional(),
5604
5644
  outside_window_policy: external_exports.enum(["route_to_team", "skip"]).optional(),
5605
- include_tools: external_exports.boolean().optional()
5645
+ include_tools: external_exports.boolean().optional(),
5646
+ /**
5647
+ * The `before_event` followup whose fire anchors this chain — its `id`, in
5648
+ * the same status. One name, one meaning, contract and schedule column
5649
+ * alike: "the followup whose fire anchors this chain". Required on
5650
+ * `inactivity_after_before_event`, forbidden on every other type; both are
5651
+ * enforced per status, where the sibling followups are visible.
5652
+ */
5653
+ after_followup_id: followupIdSchema.optional()
5606
5654
  }).passthrough().superRefine((followup, ctx) => {
5607
5655
  if (followup.delivery_mode === "direct" && !followup.direct_text?.trim()) {
5608
5656
  ctx.addIssue({
@@ -5691,12 +5739,20 @@ var init_contracts = __esm({
5691
5739
  message: `kanban status ${label}: event_due_delay_minutes requires isSchedulingStatus=true`
5692
5740
  });
5693
5741
  }
5694
- if (Array.isArray(status.followups) && status.followups.some((f) => f?.type === "before_event") && status.isSchedulingStatus !== true) {
5695
- ctx.addIssue({
5696
- code: external_exports.ZodIssueCode.custom,
5697
- path: ["followups"],
5698
- message: `kanban status ${label}: before_event followups require isSchedulingStatus=true on the parent status`
5699
- });
5742
+ if (Array.isArray(status.followups) && status.isSchedulingStatus !== true) {
5743
+ const offending = status.followups.find(
5744
+ (f) => isEventRelativeFollowupType(f?.type)
5745
+ );
5746
+ if (offending) {
5747
+ ctx.addIssue({
5748
+ code: external_exports.ZodIssueCode.custom,
5749
+ path: ["followups"],
5750
+ message: `kanban status ${label}: ${offending.type} followups require isSchedulingStatus=true on the parent status`
5751
+ });
5752
+ }
5753
+ }
5754
+ if (Array.isArray(status.followups)) {
5755
+ validateFollowupLinks(status.followups, label, ctx);
5700
5756
  }
5701
5757
  if (status.additional_context_schema && typeof status.additional_context_schema === "object") {
5702
5758
  const schema = status.additional_context_schema;
@@ -6370,8 +6426,9 @@ var init_contracts = __esm({
6370
6426
  file_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
6371
6427
  skill_name: external_exports.string().optional(),
6372
6428
  skill_version: external_exports.string().optional(),
6373
- anthropic_skill_id: external_exports.string().optional(),
6374
- anthropic_version: external_exports.string().optional(),
6429
+ // No `anthropic_skill_id`/`anthropic_version`: `resource` has neither column.
6430
+ // The provider link lives on `resource_provider_sync.provider_skill_id`,
6431
+ // written by `skillSync.ts` — never through this body.
6375
6432
  user_browsable: external_exports.boolean().optional()
6376
6433
  });
6377
6434
  syncSkillsBody = external_exports.object({
@@ -7506,7 +7563,6 @@ var init_contracts = __esm({
7506
7563
  phone: external_exports.string().optional(),
7507
7564
  email: external_exports.string().email().optional(),
7508
7565
  instagram_sid: external_exports.string().optional(),
7509
- hub_user_id: external_exports.string().uuid().optional(),
7510
7566
  tags: external_exports.array(external_exports.string()).default([]),
7511
7567
  metadata: external_exports.record(external_exports.unknown()).default({}),
7512
7568
  enabled: external_exports.boolean().default(true)
@@ -7519,7 +7575,6 @@ var init_contracts = __esm({
7519
7575
  phone: external_exports.string().nullable().optional(),
7520
7576
  email: external_exports.string().email().nullable().optional(),
7521
7577
  instagram_sid: external_exports.string().nullable().optional(),
7522
- hub_user_id: external_exports.string().uuid().nullable().optional(),
7523
7578
  tags: external_exports.array(external_exports.string()).optional(),
7524
7579
  metadata: external_exports.record(external_exports.unknown()).optional(),
7525
7580
  enabled: external_exports.boolean().optional()
@@ -8428,35 +8483,6 @@ var init_contracts = __esm({
8428
8483
  role: external_exports.enum(["org_admin", "admin", "team_user", "user"]),
8429
8484
  expires_at: external_exports.string().datetime()
8430
8485
  });
8431
- discordTier = external_exports.enum(["free", "pro", "pro_plus"]);
8432
- discordBillingCycle = external_exports.enum(["monthly", "annual"]);
8433
- discordMetadata = external_exports.object({
8434
- tier: discordTier,
8435
- billing_cycle: discordBillingCycle,
8436
- is_admin: external_exports.boolean()
8437
- });
8438
- discordOAuthStartResponse = external_exports.object({
8439
- url: external_exports.string().url()
8440
- });
8441
- discordOAuthFinalizeBody = external_exports.object({
8442
- code: external_exports.string().min(1, "code is required"),
8443
- state: external_exports.string().min(1, "state is required")
8444
- });
8445
- discordOAuthFinalizeResponse = external_exports.discriminatedUnion("ok", [
8446
- external_exports.object({
8447
- ok: external_exports.literal(true),
8448
- discord_user_id: external_exports.string(),
8449
- metadata: discordMetadata
8450
- }),
8451
- external_exports.object({
8452
- ok: external_exports.literal(false),
8453
- push_error: external_exports.literal("discord_unreachable"),
8454
- metadata: discordMetadata
8455
- })
8456
- ]);
8457
- discordDisconnectResponse = external_exports.object({
8458
- ok: external_exports.literal(true)
8459
- });
8460
8486
  jsonSchemaSchema = external_exports.record(external_exports.unknown());
8461
8487
  hubUserIdentity = external_exports.object({
8462
8488
  user_id: external_exports.string().nullable(),
@@ -8566,135 +8592,6 @@ var init_contracts = __esm({
8566
8592
  offset: external_exports.coerce.number().int().min(0).optional()
8567
8593
  });
8568
8594
  noticeIdParamSchema = external_exports.object({ id: external_exports.string().min(1) });
8569
- templateLocaleSchema = external_exports.enum(SUPPORTED_LOCALES);
8570
- TEMPLATE_SLUG_REGEX = /^[a-z0-9][a-z0-9-]{0,62}$/;
8571
- templateSlugSchema = external_exports.string().regex(TEMPLATE_SLUG_REGEX, "slug must be lowercase alphanumeric with hyphens (max 63)");
8572
- templateStatusSchema = external_exports.enum(["published", "draft", "internal"]);
8573
- templateFileMapSchema = external_exports.record(external_exports.string()).refine((m) => Object.keys(m).every(isSafeTemplatePath), {
8574
- message: 'file map contains an unsafe path (no absolute paths, "..", or backslashes)'
8575
- });
8576
- TEMPLATE_INSTANCE_ID_KEYS = /* @__PURE__ */ new Set([
8577
- // Top-level hub instance metadata (hub.yaml) — set by `wayai pull`, never authored.
8578
- "hub_id",
8579
- "hub_environment",
8580
- "preview_label",
8581
- "branch_name",
8582
- // Per-entity row id + cross-entity reference UUIDs (each has a portable name twin).
8583
- "id",
8584
- "connection_id",
8585
- "target_id",
8586
- "agent_id",
8587
- "resource_id",
8588
- "list_id",
8589
- // Account-scoped Meta WhatsApp template id (name twin: `template_whatsapp`).
8590
- "template_whatsapp_id"
8591
- ]);
8592
- TEMPLATE_OPAQUE_BLOB_KEYS = /* @__PURE__ */ new Set([
8593
- "settings",
8594
- // agent + connection connector settings
8595
- "schema_json",
8596
- // agent response_format JSON Schema
8597
- "json_schema",
8598
- // state JSON Schema
8599
- "initial_value",
8600
- // state seed value
8601
- "additional_context_schema",
8602
- // kanban-status transition-form schema
8603
- "config",
8604
- // custom-tool OpenAI function schema
8605
- "headers",
8606
- "query_params",
8607
- "body_params",
8608
- // custom-tool HTTP shaping
8609
- "mappings",
8610
- // composed-tool argument mappings
8611
- "input",
8612
- "expected",
8613
- "history",
8614
- // eval message fixtures (tool_calls carry their own `id`)
8615
- "transcript",
8616
- "step_config"
8617
- // journey fixtures (transcript carries `step_id`; step_config is keyed by it)
8618
- ]);
8619
- TEMPLATE_AUTHOR_DATA_KEYS = /* @__PURE__ */ new Set([
8620
- // Outbound campaign subsystem (hub.yaml top-level). `outbound_contacts` is the
8621
- // author's real leads — `phone`/`email`/`instagram_sid` + the required `name` are
8622
- // GDPR-grade PII. `outbound_lists` group those contacts by real name. `outbound_schedules`
8623
- // bind to the (now-absent) lists and carry the author's campaign cadence + message
8624
- // copy — operationally tied to the author's customers; a consumer builds their own.
8625
- "outbound_contacts",
8626
- "outbound_lists",
8627
- "outbound_schedules",
8628
- // Account-scoped channel identifier on a connection (Twilio SID / WhatsApp number /
8629
- // IG username / from-email, per connector). The connection stays as portable
8630
- // structure re-bound by name on push; this author-account value carries no blueprint
8631
- // value. A dedicated top-level column — never nested in the `settings` opaque blob.
8632
- "account_sid"
8633
- ]);
8634
- templateTextSchema = external_exports.object({
8635
- metaTitle: external_exports.string().min(1).max(200),
8636
- metaDescription: external_exports.string().max(1e3).default("")
8637
- });
8638
- templateUsesEntrySchema = external_exports.object({
8639
- backend: templateSlugSchema,
8640
- endpoint: templateSlugSchema
8641
- });
8642
- templateUsesSchema = external_exports.array(templateUsesEntrySchema).max(24).default([]);
8643
- templateYamlLocaleEntry = templateTextSchema.extend({ source: external_exports.string().min(1) });
8644
- templateYamlWayaiBlock = external_exports.object({
8645
- installCommand: external_exports.string().min(1).max(300),
8646
- locales: external_exports.record(templateLocaleSchema, templateYamlLocaleEntry)
8647
- });
8648
- templateTagsSchema = external_exports.array(external_exports.string().min(1).max(30)).max(12).default([]).transform((tags) => [...new Set(tags.map((t) => t.trim().toLowerCase()).filter(Boolean))]);
8649
- templateYamlSchema = external_exports.object({
8650
- slug: templateSlugSchema,
8651
- category: external_exports.string().min(1).max(60),
8652
- tags: templateTagsSchema,
8653
- status: templateStatusSchema.default("draft"),
8654
- order: external_exports.number().int().min(0).max(1e5).optional(),
8655
- defaultLocale: templateLocaleSchema,
8656
- hero: external_exports.string().optional(),
8657
- // relative path to a hero image inside the template folder
8658
- // The Rekor backend(s) this channel runs on (gh #2955). Locale-agnostic. The
8659
- // cross-link + MCP endpoint are derived from each entry's slugs, never authored.
8660
- uses: templateUsesSchema,
8661
- // A WayAI template IS a WayAI channel — the wayai slice is required. (The old
8662
- // Rekor-only store entry is gone: a pure Rekor backend lives only in Rekor's store.)
8663
- wayai: templateYamlWayaiBlock
8664
- }).refine((c) => Boolean(c.wayai.locales[c.defaultLocale]), {
8665
- message: "`wayai.locales` must include the defaultLocale"
8666
- });
8667
- templateHeroSchema = external_exports.object({
8668
- filename: external_exports.string().min(1).max(200).regex(/\.(png|jpe?g|webp|gif)$/i, "hero must be a raster image (png/jpg/webp/gif)"),
8669
- dataBase64: external_exports.string().min(1).max(8e6)
8670
- });
8671
- templatePushLocaleSchema = external_exports.object({
8672
- wayai: templateTextSchema.optional(),
8673
- readmeMarkdown: external_exports.string().default(""),
8674
- wayaiFiles: templateFileMapSchema.optional()
8675
- });
8676
- templatePushBody = external_exports.object({
8677
- slug: templateSlugSchema,
8678
- defaultLocale: templateLocaleSchema,
8679
- common: external_exports.object({
8680
- category: external_exports.string().min(1).max(60),
8681
- tags: templateTagsSchema,
8682
- status: templateStatusSchema,
8683
- order: external_exports.number().int().min(0).max(1e5).default(0),
8684
- // The WayAI install command (a WayAI template always has a wayai side). Kept
8685
- // optional on the wire so a malformed manifest 400s on the field, not the body.
8686
- installCommand: external_exports.string().min(1).max(300).optional(),
8687
- hero: templateHeroSchema.optional(),
8688
- // The channel→backend edge (gh #2955), locale-agnostic.
8689
- uses: templateUsesSchema
8690
- }),
8691
- locales: external_exports.record(templateLocaleSchema, templatePushLocaleSchema)
8692
- }).refine((b) => Boolean(b.locales[b.defaultLocale]), {
8693
- message: "`locales` must include the defaultLocale"
8694
- });
8695
- templateListQuery = external_exports.object({ locale: templateLocaleSchema.optional() });
8696
- templateSlugParam = external_exports.object({ slug: templateSlugSchema });
8697
- templateDetailQuery = external_exports.object({ locale: templateLocaleSchema.optional() });
8698
8595
  ADMIN_SKILL_NAME_REGEX = /^[a-z0-9][a-z0-9-]{0,63}$/;
8699
8596
  adminSkillNameParam = external_exports.object({
8700
8597
  name: external_exports.string().regex(ADMIN_SKILL_NAME_REGEX, "invalid skill name")
@@ -8724,13 +8621,13 @@ var init_api_client = __esm({
8724
8621
  init_sentry();
8725
8622
  init_mask_secrets();
8726
8623
  RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
8727
- delay = (ms) => new Promise((resolve6) => setTimeout(resolve6, ms));
8624
+ delay = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
8728
8625
  ApiError = class extends Error {
8729
8626
  status;
8730
8627
  body;
8731
- constructor(method, path31, status, body) {
8628
+ constructor(method, path30, status, body) {
8732
8629
  const safeBody = maskSecretsInMessage(body);
8733
- super(`API request failed: ${method} ${path31} (${status}): ${safeBody}`);
8630
+ super(`API request failed: ${method} ${path30} (${status}): ${safeBody}`);
8734
8631
  this.name = "ApiError";
8735
8632
  this.status = status;
8736
8633
  this.body = safeBody;
@@ -8787,25 +8684,6 @@ var init_api_client = __esm({
8787
8684
  commit_sha: commitSha
8788
8685
  });
8789
8686
  }
8790
- // --- Templates gallery ---
8791
- // Consumer (any authed user): list the joint template set + pull the wayai slice.
8792
- // `locale` is optional — the server resolves to each template's defaultLocale when
8793
- // omitted, and falls back to it (with a resolvedLocale signal) when unauthored.
8794
- async templateList(locale) {
8795
- const qs = locale ? `?${new URLSearchParams({ locale })}` : "";
8796
- return this.request("GET", `/api/ci/templates${qs}`);
8797
- }
8798
- async templatePull(slug, locale) {
8799
- const qs = locale ? `?${new URLSearchParams({ locale })}` : "";
8800
- return this.request("GET", `/api/ci/templates/${encodeURIComponent(slug)}${qs}`);
8801
- }
8802
- // Author (platform-admin): push a template into the store / pull it for inspection.
8803
- async adminTemplatePush(body) {
8804
- return this.request("POST", "/api/admin/templates/push", body);
8805
- }
8806
- async adminTemplatePull(slug) {
8807
- return this.request("GET", `/api/admin/templates/${encodeURIComponent(slug)}`);
8808
- }
8809
8687
  // Download a private operator skill (platform-admin gated) for local install.
8810
8688
  async adminSkillInstall(name) {
8811
8689
  return this.request("GET", `/api/admin/skills/${encodeURIComponent(name)}`);
@@ -8848,8 +8726,8 @@ var init_api_client = __esm({
8848
8726
  ...opts?.check && { check: true }
8849
8727
  });
8850
8728
  }
8851
- async lookup(path31, opts) {
8852
- const params = new URLSearchParams({ path: path31 });
8729
+ async lookup(path30, opts) {
8730
+ const params = new URLSearchParams({ path: path30 });
8853
8731
  if (opts?.organizationId) params.set("organization_id", opts.organizationId);
8854
8732
  return this.request("GET", `/api/ci/lookup?${params.toString()}`);
8855
8733
  }
@@ -9270,9 +9148,9 @@ var init_api_client = __esm({
9270
9148
  * sandbox for this conversation, or the blob was purged).
9271
9149
  */
9272
9150
  async downloadArchiveSandboxFs(hubId, conversationId) {
9273
- const path31 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
9274
- addApiBreadcrumb("GET", path31);
9275
- const url = `${this.apiUrl}${path31}`;
9151
+ const path30 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
9152
+ addApiBreadcrumb("GET", path30);
9153
+ const url = `${this.apiUrl}${path30}`;
9276
9154
  let response = await this.send(url, "GET");
9277
9155
  if (response.status === 401 && this.onUnauthorized) {
9278
9156
  let refreshed;
@@ -9286,7 +9164,7 @@ var init_api_client = __esm({
9286
9164
  }
9287
9165
  }
9288
9166
  if (!response.ok) {
9289
- throw new ApiError("GET", path31, response.status, await response.text());
9167
+ throw new ApiError("GET", path30, response.status, await response.text());
9290
9168
  }
9291
9169
  return new Uint8Array(await response.arrayBuffer());
9292
9170
  }
@@ -9326,9 +9204,9 @@ var init_api_client = __esm({
9326
9204
  `/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
9327
9205
  );
9328
9206
  }
9329
- async request(method, path31, body) {
9330
- addApiBreadcrumb(method, path31);
9331
- const url = `${this.apiUrl}${path31}`;
9207
+ async request(method, path30, body) {
9208
+ addApiBreadcrumb(method, path30);
9209
+ const url = `${this.apiUrl}${path30}`;
9332
9210
  let refreshedOn401 = false;
9333
9211
  for (let retry = 0; ; retry++) {
9334
9212
  let response = await this.send(url, method, body);
@@ -9352,7 +9230,7 @@ var init_api_client = __esm({
9352
9230
  await delay(RETRYABLE_BACKOFF_MS[retry]);
9353
9231
  continue;
9354
9232
  }
9355
- throw new ApiError(method, path31, response.status, errorBody);
9233
+ throw new ApiError(method, path30, response.status, errorBody);
9356
9234
  }
9357
9235
  }
9358
9236
  /** Issue a single authenticated request with the client's current token. */
@@ -9464,6 +9342,70 @@ function withinJsonLength2(value, max) {
9464
9342
  function visibleLength2(s) {
9465
9343
  return s.replace(INVISIBLE_NAME_CHARS2, "").length;
9466
9344
  }
9345
+ function isEventRelativeFollowupType2(type) {
9346
+ return typeof type === "string" && EVENT_RELATIVE_FOLLOWUP_TYPES2.includes(type);
9347
+ }
9348
+ function validateFollowupLinks2(followups, label, ctx) {
9349
+ const linkTargets = /* @__PURE__ */ new Set();
9350
+ followups.forEach((followup, i) => {
9351
+ const ref = followup?.after_followup_id;
9352
+ const path30 = ["followups", i, "after_followup_id"];
9353
+ if (followup?.type !== "inactivity_after_before_event") {
9354
+ if (ref !== void 0) {
9355
+ ctx.addIssue({
9356
+ code: external_exports.ZodIssueCode.custom,
9357
+ path: path30,
9358
+ message: `kanban status ${label}: after_followup_id is only valid on inactivity_after_before_event followups (this one is ${followup?.type})`
9359
+ });
9360
+ }
9361
+ return;
9362
+ }
9363
+ if (ref === void 0) {
9364
+ ctx.addIssue({
9365
+ code: external_exports.ZodIssueCode.custom,
9366
+ path: path30,
9367
+ message: `kanban status ${label}: inactivity_after_before_event requires after_followup_id naming the id of a before_event followup in the same status`
9368
+ });
9369
+ return;
9370
+ }
9371
+ linkTargets.add(ref);
9372
+ const matches = followups.filter((candidate) => candidate?.id === ref);
9373
+ if (matches.length > 1) {
9374
+ ctx.addIssue({
9375
+ code: external_exports.ZodIssueCode.custom,
9376
+ path: path30,
9377
+ message: `kanban status ${label}: after_followup_id "${ref}" matches ${matches.length} followups \u2014 a link must name exactly one`
9378
+ });
9379
+ return;
9380
+ }
9381
+ const target = matches[0];
9382
+ if (!target) {
9383
+ const hasIdlessBeforeEvent = followups.some(
9384
+ (candidate) => candidate?.type === "before_event" && candidate?.id === void 0
9385
+ );
9386
+ ctx.addIssue({
9387
+ code: external_exports.ZodIssueCode.custom,
9388
+ path: path30,
9389
+ message: hasIdlessBeforeEvent ? `kanban status ${label}: after_followup_id "${ref}" matches no followup \u2014 a link target must declare an explicit id, and this status has before_event followups without one` : `kanban status ${label}: after_followup_id "${ref}" matches no followup in this status`
9390
+ });
9391
+ return;
9392
+ }
9393
+ if (target.type !== "before_event") {
9394
+ ctx.addIssue({
9395
+ code: external_exports.ZodIssueCode.custom,
9396
+ path: path30,
9397
+ message: `kanban status ${label}: after_followup_id "${ref}" points at a ${target.type} followup \u2014 only before_event followups can anchor a chain`
9398
+ });
9399
+ }
9400
+ });
9401
+ if (linkTargets.size > MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS2) {
9402
+ ctx.addIssue({
9403
+ code: external_exports.ZodIssueCode.custom,
9404
+ path: ["followups"],
9405
+ message: `kanban status ${label}: at most ${MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS2} distinct after_followup_id targets per status (found ${linkTargets.size}) \u2014 each one rebuilds a chain on every inbound message`
9406
+ });
9407
+ }
9408
+ }
9467
9409
  function validateLaneReferences2(lanes, statuses) {
9468
9410
  const issues = [];
9469
9411
  if (!Array.isArray(statuses) || statuses.length === 0) return issues;
@@ -9527,12 +9469,12 @@ function typeMatches2(typeField, allowed) {
9527
9469
  if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
9528
9470
  return false;
9529
9471
  }
9530
- function validateSchema2(schema, path31, errors, opts = {}) {
9472
+ function validateSchema2(schema, path30, errors, opts = {}) {
9531
9473
  if (typeof schema === "boolean") return;
9532
9474
  const depth = opts.depth ?? 0;
9533
9475
  if (depth > MAX_SCHEMA_DEPTH2) {
9534
9476
  errors.push({
9535
- path: path31 || "<root>",
9477
+ path: path30 || "<root>",
9536
9478
  message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
9537
9479
  suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
9538
9480
  });
@@ -9540,7 +9482,7 @@ function validateSchema2(schema, path31, errors, opts = {}) {
9540
9482
  }
9541
9483
  if (!isRecord2(schema)) {
9542
9484
  errors.push({
9543
- path: path31,
9485
+ path: path30,
9544
9486
  message: `expected object, got ${schema === null ? "null" : typeof schema}`
9545
9487
  });
9546
9488
  return;
@@ -9548,14 +9490,14 @@ function validateSchema2(schema, path31, errors, opts = {}) {
9548
9490
  if (opts.isRoot) {
9549
9491
  if ("type" in schema && schema.type !== "object") {
9550
9492
  errors.push({
9551
- path: path31 ? `${path31}.type` : "type",
9493
+ path: path30 ? `${path30}.type` : "type",
9552
9494
  message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
9553
9495
  suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
9554
9496
  });
9555
9497
  }
9556
9498
  } else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
9557
9499
  errors.push({
9558
- path: `${path31}.type`,
9500
+ path: `${path30}.type`,
9559
9501
  message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
9560
9502
  });
9561
9503
  }
@@ -9565,25 +9507,25 @@ function validateSchema2(schema, path31, errors, opts = {}) {
9565
9507
  const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
9566
9508
  const isOutcomePlaceholder = e === "[KANBAN_OUTCOME_VALUES]";
9567
9509
  errors.push({
9568
- path: `${path31}.enum`,
9510
+ path: `${path30}.enum`,
9569
9511
  message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
9570
9512
  suggestion: isOutcomePlaceholder ? "Declare `outcomes` on the hub's terminal kanban status so the platform can render the placeholder into a valid array; with none configured the platform drops the parameter instead." : isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
9571
9513
  });
9572
9514
  } else if (!Array.isArray(e)) {
9573
9515
  errors.push({
9574
- path: `${path31}.enum`,
9516
+ path: `${path30}.enum`,
9575
9517
  message: `enum must be a non-empty array of primitives, got ${typeof e}`
9576
9518
  });
9577
9519
  } else if (e.length === 0) {
9578
9520
  errors.push({
9579
- path: `${path31}.enum`,
9521
+ path: `${path30}.enum`,
9580
9522
  message: "enum must not be empty"
9581
9523
  });
9582
9524
  } else {
9583
9525
  for (let i = 0; i < e.length; i++) {
9584
9526
  if (!isPrimitive2(e[i])) {
9585
9527
  errors.push({
9586
- path: `${path31}.enum[${i}]`,
9528
+ path: `${path30}.enum[${i}]`,
9587
9529
  message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
9588
9530
  });
9589
9531
  }
@@ -9593,7 +9535,7 @@ function validateSchema2(schema, path31, errors, opts = {}) {
9593
9535
  for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
9594
9536
  if (key in schema && typeof schema[key] === "boolean") {
9595
9537
  errors.push({
9596
- path: `${path31}.${key}`,
9538
+ path: `${path30}.${key}`,
9597
9539
  message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
9598
9540
  suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
9599
9541
  });
@@ -9602,45 +9544,45 @@ function validateSchema2(schema, path31, errors, opts = {}) {
9602
9544
  if ("properties" in schema) {
9603
9545
  if (!isRecord2(schema.properties)) {
9604
9546
  errors.push({
9605
- path: `${path31}.properties`,
9547
+ path: `${path30}.properties`,
9606
9548
  message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
9607
9549
  });
9608
9550
  } else {
9609
9551
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
9610
- validateSchema2(propSchema, `${path31}.properties.${propName}`, errors, { depth: depth + 1 });
9552
+ validateSchema2(propSchema, `${path30}.properties.${propName}`, errors, { depth: depth + 1 });
9611
9553
  }
9612
9554
  }
9613
9555
  }
9614
9556
  if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
9615
9557
  if (Array.isArray(schema.items)) {
9616
- schema.items.forEach((sub, i) => validateSchema2(sub, `${path31}.items[${i}]`, errors, { depth: depth + 1 }));
9558
+ schema.items.forEach((sub, i) => validateSchema2(sub, `${path30}.items[${i}]`, errors, { depth: depth + 1 }));
9617
9559
  } else {
9618
- validateSchema2(schema.items, `${path31}.items`, errors, { depth: depth + 1 });
9560
+ validateSchema2(schema.items, `${path30}.items`, errors, { depth: depth + 1 });
9619
9561
  }
9620
9562
  }
9621
9563
  for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
9622
9564
  if (key in schema && isRecord2(schema[key])) {
9623
- validateSchema2(schema[key], `${path31}.${key}`, errors, { depth: depth + 1 });
9565
+ validateSchema2(schema[key], `${path30}.${key}`, errors, { depth: depth + 1 });
9624
9566
  }
9625
9567
  }
9626
9568
  for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
9627
9569
  const list = schema[key];
9628
9570
  if (Array.isArray(list)) {
9629
- list.forEach((sub, i) => validateSchema2(sub, `${path31}.${key}[${i}]`, errors, { depth: depth + 1 }));
9571
+ list.forEach((sub, i) => validateSchema2(sub, `${path30}.${key}[${i}]`, errors, { depth: depth + 1 }));
9630
9572
  }
9631
9573
  }
9632
9574
  for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
9633
9575
  const map = schema[key];
9634
9576
  if (isRecord2(map)) {
9635
9577
  for (const [name, sub] of Object.entries(map)) {
9636
- validateSchema2(sub, `${path31}.${key}.${name}`, errors, { depth: depth + 1 });
9578
+ validateSchema2(sub, `${path30}.${key}.${name}`, errors, { depth: depth + 1 });
9637
9579
  }
9638
9580
  }
9639
9581
  }
9640
9582
  const reportedPaths = new Set(errors.map((e) => e.path));
9641
9583
  for (const [k, v] of Object.entries(schema)) {
9642
9584
  if (typeof v !== "string") continue;
9643
- const fieldPath = `${path31}.${k}`;
9585
+ const fieldPath = `${path30}.${k}`;
9644
9586
  if (reportedPaths.has(fieldPath)) continue;
9645
9587
  for (const token of PLACEHOLDER_TOKENS2) {
9646
9588
  if (v === token) {
@@ -9785,8 +9727,8 @@ function evalInitialStateError2(input) {
9785
9727
  const parsed = evalInitialStateEntry2.safeParse(entries[i]);
9786
9728
  if (!parsed.success) {
9787
9729
  const issue = parsed.error.issues[0];
9788
- const path31 = issue?.path.join(".") || "?";
9789
- return `initial_state[${i}].${path31} is invalid: ${issue?.message ?? "malformed"}`;
9730
+ const path30 = issue?.path.join(".") || "?";
9731
+ return `initial_state[${i}].${path30} is invalid: ${issue?.message ?? "malformed"}`;
9790
9732
  }
9791
9733
  if (seenSlugs.has(parsed.data.slug)) {
9792
9734
  return `initial_state[${i}].slug "${parsed.data.slug}" is declared more than once`;
@@ -9991,10 +9933,10 @@ function refineHubAsCodeEvals2(config, ctx) {
9991
9933
  function refineHubAsCodeEvalAttachments2(config, ctx) {
9992
9934
  const cfg = config;
9993
9935
  const referencedHashes = /* @__PURE__ */ new Set();
9994
- const addTurnIssue = (path31, turn, name) => {
9936
+ const addTurnIssue = (path30, turn, name) => {
9995
9937
  const error = evalTurnAttachmentsError2(turn);
9996
9938
  if (error) {
9997
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path31, message: `${name}: ${error}` });
9939
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path30, message: `${name}: ${error}` });
9998
9940
  return;
9999
9941
  }
10000
9942
  for (const hash of collectTurnAttachmentHashes2(turn)) referencedHashes.add(hash);
@@ -10140,11 +10082,11 @@ function refineHubAsCodeDelegation2(config, ctx) {
10140
10082
  }
10141
10083
  }
10142
10084
  if (del.context_boundary === void 0) return;
10143
- const path31 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
10085
+ const path30 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
10144
10086
  if (del.type !== "hub") {
10145
10087
  ctx.addIssue({
10146
10088
  code: external_exports.ZodIssueCode.custom,
10147
- path: path31,
10089
+ path: path30,
10148
10090
  message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
10149
10091
  });
10150
10092
  return;
@@ -10152,21 +10094,13 @@ function refineHubAsCodeDelegation2(config, ctx) {
10152
10094
  if (!CONTEXT_BOUNDARIES2.includes(del.context_boundary)) {
10153
10095
  ctx.addIssue({
10154
10096
  code: external_exports.ZodIssueCode.custom,
10155
- path: path31,
10097
+ path: path30,
10156
10098
  message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES2.join(", ")}`
10157
10099
  });
10158
10100
  }
10159
10101
  });
10160
10102
  });
10161
10103
  }
10162
- function isSafeTemplatePath2(path31) {
10163
- if (path31.length === 0 || path31.length > 300) return false;
10164
- if (path31.startsWith("/") || path31.includes("\\")) return false;
10165
- const segments = path31.split("/");
10166
- return segments.every(
10167
- (seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
10168
- );
10169
- }
10170
10104
  function identifyTokenType(token) {
10171
10105
  if (token.startsWith("way_")) return "way_token";
10172
10106
  if (token.startsWith("eyJ")) return "jwt";
@@ -10206,7 +10140,7 @@ function findStepBoundaries(transcript) {
10206
10140
  }
10207
10141
  return out;
10208
10142
  }
10209
- var UUID_RE, HEX_RE, WORKOS_ID_RE, OPAQUE_SECRET_RE, BASE64_SECRET_RE, BASE64_MARKER_RE, TOKEN_RE, SENSITIVE_FIELDS, SENSITIVE_KEY_ALTERNATION, SENSITIVE_KEY_PATTERN, JSON_CREDENTIAL_RE, QUERY_CREDENTIAL_RE, REDACTED, PROVIDER_TOKEN_RE, APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_CONTENT_BRAND, LlmProviderContentError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE2, ORG_CREDENTIAL_AUTH_TYPES2, AUTH_TYPE_DISPLAY2, LEGACY_AUTH_TYPE_MAP2, VALID_AUTH_TYPES2, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, clientOptionalString2, clientOptionalBoolean2, clientOptionalNumber2, messageAttachment2, MAX_MESSAGE_BODY_BYTES2, MAX_ATTACHMENTS_PER_MESSAGE2, MAX_AUDIO_FILE_BASE64_BYTES2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, PREVIOUS_CONVERSATIONS_MAX2, previousConversationsCountField2, summarizationThresholdField2, monitorConfigField2, agentIdParam2, listAgentsQuery2, agentConnectionsQuery2, createAgentBody2, updateAgentBody2, AGENT_PARAMETER_TYPES2, AGENT_PARAMETER_NAME_REGEX2, agentParameterCreateSchema2, MAX_AGENT_PARAMETERS_PER_REQUEST2, createAgentParametersBody2, SLUG_REGEX2, slugSchema2, INVISIBLE_NAME_CHARS2, MAX_KANBAN_STATUSES2, MAX_FOLLOWUPS_PER_STATUS2, MAX_LANES2, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2, RESERVED_TEMPLATE_DUMP_NAME2, kanbanStatusSlugSchema2, followupSchema2, MAX_OUTCOMES_PER_STATUS2, kanbanOutcomeSchema2, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, PREVIEW_LABEL_MAX_LENGTH2, MAX_ENDED_INDEX_RETENTION_DAYS2, previewLabelField2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, updateChannelTestIdentitiesBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, PRODUCTION_DIRECT_FIELDS2, setProductionCredentialBody2, registerWhatsappQuery2, registerWhatsappBody2, retryProvisioningQuery2, resendDomainStatusQuery2, PLACEHOLDER_TOKENS2, ALLOWED_TYPES2, SUBSCHEMA_OBJECT_KEYWORDS2, SUBSCHEMA_LIST_KEYWORDS2, SUBSCHEMA_MAP_KEYWORDS2, MAX_SCHEMA_DEPTH2, toolIdParam2, listToolsQuery2, toolAgentQuery2, deleteToolQuery2, toolConnectionsQuery2, nativeToolIdSchema2, CONTEXT_BOUNDARIES2, contextBoundarySchema2, addNativeToolBody2, addMcpToolBody2, createCustomToolBody2, updateCustomToolBody2, updateToolExecutionConfigBody2, initialValueCreateSchema2, initialValueUpdateSchema2, stateIdParam2, listStatesQuery2, stateNameSchema2, createStateBody2, updateStateBody2, reorderStatesBody2, variantAiModeSchema2, experimentStatusSchema2, overlayUpdateSchema2, experimentIdParam2, variantIdParam2, listExperimentsQuery2, listVariantsQuery2, listOverridesQuery2, deleteOverrideQuery2, createExperimentBody2, updateExperimentBody2, setExperimentStatusBody2, createVariantBody2, updateVariantBody2, upsertOverrideBody2, orgTagIdParam2, listOrgTagsQuery2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, orgResourceIdParam2, orgResourceFileIdParam2, orgResourceFolderIdParam2, hubOrgResourceParam2, listOrgResourcesQuery2, orgIdQuery2, createOrgResourceBody2, updateOrgResourceBody2, createOrgResourceFolderBody2, updateOrgResourceFolderBody2, uploadOrgResourceFileBody2, updateOrgResourceFileBody2, uploadOrgSkillZipBody2, linkOrgResourceBody2, resourceIdParam2, listResourcesQuery2, createResourceBody2, updateResourceBody2, syncSkillsBody2, resourceFileIdParam2, listResourceFilesQuery2, createResourceFileBody2, updateResourceFileBody2, uploadResourceFileBody2, uploadSkillZipBody2, resourceFolderIdParam2, listResourceFoldersQuery2, createResourceFolderBody2, updateResourceFolderBody2, agentResourceQuery2, hubResourceQuery2, linkAgentResourceBody2, updateAgentResourceBody2, unlinkAgentResourceQuery2, navItemSchema2, hubCountResetBody2, navItemCountResetBody2, typingBody2, analyticsHubIdParam2, analyticsVariableIdParam2, updateVariablePinBody2, updateAnalyticsViewBody2, NUMERIC_FILTER_OPS2, TEXT_FILTER_OPS2, CATEGORICAL_FILTER_OPS2, VARIABLE_FILTER_OPS2, STRUCTURED_QUERY_OPS2, STRUCTURED_QUERY_AGGREGATIONS2, filterValueSchema2, conversationsBody2, analyticsConversationIdParam2, messagesQuery2, conversationDetailDataQuery2, analyticsDataBody2, structuredQueryBody2, analyticsSqlBody2, analyticsSqlTable2, analyticsSqlSchemaQuery2, EVAL_PACING_PRESET_NAMES2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_MAX_RUNS_PER_SCENARIO2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, ISO_UTC_RE2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, evalDateContextSchema2, EVAL_FIXTURE_NAME_MAX_LENGTH2, evalFixtureOverrideSchema2, runSessionQuery2, EVAL_INPUT_ROLES2, EVAL_INPUT_ROLE_LIST2, ROLE_ECHO_MAX2, EVAL_INITIAL_STATE_SCOPES2, MAX_INITIAL_STATE_ENTRIES2, evalInitialStateEntry2, createEvalBody2, updateEvalBody2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, EVAL_MAX_SELECTED_SCENARIOS2, evalScenarioSelectionEntrySchema2, evalScenarioSelectionSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, EVAL_ATTACHMENT_HASH_REGEX2, evalAttachmentRef2, turnMayCarryAttachments2, ATTACHMENTS_USER_ONLY_MESSAGE2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, fixtureField2, createJourneyBody2, updateJourneyBody2, evalSessionConfigResponseSchema2, evalSessionResponseSchema2, seedReleaseStatusSchema2, getConversationsQuery2, getMessagesQuery2, appMessageSenderType2, appMessageReceiverType2, apiChannelMessage2, apiChannelMessageBody2, appMessageBody2, appMessageResponse2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, deleteUserConversationsResponse2, sendMessageBody2, listConversationsQuery2, flagSourceSchema2, getConversationsResponse2, getConversationDetailParams2, getConversationDetailQuery2, getConversationDetailResponse2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, copilotSuggestBody2, copilotSuggestResponse2, CONSULT_THREAD_STATUSES2, consultThreadStatus2, CONSULT_THREAD_TITLE_MAX2, consultThreadTitle2, consultThreadSummary2, listConsultThreadsQuery2, listConsultThreadsResponse2, createConsultThreadBody2, createConsultThreadResponse2, consultThreadIdParam2, updateConsultThreadBody2, updateConsultThreadResponse2, CONSULT_AWAIT_TIMEOUT_MS2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, downloadBody2, uploadQuery2, signUrlBody2, outboundSchemaQuery2, templateIdParam2, listTemplatesQuery2, deleteTemplateQuery2, templateStatusQuery2, createTemplateBody2, updateTemplateBody2, submitTemplateBody2, testTemplateBody2, contactIdParam2, listContactsQuery2, createContactBody2, updateContactBody2, listIdParam2, listListsQuery2, listListContactsQuery2, createListBody2, updateListBody2, addListContactsBody2, removeListContactsBody2, scheduleIdParam2, listSchedulesQuery2, listExecutionsQuery2, createScheduleBody2, updateScheduleBody2, MAX_RESOURCE_FILE_SIZE2, MAX_10MB_BASE64_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_CARRIERS2, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2, MAX_RESOURCE_ENCODED_BYTES2, MAX_HUB_AS_CODE_RESOURCES2, MAX_HUB_AS_CODE_RESOURCE_FILES2, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES2, MAX_CI_CONFIG_BODY_BYTES2, hubAsCodeStateSchema2, hubAsCodeResourceFileSchema2, hubAsCodeResourceSchema2, uuidPattern2, ciUuidSchema2, boundedHubAsCodeResourcesSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, CI_APPLY_ENTITY_KINDS2, CI_APPLY_OPERATIONS2, ciApplyErrorBaseSchema2, ciApplyErrorSchema2, ciSyncCountSchema2, ciSyncChangesSchema2, ciSyncWarningSchema2, ciSyncResponseSchema2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminScopedTargetBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysBody2, dataExplorerKvKeyBody2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteBody2, pitrDoNamespace2, pitrBookmarkParam2, pitrRestoreBody2, healthSamplingTriggerBody2, dataExplorerDebugDoType2, DEBUG_READ_MAX_LIMIT2, DEBUG_READ_DEFAULT_LIMIT2, DEBUG_DO_HEX_PREFIX2, debugDoEntityId2, debugTableName2, dataExplorerDebugTablesParam2, dataExplorerDebugRowsParam2, dataExplorerDebugRowsQuery2, dataExplorerDebugAnalyticsTable2, debugUuid2, dataExplorerDebugAnalyticsRowsParam2, dataExplorerDebugAnalyticsRowsQuery2, debugHubConvParam2, debugMessageIdQuery2, sandboxEgressPolicy2, SANDBOX_EXEC_MAX_CMD_LENGTH2, SANDBOX_EXEC_MAX_ALLOWLIST2, SANDBOX_EXEC_MAX_TIMEOUT_MS2, adminSandboxExecBody2, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, passwordLoginBody2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, reportMessageSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, reporterReportSummarySchema2, reporterListResponseSchema2, getReportResponseSchema2, reporterTransitionResponseSchema2, contestReportBody2, reporterListQuery2, listReportsQuery2, GITHUB_ISSUE_URL_REGEX2, githubIssueUrlSchema2, transitionReportBody2, groupReportsBody2, holdReportBody2, clickhouseReadyResponse2, bootstrapQuery2, requestSnapshotChunkMessage2, MAX_NAME_LENGTH3, MAX_VALUE_LENGTH2, MAX_TAGS2, MAX_TAG_LENGTH2, MAX_SCOPE_HUBS2, MAX_SCOPE_TAGS2, vaultSecretScopeSchema2, vaultCreateBody2, vaultUpdateBody2, PERMISSIONS2, MAX_NAME_LENGTH22, MAX_HUBS_PER_GRANT2, MAX_HUB_TAGS_PER_GRANT2, MAX_GRANTS2, permissionEnum2, grantScopeSchema2, grantSchema2, createTokenBody2, tokenOrgIdParam2, tokenGrantScopeSchema2, tokenGrantSchema2, tokenMetadataSchema2, listTokensResponse2, createTokenResponse2, orgTokenSummarySchema2, listOrgTokensResponse2, invitePreviewQuery2, invitePreviewResponse2, discordTier2, discordBillingCycle2, discordMetadata2, discordOAuthStartResponse2, discordOAuthFinalizeBody2, discordOAuthFinalizeResponse2, discordDisconnectResponse2, jsonSchemaSchema2, hubUserIdentity2, stateValueEntry2, getHubUserContextResponse2, updateHubUserBody2, updateHubUserResponse2, unlockHubUserNameResponse2, stateResetParams2, stateResetResponse2, hubAlertsParam2, hubAlertSeverity2, hubAlert2, hubAlertsListResponse2, noticeSeveritySchema2, noticeStatusSchema2, NOTICE_SCOPE_REGEX2, noticeScopeSchema2, noticeLinkSchema2, createNoticeBody2, updateNoticeBody2, listNoticesQuery2, noticeIdParamSchema2, templateLocaleSchema2, TEMPLATE_SLUG_REGEX2, templateSlugSchema2, templateStatusSchema2, templateFileMapSchema2, templateTextSchema2, templateUsesEntrySchema2, templateUsesSchema2, templateYamlLocaleEntry2, templateYamlWayaiBlock2, templateTagsSchema2, templateYamlSchema2, templateHeroSchema2, templatePushLocaleSchema2, templatePushBody2, templateListQuery2, templateSlugParam2, templateDetailQuery2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2, WAYAI_WORKSPACE_LAYOUT;
10143
+ var UUID_RE, HEX_RE, WORKOS_ID_RE, OPAQUE_SECRET_RE, BASE64_SECRET_RE, BASE64_MARKER_RE, TOKEN_RE, SENSITIVE_FIELDS, SENSITIVE_KEY_ALTERNATION, SENSITIVE_KEY_PATTERN, JSON_CREDENTIAL_RE, QUERY_CREDENTIAL_RE, REDACTED, PROVIDER_TOKEN_RE, APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_CONTENT_BRAND, LlmProviderContentError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE2, ORG_CREDENTIAL_AUTH_TYPES2, AUTH_TYPE_DISPLAY2, LEGACY_AUTH_TYPE_MAP2, VALID_AUTH_TYPES2, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, clientOptionalString2, clientOptionalBoolean2, clientOptionalNumber2, messageAttachment2, MAX_MESSAGE_BODY_BYTES2, MAX_ATTACHMENTS_PER_MESSAGE2, MAX_AUDIO_FILE_BASE64_BYTES2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, PREVIOUS_CONVERSATIONS_MAX2, previousConversationsCountField2, summarizationThresholdField2, monitorConfigField2, agentIdParam2, listAgentsQuery2, agentConnectionsQuery2, createAgentBody2, updateAgentBody2, AGENT_PARAMETER_TYPES2, AGENT_PARAMETER_NAME_REGEX2, agentParameterCreateSchema2, MAX_AGENT_PARAMETERS_PER_REQUEST2, createAgentParametersBody2, SLUG_REGEX2, slugSchema2, INVISIBLE_NAME_CHARS2, MAX_KANBAN_STATUSES2, MAX_FOLLOWUPS_PER_STATUS2, MAX_LANES2, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2, RESERVED_TEMPLATE_DUMP_NAME2, kanbanStatusSlugSchema2, followupTypeSchema2, EVENT_RELATIVE_FOLLOWUP_TYPES2, followupTimeUnitSchema2, followupIdSchema2, SELECTABLE_FOLLOWUP_TYPES2, MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS2, followupSchema2, MAX_OUTCOMES_PER_STATUS2, kanbanOutcomeSchema2, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, PREVIEW_LABEL_MAX_LENGTH2, MAX_ENDED_INDEX_RETENTION_DAYS2, previewLabelField2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, updateChannelTestIdentitiesBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, PRODUCTION_DIRECT_FIELDS2, setProductionCredentialBody2, registerWhatsappQuery2, registerWhatsappBody2, retryProvisioningQuery2, resendDomainStatusQuery2, PLACEHOLDER_TOKENS2, ALLOWED_TYPES2, SUBSCHEMA_OBJECT_KEYWORDS2, SUBSCHEMA_LIST_KEYWORDS2, SUBSCHEMA_MAP_KEYWORDS2, MAX_SCHEMA_DEPTH2, toolIdParam2, listToolsQuery2, toolAgentQuery2, deleteToolQuery2, toolConnectionsQuery2, nativeToolIdSchema2, CONTEXT_BOUNDARIES2, contextBoundarySchema2, addNativeToolBody2, addMcpToolBody2, createCustomToolBody2, updateCustomToolBody2, updateToolExecutionConfigBody2, initialValueCreateSchema2, initialValueUpdateSchema2, stateIdParam2, listStatesQuery2, stateNameSchema2, createStateBody2, updateStateBody2, reorderStatesBody2, variantAiModeSchema2, experimentStatusSchema2, overlayUpdateSchema2, experimentIdParam2, variantIdParam2, listExperimentsQuery2, listVariantsQuery2, listOverridesQuery2, deleteOverrideQuery2, createExperimentBody2, updateExperimentBody2, setExperimentStatusBody2, createVariantBody2, updateVariantBody2, upsertOverrideBody2, orgTagIdParam2, listOrgTagsQuery2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, orgResourceIdParam2, orgResourceFileIdParam2, orgResourceFolderIdParam2, hubOrgResourceParam2, listOrgResourcesQuery2, orgIdQuery2, createOrgResourceBody2, updateOrgResourceBody2, createOrgResourceFolderBody2, updateOrgResourceFolderBody2, uploadOrgResourceFileBody2, updateOrgResourceFileBody2, uploadOrgSkillZipBody2, linkOrgResourceBody2, resourceIdParam2, listResourcesQuery2, createResourceBody2, updateResourceBody2, syncSkillsBody2, resourceFileIdParam2, listResourceFilesQuery2, createResourceFileBody2, updateResourceFileBody2, uploadResourceFileBody2, uploadSkillZipBody2, resourceFolderIdParam2, listResourceFoldersQuery2, createResourceFolderBody2, updateResourceFolderBody2, agentResourceQuery2, hubResourceQuery2, linkAgentResourceBody2, updateAgentResourceBody2, unlinkAgentResourceQuery2, navItemSchema2, hubCountResetBody2, navItemCountResetBody2, typingBody2, analyticsHubIdParam2, analyticsVariableIdParam2, updateVariablePinBody2, updateAnalyticsViewBody2, NUMERIC_FILTER_OPS2, TEXT_FILTER_OPS2, CATEGORICAL_FILTER_OPS2, VARIABLE_FILTER_OPS2, STRUCTURED_QUERY_OPS2, STRUCTURED_QUERY_AGGREGATIONS2, filterValueSchema2, conversationsBody2, analyticsConversationIdParam2, messagesQuery2, conversationDetailDataQuery2, analyticsDataBody2, structuredQueryBody2, analyticsSqlBody2, analyticsSqlTable2, analyticsSqlSchemaQuery2, EVAL_PACING_PRESET_NAMES2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_MAX_RUNS_PER_SCENARIO2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, ISO_UTC_RE2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, evalDateContextSchema2, EVAL_FIXTURE_NAME_MAX_LENGTH2, evalFixtureOverrideSchema2, runSessionQuery2, EVAL_INPUT_ROLES2, EVAL_INPUT_ROLE_LIST2, ROLE_ECHO_MAX2, EVAL_INITIAL_STATE_SCOPES2, MAX_INITIAL_STATE_ENTRIES2, evalInitialStateEntry2, createEvalBody2, updateEvalBody2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, EVAL_MAX_SELECTED_SCENARIOS2, evalScenarioSelectionEntrySchema2, evalScenarioSelectionSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, EVAL_ATTACHMENT_HASH_REGEX2, evalAttachmentRef2, turnMayCarryAttachments2, ATTACHMENTS_USER_ONLY_MESSAGE2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, fixtureField2, createJourneyBody2, updateJourneyBody2, evalSessionConfigResponseSchema2, evalSessionResponseSchema2, seedReleaseStatusSchema2, getConversationsQuery2, getMessagesQuery2, appMessageSenderType2, appMessageReceiverType2, apiChannelMessage2, apiChannelMessageBody2, appMessageBody2, appMessageResponse2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, deleteUserConversationsResponse2, sendMessageBody2, listConversationsQuery2, flagSourceSchema2, getConversationsResponse2, getConversationDetailParams2, getConversationDetailQuery2, getConversationDetailResponse2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, copilotSuggestBody2, copilotSuggestResponse2, CONSULT_THREAD_STATUSES2, consultThreadStatus2, CONSULT_THREAD_TITLE_MAX2, consultThreadTitle2, consultThreadSummary2, listConsultThreadsQuery2, listConsultThreadsResponse2, createConsultThreadBody2, createConsultThreadResponse2, consultThreadIdParam2, updateConsultThreadBody2, updateConsultThreadResponse2, CONSULT_AWAIT_TIMEOUT_MS2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, downloadBody2, uploadQuery2, signUrlBody2, outboundSchemaQuery2, templateIdParam2, listTemplatesQuery2, deleteTemplateQuery2, templateStatusQuery2, createTemplateBody2, updateTemplateBody2, submitTemplateBody2, testTemplateBody2, contactIdParam2, listContactsQuery2, createContactBody2, updateContactBody2, listIdParam2, listListsQuery2, listListContactsQuery2, createListBody2, updateListBody2, addListContactsBody2, removeListContactsBody2, scheduleIdParam2, listSchedulesQuery2, listExecutionsQuery2, createScheduleBody2, updateScheduleBody2, MAX_RESOURCE_FILE_SIZE2, MAX_10MB_BASE64_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_CARRIERS2, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2, MAX_RESOURCE_ENCODED_BYTES2, MAX_HUB_AS_CODE_RESOURCES2, MAX_HUB_AS_CODE_RESOURCE_FILES2, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES2, MAX_CI_CONFIG_BODY_BYTES2, hubAsCodeStateSchema2, hubAsCodeResourceFileSchema2, hubAsCodeResourceSchema2, uuidPattern2, ciUuidSchema2, boundedHubAsCodeResourcesSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, CI_APPLY_ENTITY_KINDS2, CI_APPLY_OPERATIONS2, ciApplyErrorBaseSchema2, ciApplyErrorSchema2, ciSyncCountSchema2, ciSyncChangesSchema2, ciSyncWarningSchema2, ciSyncResponseSchema2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminScopedTargetBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysBody2, dataExplorerKvKeyBody2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteBody2, pitrDoNamespace2, pitrBookmarkParam2, pitrRestoreBody2, healthSamplingTriggerBody2, dataExplorerDebugDoType2, DEBUG_READ_MAX_LIMIT2, DEBUG_READ_DEFAULT_LIMIT2, DEBUG_DO_HEX_PREFIX2, debugDoEntityId2, debugTableName2, dataExplorerDebugTablesParam2, dataExplorerDebugRowsParam2, dataExplorerDebugRowsQuery2, dataExplorerDebugAnalyticsTable2, debugUuid2, dataExplorerDebugAnalyticsRowsParam2, dataExplorerDebugAnalyticsRowsQuery2, debugHubConvParam2, debugMessageIdQuery2, sandboxEgressPolicy2, SANDBOX_EXEC_MAX_CMD_LENGTH2, SANDBOX_EXEC_MAX_ALLOWLIST2, SANDBOX_EXEC_MAX_TIMEOUT_MS2, adminSandboxExecBody2, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, passwordLoginBody2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, reportMessageSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, reporterReportSummarySchema2, reporterListResponseSchema2, getReportResponseSchema2, reporterTransitionResponseSchema2, contestReportBody2, reporterListQuery2, listReportsQuery2, GITHUB_ISSUE_URL_REGEX2, githubIssueUrlSchema2, transitionReportBody2, groupReportsBody2, holdReportBody2, clickhouseReadyResponse2, bootstrapQuery2, requestSnapshotChunkMessage2, MAX_NAME_LENGTH3, MAX_VALUE_LENGTH2, MAX_TAGS2, MAX_TAG_LENGTH2, MAX_SCOPE_HUBS2, MAX_SCOPE_TAGS2, vaultSecretScopeSchema2, vaultCreateBody2, vaultUpdateBody2, PERMISSIONS2, MAX_NAME_LENGTH22, MAX_HUBS_PER_GRANT2, MAX_HUB_TAGS_PER_GRANT2, MAX_GRANTS2, permissionEnum2, grantScopeSchema2, grantSchema2, createTokenBody2, tokenOrgIdParam2, tokenGrantScopeSchema2, tokenGrantSchema2, tokenMetadataSchema2, listTokensResponse2, createTokenResponse2, orgTokenSummarySchema2, listOrgTokensResponse2, invitePreviewQuery2, invitePreviewResponse2, jsonSchemaSchema2, hubUserIdentity2, stateValueEntry2, getHubUserContextResponse2, updateHubUserBody2, updateHubUserResponse2, unlockHubUserNameResponse2, stateResetParams2, stateResetResponse2, hubAlertsParam2, hubAlertSeverity2, hubAlert2, hubAlertsListResponse2, noticeSeveritySchema2, noticeStatusSchema2, NOTICE_SCOPE_REGEX2, noticeScopeSchema2, noticeLinkSchema2, createNoticeBody2, updateNoticeBody2, listNoticesQuery2, noticeIdParamSchema2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2, WAYAI_WORKSPACE_LAYOUT;
10210
10144
  var init_dist = __esm({
10211
10145
  "../../packages/core/dist/index.js"() {
10212
10146
  "use strict";
@@ -10258,8 +10192,6 @@ var init_dist = __esm({
10258
10192
  init_zod();
10259
10193
  init_zod();
10260
10194
  init_zod();
10261
- init_zod();
10262
- init_zod();
10263
10195
  UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
10264
10196
  HEX_RE = /^[0-9a-f]{16,}$/;
10265
10197
  WORKOS_ID_RE = /^(?:user|org)_[0-9A-HJKMNP-TV-Z]{26}$/;
@@ -10613,12 +10545,28 @@ var init_dist = __esm({
10613
10545
  MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2 = 16384;
10614
10546
  RESERVED_TEMPLATE_DUMP_NAME2 = "additional_data";
10615
10547
  kanbanStatusSlugSchema2 = slugSchema2;
10548
+ followupTypeSchema2 = external_exports.enum([
10549
+ "inactivity",
10550
+ "before_event",
10551
+ "inactivity_after_event",
10552
+ "inactivity_after_before_event"
10553
+ ]);
10554
+ EVENT_RELATIVE_FOLLOWUP_TYPES2 = [
10555
+ "before_event",
10556
+ "inactivity_after_event",
10557
+ "inactivity_after_before_event"
10558
+ ];
10559
+ followupTimeUnitSchema2 = external_exports.enum(["seconds", "minutes", "hours", "days"]);
10560
+ followupIdSchema2 = external_exports.string().min(1, "must not be empty").refine((v) => v === v.trim(), "must not have leading or trailing whitespace");
10561
+ SELECTABLE_FOLLOWUP_TYPES2 = followupTypeSchema2.options;
10562
+ MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS2 = 5;
10616
10563
  followupSchema2 = external_exports.object({
10617
- id: external_exports.string().optional(),
10564
+ /** Optional author-supplied identifier; also the `after_followup_id` link target. */
10565
+ id: followupIdSchema2.optional(),
10618
10566
  order: external_exports.number().int().nonnegative(),
10619
- type: external_exports.enum(["inactivity", "before_event"]),
10567
+ type: followupTypeSchema2,
10620
10568
  threshold: external_exports.number().int().positive(),
10621
- timeUnit: external_exports.enum(["seconds", "minutes", "hours", "days"]),
10569
+ timeUnit: followupTimeUnitSchema2,
10622
10570
  instructions: external_exports.string().optional(),
10623
10571
  excludedWeekDays: external_exports.array(external_exports.number().int().min(0).max(6)).optional(),
10624
10572
  excludeHolidays: external_exports.boolean().optional(),
@@ -10628,7 +10576,15 @@ var init_dist = __esm({
10628
10576
  direct_text: external_exports.string().optional(),
10629
10577
  template_whatsapp_id: external_exports.string().nullable().optional(),
10630
10578
  outside_window_policy: external_exports.enum(["route_to_team", "skip"]).optional(),
10631
- include_tools: external_exports.boolean().optional()
10579
+ include_tools: external_exports.boolean().optional(),
10580
+ /**
10581
+ * The `before_event` followup whose fire anchors this chain — its `id`, in
10582
+ * the same status. One name, one meaning, contract and schedule column
10583
+ * alike: "the followup whose fire anchors this chain". Required on
10584
+ * `inactivity_after_before_event`, forbidden on every other type; both are
10585
+ * enforced per status, where the sibling followups are visible.
10586
+ */
10587
+ after_followup_id: followupIdSchema2.optional()
10632
10588
  }).passthrough().superRefine((followup, ctx) => {
10633
10589
  if (followup.delivery_mode === "direct" && !followup.direct_text?.trim()) {
10634
10590
  ctx.addIssue({
@@ -10717,12 +10673,20 @@ var init_dist = __esm({
10717
10673
  message: `kanban status ${label}: event_due_delay_minutes requires isSchedulingStatus=true`
10718
10674
  });
10719
10675
  }
10720
- if (Array.isArray(status.followups) && status.followups.some((f) => f?.type === "before_event") && status.isSchedulingStatus !== true) {
10721
- ctx.addIssue({
10722
- code: external_exports.ZodIssueCode.custom,
10723
- path: ["followups"],
10724
- message: `kanban status ${label}: before_event followups require isSchedulingStatus=true on the parent status`
10725
- });
10676
+ if (Array.isArray(status.followups) && status.isSchedulingStatus !== true) {
10677
+ const offending = status.followups.find(
10678
+ (f) => isEventRelativeFollowupType2(f?.type)
10679
+ );
10680
+ if (offending) {
10681
+ ctx.addIssue({
10682
+ code: external_exports.ZodIssueCode.custom,
10683
+ path: ["followups"],
10684
+ message: `kanban status ${label}: ${offending.type} followups require isSchedulingStatus=true on the parent status`
10685
+ });
10686
+ }
10687
+ }
10688
+ if (Array.isArray(status.followups)) {
10689
+ validateFollowupLinks2(status.followups, label, ctx);
10726
10690
  }
10727
10691
  if (status.additional_context_schema && typeof status.additional_context_schema === "object") {
10728
10692
  const schema = status.additional_context_schema;
@@ -11396,8 +11360,9 @@ var init_dist = __esm({
11396
11360
  file_metadata_schema: external_exports.record(external_exports.unknown()).optional(),
11397
11361
  skill_name: external_exports.string().optional(),
11398
11362
  skill_version: external_exports.string().optional(),
11399
- anthropic_skill_id: external_exports.string().optional(),
11400
- anthropic_version: external_exports.string().optional(),
11363
+ // No `anthropic_skill_id`/`anthropic_version`: `resource` has neither column.
11364
+ // The provider link lives on `resource_provider_sync.provider_skill_id`,
11365
+ // written by `skillSync.ts` — never through this body.
11401
11366
  user_browsable: external_exports.boolean().optional()
11402
11367
  });
11403
11368
  syncSkillsBody2 = external_exports.object({
@@ -12531,7 +12496,6 @@ var init_dist = __esm({
12531
12496
  phone: external_exports.string().optional(),
12532
12497
  email: external_exports.string().email().optional(),
12533
12498
  instagram_sid: external_exports.string().optional(),
12534
- hub_user_id: external_exports.string().uuid().optional(),
12535
12499
  tags: external_exports.array(external_exports.string()).default([]),
12536
12500
  metadata: external_exports.record(external_exports.unknown()).default({}),
12537
12501
  enabled: external_exports.boolean().default(true)
@@ -12544,7 +12508,6 @@ var init_dist = __esm({
12544
12508
  phone: external_exports.string().nullable().optional(),
12545
12509
  email: external_exports.string().email().nullable().optional(),
12546
12510
  instagram_sid: external_exports.string().nullable().optional(),
12547
- hub_user_id: external_exports.string().uuid().nullable().optional(),
12548
12511
  tags: external_exports.array(external_exports.string()).optional(),
12549
12512
  metadata: external_exports.record(external_exports.unknown()).optional(),
12550
12513
  enabled: external_exports.boolean().optional()
@@ -13453,35 +13416,6 @@ var init_dist = __esm({
13453
13416
  role: external_exports.enum(["org_admin", "admin", "team_user", "user"]),
13454
13417
  expires_at: external_exports.string().datetime()
13455
13418
  });
13456
- discordTier2 = external_exports.enum(["free", "pro", "pro_plus"]);
13457
- discordBillingCycle2 = external_exports.enum(["monthly", "annual"]);
13458
- discordMetadata2 = external_exports.object({
13459
- tier: discordTier2,
13460
- billing_cycle: discordBillingCycle2,
13461
- is_admin: external_exports.boolean()
13462
- });
13463
- discordOAuthStartResponse2 = external_exports.object({
13464
- url: external_exports.string().url()
13465
- });
13466
- discordOAuthFinalizeBody2 = external_exports.object({
13467
- code: external_exports.string().min(1, "code is required"),
13468
- state: external_exports.string().min(1, "state is required")
13469
- });
13470
- discordOAuthFinalizeResponse2 = external_exports.discriminatedUnion("ok", [
13471
- external_exports.object({
13472
- ok: external_exports.literal(true),
13473
- discord_user_id: external_exports.string(),
13474
- metadata: discordMetadata2
13475
- }),
13476
- external_exports.object({
13477
- ok: external_exports.literal(false),
13478
- push_error: external_exports.literal("discord_unreachable"),
13479
- metadata: discordMetadata2
13480
- })
13481
- ]);
13482
- discordDisconnectResponse2 = external_exports.object({
13483
- ok: external_exports.literal(true)
13484
- });
13485
13419
  jsonSchemaSchema2 = external_exports.record(external_exports.unknown());
13486
13420
  hubUserIdentity2 = external_exports.object({
13487
13421
  user_id: external_exports.string().nullable(),
@@ -13591,77 +13525,6 @@ var init_dist = __esm({
13591
13525
  offset: external_exports.coerce.number().int().min(0).optional()
13592
13526
  });
13593
13527
  noticeIdParamSchema2 = external_exports.object({ id: external_exports.string().min(1) });
13594
- templateLocaleSchema2 = external_exports.enum(SUPPORTED_LOCALES2);
13595
- TEMPLATE_SLUG_REGEX2 = /^[a-z0-9][a-z0-9-]{0,62}$/;
13596
- templateSlugSchema2 = external_exports.string().regex(TEMPLATE_SLUG_REGEX2, "slug must be lowercase alphanumeric with hyphens (max 63)");
13597
- templateStatusSchema2 = external_exports.enum(["published", "draft", "internal"]);
13598
- templateFileMapSchema2 = external_exports.record(external_exports.string()).refine((m) => Object.keys(m).every(isSafeTemplatePath2), {
13599
- message: 'file map contains an unsafe path (no absolute paths, "..", or backslashes)'
13600
- });
13601
- templateTextSchema2 = external_exports.object({
13602
- metaTitle: external_exports.string().min(1).max(200),
13603
- metaDescription: external_exports.string().max(1e3).default("")
13604
- });
13605
- templateUsesEntrySchema2 = external_exports.object({
13606
- backend: templateSlugSchema2,
13607
- endpoint: templateSlugSchema2
13608
- });
13609
- templateUsesSchema2 = external_exports.array(templateUsesEntrySchema2).max(24).default([]);
13610
- templateYamlLocaleEntry2 = templateTextSchema2.extend({ source: external_exports.string().min(1) });
13611
- templateYamlWayaiBlock2 = external_exports.object({
13612
- installCommand: external_exports.string().min(1).max(300),
13613
- locales: external_exports.record(templateLocaleSchema2, templateYamlLocaleEntry2)
13614
- });
13615
- templateTagsSchema2 = external_exports.array(external_exports.string().min(1).max(30)).max(12).default([]).transform((tags) => [...new Set(tags.map((t) => t.trim().toLowerCase()).filter(Boolean))]);
13616
- templateYamlSchema2 = external_exports.object({
13617
- slug: templateSlugSchema2,
13618
- category: external_exports.string().min(1).max(60),
13619
- tags: templateTagsSchema2,
13620
- status: templateStatusSchema2.default("draft"),
13621
- order: external_exports.number().int().min(0).max(1e5).optional(),
13622
- defaultLocale: templateLocaleSchema2,
13623
- hero: external_exports.string().optional(),
13624
- // relative path to a hero image inside the template folder
13625
- // The Rekor backend(s) this channel runs on (gh #2955). Locale-agnostic. The
13626
- // cross-link + MCP endpoint are derived from each entry's slugs, never authored.
13627
- uses: templateUsesSchema2,
13628
- // A WayAI template IS a WayAI channel — the wayai slice is required. (The old
13629
- // Rekor-only store entry is gone: a pure Rekor backend lives only in Rekor's store.)
13630
- wayai: templateYamlWayaiBlock2
13631
- }).refine((c) => Boolean(c.wayai.locales[c.defaultLocale]), {
13632
- message: "`wayai.locales` must include the defaultLocale"
13633
- });
13634
- templateHeroSchema2 = external_exports.object({
13635
- filename: external_exports.string().min(1).max(200).regex(/\.(png|jpe?g|webp|gif)$/i, "hero must be a raster image (png/jpg/webp/gif)"),
13636
- dataBase64: external_exports.string().min(1).max(8e6)
13637
- });
13638
- templatePushLocaleSchema2 = external_exports.object({
13639
- wayai: templateTextSchema2.optional(),
13640
- readmeMarkdown: external_exports.string().default(""),
13641
- wayaiFiles: templateFileMapSchema2.optional()
13642
- });
13643
- templatePushBody2 = external_exports.object({
13644
- slug: templateSlugSchema2,
13645
- defaultLocale: templateLocaleSchema2,
13646
- common: external_exports.object({
13647
- category: external_exports.string().min(1).max(60),
13648
- tags: templateTagsSchema2,
13649
- status: templateStatusSchema2,
13650
- order: external_exports.number().int().min(0).max(1e5).default(0),
13651
- // The WayAI install command (a WayAI template always has a wayai side). Kept
13652
- // optional on the wire so a malformed manifest 400s on the field, not the body.
13653
- installCommand: external_exports.string().min(1).max(300).optional(),
13654
- hero: templateHeroSchema2.optional(),
13655
- // The channel→backend edge (gh #2955), locale-agnostic.
13656
- uses: templateUsesSchema2
13657
- }),
13658
- locales: external_exports.record(templateLocaleSchema2, templatePushLocaleSchema2)
13659
- }).refine((b) => Boolean(b.locales[b.defaultLocale]), {
13660
- message: "`locales` must include the defaultLocale"
13661
- });
13662
- templateListQuery2 = external_exports.object({ locale: templateLocaleSchema2.optional() });
13663
- templateSlugParam2 = external_exports.object({ slug: templateSlugSchema2 });
13664
- templateDetailQuery2 = external_exports.object({ locale: templateLocaleSchema2.optional() });
13665
13528
  ADMIN_SKILL_NAME_REGEX2 = /^[a-z0-9][a-z0-9-]{0,63}$/;
13666
13529
  adminSkillNameParam2 = external_exports.object({
13667
13530
  name: external_exports.string().regex(ADMIN_SKILL_NAME_REGEX2, "invalid skill name")
@@ -13716,12 +13579,6 @@ function resolveLayout(gitRoot, layout = WAYAI_LAYOUT) {
13716
13579
  legacyAlsoPresent: false
13717
13580
  };
13718
13581
  }
13719
- function resolveHubsDir(gitRoot) {
13720
- return resolveLayout(gitRoot).hubsDir;
13721
- }
13722
- function resolveTemplatesDir(gitRoot) {
13723
- return path.join(gitRoot, TEMPLATES_AUTHORING_SUBDIR);
13724
- }
13725
13582
  function hubsDirLabel(gitRoot) {
13726
13583
  if (!gitRoot) return path.join(WAYAI_LAYOUT.wsDir, WAYAI_LAYOUT.hubsSubdir);
13727
13584
  return path.relative(gitRoot, resolveLayout(gitRoot).hubsDir);
@@ -13747,7 +13604,7 @@ function warnLayoutOnce(gitRoot) {
13747
13604
  );
13748
13605
  }
13749
13606
  }
13750
- var WAYAI_LAYOUT, TEMPLATES_AUTHORING_SUBDIR, _layoutWarned;
13607
+ var WAYAI_LAYOUT, _layoutWarned;
13751
13608
  var init_layout = __esm({
13752
13609
  "src/lib/layout.ts"() {
13753
13610
  "use strict";
@@ -13756,7 +13613,6 @@ var init_layout = __esm({
13756
13613
  ...WAYAI_WORKSPACE_LAYOUT,
13757
13614
  legacy: { wsDir: "workspace", orgAtRoot: "org" }
13758
13615
  };
13759
- TEMPLATES_AUTHORING_SUBDIR = "wayai-templates";
13760
13616
  _layoutWarned = false;
13761
13617
  }
13762
13618
  });
@@ -13780,7 +13636,6 @@ __export(workspace_exports, {
13780
13636
  resolveActiveHubId: () => resolveActiveHubId,
13781
13637
  resolveExplicitHubPath: () => resolveExplicitHubPath,
13782
13638
  resolveHubFolder: () => resolveHubFolder,
13783
- resolveHubFolderBySelector: () => resolveHubFolderBySelector,
13784
13639
  resolveNewHubForCreate: () => resolveNewHubForCreate,
13785
13640
  resolvePushTarget: () => resolvePushTarget,
13786
13641
  resolveWorkspaceDir: () => resolveWorkspaceDir,
@@ -13982,16 +13837,6 @@ function findHubByFolderName(workspaceDir, hubFolderName) {
13982
13837
  const all = scanWorkspaceHubs(workspaceDir);
13983
13838
  return all.find((h) => path2.basename(h.hubFolder) === hubFolderName) ?? null;
13984
13839
  }
13985
- function resolveHubFolderBySelector(hubsDir, selector) {
13986
- const asPath = path2.resolve(selector);
13987
- if (isDirectory(asPath) && fs2.existsSync(path2.join(asPath, "hub.yaml"))) return asPath;
13988
- if (UUID_RE2.test(selector)) {
13989
- const match = scanWorkspaceHubs(hubsDir).find((h) => h.hubId === selector);
13990
- return match ? match.hubFolder : null;
13991
- }
13992
- const byName = findHubByFolderName(hubsDir, selector);
13993
- return byName ? byName.hubFolder : null;
13994
- }
13995
13840
  function autoRenameHubFolder(currentFolder, hubName, hubEnvironment, hubId, previewLabel, branchName) {
13996
13841
  const expectedSlug = getHubFolderSlug(hubName, hubEnvironment, hubId, previewLabel, branchName);
13997
13842
  const currentSlug = path2.basename(currentFolder);
@@ -14229,24 +14074,24 @@ import * as path4 from "path";
14229
14074
  import * as readline from "readline";
14230
14075
  function prompt(question) {
14231
14076
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
14232
- return new Promise((resolve6) => {
14077
+ return new Promise((resolve5) => {
14233
14078
  rl.question(question, (answer) => {
14234
14079
  rl.close();
14235
- resolve6(answer.trim());
14080
+ resolve5(answer.trim());
14236
14081
  });
14237
14082
  });
14238
14083
  }
14239
14084
  function confirm(question) {
14240
14085
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
14241
- return new Promise((resolve6) => {
14086
+ return new Promise((resolve5) => {
14242
14087
  rl.question(`${question} [y/N]: `, (answer) => {
14243
14088
  rl.close();
14244
- resolve6(answer.trim().toLowerCase() === "y");
14089
+ resolve5(answer.trim().toLowerCase() === "y");
14245
14090
  });
14246
14091
  });
14247
14092
  }
14248
14093
  function promptSecret(question) {
14249
- return new Promise((resolve6) => {
14094
+ return new Promise((resolve5) => {
14250
14095
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
14251
14096
  const originalWrite = rl._writeToOutput;
14252
14097
  let firstWrite = true;
@@ -14262,18 +14107,18 @@ function promptSecret(question) {
14262
14107
  rl._writeToOutput = originalWrite;
14263
14108
  process.stdout.write("\n");
14264
14109
  rl.close();
14265
- resolve6(answer);
14110
+ resolve5(answer);
14266
14111
  });
14267
14112
  });
14268
14113
  }
14269
14114
  function readStdin() {
14270
- return new Promise((resolve6, reject) => {
14115
+ return new Promise((resolve5, reject) => {
14271
14116
  let data = "";
14272
14117
  process.stdin.setEncoding("utf-8");
14273
14118
  process.stdin.on("data", (chunk) => {
14274
14119
  data += chunk;
14275
14120
  });
14276
- process.stdin.on("end", () => resolve6(data.trim()));
14121
+ process.stdin.on("end", () => resolve5(data.trim()));
14277
14122
  process.stdin.on("error", reject);
14278
14123
  });
14279
14124
  }
@@ -14435,9 +14280,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
14435
14280
  }
14436
14281
  function readVersionCache(filename = CLI_CACHE_FILE) {
14437
14282
  try {
14438
- const path31 = getVersionCachePath(filename);
14439
- if (!existsSync4(path31)) return null;
14440
- const parsed = JSON.parse(readFileSync5(path31, "utf-8"));
14283
+ const path30 = getVersionCachePath(filename);
14284
+ if (!existsSync4(path30)) return null;
14285
+ const parsed = JSON.parse(readFileSync5(path30, "utf-8"));
14441
14286
  if (typeof parsed.lastCheck !== "number") return null;
14442
14287
  if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
14443
14288
  return parsed;
@@ -14457,10 +14302,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
14457
14302
  return Date.now() - cache.lastCheck > maxAgeMs;
14458
14303
  }
14459
14304
  function writeVersionCache(filename, cache) {
14460
- const path31 = getVersionCachePath(filename);
14461
- const dir = dirname3(path31);
14305
+ const path30 = getVersionCachePath(filename);
14306
+ const dir = dirname3(path30);
14462
14307
  if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
14463
- writeFileSync2(path31, JSON.stringify(cache));
14308
+ writeFileSync2(path30, JSON.stringify(cache));
14464
14309
  }
14465
14310
  function touchVersionCache(filename) {
14466
14311
  writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
@@ -14499,14 +14344,14 @@ function parseFrontmatterVersion(content) {
14499
14344
  function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
14500
14345
  const found = [];
14501
14346
  for (const rel of paths) {
14502
- const path31 = join7(projectRoot, rel);
14503
- if (!existsSync5(path31)) continue;
14347
+ const path30 = join7(projectRoot, rel);
14348
+ if (!existsSync5(path30)) continue;
14504
14349
  let version = null;
14505
14350
  try {
14506
- version = parseFrontmatterVersion(readFileSync6(path31, "utf-8"));
14351
+ version = parseFrontmatterVersion(readFileSync6(path30, "utf-8"));
14507
14352
  } catch {
14508
14353
  }
14509
- found.push({ path: path31, version });
14354
+ found.push({ path: path30, version });
14510
14355
  }
14511
14356
  return found;
14512
14357
  }
@@ -14979,7 +14824,7 @@ async function validateToken(apiUrl, token) {
14979
14824
  }
14980
14825
  }
14981
14826
  function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
14982
- return new Promise((resolve6, reject) => {
14827
+ return new Promise((resolve5, reject) => {
14983
14828
  const server = http.createServer((req, res) => {
14984
14829
  const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
14985
14830
  if (url.pathname === "/callback") {
@@ -15005,7 +14850,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
15005
14850
  res.writeHead(200, { "Content-Type": "text/html" });
15006
14851
  res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
15007
14852
  server.close();
15008
- resolve6({ code, port });
14853
+ resolve5({ code, port });
15009
14854
  } else {
15010
14855
  res.writeHead(400, { "Content-Type": "text/html" });
15011
14856
  res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
@@ -15216,10 +15061,10 @@ import * as readline2 from "readline";
15216
15061
  function prompt2(question, defaultValue) {
15217
15062
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
15218
15063
  const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
15219
- return new Promise((resolve6) => {
15064
+ return new Promise((resolve5) => {
15220
15065
  rl.question(display, (answer) => {
15221
15066
  rl.close();
15222
- resolve6(answer.trim() || defaultValue || "");
15067
+ resolve5(answer.trim() || defaultValue || "");
15223
15068
  });
15224
15069
  });
15225
15070
  }
@@ -15337,8 +15182,8 @@ async function tryOpenBrowser(url) {
15337
15182
  cmd = "xdg-open";
15338
15183
  args2 = [url];
15339
15184
  }
15340
- return new Promise((resolve6) => {
15341
- execFile(cmd, args2, (err) => resolve6(!err));
15185
+ return new Promise((resolve5) => {
15186
+ execFile(cmd, args2, (err) => resolve5(!err));
15342
15187
  });
15343
15188
  } catch {
15344
15189
  return false;
@@ -19961,8 +19806,8 @@ function installEvalSignalHandlers(input) {
19961
19806
  let signalCount = 0;
19962
19807
  let disposed = false;
19963
19808
  let settle;
19964
- const settled = new Promise((resolve6) => {
19965
- settle = resolve6;
19809
+ const settled = new Promise((resolve5) => {
19810
+ settle = resolve5;
19966
19811
  });
19967
19812
  const listeners = /* @__PURE__ */ new Map();
19968
19813
  const dispose = () => {
@@ -20312,7 +20157,7 @@ Timeout after ${timeoutSeconds}s${queuedSeconds > 0 ? ` (${queuedSeconds}s of it
20312
20157
  process.exit(1);
20313
20158
  }
20314
20159
  function sleep(ms) {
20315
- return new Promise((resolve6) => setTimeout(resolve6, ms));
20160
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
20316
20161
  }
20317
20162
  function parseRunNumbers(raw) {
20318
20163
  if (!raw || raw.startsWith("--")) {
@@ -21393,12 +21238,25 @@ function messageGrainNotes() {
21393
21238
  " - Rows are written when a conversation CLOSES, best-effort. An open",
21394
21239
  " conversation has no rows, and `message` is less durable than",
21395
21240
  " `conversation` \u2014 treat it as analysis-grade, not billing-grade.",
21396
- " - An unfiltered sum EXCEEDS the matching conversation figure by design:",
21397
- " message rows include background agents that conversation aggregates",
21398
- " exclude. To reconcile, filter NULL-safely, KEEPING the outer parentheses",
21399
- " (AND binds tighter than OR, so an unparenthesized copy combined with any",
21400
- " other condition silently readmits every NULL-role row):",
21401
- " WHERE (agent_role IS NULL OR agent_role NOT IN ('conversation_evaluator','message_evaluator','monitor'))",
21241
+ " - An unfiltered sum EQUALS the matching conversation figure: `message` is the",
21242
+ " DECOMPOSITION of that figure, every agent role included. Use the filter below",
21243
+ " only to ISOLATE the spend a hub's own agents did, splitting it from platform",
21244
+ " background work (evaluators, monitor, summarizer). It lands at or below the",
21245
+ " conversation total \u2014 `filtered <= total`, strict only when an excluded row",
21246
+ " actually contributed to the metric you selected. A conversation that ran no",
21247
+ " background agent has nothing to exclude, so equality there is correct, not a",
21248
+ " fault. Filter NULL-safely, KEEPING the outer parentheses (AND binds tighter",
21249
+ " than OR, so an unparenthesized copy combined with any other condition silently",
21250
+ " readmits every NULL-role row):",
21251
+ " WHERE (agent_role IS NULL OR agent_role NOT IN ('conversation_evaluator','message_evaluator','monitor','summarizer'))",
21252
+ " - HISTORICAL BOUNDARIES \u2014 TWO, both forward-only and neither backfilled, so a",
21253
+ " conversation reflects whichever rules were live when it CLOSED:",
21254
+ " * `summarizer` spend entered BOTH tables when the provider-usage carrier",
21255
+ " shipped. Before that it was recorded nowhere; no query recovers it.",
21256
+ " * evaluator and monitor spend entered the `conversation` aggregate later,",
21257
+ " when the role exclusion narrowed to shape only. `message` carried those",
21258
+ " rows all along, so for a window spanning only that second change, summing",
21259
+ " `message` is the continuous answer.",
21402
21260
  " - `connection_id` names the LLM connection only. TTS/STT/container spend",
21403
21261
  " is folded into the same row, so attributing cost to a credential means",
21404
21262
  " netting out cost_usd_tts / cost_usd_stt / cost_usd_container.",
@@ -21408,7 +21266,8 @@ function messageGrainNotes() {
21408
21266
  " - BOUND created_at. The table retains five years at per-message volume, so",
21409
21267
  " an unbounded scan is the expensive way to ask any question:",
21410
21268
  " WHERE created_at >= now() - INTERVAL 30 DAY",
21411
- " - The conversation figure stays the customer-visible one."
21269
+ " - The conversation figure stays the customer-visible one, and it is now the",
21270
+ " TOTAL: every role that spent on the conversation is in it."
21412
21271
  ];
21413
21272
  }
21414
21273
  function splitFilterExpr(raw, shape) {
@@ -22358,276 +22217,6 @@ var init_list = __esm({
22358
22217
  }
22359
22218
  });
22360
22219
 
22361
- // src/lib/template-files.ts
22362
- import * as fs22 from "fs";
22363
- import * as path28 from "path";
22364
- function readDirToFileMap(rootDir) {
22365
- const out = {};
22366
- function walk(dir, prefix) {
22367
- const entries = fs22.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
22368
- for (const entry of entries) {
22369
- const abs = path28.join(dir, entry.name);
22370
- const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
22371
- if (entry.isDirectory()) walk(abs, rel);
22372
- else if (entry.isFile()) out[rel] = fs22.readFileSync(abs, "utf-8");
22373
- }
22374
- }
22375
- if (fs22.existsSync(rootDir)) walk(rootDir, "");
22376
- return out;
22377
- }
22378
- function detectCollisions(targetDir, files) {
22379
- const collisions = [];
22380
- for (const rel of Object.keys(files)) {
22381
- if (!isSafeTemplatePath(rel)) {
22382
- throw new Error(`Refusing to inspect unsafe template path: ${rel}`);
22383
- }
22384
- if (fs22.existsSync(path28.join(targetDir, rel))) collisions.push(rel);
22385
- }
22386
- return collisions.sort((a, b) => a.localeCompare(b));
22387
- }
22388
- function writeFileMap(targetDir, files) {
22389
- const written = [];
22390
- for (const [rel, body] of Object.entries(files)) {
22391
- if (!isSafeTemplatePath(rel)) {
22392
- throw new Error(`Refusing to write unsafe template path: ${rel}`);
22393
- }
22394
- const abs = path28.join(targetDir, rel);
22395
- fs22.mkdirSync(path28.dirname(abs), { recursive: true });
22396
- fs22.writeFileSync(abs, body, "utf-8");
22397
- written.push(rel);
22398
- }
22399
- return written;
22400
- }
22401
- function listDirRelFiles(dir) {
22402
- const out = [];
22403
- function walk(d, prefix) {
22404
- for (const entry of fs22.readdirSync(d, { withFileTypes: true })) {
22405
- const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
22406
- if (entry.isDirectory()) walk(path28.join(d, entry.name), rel);
22407
- else if (entry.isFile()) out.push(rel);
22408
- }
22409
- }
22410
- if (fs22.existsSync(dir)) walk(dir, "");
22411
- return out;
22412
- }
22413
- function writeSliceSnapshot(targetDir, files) {
22414
- const keep = new Set(Object.keys(files));
22415
- const removed = listDirRelFiles(targetDir).filter((rel) => !keep.has(rel)).sort((a, b) => a.localeCompare(b));
22416
- const written = writeFileMap(targetDir, files).sort((a, b) => a.localeCompare(b));
22417
- if (fs22.existsSync(targetDir)) cleanOrphanFiles(targetDir, "", keep);
22418
- return { written, removed };
22419
- }
22420
- var init_template_files = __esm({
22421
- "src/lib/template-files.ts"() {
22422
- "use strict";
22423
- init_contracts();
22424
- init_resource_files();
22425
- }
22426
- });
22427
-
22428
- // src/commands/templates.ts
22429
- var templates_exports = {};
22430
- __export(templates_exports, {
22431
- templateCommand: () => templateCommand
22432
- });
22433
- import * as path29 from "path";
22434
- async function templateCommand(args2) {
22435
- const [sub, ...rest] = args2;
22436
- switch (sub) {
22437
- case "list":
22438
- await runTemplateList();
22439
- return;
22440
- case "pull":
22441
- await runTemplatePull(rest);
22442
- return;
22443
- case void 0:
22444
- case "help":
22445
- case "--help":
22446
- case "-h":
22447
- printTemplateHelp();
22448
- return;
22449
- default:
22450
- console.error(`Unknown template subcommand: ${sub}`);
22451
- printTemplateHelp();
22452
- process.exit(1);
22453
- }
22454
- }
22455
- function includesLabel(item) {
22456
- const parts = [];
22457
- if (item.includes.wayai) parts.push("wayai agent");
22458
- if (item.uses?.length) parts.push("rekor backend");
22459
- return parts.length ? parts.join(" + ") : "(none)";
22460
- }
22461
- async function runTemplateList() {
22462
- const { config, accessToken } = await requireAuth();
22463
- const client = new ApiClient({ apiUrl: config.api_url, accessToken });
22464
- let response;
22465
- try {
22466
- response = await client.templateList();
22467
- } catch (err) {
22468
- exitOnTemplateApiError(err);
22469
- throw err;
22470
- }
22471
- const { templates } = response;
22472
- if (templates.length === 0) {
22473
- console.log("(no templates published yet)");
22474
- return;
22475
- }
22476
- const slugWidth = Math.max(4, ...templates.map((t) => t.slug.length));
22477
- const catWidth = Math.max(8, ...templates.map((t) => t.category.length));
22478
- console.log(`${"SLUG".padEnd(slugWidth)} ${"CATEGORY".padEnd(catWidth)} INCLUDES`);
22479
- for (const t of templates) {
22480
- console.log(`${t.slug.padEnd(slugWidth)} ${t.category.padEnd(catWidth)} ${includesLabel(t)}`);
22481
- }
22482
- }
22483
- async function runTemplatePull(rest) {
22484
- const positional = [];
22485
- let lang;
22486
- let force = false;
22487
- let dryRun = false;
22488
- for (let i = 0; i < rest.length; i++) {
22489
- if (rest[i] === "--force") {
22490
- force = true;
22491
- continue;
22492
- }
22493
- if (rest[i] === "--dry-run") {
22494
- dryRun = true;
22495
- continue;
22496
- }
22497
- if (rest[i] === "--lang") {
22498
- const v = rest[++i];
22499
- if (!v) {
22500
- console.error("--lang requires a value");
22501
- process.exit(1);
22502
- }
22503
- const parsed = templateLocaleSchema.safeParse(v);
22504
- if (!parsed.success) {
22505
- console.error(`Invalid --lang "${v}": must be one of ${templateLocaleSchema.options.join(", ")}.`);
22506
- process.exit(1);
22507
- }
22508
- lang = parsed.data;
22509
- continue;
22510
- }
22511
- if (rest[i].startsWith("--")) {
22512
- console.error(`Unknown flag: ${rest[i]}`);
22513
- process.exit(1);
22514
- }
22515
- positional.push(rest[i]);
22516
- }
22517
- const slug = positional[0];
22518
- if (!slug) {
22519
- console.error("wayai template pull <slug> [--lang <locale>]");
22520
- process.exit(1);
22521
- }
22522
- if (!TEMPLATE_SLUG_REGEX.test(slug)) {
22523
- console.error(`Invalid template slug: ${slug}`);
22524
- process.exit(1);
22525
- }
22526
- const gitRoot = findGitRoot();
22527
- if (!gitRoot) {
22528
- console.error("Not in a git repository. Run `wayai template pull` inside your project repo.");
22529
- process.exit(1);
22530
- }
22531
- const { config, accessToken } = await requireAuth();
22532
- const client = new ApiClient({ apiUrl: config.api_url, accessToken });
22533
- let detail;
22534
- try {
22535
- detail = await client.templatePull(slug, lang);
22536
- } catch (err) {
22537
- exitOnTemplateApiError(err);
22538
- throw err;
22539
- }
22540
- if (detail.resolvedLocale !== detail.requestedLocale) {
22541
- console.log(`Note: "${detail.requestedLocale}" not translated yet \u2014 pulled "${detail.resolvedLocale}" instead.`);
22542
- }
22543
- if (!detail.includes.wayai) {
22544
- const backends2 = distinctUsesBackends(detail.uses);
22545
- const hint = backends2.length ? ` \u2014 run ${backends2.map((b) => `\`rekor template pull ${b}${langFlag(lang)}\``).join(" and ")} for its data layer.` : ".";
22546
- console.log(`Template "${slug}" has no WayAI slice${hint}`);
22547
- return;
22548
- }
22549
- const targetDir = path29.join(resolveLayout(gitRoot).hubsDir, slug);
22550
- const relTarget = path29.relative(gitRoot, targetDir);
22551
- const collisions = detectCollisions(targetDir, detail.files);
22552
- if (dryRun) {
22553
- const planned = Object.keys(detail.files).sort((a, b) => a.localeCompare(b));
22554
- const collisionSet = new Set(collisions);
22555
- console.log(`Dry run \u2014 would write ${planned.length} file${planned.length === 1 ? "" : "s"} into ${relTarget}/:`);
22556
- for (const rel of planned) {
22557
- console.log(` ${collisionSet.has(rel) ? "overwrite" : "create"} ${rel}`);
22558
- }
22559
- if (collisions.length > 0) {
22560
- console.log(`
22561
- ${collisions.length} existing file${collisions.length === 1 ? "" : "s"} would be overwritten \u2014 re-run with --force to proceed.`);
22562
- }
22563
- return;
22564
- }
22565
- if (collisions.length > 0 && !force) {
22566
- console.error(`Refusing to overwrite ${collisions.length} existing file${collisions.length === 1 ? "" : "s"} in ${relTarget}/:`);
22567
- for (const rel of collisions) console.error(` ${rel}`);
22568
- console.error(`
22569
- Commit or move your changes and re-run with --force to overwrite, or pull into a fresh slug dir.`);
22570
- console.error(`Preview the full file map first with --dry-run.`);
22571
- process.exit(1);
22572
- }
22573
- const written = writeFileMap(targetDir, detail.files);
22574
- console.log(`Pulled template "${slug}" \u2192 ${relTarget}/ (${written.length} file${written.length === 1 ? "" : "s"}).`);
22575
- console.log(`Next: \`wayai push\` to deploy it into your own hub.`);
22576
- const backends = distinctUsesBackends(detail.uses);
22577
- if (backends.length) {
22578
- const cmds = backends.map((b) => `\`rekor template pull ${b}${langFlag(lang)}\``).join(" and ");
22579
- const noun = backends.length === 1 ? "a Rekor backend" : "Rekor backends";
22580
- const obj = backends.length === 1 ? "it" : "them";
22581
- console.log(`
22582
- This channel runs on ${noun} \u2014 run ${cmds} to add ${obj}.`);
22583
- }
22584
- }
22585
- function langFlag(lang) {
22586
- return lang ? ` --lang ${lang}` : "";
22587
- }
22588
- function printTemplateHelp() {
22589
- console.log(`wayai template \u2014 install ready-made hub templates
22590
-
22591
- Usage:
22592
- wayai template list List available templates
22593
- wayai template pull <slug> [--lang <l>] [--force] [--dry-run]
22594
- Write a template's WayAI slice into wayai-ws/hubs/<slug>/
22595
-
22596
- --lang selects a localized variant (${templateLocaleSchema.options.join("|")}); omitted = the template's default
22597
- language. An untranslated language falls back to the default (with a note).
22598
- --dry-run previews the file map (marking files that would be overwritten) without writing.
22599
- A pull refuses to overwrite existing files in the target dir; pass --force to overwrite them.
22600
-
22601
- After pulling, run \`wayai push\` to deploy the template into your own hub.`);
22602
- }
22603
- function exitOnTemplateApiError(err) {
22604
- if (err instanceof ApiError) {
22605
- if (err.status === 401) {
22606
- console.error("Authentication failed. Run `wayai login` again.");
22607
- } else if (err.status === 404) {
22608
- console.error("Template not found. Run `wayai template list` to see available templates.");
22609
- } else if (err.status === 429) {
22610
- console.error("Rate limited. Please retry in a moment.");
22611
- } else {
22612
- console.error(err.message);
22613
- }
22614
- process.exit(1);
22615
- }
22616
- console.error(err instanceof Error ? err.message : String(err));
22617
- process.exit(1);
22618
- }
22619
- var init_templates = __esm({
22620
- "src/commands/templates.ts"() {
22621
- "use strict";
22622
- init_auth();
22623
- init_api_client();
22624
- init_workspace();
22625
- init_layout();
22626
- init_template_files();
22627
- init_contracts();
22628
- }
22629
- });
22630
-
22631
22220
  // src/lib/report-edit-args.ts
22632
22221
  function parseReportEditArgs(args2) {
22633
22222
  const patch = {};
@@ -22668,66 +22257,32 @@ var init_report_edit_args = __esm({
22668
22257
  }
22669
22258
  });
22670
22259
 
22671
- // src/lib/template-sanitize.ts
22672
- import * as yaml9 from "js-yaml";
22673
- function sanitizeWayaiSliceFiles(files) {
22674
- const out = {};
22675
- for (const [filePath, body] of Object.entries(files)) {
22676
- out[filePath] = isSanitizableSliceFile(filePath) ? sanitizeOne(filePath, body) : body;
22677
- }
22678
- return out;
22679
- }
22680
- function sanitizeOne(filePath, body) {
22681
- let parsed;
22682
- try {
22683
- parsed = yaml9.load(body);
22684
- } catch {
22685
- return body;
22686
- }
22687
- const scrubbed = stripEvalAttachments(filePath, excludeTemplateAuthorData(stripTemplateInstanceIds(parsed)));
22688
- if (JSON.stringify(parsed) === JSON.stringify(scrubbed)) return body;
22689
- return yaml9.dump(scrubbed, YAML_DUMP_OPTIONS);
22690
- }
22691
- function stripEvalAttachments(filePath, value) {
22692
- if (!value || typeof value !== "object" || Array.isArray(value)) return value;
22693
- const doc = { ...value };
22694
- const dropOnTurn = (turn) => {
22695
- if (!turn || typeof turn !== "object" || Array.isArray(turn) || !("attachments" in turn)) return turn;
22696
- const { attachments: _drop, ...rest } = turn;
22697
- return rest;
22698
- };
22699
- if (/^evals\//.test(filePath)) {
22700
- if ("input" in doc) doc.input = dropOnTurn(doc.input);
22701
- if (Array.isArray(doc.history)) doc.history = doc.history.map(dropOnTurn);
22702
- } else if (/^journeys\//.test(filePath)) {
22703
- if (Array.isArray(doc.transcript)) doc.transcript = doc.transcript.map(dropOnTurn);
22704
- }
22705
- return doc;
22260
+ // src/lib/file-map.ts
22261
+ import * as fs22 from "fs";
22262
+ import * as path28 from "path";
22263
+ function isSafeRelPath(rel) {
22264
+ if (rel.length === 0 || rel.length > 300) return false;
22265
+ if (rel.startsWith("/") || rel.includes("\\")) return false;
22266
+ const segments = rel.split("/");
22267
+ return segments.every(
22268
+ (seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
22269
+ );
22706
22270
  }
22707
- var init_template_sanitize = __esm({
22708
- "src/lib/template-sanitize.ts"() {
22709
- "use strict";
22710
- init_contracts();
22711
- init_yaml_writer();
22271
+ function writeFileMap(targetDir, files) {
22272
+ const written = [];
22273
+ for (const [rel, body] of Object.entries(files)) {
22274
+ if (!isSafeRelPath(rel)) {
22275
+ throw new Error(`Refusing to write unsafe path: ${rel}`);
22276
+ }
22277
+ const abs = path28.join(targetDir, rel);
22278
+ fs22.mkdirSync(path28.dirname(abs), { recursive: true });
22279
+ fs22.writeFileSync(abs, body, "utf-8");
22280
+ written.push(rel);
22712
22281
  }
22713
- });
22714
-
22715
- // src/lib/template-manifest.ts
22716
- function buildTemplatePushCommon(manifest, hero) {
22717
- return {
22718
- category: manifest.category,
22719
- tags: manifest.tags,
22720
- status: manifest.status,
22721
- order: manifest.order ?? 0,
22722
- installCommand: manifest.wayai.installCommand,
22723
- ...hero && { hero },
22724
- // The channel→backend edge (locale-agnostic). The store persists it verbatim; the
22725
- // website derives the "runs on backend X" cross-link + MCP endpoint from the slugs.
22726
- uses: manifest.uses
22727
- };
22282
+ return written;
22728
22283
  }
22729
- var init_template_manifest = __esm({
22730
- "src/lib/template-manifest.ts"() {
22284
+ var init_file_map = __esm({
22285
+ "src/lib/file-map.ts"() {
22731
22286
  "use strict";
22732
22287
  }
22733
22288
  });
@@ -22738,8 +22293,7 @@ __export(admin_exports, {
22738
22293
  adminCommand: () => adminCommand
22739
22294
  });
22740
22295
  import * as fs23 from "fs";
22741
- import * as path30 from "path";
22742
- import * as yaml10 from "js-yaml";
22296
+ import * as path29 from "path";
22743
22297
  async function adminCommand(args2) {
22744
22298
  const [group, ...afterGroup] = args2;
22745
22299
  if (!group) {
@@ -22853,26 +22407,6 @@ async function adminCommand(args2) {
22853
22407
  process.exit(1);
22854
22408
  }
22855
22409
  }
22856
- if (group === "template") {
22857
- if (!sub) {
22858
- printHelp2();
22859
- process.exit(1);
22860
- }
22861
- switch (sub) {
22862
- case "push":
22863
- await runTemplatePush(positional);
22864
- return;
22865
- case "pull":
22866
- await runTemplatePull2(positional, flagArgs);
22867
- return;
22868
- case "freeze":
22869
- await runTemplateFreeze(positional, flagArgs);
22870
- return;
22871
- default:
22872
- printHelp2();
22873
- process.exit(1);
22874
- }
22875
- }
22876
22410
  if (group === "skill") {
22877
22411
  if (!sub) {
22878
22412
  printHelp2();
@@ -23186,262 +22720,6 @@ function parseFlags2(flagArgs, allowed) {
23186
22720
  }
23187
22721
  return out;
23188
22722
  }
23189
- function loadTemplateManifest(slug) {
23190
- const gitRoot = findGitRoot();
23191
- if (!gitRoot) {
23192
- console.error("Not in a git repository. Run from the templates authoring repo (wayai-pro/templates).");
23193
- process.exit(1);
23194
- }
23195
- const templateDir = path30.join(resolveTemplatesDir(gitRoot), slug);
23196
- const manifestPath = path30.join(templateDir, "template.yaml");
23197
- if (!fs23.existsSync(manifestPath)) {
23198
- console.error(`template.yaml not found at ${path30.relative(gitRoot, manifestPath)}`);
23199
- process.exit(1);
23200
- }
23201
- let manifest;
23202
- try {
23203
- manifest = templateYamlSchema.parse(yaml10.load(fs23.readFileSync(manifestPath, "utf-8")));
23204
- } catch (err) {
23205
- console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
23206
- process.exit(1);
23207
- }
23208
- if (manifest.slug !== slug) {
23209
- console.error(`template.yaml slug "${manifest.slug}" does not match folder "${slug}".`);
23210
- process.exit(1);
23211
- }
23212
- return { gitRoot, templateDir, manifest };
23213
- }
23214
- async function runTemplatePush(positional) {
23215
- const slug = positional[0];
23216
- if (!slug) {
23217
- console.error("wayai admin template push <slug>");
23218
- process.exit(1);
23219
- }
23220
- if (!TEMPLATE_SLUG_REGEX.test(slug)) {
23221
- console.error(`Invalid template slug: ${slug}`);
23222
- process.exit(1);
23223
- }
23224
- const { templateDir, manifest } = loadTemplateManifest(slug);
23225
- const authoredLocales = new Set(
23226
- Object.keys(manifest.wayai.locales)
23227
- );
23228
- const locales = {};
23229
- for (const locale of authoredLocales) {
23230
- const wayaiEntry = manifest.wayai.locales[locale];
23231
- let wayaiFiles;
23232
- if (wayaiEntry) {
23233
- const sliceDir = path30.resolve(templateDir, wayaiEntry.source);
23234
- if (!fs23.existsSync(sliceDir)) {
23235
- console.error(`wayai source not found for ${locale}: ${wayaiEntry.source} (resolved ${sliceDir})`);
23236
- process.exit(1);
23237
- }
23238
- if (!isInsideTemplateDir(sliceDir, templateDir)) {
23239
- console.warn(
23240
- `Note: ${locale} source points at a live hub (${wayaiEntry.source}); it can go stale on a hub recreate. Run \`wayai admin template freeze ${slug} --locale ${locale} --from ${path30.basename(sliceDir)}\` to commit a stable frozen slice.`
23241
- );
23242
- }
23243
- wayaiFiles = readDirToFileMap(sliceDir);
23244
- }
23245
- const readmePath = path30.join(templateDir, `README.${locale}.md`);
23246
- const readmeMarkdown = fs23.existsSync(readmePath) ? fs23.readFileSync(readmePath, "utf-8") : "";
23247
- locales[locale] = {
23248
- readmeMarkdown,
23249
- ...wayaiFiles && { wayaiFiles },
23250
- ...wayaiEntry && {
23251
- wayai: { metaTitle: wayaiEntry.metaTitle, metaDescription: wayaiEntry.metaDescription }
23252
- }
23253
- };
23254
- }
23255
- let hero;
23256
- if (manifest.hero) {
23257
- const heroPath = path30.resolve(templateDir, manifest.hero);
23258
- if (fs23.existsSync(heroPath)) {
23259
- hero = { filename: path30.basename(heroPath), dataBase64: fs23.readFileSync(heroPath).toString("base64") };
23260
- } else {
23261
- console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
23262
- }
23263
- }
23264
- const body = {
23265
- slug,
23266
- defaultLocale: manifest.defaultLocale,
23267
- common: buildTemplatePushCommon(manifest, hero),
23268
- locales
23269
- };
23270
- const { config, accessToken } = await requireAuth();
23271
- const client = new ApiClient({ apiUrl: config.api_url, accessToken });
23272
- let result;
23273
- try {
23274
- result = await client.adminTemplatePush(body);
23275
- } catch (err) {
23276
- exitOnApiError(err);
23277
- throw err;
23278
- }
23279
- console.log(`Template "${result.slug}": ${result.action} (${result.filesWritten} written, ${result.filesDeleted} deleted).`);
23280
- if (manifest.status !== "published") {
23281
- console.log(`(status=${manifest.status} \u2192 unpublished from the store)`);
23282
- }
23283
- }
23284
- function isInsideTemplateDir(dest, templateDir) {
23285
- return dest === templateDir || dest.startsWith(templateDir + path30.sep);
23286
- }
23287
- async function runTemplateFreeze(positional, flagArgs) {
23288
- const slug = positional[0];
23289
- if (!slug) {
23290
- console.error("wayai admin template freeze <slug> [--locale <l>] [--from <hub>] [--dry-run]");
23291
- process.exit(1);
23292
- }
23293
- if (!TEMPLATE_SLUG_REGEX.test(slug)) {
23294
- console.error(`Invalid template slug: ${slug}`);
23295
- process.exit(1);
23296
- }
23297
- let locale;
23298
- let from;
23299
- let dryRun = false;
23300
- for (let i = 0; i < flagArgs.length; i++) {
23301
- if (flagArgs[i] === "--dry-run") {
23302
- dryRun = true;
23303
- continue;
23304
- }
23305
- if (flagArgs[i] === "--locale") {
23306
- const v = flagArgs[++i];
23307
- if (!v) {
23308
- console.error("--locale requires a value");
23309
- process.exit(1);
23310
- }
23311
- const parsed = templateLocaleSchema.safeParse(v);
23312
- if (!parsed.success) {
23313
- console.error(`Invalid --locale "${v}": must be one of ${templateLocaleSchema.options.join(", ")}.`);
23314
- process.exit(1);
23315
- }
23316
- locale = parsed.data;
23317
- continue;
23318
- }
23319
- if (flagArgs[i] === "--from") {
23320
- from = flagArgs[++i];
23321
- if (!from) {
23322
- console.error("--from requires a value");
23323
- process.exit(1);
23324
- }
23325
- continue;
23326
- }
23327
- console.error(`Unknown flag: ${flagArgs[i]}`);
23328
- process.exit(1);
23329
- }
23330
- const { gitRoot, templateDir, manifest } = loadTemplateManifest(slug);
23331
- const authored = Object.keys(manifest.wayai.locales);
23332
- let targetLocale;
23333
- if (locale) {
23334
- if (!manifest.wayai.locales[locale]) {
23335
- console.error(`Locale "${locale}" is not authored in ${slug}/template.yaml (have: ${authored.join(", ")}).`);
23336
- process.exit(1);
23337
- }
23338
- targetLocale = locale;
23339
- } else if (authored.length === 1) {
23340
- targetLocale = authored[0];
23341
- } else {
23342
- console.error(`Template "${slug}" authors ${authored.length} locales (${authored.join(", ")}). Pass --locale <l> \u2014 each freezes from its own hub.`);
23343
- process.exit(1);
23344
- }
23345
- const entry = manifest.wayai.locales[targetLocale];
23346
- const dest = path30.resolve(templateDir, entry.source);
23347
- if (!isInsideTemplateDir(dest, templateDir) || dest === templateDir) {
23348
- console.error(
23349
- `source for "${targetLocale}" must be a committed path inside ${slug}/ (e.g. "./${targetLocale}/slice"), but resolved to:
23350
- ${entry.source} \u2192 ${dest}
23351
- Set it to a subdir of the template folder and re-run freeze.`
23352
- );
23353
- process.exit(1);
23354
- }
23355
- const hubsDir = resolveHubsDir(gitRoot);
23356
- const selector = from ?? readBinding();
23357
- const hubFolder = selector ? resolveHubFolderBySelector(hubsDir, selector) : null;
23358
- if (!hubFolder) {
23359
- console.error(
23360
- selector ? `Could not resolve a source hub matching "${selector}" in ${hubsDirLabel(gitRoot)}/.` : "No --from given and this worktree has no `wayai use` binding."
23361
- );
23362
- const hubs = scanWorkspaceHubs(hubsDir);
23363
- if (hubs.length) {
23364
- console.error("Available hubs:");
23365
- for (const h of hubs) console.error(` ${path30.basename(h.hubFolder)} (${h.hubId})`);
23366
- }
23367
- console.error(`
23368
- Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`);
23369
- process.exit(1);
23370
- }
23371
- const liveFiles = readDirToFileMap(hubFolder);
23372
- if (Object.keys(liveFiles).length === 0) {
23373
- console.error(`Source hub folder has no files to freeze: ${path30.relative(gitRoot, hubFolder)}`);
23374
- process.exit(1);
23375
- }
23376
- const sanitized = sanitizeWayaiSliceFiles(liveFiles);
23377
- const relDest = path30.relative(gitRoot, dest);
23378
- const relSrc = path30.relative(gitRoot, hubFolder);
23379
- if (dryRun) {
23380
- const existing = new Set(listDirRelFiles(dest));
23381
- const nextKeys = new Set(Object.keys(sanitized));
23382
- console.log(`Dry run \u2014 would freeze ${relSrc}/ \u2192 ${relDest}/ (locale ${targetLocale}):`);
23383
- for (const rel of Object.keys(sanitized).sort((a, b) => a.localeCompare(b))) {
23384
- console.log(` ${existing.has(rel) ? "update" : "create"} ${rel}`);
23385
- }
23386
- for (const rel of [...existing].filter((k) => !nextKeys.has(k)).sort((a, b) => a.localeCompare(b))) {
23387
- console.log(` remove ${rel}`);
23388
- }
23389
- return;
23390
- }
23391
- const { written, removed } = writeSliceSnapshot(dest, sanitized);
23392
- console.log(
23393
- `Froze ${relSrc}/ \u2192 ${relDest}/ (locale ${targetLocale}): ${written.length} file${written.length === 1 ? "" : "s"} written${removed.length ? `, ${removed.length} removed` : ""}.`
23394
- );
23395
- console.log(`The slice is committed \u2014 re-push is stable across hub recreates. Next: \`wayai admin template push ${slug}\`.`);
23396
- }
23397
- async function runTemplatePull2(positional, flagArgs) {
23398
- const slug = positional[0];
23399
- if (!slug) {
23400
- console.error("wayai admin template pull <slug> [--out DIR] [--json]");
23401
- process.exit(1);
23402
- }
23403
- if (!TEMPLATE_SLUG_REGEX.test(slug)) {
23404
- console.error(`Invalid template slug: ${slug}`);
23405
- process.exit(1);
23406
- }
23407
- let outDir;
23408
- let jsonOutput = false;
23409
- for (let i = 0; i < flagArgs.length; i++) {
23410
- if (flagArgs[i] === "--json") {
23411
- jsonOutput = true;
23412
- continue;
23413
- }
23414
- if (flagArgs[i] === "--out") {
23415
- outDir = flagArgs[++i];
23416
- if (!outDir) {
23417
- console.error("--out requires a value");
23418
- process.exit(1);
23419
- }
23420
- continue;
23421
- }
23422
- console.error(`Unknown flag: ${flagArgs[i]}`);
23423
- process.exit(1);
23424
- }
23425
- const { config, accessToken } = await requireAuth();
23426
- const client = new ApiClient({ apiUrl: config.api_url, accessToken });
23427
- let detail;
23428
- try {
23429
- detail = await client.adminTemplatePull(slug);
23430
- } catch (err) {
23431
- exitOnApiError(err);
23432
- throw err;
23433
- }
23434
- if (jsonOutput) {
23435
- console.log(JSON.stringify(detail, null, 2));
23436
- return;
23437
- }
23438
- const target = outDir ? path30.resolve(outDir) : path30.join(process.cwd(), "template-store-pull", slug);
23439
- const written = writeFileMap(target, detail.files);
23440
- console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
23441
- const uses = detail.uses ?? [];
23442
- const usesLabel = uses.length ? uses.map((u) => `${u.backend}/${u.endpoint}`).join(", ") : "(none)";
23443
- console.log(`includes: wayai=${detail.includes.wayai} | uses: ${usesLabel}`);
23444
- }
23445
22723
  async function runSkillInstall(positional) {
23446
22724
  const name = positional[0] ?? "wayai-admin";
23447
22725
  if (!ADMIN_SKILL_NAME_REGEX.test(name)) {
@@ -23458,13 +22736,13 @@ async function runSkillInstall(positional) {
23458
22736
  throw err;
23459
22737
  }
23460
22738
  const root = findGitRoot() ?? process.cwd();
23461
- const present = HARNESS_SKILL_DIRS.filter((dir) => fs23.existsSync(path30.join(root, dir)));
22739
+ const present = HARNESS_SKILL_DIRS.filter((dir) => fs23.existsSync(path29.join(root, dir)));
23462
22740
  const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
23463
22741
  const fileCount = Object.keys(res.files).length;
23464
22742
  const relDirs = targets.map((harness) => {
23465
- const targetDir = path30.join(root, harness, "skills", name);
22743
+ const targetDir = path29.join(root, harness, "skills", name);
23466
22744
  writeFileMap(targetDir, res.files);
23467
- return `${path30.relative(root, targetDir)}/`;
22745
+ return `${path29.relative(root, targetDir)}/`;
23468
22746
  });
23469
22747
  console.log(`Installed skill "${name}" (${fileCount} file${fileCount === 1 ? "" : "s"}) \u2192 ${relDirs.join(", ")}`);
23470
22748
  console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
@@ -24183,11 +23461,6 @@ Usage:
24183
23461
  wayai admin notice list [--status active|resolved] [--limit N] [--offset N] [--json]
24184
23462
  wayai admin notice resolve <notice_id>
24185
23463
 
24186
- wayai admin template push <slug> Publish a template from wayai-templates/<slug>/ into the store
24187
- wayai admin template pull <slug> [--out DIR] [--json] Pull a published template from the store for inspection
24188
- wayai admin template freeze <slug> [--locale <l>] [--from <hub>] [--dry-run]
24189
- Snapshot a live hub into the template's committed slice (id/PII-scrubbed)
24190
-
24191
23464
  wayai admin skill install [name] Install a private operator skill (default: wayai-admin) into each present harness's skills/ dir
24192
23465
 
24193
23466
  wayai admin sandbox exec [--cmd "<c>" | <c>] --hub <id> --connection <id> [--egress open|allowlist|isolated] [--allow <host> ...] [--timeout <ms>] [--json]
@@ -24206,7 +23479,9 @@ Sources:
24206
23479
  do Live DO SQLite (existing conversation, hub config, etc.).
24207
23480
  analytics ClickHouse projections (conversation, message, schedule_event).
24208
23481
  \`message\` is per-message usage facts and INCLUDES background agent
24209
- roles, so its unfiltered sums exceed the conversation figures.
23482
+ roles, as the conversation figures now do \u2014 so its unfiltered sums
23483
+ REPRODUCE them, and filtering those roles out lands at or below
23484
+ (equal when the conversation ran no background agent).
24210
23485
  archive R2 archive blob \u2014 canonical content for ended conversations after DO cleanup.
24211
23486
  observability R2 LLM observability \u2014 per-message OTel GenAI records (prompts, completions,
24212
23487
  tool calls, tokens, latency). Default lists all records for the conversation;
@@ -24289,12 +23564,8 @@ var init_admin = __esm({
24289
23564
  init_observability();
24290
23565
  init_report_edit_args();
24291
23566
  init_workspace();
24292
- init_hub_binding();
24293
23567
  init_skill_version();
24294
- init_layout();
24295
- init_template_files();
24296
- init_template_sanitize();
24297
- init_template_manifest();
23568
+ init_file_map();
24298
23569
  init_contracts();
24299
23570
  VALID_TYPES = dataExplorerDebugDoType.options;
24300
23571
  VALID_ANALYTICS_TABLES = dataExplorerDebugAnalyticsTable.options;
@@ -24784,9 +24055,9 @@ init_sentry();
24784
24055
  init_errors2();
24785
24056
  init_mask_secrets();
24786
24057
  init_utils();
24787
- import { readFileSync as readFileSync21 } from "fs";
24058
+ import { readFileSync as readFileSync19 } from "fs";
24788
24059
  import { fileURLToPath as fileURLToPath2 } from "url";
24789
- import { dirname as dirname9, join as join28 } from "path";
24060
+ import { dirname as dirname9, join as join27 } from "path";
24790
24061
 
24791
24062
  // src/lib/version-refresh.ts
24792
24063
  init_version_cache();
@@ -24794,7 +24065,7 @@ init_skill_version();
24794
24065
  import { exec } from "child_process";
24795
24066
  var REFRESH_TIMEOUT_MS = 1e4;
24796
24067
  function refreshCliCache() {
24797
- return new Promise((resolve6) => {
24068
+ return new Promise((resolve5) => {
24798
24069
  exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
24799
24070
  if (!err) {
24800
24071
  const latest = stdout.trim();
@@ -24805,7 +24076,7 @@ function refreshCliCache() {
24805
24076
  }
24806
24077
  }
24807
24078
  }
24808
- resolve6();
24079
+ resolve5();
24809
24080
  });
24810
24081
  });
24811
24082
  }
@@ -24831,8 +24102,8 @@ async function refreshSkillCache() {
24831
24102
  }
24832
24103
  async function refreshAdminSkillCache() {
24833
24104
  let timer;
24834
- const deadline = new Promise((resolve6) => {
24835
- timer = setTimeout(resolve6, REFRESH_TIMEOUT_MS);
24105
+ const deadline = new Promise((resolve5) => {
24106
+ timer = setTimeout(resolve5, REFRESH_TIMEOUT_MS);
24836
24107
  });
24837
24108
  await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
24838
24109
  })]);
@@ -24942,7 +24213,7 @@ Run \`wayai admin skill install\` to update.`);
24942
24213
 
24943
24214
  // src/index.ts
24944
24215
  var __dirname = dirname9(fileURLToPath2(import.meta.url));
24945
- var pkg = JSON.parse(readFileSync21(join28(__dirname, "..", "package.json"), "utf-8"));
24216
+ var pkg = JSON.parse(readFileSync19(join27(__dirname, "..", "package.json"), "utf-8"));
24946
24217
  var [, , command, ...args] = process.argv;
24947
24218
  var isBackgroundRefresh = command === REFRESH_COMMAND;
24948
24219
  if (!isBackgroundRefresh) initSentry(command, pkg.version);
@@ -25121,11 +24392,6 @@ async function main() {
25121
24392
  await listCommand2(args);
25122
24393
  break;
25123
24394
  }
25124
- case "template": {
25125
- const { templateCommand: templateCommand2 } = await Promise.resolve().then(() => (init_templates(), templates_exports));
25126
- await templateCommand2(args);
25127
- break;
25128
- }
25129
24395
  case "admin": {
25130
24396
  const { adminCommand: adminCommand2 } = await Promise.resolve().then(() => (init_admin(), admin_exports));
25131
24397
  await adminCommand2(args);
@@ -25201,8 +24467,6 @@ Commands:
25201
24467
  sync-skills Sync skills to Anthropic/OpenAI provider connections
25202
24468
  sync-mcp Re-discover an MCP connection's tools (refresh stale schemas)
25203
24469
  list List organizations and hubs
25204
- template list List ready-made hub templates
25205
- template pull Write a template's WayAI slice into wayai-ws/hubs/<slug>/
25206
24470
  report create Report a platform bug (submits to the triage queue)
25207
24471
  report edit Amend your own pending report (title/description/error/steps/context)
25208
24472
  update Update CLI to the latest version