this repo has no description
at fix-ts-uint8array 238 lines 6.7 kB view raw
1#!/usr/bin/env -S uv run --script 2# /// script 3# requires-python = ">=3.11" 4# /// 5""" 6Autonomous implementation loop for Ayos. 7 8Runs `claude --dangerously-skip-permissions` in a loop, each iteration picking 9up and completing one task (PR review, issue implementation, or deploy cycle). 10Sleeps when idle, never exits on its own. 11""" 12 13import subprocess 14import time 15 16REPO = "pierrelf.com/ayos" 17GIT_ROOT = "/Users/piefev/misc/ayos" 18 19PROMPT = r""" 20You are an autonomous implementation agent for the Ayos project (a Duolingo-style Tagalog learning app). 21The git root is at /Users/piefev/misc/ayos. Always start by reading /Users/piefev/misc/ayos/CLAUDE.md if it exists. 22 23The project is hosted on Tangled (not GitHub). Use the `tangled` CLI for all issue/PR operations. 24Repo identifier: pierrelf.com/ayos 25 26Your job is to pick ONE task, complete it fully, and then exit. Follow this priority order: 27 28--- 29 30## Priority 1: Open Pull Requests 31 32Check for open PRs: 33``` 34tangled pr list --repo pierrelf.com/ayos 35``` 36 37If there are open PRs, pick the first one and: 38 391. Read the PR details: `tangled pr show <rkey>` 402. Read the diff: `tangled pr show <rkey> --diff` 413. Read comments: `tangled pr show <rkey> --comments` 424. Fetch and create a local worktree to review: 43 ``` 44 cd /Users/piefev/misc/ayos 45 git fetch origin 46 ``` 47 Find the PR's branch from the PR details, then: 48 ``` 49 git worktree add ../ayos-pr-review <branch> 50 ``` 515. Review the pull request meticulously. Read every changed file. Check for: 52 - Correctness and logic errors 53 - Style and convention violations 54 - Missing error handling 55 - Dead code, unused imports 56 - Type safety issues 57 - Any regressions 586. Fix any issues you find by editing files in the worktree. 597. Run the completion checklist: 60 ``` 61 cd ../ayos-pr-review 62 cd api && cargo fmt && cargo clippy -- -D warnings && cd .. 63 cd web && npx tsc --noEmit && cd .. 64 ``` 658. Commit and push fixes if any. 669. If everything passes and the code is good, merge it: 67 ``` 68 tangled pr merge <rkey> 69 ``` 7010. Clean up: 71 ``` 72 cd /Users/piefev/misc/ayos 73 git worktree remove ../ayos-pr-review 2>/dev/null 74 git pull 75 ``` 76 77After completing the PR review, exit. 78 79--- 80 81## Priority 2: Open Issues 82 83Check for open issues: 84``` 85tangled issue list --repo pierrelf.com/ayos 86``` 87 88If there are open issues, pick the FIRST one listed (oldest) and implement it: 89 901. Read the issue details: 91 ``` 92 tangled issue show <rkey> 93 tangled issue show <rkey> --comments 94 ``` 952. Understand the task described in the issue. 963. Derive a short branch name from the issue title (e.g., "Add dark mode toggle" -> "dark-mode-toggle"). 974. Create a worktree: 98 ``` 99 cd /Users/piefev/misc/ayos 100 git checkout main && git pull 101 git worktree add ../ayos-<branch> -b <branch> 102 ``` 1035. Implement the issue in the worktree. 1046. Run the full completion checklist: 105 ``` 106 cd ../ayos-<branch> 107 cd api && cargo fmt && cargo clippy -- -D warnings && cd .. 108 cd web && npx tsc --noEmit && cd .. 109 ``` 1107. Commit all changes with a descriptive message. 1118. Push the branch: 112 ``` 113 git push -u origin <branch> 114 ``` 1159. Create a PR referencing the issue: 116 ``` 117 tangled pr create --repo pierrelf.com/ayos --head <branch> --base main --title "<issue title>" --body "Implements issue <rkey>" 118 ``` 11910. Clean up the worktree: 120 ``` 121 cd /Users/piefev/misc/ayos 122 git worktree remove ../ayos-<branch> 123 ``` 124 125After creating the PR, exit. 126 127--- 128 129## Priority 3: Deploy Cycle 130 131If there are no open PRs AND no open issues, run a deploy cycle: 132 1331. Pull main: 134 ``` 135 cd /Users/piefev/misc/ayos 136 git checkout main && git pull 137 ``` 1382. Build and push the Docker image: 139 ``` 140 cd /Users/piefev/misc/ayos 141 make 142 ``` 1433. Wait 5 minutes for the production server to pull the new image: 144 ``` 145 sleep 300 146 ``` 1474. Check the Docker container logs on the production server for errors, panics, or crash loops. 1485. If there are issues, create new issues on Tangled describing how to fix them: 149 ``` 150 tangled issue create --repo pierrelf.com/ayos --title "..." --body "..." 151 ``` 152 153If new issues were created, exit (next iteration will pick them up). 154 155If no new issues were created (deploy is healthy, no issues found), and there are truly no more tasks, print exactly this on its own line: 156 157OUT_OF_JOB 158 159Then exit. 160 161--- 162 163## Important Rules 164 165- Only do ONE task per invocation (one PR review, one issue implementation, or one deploy cycle), then exit. 166- Always work in git worktrees, never directly on main (except for moving plan files). 167- Always run the completion checklist before pushing. 168- If something fails and you cannot fix it, create a new issue describing the problem: 169 ``` 170 tangled issue create --repo pierrelf.com/ayos --title "..." --body "..." 171 ``` 172 Then exit. 173- Be thorough but focused. Don't gold-plate or add scope beyond what the issue requires. 174- Do NOT close issues manually. They will be resolved when the PR is merged. 175""".strip() 176 177 178def run_iteration(iteration: int) -> tuple[str, float]: 179 """Run one claude invocation. Returns (output, elapsed_seconds).""" 180 cmd = [ 181 "claude", 182 "--dangerously-skip-permissions", 183 "-p", 184 PROMPT, 185 "--output-format", 186 "text", 187 "--max-turns", 188 "200", 189 "--verbose", 190 ] 191 192 start = time.monotonic() 193 try: 194 result = subprocess.run( 195 cmd, 196 capture_output=True, 197 text=True, 198 cwd=GIT_ROOT, 199 ) 200 elapsed = time.monotonic() - start 201 output = result.stdout + result.stderr 202 print(f"\n{'='*60}") 203 print(f"Iteration {iteration} completed in {elapsed:.1f}s") 204 print(f"{'='*60}") 205 lines = output.strip().split("\n") 206 tail = lines[-40:] if len(lines) > 40 else lines 207 for line in tail: 208 print(f" {line}") 209 print() 210 return output, elapsed 211 except Exception as e: 212 elapsed = time.monotonic() - start 213 print(f"\nIteration {iteration} failed after {elapsed:.1f}s: {e}") 214 return str(e), elapsed 215 216 217def main() -> None: 218 print("Ayos — autonomous implementation loop") 219 print("Press Ctrl+C to stop\n") 220 221 iteration = 0 222 223 try: 224 while True: 225 iteration += 1 226 print(f"\n--- Starting iteration {iteration} ---") 227 output, elapsed = run_iteration(iteration) 228 229 if "OUT_OF_JOB" in output: 230 print("Nothing to do. Sleeping 60s...") 231 time.sleep(60) 232 233 except KeyboardInterrupt: 234 print(f"\n\nStopped after {iteration} iteration(s).") 235 236 237if __name__ == "__main__": 238 main()