ha-inlite

Home Assistant integration for in-lite
git clone https://git.stephank.nl/ha-inlite
Log | Files | Refs | README | LICENSE | ZIP

sync-mesh.ps1 (3996B)


      1 # sync-mesh.ps1 — Materialize remote squad state locally
      2 #
      3 # Reads mesh.json, fetches remote squads into local directories.
      4 # Run before agent reads. No daemon. No service. ~40 lines.
      5 #
      6 # Usage: .\sync-mesh.ps1 [path-to-mesh.json]
      7 #        .\sync-mesh.ps1 -Init [path-to-mesh.json]
      8 # Requires: git
      9 param(
     10     [switch]$Init,
     11     [string]$MeshJson = "mesh.json"
     12 )
     13 $ErrorActionPreference = "Stop"
     14 
     15 # Handle -Init mode
     16 if ($Init) {
     17     if (-not (Test-Path $MeshJson)) {
     18         Write-Host "❌ $MeshJson not found"
     19         exit 1
     20     }
     21     
     22     Write-Host "🚀 Initializing mesh state repository..."
     23     $config = Get-Content $MeshJson -Raw | ConvertFrom-Json
     24     $squads = $config.squads.PSObject.Properties.Name
     25     
     26     # Create squad directories with placeholder SUMMARY.md
     27     foreach ($squad in $squads) {
     28         if (-not (Test-Path $squad)) {
     29             New-Item -ItemType Directory -Path $squad | Out-Null
     30             Write-Host "  ✓ Created $squad/"
     31         } else {
     32             Write-Host "  • $squad/ exists (skipped)"
     33         }
     34         
     35         $summaryPath = "$squad/SUMMARY.md"
     36         if (-not (Test-Path $summaryPath)) {
     37             "# $squad`n`n_No state published yet._" | Set-Content $summaryPath
     38             Write-Host "  ✓ Created $summaryPath"
     39         } else {
     40             Write-Host "  • $summaryPath exists (skipped)"
     41         }
     42     }
     43     
     44     # Generate root README.md
     45     if (-not (Test-Path "README.md")) {
     46         $readme = @"
     47 # Squad Mesh State Repository
     48 
     49 This repository tracks published state from participating squads.
     50 
     51 ## Participating Squads
     52 
     53 "@
     54         foreach ($squad in $squads) {
     55             $zone = $config.squads.$squad.zone
     56             $readme += "- **$squad** (Zone: $zone)`n"
     57         }
     58         $readme += @"
     59 
     60 Each squad directory contains a ``SUMMARY.md`` with their latest published state.
     61 State is synchronized using ``sync-mesh.sh`` or ``sync-mesh.ps1``.
     62 "@
     63         $readme | Set-Content "README.md"
     64         Write-Host "  ✓ Created README.md"
     65     } else {
     66         Write-Host "  • README.md exists (skipped)"
     67     }
     68     
     69     Write-Host ""
     70     Write-Host "✅ Mesh state repository initialized"
     71     exit 0
     72 }
     73 
     74 $config = Get-Content $MeshJson -Raw | ConvertFrom-Json
     75 
     76 # Zone 2: Remote-trusted — git clone/pull
     77 foreach ($entry in $config.squads.PSObject.Properties | Where-Object { $_.Value.zone -eq "remote-trusted" }) {
     78     $squad  = $entry.Name
     79     $source = $entry.Value.source
     80     $ref    = if ($entry.Value.ref) { $entry.Value.ref } else { "main" }
     81     $target = $entry.Value.sync_to
     82 
     83     if (Test-Path "$target/.git") {
     84         git -C $target pull --rebase --quiet 2>$null
     85         if ($LASTEXITCODE -ne 0) { Write-Host "⚠ ${squad}: pull failed (using stale)" }
     86     } else {
     87         New-Item -ItemType Directory -Force -Path (Split-Path $target -Parent) | Out-Null
     88         git clone --quiet --depth 1 --branch $ref $source $target 2>$null
     89         if ($LASTEXITCODE -ne 0) { Write-Host "⚠ ${squad}: clone failed (unavailable)" }
     90     }
     91 }
     92 
     93 # Zone 3: Remote-opaque — fetch published contracts
     94 foreach ($entry in $config.squads.PSObject.Properties | Where-Object { $_.Value.zone -eq "remote-opaque" }) {
     95     $squad  = $entry.Name
     96     $source = $entry.Value.source
     97     $target = $entry.Value.sync_to
     98     $auth   = $entry.Value.auth
     99 
    100     New-Item -ItemType Directory -Force -Path $target | Out-Null
    101     $params = @{ Uri = $source; OutFile = "$target/SUMMARY.md"; UseBasicParsing = $true }
    102     if ($auth -eq "bearer") {
    103         $tokenVar = ($squad.ToUpper() -replace '-', '_') + "_TOKEN"
    104         $token = [Environment]::GetEnvironmentVariable($tokenVar)
    105         if ($token) { $params.Headers = @{ Authorization = "Bearer $token" } }
    106     }
    107     try { Invoke-WebRequest @params -ErrorAction Stop }
    108     catch { "# ${squad} — unavailable ($(Get-Date))" | Set-Content "$target/SUMMARY.md" }
    109 }
    110 
    111 Write-Host "✓ Mesh sync complete"