export const PRODUCT_OVERVIEW_FILENAME = 'PRODUCT_OVERVIEW.md'; export const LEGACY_PROMOTION_PLAN_FILENAME = 'PROMOTION_PLAN.md'; export const PROJECT_TYPES = ['interactive_ai_app', 'custom'] as const; export type ProjectType = (typeof PROJECT_TYPES)[number]; const LEGACY_INTERACTIVE_PROJECT_TYPES = new Set(['mini_game', 'mini_program']); export function isProjectType(value: unknown): value is ProjectType { return typeof value === 'string' && PROJECT_TYPES.includes(value as ProjectType); } export function normalizeProjectType(value: unknown): ProjectType | undefined { if (isProjectType(value)) return value; if (typeof value === 'string' && LEGACY_INTERACTIVE_PROJECT_TYPES.has(value)) { return 'interactive_ai_app'; } return undefined; } export type ProjectAgentResponsibility = { mission: string; owns: string[]; boundaries: string[]; collaborators: string[]; principles: string[]; }; export const MAX_PROJECT_AGENT_AVATAR_DATA_URL_LENGTH = 800_000; const PROJECT_AGENT_AVATAR_DATA_URL_PATTERN = /^data:image\/(?:webp|png|jpeg);base64,[A-Za-z0-9+/]+={0,2}$/u; export function isProjectAgentAvatarDataUrl(value: unknown): value is string { return typeof value === 'string' && value.length <= MAX_PROJECT_AGENT_AVATAR_DATA_URL_LENGTH && PROJECT_AGENT_AVATAR_DATA_URL_PATTERN.test(value); }