- Add SOUL.md.template with {{PLACEHOLDERS}} for interactive generation
- Add mosaic-init (bash + PS1) for interactive SOUL.md creation with flag overrides
- Add mosaic launcher (bash + PS1) — unified CLI for claude/opencode/codex with SOUL.md injection
- Add codex runtime adapter (runtime/codex/instructions.md)
- Update runtime adapters (claude, opencode) with SOUL.md read directive
- Update mosaic-link-runtime-assets to push codex adapter to ~/.codex/
- Update installers to prompt for mosaic init when SOUL.md is missing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
145 lines
5.4 KiB
PowerShell
145 lines
5.4 KiB
PowerShell
# 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 <name>] [-Role <desc>] [-Style direct|friendly|formal]
|
|
[-Accessibility <prefs>] [-Guardrails <rules>] [-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"
|