export const PRODUCT_OVERVIEW_FILENAME = 'PRODUCT_OVERVIEW.md'; export const LEGACY_PROMOTION_PLAN_FILENAME = 'PROMOTION_PLAN.md'; export type ProjectAgentResponsibility = { mission: string; owns: string[]; boundaries: string[]; collaborators: string[]; principles: string[]; }; export type ProjectAgentConfig = { id: string; avatarId: string; roleName: string; name: string; builtIn: boolean; enabled: boolean; model: string | null; skillIds: string[]; responsibility: ProjectAgentResponsibility; prompt: string; archivedAt?: string | null; pinned?: boolean; createdAt?: string; updatedAt?: string; }; export type ProjectConfig = { schemaVersion: 1; initialized: boolean; superpowersEnabled: boolean; defaultModel: string | null; agents: ProjectAgentConfig[]; knowledgeDirectory: 'knowledge'; createdAt: string; updatedAt: string; }; export function createProjectConfig(now = new Date().toISOString()): ProjectConfig { return { schemaVersion: 1, initialized: false, superpowersEnabled: false, defaultModel: null, agents: [], knowledgeDirectory: 'knowledge', createdAt: now, updatedAt: now, }; } export function validateAgentNames(agents: ProjectAgentConfig[]): string[] { const errors: string[] = []; const names = new Set(); for (const item of agents) { const name = item.name.trim(); if (!name) errors.push(`${item.id}:name-required`); if (name.length > 30) errors.push(`${item.id}:name-too-long`); const key = name.toLocaleLowerCase(); if (key && names.has(key)) errors.push(`${item.id}:name-duplicate`); names.add(key); } return errors; } export function validateAgentConfigs(agents: ProjectAgentConfig[]): string[] { const errors = validateAgentNames(agents); for (const agent of agents) { if (!/^avatar-(0[1-9]|1[0-6])$/.test(agent.avatarId)) { errors.push(`${agent.id}:avatar-required`); } if (!agent.model?.trim()) { errors.push(`${agent.id}:model-required`); } if (!agent.responsibility.mission.trim()) { errors.push(`${agent.id}:responsibility-required`); } } return errors; }