export const CURSOR_CHANNEL_FEATURES = Object.freeze({ PAGE_GENERATE: 'pageGenerate', PAGE_DATA: 'pageData', EXCEL_ANALYSIS: 'excelAnalysis', CHAT_BRIDGE: 'chatBridge', SCHEDULED_TASKS: 'scheduledTasks', }); export const CURSOR_TASK_KIND = Object.freeze({ PAGE_GENERATION: 'page_generation', PAGE_DATA: 'page_data', EXCEL_ANALYSIS: 'excel_analysis', }); const TASK_KIND_TO_FEATURE = Object.freeze({ [CURSOR_TASK_KIND.PAGE_GENERATION]: CURSOR_CHANNEL_FEATURES.PAGE_GENERATE, [CURSOR_TASK_KIND.PAGE_DATA]: CURSOR_CHANNEL_FEATURES.PAGE_DATA, [CURSOR_TASK_KIND.EXCEL_ANALYSIS]: CURSOR_CHANNEL_FEATURES.EXCEL_ANALYSIS, }); export function defaultCursorChannelFeatures() { return { [CURSOR_CHANNEL_FEATURES.PAGE_GENERATE]: { enabled: true }, [CURSOR_CHANNEL_FEATURES.PAGE_DATA]: { enabled: false }, [CURSOR_CHANNEL_FEATURES.EXCEL_ANALYSIS]: { enabled: false }, [CURSOR_CHANNEL_FEATURES.CHAT_BRIDGE]: { enabled: false }, [CURSOR_CHANNEL_FEATURES.SCHEDULED_TASKS]: { enabled: false }, }; } function normalizeFeatureFlag(value, fallback = false) { if (value == null) return fallback; if (typeof value === 'boolean') return value; if (typeof value === 'object' && value !== null && 'enabled' in value) { return normalizeFeatureFlag(value.enabled, fallback); } const normalized = String(value).trim().toLowerCase(); if (['1', 'true', 'yes', 'on'].includes(normalized)) return true; if (['0', 'false', 'no', 'off'].includes(normalized)) return false; return fallback; } export function normalizeCursorChannelFeatures(rawFeatures, { intentAllowlist = ['page.generate'], } = {}) { const defaults = defaultCursorChannelFeatures(); const source = rawFeatures && typeof rawFeatures === 'object' ? rawFeatures : {}; const legacyIntents = Array.isArray(intentAllowlist) ? intentAllowlist.map((item) => String(item ?? '').trim()).filter(Boolean) : []; const hasExplicitFeatures = Object.keys(source).length > 0; return { [CURSOR_CHANNEL_FEATURES.PAGE_GENERATE]: { enabled: hasExplicitFeatures ? normalizeFeatureFlag( source[CURSOR_CHANNEL_FEATURES.PAGE_GENERATE], legacyIntents.includes('page.generate'), ) : legacyIntents.includes('page.generate'), }, [CURSOR_CHANNEL_FEATURES.PAGE_DATA]: { enabled: normalizeFeatureFlag(source[CURSOR_CHANNEL_FEATURES.PAGE_DATA], false), }, [CURSOR_CHANNEL_FEATURES.EXCEL_ANALYSIS]: { enabled: normalizeFeatureFlag(source[CURSOR_CHANNEL_FEATURES.EXCEL_ANALYSIS], false), }, [CURSOR_CHANNEL_FEATURES.CHAT_BRIDGE]: { enabled: normalizeFeatureFlag(source[CURSOR_CHANNEL_FEATURES.CHAT_BRIDGE], false), }, [CURSOR_CHANNEL_FEATURES.SCHEDULED_TASKS]: { enabled: normalizeFeatureFlag(source[CURSOR_CHANNEL_FEATURES.SCHEDULED_TASKS], false), }, }; } export function intentAllowlistFromFeatures(features) { const normalized = normalizeCursorChannelFeatures(features); const intents = []; if (normalized[CURSOR_CHANNEL_FEATURES.PAGE_GENERATE]?.enabled) { intents.push('page.generate'); } return intents.length > 0 ? intents : ['page.generate']; } export function isCursorFeatureEnabled(policy, featureKey) { if (!policy?.enabled) return false; const features = policy.features ?? normalizeCursorChannelFeatures(null, { intentAllowlist: policy.intentAllowlist }); return normalizeFeatureFlag(features?.[featureKey], false); } export function isCursorTaskKindEnabled(policy, taskKind) { const featureKey = TASK_KIND_TO_FEATURE[String(taskKind ?? '').trim()]; if (!featureKey) return false; return isCursorFeatureEnabled(policy, featureKey); }