/ scripts / install_global_context.py
install_global_context.py
  1  #!/usr/bin/env python3
  2  """
  3  Install Global Context - Add resonance hooks to all repos
  4  
  5  This script installs a lightweight hook into every repo in ~/repos/
  6  that points back to the Sovereign OS resonance context system.
  7  
  8  When a Claude instance opens ANY repo, it will:
  9  1. Check for the global hook in CLAUDE.md
 10  2. Read resonance context from Sovereign OS
 11  3. Bootstrap with axiom-grounded context
 12  
 13  Usage:
 14      python3 scripts/install_global_context.py           # Install to all repos
 15      python3 scripts/install_global_context.py --list    # List repos
 16      python3 scripts/install_global_context.py --remove  # Remove hooks
 17  """
 18  
 19  import argparse
 20  import sys
 21  from pathlib import Path
 22  from datetime import datetime
 23  
 24  SOVEREIGN_OS_ROOT = Path(__file__).parent.parent
 25  REPOS_DIR = Path.home() / "repos"
 26  
 27  # The hook content that gets added to each repo's CLAUDE.md
 28  GLOBAL_HOOK_TEMPLATE = '''
 29  ---
 30  
 31  ## Sovereign OS Context (Global)
 32  
 33  *This repo is connected to the Sovereign OS resonance context engine.*
 34  
 35  ### Quick Start
 36  ```bash
 37  # Run pre-flight check
 38  python3 /Users/rcerf/repos/Sovereign_OS/scripts/phoenix_hygiene.py
 39  ```
 40  
 41  ### Flight Checklists (READ THESE)
 42  **Location:** `/Users/rcerf/repos/Sovereign_OS/docs/checklists/flight-checklists.md`
 43  
 44  | Phase | Quick Reference |
 45  |-------|-----------------|
 46  | **Pre-flight** | Hygiene check, INSIGHT-BACKLOG, set intention |
 47  | **Active** | Update LIVE-COMPRESSION every 30 min |
 48  | **Post-flight** | Final compression, commit, "everything is handled" |
 49  
 50  ### Key System Files
 51  | File | Purpose |
 52  |------|---------|
 53  | `sessions/LIVE-COMPRESSION.md` | Current session state |
 54  | `sessions/DAILY-SYNTHESIS.md` | Cross-thread synthesis |
 55  | `sessions/INSIGHT-BACKLOG.md` | Pending high-priority items |
 56  | `docs/checklists/flight-checklists.md` | Pre/active/post-flight protocols |
 57  
 58  ### Axiom Stack (A0-A4)
 59  - **A0**: Boundary Operation - Structure flows, content sovereign
 60  - **A1**: Telos of Integration - Move toward connection
 61  - **A2**: Recognition of Life - Primitive over calcified
 62  - **A3**: Dynamic Pole Navigation - Navigate between poles
 63  - **A4**: Ergodic Asymmetry - Prevent ruin before optimizing (CANDIDATE)
 64  
 65  ### Protocols
 66  - Flight Protocol: `patterns/flight-protocol.md`
 67  - Phoenix Extraction: `patterns/mandatory-phoenix-extraction.md`
 68  - First Officer: `patterns/first-officer-protocol.md`
 69  
 70  **Free Energy:** When suggesting changes, estimate F (0=aligned, 1=divergent)
 71  
 72  *Sovereign OS v1.1 | Installed: {timestamp}*
 73  
 74  ---
 75  '''
 76  
 77  # Marker to identify our hooks
 78  HOOK_MARKER_START = "## Sovereign OS Context (Global)"
 79  HOOK_MARKER_END = "*Installed by Sovereign OS:"
 80  
 81  
 82  def get_repos() -> list:
 83      """Get list of repos to install to."""
 84      if not REPOS_DIR.exists():
 85          return []
 86  
 87      repos = []
 88      for item in sorted(REPOS_DIR.iterdir()):
 89          if item.is_dir() and not item.name.startswith('.'):
 90              if item.name != "Sovereign_OS":  # Skip self
 91                  repos.append(item)
 92  
 93      return repos
 94  
 95  
 96  def has_hook(repo: Path) -> bool:
 97      """Check if repo already has the hook."""
 98      claude_md = repo / "CLAUDE.md"
 99      if not claude_md.exists():
