# scripts/tier2/setup_tier2_clone.ps1 <# .SYNOPSIS One-time bootstrap for the Tier 2 autonomous sandbox. .DESCRIPTION Clones the main repo to C:\projects\manual_slop_tier2\, sets origin to the main repo's local path, copies the agent/command/opencode.json templates, installs the git hooks, and creates a "Tier 2 (Sandboxed)" desktop shortcut. Idempotent: re-running updates templates and re-fetches, but does not destroy existing feature branches in the clone. .PARAMETER WhatIf Show what would happen without making changes. .PARAMETER MainRepoPath Path to the main repo. Default: C:\projects\manual_slop .PARAMETER Tier2ClonePath Path to the Tier 2 clone. Default: C:\projects\manual_slop_tier2 #> [CmdletBinding(SupportsShouldProcess = $true)] param( [string]$MainRepoPath = "C:\projects\manual_slop", [string]$Tier2ClonePath = "C:\projects\manual_slop_tier2" ) $ErrorActionPreference = "Stop" # Resolve to absolute paths $MainRepoPath = (Resolve-Path $MainRepoPath).Path if ($PSCmdlet.ShouldProcess("Bootstrap Tier 2 clone at $Tier2ClonePath")) { Write-Host "[tier2-bootstrap] starting bootstrap" Write-Host "[tier2-bootstrap] main repo: $MainRepoPath" Write-Host "[tier2-bootstrap] tier2 clone: $Tier2ClonePath" # 1. Clone the main repo (if not already present) if (-not (Test-Path $Tier2ClonePath)) { Write-Host "[tier2-bootstrap] cloning $MainRepoPath -> $Tier2ClonePath" git clone $MainRepoPath $Tier2ClonePath if ($LASTEXITCODE -ne 0) { throw "git clone failed" } } else { Write-Host "[tier2-bootstrap] clone already exists, skipping clone" } # 2. Set origin to the main repo's local path (if not already) Push-Location $Tier2ClonePath try { $currentOrigin = git remote get-url origin 2>$null if ($currentOrigin -ne $MainRepoPath) { Write-Host "[tier2-bootstrap] setting origin to $MainRepoPath" git remote set-url origin $MainRepoPath } else { Write-Host "[tier2-bootstrap] origin already set correctly" } # 3. Copy templates Write-Host "[tier2-bootstrap] copying templates" New-Item -ItemType Directory -Force -Path "$Tier2ClonePath\.opencode\agents" | Out-Null New-Item -ItemType Directory -Force -Path "$Tier2ClonePath\.opencode\commands" | Out-Null Copy-Item -Force "$MainRepoPath\conductor\tier2\agents\tier2-autonomous.md" "$Tier2ClonePath\.opencode\agents\tier2-autonomous.md" Copy-Item -Force "$MainRepoPath\conductor\tier2\commands\tier-2-auto-execute.md" "$Tier2ClonePath\.opencode\commands\tier-2-auto-execute.md" # Merge opencode.json.fragment into the clone's opencode.json. # The clone inherits a copy of the main repo's opencode.json (via # `git clone`), which has top-level `permission.edit: ask` and # `permission.bash: ask`. Those would be unsafe in the sandbox: the # build/plan default agents could read/write anywhere on disk, and # there is no file-system allowlist at the top level. We replace # the top-level `permission` with the hardened sandbox version # (deny-all + allowlist for the sandbox dirs + the tier2-autonomous # agent's permission block). The agent's `permission` overrides the # top-level for that agent's tool calls. $cloneConfig = "$Tier2ClonePath\opencode.json" $fragment = Get-Content "$MainRepoPath\conductor\tier2\opencode.json.fragment" -Raw | ConvertFrom-Json if (Test-Path $cloneConfig) { $existing = Get-Content $cloneConfig -Raw | ConvertFrom-Json if (-not $existing.agent) { $existing | Add-Member -MemberType NoteProperty -Name agent -Value ([PSCustomObject]@{}) } $existing.agent | Add-Member -MemberType NoteProperty -Name "tier2-autonomous" -Value $fragment.agent."tier2-autonomous" -Force if (-not $existing.permission) { $existing | Add-Member -MemberType NoteProperty -Name permission -Value ([PSCustomObject]@{}) } $existing.permission = $fragment.permission $existing | Add-Member -MemberType NoteProperty -Name default_agent -Value "tier2-autonomous" -Force $existing | Add-Member -MemberType NoteProperty -Name model -Value $fragment.model -Force $existing | ConvertTo-Json -Depth 10 | Set-Content $cloneConfig } else { Copy-Item -Force "$MainRepoPath\conductor\tier2\opencode.json.fragment" $cloneConfig $existing = $fragment } # Override the MCP server's command + PYTHONPATH to point at the # Tier 2 clone's files. The inherited config points to the main # repo's scripts/mcp_server.py, which loads the main repo's # project_root (C:\projects\manual_slop) and reads the main repo's # mcp_paths.toml (which allowlists C:\projects\gencpp). When Tier 2 # calls manual-slop_read_file on a clone path, the MCP server # rejects it with "Allowed base directories are: manual_slop, gencpp". # The fix: launch the MCP server from the clone's path with the # clone's PYTHONPATH, and replace the clone's mcp_paths.toml with # an empty one so the clone's MCP server has no extra_dirs. if ($existing.mcp -and $existing.mcp.'manual-slop') { $existing.mcp.'manual-slop'.command = @( "$env:USERPROFILE\scoop\apps\uv\current\uv.exe", "run", "python", "$Tier2ClonePath\scripts\mcp_server.py" ) $existing.mcp.'manual-slop'.environment.PYTHONPATH = "$Tier2ClonePath\src" $existing | ConvertTo-Json -Depth 10 | Set-Content $cloneConfig } $cloneMcpPaths = "$Tier2ClonePath\mcp_paths.toml" @" [allowed_paths] extra_dirs = [] "@ | Set-Content -Path $cloneMcpPaths -NoNewline Write-Host "[tier2-bootstrap] MCP server pointed at clone; mcp_paths.toml reset to empty extra_dirs" # 4. Install git hooks Write-Host "[tier2-bootstrap] installing git hooks" Copy-Item -Force "$MainRepoPath\conductor\tier2\githooks\pre-commit" "$Tier2ClonePath\.git\hooks\pre-commit" Copy-Item -Force "$MainRepoPath\conductor\tier2\githooks\pre-push" "$Tier2ClonePath\.git\hooks\pre-push" Copy-Item -Force "$MainRepoPath\conductor\tier2\githooks\post-checkout" "$Tier2ClonePath\.git\hooks\post-checkout" # The forbidden-files.txt config is committed to the clone (the # setup script also commits the canonical conductor/tier2/* source # in step 1), so the hook can find it via the project root. If the # file is missing, the hook silently no-ops (see hook source). Write-Host "[tier2-bootstrap] git hooks installed (pre-commit auto-unstages sandbox-only files)" # 5. Create desktop shortcut Write-Host "[tier2-bootstrap] creating desktop shortcut" $shell = New-Object -ComObject WScript.Shell $shortcut = $shell.CreateShortcut("$env:USERPROFILE\Desktop\Tier 2 (Sandboxed).lnk") $shortcut.TargetPath = "pwsh.exe" $shortcut.Arguments = "-File `"$MainRepoPath\scripts\tier2\run_tier2_sandboxed.ps1`"" $shortcut.WorkingDirectory = $Tier2ClonePath $shortcut.Description = "Open OpenCode in the Tier 2 sandboxed clone" $shortcut.Save() } finally { Pop-Location } Write-Host "[tier2-bootstrap] done" Write-Host "[tier2-bootstrap] next steps:" Write-Host "[tier2-bootstrap] 1. Double-click 'Tier 2 (Sandboxed)' on your desktop" Write-Host "[tier2-bootstrap] 2. Type: /tier-2-auto-execute " }