@wayai/cli 0.3.151 → 0.3.153

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
@@ -5369,7 +5369,7 @@ function refineHubAsCodeDelegation(config, ctx) {
5369
5369
  });
5370
5370
  });
5371
5371
  }
5372
- 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, MAX_EVAL_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, ORG_TAG_NAME_REGEX, ORG_TAG_NAME_MAX_LENGTH, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, BASE_CREDENTIAL_MANAGED_BY, BASE_CREDENTIAL_NAME_MAX, baseCredentialNameSchema, createBaseCredentialLinkBody, baseCredentialLinkParams, baseCredentialLinkQuery, 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, EVAL_LIST_MAX_LIMIT, evalListLimit, 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, evalSessionListConfigSchema, evalSessionListItemSchema, 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, planKeySchema, billingStatusSchema, billingPlanTypeSchema, REKOR_ENTITLEMENT_CONTRACT_VERSION, entitlementProjectionSchema, rekorEntitlementRefreshMessageSchema, 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, PRICING_PLAN_ID_RE, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, adminScopedTargetBody, adminRepairLegacyOrgGrantsBody, adminRepairCompedPlansBody, 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, REKOR_ACTOR_TYPE_HEADER, REKOR_ACTOR_ID_HEADER, REKOR_ACTOR_LABEL_HEADER, REKOR_ACTOR_ORG_HEADER, REKOR_ACTOR_ADMIN_HEADER, REKOR_CLIENT_HEADER, REKOR_TOOL_ID_HEADER, REKOR_CLIENTS, rekorClientSchema, MAX_REKOR_TOOL_ID_LENGTH, rekorToolIdSchema, DATA_PROXY_MOUNT, DATA_PROXY_PREFIX, REKOR_V1_PREFIX, DATA_PROXY_ORG_QUERY_PARAM, MAX_PROVISIONING_BODY_BYTES, dataProxyQuery, rekorAttestation, REQUIRED_REKOR_ATTESTATION_HEADERS, BASE_DESTRUCTION_MOUNT, BASE_DESTRUCTION_PREFIX, BASE_DESTRUCTION_CONFIRM_PATH, baseDestructionConfirmBody, BASE_DESTRUCTION_GRACE_MS, BASE_DESTRUCTION_CONFIRM_TTL_MS, BASE_DESTRUCTION_ORG_QUERY_PARAM, baseDestructionQuery, baseDestructionParam, baseDestructionInitiateBody, baseDestructionStatus, baseDestructionRequest, baseDestructionListResponse, baseDestructionInitiateResponse, baseDestructionConfirmResponse, baseDestructionCancelResponse, rekorBaseChangeMessageSchema;
5372
+ 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, MAX_EVAL_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, ORG_TAG_NAME_REGEX, ORG_TAG_NAME_MAX_LENGTH, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, BASE_CREDENTIAL_MANAGED_BY, BASE_CREDENTIAL_NAME_MAX, baseCredentialNameSchema, createBaseCredentialLinkBody, baseCredentialLinkParams, baseCredentialLinkQuery, 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, EVAL_LIST_MAX_LIMIT, evalListLimit, 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, evalSessionListConfigSchema, evalSessionListItemSchema, 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, planKeySchema, billingStatusSchema, billingPlanTypeSchema, REKOR_ENTITLEMENT_CONTRACT_VERSION, entitlementProjectionSchema, rekorEntitlementRefreshMessageSchema, 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, PRICING_PLAN_ID_RE, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, updatePlatformConfigBody, updateFreeOrgLimitBody, adminScopedTargetBody, adminRepairLegacyOrgGrantsBody, adminRepairCompedPlansBody, 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, META_ENTITY_ID_PATTERN, metaEntityId, 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, REKOR_ACTOR_TYPE_HEADER, REKOR_ACTOR_ID_HEADER, REKOR_ACTOR_LABEL_HEADER, REKOR_ACTOR_ORG_HEADER, REKOR_ACTOR_ADMIN_HEADER, REKOR_CLIENT_HEADER, REKOR_TOOL_ID_HEADER, REKOR_CLIENTS, rekorClientSchema, MAX_REKOR_TOOL_ID_LENGTH, rekorToolIdSchema, DATA_PROXY_MOUNT, DATA_PROXY_PREFIX, REKOR_V1_PREFIX, DATA_PROXY_ORG_QUERY_PARAM, MAX_PROVISIONING_BODY_BYTES, dataProxyQuery, rekorAttestation, REQUIRED_REKOR_ATTESTATION_HEADERS, BASE_DESTRUCTION_MOUNT, BASE_DESTRUCTION_PREFIX, BASE_DESTRUCTION_CONFIRM_PATH, baseDestructionConfirmBody, BASE_DESTRUCTION_GRACE_MS, BASE_DESTRUCTION_CONFIRM_TTL_MS, BASE_DESTRUCTION_ORG_QUERY_PARAM, baseDestructionQuery, baseDestructionParam, baseDestructionInitiateBody, baseDestructionStatus, baseDestructionRequest, baseDestructionListResponse, baseDestructionInitiateResponse, baseDestructionConfirmResponse, baseDestructionCancelResponse, rekorBaseChangeMessageSchema;
5373
5373
  var init_contracts = __esm({
5374
5374
  "../../packages/core/dist/contracts/index.js"() {
5375
5375
  "use strict";
@@ -8087,6 +8087,14 @@ var init_contracts = __esm({
8087
8087
  * accepts it; this exposes it on the route.
8088
8088
  */
8089
8089
  harness_enabled: external_exports.number().int().min(0).max(1).optional(),
8090
+ /**
8091
+ * The ConversationDO `runTurn` TurnState conversion gate (refactor #4 Tier 3,
8092
+ * `turn/` Step A). 0 = off (the RETAINED pre-conversion turn body runs), 1 = on (the
8093
+ * converted `TurnState` body runs). Default-deny, and the reader fails CLOSED — a
8094
+ * platform-config read error also runs the retained body. Both bodies stay compiled in
8095
+ * while this flag is live, so a change to either is a change to both.
8096
+ */
8097
+ turn_state_enabled: external_exports.number().int().min(0).max(1).optional(),
8090
8098
  /**
8091
8099
  * Default eval-session retention window in days, used by every hub that sets no
8092
8100
  * `eval_retention_days` override. `0` disables eval retention platform-wide.
@@ -8303,11 +8311,21 @@ var init_contracts = __esm({
8303
8311
  /** Sandbox wall-clock lifetime in ms (bounded). */
8304
8312
  timeout_ms: external_exports.number().int().min(1).max(SANDBOX_EXEC_MAX_TIMEOUT_MS).optional()
8305
8313
  });
8314
+ META_ENTITY_ID_PATTERN = /^\d{1,32}$/;
8315
+ metaEntityId = external_exports.string().regex(META_ENTITY_ID_PATTERN, "must be a numeric Meta entity id");
8306
8316
  whatsappCallbackBody = external_exports.object({
8307
8317
  state: external_exports.string().min(1, "state is required"),
8308
8318
  code: external_exports.string().optional(),
8309
8319
  access_token: external_exports.string().optional(),
8310
- user_id: external_exports.string().optional()
8320
+ user_id: external_exports.string().optional(),
8321
+ /**
8322
+ * The phone number and WABA the operator actually picked in Meta's Embedded
8323
+ * Signup popup (posted to the opener as `WA_EMBEDDED_SIGNUP`). Optional:
8324
+ * older clients, and the redirect-based flow, never see that event and fall
8325
+ * back to discovery.
8326
+ */
8327
+ phone_number_id: metaEntityId.optional(),
8328
+ waba_id: metaEntityId.optional()
8311
8329
  }).refine(
8312
8330
  (data) => !!data.access_token || !!data.code,
8313
8331
  { message: "Missing required parameters: state and either access_token or code" }
@@ -8942,7 +8960,7 @@ var init_api_client = __esm({
8942
8960
  init_sentry();
8943
8961
  init_mask_secrets();
8944
8962
  RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
8945
- delay = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
8963
+ delay = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
8946
8964
  ApiError = class extends Error {
8947
8965
  status;
8948
8966
  body;
@@ -9037,12 +9055,14 @@ var init_api_client = __esm({
9037
9055
  async adminRepairLegacyOrgGrants(body) {
9038
9056
  return this.request("POST", "/api/admin/organizations/repair-legacy-grants", body);
9039
9057
  }
9040
- // Read the platform config (platform-admin gated). Used by `wayai admin harness status`.
9058
+ // Read the platform config (platform-admin gated). Used by every `wayai admin
9059
+ // <gate> status` — `harness`, `turn-state`.
9041
9060
  async adminGetConfig() {
9042
9061
  return this.request("GET", "/api/admin/config");
9043
9062
  }
9044
- // Patch the platform config (platform-admin gated). Used by `wayai admin harness
9045
- // disable|enable` to flip `harness_enabled`.
9063
+ // Patch the platform config (platform-admin gated). Used by every `wayai admin
9064
+ // <gate> disable|enable` — `harness` flips `harness_enabled`, `turn-state` flips
9065
+ // `turn_state_enabled`.
9046
9066
  async adminUpdateConfig(body) {
9047
9067
  return this.request("PATCH", "/api/admin/config", body);
9048
9068
  }
@@ -9607,7 +9627,7 @@ var init_api_client = __esm({
9607
9627
  * `dataErrorMessage` recovers the envelope's own message for display.
9608
9628
  *
9609
9629
  * `orgId` is the caller's org SELECTOR (the `--org` flag, else the repo's
9610
- * `.wayai.yaml`), not an authorization claim: the backend validates it against
9630
+ * `wayai-ws/wayai.yaml`), not an authorization claim: the backend validates it against
9611
9631
  * the caller's grants and attests only the validated result. A multi-org user
9612
9632
  * needs it to pick; a single-org user can omit it.
9613
9633
  *
@@ -10608,7 +10628,7 @@ function findStepBoundaries(transcript) {
10608
10628
  }
10609
10629
  return out;
10610
10630
  }
10611
- 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, REKOR_ACTOR_TYPE_HEADER2, REKOR_ACTOR_ID_HEADER2, REKOR_ACTOR_LABEL_HEADER2, REKOR_ACTOR_ORG_HEADER2, REKOR_ACTOR_ADMIN_HEADER2, REKOR_CLIENT_HEADER2, REKOR_TOOL_ID_HEADER2, REKOR_CLIENTS2, rekorClientSchema2, MAX_REKOR_TOOL_ID_LENGTH2, rekorToolIdSchema2, DATA_PROXY_MOUNT2, DATA_PROXY_PREFIX2, DATA_PROXY_ORG_QUERY_PARAM2, MAX_PROVISIONING_BODY_BYTES2, dataProxyQuery2, rekorAttestation2, REQUIRED_REKOR_ATTESTATION_HEADERS2, BASE_DESTRUCTION_MOUNT2, BASE_DESTRUCTION_PREFIX2, BASE_DESTRUCTION_CONFIRM_PATH2, baseDestructionConfirmBody2, BASE_DESTRUCTION_GRACE_MS2, BASE_DESTRUCTION_CONFIRM_TTL_MS2, BASE_DESTRUCTION_ORG_QUERY_PARAM2, baseDestructionQuery2, baseDestructionParam2, baseDestructionInitiateBody2, baseDestructionStatus2, baseDestructionRequest2, baseDestructionListResponse2, baseDestructionInitiateResponse2, baseDestructionConfirmResponse2, baseDestructionCancelResponse2, ENDPOINT_CONFIGS, 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, MAX_EVAL_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, ORG_TAG_NAME_REGEX2, ORG_TAG_NAME_MAX_LENGTH2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, BASE_CREDENTIAL_NAME_MAX2, baseCredentialNameSchema2, createBaseCredentialLinkBody2, baseCredentialLinkParams2, baseCredentialLinkQuery2, 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, EVAL_LIST_MAX_LIMIT2, evalListLimit2, 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, evalSessionListConfigSchema2, evalSessionListItemSchema2, 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, planKeySchema2, billingStatusSchema2, billingPlanTypeSchema2, REKOR_ENTITLEMENT_CONTRACT_VERSION2, entitlementProjectionSchema2, rekorEntitlementRefreshMessageSchema2, 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, PRICING_PLAN_ID_RE2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminScopedTargetBody2, adminRepairLegacyOrgGrantsBody2, adminRepairCompedPlansBody2, 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, rekorBaseChangeMessageSchema2, WAYAI_WORKSPACE_LAYOUT;
10631
+ 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, REKOR_ACTOR_TYPE_HEADER2, REKOR_ACTOR_ID_HEADER2, REKOR_ACTOR_LABEL_HEADER2, REKOR_ACTOR_ORG_HEADER2, REKOR_ACTOR_ADMIN_HEADER2, REKOR_CLIENT_HEADER2, REKOR_TOOL_ID_HEADER2, REKOR_CLIENTS2, rekorClientSchema2, MAX_REKOR_TOOL_ID_LENGTH2, rekorToolIdSchema2, DATA_PROXY_MOUNT2, DATA_PROXY_PREFIX2, DATA_PROXY_ORG_QUERY_PARAM2, MAX_PROVISIONING_BODY_BYTES2, dataProxyQuery2, rekorAttestation2, REQUIRED_REKOR_ATTESTATION_HEADERS2, BASE_DESTRUCTION_MOUNT2, BASE_DESTRUCTION_PREFIX2, BASE_DESTRUCTION_CONFIRM_PATH2, baseDestructionConfirmBody2, BASE_DESTRUCTION_GRACE_MS2, BASE_DESTRUCTION_CONFIRM_TTL_MS2, BASE_DESTRUCTION_ORG_QUERY_PARAM2, baseDestructionQuery2, baseDestructionParam2, baseDestructionInitiateBody2, baseDestructionStatus2, baseDestructionRequest2, baseDestructionListResponse2, baseDestructionInitiateResponse2, baseDestructionConfirmResponse2, baseDestructionCancelResponse2, ENDPOINT_CONFIGS, 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, MAX_EVAL_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, ORG_TAG_NAME_REGEX2, ORG_TAG_NAME_MAX_LENGTH2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, BASE_CREDENTIAL_NAME_MAX2, baseCredentialNameSchema2, createBaseCredentialLinkBody2, baseCredentialLinkParams2, baseCredentialLinkQuery2, 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, EVAL_LIST_MAX_LIMIT2, evalListLimit2, 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, evalSessionListConfigSchema2, evalSessionListItemSchema2, 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, planKeySchema2, billingStatusSchema2, billingPlanTypeSchema2, REKOR_ENTITLEMENT_CONTRACT_VERSION2, entitlementProjectionSchema2, rekorEntitlementRefreshMessageSchema2, 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, PRICING_PLAN_ID_RE2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminScopedTargetBody2, adminRepairLegacyOrgGrantsBody2, adminRepairCompedPlansBody2, 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, META_ENTITY_ID_PATTERN2, metaEntityId2, 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, rekorBaseChangeMessageSchema2, WAYAI_WORKSPACE_LAYOUT;
10612
10632
  var init_dist = __esm({
10613
10633
  "../../packages/core/dist/index.js"() {
10614
10634
  "use strict";
@@ -13767,6 +13787,14 @@ var init_dist = __esm({
13767
13787
  * accepts it; this exposes it on the route.
13768
13788
  */
13769
13789
  harness_enabled: external_exports.number().int().min(0).max(1).optional(),
13790
+ /**
13791
+ * The ConversationDO `runTurn` TurnState conversion gate (refactor #4 Tier 3,
13792
+ * `turn/` Step A). 0 = off (the RETAINED pre-conversion turn body runs), 1 = on (the
13793
+ * converted `TurnState` body runs). Default-deny, and the reader fails CLOSED — a
13794
+ * platform-config read error also runs the retained body. Both bodies stay compiled in
13795
+ * while this flag is live, so a change to either is a change to both.
13796
+ */
13797
+ turn_state_enabled: external_exports.number().int().min(0).max(1).optional(),
13770
13798
  /**
13771
13799
  * Default eval-session retention window in days, used by every hub that sets no
13772
13800
  * `eval_retention_days` override. `0` disables eval retention platform-wide.
@@ -13983,11 +14011,21 @@ var init_dist = __esm({
13983
14011
  /** Sandbox wall-clock lifetime in ms (bounded). */
13984
14012
  timeout_ms: external_exports.number().int().min(1).max(SANDBOX_EXEC_MAX_TIMEOUT_MS2).optional()
13985
14013
  });
14014
+ META_ENTITY_ID_PATTERN2 = /^\d{1,32}$/;
14015
+ metaEntityId2 = external_exports.string().regex(META_ENTITY_ID_PATTERN2, "must be a numeric Meta entity id");
13986
14016
  whatsappCallbackBody2 = external_exports.object({
13987
14017
  state: external_exports.string().min(1, "state is required"),
13988
14018
  code: external_exports.string().optional(),
13989
14019
  access_token: external_exports.string().optional(),
13990
- user_id: external_exports.string().optional()
14020
+ user_id: external_exports.string().optional(),
14021
+ /**
14022
+ * The phone number and WABA the operator actually picked in Meta's Embedded
14023
+ * Signup popup (posted to the opener as `WA_EMBEDDED_SIGNUP`). Optional:
14024
+ * older clients, and the redirect-based flow, never see that event and fall
14025
+ * back to discovery.
14026
+ */
14027
+ phone_number_id: metaEntityId2.optional(),
14028
+ waba_id: metaEntityId2.optional()
13991
14029
  }).refine(
13992
14030
  (data) => !!data.access_token || !!data.code,
13993
14031
  { message: "Missing required parameters: state and either access_token or code" }
@@ -14516,34 +14554,15 @@ function resolveLayout(gitRoot, layout = WAYAI_LAYOUT) {
14516
14554
  const newWs = path.join(gitRoot, layout.wsDir);
14517
14555
  const legacyWs = path.join(gitRoot, layout.legacy.wsDir);
14518
14556
  const legacyOrg = path.join(gitRoot, layout.legacy.orgAtRoot);
14519
- const newExists = isDirectory(newWs);
14520
14557
  const legacyExists = isDirectory(legacyWs) || isDirectory(legacyOrg);
14521
14558
  const basesDir = path.join(newWs, layout.basesSubdir);
14522
- if (newExists) {
14523
- return {
14524
- hubsDir: path.join(newWs, layout.hubsSubdir),
14525
- orgDir: path.join(newWs, layout.orgSubdir),
14526
- basesDir,
14527
- isLegacy: false,
14528
- legacyAlsoPresent: legacyExists
14529
- };
14559
+ const hubsDir = path.join(newWs, layout.hubsSubdir);
14560
+ const orgDir = path.join(newWs, layout.orgSubdir);
14561
+ const newDisplacesLegacy = () => isDirectory(hubsDir) || isDirectory(orgDir) || isDirectory(basesDir);
14562
+ if (legacyExists && !newDisplacesLegacy()) {
14563
+ return { hubsDir: legacyWs, orgDir: legacyOrg, basesDir, isLegacy: true, legacyAlsoPresent: false };
14530
14564
  }
14531
- if (legacyExists) {
14532
- return {
14533
- hubsDir: legacyWs,
14534
- orgDir: legacyOrg,
14535
- basesDir,
14536
- isLegacy: true,
14537
- legacyAlsoPresent: false
14538
- };
14539
- }
14540
- return {
14541
- hubsDir: path.join(newWs, layout.hubsSubdir),
14542
- orgDir: path.join(newWs, layout.orgSubdir),
14543
- basesDir,
14544
- isLegacy: false,
14545
- legacyAlsoPresent: false
14546
- };
14565
+ return { hubsDir, orgDir, basesDir, isLegacy: false, legacyAlsoPresent: legacyExists };
14547
14566
  }
14548
14567
  function resolveBasesDir(gitRoot) {
14549
14568
  return resolveLayout(gitRoot).basesDir;
@@ -14960,111 +14979,344 @@ var init_workspace = __esm({
14960
14979
  }
14961
14980
  });
14962
14981
 
14982
+ // src/lib/workspace-manifest.ts
14983
+ import * as fs3 from "fs";
14984
+ import * as path3 from "path";
14985
+ import * as yaml2 from "js-yaml";
14986
+ function workspaceManifestPath(gitRoot) {
14987
+ return path3.join(gitRoot, WAYAI_LAYOUT.wsDir, WORKSPACE_MANIFEST_FILE);
14988
+ }
14989
+ function rootConfigPath(gitRoot) {
14990
+ return path3.join(gitRoot, ROOT_CONFIG_FILE);
14991
+ }
14992
+ function loadYamlMapping(file) {
14993
+ let raw;
14994
+ try {
14995
+ raw = fs3.readFileSync(file, "utf-8");
14996
+ } catch (err) {
14997
+ if (err.code === "ENOENT") return { kind: "absent" };
14998
+ return { kind: "malformed", reason: err instanceof Error ? err.message : String(err) };
14999
+ }
15000
+ let doc;
15001
+ try {
15002
+ doc = yaml2.load(raw);
15003
+ } catch (err) {
15004
+ return { kind: "malformed", reason: err instanceof Error ? err.message : String(err) };
15005
+ }
15006
+ if (doc === void 0 || doc === null) return { kind: "ok", doc: {} };
15007
+ if (typeof doc !== "object" || Array.isArray(doc)) {
15008
+ return { kind: "malformed", reason: "expected a YAML mapping of settings" };
15009
+ }
15010
+ return { kind: "ok", doc };
15011
+ }
15012
+ function loadWorkspaceManifest(gitRoot) {
15013
+ return loadYamlMapping(workspaceManifestPath(gitRoot));
15014
+ }
15015
+ var WORKSPACE_MANIFEST_FILE, WORKSPACE_MANIFEST_LABEL, ROOT_CONFIG_FILE;
15016
+ var init_workspace_manifest = __esm({
15017
+ "src/lib/workspace-manifest.ts"() {
15018
+ "use strict";
15019
+ init_layout();
15020
+ WORKSPACE_MANIFEST_FILE = "wayai.yaml";
15021
+ WORKSPACE_MANIFEST_LABEL = `${WAYAI_LAYOUT.wsDir}/${WORKSPACE_MANIFEST_FILE}`;
15022
+ ROOT_CONFIG_FILE = ".wayai.yaml";
15023
+ }
15024
+ });
15025
+
14963
15026
  // src/lib/repo-config.ts
14964
15027
  var repo_config_exports = {};
14965
15028
  __export(repo_config_exports, {
15029
+ _resetRepoConfigNotices: () => _resetRepoConfigNotices,
15030
+ planOrgMigration: () => planOrgMigration,
14966
15031
  readRepoConfig: () => readRepoConfig,
15032
+ readRepoConfigUnlessBlocked: () => readRepoConfigUnlessBlocked,
15033
+ readRepoScopeBlocker: () => readRepoScopeBlocker,
14967
15034
  requireRepoConfig: () => requireRepoConfig,
15035
+ resolveRepoConfig: () => resolveRepoConfig,
14968
15036
  writeRepoConfig: () => writeRepoConfig
14969
15037
  });
14970
- import * as fs3 from "fs";
14971
- import * as path3 from "path";
14972
- import * as yaml2 from "js-yaml";
14973
- function warnAboutLegacyFields(found) {
14974
- if (legacyFieldsWarned || found.length === 0) return;
14975
- legacyFieldsWarned = true;
14976
- console.warn(
14977
- `Note: .wayai.yaml contains deprecated field(s) ${found.join(", ")}. These are ignored \u2014 only organization_id is used now. You can remove them.`
14978
- );
15038
+ import * as fs4 from "fs";
15039
+ import * as path4 from "path";
15040
+ import * as yaml3 from "js-yaml";
15041
+ function noticeOnce(key, emit) {
15042
+ if (noticed.has(key)) return;
15043
+ noticed.add(key);
15044
+ emit();
15045
+ }
15046
+ function _resetRepoConfigNotices() {
15047
+ noticed.clear();
15048
+ }
15049
+ function readOrgFields(doc) {
15050
+ const raw = doc.organization_id;
15051
+ if (raw === void 0 || raw === null) {
15052
+ if (typeof doc.organization === "string") {
15053
+ return {
15054
+ kind: "invalid",
15055
+ detail: "it uses the old format (organization: <name>) \u2014 replace it with organization_id: <uuid>"
15056
+ };
15057
+ }
15058
+ return { kind: "none" };
15059
+ }
15060
+ if (typeof raw !== "string" || !UUID_RE2.test(raw.trim())) {
15061
+ return { kind: "invalid", detail: "organization_id must be a UUID" };
15062
+ }
15063
+ const name = typeof doc.organization_name === "string" && doc.organization_name.trim() ? doc.organization_name.trim() : void 0;
15064
+ const config = { organization_id: raw.trim() };
15065
+ if (name) config.organization_name = name;
15066
+ return { kind: "declared", config };
15067
+ }
15068
+ function declarationFrom(load11) {
15069
+ if (load11.kind === "absent") return { kind: "none" };
15070
+ if (load11.kind === "malformed") return { kind: "invalid", detail: `it does not parse (${load11.reason})` };
15071
+ return readOrgFields(load11.doc);
15072
+ }
15073
+ function legacyFieldsIn(load11) {
15074
+ if (load11.kind !== "ok") return [];
15075
+ return LEGACY_FIELDS.filter((f) => load11.doc[f] !== void 0);
15076
+ }
15077
+ function resolve2(gitRoot) {
15078
+ const manifestFile = workspaceManifestPath(gitRoot);
15079
+ const manifest = declarationFrom(loadWorkspaceManifest(gitRoot));
15080
+ if (manifest.kind === "invalid") {
15081
+ return { kind: "invalid", source: "manifest", file: manifestFile, detail: manifest.detail };
15082
+ }
15083
+ const rootFile = rootConfigPath(gitRoot);
15084
+ const rootLoad = loadYamlMapping(rootFile);
15085
+ const root = declarationFrom(rootLoad);
15086
+ if (manifest.kind === "declared") {
15087
+ if (root.kind === "declared" && root.config.organization_id !== manifest.config.organization_id) {
15088
+ return {
15089
+ kind: "conflict",
15090
+ manifestOrg: manifest.config.organization_id,
15091
+ rootOrg: root.config.organization_id
15092
+ };
15093
+ }
15094
+ return {
15095
+ kind: "ok",
15096
+ resolved: { config: manifest.config, source: "manifest", path: manifestFile },
15097
+ legacyRootFields: []
15098
+ };
15099
+ }
15100
+ if (root.kind === "declared") {
15101
+ return {
15102
+ kind: "ok",
15103
+ resolved: { config: root.config, source: "root", path: rootFile },
15104
+ legacyRootFields: legacyFieldsIn(rootLoad)
15105
+ };
15106
+ }
15107
+ if (root.kind === "invalid") {
15108
+ return { kind: "invalid", source: "root", file: rootFile, detail: root.detail };
15109
+ }
15110
+ return { kind: "none" };
15111
+ }
15112
+ function conflictMessage(manifestOrg, rootOrg, remedy = RECONCILE_REMEDY) {
15113
+ return [
15114
+ "Refusing to guess the organization: two files in this repo name different ones.",
15115
+ ` ${WORKSPACE_MANIFEST_LABEL} -> ${manifestOrg} (the workspace manifest)`,
15116
+ ` ${ROOT_CONFIG_FILE} -> ${rootOrg} (deprecated fallback)`,
15117
+ "",
15118
+ ...remedy
15119
+ ].join("\n");
15120
+ }
15121
+ function rebindRefusal(requestedOrg, rootOrg) {
15122
+ return [
15123
+ `Refusing to re-bind the organization: ${ROOT_CONFIG_FILE} still names a different one, and it is read as a fallback.`,
15124
+ ` requested -> ${requestedOrg}`,
15125
+ ` ${ROOT_CONFIG_FILE} -> ${rootOrg} (deprecated fallback)`,
15126
+ "",
15127
+ `Delete ${ROOT_CONFIG_FILE} (or set its organization_id to ${requestedOrg}), then re-run.`,
15128
+ "Nothing was written \u2014 this repo still resolves to the organization it had."
15129
+ ].join("\n");
15130
+ }
15131
+ function invalidMessage(file, detail) {
15132
+ return [
15133
+ `Invalid organization binding in ${file}: ${detail}.`,
15134
+ "",
15135
+ " organization_id: <your-org-uuid>",
15136
+ "",
15137
+ "Run `wayai init` to set up the workspace."
15138
+ ].join("\n");
15139
+ }
15140
+ function missingMessage() {
15141
+ return [
15142
+ "This repository is not scoped to an organization.",
15143
+ `Declare it in ${WORKSPACE_MANIFEST_LABEL}:`,
15144
+ "",
15145
+ " organization_id: <your-org-uuid>",
15146
+ "",
15147
+ "Run `wayai init` to set up the workspace."
15148
+ ].join("\n");
15149
+ }
15150
+ function report(r, posture) {
15151
+ switch (r.kind) {
15152
+ case "ok":
15153
+ if (r.resolved.source !== "root") return;
15154
+ noticeOnce(
15155
+ "root-fallback",
15156
+ () => console.warn(
15157
+ `Note: this repo's organization binding is still in ${ROOT_CONFIG_FILE} at the repository root. It belongs in the workspace manifest ${WORKSPACE_MANIFEST_LABEL} \u2014 run \`wayai migrate\` to copy it there.`
15158
+ )
15159
+ );
15160
+ if (r.legacyRootFields.length > 0) {
15161
+ noticeOnce(
15162
+ "legacy-fields",
15163
+ () => console.warn(
15164
+ `Note: ${ROOT_CONFIG_FILE} contains deprecated field(s) ${r.legacyRootFields.join(", ")}. These are ignored \u2014 only organization_id is used now. You can remove them.`
15165
+ )
15166
+ );
15167
+ }
15168
+ return;
15169
+ case "invalid": {
15170
+ const emit = () => console.error(invalidMessage(r.file, r.detail));
15171
+ if (posture === "hard") emit();
15172
+ else noticeOnce(`invalid:${r.source}`, emit);
15173
+ return;
15174
+ }
15175
+ case "conflict":
15176
+ console.error(conflictMessage(r.manifestOrg, r.rootOrg));
15177
+ return;
15178
+ case "none":
15179
+ if (posture === "hard") console.error(missingMessage());
15180
+ return;
15181
+ }
15182
+ }
15183
+ function resolveRepoConfig(root) {
15184
+ const gitRoot = root ?? findGitRoot();
15185
+ if (!gitRoot) return null;
15186
+ const r = resolve2(gitRoot);
15187
+ report(r, "soft");
15188
+ return r.kind === "ok" ? r.resolved : null;
14979
15189
  }
14980
15190
  function readRepoConfig(root) {
15191
+ return resolveRepoConfig(root)?.config ?? null;
15192
+ }
15193
+ function readRepoConfigUnlessBlocked(root) {
14981
15194
  const gitRoot = root ?? findGitRoot();
14982
15195
  if (!gitRoot) return null;
14983
- const configPath3 = path3.join(gitRoot, ".wayai.yaml");
14984
- if (!fs3.existsSync(configPath3)) return null;
14985
- try {
14986
- const content = fs3.readFileSync(configPath3, "utf-8");
14987
- const config = yaml2.load(content);
14988
- if (!config?.organization_id || typeof config.organization_id !== "string") {
14989
- if (config?.organization && typeof config.organization === "string") {
14990
- console.error(
14991
- ".wayai.yaml uses the old format (organization: name). Replace it with organization_id: <uuid>."
14992
- );
14993
- }
15196
+ const r = resolve2(gitRoot);
15197
+ switch (r.kind) {
15198
+ case "ok":
15199
+ report(r, "soft");
15200
+ return r.resolved.config;
15201
+ case "none":
14994
15202
  return null;
14995
- }
14996
- if (!UUID_RE2.test(config.organization_id)) return null;
14997
- const presentLegacy = LEGACY_FIELDS.filter((f) => config[f] !== void 0);
14998
- warnAboutLegacyFields(presentLegacy);
14999
- const organizationName = typeof config.organization_name === "string" && config.organization_name.trim() ? config.organization_name.trim() : void 0;
15203
+ case "conflict":
15204
+ throw expected(conflictMessage(r.manifestOrg, r.rootOrg));
15205
+ case "invalid":
15206
+ throw expected(invalidMessage(r.file, r.detail));
15207
+ }
15208
+ }
15209
+ function requireRepoConfig(root) {
15210
+ const gitRoot = root ?? findGitRoot();
15211
+ const r = gitRoot ? resolve2(gitRoot) : { kind: "none" };
15212
+ report(r, "hard");
15213
+ if (r.kind === "ok") return r.resolved.config;
15214
+ return process.exit(1);
15215
+ }
15216
+ function readRepoScopeBlocker(root) {
15217
+ const gitRoot = root ?? findGitRoot();
15218
+ if (!gitRoot) return null;
15219
+ const r = resolve2(gitRoot);
15220
+ if (r.kind === "conflict") {
15000
15221
  return {
15001
- organization_id: config.organization_id,
15002
- organization_name: organizationName
15222
+ kind: "conflict",
15223
+ manifest_organization_id: r.manifestOrg,
15224
+ root_organization_id: r.rootOrg
15003
15225
  };
15004
- } catch {
15005
- return null;
15006
15226
  }
15227
+ if (r.kind === "invalid") return { kind: "invalid", path: r.file, detail: r.detail };
15228
+ return null;
15007
15229
  }
15008
- function requireRepoConfig(root) {
15009
- const config = readRepoConfig(root);
15010
- if (!config) {
15011
- console.error("Missing or invalid .wayai.yaml at the repository root.");
15012
- console.error("The file must contain organization_id:");
15013
- console.error("");
15014
- console.error(" organization_id: <your-org-uuid>");
15015
- console.error("");
15016
- console.error("Run `wayai init` to set up the workspace.");
15017
- process.exit(1);
15230
+ function planOrgMigration(gitRoot) {
15231
+ const manifest = declarationFrom(loadWorkspaceManifest(gitRoot));
15232
+ const root = declarationFrom(loadYamlMapping(rootConfigPath(gitRoot)));
15233
+ if (root.kind !== "declared") return { kind: "nothing" };
15234
+ if (manifest.kind === "declared") {
15235
+ if (manifest.config.organization_id === root.config.organization_id) return { kind: "nothing" };
15236
+ return {
15237
+ kind: "refuse",
15238
+ message: conflictMessage(manifest.config.organization_id, root.config.organization_id, [
15239
+ "Reconcile them by hand \u2014 migrate cannot know which one you meant."
15240
+ ])
15241
+ };
15018
15242
  }
15019
- return config;
15243
+ if (manifest.kind === "invalid") {
15244
+ return {
15245
+ kind: "refuse",
15246
+ message: `Cannot copy the organization binding: ${WORKSPACE_MANIFEST_LABEL} is unusable \u2014 ${manifest.detail}. Fix or delete it, then re-run \`wayai migrate\`.`
15247
+ };
15248
+ }
15249
+ return { kind: "copy", config: root.config };
15020
15250
  }
15021
15251
  function writeRepoConfig(config, root) {
15022
15252
  const gitRoot = root ?? findGitRoot();
15023
15253
  if (!gitRoot) {
15024
15254
  throw new Error("Not inside a git repository. Run `git init` first.");
15025
15255
  }
15026
- const configPath3 = path3.join(gitRoot, ".wayai.yaml");
15256
+ const stale = declarationFrom(loadYamlMapping(rootConfigPath(gitRoot)));
15257
+ if (stale.kind === "declared" && stale.config.organization_id !== config.organization_id) {
15258
+ throw expected(rebindRefusal(config.organization_id, stale.config.organization_id));
15259
+ }
15260
+ const load11 = loadWorkspaceManifest(gitRoot);
15261
+ if (load11.kind === "malformed") {
15262
+ throw expected(
15263
+ `Cannot write the organization binding: ${WORKSPACE_MANIFEST_LABEL} does not parse (${load11.reason}). Fix or delete it, then re-run.`
15264
+ );
15265
+ }
15266
+ const { organization_id: _id, organization_name: _name, ...rest } = load11.kind === "ok" ? load11.doc : {};
15027
15267
  const doc = { organization_id: config.organization_id };
15028
15268
  if (config.organization_name?.trim()) doc.organization_name = config.organization_name.trim();
15029
- const content = yaml2.dump(doc, { quotingType: '"', forceQuotes: false });
15030
- fs3.writeFileSync(configPath3, content, "utf-8");
15031
- return configPath3;
15269
+ Object.assign(doc, rest);
15270
+ const file = workspaceManifestPath(gitRoot);
15271
+ fs4.mkdirSync(path4.dirname(file), { recursive: true });
15272
+ fs4.writeFileSync(
15273
+ file,
15274
+ yaml3.dump(doc, { lineWidth: -1, quotingType: '"', forceQuotes: false }),
15275
+ "utf-8"
15276
+ );
15277
+ return file;
15032
15278
  }
15033
- var LEGACY_FIELDS, legacyFieldsWarned;
15279
+ var LEGACY_FIELDS, noticed, RECONCILE_REMEDY;
15034
15280
  var init_repo_config = __esm({
15035
15281
  "src/lib/repo-config.ts"() {
15036
15282
  "use strict";
15283
+ init_expected();
15037
15284
  init_workspace();
15038
15285
  init_utils();
15286
+ init_workspace_manifest();
15039
15287
  LEGACY_FIELDS = ["project_id", "project_name", "hub_id", "hub_name"];
15040
- legacyFieldsWarned = false;
15288
+ noticed = /* @__PURE__ */ new Set();
15289
+ RECONCILE_REMEDY = [
15290
+ "Keep the organization_id you actually work in and delete the other declaration.",
15291
+ `\`wayai init\` rewrites ${WORKSPACE_MANIFEST_LABEL}; the root file is yours to remove.`
15292
+ ];
15041
15293
  }
15042
15294
  });
15043
15295
 
15044
15296
  // src/lib/utils.ts
15045
- import * as fs4 from "fs";
15046
- import * as path4 from "path";
15297
+ import * as fs5 from "fs";
15298
+ import * as path5 from "path";
15047
15299
  import * as readline from "readline";
15048
15300
  function prompt(question) {
15049
15301
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
15050
- return new Promise((resolve7) => {
15302
+ return new Promise((resolve8) => {
15051
15303
  rl.question(question, (answer) => {
15052
15304
  rl.close();
15053
- resolve7(answer.trim());
15305
+ resolve8(answer.trim());
15054
15306
  });
15055
15307
  });
15056
15308
  }
15057
15309
  function confirm(question) {
15058
15310
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
15059
- return new Promise((resolve7) => {
15311
+ return new Promise((resolve8) => {
15060
15312
  rl.question(`${question} [y/N]: `, (answer) => {
15061
15313
  rl.close();
15062
- resolve7(answer.trim().toLowerCase() === "y");
15314
+ resolve8(answer.trim().toLowerCase() === "y");
15063
15315
  });
15064
15316
  });
15065
15317
  }
15066
15318
  function promptSecret(question) {
15067
- return new Promise((resolve7) => {
15319
+ return new Promise((resolve8) => {
15068
15320
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
15069
15321
  const originalWrite = rl._writeToOutput;
15070
15322
  let firstWrite = true;
@@ -15080,25 +15332,25 @@ function promptSecret(question) {
15080
15332
  rl._writeToOutput = originalWrite;
15081
15333
  process.stdout.write("\n");
15082
15334
  rl.close();
15083
- resolve7(answer);
15335
+ resolve8(answer);
15084
15336
  });
15085
15337
  });
15086
15338
  }
15087
15339
  function readStdin() {
15088
- return new Promise((resolve7, reject) => {
15340
+ return new Promise((resolve8, reject) => {
15089
15341
  let data = "";
15090
15342
  process.stdin.setEncoding("utf-8");
15091
15343
  process.stdin.on("data", (chunk) => {
15092
15344
  data += chunk;
15093
15345
  });
15094
- process.stdin.on("end", () => resolve7(data.trim()));
15346
+ process.stdin.on("end", () => resolve8(data.trim()));
15095
15347
  process.stdin.on("error", reject);
15096
15348
  });
15097
15349
  }
15098
15350
  function resolveHubYamlPath(hubFolder) {
15099
15351
  for (const filename of ["hub.yaml", "wayai.yaml"]) {
15100
- const yamlPath = path4.join(hubFolder, filename);
15101
- if (fs4.existsSync(yamlPath)) return yamlPath;
15352
+ const yamlPath = path5.join(hubFolder, filename);
15353
+ if (fs5.existsSync(yamlPath)) return yamlPath;
15102
15354
  }
15103
15355
  return null;
15104
15356
  }
@@ -15175,8 +15427,8 @@ async function resolveOrganizationId(client, orgIdFlag) {
15175
15427
  }
15176
15428
  return { organizationId: orgIdFlag };
15177
15429
  }
15178
- const { readRepoConfig: readRepoConfig2 } = await Promise.resolve().then(() => (init_repo_config(), repo_config_exports));
15179
- const repoConfig = readRepoConfig2();
15430
+ const { readRepoConfigUnlessBlocked: readRepoConfigUnlessBlocked2 } = await Promise.resolve().then(() => (init_repo_config(), repo_config_exports));
15431
+ const repoConfig = readRepoConfigUnlessBlocked2();
15180
15432
  if (repoConfig) {
15181
15433
  return { organizationId: repoConfig.organization_id, organizationName: repoConfig.organization_name };
15182
15434
  }
@@ -15312,7 +15564,7 @@ var init_registry = __esm({
15312
15564
  surviving: null,
15313
15565
  clause: 1,
15314
15566
  shipped: true,
15315
- reason: "One root org binding (`.wayai.yaml`), so one `init`."
15567
+ reason: "One org binding per repo (`wayai-ws/wayai.yaml`), so one `init`."
15316
15568
  },
15317
15569
  {
15318
15570
  original: "update",
@@ -15563,8 +15815,8 @@ var init_registry = __esm({
15563
15815
  });
15564
15816
 
15565
15817
  // src/lib/version-cache.ts
15566
- import { existsSync as existsSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync2, mkdirSync } from "fs";
15567
- import { dirname as dirname3, join as join6 } from "path";
15818
+ import { existsSync as existsSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
15819
+ import { dirname as dirname4, join as join6 } from "path";
15568
15820
  import { homedir as homedir2 } from "os";
15569
15821
  function getVersionCachePath(filename = CLI_CACHE_FILE) {
15570
15822
  return join6(homedir2(), ".wayai", filename);
@@ -15572,7 +15824,7 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
15572
15824
  function readVersionCache(filename = CLI_CACHE_FILE) {
15573
15825
  try {
15574
15826
  const path35 = getVersionCachePath(filename);
15575
- if (!existsSync4(path35)) return null;
15827
+ if (!existsSync3(path35)) return null;
15576
15828
  const parsed = JSON.parse(readFileSync5(path35, "utf-8"));
15577
15829
  if (typeof parsed.lastCheck !== "number") return null;
15578
15830
  if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
@@ -15594,8 +15846,8 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
15594
15846
  }
15595
15847
  function writeVersionCache(filename, cache) {
15596
15848
  const path35 = getVersionCachePath(filename);
15597
- const dir = dirname3(path35);
15598
- if (!existsSync4(dir)) mkdirSync(dir, { recursive: true });
15849
+ const dir = dirname4(path35);
15850
+ if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
15599
15851
  writeFileSync2(path35, JSON.stringify(cache));
15600
15852
  }
15601
15853
  function touchVersionCache(filename) {
@@ -15613,9 +15865,9 @@ var init_version_cache = __esm({
15613
15865
  });
15614
15866
 
15615
15867
  // src/lib/skill-version.ts
15616
- import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
15868
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
15617
15869
  import { join as join7 } from "path";
15618
- import * as yaml3 from "js-yaml";
15870
+ import * as yaml4 from "js-yaml";
15619
15871
  function skillInstallPaths(skillName) {
15620
15872
  return HARNESS_SKILL_DIRS.map((dir) => `${dir}/skills/${skillName}/${SKILL_FILENAME}`);
15621
15873
  }
@@ -15624,7 +15876,7 @@ function parseFrontmatterVersion(content) {
15624
15876
  if (!match) return null;
15625
15877
  let parsed;
15626
15878
  try {
15627
- parsed = yaml3.load(match[1]);
15879
+ parsed = yaml4.load(match[1]);
15628
15880
  } catch {
15629
15881
  return null;
15630
15882
  }
@@ -15636,7 +15888,7 @@ function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
15636
15888
  const found = [];
15637
15889
  for (const rel of paths) {
15638
15890
  const path35 = join7(projectRoot, rel);
15639
- if (!existsSync5(path35)) continue;
15891
+ if (!existsSync4(path35)) continue;
15640
15892
  let version = null;
15641
15893
  try {
15642
15894
  version = parseFrontmatterVersion(readFileSync6(path35, "utf-8"));
@@ -15673,22 +15925,22 @@ __export(config_exports, {
15673
15925
  readConfig: () => readConfig,
15674
15926
  writeConfig: () => writeConfig
15675
15927
  });
15676
- import * as fs5 from "fs";
15677
- import * as path5 from "path";
15928
+ import * as fs6 from "fs";
15929
+ import * as path6 from "path";
15678
15930
  import * as os from "os";
15679
15931
  function configDir() {
15680
- return path5.join(os.homedir(), ".wayai");
15932
+ return path6.join(os.homedir(), ".wayai");
15681
15933
  }
15682
15934
  function configPath() {
15683
- return path5.join(configDir(), "config.json");
15935
+ return path6.join(configDir(), "config.json");
15684
15936
  }
15685
15937
  function getConfigPath() {
15686
15938
  return configPath();
15687
15939
  }
15688
15940
  function readConfig() {
15689
- if (!fs5.existsSync(configPath())) return null;
15941
+ if (!fs6.existsSync(configPath())) return null;
15690
15942
  try {
15691
- const content = fs5.readFileSync(configPath(), "utf-8");
15943
+ const content = fs6.readFileSync(configPath(), "utf-8");
15692
15944
  const parsed = JSON.parse(content);
15693
15945
  if (!parsed.api_url) return null;
15694
15946
  return {
@@ -15701,13 +15953,13 @@ function readConfig() {
15701
15953
  }
15702
15954
  }
15703
15955
  function writeConfig(config) {
15704
- if (!fs5.existsSync(configDir())) {
15705
- fs5.mkdirSync(configDir(), { recursive: true });
15956
+ if (!fs6.existsSync(configDir())) {
15957
+ fs6.mkdirSync(configDir(), { recursive: true });
15706
15958
  }
15707
15959
  let existing = {};
15708
- if (fs5.existsSync(configPath())) {
15960
+ if (fs6.existsSync(configPath())) {
15709
15961
  try {
15710
- existing = JSON.parse(fs5.readFileSync(configPath(), "utf-8"));
15962
+ existing = JSON.parse(fs6.readFileSync(configPath(), "utf-8"));
15711
15963
  } catch {
15712
15964
  }
15713
15965
  }
@@ -15715,14 +15967,14 @@ function writeConfig(config) {
15715
15967
  delete existing.access_token;
15716
15968
  delete existing.refresh_token;
15717
15969
  Object.assign(existing, config);
15718
- fs5.writeFileSync(configPath(), JSON.stringify(existing, null, 2) + "\n", {
15970
+ fs6.writeFileSync(configPath(), JSON.stringify(existing, null, 2) + "\n", {
15719
15971
  mode: 384
15720
15972
  // owner-only read/write
15721
15973
  });
15722
15974
  }
15723
15975
  function deleteConfig() {
15724
- if (fs5.existsSync(configPath())) {
15725
- fs5.unlinkSync(configPath());
15976
+ if (fs6.existsSync(configPath())) {
15977
+ fs6.unlinkSync(configPath());
15726
15978
  }
15727
15979
  }
15728
15980
  var init_config = __esm({
@@ -15732,14 +15984,14 @@ var init_config = __esm({
15732
15984
  });
15733
15985
 
15734
15986
  // src/lib/token-store.ts
15735
- import * as fs6 from "fs";
15736
- import * as path6 from "path";
15987
+ import * as fs7 from "fs";
15988
+ import * as path7 from "path";
15737
15989
  import * as os2 from "os";
15738
15990
  function configDir2() {
15739
- return path6.join(os2.homedir(), ".wayai");
15991
+ return path7.join(os2.homedir(), ".wayai");
15740
15992
  }
15741
15993
  function configPath2() {
15742
- return path6.join(configDir2(), "config.json");
15994
+ return path7.join(configDir2(), "config.json");
15743
15995
  }
15744
15996
  function manualCleanupCommand(account) {
15745
15997
  if (process.platform === "darwin") {
@@ -15791,9 +16043,9 @@ async function getKeyring() {
15791
16043
  return keyringCache;
15792
16044
  }
15793
16045
  function readLegacyConfigFile() {
15794
- if (!fs6.existsSync(configPath2())) return null;
16046
+ if (!fs7.existsSync(configPath2())) return null;
15795
16047
  try {
15796
- return JSON.parse(fs6.readFileSync(configPath2(), "utf-8"));
16048
+ return JSON.parse(fs7.readFileSync(configPath2(), "utf-8"));
15797
16049
  } catch {
15798
16050
  return null;
15799
16051
  }
@@ -15806,7 +16058,7 @@ function stripTokensFromFile() {
15806
16058
  if (k === "token" || k === "access_token" || k === "refresh_token") continue;
15807
16059
  cleaned[k] = v;
15808
16060
  }
15809
- fs6.writeFileSync(configPath2(), JSON.stringify(cleaned, null, 2) + "\n", { mode: 384 });
16061
+ fs7.writeFileSync(configPath2(), JSON.stringify(cleaned, null, 2) + "\n", { mode: 384 });
15810
16062
  }
15811
16063
  async function migrateLegacyTokens() {
15812
16064
  const legacy = readLegacyConfigFile();
@@ -15957,8 +16209,8 @@ async function clearTokens() {
15957
16209
  }
15958
16210
  }
15959
16211
  }
15960
- if (fs6.existsSync(configPath2())) {
15961
- fs6.unlinkSync(configPath2());
16212
+ if (fs7.existsSync(configPath2())) {
16213
+ fs7.unlinkSync(configPath2());
15962
16214
  }
15963
16215
  }
15964
16216
  function readMetadataExpiresAt() {
@@ -15972,7 +16224,7 @@ function writeMetadataExpiresAt(expires_at) {
15972
16224
  delete existing.refresh_token;
15973
16225
  existing.token_expires_at = expires_at;
15974
16226
  ensureConfigDir();
15975
- fs6.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
16227
+ fs7.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
15976
16228
  }
15977
16229
  function clearMetadataExpiresAt() {
15978
16230
  const existing = readLegacyConfigFile();
@@ -15982,11 +16234,11 @@ function clearMetadataExpiresAt() {
15982
16234
  delete existing.refresh_token;
15983
16235
  delete existing.token_expires_at;
15984
16236
  ensureConfigDir();
15985
- fs6.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
16237
+ fs7.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
15986
16238
  }
15987
16239
  function ensureConfigDir() {
15988
- if (!fs6.existsSync(configDir2())) {
15989
- fs6.mkdirSync(configDir2(), { recursive: true });
16240
+ if (!fs7.existsSync(configDir2())) {
16241
+ fs7.mkdirSync(configDir2(), { recursive: true });
15990
16242
  }
15991
16243
  }
15992
16244
  function writeFileFallback(tokens) {
@@ -15997,7 +16249,7 @@ function writeFileFallback(tokens) {
15997
16249
  delete existing.token_expires_at;
15998
16250
  Object.assign(existing, tokens);
15999
16251
  ensureConfigDir();
16000
- fs6.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
16252
+ fs7.writeFileSync(configPath2(), JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
16001
16253
  }
16002
16254
  var KEYRING_SERVICE, KEY_WAY_TOKEN, KEY_OAUTH_ACCESS, KEY_OAUTH_REFRESH, keyringCache, StaleKeyringSlotError;
16003
16255
  var init_token_store = __esm({
@@ -16106,7 +16358,7 @@ async function validateToken(apiUrl, token) {
16106
16358
  }
16107
16359
  }
16108
16360
  function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
16109
- return new Promise((resolve7, reject) => {
16361
+ return new Promise((resolve8, reject) => {
16110
16362
  const server = http.createServer((req, res) => {
16111
16363
  const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
16112
16364
  if (url.pathname === "/callback") {
@@ -16132,7 +16384,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
16132
16384
  res.writeHead(200, { "Content-Type": "text/html" });
16133
16385
  res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
16134
16386
  server.close();
16135
- resolve7({ code, port });
16387
+ resolve8({ code, port });
16136
16388
  } else {
16137
16389
  res.writeHead(400, { "Content-Type": "text/html" });
16138
16390
  res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
@@ -16239,14 +16491,14 @@ __export(skill_symlink_exports, {
16239
16491
  healClaudeSkillLink: () => healClaudeSkillLink,
16240
16492
  healSkillLinkForCommand: () => healSkillLinkForCommand
16241
16493
  });
16242
- import { existsSync as existsSync8, lstatSync, mkdirSync as mkdirSync4, rmSync, symlinkSync } from "fs";
16494
+ import { existsSync as existsSync7, lstatSync, mkdirSync as mkdirSync5, rmSync, symlinkSync } from "fs";
16243
16495
  import { join as join10 } from "path";
16244
16496
  function healClaudeSkillLink(root) {
16245
16497
  try {
16246
16498
  const source = join10(root, ".agents", "skills", SKILL_NAME);
16247
- if (!existsSync8(join10(source, SKILL_FILENAME))) return false;
16499
+ if (!existsSync7(join10(source, SKILL_FILENAME))) return false;
16248
16500
  const link = join10(root, ".claude", "skills", SKILL_NAME);
16249
- if (existsSync8(join10(link, SKILL_FILENAME))) return false;
16501
+ if (existsSync7(join10(link, SKILL_FILENAME))) return false;
16250
16502
  let entry = null;
16251
16503
  try {
16252
16504
  entry = lstatSync(link);
@@ -16257,7 +16509,7 @@ function healClaudeSkillLink(root) {
16257
16509
  if (!entry.isSymbolicLink()) return false;
16258
16510
  rmSync(link, { force: true });
16259
16511
  }
16260
- mkdirSync4(join10(root, ".claude", "skills"), { recursive: true });
16512
+ mkdirSync5(join10(root, ".claude", "skills"), { recursive: true });
16261
16513
  symlinkSync(join10("..", "..", ".agents", "skills", SKILL_NAME), link, "dir");
16262
16514
  return true;
16263
16515
  } catch {
@@ -16344,10 +16596,10 @@ import * as readline2 from "readline";
16344
16596
  function prompt2(question, defaultValue) {
16345
16597
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
16346
16598
  const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
16347
- return new Promise((resolve7) => {
16599
+ return new Promise((resolve8) => {
16348
16600
  rl.question(display, (answer) => {
16349
16601
  rl.close();
16350
- resolve7(answer.trim() || defaultValue || "");
16602
+ resolve8(answer.trim() || defaultValue || "");
16351
16603
  });
16352
16604
  });
16353
16605
  }
@@ -16475,8 +16727,8 @@ async function tryOpenBrowser(url) {
16475
16727
  cmd = "xdg-open";
16476
16728
  args2 = [url];
16477
16729
  }
16478
- return new Promise((resolve7) => {
16479
- execFile(cmd, args2, (err) => resolve7(!err));
16730
+ return new Promise((resolve8) => {
16731
+ execFile(cmd, args2, (err) => resolve8(!err));
16480
16732
  });
16481
16733
  } catch {
16482
16734
  return false;
@@ -16541,9 +16793,9 @@ var init_base_id = __esm({
16541
16793
 
16542
16794
  // src/lib/worktree-scope.ts
16543
16795
  import { execFileSync as execFileSync2 } from "child_process";
16544
- import * as fs7 from "fs";
16545
- import * as path7 from "path";
16546
- import * as yaml4 from "js-yaml";
16796
+ import * as fs8 from "fs";
16797
+ import * as path8 from "path";
16798
+ import * as yaml5 from "js-yaml";
16547
16799
  function axisNoun(axis) {
16548
16800
  return AXES[axis].noun;
16549
16801
  }
@@ -16557,7 +16809,7 @@ function resolveGitDir() {
16557
16809
  encoding: "utf-8",
16558
16810
  stdio: ["pipe", "pipe", "pipe"]
16559
16811
  }).trim();
16560
- gitDir = raw ? path7.resolve(cwd, raw) : null;
16812
+ gitDir = raw ? path8.resolve(cwd, raw) : null;
16561
16813
  } catch {
16562
16814
  gitDir = null;
16563
16815
  }
@@ -16566,12 +16818,12 @@ function resolveGitDir() {
16566
16818
  }
16567
16819
  function getScopePath() {
16568
16820
  const gitDir = resolveGitDir();
16569
- return gitDir ? path7.join(gitDir, SCOPE_FILE) : null;
16821
+ return gitDir ? path8.join(gitDir, SCOPE_FILE) : null;
16570
16822
  }
16571
16823
  function legacyPaths() {
16572
16824
  const gitDir = resolveGitDir();
16573
16825
  if (!gitDir) return [];
16574
- return AXIS_ORDER.flatMap((axis) => AXES[axis].legacyFiles).map((f) => path7.join(gitDir, f));
16826
+ return AXIS_ORDER.flatMap((axis) => AXES[axis].legacyFiles).map((f) => path8.join(gitDir, f));
16575
16827
  }
16576
16828
  function emptyScope() {
16577
16829
  return { hubs: [], bases: [] };
@@ -16595,7 +16847,7 @@ function readLegacyAxis(axis) {
16595
16847
  for (const filename of legacyFiles) {
16596
16848
  let raw;
16597
16849
  try {
16598
- raw = fs7.readFileSync(path7.join(gitDir, filename), "utf-8");
16850
+ raw = fs8.readFileSync(path8.join(gitDir, filename), "utf-8");
16599
16851
  } catch (err) {
16600
16852
  if (err.code === "ENOENT") continue;
16601
16853
  throw err;
@@ -16610,7 +16862,7 @@ function readScope() {
16610
16862
  if (!scopePath) return emptyScope();
16611
16863
  let raw;
16612
16864
  try {
16613
- raw = fs7.readFileSync(scopePath, "utf-8");
16865
+ raw = fs8.readFileSync(scopePath, "utf-8");
16614
16866
  } catch (err) {
16615
16867
  if (err.code === "ENOENT") {
16616
16868
  return { hubs: readLegacyAxis("hubs"), bases: readLegacyAxis("bases") };
@@ -16619,7 +16871,7 @@ function readScope() {
16619
16871
  }
16620
16872
  let doc;
16621
16873
  try {
16622
- doc = yaml4.load(raw);
16874
+ doc = yaml5.load(raw);
16623
16875
  } catch {
16624
16876
  return emptyScope();
16625
16877
  }
@@ -16630,7 +16882,7 @@ function readScope() {
16630
16882
  function sweepLegacyFiles() {
16631
16883
  for (const legacyPath of legacyPaths()) {
16632
16884
  try {
16633
- fs7.unlinkSync(legacyPath);
16885
+ fs8.unlinkSync(legacyPath);
16634
16886
  } catch {
16635
16887
  }
16636
16888
  }
@@ -16646,14 +16898,14 @@ function writeScope(scope) {
16646
16898
  if (!scopePath) {
16647
16899
  throw expected("Not inside a git repository \u2014 cannot write the worktree scope.");
16648
16900
  }
16649
- const body = yaml4.dump({ hubs: scope.hubs, bases: scope.bases }, { flowLevel: 1 });
16901
+ const body = yaml5.dump({ hubs: scope.hubs, bases: scope.bases }, { flowLevel: 1 });
16650
16902
  const tmpPath = `${scopePath}.tmp-${process.pid}`;
16651
16903
  try {
16652
- fs7.writeFileSync(tmpPath, body, "utf-8");
16653
- fs7.renameSync(tmpPath, scopePath);
16904
+ fs8.writeFileSync(tmpPath, body, "utf-8");
16905
+ fs8.renameSync(tmpPath, scopePath);
16654
16906
  } catch (err) {
16655
16907
  try {
16656
- fs7.unlinkSync(tmpPath);
16908
+ fs8.unlinkSync(tmpPath);
16657
16909
  } catch {
16658
16910
  }
16659
16911
  throw asExpectedEnvironmentError(err);
@@ -16689,7 +16941,7 @@ function clearScope() {
16689
16941
  let removed = false;
16690
16942
  for (const target of [...scopePath ? [scopePath] : [], ...legacyPaths()]) {
16691
16943
  try {
16692
- fs7.unlinkSync(target);
16944
+ fs8.unlinkSync(target);
16693
16945
  removed = true;
16694
16946
  } catch (err) {
16695
16947
  if (err.code !== "ENOENT") throw err;
@@ -16794,7 +17046,6 @@ __export(status_exports, {
16794
17046
  parseArgs: () => parseArgs,
16795
17047
  statusCommand: () => statusCommand
16796
17048
  });
16797
- import * as path8 from "path";
16798
17049
  function parseArgs(args2) {
16799
17050
  return { json: args2.includes("--json") };
16800
17051
  }
@@ -16814,19 +17065,19 @@ function buildSkillState() {
16814
17065
  paths: installs.map((i) => i.path)
16815
17066
  };
16816
17067
  }
16817
- function buildWorkspaceState(repoConfig) {
16818
- if (!repoConfig) return { scoped: false, path: null, hub_count: 0 };
17068
+ function buildWorkspaceState(resolved) {
17069
+ if (!resolved) return { scoped: false, path: null, hub_count: 0 };
16819
17070
  const ws = detectWorkspace();
16820
- const gitRoot = ws?.gitRoot ?? findGitRoot();
16821
17071
  const hubCount = ws ? scanWorkspaceHubs(ws.workspaceDir).length : 0;
16822
- const yamlPath = gitRoot ? path8.join(gitRoot, ".wayai.yaml") : null;
16823
- return { scoped: true, path: yamlPath, hub_count: hubCount };
17072
+ return { scoped: true, path: resolved.path, hub_count: hubCount };
16824
17073
  }
16825
17074
  async function statusCommand(args2, pkg2) {
16826
17075
  const { json } = parseArgs(args2);
16827
17076
  const config = readConfig();
16828
- const repoConfig = readRepoConfig();
16829
- const workspace = buildWorkspaceState(repoConfig);
17077
+ const resolvedRepo = resolveRepoConfig();
17078
+ const repoConfig = resolvedRepo?.config ?? null;
17079
+ const workspace = buildWorkspaceState(resolvedRepo);
17080
+ const repoScopeBlocker = resolvedRepo ? null : readRepoScopeBlocker();
16830
17081
  const cachedCliLatest = readCachedLatest(CLI_CACHE_FILE);
16831
17082
  const cliLatest = cachedCliLatest && isNewerVersion(cachedCliLatest, pkg2.version) ? cachedCliLatest : null;
16832
17083
  const skill = buildSkillState();
@@ -16849,6 +17100,7 @@ async function statusCommand(args2, pkg2) {
16849
17100
  orgs: [],
16850
17101
  active_org: null,
16851
17102
  workspace,
17103
+ repo_scope_blocker: repoScopeBlocker,
16852
17104
  worktree_scope: scope,
16853
17105
  worktree_binding: { hub_id: boundHubId },
16854
17106
  worktree_lock: { hub_id: boundHubId }
@@ -16905,6 +17157,7 @@ async function statusCommand(args2, pkg2) {
16905
17157
  orgs,
16906
17158
  active_org: activeOrg,
16907
17159
  workspace,
17160
+ repo_scope_blocker: repoScopeBlocker,
16908
17161
  worktree_scope: scope,
16909
17162
  worktree_binding: { hub_id: boundHubId },
16910
17163
  worktree_lock: { hub_id: boundHubId }
@@ -16934,8 +17187,17 @@ async function statusCommand(args2, pkg2) {
16934
17187
  console.log(`Repository scope:`);
16935
17188
  console.log(` Organization: ${orgLine}`);
16936
17189
  console.log(` Hubs: ${workspace.hub_count}`);
17190
+ } else if (repoScopeBlocker?.kind === "conflict") {
17191
+ console.log("Repository scope: UNRESOLVED \u2014 two files name different organizations:");
17192
+ console.log(` ${WORKSPACE_MANIFEST_LABEL} -> ${repoScopeBlocker.manifest_organization_id}`);
17193
+ console.log(` ${ROOT_CONFIG_FILE} -> ${repoScopeBlocker.root_organization_id}`);
17194
+ console.log(` Delete or correct ${ROOT_CONFIG_FILE}; until then every command refuses.`);
17195
+ } else if (repoScopeBlocker?.kind === "invalid") {
17196
+ console.log(`Repository scope: UNRESOLVED \u2014 ${repoScopeBlocker.path} is unusable (${repoScopeBlocker.detail}).`);
16937
17197
  } else {
16938
- console.log("No .wayai.yaml found \u2014 run `wayai init` to scope this repo to an organization.");
17198
+ console.log(
17199
+ `No organization binding found in ${WORKSPACE_MANIFEST_LABEL} \u2014 run \`wayai init\` to scope this repo to an organization.`
17200
+ );
16939
17201
  }
16940
17202
  if (scope.hubs.length > 0 || scope.bases.length > 0) {
16941
17203
  console.log("Worktree scope: (run `wayai unbind` to clear)");
@@ -16952,6 +17214,7 @@ var init_status = __esm({
16952
17214
  init_config();
16953
17215
  init_auth();
16954
17216
  init_repo_config();
17217
+ init_workspace_manifest();
16955
17218
  init_workspace();
16956
17219
  init_worktree_scope();
16957
17220
  init_api_client();
@@ -17035,7 +17298,7 @@ var init_constants = __esm({
17035
17298
  });
17036
17299
 
17037
17300
  // src/lib/workspace-files.ts
17038
- import * as fs8 from "fs";
17301
+ import * as fs9 from "fs";
17039
17302
  import * as path9 from "path";
17040
17303
  function perHubAgentsMd(hubFolderName) {
17041
17304
  return [
@@ -17052,12 +17315,13 @@ function perHubAgentsMd(hubFolderName) {
17052
17315
  ].join("\n");
17053
17316
  }
17054
17317
  function isWorkspace(gitRoot) {
17055
- if (fs8.existsSync(path9.join(gitRoot, ".wayai.yaml"))) return true;
17318
+ if (fs9.existsSync(workspaceManifestPath(gitRoot))) return true;
17319
+ if (fs9.existsSync(rootConfigPath(gitRoot))) return true;
17056
17320
  return isDirectory(resolveLayout(gitRoot).hubsDir);
17057
17321
  }
17058
17322
  function writeIfAbsent(filePath, content) {
17059
- if (fs8.existsSync(filePath)) return null;
17060
- fs8.writeFileSync(filePath, content, "utf-8");
17323
+ if (fs9.existsSync(filePath)) return null;
17324
+ fs9.writeFileSync(filePath, content, "utf-8");
17061
17325
  return path9.basename(filePath);
17062
17326
  }
17063
17327
  function ensureWorkspaceFiles(gitRoot) {
@@ -17075,6 +17339,7 @@ var init_workspace_files = __esm({
17075
17339
  "use strict";
17076
17340
  init_constants();
17077
17341
  init_layout();
17342
+ init_workspace_manifest();
17078
17343
  CLAUDE_MD_SHIM = "@AGENTS.md\n";
17079
17344
  ROOT_AGENTS_MD = [
17080
17345
  "# Working with WayAI",
@@ -17112,12 +17377,12 @@ __export(init_exports, {
17112
17377
  initCommand: () => initCommand,
17113
17378
  parseArgs: () => parseArgs3
17114
17379
  });
17115
- import { mkdirSync as mkdirSync5 } from "fs";
17380
+ import { mkdirSync as mkdirSync6 } from "fs";
17116
17381
  import path10 from "path";
17117
17382
  function ensureHubsDir(gitRoot) {
17118
17383
  const hubsDir = resolveLayout(gitRoot).hubsDir;
17119
17384
  if (isDirectory(hubsDir)) return null;
17120
- mkdirSync5(hubsDir, { recursive: true });
17385
+ mkdirSync6(hubsDir, { recursive: true });
17121
17386
  return `${path10.relative(gitRoot, hubsDir)}/`;
17122
17387
  }
17123
17388
  function parseArgs3(args2) {
@@ -17252,18 +17517,18 @@ var init_init = __esm({
17252
17517
  });
17253
17518
 
17254
17519
  // src/lib/fs-safety.ts
17255
- import * as fs9 from "fs";
17520
+ import * as fs10 from "fs";
17256
17521
  import * as path11 from "path";
17257
17522
  function fileHasBytes(abs, data) {
17258
17523
  let st;
17259
17524
  try {
17260
- st = fs9.lstatSync(abs);
17525
+ st = fs10.lstatSync(abs);
17261
17526
  } catch {
17262
17527
  return false;
17263
17528
  }
17264
17529
  if (!st.isFile() || st.isSymbolicLink()) return false;
17265
17530
  try {
17266
- return fs9.readFileSync(abs).equals(data);
17531
+ return fs10.readFileSync(abs).equals(data);
17267
17532
  } catch {
17268
17533
  return false;
17269
17534
  }
@@ -17272,8 +17537,8 @@ function realpathContained(root, abs) {
17272
17537
  let realRoot;
17273
17538
  let realAbs;
17274
17539
  try {
17275
- realRoot = fs9.realpathSync(root);
17276
- realAbs = fs9.realpathSync(abs);
17540
+ realRoot = fs10.realpathSync(root);
17541
+ realAbs = fs10.realpathSync(abs);
17277
17542
  } catch {
17278
17543
  return false;
17279
17544
  }
@@ -17281,13 +17546,13 @@ function realpathContained(root, abs) {
17281
17546
  }
17282
17547
  function mkdirTolerateRace(dir) {
17283
17548
  try {
17284
- fs9.mkdirSync(dir);
17549
+ fs10.mkdirSync(dir);
17285
17550
  return true;
17286
17551
  } catch (err) {
17287
17552
  if (err.code !== "EEXIST") throw err;
17288
17553
  let st;
17289
17554
  try {
17290
- st = fs9.lstatSync(dir);
17555
+ st = fs10.lstatSync(dir);
17291
17556
  } catch {
17292
17557
  st = void 0;
17293
17558
  }
@@ -17299,7 +17564,7 @@ function ensureRealSubdirNoSymlink(root, target, create) {
17299
17564
  const targetResolved = path11.resolve(target);
17300
17565
  if (targetResolved !== rootResolved && !targetResolved.startsWith(rootResolved + path11.sep)) return false;
17301
17566
  try {
17302
- if (!fs9.lstatSync(rootResolved).isDirectory()) return false;
17567
+ if (!fs10.lstatSync(rootResolved).isDirectory()) return false;
17303
17568
  } catch {
17304
17569
  return false;
17305
17570
  }
@@ -17310,7 +17575,7 @@ function ensureRealSubdirNoSymlink(root, target, create) {
17310
17575
  cur = path11.join(cur, segment);
17311
17576
  let st;
17312
17577
  try {
17313
- st = fs9.lstatSync(cur);
17578
+ st = fs10.lstatSync(cur);
17314
17579
  } catch {
17315
17580
  st = void 0;
17316
17581
  }
@@ -17327,8 +17592,8 @@ function ensureRealSubdirNoSymlink(root, target, create) {
17327
17592
  function readFileNoFollow(root, abs) {
17328
17593
  if (!ensureRealSubdirNoSymlink(root, path11.dirname(abs), false)) return null;
17329
17594
  try {
17330
- if (!fs9.lstatSync(abs).isFile()) return null;
17331
- return fs9.readFileSync(abs);
17595
+ if (!fs10.lstatSync(abs).isFile()) return null;
17596
+ return fs10.readFileSync(abs);
17332
17597
  } catch {
17333
17598
  return null;
17334
17599
  }
@@ -17338,11 +17603,11 @@ function writeFileNoFollow(root, abs, data) {
17338
17603
  if (!ensureRealSubdirNoSymlink(root, parent, true)) return false;
17339
17604
  let st;
17340
17605
  try {
17341
- st = fs9.lstatSync(abs);
17606
+ st = fs10.lstatSync(abs);
17342
17607
  } catch {
17343
17608
  }
17344
- if (st?.isSymbolicLink()) fs9.rmSync(abs);
17345
- fs9.writeFileSync(abs, data);
17609
+ if (st?.isSymbolicLink()) fs10.rmSync(abs);
17610
+ fs10.writeFileSync(abs, data);
17346
17611
  return true;
17347
17612
  }
17348
17613
  var init_fs_safety = __esm({
@@ -17352,7 +17617,7 @@ var init_fs_safety = __esm({
17352
17617
  });
17353
17618
 
17354
17619
  // src/lib/resource-files.ts
17355
- import * as fs10 from "fs";
17620
+ import * as fs11 from "fs";
17356
17621
  import * as path12 from "path";
17357
17622
  import * as crypto3 from "crypto";
17358
17623
  function isBinaryFile(filename) {
@@ -17399,14 +17664,14 @@ function computeHash(data) {
17399
17664
  }
17400
17665
  function scanResourceFiles(dir, prefix = "") {
17401
17666
  const files = [];
17402
- const entries = fs10.readdirSync(dir, { withFileTypes: true });
17667
+ const entries = fs11.readdirSync(dir, { withFileTypes: true });
17403
17668
  for (const entry of entries) {
17404
17669
  const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
17405
17670
  if (entry.isDirectory()) {
17406
17671
  files.push(...scanResourceFiles(path12.join(dir, entry.name), relPath));
17407
17672
  } else if (entry.isFile()) {
17408
17673
  const fullPath = path12.join(dir, entry.name);
17409
- const stat2 = fs10.statSync(fullPath);
17674
+ const stat2 = fs11.statSync(fullPath);
17410
17675
  if (stat2.size > MAX_RESOURCE_FILE_SIZE3) {
17411
17676
  console.warn(` Warning: skipping ${relPath} (${(stat2.size / 1024 / 1024).toFixed(1)}MB exceeds 10MB limit)`);
17412
17677
  continue;
@@ -17416,7 +17681,7 @@ function scanResourceFiles(dir, prefix = "") {
17416
17681
  mime_type: guessMimeType(entry.name),
17417
17682
  file_size: stat2.size
17418
17683
  };
17419
- const data = fs10.readFileSync(fullPath);
17684
+ const data = fs11.readFileSync(fullPath);
17420
17685
  fileEntry.hash = computeHash(data);
17421
17686
  if (isBinaryFile(entry.name)) {
17422
17687
  fileEntry.content_base64 = data.toString("base64");
@@ -17476,7 +17741,7 @@ function writeResourceFileTree(resDir, files, root, log) {
17476
17741
  return;
17477
17742
  }
17478
17743
  if (files.length === 0) {
17479
- if (fs10.existsSync(resDir)) cleanOrphanFiles(resDir, "", /* @__PURE__ */ new Set(), root, log);
17744
+ if (fs11.existsSync(resDir)) cleanOrphanFiles(resDir, "", /* @__PURE__ */ new Set(), root, log);
17480
17745
  return;
17481
17746
  }
17482
17747
  const writtenPaths = /* @__PURE__ */ new Set();
@@ -17497,18 +17762,18 @@ function writeResourceFileTree(resDir, files, root, log) {
17497
17762
  writtenPaths.delete(file.path);
17498
17763
  }
17499
17764
  }
17500
- if (fs10.existsSync(resDir)) cleanOrphanFiles(resDir, "", writtenPaths, root, log);
17765
+ if (fs11.existsSync(resDir)) cleanOrphanFiles(resDir, "", writtenPaths, root, log);
17501
17766
  }
17502
17767
  function cleanOrphanFiles(dir, prefix, writtenPaths, root, log) {
17503
- const entries = fs10.readdirSync(dir, { withFileTypes: true });
17768
+ const entries = fs11.readdirSync(dir, { withFileTypes: true });
17504
17769
  for (const entry of entries) {
17505
17770
  const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
17506
17771
  const fullPath = path12.join(dir, entry.name);
17507
17772
  if (entry.isDirectory()) {
17508
17773
  cleanOrphanFiles(fullPath, relPath, writtenPaths, root, log);
17509
- if (fs10.readdirSync(fullPath).length === 0) fs10.rmdirSync(fullPath);
17774
+ if (fs11.readdirSync(fullPath).length === 0) fs11.rmdirSync(fullPath);
17510
17775
  } else if (!writtenPaths.has(relPath)) {
17511
- fs10.unlinkSync(fullPath);
17776
+ fs11.unlinkSync(fullPath);
17512
17777
  if (log && root) log.removed.push(path12.relative(root, fullPath));
17513
17778
  }
17514
17779
  }
@@ -17529,8 +17794,8 @@ async function downloadBinaryFiles(resDir, files, root, log) {
17529
17794
  }
17530
17795
  if (file.hash) {
17531
17796
  try {
17532
- const st = fs10.lstatSync(filePath);
17533
- if (st.isFile() && !st.isSymbolicLink() && computeHash(fs10.readFileSync(filePath)) === file.hash) continue;
17797
+ const st = fs11.lstatSync(filePath);
17798
+ if (st.isFile() && !st.isSymbolicLink() && computeHash(fs11.readFileSync(filePath)) === file.hash) continue;
17534
17799
  } catch {
17535
17800
  }
17536
17801
  }
@@ -17584,7 +17849,7 @@ var init_resource_files = __esm({
17584
17849
  });
17585
17850
 
17586
17851
  // src/lib/eval-attachments.ts
17587
- import * as fs11 from "fs";
17852
+ import * as fs12 from "fs";
17588
17853
  import * as path13 from "path";
17589
17854
  function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
17590
17855
  const raw = turn.attachments;
@@ -17608,7 +17873,7 @@ function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
17608
17873
  }
17609
17874
  let stat2;
17610
17875
  try {
17611
- stat2 = fs11.statSync(abs);
17876
+ stat2 = fs12.statSync(abs);
17612
17877
  } catch {
17613
17878
  }
17614
17879
  if (!stat2?.isFile()) {
@@ -17622,7 +17887,7 @@ function resolveTurnAttachments(hubFolder, turn, label, bytesByHash) {
17622
17887
  `${label}: attachment "${entry}" is ${(stat2.size / 1024 / 1024).toFixed(1)}MB, over the 10MB limit.`
17623
17888
  );
17624
17889
  }
17625
- const data = fs11.readFileSync(abs);
17890
+ const data = fs12.readFileSync(abs);
17626
17891
  const hash = computeHash(data);
17627
17892
  const fileName = path13.basename(abs);
17628
17893
  const mimeType = guessMimeType(fileName) ?? "application/octet-stream";
@@ -17730,16 +17995,16 @@ async function downloadEvalAttachments(hubFolder, downloads) {
17730
17995
  console.warn(` Warning: ${ATTACHMENTS_DIR}/ is not reachable inside the hub folder without a symlink; skipping attachment sync.`);
17731
17996
  return result;
17732
17997
  }
17733
- if (!fs11.existsSync(attachDir)) return result;
17998
+ if (!fs12.existsSync(attachDir)) return result;
17734
17999
  for (const dl of downloads) {
17735
18000
  const abs = path13.resolve(hubFolder, dl.relPath);
17736
18001
  if (abs !== attachDir && !abs.startsWith(attachDir + path13.sep)) continue;
17737
18002
  let existing;
17738
18003
  try {
17739
- existing = fs11.lstatSync(abs);
18004
+ existing = fs12.lstatSync(abs);
17740
18005
  } catch {
17741
18006
  }
17742
- if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(fs11.readFileSync(abs)) === dl.hash) {
18007
+ if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(fs12.readFileSync(abs)) === dl.hash) {
17743
18008
  continue;
17744
18009
  }
17745
18010
  try {
@@ -17757,11 +18022,11 @@ async function downloadEvalAttachments(hubFolder, downloads) {
17757
18022
  }
17758
18023
  }
17759
18024
  const keep = new Set(downloads.map((d) => path13.resolve(hubFolder, d.relPath)));
17760
- for (const name of fs11.readdirSync(attachDir)) {
18025
+ for (const name of fs12.readdirSync(attachDir)) {
17761
18026
  const abs = path13.join(attachDir, name);
17762
- const st = fs11.lstatSync(abs);
18027
+ const st = fs12.lstatSync(abs);
17763
18028
  if ((st.isFile() || st.isSymbolicLink()) && !keep.has(abs)) {
17764
- fs11.rmSync(abs);
18029
+ fs12.rmSync(abs);
17765
18030
  result.removed.push(path13.relative(hubFolder, abs));
17766
18031
  }
17767
18032
  }
@@ -17779,20 +18044,20 @@ var init_eval_attachments = __esm({
17779
18044
  });
17780
18045
 
17781
18046
  // src/lib/parser.ts
17782
- import * as fs12 from "fs";
18047
+ import * as fs13 from "fs";
17783
18048
  import * as path14 from "path";
17784
- import * as yaml5 from "js-yaml";
18049
+ import * as yaml6 from "js-yaml";
17785
18050
  function parseHubFolder(hubFolder, opts) {
17786
18051
  const yamlPath = resolveHubYamlPath(hubFolder);
17787
18052
  if (!yamlPath) {
17788
18053
  throw expected(`hub.yaml not found in ${hubFolder}`);
17789
18054
  }
17790
- const yamlContent = fs12.readFileSync(yamlPath, "utf-8");
18055
+ const yamlContent = fs13.readFileSync(yamlPath, "utf-8");
17791
18056
  let config;
17792
18057
  try {
17793
- config = yaml5.load(yamlContent);
18058
+ config = yaml6.load(yamlContent);
17794
18059
  } catch (err) {
17795
- if (err instanceof yaml5.YAMLException) {
18060
+ if (err instanceof yaml6.YAMLException) {
17796
18061
  throw expected(`Invalid YAML in ${yamlPath}: ${err.message}`);
17797
18062
  }
17798
18063
  throw err;
@@ -17815,8 +18080,8 @@ function parseHubFolder(hubFolder, opts) {
17815
18080
  if (typeof resolved.instructions === "string" && resolved.instructions.endsWith(".md")) {
17816
18081
  const instrValue = resolved.instructions;
17817
18082
  const instructionsPath = instrValue.startsWith("agents/") ? path14.join(hubFolder, instrValue) : path14.join(hubFolder, "agents", instrValue);
17818
- if (fs12.existsSync(instructionsPath)) {
17819
- resolved.instructions = fs12.readFileSync(instructionsPath, "utf-8");
18083
+ if (fs13.existsSync(instructionsPath)) {
18084
+ resolved.instructions = fs13.readFileSync(instructionsPath, "utf-8");
17820
18085
  } else {
17821
18086
  throw expected(
17822
18087
  `Agent instructions file not found: ${instructionsPath} (referenced by agent "${agent.name}")`
@@ -17824,8 +18089,8 @@ function parseHubFolder(hubFolder, opts) {
17824
18089
  }
17825
18090
  } else if (resolved.instructions === void 0 && typeof agent.name === "string") {
17826
18091
  const conventionPath = path14.join(hubFolder, "agents", `${slugify(agent.name)}.md`);
17827
- if (fs12.existsSync(conventionPath)) {
17828
- resolved.instructions = fs12.readFileSync(conventionPath, "utf-8");
18092
+ if (fs13.existsSync(conventionPath)) {
18093
+ resolved.instructions = fs13.readFileSync(conventionPath, "utf-8");
17829
18094
  }
17830
18095
  }
17831
18096
  return resolved;
@@ -17880,17 +18145,17 @@ function parseHubFolder(hubFolder, opts) {
17880
18145
  }
17881
18146
  function scanEvalYamlFiles(hubFolder, bytesByHash) {
17882
18147
  const evalsDir = path14.join(hubFolder, "evals");
17883
- if (!fs12.existsSync(evalsDir)) return [];
18148
+ if (!fs13.existsSync(evalsDir)) return [];
17884
18149
  const evals = [];
17885
18150
  const seen = /* @__PURE__ */ new Set();
17886
- const topEntries = fs12.readdirSync(evalsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
18151
+ const topEntries = fs13.readdirSync(evalsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
17887
18152
  for (const entry of topEntries) {
17888
18153
  if (entry.isFile() && entry.name.endsWith(".yaml")) {
17889
18154
  collectEval(evals, seen, path14.join(evalsDir, entry.name), `evals/${entry.name}`, null, hubFolder, bytesByHash);
17890
18155
  } else if (entry.isDirectory()) {
17891
18156
  const setName = entry.name;
17892
18157
  const setDir = path14.join(evalsDir, setName);
17893
- const setEntries = fs12.readdirSync(setDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
18158
+ const setEntries = fs13.readdirSync(setDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
17894
18159
  for (const sub of setEntries) {
17895
18160
  if (sub.isDirectory()) {
17896
18161
  throw expected(
@@ -17919,12 +18184,12 @@ function collectEval(evals, seen, filePath, relPath, setName, hubFolder, bytesBy
17919
18184
  evals.push(evalEntry);
17920
18185
  }
17921
18186
  function parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash) {
17922
- const content = fs12.readFileSync(filePath, "utf-8");
18187
+ const content = fs13.readFileSync(filePath, "utf-8");
17923
18188
  let raw;
17924
18189
  try {
17925
- raw = yaml5.load(content);
18190
+ raw = yaml6.load(content);
17926
18191
  } catch (err) {
17927
- if (err instanceof yaml5.YAMLException) {
18192
+ if (err instanceof yaml6.YAMLException) {
17928
18193
  throw expected(`Invalid YAML in ${relPath}: ${err.message}`);
17929
18194
  }
17930
18195
  throw err;
@@ -18022,10 +18287,10 @@ function parseFixtureField(raw, label, key) {
18022
18287
  }
18023
18288
  function scanJourneyYamlFiles(hubFolder, bytesByHash) {
18024
18289
  const journeysDir = path14.join(hubFolder, "journeys");
18025
- if (!fs12.existsSync(journeysDir)) return [];
18290
+ if (!fs13.existsSync(journeysDir)) return [];
18026
18291
  const journeys = [];
18027
18292
  const seen = /* @__PURE__ */ new Set();
18028
- const entries = fs12.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
18293
+ const entries = fs13.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
18029
18294
  for (const entry of entries) {
18030
18295
  if (entry.isDirectory()) {
18031
18296
  throw expected(
@@ -18046,12 +18311,12 @@ function scanJourneyYamlFiles(hubFolder, bytesByHash) {
18046
18311
  return journeys;
18047
18312
  }
18048
18313
  function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
18049
- const content = fs12.readFileSync(filePath, "utf-8");
18314
+ const content = fs13.readFileSync(filePath, "utf-8");
18050
18315
  let raw;
18051
18316
  try {
18052
- raw = yaml5.load(content);
18317
+ raw = yaml6.load(content);
18053
18318
  } catch (err) {
18054
- if (err instanceof yaml5.YAMLException) {
18319
+ if (err instanceof yaml6.YAMLException) {
18055
18320
  throw expected(`Invalid YAML in ${relPath}: ${err.message}`);
18056
18321
  }
18057
18322
  throw err;
@@ -18102,18 +18367,18 @@ function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
18102
18367
  }
18103
18368
  function scanAgentYamlFiles(hubFolder) {
18104
18369
  const agentsDir = path14.join(hubFolder, "agents");
18105
- if (!fs12.existsSync(agentsDir)) return [];
18106
- const yamlFiles = fs12.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml")).sort();
18370
+ if (!fs13.existsSync(agentsDir)) return [];
18371
+ const yamlFiles = fs13.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml")).sort();
18107
18372
  if (yamlFiles.length === 0) return [];
18108
18373
  const agents = [];
18109
18374
  for (const file of yamlFiles) {
18110
18375
  const filePath = path14.join(agentsDir, file);
18111
- const content = fs12.readFileSync(filePath, "utf-8");
18376
+ const content = fs13.readFileSync(filePath, "utf-8");
18112
18377
  let agent;
18113
18378
  try {
18114
- agent = yaml5.load(content);
18379
+ agent = yaml6.load(content);
18115
18380
  } catch (err) {
18116
- if (err instanceof yaml5.YAMLException) {
18381
+ if (err instanceof yaml6.YAMLException) {
18117
18382
  throw expected(`Invalid YAML in agents/${file}: ${err.message}`);
18118
18383
  }
18119
18384
  throw err;
@@ -18143,7 +18408,7 @@ function parseResources(hubFolder, configResources) {
18143
18408
  if (res.skill_name) resource.skill_name = res.skill_name;
18144
18409
  const resSlug = slugify(resource.name);
18145
18410
  const resDir = path14.join(resourcesDir, resSlug);
18146
- if (fs12.existsSync(resDir)) {
18411
+ if (fs13.existsSync(resDir)) {
18147
18412
  const files = scanResourceFiles(resDir, "");
18148
18413
  if (files.length > 0) {
18149
18414
  resource.files = files;
@@ -18191,9 +18456,9 @@ var init_diff_display = __esm({
18191
18456
  });
18192
18457
 
18193
18458
  // src/lib/yaml-writer.ts
18194
- import * as fs13 from "fs";
18459
+ import * as fs14 from "fs";
18195
18460
  import * as path15 from "path";
18196
- import * as yaml6 from "js-yaml";
18461
+ import * as yaml7 from "js-yaml";
18197
18462
  function writeFileIfChanged(hubFolder, absPath, content, log) {
18198
18463
  const buf = Buffer.from(content, "utf-8");
18199
18464
  if (fileHasBytes(absPath, buf)) return;
@@ -18242,15 +18507,15 @@ function buildEvalYamlObject(evalEntry, slug) {
18242
18507
  function writeHubFolder(hubFolder, payload, options = {}) {
18243
18508
  const log = { changed: [], removed: [] };
18244
18509
  const agentsDir = path15.join(hubFolder, "agents");
18245
- if (!fs13.existsSync(hubFolder)) {
18246
- fs13.mkdirSync(hubFolder, { recursive: true });
18510
+ if (!fs14.existsSync(hubFolder)) {
18511
+ fs14.mkdirSync(hubFolder, { recursive: true });
18247
18512
  }
18248
- if (!fs13.existsSync(agentsDir)) {
18249
- fs13.mkdirSync(agentsDir, { recursive: true });
18513
+ if (!fs14.existsSync(agentsDir)) {
18514
+ fs14.mkdirSync(agentsDir, { recursive: true });
18250
18515
  }
18251
18516
  const yamlPayload = buildYamlPayload(payload);
18252
18517
  const agentFiles = extractAgentFiles(payload);
18253
- const yamlContent = yaml6.dump(yamlPayload, YAML_DUMP_OPTIONS);
18518
+ const yamlContent = yaml7.dump(yamlPayload, YAML_DUMP_OPTIONS);
18254
18519
  writeFileIfChanged(hubFolder, path15.join(hubFolder, "hub.yaml"), yamlContent, log);
18255
18520
  if (options.seedAgentContext ?? true) {
18256
18521
  for (const seeded of [
@@ -18261,8 +18526,8 @@ function writeHubFolder(hubFolder, payload, options = {}) {
18261
18526
  }
18262
18527
  }
18263
18528
  const oldYamlPath = path15.join(hubFolder, "wayai.yaml");
18264
- if (fs13.existsSync(oldYamlPath)) {
18265
- fs13.unlinkSync(oldYamlPath);
18529
+ if (fs14.existsSync(oldYamlPath)) {
18530
+ fs14.unlinkSync(oldYamlPath);
18266
18531
  log.removed.push(path15.relative(hubFolder, oldYamlPath));
18267
18532
  }
18268
18533
  const yamlSlugs = writeAgentYamlFiles(hubFolder, agentsDir, payload.agents || [], log);
@@ -18271,20 +18536,20 @@ function writeHubFolder(hubFolder, payload, options = {}) {
18271
18536
  mdSlugs.add(slug);
18272
18537
  writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.md`), content, log);
18273
18538
  }
18274
- const existingFiles = fs13.readdirSync(agentsDir);
18539
+ const existingFiles = fs14.readdirSync(agentsDir);
18275
18540
  for (const file of existingFiles) {
18276
18541
  if (file.endsWith(".yaml")) {
18277
18542
  const slug = file.slice(0, -5);
18278
18543
  if (!yamlSlugs.has(slug)) {
18279
18544
  const orphan = path15.join(agentsDir, file);
18280
- fs13.unlinkSync(orphan);
18545
+ fs14.unlinkSync(orphan);
18281
18546
  log.removed.push(path15.relative(hubFolder, orphan));
18282
18547
  }
18283
18548
  } else if (file.endsWith(".md")) {
18284
18549
  const slug = file.slice(0, -3);
18285
18550
  if (!mdSlugs.has(slug)) {
18286
18551
  const orphan = path15.join(agentsDir, file);
18287
- fs13.unlinkSync(orphan);
18552
+ fs14.unlinkSync(orphan);
18288
18553
  log.removed.push(path15.relative(hubFolder, orphan));
18289
18554
  }
18290
18555
  }
@@ -18297,10 +18562,10 @@ function writeHubFolder(hubFolder, payload, options = {}) {
18297
18562
  function setPreviewLabelInHubYaml(hubFolder, label) {
18298
18563
  const yamlPath = resolveHubYamlPath(hubFolder);
18299
18564
  if (!yamlPath) return;
18300
- const obj = yaml6.load(fs13.readFileSync(yamlPath, "utf-8")) ?? {};
18565
+ const obj = yaml7.load(fs14.readFileSync(yamlPath, "utf-8")) ?? {};
18301
18566
  if (label) obj.preview_label = label;
18302
18567
  else delete obj.preview_label;
18303
- fs13.writeFileSync(yamlPath, yaml6.dump(obj, YAML_DUMP_OPTIONS), "utf-8");
18568
+ fs14.writeFileSync(yamlPath, yaml7.dump(obj, YAML_DUMP_OPTIONS), "utf-8");
18304
18569
  }
18305
18570
  function buildYamlPayload(payload) {
18306
18571
  const result = {
@@ -18345,7 +18610,7 @@ function writeAgentYamlFiles(hubFolder, agentsDir, agents, log) {
18345
18610
  slugs.add(slug);
18346
18611
  const entry = { ...agent };
18347
18612
  delete entry.instructions;
18348
- const yamlContent = yaml6.dump(entry, YAML_DUMP_OPTIONS);
18613
+ const yamlContent = yaml7.dump(entry, YAML_DUMP_OPTIONS);
18349
18614
  writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.yaml`), yamlContent, log);
18350
18615
  }
18351
18616
  return slugs;
@@ -18365,17 +18630,17 @@ function extractAgentFiles(payload) {
18365
18630
  function writeEvalYamlFiles(hubFolder, evals, log) {
18366
18631
  const evalsDir = path15.join(hubFolder, "evals");
18367
18632
  if (evals.length === 0) {
18368
- if (fs13.existsSync(evalsDir)) {
18633
+ if (fs14.existsSync(evalsDir)) {
18369
18634
  cleanEvalOrphans(hubFolder, evalsDir, /* @__PURE__ */ new Set(), log);
18370
18635
  try {
18371
- if (fs13.readdirSync(evalsDir).length === 0) fs13.rmdirSync(evalsDir);
18636
+ if (fs14.readdirSync(evalsDir).length === 0) fs14.rmdirSync(evalsDir);
18372
18637
  } catch {
18373
18638
  }
18374
18639
  }
18375
18640
  return;
18376
18641
  }
18377
- if (!fs13.existsSync(evalsDir)) {
18378
- fs13.mkdirSync(evalsDir, { recursive: true });
18642
+ if (!fs14.existsSync(evalsDir)) {
18643
+ fs14.mkdirSync(evalsDir, { recursive: true });
18379
18644
  }
18380
18645
  const writtenRelPaths = /* @__PURE__ */ new Set();
18381
18646
  for (const evalEntry of evals) {
@@ -18389,42 +18654,42 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
18389
18654
  }
18390
18655
  if (setName) {
18391
18656
  const setDir = path15.join(evalsDir, setName);
18392
- if (!fs13.existsSync(setDir)) {
18393
- fs13.mkdirSync(setDir, { recursive: true });
18657
+ if (!fs14.existsSync(setDir)) {
18658
+ fs14.mkdirSync(setDir, { recursive: true });
18394
18659
  }
18395
18660
  }
18396
- const yamlContent = yaml6.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);
18661
+ const yamlContent = yaml7.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);
18397
18662
  writeFileIfChanged(hubFolder, targetPath, yamlContent, log);
18398
18663
  writtenRelPaths.add(relPath);
18399
18664
  }
18400
18665
  cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log);
18401
18666
  }
18402
18667
  function cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log) {
18403
- const entries = fs13.readdirSync(evalsDir, { withFileTypes: true });
18668
+ const entries = fs14.readdirSync(evalsDir, { withFileTypes: true });
18404
18669
  for (const entry of entries) {
18405
18670
  const fullPath = path15.join(evalsDir, entry.name);
18406
18671
  if (entry.isFile()) {
18407
18672
  if (entry.name.endsWith(".yaml") && !writtenRelPaths.has(entry.name)) {
18408
- fs13.unlinkSync(fullPath);
18673
+ fs14.unlinkSync(fullPath);
18409
18674
  log.removed.push(path15.relative(hubFolder, fullPath));
18410
18675
  }
18411
18676
  continue;
18412
18677
  }
18413
18678
  if (entry.isDirectory()) {
18414
18679
  const setName = entry.name;
18415
- const subEntries = fs13.readdirSync(fullPath, { withFileTypes: true });
18680
+ const subEntries = fs14.readdirSync(fullPath, { withFileTypes: true });
18416
18681
  for (const sub of subEntries) {
18417
18682
  if (sub.isFile() && sub.name.endsWith(".yaml")) {
18418
18683
  const relPath = `${setName}/${sub.name}`;
18419
18684
  if (!writtenRelPaths.has(relPath)) {
18420
18685
  const orphan = path15.join(fullPath, sub.name);
18421
- fs13.unlinkSync(orphan);
18686
+ fs14.unlinkSync(orphan);
18422
18687
  log.removed.push(path15.relative(hubFolder, orphan));
18423
18688
  }
18424
18689
  }
18425
18690
  }
18426
18691
  try {
18427
- if (fs13.readdirSync(fullPath).length === 0) fs13.rmdirSync(fullPath);
18692
+ if (fs14.readdirSync(fullPath).length === 0) fs14.rmdirSync(fullPath);
18428
18693
  } catch {
18429
18694
  }
18430
18695
  }
@@ -18463,35 +18728,35 @@ function buildJourneyYamlObject(journeyEntry, slug) {
18463
18728
  function writeJourneyYamlFiles(hubFolder, journeys, log) {
18464
18729
  const journeysDir = path15.join(hubFolder, "journeys");
18465
18730
  if (journeys.length === 0) {
18466
- if (fs13.existsSync(journeysDir)) {
18731
+ if (fs14.existsSync(journeysDir)) {
18467
18732
  cleanJourneyOrphans(hubFolder, journeysDir, /* @__PURE__ */ new Set(), log);
18468
18733
  try {
18469
- if (fs13.readdirSync(journeysDir).length === 0) fs13.rmdirSync(journeysDir);
18734
+ if (fs14.readdirSync(journeysDir).length === 0) fs14.rmdirSync(journeysDir);
18470
18735
  } catch {
18471
18736
  }
18472
18737
  }
18473
18738
  return;
18474
18739
  }
18475
- if (!fs13.existsSync(journeysDir)) {
18476
- fs13.mkdirSync(journeysDir, { recursive: true });
18740
+ if (!fs14.existsSync(journeysDir)) {
18741
+ fs14.mkdirSync(journeysDir, { recursive: true });
18477
18742
  }
18478
18743
  const writtenFiles = /* @__PURE__ */ new Set();
18479
18744
  const usedSlugs = /* @__PURE__ */ new Set();
18480
18745
  for (const journeyEntry of journeys) {
18481
18746
  const slug = ensureUniqueSlug(slugify(journeyEntry.name), usedSlugs);
18482
18747
  const fileName = `${slug}.yaml`;
18483
- const yamlContent = yaml6.dump(buildJourneyYamlObject(journeyEntry, slug), YAML_DUMP_OPTIONS);
18748
+ const yamlContent = yaml7.dump(buildJourneyYamlObject(journeyEntry, slug), YAML_DUMP_OPTIONS);
18484
18749
  writeFileIfChanged(hubFolder, path15.join(journeysDir, fileName), yamlContent, log);
18485
18750
  writtenFiles.add(fileName);
18486
18751
  }
18487
18752
  cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log);
18488
18753
  }
18489
18754
  function cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log) {
18490
- const entries = fs13.readdirSync(journeysDir, { withFileTypes: true });
18755
+ const entries = fs14.readdirSync(journeysDir, { withFileTypes: true });
18491
18756
  for (const entry of entries) {
18492
18757
  if (entry.isFile() && entry.name.endsWith(".yaml") && !writtenFiles.has(entry.name)) {
18493
18758
  const orphan = path15.join(journeysDir, entry.name);
18494
- fs13.unlinkSync(orphan);
18759
+ fs14.unlinkSync(orphan);
18495
18760
  log.removed.push(path15.relative(hubFolder, orphan));
18496
18761
  }
18497
18762
  }
@@ -18505,12 +18770,12 @@ function writeResourceFiles(hubFolder, resources, log) {
18505
18770
  const resDir = path15.join(resourcesDir, resSlug);
18506
18771
  writeResourceFileTree(resDir, resource.files || [], hubFolder, log);
18507
18772
  }
18508
- if (fs13.existsSync(resourcesDir)) {
18509
- const existingDirs = fs13.readdirSync(resourcesDir, { withFileTypes: true });
18773
+ if (fs14.existsSync(resourcesDir)) {
18774
+ const existingDirs = fs14.readdirSync(resourcesDir, { withFileTypes: true });
18510
18775
  for (const entry of existingDirs) {
18511
18776
  if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
18512
18777
  const orphanDir = path15.join(resourcesDir, entry.name);
18513
- fs13.rmSync(orphanDir, { recursive: true, force: true });
18778
+ fs14.rmSync(orphanDir, { recursive: true, force: true });
18514
18779
  log.removed.push(`${path15.relative(hubFolder, orphanDir)}/`);
18515
18780
  }
18516
18781
  }
@@ -18599,15 +18864,15 @@ var init_terminal_output = __esm({
18599
18864
  });
18600
18865
 
18601
18866
  // src/lib/base-workspace.ts
18602
- import * as fs14 from "fs";
18867
+ import * as fs15 from "fs";
18603
18868
  import * as path17 from "path";
18604
- import * as yaml7 from "js-yaml";
18869
+ import * as yaml8 from "js-yaml";
18605
18870
  function readBaseMeta(folder) {
18606
18871
  const bytes = readFileNoFollow(folder, path17.join(folder, BASE_META_FILE));
18607
18872
  if (bytes === null) return null;
18608
18873
  let doc;
18609
18874
  try {
18610
- doc = yaml7.load(bytes.toString("utf-8"));
18875
+ doc = yaml8.load(bytes.toString("utf-8"));
18611
18876
  } catch {
18612
18877
  return null;
18613
18878
  }
@@ -18617,7 +18882,7 @@ function readBaseMeta(folder) {
18617
18882
  function listBaseFolders(basesDir) {
18618
18883
  let entries;
18619
18884
  try {
18620
- entries = fs14.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
18885
+ entries = fs15.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
18621
18886
  } catch {
18622
18887
  return [];
18623
18888
  }
@@ -18704,7 +18969,7 @@ function resolveBaseSelectorToId(gitRoot, selector) {
18704
18969
  }
18705
18970
  function hasBaseMetaFile(folder) {
18706
18971
  try {
18707
- return fs14.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
18972
+ return fs15.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
18708
18973
  } catch {
18709
18974
  return false;
18710
18975
  }
@@ -18722,25 +18987,17 @@ var init_base_workspace = __esm({
18722
18987
  });
18723
18988
 
18724
18989
  // src/lib/subtree-routing.ts
18725
- import * as fs15 from "fs";
18726
18990
  import * as path18 from "path";
18727
- import * as yaml8 from "js-yaml";
18728
18991
  function readRepoDefaults(gitRoot) {
18729
- const file = path18.join(gitRoot, WAYAI_LAYOUT.wsDir, REPO_DEFAULTS_FILE);
18730
- let doc;
18731
- try {
18732
- doc = yaml8.load(fs15.readFileSync(file, "utf-8"));
18733
- } catch {
18734
- return {};
18735
- }
18736
- if (!doc || typeof doc !== "object") return {};
18737
- const raw = doc;
18992
+ const load11 = loadWorkspaceManifest(gitRoot);
18993
+ if (load11.kind !== "ok") return {};
18994
+ const raw = load11.doc;
18738
18995
  const str = (v) => {
18739
18996
  if (typeof v !== "string" || !v.trim()) return void 0;
18740
18997
  const value = v.trim();
18741
18998
  if (value.includes("/") || value.includes(path18.sep) || value === "." || value === "..") {
18742
18999
  console.warn(
18743
- `Warning: ignoring ${JSON.stringify(value)} in ${WAYAI_LAYOUT.wsDir}/${REPO_DEFAULTS_FILE} \u2014 a default names a hub or base, not a path.`
19000
+ `Warning: ignoring ${JSON.stringify(value)} in ${WORKSPACE_MANIFEST_LABEL} \u2014 a default names a hub or base, not a path.`
18744
19001
  );
18745
19002
  return void 0;
18746
19003
  }
@@ -18828,11 +19085,11 @@ function routeSubtree(options) {
18828
19085
  return {
18829
19086
  ok: false,
18830
19087
  refusal: [
18831
- `\`wayai ${verb}\` does not take --org: it operates on the organization named by .wayai.yaml at the repo root.`,
19088
+ `\`wayai ${verb}\` does not take --org: it operates on the organization named by ${WORKSPACE_MANIFEST_LABEL}.`,
18832
19089
  "",
18833
19090
  "To act on another organization:",
18834
19091
  " wayai bases <command> --org <uuid> # the Data surface honors it",
18835
- " # or run from a checkout whose .wayai.yaml names that organization"
19092
+ " # or run from a checkout whose workspace manifest names that organization"
18836
19093
  ].join("\n")
18837
19094
  };
18838
19095
  }
@@ -18899,15 +19156,15 @@ function requireSubtree(verb, args2, gitRoot) {
18899
19156
  }
18900
19157
  return { subtree: result.subtree, selector: result.selector };
18901
19158
  }
18902
- var REPO_DEFAULTS_FILE, VALUE_FLAGS;
19159
+ var VALUE_FLAGS;
18903
19160
  var init_subtree_routing = __esm({
18904
19161
  "src/lib/subtree-routing.ts"() {
18905
19162
  "use strict";
18906
19163
  init_layout();
18907
19164
  init_terminal_output();
19165
+ init_workspace_manifest();
18908
19166
  init_workspace();
18909
19167
  init_base_workspace();
18910
- REPO_DEFAULTS_FILE = "wayai.yaml";
18911
19168
  VALUE_FLAGS = /* @__PURE__ */ new Set(["--hub", "--base", "--label", "--org"]);
18912
19169
  }
18913
19170
  });
@@ -18934,12 +19191,12 @@ async function createDataClient(orgId) {
18934
19191
  if (selected !== void 0 && !UUID_RE2.test(selected)) {
18935
19192
  throw expected(`Invalid --org: ${JSON.stringify(selected)}. Expected an organization UUID.`);
18936
19193
  }
18937
- const org = selected ?? readRepoConfig()?.organization_id;
19194
+ const org = selected ?? readRepoConfigUnlessBlocked()?.organization_id;
18938
19195
  async function requireOrgForSetupRoute(what) {
18939
19196
  const orgId2 = org ?? (await api.me()).org_id;
18940
19197
  if (!orgId2) {
18941
19198
  throw expected(
18942
- `No organization to ${what} against. Pass --org <uuid>, or run this from a repo with .wayai.yaml.`
19199
+ `No organization to ${what} against. Pass --org <uuid>, or run this from a repo scoped by \`wayai init\`.`
18943
19200
  );
18944
19201
  }
18945
19202
  return orgId2;
@@ -19025,7 +19282,7 @@ var init_client = __esm({
19025
19282
  });
19026
19283
 
19027
19284
  // src/data/helpers.ts
19028
- import { readFileSync as readFileSync16 } from "fs";
19285
+ import { readFileSync as readFileSync15 } from "fs";
19029
19286
  function pathSegment(id, label = "id") {
19030
19287
  if (!isPathSafeId(id)) {
19031
19288
  throw expected(`Invalid ${label}: ${JSON.stringify(id)}. An id may use ${PATH_SAFE_ID_RULE}.`);
@@ -19053,7 +19310,7 @@ function parseData(data, flag) {
19053
19310
  let text = data;
19054
19311
  if (source !== void 0) {
19055
19312
  try {
19056
- text = readFileSync16(source, "utf-8");
19313
+ text = readFileSync15(source, "utf-8");
19057
19314
  } catch (e) {
19058
19315
  throw expected(`${prefix}${source}: ${e instanceof Error ? e.message : "could not be read"}`);
19059
19316
  }
@@ -21148,9 +21405,10 @@ async function migrateCommand(_args) {
21148
21405
  const newOrg = path29.join(newWs, WAYAI_LAYOUT.orgSubdir);
21149
21406
  const hasLegacyWs = isDirectory(legacyWs);
21150
21407
  const hasLegacyOrg = isDirectory(legacyOrg);
21151
- if (!hasLegacyWs && !hasLegacyOrg) {
21152
- console.log(`Already migrated \u2014 no legacy ${WAYAI_LAYOUT.legacy.wsDir}/ or ${WAYAI_LAYOUT.legacy.orgAtRoot}/ to move.`);
21153
- return;
21408
+ const orgPlan = planOrgMigration(gitRoot);
21409
+ if (orgPlan.kind === "refuse") {
21410
+ console.error(orgPlan.message);
21411
+ process.exit(1);
21154
21412
  }
21155
21413
  if (hasLegacyWs && isDirectory(newHubs)) {
21156
21414
  console.error(
@@ -21176,10 +21434,30 @@ async function migrateCommand(_args) {
21176
21434
  usedFsFallback ||= how === "fs";
21177
21435
  moved.push(`${WAYAI_LAYOUT.legacy.orgAtRoot}/ \u2192 ${rel(newOrg)}/`);
21178
21436
  }
21179
- console.log(`Migrated to the ${WAYAI_LAYOUT.wsDir}/ layout:`);
21180
- for (const m of moved) console.log(` ${m}`);
21181
- if (usedFsFallback) {
21182
- console.log("\n(Some dirs were moved on disk, not via git \u2014 they will show as untracked.)");
21437
+ if (moved.length > 0) {
21438
+ console.log(`Migrated to the ${WAYAI_LAYOUT.wsDir}/ layout:`);
21439
+ for (const m of moved) console.log(` ${m}`);
21440
+ if (usedFsFallback) {
21441
+ console.log("\n(Some dirs were moved on disk, not via git \u2014 they will show as untracked.)");
21442
+ }
21443
+ }
21444
+ const copiedOrg = orgPlan.kind === "copy";
21445
+ if (copiedOrg) {
21446
+ writeRepoConfig(orgPlan.config, gitRoot);
21447
+ console.log(`${moved.length > 0 ? "\n" : ""}Copied the organization binding into ${WORKSPACE_MANIFEST_LABEL}.`);
21448
+ console.log(
21449
+ ` ${ROOT_CONFIG_FILE} is KEPT on purpose \u2014 an older CLI in a teammate's environment or in CI still requires it.`
21450
+ );
21451
+ console.log(
21452
+ " It stays a supported fallback until the next major, which removes both the fallback and the file."
21453
+ );
21454
+ console.log(" Delete it once every environment that runs this repo reads the manifest.");
21455
+ }
21456
+ if (moved.length === 0 && !copiedOrg) {
21457
+ console.log(
21458
+ `Already migrated \u2014 no legacy ${WAYAI_LAYOUT.legacy.wsDir}/ or ${WAYAI_LAYOUT.legacy.orgAtRoot}/ to move, and no organization binding to copy into ${WORKSPACE_MANIFEST_LABEL}.`
21459
+ );
21460
+ return;
21183
21461
  }
21184
21462
  console.log("\nNext steps:");
21185
21463
  console.log(' git add -A && git commit -m "chore: migrate to wayai-ws layout"');
@@ -21190,6 +21468,8 @@ var init_migrate = __esm({
21190
21468
  "use strict";
21191
21469
  init_workspace();
21192
21470
  init_layout();
21471
+ init_repo_config();
21472
+ init_workspace_manifest();
21193
21473
  }
21194
21474
  });
21195
21475
 
@@ -22583,8 +22863,8 @@ function installEvalSignalHandlers(input) {
22583
22863
  let signalCount = 0;
22584
22864
  let disposed = false;
22585
22865
  let settle;
22586
- const settled = new Promise((resolve7) => {
22587
- settle = resolve7;
22866
+ const settled = new Promise((resolve8) => {
22867
+ settle = resolve8;
22588
22868
  });
22589
22869
  const listeners = /* @__PURE__ */ new Map();
22590
22870
  const dispose = () => {
@@ -22934,7 +23214,7 @@ Timeout after ${timeoutSeconds}s${queuedSeconds > 0 ? ` (${queuedSeconds}s of it
22934
23214
  process.exit(1);
22935
23215
  }
22936
23216
  function sleep(ms) {
22937
- return new Promise((resolve7) => setTimeout(resolve7, ms));
23217
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
22938
23218
  }
22939
23219
  function parseRunNumbers(raw) {
22940
23220
  if (!raw || raw.startsWith("--")) {
@@ -25269,7 +25549,27 @@ async function adminCommand(args2) {
25269
25549
  await runHarnessToggle(true, flagArgs);
25270
25550
  return;
25271
25551
  case "status":
25272
- await runHarnessStatus(flagArgs);
25552
+ await runPlatformGateStatus(HARNESS_GATE, flagArgs);
25553
+ return;
25554
+ default:
25555
+ printHelp2();
25556
+ process.exit(1);
25557
+ }
25558
+ }
25559
+ if (group === "turn-state") {
25560
+ if (!sub) {
25561
+ printHelp2();
25562
+ process.exit(1);
25563
+ }
25564
+ switch (sub) {
25565
+ case "disable":
25566
+ await runTurnStateToggle(false, flagArgs);
25567
+ return;
25568
+ case "enable":
25569
+ await runTurnStateToggle(true, flagArgs);
25570
+ return;
25571
+ case "status":
25572
+ await runPlatformGateStatus(TURN_STATE_GATE, flagArgs);
25273
25573
  return;
25274
25574
  default:
25275
25575
  printHelp2();
@@ -25858,49 +26158,71 @@ async function runHarnessMassDestroy(flagArgs) {
25858
26158
  );
25859
26159
  }
25860
26160
  }
25861
- function rejectHarnessFlags(flagArgs, usage3) {
26161
+ function rejectPlatformGateFlags(gate, sub, flagArgs) {
25862
26162
  if (flagArgs.length === 0) return;
25863
26163
  console.error(`Unknown flag: ${flagArgs[0]}`);
25864
- console.error("The harness rollout gate is platform-wide; there is no --org/--hub layer.");
25865
- console.error(usage3);
26164
+ console.error(`The ${gate.label} is platform-wide; there is no --org/--hub layer.`);
26165
+ console.error(`wayai admin ${gate.group} ${sub}`);
25866
26166
  process.exit(1);
25867
26167
  }
25868
- async function runHarnessToggle(enable, flagArgs) {
25869
- const USAGE2 = "wayai admin harness enable|disable";
25870
- rejectHarnessFlags(flagArgs, USAGE2);
26168
+ function readGateValue(data, key) {
26169
+ const value = data[key];
26170
+ return typeof value === "number" ? value : void 0;
26171
+ }
26172
+ async function patchPlatformGate(gate, enable) {
25871
26173
  const { config, accessToken } = await requireAuth();
25872
26174
  const client = new ApiClient({ apiUrl: config.api_url, accessToken });
25873
- let value;
25874
26175
  try {
25875
- const res = await client.adminUpdateConfig({ harness_enabled: enable ? 1 : 0 });
25876
- value = res.data.harness_enabled;
26176
+ const res = await client.adminUpdateConfig({ [gate.key]: enable ? 1 : 0 });
26177
+ return readGateValue(res.data, gate.key);
25877
26178
  } catch (err) {
25878
26179
  exitOnApiError(err);
25879
26180
  throw err;
25880
26181
  }
25881
- const state = enable ? "ENABLED" : "DISABLED";
25882
- console.log(`Harness ${state} platform-wide (harness_enabled=${value ?? (enable ? 1 : 0)}).`);
25883
- if (enable) {
25884
- console.log("Harness agents may be created again and new harness turns may run.");
25885
- } else {
25886
- console.log("The per-turn kill switch now aborts every harness turn on its next invocation.");
25887
- console.log("Next: run `wayai admin harness mass-destroy --all --dry-run` to see what is still live, then reap it.");
25888
- }
25889
26182
  }
25890
- async function runHarnessStatus(flagArgs) {
25891
- const USAGE2 = "wayai admin harness status";
25892
- rejectHarnessFlags(flagArgs, USAGE2);
26183
+ async function runPlatformGateStatus(gate, flagArgs) {
26184
+ rejectPlatformGateFlags(gate, "status", flagArgs);
25893
26185
  const { config, accessToken } = await requireAuth();
25894
26186
  const client = new ApiClient({ apiUrl: config.api_url, accessToken });
25895
26187
  let value = 0;
25896
26188
  try {
25897
26189
  const res = await client.adminGetConfig();
25898
- value = res.data.harness_enabled ?? 0;
26190
+ value = readGateValue(res.data, gate.key) ?? 0;
25899
26191
  } catch (err) {
25900
26192
  exitOnApiError(err);
25901
26193
  throw err;
25902
26194
  }
25903
- console.log(`harness_enabled (platform): ${value} (${value ? "ENABLED" : "DISABLED"})`);
26195
+ console.log(`${gate.key} (platform): ${value} (${value ? "ENABLED" : "DISABLED"})`);
26196
+ }
26197
+ async function runHarnessToggle(enable, flagArgs) {
26198
+ rejectPlatformGateFlags(HARNESS_GATE, "enable|disable", flagArgs);
26199
+ const value = await patchPlatformGate(HARNESS_GATE, enable);
26200
+ const state = enable ? "ENABLED" : "DISABLED";
26201
+ console.log(`Harness ${state} platform-wide (harness_enabled=${value ?? (enable ? 1 : 0)}).`);
26202
+ if (enable) {
26203
+ console.log("Harness agents may be created again and new harness turns may run.");
26204
+ } else {
26205
+ console.log("The per-turn kill switch now aborts every harness turn on its next invocation.");
26206
+ console.log("Next: run `wayai admin harness mass-destroy --all --dry-run` to see what is still live, then reap it.");
26207
+ }
26208
+ }
26209
+ async function runTurnStateToggle(enable, flagArgs) {
26210
+ rejectPlatformGateFlags(TURN_STATE_GATE, "enable|disable", flagArgs);
26211
+ const value = await patchPlatformGate(TURN_STATE_GATE, enable);
26212
+ if (value === void 0) {
26213
+ console.error("PATCH /api/admin/config returned no turn_state_enabled value \u2014 the flag state is UNKNOWN.");
26214
+ console.error("Run `wayai admin turn-state status` to read what the platform config now holds.");
26215
+ process.exit(1);
26216
+ }
26217
+ const state = value ? "ENABLED" : "DISABLED";
26218
+ console.log(`TurnState conversion ${state} platform-wide (turn_state_enabled=${value}).`);
26219
+ if (value) {
26220
+ console.log("New turns run the converted TurnState body (runTurnWithState) once the platform-config cache clears \u2014 up to ~60s.");
26221
+ console.log("Roll back with `wayai admin turn-state disable` \u2014 the retained body stays compiled in while this flag is live.");
26222
+ } else {
26223
+ console.log("New turns run the RETAINED pre-conversion body (runTurnRetained) \u2014 the fail-closed default \u2014 once the platform-config cache clears, up to ~60s.");
26224
+ }
26225
+ console.log("Turns already in flight finish on the body they picked at entry.");
25904
26226
  }
25905
26227
  function requireFlagValue(flagArgs, index, flag) {
25906
26228
  const v = flagArgs[index];
@@ -26342,6 +26664,10 @@ Usage:
26342
26664
  wayai admin harness mass-destroy --all | --org <org_id> | --hub <hub_id> [--dry-run] [--yes] [--json]
26343
26665
  Reap every live harness sandbox/token/slot in scope (run --dry-run first to see the blast radius)
26344
26666
 
26667
+ wayai admin turn-state disable Flip the platform turn_state_enabled flag OFF (new turns run the RETAINED pre-conversion body \u2014 the fail-closed default)
26668
+ wayai admin turn-state enable Flip the platform turn_state_enabled flag ON (new turns run the converted TurnState body)
26669
+ wayai admin turn-state status Print the platform turn_state_enabled flag
26670
+
26345
26671
  Sources:
26346
26672
  do Live DO SQLite (existing conversation, hub config, etc.).
26347
26673
  analytics ClickHouse projections (conversation, message, schedule_event).
@@ -26399,6 +26725,15 @@ Sources:
26399
26725
  sandbox/token/slot that is live NOW (scope: --hub < --org < --all, prefer
26400
26726
  the narrowest). Run \`mass-destroy --dry-run\` first to see the blast
26401
26727
  radius. See docs/runbooks/harness-incident-response.md.
26728
+ turn-state The ConversationDO TurnState conversion gate. \`disable\`/\`enable\` flip the
26729
+ single PLATFORM-wide turn_state_enabled flag; \`status\` prints it. That one
26730
+ flag picks which turn body runs: OFF (default-deny, fail-closed \u2014 a
26731
+ platform-config read error lands here too) runs the RETAINED pre-conversion
26732
+ body, ON runs the converted TurnState body. Both stay compiled in while the
26733
+ flag is live, so \`disable\` is the rollback. The turn reads the flag at
26734
+ entry through the platform-config KV cache this write invalidates, so a
26735
+ flip propagates in up to ~60s, and a turn already in flight finishes on the
26736
+ body it picked.
26402
26737
 
26403
26738
  Types (do): ${VALID_TYPES.join(" | ")}
26404
26739
  Tables (analytics): ${VALID_ANALYTICS_TABLES.join(" | ")}
@@ -26428,6 +26763,9 @@ Examples:
26428
26763
  wayai admin harness mass-destroy --all --dry-run
26429
26764
  wayai admin harness mass-destroy --hub <hub-id> --yes
26430
26765
  wayai admin harness enable
26766
+ wayai admin turn-state status
26767
+ wayai admin turn-state enable
26768
+ wayai admin turn-state disable
26431
26769
 
26432
26770
  Audit + rate limit:
26433
26771
  Every successful read is logged as admin_debug_read (queryable in Grafana
@@ -26435,7 +26773,7 @@ Audit + rate limit:
26435
26773
  across all sources. Platform-admin grant required.
26436
26774
  `.trim());
26437
26775
  }
26438
- var VALID_TYPES, VALID_ANALYTICS_TABLES, VALID_NOTICE_SEVERITIES;
26776
+ var VALID_TYPES, VALID_ANALYTICS_TABLES, HARNESS_GATE, TURN_STATE_GATE, VALID_NOTICE_SEVERITIES;
26439
26777
  var init_admin = __esm({
26440
26778
  "src/commands/admin.ts"() {
26441
26779
  "use strict";
@@ -26450,6 +26788,16 @@ var init_admin = __esm({
26450
26788
  init_contracts();
26451
26789
  VALID_TYPES = dataExplorerDebugDoType.options;
26452
26790
  VALID_ANALYTICS_TABLES = dataExplorerDebugAnalyticsTable.options;
26791
+ HARNESS_GATE = {
26792
+ group: "harness",
26793
+ key: "harness_enabled",
26794
+ label: "harness rollout gate"
26795
+ };
26796
+ TURN_STATE_GATE = {
26797
+ group: "turn-state",
26798
+ key: "turn_state_enabled",
26799
+ label: "TurnState conversion gate"
26800
+ };
26453
26801
  VALID_NOTICE_SEVERITIES = ["critical", "warn", "info"];
26454
26802
  }
26455
26803
  });
@@ -26790,26 +27138,26 @@ async function reportGetCommand(args2) {
26790
27138
  console.log(JSON.stringify(result, null, 2));
26791
27139
  return;
26792
27140
  }
26793
- const { report, messages } = result;
26794
- const title = sanitizeTerminalText(report.title);
26795
- const description = sanitizeTerminalText(report.description);
26796
- console.log(`Report ${report.report_id}`);
27141
+ const { report: report2, messages } = result;
27142
+ const title = sanitizeTerminalText(report2.title);
27143
+ const description = sanitizeTerminalText(report2.description);
27144
+ console.log(`Report ${report2.report_id}`);
26797
27145
  console.log(` title: ${title}`);
26798
27146
  console.log(` description: ${description.replace(/\n/g, "\n ")}`);
26799
- console.log(` status: ${report.status}`);
26800
- console.log(` classification: ${report.classification}`);
26801
- if (report.contest_count > 0) console.log(` contests: ${report.contest_count}`);
26802
- if (report.dismissal_final) console.log(" dismissal: final (non-contestable)");
27147
+ console.log(` status: ${report2.status}`);
27148
+ console.log(` classification: ${report2.classification}`);
27149
+ if (report2.contest_count > 0) console.log(` contests: ${report2.contest_count}`);
27150
+ if (report2.dismissal_final) console.log(" dismissal: final (non-contestable)");
26803
27151
  if (messages.length > 0) {
26804
27152
  console.log("\n Thread:");
26805
27153
  for (const m of messages) {
26806
27154
  console.log(` [${m.author_role}] ${sanitizeTerminalText(m.body)}`);
26807
27155
  }
26808
27156
  }
26809
- if (report.status === "shipped") {
27157
+ if (report2.status === "shipped") {
26810
27158
  console.log(`
26811
- This fix is shipped. Run \`wayai report accept ${report.report_id}\` if it works,`);
26812
- console.log(` or \`wayai report contest ${report.report_id} --reason "..."\` if it does not.`);
27159
+ This fix is shipped. Run \`wayai report accept ${report2.report_id}\` if it works,`);
27160
+ console.log(` or \`wayai report contest ${report2.report_id} --reason "..."\` if it does not.`);
26813
27161
  }
26814
27162
  } catch (err) {
26815
27163
  reportActionError(err);
@@ -27089,7 +27437,7 @@ var init_actions = __esm({
27089
27437
 
27090
27438
  // src/data/commands/attachments.ts
27091
27439
  import { Command as Command2 } from "commander";
27092
- import { readFileSync as readFileSync21 } from "fs";
27440
+ import { readFileSync as readFileSync20 } from "fs";
27093
27441
  function findAttachmentByFilename(attachments, filename) {
27094
27442
  return attachments.find((a) => a.key.endsWith(`/${filename}`)) ?? null;
27095
27443
  }
@@ -27130,7 +27478,7 @@ function buildAttachmentsCommand() {
27130
27478
  printOutput(data, outputFormat(this));
27131
27479
  return;
27132
27480
  }
27133
- const body = readFileSync21(opts.file);
27481
+ const body = readFileSync20(opts.file);
27134
27482
  await client.upload(uploadPathFrom(data?.upload_url), body, opts.contentType);
27135
27483
  printOutput({ ...data, uploaded: true }, outputFormat(this));
27136
27484
  });
@@ -27610,16 +27958,16 @@ var init_providers = __esm({
27610
27958
 
27611
27959
  // src/data/commands/report.ts
27612
27960
  import { Command as Command6 } from "commander";
27613
- import { readFileSync as readFileSync22 } from "fs";
27614
- import { dirname as dirname11, join as join32 } from "path";
27961
+ import { readFileSync as readFileSync21 } from "fs";
27962
+ import { dirname as dirname12, join as join31 } from "path";
27615
27963
  import { fileURLToPath as fileURLToPath2 } from "url";
27616
27964
  function resolveCliVersion() {
27617
27965
  for (const candidate of [
27618
- join32(here, "..", "package.json"),
27619
- join32(here, "..", "..", "..", "package.json")
27966
+ join31(here, "..", "package.json"),
27967
+ join31(here, "..", "..", "..", "package.json")
27620
27968
  ]) {
27621
27969
  try {
27622
- const version = JSON.parse(readFileSync22(candidate, "utf-8")).version;
27970
+ const version = JSON.parse(readFileSync21(candidate, "utf-8")).version;
27623
27971
  if (typeof version === "string" && version) return version;
27624
27972
  } catch {
27625
27973
  }
@@ -27653,10 +28001,10 @@ function reportActionError2(err) {
27653
28001
  throw err;
27654
28002
  }
27655
28003
  function buildBasesReportCommand() {
27656
- const report = new Command6("report").description(
28004
+ const report2 = new Command6("report").description(
27657
28005
  "File a report to the Data triage queue and verify the outcome"
27658
28006
  );
27659
- report.command("create").description("Submit a report to the Data triage queue (deduplicated)").requiredOption("--title <title>", "Short summary").requiredOption("--description <text>", "What happened").option("--source <source>", "Origin: cli_report (default) | review | security_audit").option("--classification <c>", "Nature: bug (default) | flaky_test | security | enhancement").option(
28007
+ report2.command("create").description("Submit a report to the Data triage queue (deduplicated)").requiredOption("--title <title>", "Short summary").requiredOption("--description <text>", "What happened").option("--source <source>", "Origin: cli_report (default) | review | security_audit").option("--classification <c>", "Nature: bug (default) | flaky_test | security | enhancement").option(
27660
28008
  "--dedup-key <key>",
27661
28009
  'Stable dedup key (e.g. "<file>::<test>"); collapses repeat occurrences'
27662
28010
  ).option("--severity <level>", "low | medium | high | critical").option("--steps <text>", "Steps to reproduce").option("--error-message <text>", "Exact error text if any").option("--context <text>", "Additional context (logs, request ids)").option("--locale <code>", "Notification locale (en | pt | es)", "en").option("--reporter-email <addr>", "Override reporter email (defaults to session email)").option("--base-id <id>", "Base the error relates to (defaults to the configured base)").option("--record-type <name>", "Record type the error relates to").option("--record-id <id>", "Record id (UUID) the error relates to").option("--external-id <id>", "External id of the related record").option("--external-source <src>", "External source of the related record").option("--relationship-id <id>", "Relationship id the error relates to").action(async function(opts) {
@@ -27707,7 +28055,7 @@ function buildBasesReportCommand() {
27707
28055
  );
27708
28056
  }
27709
28057
  });
27710
- report.command("list").description("List your reports, newest first").option("--status <s>", "Filter by status (e.g. shipped \u2014 awaiting your verification)").action(async function(opts) {
28058
+ report2.command("list").description("List your reports, newest first").option("--status <s>", "Filter by status (e.g. shipped \u2014 awaiting your verification)").action(async function(opts) {
27711
28059
  const client = await createDataClient();
27712
28060
  const qs = opts.status ? `?status=${encodeURIComponent(opts.status)}` : "";
27713
28061
  try {
@@ -27730,7 +28078,7 @@ function buildBasesReportCommand() {
27730
28078
  reportActionError2(err);
27731
28079
  }
27732
28080
  });
27733
- report.command("get <report_id>").description("Show one of your reports: status + the message thread").action(async function(reportId) {
28081
+ report2.command("get <report_id>").description("Show one of your reports: status + the message thread").action(async function(reportId) {
27734
28082
  const client = await createDataClient();
27735
28083
  try {
27736
28084
  const data = await client.request("GET", `/v1/reports/${pathSegment(reportId, "report id")}`);
@@ -27767,7 +28115,7 @@ function buildBasesReportCommand() {
27767
28115
  reportActionError2(err);
27768
28116
  }
27769
28117
  });
27770
- report.command("accept <report_id>").description("Accept a shipped fix (\u2192 addressed)").action(async function(reportId) {
28118
+ report2.command("accept <report_id>").description("Accept a shipped fix (\u2192 addressed)").action(async function(reportId) {
27771
28119
  const client = await createDataClient();
27772
28120
  try {
27773
28121
  const data = await client.request(
@@ -27783,7 +28131,7 @@ function buildBasesReportCommand() {
27783
28131
  reportActionError2(err);
27784
28132
  }
27785
28133
  });
27786
- report.command("contest <report_id>").description("Contest a shipped fix or a dismissal (\u2192 back to triage)").requiredOption("--reason <text>", "Why the fix/dismissal is wrong").action(async function(reportId, opts) {
28134
+ report2.command("contest <report_id>").description("Contest a shipped fix or a dismissal (\u2192 back to triage)").requiredOption("--reason <text>", "Why the fix/dismissal is wrong").action(async function(reportId, opts) {
27787
28135
  const client = await createDataClient();
27788
28136
  try {
27789
28137
  const data = await client.request(
@@ -27802,7 +28150,7 @@ function buildBasesReportCommand() {
27802
28150
  reportActionError2(err);
27803
28151
  }
27804
28152
  });
27805
- return report;
28153
+ return report2;
27806
28154
  }
27807
28155
  var here;
27808
28156
  var init_report2 = __esm({
@@ -27815,13 +28163,13 @@ var init_report2 = __esm({
27815
28163
  init_terminal_output();
27816
28164
  init_workspace();
27817
28165
  init_skill_version();
27818
- here = dirname11(fileURLToPath2(import.meta.url));
28166
+ here = dirname12(fileURLToPath2(import.meta.url));
27819
28167
  }
27820
28168
  });
27821
28169
 
27822
28170
  // src/data/commands/credentials.ts
27823
28171
  import { Command as Command7 } from "commander";
27824
- import { readFileSync as readFileSync23 } from "fs";
28172
+ import { readFileSync as readFileSync22 } from "fs";
27825
28173
  function withValueSourceOptions(cmd, what) {
27826
28174
  return cmd.option(
27827
28175
  "--file <path>",
@@ -27834,7 +28182,7 @@ async function resolveValue(opts, label) {
27834
28182
  throw expected("--file cannot be combined with --value-stdin or --value-prompt \u2014 pass one.");
27835
28183
  }
27836
28184
  try {
27837
- return readFileSync23(opts.file).toString("base64");
28185
+ return readFileSync22(opts.file).toString("base64");
27838
28186
  } catch (e) {
27839
28187
  throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
27840
28188
  }
@@ -27983,7 +28331,7 @@ var init_credentials = __esm({
27983
28331
 
27984
28332
  // src/data/commands/sql.ts
27985
28333
  import { Command as Command8 } from "commander";
27986
- import { readFileSync as readFileSync24 } from "fs";
28334
+ import { readFileSync as readFileSync23 } from "fs";
27987
28335
  function buildBasesSqlCommand() {
27988
28336
  return withBaseOption(new Command8("sql")).description("Execute a read-only SQL query against base data").argument("[query]", "SQL query (SELECT only)").option("--file <path>", "Read SQL from a file instead of the argument").option(
27989
28337
  "--param <kv...>",
@@ -27993,7 +28341,7 @@ function buildBasesSqlCommand() {
27993
28341
  let query;
27994
28342
  if (opts.file) {
27995
28343
  try {
27996
- query = readFileSync24(opts.file, "utf-8").trim();
28344
+ query = readFileSync23(opts.file, "utf-8").trim();
27997
28345
  } catch (e) {
27998
28346
  throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
27999
28347
  }
@@ -28648,7 +28996,7 @@ var init_file_types = __esm({
28648
28996
 
28649
28997
  // src/data/commands/files.ts
28650
28998
  import { Command as Command12 } from "commander";
28651
- import { readFileSync as readFileSync25, writeFileSync as writeFileSync16 } from "fs";
28999
+ import { readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "fs";
28652
29000
  import { basename as basename18 } from "path";
28653
29001
  function renderFileDiff(fileType, filePath, from, to, d) {
28654
29002
  console.log(sanitizeTerminalText(`${fileType}/${filePath}: v${from} \u2192 v${to}`));
@@ -28697,7 +29045,7 @@ function buildFilesCommand() {
28697
29045
  "Upload a local file to a path (e.g. wayai files put reports q3/summary.pdf --file ./summary.pdf)"
28698
29046
  ).requiredOption("--file <local>", "Local file to upload").option("--content-type <type>", "MIME type", "application/octet-stream").action(async function(fileType, filePath, opts) {
28699
29047
  const base = pathSegment(requireBase(this), "--base");
28700
- const body = readFileSync25(opts.file);
29048
+ const body = readFileSync24(opts.file);
28701
29049
  const client = await createDataClient();
28702
29050
  printOutput(
28703
29051
  await client.upload(
@@ -29658,7 +30006,7 @@ __export(program_exports, {
29658
30006
  });
29659
30007
  import { Command as Command22 } from "commander";
29660
30008
  function withDataGlobals(command2) {
29661
- return command2.option("--org <uuid>", "Organization to operate against (overrides .wayai.yaml)").option("--output <format>", "Output format: json or table", "table").option("--json", "Shorthand for --output json");
30009
+ return command2.option("--org <uuid>", "Organization to operate against (overrides the repo's org binding)").option("--output <format>", "Output format: json or table", "table").option("--json", "Shorthand for --output json");
29662
30010
  }
29663
30011
  function routeErrorsToCli(command2) {
29664
30012
  command2.exitOverride().configureOutput({ outputError: () => {
@@ -29746,9 +30094,9 @@ init_errors2();
29746
30094
  init_mask_secrets();
29747
30095
  init_utils();
29748
30096
  init_registry();
29749
- import { readFileSync as readFileSync26 } from "fs";
30097
+ import { readFileSync as readFileSync25 } from "fs";
29750
30098
  import { fileURLToPath as fileURLToPath3 } from "url";
29751
- import { dirname as dirname12, join as join33 } from "path";
30099
+ import { dirname as dirname13, join as join32 } from "path";
29752
30100
 
29753
30101
  // src/lib/version-refresh.ts
29754
30102
  init_version_cache();
@@ -29756,7 +30104,7 @@ init_skill_version();
29756
30104
  import { exec } from "child_process";
29757
30105
  var REFRESH_TIMEOUT_MS = 1e4;
29758
30106
  function refreshCliCache() {
29759
- return new Promise((resolve7) => {
30107
+ return new Promise((resolve8) => {
29760
30108
  exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
29761
30109
  if (!err) {
29762
30110
  const latest = stdout.trim();
@@ -29767,7 +30115,7 @@ function refreshCliCache() {
29767
30115
  }
29768
30116
  }
29769
30117
  }
29770
- resolve7();
30118
+ resolve8();
29771
30119
  });
29772
30120
  });
29773
30121
  }
@@ -29793,8 +30141,8 @@ async function refreshSkillCache() {
29793
30141
  }
29794
30142
  async function refreshAdminSkillCache() {
29795
30143
  let timer;
29796
- const deadline = new Promise((resolve7) => {
29797
- timer = setTimeout(resolve7, REFRESH_TIMEOUT_MS);
30144
+ const deadline = new Promise((resolve8) => {
30145
+ timer = setTimeout(resolve8, REFRESH_TIMEOUT_MS);
29798
30146
  });
29799
30147
  await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
29800
30148
  })]);
@@ -29903,8 +30251,8 @@ Run \`wayai admin skill install\` to update.`);
29903
30251
  }
29904
30252
 
29905
30253
  // src/index.ts
29906
- var __dirname = dirname12(fileURLToPath3(import.meta.url));
29907
- var pkg = JSON.parse(readFileSync26(join33(__dirname, "..", "package.json"), "utf-8"));
30254
+ var __dirname = dirname13(fileURLToPath3(import.meta.url));
30255
+ var pkg = JSON.parse(readFileSync25(join32(__dirname, "..", "package.json"), "utf-8"));
29908
30256
  var [, , command, ...args] = process.argv;
29909
30257
  var isBackgroundRefresh = command === REFRESH_COMMAND;
29910
30258
  if (!isBackgroundRefresh) initSentry(command, pkg.version);
@@ -30139,7 +30487,7 @@ Commands:
30139
30487
  logout Clear stored credentials
30140
30488
  status Show current auth and config status
30141
30489
  whoami Show the authenticated identity (supports --json)
30142
- init Set up .wayai.yaml (pick organization)
30490
+ init Scope this repo to an organization (pick one)
30143
30491
  create-credential Create an organization credential (API key, token, etc.)
30144
30492
  update-credential Update / rotate an organization credential (by name)
30145
30493
  set-connection-credential Set a connection's credential directly (org link or --field/--stdin), preview or production
@@ -30222,7 +30570,7 @@ Flags:
30222
30570
  --version, -v Show CLI version
30223
30571
 
30224
30572
  Org-scoped mode:
30225
- Each repository is scoped to a single organization via .wayai.yaml
30573
+ Each repository is scoped to a single organization via wayai-ws/wayai.yaml
30226
30574
  (only \`organization_id\` is required). Hubs self-identify via \`hub.yaml\`
30227
30575
  inside their folder under \`workspace/\`.
30228
30576