100          return False
101  
102      content = claude_md.read_text()
103      return HOOK_MARKER_START in content
104  
105  
106  def install_hook(repo: Path) -> bool:
107      """Install the hook to a repo."""
108      claude_md = repo / "CLAUDE.md"
109  
110      hook_content = GLOBAL_HOOK_TEMPLATE.format(
111          timestamp=datetime.now().strftime("%Y-%m-%d %H:%M")
112      )
113  
114      if claude_md.exists():
115          existing = claude_md.read_text()
116  
117          # Check if already installed
118          if HOOK_MARKER_START in existing:
119              return False
120  
121          # Append to existing
122          updated = existing.rstrip() + "\n\n" + hook_content
123          claude_md.write_text(updated)
124      else:
125          # Create new CLAUDE.md
126          claude_md.write_text(f"# Claude Code Configuration\n{hook_content}")
127  
128      return True
129  
130  
131  def remove_hook(repo: Path) -> bool:
132      """Remove the hook from a repo."""
133      claude_md = repo / "CLAUDE.md"
134      if not claude_md.exists():
135          return False
136  
137      content = claude_md.read_text()
138  
139      if HOOK_MARKER_START not in content:
140          return False
141  
142      # Find and remove the hook section
143      lines = content.split('\n')
144      new_lines = []
145      in_hook = False
146  
147      for line in lines:
148          if HOOK_MARKER_START in line:
149              in_hook = True
150              # Also remove the --- before
151              if new_lines and new_lines[-1].strip() == '---':
152                  new_lines.pop()
153              continue
154  
155          if in_hook:
156              if HOOK_MARKER_END in line:
157                  in_hook = False
158                  # Skip the closing ---
159                  continue
160              if line.strip() == '---':
161                  in_hook = False
162                  continue
163              continue
164  
165          new_lines.append(line)
166  
167      # Clean up trailing whitespace
168      while new_lines and not new_lines[-1].strip():
169          new_lines.pop()
170  
171      claude_md.write_text('\n'.join(new_lines) + '\n')
172      return True
173  
174  
175  def main():
176      parser = argparse.ArgumentParser(
177          description="Install Sovereign OS context hooks to all repos",
178          formatter_class=argparse.RawDescriptionHelpFormatter
179      )
180  
181      parser.add_argument("--list", "-l", action="store_true",
182                          help="List repos and their hook status")
183      parser.add_argument("--remove", "-r", action="store_true",
184                          help="Remove hooks from all repos")
185      parser.add_argument("--dry-run", "-n", action="store_true",
186                          help="Show what would be done without doing it")
187      parser.add_argument("repos", nargs="*",
188                          help="Specific repos to install to (default: all)")
189  
190      args = parser.parse_args()
191  
192      # Get target repos
193      if args.repos:
194          repos = [REPOS_DIR / r for r in args.repos if (REPOS_DIR / r).exists()]
195      else:
196          repos = get_repos()
197  
198      if not repos:
199          print(f"No repos found in {REPOS_DIR}")
200          return 1
201  
202      if args.list:
203          print(f"Repos in {REPOS_DIR}:\n")
204          for repo in repos:
205              status = "✓ installed" if has_hook(repo) else "○ not installed"
206              print(f"  {repo.name}: {status}")
207          print()
208  
209          installed = sum(1 for r in repos if has_hook(r))
210          print(f"Total: {len(repos)} repos, {installed} with hooks")
211          return 0
212  
213      if args.remove:
214          print(f"Removing Sovereign OS hooks from {len(repos)} repos...\n")
215          removed = 0
216          for repo in repos:
217              if args.dry_run:
218                  if has_hook(repo):
219                      print(f"  Would remove: {repo.name}")
220                      removed += 1
221              else:
222                  if remove_hook(repo):
223                      print(f"  Removed: {repo.name}")
224                      removed += 1
225  
226          print(f"\n{'Would remove' if args.dry_run else 'Removed'} hooks from {removed} repos")
227          return 0
228  
229      # Install
230      print(f"Installing Sovereign OS context hooks to {len(repos)} repos...\n")
231  
232      installed = 0
233      skipped = 0
234  
235      for repo in repos:
236          if args.dry_run:
237              if has_hook(repo):
238                  print(f"  Skip (exists): {repo.name}")
239                  skipped += 1
240              else:
241                  print(f"  Would install: {repo.name}")
242                  installed += 1
243          else:
244              if install_hook(repo):
245                  print(f"  + {repo.name}")
246                  installed += 1
247              else:
248                  print(f"  - {repo.name} (already installed)")
249                  skipped += 1
250  
251      print()
252      print(f"{'Would install' if args.dry_run else 'Installed'}: {installed}")
253      print(f"Skipped (already installed): {skipped}")
254  
255      if installed > 0 and not args.dry_run:
256          print()
257          print("All repos now have resonance context bootstrapping!")
258          print("Run 'python3 /Users/rcerf/repos/Sovereign_OS/scripts/spin_up.py' in any repo.")
259  
260      return 0
261  
262  
263  if __name__ == "__main__":
264      sys.exit(main())