name: Sovereign Swarm — Multi-Repo Agent on: schedule: - cron: '0 */6 * * *' workflow_dispatch: inputs: task: description: 'Task to run across all repos (leave blank for auto-scan)' required: false default: '' target_repo: description: 'Single repo to target (leave blank for all)' required: false default: '' permissions: contents: write jobs: discover: runs-on: ubuntu-latest outputs: repos: ${{ steps.list.outputs.repos }} steps: - name: List repos id: list env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | if [ -n "${{ github.event.inputs.target_repo }}" ]; then echo 'repos=["${{ github.event.inputs.target_repo }}"]' >> $GITHUB_OUTPUT else REPOS=$(gh repo list SNAPKITTYWEST --limit 100 --json name --jq '[.[].name]') echo "repos=$REPOS" >> $GITHUB_OUTPUT fi agent: needs: discover runs-on: ubuntu-latest strategy: matrix: repo: ${{ fromJson(needs.discover.outputs.repos) }} max-parallel: 8 fail-fast: false steps: - name: Checkout target repo uses: actions/checkout@v4 with: repository: SNAPKITTYWEST/${{ matrix.repo }} token: ${{ secrets.PAT_TOKEN }} path: repo - uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install deps run: pip install requests orjson - name: Run agent on ${{ matrix.repo }} env: OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} REPO_NAME: ${{ matrix.repo }} OVERRIDE_TASK: ${{ github.event.inputs.task }} WORKSPACE: ${{ github.workspace }}/repo run: python repo/.github/scripts/agent.py || python - << 'PYEOF' import os, sys, re, requests from pathlib import Path KEY = os.environ.get("OPENROUTER_API_KEY", "") ROOT = Path(os.environ.get("WORKSPACE", "repo")) REPO = os.environ.get("REPO_NAME", "unknown") TASK = os.environ.get("OVERRIDE_TASK", "") MODEL = "qwen/qwen-2.5-coder-32b-instruct" SCAN_PATTERNS = { "sorry": (["*.lean"], r'\bsorry\b'), "todo": (["*.py","*.rs","*.hs","*.ml","*.lean"], r'#\s*TODO|--\s*TODO|//\s*TODO'), "stub": (["*.py"], r'raise NotImplementedError'), "fixme": (["*.py","*.rs","*.lean"], r'FIXME|XXX'), } def or_call(prompt): if not KEY: return "" resp = requests.post("https://openrouter.ai/api/v1/chat/completions", headers={"Authorization": f"Bearer {KEY}", "HTTP-Referer": "https://snapkittywest.io"}, json={"model": MODEL, "messages": [{"role":"user","content":prompt}], "temperature": 0.1, "max_tokens": 8192}, timeout=300) return resp.json()["choices"][0]["message"]["content"] findings = [] for tag, (globs, pattern) in SCAN_PATTERNS.items(): for g in globs: for path in ROOT.rglob(g): if any(p in str(path) for p in [".github","node_modules",".git","__pycache__",".lake","build"]): continue try: text = path.read_text(encoding="utf-8", errors="ignore") for i, line in enumerate(text.split("\n")): if re.search(pattern, line): findings.append({"tag":tag,"file":str(path.relative_to(ROOT)),"line":i+1,"content":line.strip()}) except: pass print(f"[{REPO}] {len(findings)} findings") if not findings: print("Clean repo — skipping") sys.exit(0) priority = {"sorry":0,"stub":1,"todo":2,"fixme":3} findings.sort(key=lambda f: priority.get(f["tag"],9)) top = findings[:3] first = top[0] try: full = (ROOT / first["file"]).read_text(encoding="utf-8", errors="ignore") except: full = first["content"] items = "\n".join(f"[{f['tag'].upper()}] {f['file']}:{f['line']} — {f['content']}" for f in top) prompt = f"""Fix these issues in {REPO}/{first['file']}. Output ONLY the complete corrected file. No markdown. ISSUES: {items} FILE: {full[:6000]} """ result = or_call(TASK if TASK else prompt) if not result or len(result) < 50: print("Empty response"); sys.exit(0) m = re.search(r'```[\w]*\n(.*?)```', result, re.DOTALL) if m: result = m.group(1).strip() else: m2 = re.search(r'^(import |from |namespace |theorem |def |pub )', result, re.MULTILINE) if m2: result = result[m2.start():] target = ROOT / first["file"] target.write_text(result, encoding="utf-8") print(f"Written: {target} ({len(result)} chars)") PYEOF - name: Commit and push working-directory: repo run: | git config user.name "SNAPKITTY-SWARM" git config user.email "swarm@snapkittywest.io" git add -A if git diff --cached --quiet; then echo "[${{ matrix.repo }}] Nothing to commit." else git commit -m "⟦Ω⟧ swarm(${{ matrix.repo }}): $(date -u +%Y-%m-%dT%H:%M:%SZ)" git push origin HEAD echo "[${{ matrix.repo }}] Pushed." fi