"""Grite: the issue tracker that lives in your repo, built for AI agents. This Space runs the REAL `grite` CLI (pip install grite-cli) inside a throwaway git repo to show the core idea from the paper "Before the Pull Request: Mining Multi-Agent Coordination" (arXiv:2606.19616): when issues live as an append-only event log in git refs, two agents can coordinate on the same repo with no server, no database, and no merge conflicts. Tool: https://github.com/neul-labs/grite · Paper: arXiv:2606.19616 """ import os import shlex import subprocess import tempfile import gradio as gr GRITE = os.environ.get("GRITE_BIN", "grite") def run(cmd, cwd): """Run a shell command, return (rc, combined_output). Never raises.""" try: p = subprocess.run( cmd if isinstance(cmd, list) else shlex.split(cmd), cwd=cwd, capture_output=True, text=True, timeout=60, env={**os.environ, "GRITE_NO_DAEMON": "1"}, ) out = (p.stdout or "") + (p.stderr or "") return p.returncode, out.strip() except Exception as e: return 1, f"(error: {e})" def _g(args, cwd): # grite in --no-daemon mode to avoid IPC in the sandbox return run([GRITE, "--no-daemon", *args], cwd) def setup_repo(): d = tempfile.mkdtemp(prefix="grite-demo-") run("git init -q", d) run("git config user.email demo@grite.dev", d) run("git config user.name grite-demo", d) # a file so the repo is real open(os.path.join(d, "greet.py"), "w").write("def greet(n):\n return f'Hello {n}'\n") run("git add -A && git commit -q -m init", d) _g(["init"], d) run("git add -A && git commit -q -m 'grite init' || true", d) return d def section(title, cmd, out): return f"### {title}\n```\n$ {cmd}\n{out or '(no output)'}\n```\n" def grite_version(): rc, out = run([GRITE, "--version"], tempfile.gettempdir()) return out if rc == 0 else "grite-cli (version unknown)" def multi_agent_demo(): d = setup_repo() report = [f"_Running real `grite` in a throwaway repo: `{d}`_ · {grite_version()}\n"] # Agent A: a task issue _, a = _g(["issue", "create", "--title", "Add --style flag to greet()", "--body", "formal / casual / enthusiastic styles", "--label", "agent:todo"], d) report.append(section("Agent A files a task", "grite issue create --label agent:todo …", a)) # Agent B (concurrently): a memory note — agents persist learnings as issues _, b = _g(["issue", "create", "--title", "[Memory] CLI uses argparse", "--body", "Pattern: ArgumentParser -> add_argument -> parse_args.", "--label", "memory"], d) report.append(section("Agent B records a memory", "grite issue create --label memory …", b)) # Both issues are there, merged, no conflict _, lst = _g(["issue", "list"], d) report.append(section("Both issues coexist (one repo, two agents)", "grite issue list", lst)) # The proof: the issues live in git refs; the only tree file is AGENTS.md _, refs = run("git for-each-ref --format='%(refname)' refs/grite", d) _, status = run("git status --porcelain", d) proof = ((refs or "(no grite refs found)") + "\n\nworking tree: " + (status or "clean") + "\n# ^ the issues live in refs/grite/wal (the append-only event log)." + "\n# the only file grite writes to your tree is AGENTS.md, so agents discover it.") report.append(section("It lives in git, not a server", "git for-each-ref refs/grite ; git status", proof)) # AGENTS.md so agents discover grite on entry agents_md = "" p = os.path.join(d, "AGENTS.md") if os.path.exists(p): agents_md = open(p).read()[:600] if agents_md: report.append("### grite init drops an AGENTS.md so any agent discovers it\n```\n" + agents_md + "\n```\n") report.append("> Two agents. One repo. No server, no database, no merge conflict. " "The coordination signal lives *before the pull request* " "([arXiv:2606.19616](https://huggingface.co/papers/2606.19616)).") return "\n".join(report) def custom_issue(title, body, label): if not title.strip(): return "Enter a title first." d = setup_repo() _, out = _g(["issue", "create", "--title", title, "--body", body or "", "--label", label or "agent:todo"], d) _, lst = _g(["issue", "list"], d) _, refs = run("git for-each-ref --format='%(refname)' refs/grite", d) return section("Created", f"grite issue create --title '{title}' --label {label or 'agent:todo'}", out) + \ section("grite issue list", "grite issue list", lst) + \ section("stored in git refs", "git for-each-ref refs/grite", refs or "(none)") HEADER = """# Grite: an issue tracker that lives in your repo Built for AI agents. Works for humans. Issues are an **append-only event log in git refs** (`refs/grite/wal`) — no server, no database, and CRDT merge means no conflicts when multiple agents work the same repo. Your issues branch when you branch and sync on `git push`. This Space runs the **real `grite` CLI** to show it. Companion to the paper **[Before the Pull Request: Mining Multi-Agent Coordination](https://huggingface.co/papers/2606.19616)** — the missing coordination signal lives before the PR. 🔧 Tool: [github.com/neul-labs/grite](https://github.com/neul-labs/grite) · `pip install grite-cli` """ with gr.Blocks(title="Grite — git-native issue tracking for agents") as demo: gr.Markdown(HEADER) with gr.Tab("Two agents, zero conflicts"): btn = gr.Button("Run the multi-agent demo", variant="primary") out = gr.Markdown() btn.click(multi_agent_demo, None, out) demo.load(multi_agent_demo, None, out) with gr.Tab("File your own issue"): t = gr.Textbox(label="Title", value="Add input validation") b = gr.Textbox(label="Body", value="Reject empty names", lines=2) l = gr.Dropdown(["agent:todo", "memory", "bug", "task"], value="agent:todo", label="Label") cb = gr.Button("grite issue create", variant="primary") co = gr.Markdown() cb.click(custom_issue, [t, b, l], co) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)