import type { CommunicationStyle, SoulConfig, UserConfig, ToolsConfig, GitProvider } from '../types.js'; import { DEFAULTS } from '../constants.js'; import type { TemplateVars } from './engine.js'; /** * Build behavioral principles text based on communication style. * Replicates mosaic-init lines 177-204 exactly. */ function buildBehavioralPrinciples( style: CommunicationStyle, accessibility?: string, ): string { let principles: string; switch (style) { case 'direct': principles = `1. Clarity over performance theater. 2. Practical execution over abstract planning. 3. Truthfulness over confidence: state uncertainty explicitly. 4. Visible state over hidden assumptions. 5. Accessibility-aware — see \`~/.config/mosaic/USER.md\` for user-specific accommodations.`; break; case 'friendly': principles = `1. Be helpful and approachable while staying efficient. 2. Provide context and explain reasoning when helpful. 3. Truthfulness over confidence: state uncertainty explicitly. 4. Visible state over hidden assumptions. 5. Accessibility-aware — see \`~/.config/mosaic/USER.md\` for user-specific accommodations.`; break; case 'formal': principles = `1. Maintain professional, structured communication. 2. Provide thorough analysis with explicit tradeoffs. 3. Truthfulness over confidence: state uncertainty explicitly. 4. Document decisions and rationale clearly. 5. Accessibility-aware — see \`~/.config/mosaic/USER.md\` for user-specific accommodations.`; break; } if (accessibility && accessibility !== 'none' && accessibility.length > 0) { principles += `\n6. ${accessibility}.`; } return principles; } /** * Build communication style text based on style choice. * Replicates mosaic-init lines 208-227 exactly. */ function buildCommunicationStyleText(style: CommunicationStyle): string { switch (style) { case 'direct': return `- Be direct, concise, and concrete. - Avoid fluff, hype, and anthropomorphic roleplay. - Do not simulate certainty when facts are missing. - Prefer actionable next steps and explicit tradeoffs.`; case 'friendly': return `- Be warm and conversational while staying focused. - Explain your reasoning when it helps the user. - Do not simulate certainty when facts are missing. - Prefer actionable next steps with clear context.`; case 'formal': return `- Use professional, structured language. - Provide thorough explanations with supporting detail. - Do not simulate certainty when facts are missing. - Present options with explicit tradeoffs and recommendations.`; } } /** * Build communication preferences for USER.md based on style. * Replicates mosaic-init lines 299-316 exactly. */ function buildCommunicationPrefs(style: CommunicationStyle): string { switch (style) { case 'direct': return `- Direct and concise - No sycophancy - Executive summaries and tables for overview`; case 'friendly': return `- Warm and conversational - Explain reasoning when helpful - Balance thoroughness with brevity`; case 'formal': return `- Professional and structured - Thorough explanations with supporting detail - Formal tone with explicit recommendations`; } } /** * Build git providers markdown table from provider list. * Replicates mosaic-init lines 362-384. */ function buildGitProvidersTable(providers?: GitProvider[]): string { if (!providers || providers.length === 0) { return DEFAULTS.gitProvidersTable; } const rows = providers .map((p) => `| ${p.name} | ${p.url} | \`${p.cli}\` | ${p.purpose} |`) .join('\n'); return `| Instance | URL | CLI | Purpose | |----------|-----|-----|---------| ${rows}`; } export function buildSoulTemplateVars(config: SoulConfig): TemplateVars { const style = config.communicationStyle ?? 'direct'; const guardrails = config.customGuardrails ? `- ${config.customGuardrails}` : ''; return { AGENT_NAME: config.agentName ?? DEFAULTS.agentName, ROLE_DESCRIPTION: config.roleDescription ?? DEFAULTS.roleDescription, BEHAVIORAL_PRINCIPLES: buildBehavioralPrinciples(style, config.accessibility), COMMUNICATION_STYLE: buildCommunicationStyleText(style), CUSTOM_GUARDRAILS: guardrails, }; } export function buildUserTemplateVars(config: UserConfig): TemplateVars { return { USER_NAME: config.userName ?? '', PRONOUNS: config.pronouns ?? DEFAULTS.pronouns, TIMEZONE: config.timezone ?? DEFAULTS.timezone, BACKGROUND: config.background ?? DEFAULTS.background, ACCESSIBILITY_SECTION: config.accessibilitySection ?? DEFAULTS.accessibilitySection, COMMUNICATION_PREFS: config.communicationPrefs ?? buildCommunicationPrefs('direct'), PERSONAL_BOUNDARIES: config.personalBoundaries ?? DEFAULTS.personalBoundaries, PROJECTS_TABLE: config.projectsTable ?? DEFAULTS.projectsTable, }; } export function buildToolsTemplateVars(config: ToolsConfig): TemplateVars { return { GIT_PROVIDERS_TABLE: buildGitProvidersTable(config.gitProviders), CREDENTIALS_LOCATION: config.credentialsLocation ?? DEFAULTS.credentialsLocation, CUSTOM_TOOLS_SECTION: config.customToolsSection ?? DEFAULTS.customToolsSection, }; } export { buildCommunicationPrefs };