Files
bootstrap/bin/mosaic-link-runtime-assets.ps1
Jason Woltje 7c2eba4e15 feat: centralized SOUL.md, mosaic-init generator, and unified launcher
- 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>
2026-02-19 12:38:22 -06:00

107 lines
4.1 KiB
PowerShell

# mosaic-link-runtime-assets.ps1
# Syncs Mosaic runtime config files into agent runtime directories.
# PowerShell equivalent of mosaic-link-runtime-assets (bash).
$ErrorActionPreference = "Stop"
$MosaicHome = if ($env:MOSAIC_HOME) { $env:MOSAIC_HOME } else { Join-Path $env:USERPROFILE ".config\mosaic" }
$BackupStamp = Get-Date -Format "yyyyMMddHHmmss"
function Copy-FileManaged {
param([string]$Src, [string]$Dst)
$parent = Split-Path $Dst -Parent
if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null }
# Remove existing symlink/junction
$item = Get-Item $Dst -Force -ErrorAction SilentlyContinue
if ($item -and $item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) {
Remove-Item $Dst -Force
}
if (Test-Path $Dst) {
$srcHash = (Get-FileHash $Src -Algorithm SHA256).Hash
$dstHash = (Get-FileHash $Dst -Algorithm SHA256).Hash
if ($srcHash -eq $dstHash) { return }
Rename-Item $Dst "$Dst.mosaic-bak-$BackupStamp"
}
Copy-Item $Src $Dst -Force
}
function Remove-LegacyPath {
param([string]$Path)
if (-not (Test-Path $Path)) { return }
$item = Get-Item $Path -Force -ErrorAction SilentlyContinue
if ($item -and $item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) {
Remove-Item $Path -Force
return
}
if (Test-Path $Path -PathType Container) {
# Remove symlinks/junctions inside, then empty dirs
Get-ChildItem $Path -Recurse -Force | Where-Object {
$_.Attributes -band [System.IO.FileAttributes]::ReparsePoint
} | Remove-Item -Force
Get-ChildItem $Path -Recurse -Directory -Force |
Sort-Object { $_.FullName.Length } -Descending |
Where-Object { (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0 } |
Remove-Item -Force
}
}
# Remove legacy compatibility paths
$legacyPaths = @(
(Join-Path $env:USERPROFILE ".claude\agent-guides"),
(Join-Path $env:USERPROFILE ".claude\scripts\git"),
(Join-Path $env:USERPROFILE ".claude\scripts\codex"),
(Join-Path $env:USERPROFILE ".claude\scripts\bootstrap"),
(Join-Path $env:USERPROFILE ".claude\scripts\cicd"),
(Join-Path $env:USERPROFILE ".claude\scripts\portainer"),
(Join-Path $env:USERPROFILE ".claude\scripts\debug-hook.sh"),
(Join-Path $env:USERPROFILE ".claude\scripts\qa-hook-handler.sh"),
(Join-Path $env:USERPROFILE ".claude\scripts\qa-hook-stdin.sh"),
(Join-Path $env:USERPROFILE ".claude\scripts\qa-hook-wrapper.sh"),
(Join-Path $env:USERPROFILE ".claude\scripts\qa-queue-monitor.sh"),
(Join-Path $env:USERPROFILE ".claude\scripts\remediation-hook-handler.sh"),
(Join-Path $env:USERPROFILE ".claude\templates"),
(Join-Path $env:USERPROFILE ".claude\presets\domains"),
(Join-Path $env:USERPROFILE ".claude\presets\tech-stacks"),
(Join-Path $env:USERPROFILE ".claude\presets\workflows"),
(Join-Path $env:USERPROFILE ".claude\presets\jarvis-ralph.json")
)
foreach ($p in $legacyPaths) {
Remove-LegacyPath $p
}
# Sync runtime config files (copy, not link)
$runtimeFiles = @("CLAUDE.md", "settings.json", "hooks-config.json", "context7-integration.md")
foreach ($rf in $runtimeFiles) {
$src = Join-Path $MosaicHome "runtime\claude\$rf"
if (-not (Test-Path $src)) { continue }
$dst = Join-Path $env:USERPROFILE ".claude\$rf"
Copy-FileManaged $src $dst
}
# OpenCode runtime adapter
$opencodeSrc = Join-Path $MosaicHome "runtime\opencode\AGENTS.md"
if (Test-Path $opencodeSrc) {
$opencodeDst = Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md"
Copy-FileManaged $opencodeSrc $opencodeDst
}
# Codex runtime adapter
$codexSrc = Join-Path $MosaicHome "runtime\codex\instructions.md"
if (Test-Path $codexSrc) {
$codexDir = Join-Path $env:USERPROFILE ".codex"
if (-not (Test-Path $codexDir)) { New-Item -ItemType Directory -Path $codexDir -Force | Out-Null }
$codexDst = Join-Path $codexDir "instructions.md"
Copy-FileManaged $codexSrc $codexDst
}
Write-Host "[mosaic-link] Runtime assets synced (non-symlink mode)"
Write-Host "[mosaic-link] Canonical source: $MosaicHome"