main
sh 104 lines 3.33 KB
Raw
1 #!/bin/bash
2 # sync-mesh.sh — Materialize remote squad state locally
3 #
4 # Reads mesh.json, fetches remote squads into local directories.
5 # Run before agent reads. No daemon. No service. ~40 lines.
6 #
7 # Usage: ./sync-mesh.sh [path-to-mesh.json]
8 # ./sync-mesh.sh --init [path-to-mesh.json]
9 # Requires: jq (https://github.com/jqlang/jq), git, curl
10
11 set -euo pipefail
12
13 # Handle --init mode
14 if [ "${1:-}" = "--init" ]; then
15 MESH_JSON="${2:-mesh.json}"
16
17 if [ ! -f "$MESH_JSON" ]; then
18 echo "❌ $MESH_JSON not found"
19 exit 1
20 fi
21
22 echo "🚀 Initializing mesh state repository..."
23 squads=$(jq -r '.squads | keys[]' "$MESH_JSON")
24
25 # Create squad directories with placeholder SUMMARY.md
26 for squad in $squads; do
27 if [ ! -d "$squad" ]; then
28 mkdir -p "$squad"
29 echo " ✓ Created $squad/"
30 else
31 echo " • $squad/ exists (skipped)"
32 fi
33
34 if [ ! -f "$squad/SUMMARY.md" ]; then
35 echo -e "# $squad\n\n_No state published yet._" > "$squad/SUMMARY.md"
36 echo " ✓ Created $squad/SUMMARY.md"
37 else
38 echo " • $squad/SUMMARY.md exists (skipped)"
39 fi
40 done
41
42 # Generate root README.md
43 if [ ! -f "README.md" ]; then
44 {
45 echo "# Squad Mesh State Repository"
46 echo ""
47 echo "This repository tracks published state from participating squads."
48 echo ""
49 echo "## Participating Squads"
50 echo ""
51 for squad in $squads; do
52 zone=$(jq -r ".squads.\"$squad\".zone" "$MESH_JSON")
53 echo "- **$squad** (Zone: $zone)"
54 done
55 echo ""
56 echo "Each squad directory contains a \`SUMMARY.md\` with their latest published state."
57 echo "State is synchronized using \`sync-mesh.sh\` or \`sync-mesh.ps1\`."
58 } > README.md
59 echo " ✓ Created README.md"
60 else
61 echo " • README.md exists (skipped)"
62 fi
63
64 echo ""
65 echo "✅ Mesh state repository initialized"
66 exit 0
67 fi
68
69 MESH_JSON="${1:-mesh.json}"
70
71 # Zone 2: Remote-trusted — git clone/pull
72 for squad in $(jq -r '.squads | to_entries[] | select(.value.zone == "remote-trusted") | .key' "$MESH_JSON"); do
73 source=$(jq -r ".squads.\"$squad\".source" "$MESH_JSON")
74 ref=$(jq -r ".squads.\"$squad\".ref // \"main\"" "$MESH_JSON")
75 target=$(jq -r ".squads.\"$squad\".sync_to" "$MESH_JSON")
76
77 if [ -d "$target/.git" ]; then
78 git -C "$target" pull --rebase --quiet 2>/dev/null \
79 || echo "⚠ $squad: pull failed (using stale)"
80 else
81 mkdir -p "$(dirname "$target")"
82 git clone --quiet --depth 1 --branch "$ref" "$source" "$target" 2>/dev/null \
83 || echo "⚠ $squad: clone failed (unavailable)"
84 fi
85 done
86
87 # Zone 3: Remote-opaque — fetch published contracts
88 for squad in $(jq -r '.squads | to_entries[] | select(.value.zone == "remote-opaque") | .key' "$MESH_JSON"); do
89 source=$(jq -r ".squads.\"$squad\".source" "$MESH_JSON")
90 target=$(jq -r ".squads.\"$squad\".sync_to" "$MESH_JSON")
91 auth=$(jq -r ".squads.\"$squad\".auth // \"\"" "$MESH_JSON")
92
93 mkdir -p "$target"
94 auth_flag=""
95 if [ "$auth" = "bearer" ]; then
96 token_var="$(echo "${squad}" | tr '[:lower:]-' '[:upper:]_')_TOKEN"
97 [ -n "${!token_var:-}" ] && auth_flag="--header \"Authorization: Bearer ${!token_var}\""
98 fi
99
100 eval curl --silent --fail $auth_flag "$source" -o "$target/SUMMARY.md" 2>/dev/null \
101 || echo "# ${squad} — unavailable ($(date))" > "$target/SUMMARY.md"
102 done
103
104 echo "✓ Mesh sync complete"