- 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>
107 lines
4.1 KiB
PowerShell
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"
|