{"id":50989322,"url":"https://github.com/chifunghillmanchan/convoy","last_synced_at":"2026-06-20T00:01:17.032Z","repository":{"id":357220878,"uuid":"1235968807","full_name":"ChiFungHillmanChan/convoy","owner":"ChiFungHillmanChan","description":"Local coordination layer for AI coding agents — two Claude Code sessions in the same project can discover each other, claim files, send messages, and wait for peers.","archived":false,"fork":false,"pushed_at":"2026-05-11T21:09:42.000Z","size":163,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T22:27:29.161Z","etag":null,"topics":["ai-agents","claude-code","coordination","developer-tools","llm-tools","multi-agent","rust"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChiFungHillmanChan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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-05-11T20:36:22.000Z","updated_at":"2026-05-11T21:09:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ChiFungHillmanChan/convoy","commit_stats":null,"previous_names":["chifunghillmanchan/convoy"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ChiFungHillmanChan/convoy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChiFungHillmanChan%2Fconvoy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChiFungHillmanChan%2Fconvoy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChiFungHillmanChan%2Fconvoy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChiFungHillmanChan%2Fconvoy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChiFungHillmanChan","download_url":"https://codeload.github.com/ChiFungHillmanChan/convoy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChiFungHillmanChan%2Fconvoy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34552295,"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-19T02:00:06.005Z","response_time":61,"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":["ai-agents","claude-code","coordination","developer-tools","llm-tools","multi-agent","rust"],"created_at":"2026-06-20T00:00:50.824Z","updated_at":"2026-06-20T00:01:17.011Z","avatar_url":"https://github.com/ChiFungHillmanChan.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Convoy\n\n\u003e Local coordination layer for AI coding agents.\n\nTwo or more Claude Code sessions running in the same project (or in different\ngit worktrees of the same repo) can discover each other, share status, send\nmessages, claim files, and wait for peers — so they don't stomp on each\nother's work.\n\n**Status:** v0.1.0 (M1). Single-host, Claude Code only. Codex / Gemini\nadapters in M2. Native MCP integration in M1.1.\n\n---\n\n## Why Convoy\n\nIf you run multiple AI coding agents on the same machine, sooner or later\nthey will:\n\n- Edit the same file at the same time and clobber each other\n- Run conflicting `git` operations (stash, rebase, checkout) from underneath\n  each other\n- Repeat the same investigation independently\n- Sit idle waiting for a file they could have known was about to be released\n\nConvoy is a thin local layer that gives them just enough shared context to\nbehave like co-workers instead of strangers.\n\n```\n+----------------+        +----------------+\n|  Claude  A     |        |  Claude  B     |\n|  (terminal 1)  |        |  (terminal 2)  |\n|  branch X      |        |  branch Y      |\n+-------+--------+        +-------+--------+\n        |                         |\n        +------ hooks + CLI ------+\n                   |\n            +------+------+\n            |   convoyd   |\n            |  (one per   |\n            |   host)     |\n            +------+------+\n                   |\n            +------+------+\n            |  SQLite per |\n            |   project   |\n            +-------------+\n```\n\n---\n\n## What you get in v0.1.0\n\n- **Discovery** — `convoy session list-sessions` returns every active Claude\n  on the same project, with branch + last status.\n- **File claims** — `convoy session claim \u003cpath\u003e` reserves a file for your\n  session. Other sessions trying to claim get `held_by` + `held_until`.\n  Claims auto-expire on TTL (default 30 min).\n- **Inbox** — peers can send each other typed messages (`info`, `question`,\n  `ack`, `request-yield`, `status-broadcast`). Auto-injected into the next\n  Claude turn via hooks.\n- **Cooperative wait** — `convoy session wait` registers a non-blocking\n  subscription on a condition (lock released, peer ended, message received).\n  Wake-up is delivered on the next Claude turn.\n- **Crash recovery** — if a Claude session is SIGKILL'd, the daemon's PID\n  probe reaps it within ~5 minutes and releases its locks.\n- **Per-project isolation** — every project has its own SQLite at\n  `~/.convoy/projects/\u003cid\u003e/state.db`. Worktrees of the same repo share state\n  via `git rev-parse --git-common-dir`. `rm -rf` the folder = full reset for\n  that project.\n- **Transparent storage** — auto-generated markdown mirror in `exports/`:\n  `sessions.md`, `recent_mail.md`, `locks.md`. `cat` it any time without\n  touching SQLite.\n\n---\n\n## Install\n\nRequires Rust 1.85+ (workspace pins this in `rust-toolchain.toml`).\n\n```bash\ngit clone https://github.com/ChiFungHillmanChan/convoy\ncd convoy\ncargo install --path crates/convoy-bin\n```\n\nThis puts a `convoy` binary in `~/.cargo/bin/`.\n\n---\n\n## Quick start\n\n```bash\n# 1. Write hooks into ~/.claude/settings.json\nconvoy setup --yes\n\n# 2. Start the coordination daemon\nconvoy daemon \u0026                    # detaches; logs to ~/.convoy/daemon.log\n\n# 3. Open two Claude Code sessions in two terminals, both inside the\n#    same git repo (or two worktrees of the same repo). They auto-register.\n\n# 4. Inspect from a third terminal\nconvoy list                        # all projects\nconvoy status                      # this project's sessions + locks + mail\nconvoy show $(pwd) --section sessions\n```\n\nThe Claude model in each session can use any of these via `Bash`:\n\n```bash\nconvoy session list-sessions\nconvoy session claim ./src/main.rs --reason \"refactoring login\"\nconvoy session send --to \u003cpeer-id\u003e --kind question \"Are you done with config.yaml?\"\nconvoy session inbox --unread-only\nconvoy session wait --condition '{\"type\":\"lock_released\",\"abs_path\":\"./x.rs\"}'\nconvoy session status \"phase 1 done, starting tests\"\nconvoy session release ./src/main.rs\n```\n\nThe `SessionStart` and `UserPromptSubmit` hooks auto-inject peer state, unread\nmessages, and satisfied waits into the model's context — the model doesn't\nhave to remember to poll.\n\n---\n\n## What's coordinating exactly\n\nEach `~/.convoy/projects/\u003cproject-id\u003e/` holds:\n\n```\nmeta.toml        # project_path, created_at, status (active|finished)\nstate.db         # SQLite WAL: sessions, messages, file_locks, waits, ...\nexports/         # human-readable markdown mirror, regenerated every 10s\narchive/         # snapshots written by `convoy finish`\n```\n\nProject id = `sha256(realpath(git_common_dir or cwd))[:12]`. Git worktrees of\nthe same repo always map to the same project id.\n\n---\n\n## Lifecycle commands\n\n```\nconvoy list                          # show all known projects\nconvoy status [\u003cpath\u003e]               # active sessions, locks, recent mail\nconvoy show \u003cpath\u003e --section \u003cs\u003e     # render one of: sessions, recent_mail, locks\nconvoy export \u003cpath\u003e --to \u003cdir\u003e [--redacted]\n                                     # portable JSON+md bundle for sharing / bug reports\nconvoy finish \u003cpath\u003e                 # archive state, refuse new sessions\nconvoy reopen \u003cpath\u003e                 # undo finish\nconvoy forget \u003cpath\u003e --yes           # rm -rf this project's state\nconvoy doctor                        # check daemon health, schema versions, orphan locks\nconvoy gc --older-than 30            # drop ended-session rows older than N days\n```\n\n---\n\n## Design\n\nRead the design spec at\n[`docs/specs/2026-05-11-m1-design.md`](docs/specs/2026-05-11-m1-design.md) and\nthe TDD implementation plan at\n[`docs/plans/2026-05-11-m1-implementation.md`](docs/plans/2026-05-11-m1-implementation.md).\n\nKey choices:\n\n- **Single daemon, per-project SQLite** — one `convoyd` per host, lazy\n  `HashMap\u003cProjectId, Store\u003e` inside it. Crash-recoverable: SQLite is the\n  source of truth; daemon owns only liveness + push + exports.\n- **Hooks for passive awareness, CLI for active operations** — `SessionStart`\n  / `UserPromptSubmit` hooks inject context automatically; the model uses\n  `Bash(\"convoy session ...\")` calls for active coordination.\n- **Native MCP deferred to M1.1** — `rmcp` is still 0.x; the Bash surface\n  works today and is what Codex / Gemini will use in M2 anyway.\n- **Cooperative `wait_for`, not blocking** — LLM turns can't actually block;\n  waits are subscriptions, satisfaction is delivered on the next hook\n  injection.\n\n---\n\n## Roadmap\n\n| Milestone | Scope |\n|---|---|\n| **v0.1.0 (M1)** | Claude Code only, single host, Bash CLI coordination. **This release.** |\n| v0.2.0 (M1.1) | Native MCP tool surface once `rmcp` stabilises |\n| v0.3.0 (M2) | Codex CLI + Gemini CLI adapters (already-present `convoy session` Bash interface gets thin shims) |\n| v0.4.0 (M3) | Web dashboard at `localhost:7444`; multi-project switcher; comm volume analytics |\n| beyond | Cursor / VSCode internal-agent integration; remote host coordination |\n\n---\n\n## Architecture\n\nSeven Rust crates in a Cargo workspace:\n\n```\ncrates/\n+-- convoy-core      # pure domain types, no I/O\n+-- convoy-store     # Store trait + MemoryStore + SqliteStore + parity tests\n+-- convoy-daemon    # socket server, liveness probe, expiry sweep, notify, exports\n+-- convoy-hook      # 5 Claude Code lifecycle hooks\n+-- convoy-cli       # user-facing + session-facing subcommands\n+-- convoy-bin       # top-level `convoy` binary\n+-- convoy-e2e       # workspace integration tests (acceptance scenarios)\n```\n\n82 tests cover unit + integration + cross-store parity + proptest race\ninvariants + 10 e2e acceptance scenarios from the design spec §15.\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). The short version:\n\n- TDD: write the failing test before the fix\n- `cargo fmt --all \u0026\u0026 cargo clippy --workspace --all-targets -- -D warnings`\n  before pushing\n- Each commit should be focused and reviewable independently\n- One problem per PR\n\n---\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchifunghillmanchan%2Fconvoy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchifunghillmanchan%2Fconvoy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchifunghillmanchan%2Fconvoy/lists"}