@wayai/cli 0.3.63 → 0.3.65

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
@@ -5255,7 +5255,7 @@ function findStepBoundaries(transcript) {
5255
5255
  }
5256
5256
  return out;
5257
5257
  }
5258
- var APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, uuidSchema, paginationSchema, timestampSchema, idParamSchema, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, 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, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, 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, 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, analyticsSqlSchemaQuery, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, createJourneyBody, updateJourneyBody, getConversationsQuery, getMessagesQuery, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, sendMessageBody, listConversationsQuery, getConversationDetailParams, getConversationDetailQuery, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, completionsBody, 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, uuidPattern, ciUuidSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysQuery, dataExplorerKvKeyParam, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteQuery, 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, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, sentryRefStatusSchema, createReportBody, editReportBody, 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, templateTextSchema, templateHttpUrl, templateRekorPointerSchema, templateYamlLocaleEntry, templateYamlWayaiBlock, templateYamlRekorBlock, templateTagsSchema, templateYamlSchema, templateHeroSchema, templatePushLocaleSchema, templatePushBody, templateListQuery, templateSlugParam, templateDetailQuery, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam, WAYAI_WORKSPACE_LAYOUT, MAX_RESOURCE_FILE_SIZE;
5258
+ var APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, uuidSchema, paginationSchema, timestampSchema, idParamSchema, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, 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, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, 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, 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, analyticsSqlSchemaQuery, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, createEvalBody, updateEvalBody, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, createJourneyBody, updateJourneyBody, getConversationsQuery, getMessagesQuery, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, sendMessageBody, listConversationsQuery, getConversationDetailParams, getConversationDetailQuery, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, downloadBody, uploadQuery, signUrlBody, completionsBody, 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, uuidPattern, ciUuidSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysQuery, dataExplorerKvKeyParam, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteQuery, 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, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, sentryRefStatusSchema, createReportBody, editReportBody, 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, templateTextSchema, templateUsesEntrySchema, templateUsesSchema, templateYamlLocaleEntry, templateYamlWayaiBlock, templateTagsSchema, templateYamlSchema, templateHeroSchema, templatePushLocaleSchema, templatePushBody, templateListQuery, templateSlugParam, templateDetailQuery, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam, WAYAI_WORKSPACE_LAYOUT, MAX_RESOURCE_FILE_SIZE;
5259
5259
  var init_dist = __esm({
5260
5260
  "../../packages/core/dist/index.js"() {
5261
5261
  "use strict";
@@ -7694,19 +7694,16 @@ var init_dist = __esm({
7694
7694
  metaTitle: external_exports.string().min(1).max(200),
7695
7695
  metaDescription: external_exports.string().max(1e3).default("")
7696
7696
  });
7697
- templateHttpUrl = external_exports.string().url().refine((u) => /^https?:\/\//i.test(u), { message: "must be an http(s) URL" });
7698
- templateRekorPointerSchema = external_exports.object({
7699
- mcpEndpoint: templateHttpUrl.optional(),
7700
- url: templateHttpUrl.optional()
7697
+ templateUsesEntrySchema = external_exports.object({
7698
+ backend: templateSlugSchema,
7699
+ endpoint: templateSlugSchema
7701
7700
  });
7701
+ templateUsesSchema = external_exports.array(templateUsesEntrySchema).max(24).default([]);
7702
7702
  templateYamlLocaleEntry = templateTextSchema.extend({ source: external_exports.string().min(1) });
7703
7703
  templateYamlWayaiBlock = external_exports.object({
7704
7704
  installCommand: external_exports.string().min(1).max(300),
7705
7705
  locales: external_exports.record(templateLocaleSchema, templateYamlLocaleEntry)
7706
7706
  });
7707
- templateYamlRekorBlock = templateRekorPointerSchema.extend({
7708
- locales: external_exports.record(templateLocaleSchema, templateYamlLocaleEntry)
7709
- });
7710
7707
  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))]);
7711
7708
  templateYamlSchema = external_exports.object({
7712
7709
  slug: templateSlugSchema,
@@ -7717,21 +7714,14 @@ var init_dist = __esm({
7717
7714
  defaultLocale: templateLocaleSchema,
7718
7715
  hero: external_exports.string().optional(),
7719
7716
  // relative path to a hero image inside the template folder
7720
- // The Rekor MCP Factory endpoint this template stands up (locale-agnostic).
7721
- // Authored at the TOP LEVEL so one shared `template.yaml` satisfies both
7722
- // `wayai admin template push` (here) and `rekor admin template push` (which reads
7723
- // it flat). Mirrored onto the wire as `common.rekorPointer.mcpEndpoint`. The
7724
- // deprecated `rekor.mcpEndpoint` nesting is still honored as a fallback always
7725
- // read via `resolveTemplateMcpEndpoint`, never one location directly.
7726
- mcpEndpoint: templateHttpUrl.optional(),
7727
- wayai: templateYamlWayaiBlock.optional(),
7728
- rekor: templateYamlRekorBlock.optional()
7729
- }).refine((c) => Boolean(c.wayai) || Boolean(c.rekor), {
7730
- message: "template.yaml must define at least one of `wayai:` or `rekor:`"
7731
- }).refine((c) => !c.wayai || Boolean(c.wayai.locales[c.defaultLocale]), {
7717
+ // The Rekor backend(s) this channel runs on (gh #2955). Locale-agnostic. The
7718
+ // cross-link + MCP endpoint are derived from each entry's slugs, never authored.
7719
+ uses: templateUsesSchema,
7720
+ // A WayAI template IS a WayAI channel — the wayai slice is required. (The old
7721
+ // Rekor-only store entry is gone: a pure Rekor backend lives only in Rekor's store.)
7722
+ wayai: templateYamlWayaiBlock
7723
+ }).refine((c) => Boolean(c.wayai.locales[c.defaultLocale]), {
7732
7724
  message: "`wayai.locales` must include the defaultLocale"
7733
- }).refine((c) => !c.rekor || Boolean(c.rekor.locales[c.defaultLocale]), {
7734
- message: "`rekor.locales` must include the defaultLocale"
7735
7725
  });
7736
7726
  templateHeroSchema = external_exports.object({
7737
7727
  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)"),
@@ -7739,7 +7729,6 @@ var init_dist = __esm({
7739
7729
  });
7740
7730
  templatePushLocaleSchema = external_exports.object({
7741
7731
  wayai: templateTextSchema.optional(),
7742
- rekorText: templateTextSchema.optional(),
7743
7732
  readmeMarkdown: external_exports.string().default(""),
7744
7733
  wayaiFiles: templateFileMapSchema.optional()
7745
7734
  });
@@ -7751,11 +7740,12 @@ var init_dist = __esm({
7751
7740
  tags: templateTagsSchema,
7752
7741
  status: templateStatusSchema,
7753
7742
  order: external_exports.number().int().min(0).max(1e5).default(0),
7754
- // The WayAI install command present iff the template has a wayai side; a
7755
- // Rekor-only template omits it.
7743
+ // The WayAI install command (a WayAI template always has a wayai side). Kept
7744
+ // optional on the wire so a malformed manifest 400s on the field, not the body.
7756
7745
  installCommand: external_exports.string().min(1).max(300).optional(),
7757
7746
  hero: templateHeroSchema.optional(),
7758
- rekorPointer: templateRekorPointerSchema.optional()
7747
+ // The channel→backend edge (gh #2955), locale-agnostic.
7748
+ uses: templateUsesSchema
7759
7749
  }),
7760
7750
  locales: external_exports.record(templateLocaleSchema, templatePushLocaleSchema)
7761
7751
  }).refine((b) => Boolean(b.locales[b.defaultLocale]), {
@@ -7819,6 +7809,9 @@ function resolveLayout(gitRoot, layout = WAYAI_LAYOUT) {
7819
7809
  legacyAlsoPresent: false
7820
7810
  };
7821
7811
  }
7812
+ function resolveHubsDir(gitRoot) {
7813
+ return resolveLayout(gitRoot).hubsDir;
7814
+ }
7822
7815
  function resolveTemplatesDir(gitRoot) {
7823
7816
  return path.join(gitRoot, TEMPLATES_AUTHORING_SUBDIR);
7824
7817
  }
@@ -7856,7 +7849,7 @@ var init_layout = __esm({
7856
7849
  ...WAYAI_WORKSPACE_LAYOUT,
7857
7850
  legacy: { wsDir: "workspace", orgAtRoot: "org" }
7858
7851
  };
7859
- TEMPLATES_AUTHORING_SUBDIR = "templates";
7852
+ TEMPLATES_AUTHORING_SUBDIR = "wayai-templates";
7860
7853
  _layoutWarned = false;
7861
7854
  }
7862
7855
  });
@@ -7968,6 +7961,16 @@ function findHubByFolderName(workspaceDir, hubFolderName) {
7968
7961
  const all = scanWorkspaceHubs(workspaceDir);
7969
7962
  return all.find((h) => path2.basename(h.hubFolder) === hubFolderName) ?? null;
7970
7963
  }
7964
+ function resolveHubFolderBySelector(hubsDir, selector) {
7965
+ const asPath = path2.resolve(selector);
7966
+ if (isDirectory(asPath) && fs2.existsSync(path2.join(asPath, "hub.yaml"))) return asPath;
7967
+ if (UUID_RE.test(selector)) {
7968
+ const match = scanWorkspaceHubs(hubsDir).find((h) => h.hubId === selector);
7969
+ return match ? match.hubFolder : null;
7970
+ }
7971
+ const byName = findHubByFolderName(hubsDir, selector);
7972
+ return byName ? byName.hubFolder : null;
7973
+ }
7971
7974
  function autoRenameHubFolder(currentFolder, hubName, hubEnvironment, hubId, previewLabel, branchName) {
7972
7975
  const expectedSlug = getHubFolderSlug(hubName, hubEnvironment, hubId, previewLabel, branchName);
7973
7976
  const currentSlug = path2.basename(currentFolder);
@@ -13288,10 +13291,37 @@ function isSafeTemplatePath2(path22) {
13288
13291
  (seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg)
13289
13292
  );
13290
13293
  }
13291
- function resolveTemplateMcpEndpoint(manifest) {
13292
- return manifest.mcpEndpoint ?? manifest.rekor?.mcpEndpoint;
13294
+ function dropTemplateKeys(value, drop) {
13295
+ if (Array.isArray(value)) return value.map((v) => dropTemplateKeys(v, drop));
13296
+ if (isPlainObject(value)) {
13297
+ const out = {};
13298
+ for (const [key, child] of Object.entries(value)) {
13299
+ if (drop.has(key)) continue;
13300
+ out[key] = TEMPLATE_OPAQUE_BLOB_KEYS.has(key) ? child : dropTemplateKeys(child, drop);
13301
+ }
13302
+ return out;
13303
+ }
13304
+ return value;
13305
+ }
13306
+ function stripTemplateInstanceIds(value) {
13307
+ return dropTemplateKeys(value, TEMPLATE_INSTANCE_ID_KEYS);
13293
13308
  }
13294
- var uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, AUTH_TYPE2, ORG_CREDENTIAL_AUTH_TYPES2, AUTH_TYPE_DISPLAY2, LEGACY_AUTH_TYPE_MAP2, VALID_AUTH_TYPES2, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, 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, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, 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, 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, analyticsSqlSchemaQuery2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, createEvalBody2, updateEvalBody2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, createJourneyBody2, updateJourneyBody2, getConversationsQuery2, getMessagesQuery2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, sendMessageBody2, listConversationsQuery2, getConversationDetailParams2, getConversationDetailQuery2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, downloadBody2, uploadQuery2, signUrlBody2, completionsBody2, 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, uuidPattern2, ciUuidSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysQuery2, dataExplorerKvKeyParam2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteQuery2, 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, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, 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, templateHttpUrl2, templateRekorPointerSchema2, templateYamlLocaleEntry2, templateYamlWayaiBlock2, templateYamlRekorBlock2, templateTagsSchema2, templateYamlSchema2, templateHeroSchema2, templatePushLocaleSchema2, templatePushBody2, templateListQuery2, templateSlugParam2, templateDetailQuery2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2;
13309
+ function excludeTemplateAuthorData(value) {
13310
+ return dropTemplateKeys(value, TEMPLATE_AUTHOR_DATA_KEYS);
13311
+ }
13312
+ function isPlainObject(value) {
13313
+ if (value === null || typeof value !== "object") return false;
13314
+ const proto = Object.getPrototypeOf(value);
13315
+ return proto === Object.prototype || proto === null;
13316
+ }
13317
+ function isSanitizableSliceFile(path22) {
13318
+ if (!/\.ya?ml$/i.test(path22)) return false;
13319
+ return path22 !== "resources" && !path22.startsWith("resources/");
13320
+ }
13321
+ function distinctUsesBackends(uses) {
13322
+ return [...new Set((uses ?? []).map((u) => u.backend))];
13323
+ }
13324
+ var uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, AUTH_TYPE2, ORG_CREDENTIAL_AUTH_TYPES2, AUTH_TYPE_DISPLAY2, LEGACY_AUTH_TYPE_MAP2, VALID_AUTH_TYPES2, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, 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, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, 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, 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, analyticsSqlSchemaQuery2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, createEvalBody2, updateEvalBody2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, createJourneyBody2, updateJourneyBody2, getConversationsQuery2, getMessagesQuery2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, sendMessageBody2, listConversationsQuery2, getConversationDetailParams2, getConversationDetailQuery2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, downloadBody2, uploadQuery2, signUrlBody2, completionsBody2, 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, uuidPattern2, ciUuidSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysQuery2, dataExplorerKvKeyParam2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteQuery2, 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, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, 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, TEMPLATE_INSTANCE_ID_KEYS, TEMPLATE_OPAQUE_BLOB_KEYS, TEMPLATE_AUTHOR_DATA_KEYS, templateTextSchema2, templateUsesEntrySchema2, templateUsesSchema2, templateYamlLocaleEntry2, templateYamlWayaiBlock2, templateTagsSchema2, templateYamlSchema2, templateHeroSchema2, templatePushLocaleSchema2, templatePushBody2, templateListQuery2, templateSlugParam2, templateDetailQuery2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2;
13295
13325
  var init_contracts = __esm({
13296
13326
  "../../packages/core/dist/contracts/index.js"() {
13297
13327
  "use strict";
@@ -15642,23 +15672,78 @@ var init_contracts = __esm({
15642
15672
  templateFileMapSchema2 = external_exports.record(external_exports.string()).refine((m) => Object.keys(m).every(isSafeTemplatePath2), {
15643
15673
  message: 'file map contains an unsafe path (no absolute paths, "..", or backslashes)'
15644
15674
  });
15675
+ TEMPLATE_INSTANCE_ID_KEYS = /* @__PURE__ */ new Set([
15676
+ // Top-level hub instance metadata (hub.yaml) — set by `wayai pull`, never authored.
15677
+ "hub_id",
15678
+ "hub_environment",
15679
+ "preview_label",
15680
+ "branch_name",
15681
+ // Per-entity row id + cross-entity reference UUIDs (each has a portable name twin).
15682
+ "id",
15683
+ "connection_id",
15684
+ "target_id",
15685
+ "agent_id",
15686
+ "resource_id",
15687
+ "list_id",
15688
+ // Account-scoped Meta WhatsApp template id (name twin: `template_whatsapp`).
15689
+ "template_whatsapp_id"
15690
+ ]);
15691
+ TEMPLATE_OPAQUE_BLOB_KEYS = /* @__PURE__ */ new Set([
15692
+ "settings",
15693
+ // agent + connection connector settings
15694
+ "schema_json",
15695
+ // agent response_format JSON Schema
15696
+ "json_schema",
15697
+ // state JSON Schema
15698
+ "initial_value",
15699
+ // state seed value
15700
+ "additional_context_schema",
15701
+ // kanban-status transition-form schema
15702
+ "config",
15703
+ // custom-tool OpenAI function schema
15704
+ "headers",
15705
+ "query_params",
15706
+ "body_params",
15707
+ // custom-tool HTTP shaping
15708
+ "mappings",
15709
+ // composed-tool argument mappings
15710
+ "input",
15711
+ "expected",
15712
+ "history",
15713
+ // eval message fixtures (tool_calls carry their own `id`)
15714
+ "transcript",
15715
+ "step_config"
15716
+ // journey fixtures (transcript carries `step_id`; step_config is keyed by it)
15717
+ ]);
15718
+ TEMPLATE_AUTHOR_DATA_KEYS = /* @__PURE__ */ new Set([
15719
+ // Outbound campaign subsystem (hub.yaml top-level). `outbound_contacts` is the
15720
+ // author's real leads — `phone`/`email`/`instagram_sid` + the required `name` are
15721
+ // GDPR-grade PII. `outbound_lists` group those contacts by real name. `outbound_schedules`
15722
+ // bind to the (now-absent) lists and carry the author's campaign cadence + message
15723
+ // copy — operationally tied to the author's customers; a consumer builds their own.
15724
+ "outbound_contacts",
15725
+ "outbound_lists",
15726
+ "outbound_schedules",
15727
+ // Account-scoped channel identifier on a connection (Twilio SID / WhatsApp number /
15728
+ // IG username / from-email, per connector). The connection stays as portable
15729
+ // structure re-bound by name on push; this author-account value carries no blueprint
15730
+ // value. A dedicated top-level column — never nested in the `settings` opaque blob.
15731
+ "account_sid"
15732
+ ]);
15645
15733
  templateTextSchema2 = external_exports.object({
15646
15734
  metaTitle: external_exports.string().min(1).max(200),
15647
15735
  metaDescription: external_exports.string().max(1e3).default("")
15648
15736
  });
15649
- templateHttpUrl2 = external_exports.string().url().refine((u) => /^https?:\/\//i.test(u), { message: "must be an http(s) URL" });
15650
- templateRekorPointerSchema2 = external_exports.object({
15651
- mcpEndpoint: templateHttpUrl2.optional(),
15652
- url: templateHttpUrl2.optional()
15737
+ templateUsesEntrySchema2 = external_exports.object({
15738
+ backend: templateSlugSchema2,
15739
+ endpoint: templateSlugSchema2
15653
15740
  });
15741
+ templateUsesSchema2 = external_exports.array(templateUsesEntrySchema2).max(24).default([]);
15654
15742
  templateYamlLocaleEntry2 = templateTextSchema2.extend({ source: external_exports.string().min(1) });
15655
15743
  templateYamlWayaiBlock2 = external_exports.object({
15656
15744
  installCommand: external_exports.string().min(1).max(300),
15657
15745
  locales: external_exports.record(templateLocaleSchema2, templateYamlLocaleEntry2)
15658
15746
  });
15659
- templateYamlRekorBlock2 = templateRekorPointerSchema2.extend({
15660
- locales: external_exports.record(templateLocaleSchema2, templateYamlLocaleEntry2)
15661
- });
15662
15747
  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))]);
15663
15748
  templateYamlSchema2 = external_exports.object({
15664
15749
  slug: templateSlugSchema2,
@@ -15669,21 +15754,14 @@ var init_contracts = __esm({
15669
15754
  defaultLocale: templateLocaleSchema2,
15670
15755
  hero: external_exports.string().optional(),
15671
15756
  // relative path to a hero image inside the template folder
15672
- // The Rekor MCP Factory endpoint this template stands up (locale-agnostic).
15673
- // Authored at the TOP LEVEL so one shared `template.yaml` satisfies both
15674
- // `wayai admin template push` (here) and `rekor admin template push` (which reads
15675
- // it flat). Mirrored onto the wire as `common.rekorPointer.mcpEndpoint`. The
15676
- // deprecated `rekor.mcpEndpoint` nesting is still honored as a fallback always
15677
- // read via `resolveTemplateMcpEndpoint`, never one location directly.
15678
- mcpEndpoint: templateHttpUrl2.optional(),
15679
- wayai: templateYamlWayaiBlock2.optional(),
15680
- rekor: templateYamlRekorBlock2.optional()
15681
- }).refine((c) => Boolean(c.wayai) || Boolean(c.rekor), {
15682
- message: "template.yaml must define at least one of `wayai:` or `rekor:`"
15683
- }).refine((c) => !c.wayai || Boolean(c.wayai.locales[c.defaultLocale]), {
15757
+ // The Rekor backend(s) this channel runs on (gh #2955). Locale-agnostic. The
15758
+ // cross-link + MCP endpoint are derived from each entry's slugs, never authored.
15759
+ uses: templateUsesSchema2,
15760
+ // A WayAI template IS a WayAI channel — the wayai slice is required. (The old
15761
+ // Rekor-only store entry is gone: a pure Rekor backend lives only in Rekor's store.)
15762
+ wayai: templateYamlWayaiBlock2
15763
+ }).refine((c) => Boolean(c.wayai.locales[c.defaultLocale]), {
15684
15764
  message: "`wayai.locales` must include the defaultLocale"
15685
- }).refine((c) => !c.rekor || Boolean(c.rekor.locales[c.defaultLocale]), {
15686
- message: "`rekor.locales` must include the defaultLocale"
15687
15765
  });
15688
15766
  templateHeroSchema2 = external_exports.object({
15689
15767
  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)"),
@@ -15691,7 +15769,6 @@ var init_contracts = __esm({
15691
15769
  });
15692
15770
  templatePushLocaleSchema2 = external_exports.object({
15693
15771
  wayai: templateTextSchema2.optional(),
15694
- rekorText: templateTextSchema2.optional(),
15695
15772
  readmeMarkdown: external_exports.string().default(""),
15696
15773
  wayaiFiles: templateFileMapSchema2.optional()
15697
15774
  });
@@ -15703,11 +15780,12 @@ var init_contracts = __esm({
15703
15780
  tags: templateTagsSchema2,
15704
15781
  status: templateStatusSchema2,
15705
15782
  order: external_exports.number().int().min(0).max(1e5).default(0),
15706
- // The WayAI install command present iff the template has a wayai side; a
15707
- // Rekor-only template omits it.
15783
+ // The WayAI install command (a WayAI template always has a wayai side). Kept
15784
+ // optional on the wire so a malformed manifest 400s on the field, not the body.
15708
15785
  installCommand: external_exports.string().min(1).max(300).optional(),
15709
15786
  hero: templateHeroSchema2.optional(),
15710
- rekorPointer: templateRekorPointerSchema2.optional()
15787
+ // The channel→backend edge (gh #2955), locale-agnostic.
15788
+ uses: templateUsesSchema2
15711
15789
  }),
15712
15790
  locales: external_exports.record(templateLocaleSchema2, templatePushLocaleSchema2)
15713
15791
  }).refine((b) => Boolean(b.locales[b.defaultLocale]), {
@@ -16953,10 +17031,30 @@ function writeFileMap(targetDir, files) {
16953
17031
  }
16954
17032
  return written;
16955
17033
  }
17034
+ function listDirRelFiles(dir) {
17035
+ const out = [];
17036
+ function walk(d, prefix) {
17037
+ for (const entry of fs16.readdirSync(d, { withFileTypes: true })) {
17038
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
17039
+ if (entry.isDirectory()) walk(path19.join(d, entry.name), rel);
17040
+ else if (entry.isFile()) out.push(rel);
17041
+ }
17042
+ }
17043
+ if (fs16.existsSync(dir)) walk(dir, "");
17044
+ return out;
17045
+ }
17046
+ function writeSliceSnapshot(targetDir, files) {
17047
+ const keep = new Set(Object.keys(files));
17048
+ const removed = listDirRelFiles(targetDir).filter((rel) => !keep.has(rel)).sort((a, b) => a.localeCompare(b));
17049
+ const written = writeFileMap(targetDir, files).sort((a, b) => a.localeCompare(b));
17050
+ if (fs16.existsSync(targetDir)) cleanOrphanFiles(targetDir, "", keep);
17051
+ return { written, removed };
17052
+ }
16956
17053
  var init_template_files = __esm({
16957
17054
  "src/lib/template-files.ts"() {
16958
17055
  "use strict";
16959
17056
  init_contracts();
17057
+ init_resource_files();
16960
17058
  }
16961
17059
  });
16962
17060
 
@@ -16987,10 +17085,10 @@ async function templateCommand(args2) {
16987
17085
  process.exit(1);
16988
17086
  }
16989
17087
  }
16990
- function includesLabel(includes) {
17088
+ function includesLabel(item) {
16991
17089
  const parts = [];
16992
- if (includes.wayai) parts.push("wayai agent");
16993
- if (includes.rekor) parts.push("rekor data layer");
17090
+ if (item.includes.wayai) parts.push("wayai agent");
17091
+ if (item.uses?.length) parts.push("rekor backend");
16994
17092
  return parts.length ? parts.join(" + ") : "(none)";
16995
17093
  }
16996
17094
  async function runTemplateList() {
@@ -17012,7 +17110,7 @@ async function runTemplateList() {
17012
17110
  const catWidth = Math.max(8, ...templates.map((t) => t.category.length));
17013
17111
  console.log(`${"SLUG".padEnd(slugWidth)} ${"CATEGORY".padEnd(catWidth)} INCLUDES`);
17014
17112
  for (const t of templates) {
17015
- console.log(`${t.slug.padEnd(slugWidth)} ${t.category.padEnd(catWidth)} ${includesLabel(t.includes)}`);
17113
+ console.log(`${t.slug.padEnd(slugWidth)} ${t.category.padEnd(catWidth)} ${includesLabel(t)}`);
17016
17114
  }
17017
17115
  }
17018
17116
  async function runTemplatePull(rest) {
@@ -17076,7 +17174,9 @@ async function runTemplatePull(rest) {
17076
17174
  console.log(`Note: "${detail.requestedLocale}" not translated yet \u2014 pulled "${detail.resolvedLocale}" instead.`);
17077
17175
  }
17078
17176
  if (!detail.includes.wayai) {
17079
- console.log(`Template "${slug}" has no WayAI slice \u2014 run \`rekor template pull ${slug}${langFlag(lang)}\` for its data layer.`);
17177
+ const backends2 = distinctUsesBackends(detail.uses);
17178
+ const hint = backends2.length ? ` \u2014 run ${backends2.map((b) => `\`rekor template pull ${b}${langFlag(lang)}\``).join(" and ")} for its data layer.` : ".";
17179
+ console.log(`Template "${slug}" has no WayAI slice${hint}`);
17080
17180
  return;
17081
17181
  }
17082
17182
  const targetDir = path20.join(resolveLayout(gitRoot).hubsDir, slug);
@@ -17106,9 +17206,13 @@ Commit or move your changes and re-run with --force to overwrite, or pull into a
17106
17206
  const written = writeFileMap(targetDir, detail.files);
17107
17207
  console.log(`Pulled template "${slug}" \u2192 ${relTarget}/ (${written.length} file${written.length === 1 ? "" : "s"}).`);
17108
17208
  console.log(`Next: \`wayai push\` to deploy it into your own hub.`);
17109
- if (detail.includes.rekor) {
17209
+ const backends = distinctUsesBackends(detail.uses);
17210
+ if (backends.length) {
17211
+ const cmds = backends.map((b) => `\`rekor template pull ${b}${langFlag(lang)}\``).join(" and ");
17212
+ const noun = backends.length === 1 ? "a Rekor backend" : "Rekor backends";
17213
+ const obj = backends.length === 1 ? "it" : "them";
17110
17214
  console.log(`
17111
- This template includes a Rekor data layer \u2014 run \`rekor template pull ${slug}${langFlag(lang)}\` to add it.`);
17215
+ This channel runs on ${noun} \u2014 run ${cmds} to add ${obj}.`);
17112
17216
  }
17113
17217
  }
17114
17218
  function langFlag(lang) {
@@ -17197,34 +17301,51 @@ var init_report_edit_args = __esm({
17197
17301
  }
17198
17302
  });
17199
17303
 
17304
+ // src/lib/template-sanitize.ts
17305
+ import * as yaml9 from "js-yaml";
17306
+ function sanitizeWayaiSliceFiles(files) {
17307
+ const out = {};
17308
+ for (const [filePath, body] of Object.entries(files)) {
17309
+ out[filePath] = isSanitizableSliceFile(filePath) ? sanitizeOne(body) : body;
17310
+ }
17311
+ return out;
17312
+ }
17313
+ function sanitizeOne(body) {
17314
+ let parsed;
17315
+ try {
17316
+ parsed = yaml9.load(body);
17317
+ } catch {
17318
+ return body;
17319
+ }
17320
+ const scrubbed = excludeTemplateAuthorData(stripTemplateInstanceIds(parsed));
17321
+ if (JSON.stringify(parsed) === JSON.stringify(scrubbed)) return body;
17322
+ return yaml9.dump(scrubbed, YAML_DUMP_OPTIONS);
17323
+ }
17324
+ var init_template_sanitize = __esm({
17325
+ "src/lib/template-sanitize.ts"() {
17326
+ "use strict";
17327
+ init_contracts();
17328
+ init_yaml_writer();
17329
+ }
17330
+ });
17331
+
17200
17332
  // src/lib/template-manifest.ts
17201
17333
  function buildTemplatePushCommon(manifest, hero) {
17202
- const mcpEndpoint = resolveTemplateMcpEndpoint(manifest);
17203
17334
  return {
17204
17335
  category: manifest.category,
17205
17336
  tags: manifest.tags,
17206
17337
  status: manifest.status,
17207
17338
  order: manifest.order ?? 0,
17208
- // The install command is the wayai one (locale-agnostic). OMIT it for a Rekor-only
17209
- // template — the contract requires installCommand be non-empty when present, so
17210
- // sending '' would 400 the whole push.
17211
- ...manifest.wayai?.installCommand && { installCommand: manifest.wayai.installCommand },
17339
+ installCommand: manifest.wayai.installCommand,
17212
17340
  ...hero && { hero },
17213
- // The rekor pointer carries the (locale-agnostic) mcpEndpoint + cross-link url. Only
17214
- // emitted alongside a `rekor:` block the store gates the endpoint behind per-locale
17215
- // rekorText, so a block-less endpoint would be dead data (the command warns on it).
17216
- ...manifest.rekor && (mcpEndpoint || manifest.rekor.url) && {
17217
- rekorPointer: {
17218
- ...mcpEndpoint && { mcpEndpoint },
17219
- ...manifest.rekor.url && { url: manifest.rekor.url }
17220
- }
17221
- }
17341
+ // The channel→backend edge (locale-agnostic). The store persists it verbatim; the
17342
+ // website derives the "runs on backend X" cross-link + MCP endpoint from the slugs.
17343
+ uses: manifest.uses
17222
17344
  };
17223
17345
  }
17224
17346
  var init_template_manifest = __esm({
17225
17347
  "src/lib/template-manifest.ts"() {
17226
17348
  "use strict";
17227
- init_contracts();
17228
17349
  }
17229
17350
  });
17230
17351
 
@@ -17235,7 +17356,7 @@ __export(admin_exports, {
17235
17356
  });
17236
17357
  import * as fs17 from "fs";
17237
17358
  import * as path21 from "path";
17238
- import * as yaml9 from "js-yaml";
17359
+ import * as yaml10 from "js-yaml";
17239
17360
  async function adminCommand(args2) {
17240
17361
  const [group, ...afterGroup] = args2;
17241
17362
  if (!group) {
@@ -17361,6 +17482,9 @@ async function adminCommand(args2) {
17361
17482
  case "pull":
17362
17483
  await runTemplatePull2(positional, flagArgs);
17363
17484
  return;
17485
+ case "freeze":
17486
+ await runTemplateFreeze(positional, flagArgs);
17487
+ return;
17364
17488
  default:
17365
17489
  printHelp2();
17366
17490
  process.exit(1);
@@ -17604,16 +17728,7 @@ function parseFlags2(flagArgs, allowed) {
17604
17728
  }
17605
17729
  return out;
17606
17730
  }
17607
- async function runTemplatePush(positional) {
17608
- const slug = positional[0];
17609
- if (!slug) {
17610
- console.error("wayai admin template push <slug>");
17611
- process.exit(1);
17612
- }
17613
- if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
17614
- console.error(`Invalid template slug: ${slug}`);
17615
- process.exit(1);
17616
- }
17731
+ function loadTemplateManifest(slug) {
17617
17732
  const gitRoot = findGitRoot();
17618
17733
  if (!gitRoot) {
17619
17734
  console.error("Not in a git repository. Run from the tutorials/ authoring repo.");
@@ -17627,7 +17742,7 @@ async function runTemplatePush(positional) {
17627
17742
  }
17628
17743
  let manifest;
17629
17744
  try {
17630
- manifest = templateYamlSchema2.parse(yaml9.load(fs17.readFileSync(manifestPath, "utf-8")));
17745
+ manifest = templateYamlSchema2.parse(yaml10.load(fs17.readFileSync(manifestPath, "utf-8")));
17631
17746
  } catch (err) {
17632
17747
  console.error(`Invalid template.yaml: ${err instanceof Error ? err.message : String(err)}`);
17633
17748
  process.exit(1);
@@ -17636,14 +17751,25 @@ async function runTemplatePush(positional) {
17636
17751
  console.error(`template.yaml slug "${manifest.slug}" does not match folder "${slug}".`);
17637
17752
  process.exit(1);
17638
17753
  }
17639
- const authoredLocales = /* @__PURE__ */ new Set([
17640
- ...manifest.wayai ? Object.keys(manifest.wayai.locales) : [],
17641
- ...manifest.rekor ? Object.keys(manifest.rekor.locales) : []
17642
- ]);
17754
+ return { gitRoot, templateDir, manifest };
17755
+ }
17756
+ async function runTemplatePush(positional) {
17757
+ const slug = positional[0];
17758
+ if (!slug) {
17759
+ console.error("wayai admin template push <slug>");
17760
+ process.exit(1);
17761
+ }
17762
+ if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
17763
+ console.error(`Invalid template slug: ${slug}`);
17764
+ process.exit(1);
17765
+ }
17766
+ const { templateDir, manifest } = loadTemplateManifest(slug);
17767
+ const authoredLocales = new Set(
17768
+ Object.keys(manifest.wayai.locales)
17769
+ );
17643
17770
  const locales = {};
17644
17771
  for (const locale of authoredLocales) {
17645
- const wayaiEntry = manifest.wayai?.locales[locale];
17646
- const rekorEntry = manifest.rekor?.locales[locale];
17772
+ const wayaiEntry = manifest.wayai.locales[locale];
17647
17773
  let wayaiFiles;
17648
17774
  if (wayaiEntry) {
17649
17775
  const sliceDir = path21.resolve(templateDir, wayaiEntry.source);
@@ -17651,6 +17777,11 @@ async function runTemplatePush(positional) {
17651
17777
  console.error(`wayai source not found for ${locale}: ${wayaiEntry.source} (resolved ${sliceDir})`);
17652
17778
  process.exit(1);
17653
17779
  }
17780
+ if (!isInsideTemplateDir(sliceDir, templateDir)) {
17781
+ console.warn(
17782
+ `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 ${path21.basename(sliceDir)}\` to commit a stable frozen slice.`
17783
+ );
17784
+ }
17654
17785
  wayaiFiles = readDirToFileMap(sliceDir);
17655
17786
  }
17656
17787
  const readmePath = path21.join(templateDir, `README.${locale}.md`);
@@ -17660,9 +17791,6 @@ async function runTemplatePush(positional) {
17660
17791
  ...wayaiFiles && { wayaiFiles },
17661
17792
  ...wayaiEntry && {
17662
17793
  wayai: { metaTitle: wayaiEntry.metaTitle, metaDescription: wayaiEntry.metaDescription }
17663
- },
17664
- ...rekorEntry && {
17665
- rekorText: { metaTitle: rekorEntry.metaTitle, metaDescription: rekorEntry.metaDescription }
17666
17794
  }
17667
17795
  };
17668
17796
  }
@@ -17675,12 +17803,6 @@ async function runTemplatePush(positional) {
17675
17803
  console.error(`Warning: hero not found at ${manifest.hero}; skipping.`);
17676
17804
  }
17677
17805
  }
17678
- const mcpEndpoint = resolveTemplateMcpEndpoint(manifest);
17679
- if (mcpEndpoint && !manifest.rekor) {
17680
- console.error(
17681
- "Warning: `mcpEndpoint` is set but there is no `rekor:` block to attach it to \u2014 it will be ignored. Add a `rekor:` block (the cross-link to the paired template) or remove `mcpEndpoint`."
17682
- );
17683
- }
17684
17806
  const body = {
17685
17807
  slug,
17686
17808
  defaultLocale: manifest.defaultLocale,
@@ -17701,6 +17823,119 @@ async function runTemplatePush(positional) {
17701
17823
  console.log(`(status=${manifest.status} \u2192 unpublished from the store)`);
17702
17824
  }
17703
17825
  }
17826
+ function isInsideTemplateDir(dest, templateDir) {
17827
+ return dest === templateDir || dest.startsWith(templateDir + path21.sep);
17828
+ }
17829
+ async function runTemplateFreeze(positional, flagArgs) {
17830
+ const slug = positional[0];
17831
+ if (!slug) {
17832
+ console.error("wayai admin template freeze <slug> [--locale <l>] [--from <hub>] [--dry-run]");
17833
+ process.exit(1);
17834
+ }
17835
+ if (!TEMPLATE_SLUG_REGEX2.test(slug)) {
17836
+ console.error(`Invalid template slug: ${slug}`);
17837
+ process.exit(1);
17838
+ }
17839
+ let locale;
17840
+ let from;
17841
+ let dryRun = false;
17842
+ for (let i = 0; i < flagArgs.length; i++) {
17843
+ if (flagArgs[i] === "--dry-run") {
17844
+ dryRun = true;
17845
+ continue;
17846
+ }
17847
+ if (flagArgs[i] === "--locale") {
17848
+ const v = flagArgs[++i];
17849
+ if (!v) {
17850
+ console.error("--locale requires a value");
17851
+ process.exit(1);
17852
+ }
17853
+ const parsed = templateLocaleSchema2.safeParse(v);
17854
+ if (!parsed.success) {
17855
+ console.error(`Invalid --locale "${v}": must be one of ${templateLocaleSchema2.options.join(", ")}.`);
17856
+ process.exit(1);
17857
+ }
17858
+ locale = parsed.data;
17859
+ continue;
17860
+ }
17861
+ if (flagArgs[i] === "--from") {
17862
+ from = flagArgs[++i];
17863
+ if (!from) {
17864
+ console.error("--from requires a value");
17865
+ process.exit(1);
17866
+ }
17867
+ continue;
17868
+ }
17869
+ console.error(`Unknown flag: ${flagArgs[i]}`);
17870
+ process.exit(1);
17871
+ }
17872
+ const { gitRoot, templateDir, manifest } = loadTemplateManifest(slug);
17873
+ const authored = Object.keys(manifest.wayai.locales);
17874
+ let targetLocale;
17875
+ if (locale) {
17876
+ if (!manifest.wayai.locales[locale]) {
17877
+ console.error(`Locale "${locale}" is not authored in ${slug}/template.yaml (have: ${authored.join(", ")}).`);
17878
+ process.exit(1);
17879
+ }
17880
+ targetLocale = locale;
17881
+ } else if (authored.length === 1) {
17882
+ targetLocale = authored[0];
17883
+ } else {
17884
+ console.error(`Template "${slug}" authors ${authored.length} locales (${authored.join(", ")}). Pass --locale <l> \u2014 each freezes from its own hub.`);
17885
+ process.exit(1);
17886
+ }
17887
+ const entry = manifest.wayai.locales[targetLocale];
17888
+ const dest = path21.resolve(templateDir, entry.source);
17889
+ if (!isInsideTemplateDir(dest, templateDir) || dest === templateDir) {
17890
+ console.error(
17891
+ `source for "${targetLocale}" must be a committed path inside ${slug}/ (e.g. "./${targetLocale}/slice"), but resolved to:
17892
+ ${entry.source} \u2192 ${dest}
17893
+ Set it to a subdir of the template folder and re-run freeze.`
17894
+ );
17895
+ process.exit(1);
17896
+ }
17897
+ const hubsDir = resolveHubsDir(gitRoot);
17898
+ const selector = from ?? readBinding();
17899
+ const hubFolder = selector ? resolveHubFolderBySelector(hubsDir, selector) : null;
17900
+ if (!hubFolder) {
17901
+ console.error(
17902
+ selector ? `Could not resolve a source hub matching "${selector}" in ${hubsDirLabel(gitRoot)}/.` : "No --from given and this worktree has no `wayai use` binding."
17903
+ );
17904
+ const hubs = scanWorkspaceHubs(hubsDir);
17905
+ if (hubs.length) {
17906
+ console.error("Available hubs:");
17907
+ for (const h of hubs) console.error(` ${path21.basename(h.hubFolder)} (${h.hubId})`);
17908
+ }
17909
+ console.error(`
17910
+ Pass --from <folder|uuid>${selector ? "." : " or run `wayai use <hub>` first."}`);
17911
+ process.exit(1);
17912
+ }
17913
+ const liveFiles = readDirToFileMap(hubFolder);
17914
+ if (Object.keys(liveFiles).length === 0) {
17915
+ console.error(`Source hub folder has no files to freeze: ${path21.relative(gitRoot, hubFolder)}`);
17916
+ process.exit(1);
17917
+ }
17918
+ const sanitized = sanitizeWayaiSliceFiles(liveFiles);
17919
+ const relDest = path21.relative(gitRoot, dest);
17920
+ const relSrc = path21.relative(gitRoot, hubFolder);
17921
+ if (dryRun) {
17922
+ const existing = new Set(listDirRelFiles(dest));
17923
+ const nextKeys = new Set(Object.keys(sanitized));
17924
+ console.log(`Dry run \u2014 would freeze ${relSrc}/ \u2192 ${relDest}/ (locale ${targetLocale}):`);
17925
+ for (const rel of Object.keys(sanitized).sort((a, b) => a.localeCompare(b))) {
17926
+ console.log(` ${existing.has(rel) ? "update" : "create"} ${rel}`);
17927
+ }
17928
+ for (const rel of [...existing].filter((k) => !nextKeys.has(k)).sort((a, b) => a.localeCompare(b))) {
17929
+ console.log(` remove ${rel}`);
17930
+ }
17931
+ return;
17932
+ }
17933
+ const { written, removed } = writeSliceSnapshot(dest, sanitized);
17934
+ console.log(
17935
+ `Froze ${relSrc}/ \u2192 ${relDest}/ (locale ${targetLocale}): ${written.length} file${written.length === 1 ? "" : "s"} written${removed.length ? `, ${removed.length} removed` : ""}.`
17936
+ );
17937
+ console.log(`The slice is committed \u2014 re-push is stable across hub recreates. Next: \`wayai admin template push ${slug}\`.`);
17938
+ }
17704
17939
  async function runTemplatePull2(positional, flagArgs) {
17705
17940
  const slug = positional[0];
17706
17941
  if (!slug) {
@@ -17745,7 +17980,9 @@ async function runTemplatePull2(positional, flagArgs) {
17745
17980
  const target = outDir ? path21.resolve(outDir) : path21.join(process.cwd(), "template-store-pull", slug);
17746
17981
  const written = writeFileMap(target, detail.files);
17747
17982
  console.log(`Pulled "${slug}" from the store \u2192 ${target} (${written.length} file${written.length === 1 ? "" : "s"}).`);
17748
- console.log(`includes: wayai=${detail.includes.wayai} rekor=${detail.includes.rekor}`);
17983
+ const uses = detail.uses ?? [];
17984
+ const usesLabel = uses.length ? uses.map((u) => `${u.backend}/${u.endpoint}`).join(", ") : "(none)";
17985
+ console.log(`includes: wayai=${detail.includes.wayai} | uses: ${usesLabel}`);
17749
17986
  }
17750
17987
  async function runSkillInstall(positional) {
17751
17988
  const name = positional[0] ?? "wayai-admin";
@@ -18185,8 +18422,10 @@ Usage:
18185
18422
  wayai admin notice list [--status active|resolved] [--limit N] [--offset N] [--json]
18186
18423
  wayai admin notice resolve <notice_id>
18187
18424
 
18188
- wayai admin template push <slug> Publish a template from tutorials/templates/<slug>/ into the store
18425
+ wayai admin template push <slug> Publish a template from wayai-templates/<slug>/ into the store
18189
18426
  wayai admin template pull <slug> [--out DIR] [--json] Pull a published template from the store for inspection
18427
+ wayai admin template freeze <slug> [--locale <l>] [--from <hub>] [--dry-run]
18428
+ Snapshot a live hub into the template's committed slice (id/PII-scrubbed)
18190
18429
 
18191
18430
  wayai admin skill install [name] Install a private operator skill (default: wayai-admin) into each present harness's skills/ dir
18192
18431
 
@@ -18248,9 +18487,11 @@ var init_admin = __esm({
18248
18487
  init_observability();
18249
18488
  init_report_edit_args();
18250
18489
  init_workspace();
18490
+ init_hub_binding();
18251
18491
  init_skill_version();
18252
18492
  init_layout();
18253
18493
  init_template_files();
18494
+ init_template_sanitize();
18254
18495
  init_template_manifest();
18255
18496
  init_contracts();
18256
18497
  VALID_TYPES = dataExplorerDebugDoType2.options;