feat: TypeScript installation wizard with @clack/prompts TUI (#1)
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #1.
This commit is contained in:
145
src/template/builders.ts
Normal file
145
src/template/builders.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
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 };
|
||||
Reference in New Issue
Block a user