Spaces:
Running
Running
| """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) | |