{"id":50884403,"url":"https://github.com/keepitmello/claude-codex-meight","last_synced_at":"2026-06-18T18:00:54.914Z","repository":{"id":364352574,"uuid":"1267565743","full_name":"keepitmello/claude-codex-meight","owner":"keepitmello","description":"Agent-first harness: Claude Code drives OpenAI Codex workers like native subagents — mid-turn steering, token-free observation, bidirectional QUESTION protocol. Built on the official openai-codex Python SDK.","archived":false,"fork":false,"pushed_at":"2026-06-16T05:34:47.000Z","size":395,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-16T16:28:14.181Z","etag":null,"topics":["agent-orchestration","claude","claude-code","codex","llm-agents","multi-agent","openai-codex","subagents"],"latest_commit_sha":null,"homepage":null,"language":"Python","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/keepitmello.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-12T16:53:19.000Z","updated_at":"2026-06-16T05:34:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/keepitmello/claude-codex-meight","commit_stats":null,"previous_names":["keepitmello/claude-codex-meight"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/keepitmello/claude-codex-meight","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepitmello%2Fclaude-codex-meight","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepitmello%2Fclaude-codex-meight/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepitmello%2Fclaude-codex-meight/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepitmello%2Fclaude-codex-meight/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keepitmello","download_url":"https://codeload.github.com/keepitmello/claude-codex-meight/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepitmello%2Fclaude-codex-meight/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34457743,"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-17T02:00:05.408Z","response_time":127,"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":["agent-orchestration","claude","claude-code","codex","llm-agents","multi-agent","openai-codex","subagents"],"created_at":"2026-06-15T15:32:45.369Z","updated_at":"2026-06-17T17:01:18.716Z","avatar_url":"https://github.com/keepitmello.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# claude-codex-meight\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./docs/hero.jpg\" alt=\"Claude Fable 5 + Codex\" width=\"720\"\u003e\n\u003c/p\u003e\n\n**English** | [한국어](./docs/README.ko.md)\n\n\u003e **A two-way harness for Claude × Codex.** Not just dispatch-and-wait: Codex workers raise questions and flag better ideas mid-run, the Claude orchestrator consults them when it's stuck, and both sides review each other's work — a real collaboration loop, not one model bossing the other around. Built on the official `openai-codex` Python SDK. CLI: `meight`.\n\nMost Claude↔Codex bridges are built for *a human watching a terminal* — tmux panes to attach to, dashboards to click. Meight is built for the agents themselves: a Claude orchestrator and Codex workers collaborating directly, with no human in the loop. In practice that means:\n\n- **Both directions, same thread.** Codex isn't just an executor — a worker ends a turn with a `QUESTION:` to flag a better path or a shaky assumption (not only when it's blocked), and the orchestrator answers or adjusts the direction with it. Real back-and-forth, not fire-a-task-collect-a-result.\n- **Consult, don't just delegate.** Stuck on a design? The orchestrator dispatches a read-only worker to think a problem through *with* it — the sibling of code review, applied to the thinking instead of the artifact.\n- **Each model checks the other.** Codex implements → a Claude agent verifies; Claude implements → a Codex worker reviews. Cross-model review catches what same-model self-review misses.\n- **Supervised, on your terms.** The `start`+`wait` split lets the orchestrator pull `status` and `steer` mid-run — how often, and whether at all, is its judgment, not a fixed cadence. Progress lives in small disk files, so watching costs ~0 context.\n- **One-shot when it fits.** `meight dispatch` still gives fire-and-forget for trivial, short, low-risk tasks.\n\n```\n   Claude orchestrator   ⇄   Codex worker(s)\n   (what \u0026 why)               (how)\n        │                          ▲\n        ├──  start + brief  ───────┘\n        │\n        │◀──  QUESTION:  better idea · wrong assumption · blocked · done\n        │──▶  answer · steer · consult · review\n        │            (either side can open the next turn, same thread)\n        │\n        ▼   orchestrator pulls disk digests on demand — ~0 context, never streamed\n   per-repo daemon ── official openai-codex SDK ── codex app-server (1 process, N threads)\n        status.json · events.log · result.md\n```\n\n## Why two models, working together\n\nAnthropic's new Mythos-class models (**Claude Fable 5**) are remarkably good at planning and judgment — seeing the whole picture, breaking work down, making the right call when things are ambiguous. They are also expensive to run. Codex (**GPT-5.5**) costs much less per unit of work and is very good at the details: race conditions, type drift, missed edge cases, contract violations.\n\nMeight pairs them so you get higher quality at lower cost: Claude holds the *what and why*, Codex the *how*. But the division only pays off because the two work as **teammates, not boss and tool** — a worker pushes back when it sees a better path, the orchestrator consults a worker when it's stuck, and each reviews the other's output (cross-model review catches what same-model self-review misses). A side benefit: the workload spreads across two subscriptions. The full collaboration policy ships as [`CLAUDE.md`](./CLAUDE.md).\n\n## Why this exists\n\nAs of June 2026, every public Claude↔Codex project we could find drives Codex through its **CLI** — spawning `codex exec` subprocesses or typing into tmux. Tools built that way share the same limits: to redirect a running worker you have to kill it (and lose its work), to see progress you have to pipe everything into the orchestrator's context, and a stuck worker has no way to ask for help.\n\nOpenAI's official **`openai-codex` Python SDK** (released May 2026) removed those limits: it talks to `codex app-server` directly and exposes steering, interrupting, and streaming as real APIs, with a single Codex process running many workers at once. **Meight is — to our knowledge — the first public harness built on it.** Side by side:\n\n| | tmux/exec bridges | MCP wrappers | **Meight** |\n|---|---|---|---|\n| Parallel workers | 1 process per worker | blocking tool calls | N threads, 1 codex process |\n| Mid-turn steering | attach \u0026 type (human) or kill+resume (loses work) | ✗ | **`meight steer` — programmatic, no work lost** |\n| Progress observation | scrape stdout / stream into context | ✗ | **disk digest, pull on demand (~0 tokens)** |\n| Two-way conversation | ✗ (guesses or stalls) | ✗ | **worker raises `QUESTION:` (blocked *or* better idea) → exit 3 → `meight reply`; orchestrator can `consult` back** |\n| Result delivery | scrape | tool return | **exit-code contract + result on stdout** |\n| Session continuity | fragile | threadId | **same-thread `follow`/`reply` turns** |\n\n## Quick start\n\nRequirements: [Codex CLI](https://developers.openai.com/codex) installed \u0026 authenticated, Python ≥ 3.10.\n\n```bash\ngit clone https://github.com/keepitmello/claude-codex-meight\ncd claude-codex-meight \u0026\u0026 ./install.sh   # creates .venv + ~/.local/bin/meight\n```\n\nFor substantial work, use supervised dispatch (from any git repo — state is isolated per repo under `.meight/`). `start` expects the per-repo daemon to be running; if it is not, start it once separately with `meight daemon`.\n\n```bash\nmeight start impl-1 --brief-file - --cwd ~/my-repo \u003c\u003c'EOF'\nImplement X in src/foo.py. Existing pattern: see src/bar.py:42.\nVerify with: pytest tests/test_foo.py. Report changed files + test output.\nEOF\n\nmeight wait impl-1 --timeout 300\n# exit 0=completed · 2=failed/interrupted · 3=worker asked a question · 4=daemon dead · 1=checkpoint timeout\n```\n\nOn exit `1`, the worker is still running. Inspect once, then either wait again or steer:\n\n```bash\nmeight status impl-1\nmeight steer impl-1 \"Stop refactoring the helper — only fix the bug.\"\nmeight wait impl-1 --timeout 300\n```\n\nOn exit `0`, `2`, or `3`, `wait` prints a status summary. Read the full message from disk:\n\n```bash\nmeight result impl-1\n```\n\nThe worker asked a question (exit 3)? The question is also visible in `meight status impl-1` as `needs_input_detail`. Answer in one shot, same thread:\n\n```bash\nmeight reply impl-1 --brief \"Use config-a.json, and keep the legacy field.\"\n```\n\nYou're the one who's stuck? Run the loop the other way — dispatch a read-only worker to think a problem through *with* you, then `follow` to refine the direction together:\n\n```bash\nmeight start consult-1 --sandbox ro --brief \"My plan is X but I'm unsure about Y. Read src/ and tell me what I'm missing — and a better approach if you see one.\"\nmeight wait consult-1 --timeout 300\nmeight follow consult-1 --brief \"Good point on Y. If we go that way, how does Z hold up?\"\n```\n\nFor trivial, short, low-risk tasks, one-shot dispatch is still available:\n\n```bash\nmeight dispatch tiny-1 --brief \"Check whether README mentions LICENSE.\" --sandbox ro\n```\n\n## Using it from Claude Code\n\nThis is the intended consumer. For real work, run `wait --timeout` as the **background Bash call**. Claude wakes at the checkpoint, reads one `status`, and either waits again or sends a targeted `steer`:\n\n```\nBash(command: \"meight start review-1 --sandbox ro --effort high --brief-file - \u003c\u003c'EOF' ... EOF\")\nBash(command: \"meight wait review-1 --timeout 300\",\n     run_in_background: true)\n→ ... Claude keeps working ...\n→ \u003ctask-notification\u003e exit 1 checkpoint timeout\n→ meight status review-1\n→ healthy: wait again · drifting: meight steer review-1 \"...\"\n```\n\nWhen the worker reaches a terminal state, the notification is `0` (completed), `2` (failed/interrupted), or `3` (worker question). Use `meight result review-1` for the full report. On `0`, verify the work before accepting it. On `3`, answer with `meight reply`.\n\nEvery brief is automatically prefixed with a harness preamble that (a) forbids `git commit`/`push` — git stays owned by the orchestrator — and (b) frames the worker as a teammate: rather than guessing or silently complying, end with a `QUESTION:` paragraph when blocked *or* to flag a better approach, a wrong assumption, or a decision that could shift direction. Disable with `--no-preamble`.\n\nA drop-in orchestrator prompt (role split, routing table, dispatch protocol, cross-model review rules) ships as [`CLAUDE.md`](./CLAUDE.md) — copy it into your project or global Claude Code memory. A self-contained Claude Code **skill** ships at [`skills/meight/`](./skills/meight/SKILL.md) — copy it into `~/.claude/skills/` for trigger-based JIT loading.\n\n## What \"easy for an agent\" actually means\n\nSmall decisions everywhere assume the user is an LLM agent, not a person at a terminal:\n\n- **Exit codes are the API.** `0` done, `2` failed, `3` question, `4` daemon gone. The agent branches on a number instead of reading prose and guessing whether things worked. Unknown outcomes map to *failed*, never to *completed* — exit 0 can be trusted.\n- **Sparse checkpoints, not busy polling.** Set `wait --timeout` near the work's expected duration: finish in time and the orchestrator just gets the completion push; overrun and the timeout wakes it for one `status` look. A timeout returns exit `1` and leaves the worker running. No fixed interval, no obligation to check — `status` and `steer` stay available without tight polling loops that burn turns.\n- **Names, not session IDs.** Workers are addressed as `review-1`, follow-ups included. No UUID bookkeeping to get wrong.\n- **Results survive on disk.** `result.md` stays re-readable — if the agent's context gets compacted mid-session, nothing is lost.\n- **Status is pre-digested.** Instead of raw logs, `status` returns what a decision needs: what the worker is doing now, which files changed, its last thought. Exactly enough to choose between wait, steer, and interrupt.\n- **Policy can't be forgotten.** The no-commit rule and the QUESTION protocol are injected into every brief by the harness, not remembered by the agent.\n- **Briefs go through stdin.** Long multi-line briefs avoid shell-quoting traps entirely.\n\n## Command reference\n\n| Command | What it does |\n|---|---|\n| `meight start \u003cname\u003e [opts]` | Start a worker and return immediately with the thread id. Supervised workflow entry point. |\n| `meight wait \u003cname\u003e --timeout SEC` | Checkpoint wait: return on terminal state, QUESTION, daemon death, or timeout. Timeout leaves the worker running. |\n| `meight dispatch \u003cname\u003e [opts]` | One-shot: auto-start daemon → start worker → wait → print result. Use for trivial, short, low-risk work. |\n| `meight reply \u003cname\u003e --brief ...` | One-shot answer to a worker question: follow + wait + print last-turn result |\n| `meight status [name]` | Pull digest (table or detail). Reads disk — works without the daemon |\n| `meight steer \u003cname\u003e \"text\"` | Inject instruction into the running turn (no work lost) |\n| `meight interrupt \u003cname\u003e` | Cancel the running turn (idempotent) |\n| `meight follow \u003cname\u003e --brief ...` | Low-level: new turn on the same thread (context preserved) |\n| `meight result / list / daemon / ping / shutdown` | Low-level support commands |\n\nOptions: `--cwd` (worker workdir — use separate git worktrees for overlapping file scopes), `--sandbox ws|ro|full` (default `ws` = workspace-write; reviews run `ro`), `--effort low|medium|high|xhigh` (default `medium`; raise by task complexity), `--model`, `--fast`/`--no-fast` (per-worker toggle for the codex Fast/priority tier — `--no-fast` for a cheaper run; omit to inherit config), `--timeout`.\n\nWorker state lives in `\u003crepo\u003e/.meight/workers/\u003cname\u003e/`: `brief.md`, `status.json` (state machine + tokens + files changed + last activity), `events.log` (one line per meaningful event), `result.md` (final message per turn). Add `.meight/` to your global gitignore.\n\n## Good to know\n\n- Meight inherits your `~/.codex/config.toml` as-is (model, MCP servers, auth) — under the hood the SDK runs a standard `codex app-server`. If `codex` works in your terminal, `meight` works. Per-worker overrides (`--model`, `--fast`/`--no-fast`) take precedence over the config for that worker.\n- `openai-codex` is pinned (`0.1.0b3`, beta). When bumping, re-run the verification suite in [`SPEC.md`](./SPEC.md).\n- Design details — the concurrency model, state machine, and orchestration policy — live in [`ARCHITECTURE.md`](./ARCHITECTURE.md).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeepitmello%2Fclaude-codex-meight","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeepitmello%2Fclaude-codex-meight","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeepitmello%2Fclaude-codex-meight/lists"}