{"id":50781362,"url":"https://github.com/ngthluu/agentloop","last_synced_at":"2026-06-12T03:30:22.862Z","repository":{"id":362021429,"uuid":"1256902961","full_name":"ngthluu/agentloop","owner":"ngthluu","description":"1 prompt 1 product","archived":false,"fork":false,"pushed_at":"2026-06-02T09:03:18.000Z","size":166,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-02T09:22:10.979Z","etag":null,"topics":["agentic-ai","claude-code","codex-cli","harness-engineering"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngthluu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-02T07:25:16.000Z","updated_at":"2026-06-02T09:03:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ngthluu/agentloop","commit_stats":null,"previous_names":["ngthluu/agentloop"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ngthluu/agentloop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngthluu%2Fagentloop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngthluu%2Fagentloop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngthluu%2Fagentloop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngthluu%2Fagentloop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngthluu","download_url":"https://codeload.github.com/ngthluu/agentloop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngthluu%2Fagentloop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34228097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-ai","claude-code","codex-cli","harness-engineering"],"created_at":"2026-06-12T03:30:21.520Z","updated_at":"2026-06-12T03:30:22.853Z","avatar_url":"https://github.com/ngthluu.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agentloop\n\nAutonomous app builder. Give it one goal; a manager maintains a business backlog,\narchitects write per-task technical designs, builders implement independent subitems\nin parallel git worktrees, `verify.sh` checks software behavior, and a silly\ncustomer approves each business task against its acceptance criteria before the loop\ncalls it done.\n\nWhen run in a terminal it shows a live TUI: a goal-entry screen lets you confirm or\nedit the goal before anything runs, then a jobs panel and a persistent input bar for\nadding tasks. Questions agents raise are answered automatically (\"you decide\"), so\nthe loop never waits on you. When the goal is done it stays alive in standby so you\ncan keep adding tasks. Piped/non-TTY runs fall back to plain event-line output and\nexit on completion.\n\n## Install\n\nPrebuilt binaries (macOS arm64/x86_64, Linux x86_64):\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/ngthluu/agentloop/main/scripts/install.sh | bash\n```\n\nThis installs the `agentloop` binary to `~/.local/bin` (override with\n`AGENTLOOP_INSTALL_DIR=/usr/local/bin`). Ensure the install dir is on your `PATH`.\nThe `claude` and/or `codex` CLIs must also be on `PATH` at runtime.\n\n## Requirements\n\nRust (edition 2021), git, and the `claude` and/or `codex` CLIs on PATH.\n\n**Platforms: macOS and Linux only.** agentloop manages agent processes with POSIX\nprocess groups and signals; it does not build on Windows (a clear `compile_error!`\nsays so). Use WSL on Windows.\n\n## Security model — read this first\n\nagentloop is built to run **unattended**, which means it deliberately removes the\nsafety prompts you may be used to:\n\n- Every agent is spawned with permission checks disabled (`claude\n  --dangerously-skip-permissions`, `codex --yolo`). Agents can run any shell\n  command, edit any file your user can, and access the network.\n- `.agentloop/verify.sh` is executed via `bash` on every iteration. It is\n  arbitrary code living inside the workspace — anything that can write to the\n  workspace (including the agents themselves) controls what it does.\n- Task descriptions, designs, and notes written by one agent are fed into the\n  prompts of others. agentloop sanitizes the *identifiers* (branch/path safety)\n  and bounds the *sizes*, but it cannot make prompt content trustworthy.\n\nTherefore: **only point agentloop at goals and workspaces you trust, with\ncredentials you accept being exercised autonomously.** For anything else, run it\ninside a container or VM with scoped credentials. A run can also spend real API\ncredits for hours; set `caps.total_budget_sec` / `caps.max_iterations`\naccordingly and watch the first runs of a new goal.\n\n## Build\n\n```bash\ncargo build --release\n```\n\n## Usage\n\n```bash\n./target/release/agentloop \"\u003cgoal\u003e\" --workspace ./app   # pre-fills goal-entry screen with \u003cgoal\u003e\n./target/release/agentloop --workspace ./app             # resume: entry screen pre-filled from goal.md\n./target/release/agentloop --workspace ./new-dir         # fresh dir: entry screen is empty\n```\n\nEvery interactive (terminal) launch opens on a **goal-entry screen** first. The screen\nis pre-filled with the existing goal from `\u003cworkspace\u003e/.agentloop/state/goal.md`, or\nempty on a fresh workspace. Nothing runs until you\ntype/edit the goal and press `enter` (the \"[ Continue ]\" action). `Ctrl-C` at the\nentry screen quits without running. A goal passed as the CLI argument pre-fills the\nentry screen rather than starting immediately.\n\nHeadless/piped (non-TTY) runs are unchanged: they use the goal arg or persisted goal\nand run directly without the entry screen.\n\nOptions:\n\n- `--config \u003cpath\u003e` — `config.json` path. By default agentloop uses\n  `$AGENTLOOP_CONFIG` when set, otherwise `~/.agentloop/config.json`.\n- `--fresh` — wipe existing `.agentloop` state and start over. Prompts for\n  confirmation (it deletes all run state, logs, and results); pass `--yes` to\n  skip the prompt in scripts. The existing goal is preserved unless you pass a\n  new one.\n- `--yes` — skip confirmation prompts (required for `--fresh` when not on a TTY)\n- `--max-iterations N` — override `caps.max_iterations` from config\n- `--dry-run` — run the manager once and print the business backlog; do not dispatch builders\n- `--report` — print the bounce/failure troubleshooting report for the workspace and exit\n\nOne run per workspace: agentloop holds an advisory lock on\n`.agentloop/state/.lock`; a second concurrent run on the same workspace exits\nwith an error instead of corrupting shared state.\n\n## How it works\n\n- **State:** `.agentloop/state/backlog.json` is the manager-owned business backlog,\n  with `.agentloop/state/master.md` as the human-readable status board. Per-task\n  technical state lives under `.agentloop/state/tasks/\u003ctask-id\u003e/`, including the\n  architect's `design.md`, builder subitems, and customer approval state.\n- **Routing:** global `~/.agentloop/config.json` maps roles to tool/model/effort.\n  The available roles are `manager`, `architect`, `builder`, `customer`, and\n  `resolver`. Tool permission switches are fixed by agentloop: `claude` always gets\n  `--dangerously-skip-permissions`, and `codex` always gets `--yolo`.\n  An omitted `model`/`effort` leaves the choice to the tool itself — the default\n  config pins no codex model, because codex model slugs churn (`gpt-5` no longer\n  exists). Press `ctrl-o` in the TUI to pick and persist tool/model/effort per\n  role: edits are written back to the config file immediately and apply to the\n  running loop from its next dispatch.\n- **Gate and customer:** `.agentloop/verify.sh` still gates software behavior, so\n  agentloop can target any kind of software. The manager owns the script; its\n  contract is build + the project's test suite, nothing more. A business task's\n  acceptance run passes that task id as `$1` (so one task's flaky check can't\n  fail — and force a redesign of — an unrelated task); the per-iteration DONE\n  gate runs with no arguments. Scripts may ignore `$1` and always run everything.\n  After the scoped gate passes for a business task, the customer approves or\n  rejects that task by its acceptance criteria.\n  The gate runs in its own process group with a wall-clock cap (default 30 min,\n  override with `AGENTLOOP_GATE_TIMEOUT_SECS`) so a hung verify.sh can never\n  hang the loop; a timeout reads as a gate failure (rc 124).\n- **Caps:** `max_iterations`, `max_parallel`, `item_timeout_sec`, `total_budget_sec`,\n  `max_attempts`, and `max_redesigns` (whole-task re-plans; deliberately separate\n  from and higher than the per-builder attempt cap, so a handful of flaky gate\n  runs can't fail a task outright). The loop also stops on a no-progress stall: two consecutive\n  iterations that merge nothing **and** change no loop-relevant state (gate verdict,\n  backlog/builder statuses and attempts). Iterations where the manager re-scopes a\n  failed task or a builder consumes an attempt count as progress — those are\n  cap-bounded, so they can't keep the loop alive forever.\n- **Parallelism:** independent ready items run concurrently, each in its own git worktree;\n  successful builders are merged back sequentially. Loop-owned tracked changes under\n  `.agentloop/` (e.g. the manager's verify.sh rewrites) are auto-committed before\n  integration so they never read as a dirty tree; USER uncommitted changes still block\n  all merges — that bounce refunds the builder's attempt, since the dirty tree says\n  nothing about the work.\n- **No-change dones:** a builder that verifies its item and finds the acceptance\n  criteria already hold reports done with `\"no_changes\": true` and commits nothing —\n  accepted as a first-class done (the task-scoped gate still judges the task). A done\n  with no commits and no such declaration is bounced as a lazy builder.\n- **Merge conflicts:** when a builder's branch conflicts on merge, agentloop spawns a\n  dedicated **resolver** agent (config role `resolver`) in the workspace to resolve the\n  conflict and complete the merge, instead of bouncing the item. The resolver is unbounded\n  (no attempt cap, no timeout) but is killed when you quit, so it never orphans. If it\n  cannot resolve, the merge is aborted and the item is returned for manager repair.\n- **Autonomous decisions:** a builder that hits a decision writes\n  `.agentloop/questions/\u003cid\u003e.json` and reports `status:\"needs_input\"`. The loop answers\n  it immediately with a canned \"decide the best option for me — you decide\" reply\n  (stored in `.agentloop/answers/\u003cid\u003e.json`) and re-dispatches the item with the Q\u0026A\n  appended to its prompt. Nothing waits on the user.\n- **Usage limits:** when claude/codex dies on a provider usage/rate limit, agentloop\n  parses the reset time when the output includes one (else waits a fallback window),\n  logs a ⏳ note to the job log, and re-runs the agent automatically. Quitting\n  interrupts the wait.\n- **Backlog repair:** after every manager round the orchestrator drops deps on ids\n  that don't exist in the backlog, re-architects `in_progress` tasks that lost their\n  plan, and redesigns plans whose remaining items can never dispatch — the loop never\n  idles while open work exists.\n- **Add tasks any time:** an add-task request is appended to `.agentloop/state/requests.jsonl`;\n  the manager folds it into the business backlog on its next round (you feed intent;\n  the manager stays the sole owner of the backlog).\n- **Standby:** on completion (or a cap/stall) the interactive run idles in standby instead\n  of exiting; adding a task re-engages it with a fresh budget window. The status bar\n  shows *why* it parked (done / stall / max_iterations / budget, with open and failed\n  counts).\n- **Failed tasks hold the run open:** a task that exhausts its redesign cap is marked\n  `failed`, but the run is only DONE when the gate passes and **no open or failed**\n  items remain. Every failed item — including leaves nothing depends on — is listed\n  in the manager prompt with its failure note, and the manager is required to\n  reshape it into new tasks or drop it, instead of the loop silently ending over\n  (or grinding forever against) abandoned work.\n- **Re-run = more context:** re-running with new goal text (without `--fresh`) appends it\n  to `goal.md` and queues it as a pending request, so the manager folds it into the\n  business backlog as new tasks and the loop re-engages instead of reporting an instant\n  \"Done, nothing changed.\"\n\n## Interactive mode (TUI)\n\nRunning in a terminal opens a full-screen panel. A persistent, text-wrapping input bar\nsits at the bottom of the screen at all times (similar to Claude Code's input). Keys:\n\n- Printable keys always type into the persistent bottom input bar; it wraps long text\n  automatically. `shift+enter` (or `alt+enter`) inserts a newline.\n- `enter` — submits the input as a new task for the manager. When the input is empty,\n  `enter` opens the selected job's detail view (live log tail + a real-time working\n  timer).\n- `↑`/`↓` — navigate the jobs list, or scroll the log in the job-detail view\n- `esc` — clear the input bar, or leave the job-detail view\n- `q` — quit (only when the input bar is empty); `Ctrl-C` always quits\n\nThe status bar shows the goal, current iteration, gate state, open-item count, and a\nlive `⏱` total-run-time readout. When the run parks, the banner says why:\n`✓ DONE · standby` only when everything is done and the gate passes, otherwise\n`⏸ standby: \u003creason\u003e` (stall / max_iterations / budget, with open and failed counts).\nThe gate itself appears as a `gate` job row while `verify.sh` runs, so a long verify\nnever looks like a dead loop. (Headless runs print the total elapsed time on exit.)\nLong goals are ellipsized so the counters and timer always stay visible.\n\nThe main panel is the Jobs list (full width).\n\n## Troubleshooting\n\nNothing the loop produces is deleted:\n\n- `.agentloop/state/events.jsonl` — append-only history of every dispatch and\n  status transition (bounced/failed/merged/approved/rejected/redesign) with its\n  reason. `agentloop --report --workspace \u003cdir\u003e` prints all bounced and failed\n  cases plus what is currently failed in the backlog and builder plans.\n- `.agentloop/logs/iter-N/` — per-iteration agent logs, plus each builder's\n  archived result JSON (timestamp-prefixed).\n- `.agentloop/logs/gate.log` — every verify.sh run (timestamp, rc, full output);\n  `state/last_gate.txt` keeps just the latest.\n- `.agentloop/state/tasks/\u003cid\u003e/archive/` — superseded builder plans, designs,\n  customer reviews, and redesign counters.\n- `.agentloop/logs/answered-\u003cid\u003e-\u003cts\u003e.json` — consumed agent questions.\n\nThese files and archive dirs grow without bound by design (they are the audit\ntrail); prune them manually — or start over with `--fresh` — if a long-lived\nworkspace gets too big.\n\nBefore running, agentloop verifies that every CLI tool the config routes roles\nto (claude/codex) is installed, and exits with install instructions otherwise.\n\n## Layout\n\n```\nsrc/\n  main.rs          binary entry point\n  cli.rs           arg parsing (clap), workspace bootstrap, dry-run wiring\n  config.rs        Config / Caps / Role deserialization + helpers\n  state.rs         backlog.json validate / query / mutate (atomic writes)\n  spawn.rs         timeout + claude/codex command building (+ fake-agent hook)\n  worktree.rs      worktree create / merge / cleanup\n  manager.rs       business backlog prompt + invoke + validate\n  architect.rs     per-business-task design + builder plan prompt\n  worker.rs        builder and resolver prompts + dispatch\n  customer.rs      acceptance-criteria approval prompt + validation\n  task_state.rs    task-local design/builders/customer state helpers\n  events.rs        Reporter trait, Event/Command enums, stderr + channel reporters\n  history.rs       append-only state/events.jsonl, artifact archiving, --report\n  preflight.rs     startup check that configured agent CLIs are installed\n  inbox.rs         question/answer file IO + prior-Q\u0026A prompt block (auto-answered)\n  limits.rs        usage/rate-limit detection + auto-continue wait math\n  requests.rs      pending user-request log (requests.jsonl) + manager prompt block\n  orchestrator.rs  iteration loop, dispatch, integration, termination, standby machine\n  tui.rs           ratatui view-model (events -\u003e state, keys -\u003e commands) + render\n  app.rs           wires orchestrator + TUI over channels; TTY vs headless dispatch\n  bin/fake_agent.rs  offline stub used by tests\ntemplates/\n  master.md        embedded default master status board\ntests/             offline integration suite (fake_agent, scripted stub, no tokens)\n```\n\n## Releasing (CD)\n\nReleases are cut by pushing to the `production` branch:\n\n1. Bump `version` in `Cargo.toml` (e.g. `0.1.0` -\u003e `0.1.1`) and merge to `main`.\n2. Fast-forward/merge `main` into `production` and push:\n\n   ```bash\n   git push origin main:production\n   ```\n\n3. The `release` workflow reads `version` from `Cargo.toml`, creates and pushes\n   the tag `v{version}`, builds `agentloop` for each supported target, and\n   publishes a GitHub Release with the `agentloop-\u003ctarget\u003e.tar.gz` assets.\n\nIf the tag `v{version}` already exists, the workflow no-ops — bump the version to\ncut a new release. `install.sh` always fetches the **latest** release.\n\n## Tests\n\n```bash\ncargo test          # offline; uses the in-crate fake_agent + scripted stub, no tokens spent\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngthluu%2Fagentloop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngthluu%2Fagentloop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngthluu%2Fagentloop/lists"}