# mosaic-init.ps1 — Interactive SOUL.md generator (Windows) # # Usage: # mosaic-init.ps1 # Interactive mode # mosaic-init.ps1 -Name "Jarvis" -Style direct # Flag overrides $ErrorActionPreference = "Stop" param( [string]$Name, [string]$Role, [ValidateSet("direct", "friendly", "formal")] [string]$Style, [string]$Accessibility, [string]$Guardrails, [switch]$NonInteractive, [switch]$Help ) $MosaicHome = if ($env:MOSAIC_HOME) { $env:MOSAIC_HOME } else { Join-Path $env:USERPROFILE ".config\mosaic" } $Template = Join-Path $MosaicHome "templates\SOUL.md.template" $Output = Join-Path $MosaicHome "SOUL.md" if ($Help) { Write-Host @" Usage: mosaic-init.ps1 [-Name ] [-Role ] [-Style direct|friendly|formal] [-Accessibility ] [-Guardrails ] [-NonInteractive] Generate ~/.config/mosaic/SOUL.md - the universal agent identity contract. Interactive by default. Use flags to skip prompts. "@ exit 0 } function Prompt-IfEmpty { param([string]$Current, [string]$PromptText, [string]$Default = "") if ($Current) { return $Current } if ($NonInteractive) { if ($Default) { return $Default } Write-Host "[mosaic-init] ERROR: Value required in non-interactive mode: $PromptText" -ForegroundColor Red exit 1 } $display = if ($Default) { "$PromptText [$Default]" } else { $PromptText } $value = Read-Host $display if (-not $value -and $Default) { return $Default } return $value } Write-Host "[mosaic-init] Generating SOUL.md - your universal agent identity contract" Write-Host "" $Name = Prompt-IfEmpty $Name "What name should agents use" "Assistant" $Role = Prompt-IfEmpty $Role "Agent role description" "execution partner and visibility engine" if (-not $Style) { if ($NonInteractive) { $Style = "direct" } else { Write-Host "" Write-Host "Communication style:" Write-Host " 1) direct - Concise, no fluff, actionable" Write-Host " 2) friendly - Warm but efficient, conversational" Write-Host " 3) formal - Professional, structured, thorough" $choice = Read-Host "Choose [1/2/3] (default: 1)" $Style = switch ($choice) { "2" { "friendly" } "3" { "formal" } default { "direct" } } } } $Accessibility = Prompt-IfEmpty $Accessibility "Accessibility preferences (or 'none')" "none" if (-not $Guardrails -and -not $NonInteractive) { Write-Host "" $Guardrails = Read-Host "Custom guardrails (optional, press Enter to skip)" } # Build behavioral principles $BehavioralPrinciples = switch ($Style) { "direct" { "1. Clarity over performance theater.`n2. Practical execution over abstract planning.`n3. Truthfulness over confidence: state uncertainty explicitly.`n4. Visible state over hidden assumptions." } "friendly" { "1. Be helpful and approachable while staying efficient.`n2. Provide context and explain reasoning when helpful.`n3. Truthfulness over confidence: state uncertainty explicitly.`n4. Visible state over hidden assumptions." } "formal" { "1. Maintain professional, structured communication.`n2. Provide thorough analysis with explicit tradeoffs.`n3. Truthfulness over confidence: state uncertainty explicitly.`n4. Document decisions and rationale clearly." } } if ($Accessibility -and $Accessibility -ne "none") { $BehavioralPrinciples += "`n5. $Accessibility." } # Build communication style $CommunicationStyle = switch ($Style) { "direct" { "- Be direct, concise, and concrete.`n- Avoid fluff, hype, and anthropomorphic roleplay.`n- Do not simulate certainty when facts are missing.`n- Prefer actionable next steps and explicit tradeoffs." } "friendly" { "- Be warm and conversational while staying focused.`n- Explain your reasoning when it helps the user.`n- Do not simulate certainty when facts are missing.`n- Prefer actionable next steps with clear context." } "formal" { "- Use professional, structured language.`n- Provide thorough explanations with supporting detail.`n- Do not simulate certainty when facts are missing.`n- Present options with explicit tradeoffs and recommendations." } } # Format custom guardrails $FormattedGuardrails = if ($Guardrails) { "- $Guardrails" } else { "" } # Verify template if (-not (Test-Path $Template)) { Write-Host "[mosaic-init] ERROR: Template not found: $Template" -ForegroundColor Red exit 1 } # Generate SOUL.md $content = Get-Content $Template -Raw $content = $content -replace '\{\{AGENT_NAME\}\}', $Name $content = $content -replace '\{\{ROLE_DESCRIPTION\}\}', $Role $content = $content -replace '\{\{BEHAVIORAL_PRINCIPLES\}\}', $BehavioralPrinciples $content = $content -replace '\{\{COMMUNICATION_STYLE\}\}', $CommunicationStyle $content = $content -replace '\{\{CUSTOM_GUARDRAILS\}\}', $FormattedGuardrails Set-Content -Path $Output -Value $content -Encoding UTF8 Write-Host "" Write-Host "[mosaic-init] Generated: $Output" Write-Host "[mosaic-init] Agent name: $Name" Write-Host "[mosaic-init] Style: $Style" # Push to runtime adapters $linkScript = Join-Path $MosaicHome "bin\mosaic-link-runtime-assets.ps1" if (Test-Path $linkScript) { Write-Host "[mosaic-init] Updating runtime adapters..." & $linkScript } Write-Host "[mosaic-init] Done. Launch with: mosaic claude"