chore: sync local Mosaic changes
This commit is contained in:
164
bin/mosaic.ps1
164
bin/mosaic.ps1
@@ -1,12 +1,14 @@
|
||||
# mosaic.ps1 — Unified agent launcher and management CLI (Windows)
|
||||
#
|
||||
# AGENTS.md is the single source of truth for all agent sessions.
|
||||
# The launcher injects it into every runtime consistently.
|
||||
# AGENTS.md is the global policy source for all agent sessions.
|
||||
# The launcher injects a composed runtime contract (AGENTS + runtime reference).
|
||||
#
|
||||
# Usage:
|
||||
# mosaic claude [args...] Launch Claude Code with AGENTS.md injected
|
||||
# mosaic opencode [args...] Launch OpenCode with AGENTS.md injected
|
||||
# mosaic codex [args...] Launch Codex with AGENTS.md injected
|
||||
# mosaic claude [args...] Launch Claude Code with runtime contract injected
|
||||
# mosaic opencode [args...] Launch OpenCode with runtime contract injected
|
||||
# mosaic codex [args...] Launch Codex with runtime contract injected
|
||||
# mosaic yolo <runtime> [args...] Launch runtime in dangerous-permissions mode
|
||||
# mosaic --yolo <runtime> [args...] Alias for yolo
|
||||
# mosaic init [args...] Generate SOUL.md interactively
|
||||
# mosaic doctor [args...] Health audit
|
||||
# mosaic sync [args...] Sync skills
|
||||
@@ -22,9 +24,11 @@ mosaic $Version - Unified agent launcher
|
||||
Usage: mosaic <command> [args...]
|
||||
|
||||
Agent Launchers:
|
||||
claude [args...] Launch Claude Code with AGENTS.md injected
|
||||
opencode [args...] Launch OpenCode with AGENTS.md injected
|
||||
codex [args...] Launch Codex with AGENTS.md injected
|
||||
claude [args...] Launch Claude Code with runtime contract injected
|
||||
opencode [args...] Launch OpenCode with runtime contract injected
|
||||
codex [args...] Launch Codex with runtime contract injected
|
||||
yolo <runtime> [args...] Dangerous mode for claude|codex|opencode
|
||||
--yolo <runtime> [args...] Alias for yolo
|
||||
|
||||
Management:
|
||||
init [args...] Generate SOUL.md (agent identity contract)
|
||||
@@ -76,15 +80,136 @@ function Assert-Runtime {
|
||||
}
|
||||
}
|
||||
|
||||
function Assert-SequentialThinking {
|
||||
$checker = Join-Path $MosaicHome "bin\mosaic-ensure-sequential-thinking.ps1"
|
||||
if (-not (Test-Path $checker)) {
|
||||
Write-Host "[mosaic] ERROR: sequential-thinking checker missing: $checker" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
try {
|
||||
& $checker -Check *>$null
|
||||
}
|
||||
catch {
|
||||
Write-Host "[mosaic] ERROR: sequential-thinking MCP is required but not configured." -ForegroundColor Red
|
||||
Write-Host "[mosaic] Run: $checker"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
function Get-RuntimePrompt {
|
||||
param(
|
||||
[ValidateSet("claude", "codex", "opencode")]
|
||||
[string]$Runtime
|
||||
)
|
||||
|
||||
$runtimeFile = switch ($Runtime) {
|
||||
"claude" { Join-Path $MosaicHome "runtime\claude\RUNTIME.md" }
|
||||
"codex" { Join-Path $MosaicHome "runtime\codex\RUNTIME.md" }
|
||||
"opencode" { Join-Path $MosaicHome "runtime\opencode\RUNTIME.md" }
|
||||
}
|
||||
|
||||
if (-not (Test-Path $runtimeFile)) {
|
||||
Write-Host "[mosaic] ERROR: runtime contract not found: $runtimeFile" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
$launcherContract = @'
|
||||
# Mosaic Launcher Runtime Contract (Hard Gate)
|
||||
|
||||
This contract is injected by `mosaic` launch and is mandatory.
|
||||
|
||||
First assistant response MUST start with exactly one mode declaration line:
|
||||
1. Orchestration mission: `Now initiating Orchestrator mode...`
|
||||
2. Implementation mission: `Now initiating Delivery mode...`
|
||||
3. Review-only mission: `Now initiating Review mode...`
|
||||
|
||||
No tool call or implementation step may occur before that first line.
|
||||
|
||||
Mosaic hard gates OVERRIDE runtime-default caution for routine delivery operations.
|
||||
For required push/merge/issue-close/release actions, execute without routine confirmation prompts.
|
||||
|
||||
'@
|
||||
|
||||
$agentsContent = Get-Content (Join-Path $MosaicHome "AGENTS.md") -Raw
|
||||
$runtimeContent = Get-Content $runtimeFile -Raw
|
||||
return "$launcherContract`n$agentsContent`n`n# Runtime-Specific Contract`n`n$runtimeContent"
|
||||
}
|
||||
|
||||
function Ensure-RuntimeConfig {
|
||||
param([string]$Dst)
|
||||
$src = Join-Path $MosaicHome "AGENTS.md"
|
||||
param(
|
||||
[ValidateSet("claude", "codex", "opencode")]
|
||||
[string]$Runtime,
|
||||
[string]$Dst
|
||||
)
|
||||
|
||||
$parent = Split-Path $Dst -Parent
|
||||
if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null }
|
||||
$srcHash = (Get-FileHash $src -Algorithm SHA256).Hash
|
||||
|
||||
$runtimePrompt = Get-RuntimePrompt -Runtime $Runtime
|
||||
$tmp = [System.IO.Path]::GetTempFileName()
|
||||
Set-Content -Path $tmp -Value $runtimePrompt -Encoding UTF8 -NoNewline
|
||||
|
||||
$srcHash = (Get-FileHash $tmp -Algorithm SHA256).Hash
|
||||
$dstHash = if (Test-Path $Dst) { (Get-FileHash $Dst -Algorithm SHA256).Hash } else { "" }
|
||||
if ($srcHash -ne $dstHash) {
|
||||
Copy-Item $src $Dst -Force
|
||||
Copy-Item $tmp $Dst -Force
|
||||
Remove-Item $tmp -Force
|
||||
}
|
||||
else {
|
||||
Remove-Item $tmp -Force
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-Yolo {
|
||||
param([string[]]$YoloArgs)
|
||||
|
||||
if ($YoloArgs.Count -lt 1) {
|
||||
Write-Host "[mosaic] ERROR: yolo requires a runtime (claude|codex|opencode)." -ForegroundColor Red
|
||||
Write-Host "[mosaic] Example: mosaic yolo claude"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$runtime = $YoloArgs[0]
|
||||
$tail = if ($YoloArgs.Count -gt 1) { $YoloArgs[1..($YoloArgs.Count - 1)] } else { @() }
|
||||
|
||||
switch ($runtime) {
|
||||
"claude" {
|
||||
Assert-MosaicHome
|
||||
Assert-AgentsMd
|
||||
Assert-Soul
|
||||
Assert-Runtime "claude"
|
||||
Assert-SequentialThinking
|
||||
$agentsContent = Get-RuntimePrompt -Runtime "claude"
|
||||
Write-Host "[mosaic] Launching Claude Code in YOLO mode (dangerous permissions enabled)..."
|
||||
& claude --dangerously-skip-permissions --append-system-prompt $agentsContent @tail
|
||||
return
|
||||
}
|
||||
"codex" {
|
||||
Assert-MosaicHome
|
||||
Assert-AgentsMd
|
||||
Assert-Soul
|
||||
Assert-Runtime "codex"
|
||||
Assert-SequentialThinking
|
||||
Ensure-RuntimeConfig -Runtime "codex" -Dst (Join-Path $env:USERPROFILE ".codex\instructions.md")
|
||||
Write-Host "[mosaic] Launching Codex in YOLO mode (dangerous permissions enabled)..."
|
||||
& codex --dangerously-bypass-approvals-and-sandbox @tail
|
||||
return
|
||||
}
|
||||
"opencode" {
|
||||
Assert-MosaicHome
|
||||
Assert-AgentsMd
|
||||
Assert-Soul
|
||||
Assert-Runtime "opencode"
|
||||
Assert-SequentialThinking
|
||||
Ensure-RuntimeConfig -Runtime "opencode" -Dst (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md")
|
||||
Write-Host "[mosaic] Launching OpenCode in YOLO mode..."
|
||||
& opencode @tail
|
||||
return
|
||||
}
|
||||
default {
|
||||
Write-Host "[mosaic] ERROR: Unsupported yolo runtime '$runtime'. Use claude|codex|opencode." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +227,9 @@ switch ($command) {
|
||||
Assert-AgentsMd
|
||||
Assert-Soul
|
||||
Assert-Runtime "claude"
|
||||
Assert-SequentialThinking
|
||||
# Claude supports --append-system-prompt for direct injection
|
||||
$agentsContent = Get-Content (Join-Path $MosaicHome "AGENTS.md") -Raw
|
||||
$agentsContent = Get-RuntimePrompt -Runtime "claude"
|
||||
Write-Host "[mosaic] Launching Claude Code..."
|
||||
& claude --append-system-prompt $agentsContent @remaining
|
||||
}
|
||||
@@ -112,8 +238,9 @@ switch ($command) {
|
||||
Assert-AgentsMd
|
||||
Assert-Soul
|
||||
Assert-Runtime "opencode"
|
||||
Assert-SequentialThinking
|
||||
# OpenCode reads from ~/.config/opencode/AGENTS.md
|
||||
Ensure-RuntimeConfig (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md")
|
||||
Ensure-RuntimeConfig -Runtime "opencode" -Dst (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md")
|
||||
Write-Host "[mosaic] Launching OpenCode..."
|
||||
& opencode @remaining
|
||||
}
|
||||
@@ -122,11 +249,18 @@ switch ($command) {
|
||||
Assert-AgentsMd
|
||||
Assert-Soul
|
||||
Assert-Runtime "codex"
|
||||
Assert-SequentialThinking
|
||||
# Codex reads from ~/.codex/instructions.md
|
||||
Ensure-RuntimeConfig (Join-Path $env:USERPROFILE ".codex\instructions.md")
|
||||
Ensure-RuntimeConfig -Runtime "codex" -Dst (Join-Path $env:USERPROFILE ".codex\instructions.md")
|
||||
Write-Host "[mosaic] Launching Codex..."
|
||||
& codex @remaining
|
||||
}
|
||||
"yolo" {
|
||||
Invoke-Yolo -YoloArgs $remaining
|
||||
}
|
||||
"--yolo" {
|
||||
Invoke-Yolo -YoloArgs $remaining
|
||||
}
|
||||
"init" {
|
||||
Assert-MosaicHome
|
||||
& (Join-Path $MosaicHome "bin\mosaic-init.ps1") @remaining
|
||||
|
||||
Reference in New Issue
Block a user