{"_id":"@astrosteveo/claudex","_rev":"5-9405a3543dac5272c7104cac2dfa6e55","name":"@astrosteveo/claudex","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.0":{"name":"@astrosteveo/claudex","version":"0.1.0","keywords":["claude-code","codex","mcp","ai","code-review","agent"],"license":"MIT","_id":"@astrosteveo/claudex@0.1.0","maintainers":[{"name":"astrosteveo","email":"stevengmjr@gmail.com"}],"homepage":"https://github.com/astrosteveo/claudex#readme","bugs":{"url":"https://github.com/astrosteveo/claudex/issues"},"bin":{"claudex":"dist/cli.js","claudex-mcp":"dist/mcp-server.js"},"dist":{"shasum":"60ebefd6aa5461c9075c55485301ca92c6eaf41a","tarball":"https://registry.npmjs.org/@astrosteveo/claudex/-/claudex-0.1.0.tgz","fileCount":8,"integrity":"sha512-Nl6SQoeiLcCsXN2JT6Kzq1lNzQKnDRdytfPJNKOi8SrfGdS/9ROEHVUYNwRRxYy0hbuoX74BMOYzlUFFEBtSwQ==","signatures":[{"sig":"MEYCIQCaROqx4XIRBpib6v7k8ay+Q4JeWwfSKP9nsol0nWMqpAIhAPkGYxT0KLmnE6HrLDaXcqOY4huYy/zKzWw4KAtBCik3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":857746},"type":"module","engines":{"node":">=20.11"},"gitHead":"12fc7d5f9f9f517b61dbe4877fe887426cb720b8","scripts":{"dev":"tsup --watch","test":"npm run build && node --test 'test/*.test.ts'","build":"tsup","test:only":"node --test 'test/*.test.ts'","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"astrosteveo","email":"stevengmjr@gmail.com"},"repository":{"url":"git+https://github.com/astrosteveo/claudex.git","type":"git"},"_npmVersion":"11.19.0","description":"Give Claude Code a governed second opinion from your authenticated Codex CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.22.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","typescript":"^5.9.2","@types/node":"^22.15.3"},"_npmOperationalInternal":{"tmp":"tmp/claudex_0.1.0_1788212119051_0.011122974079195158","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@astrosteveo/claudex","version":"0.1.1","keywords":["claude-code","codex","mcp","ai","code-review","agent"],"license":"MIT","_id":"@astrosteveo/claudex@0.1.1","maintainers":[{"name":"astrosteveo","email":"stevengmjr@gmail.com"}],"homepage":"https://github.com/astrosteveo/claudex#readme","bugs":{"url":"https://github.com/astrosteveo/claudex/issues"},"bin":{"claudex":"dist/cli.js","claudex-mcp":"dist/mcp-server.js"},"dist":{"shasum":"e5774a71c4b339b095f9f102388549316472f86f","tarball":"https://registry.npmjs.org/@astrosteveo/claudex/-/claudex-0.1.1.tgz","fileCount":8,"integrity":"sha512-vVSabIMj4zWitFHsmpk5rXN9Fx8LJj2NXCk0A8Jt+cElh7xO2k8MnF4ln9Kj1+IPe/NJRO3gtib/YDMhaw25dg==","signatures":[{"sig":"MEUCIQC2JFsirbk7XKLN/QfBTROJEYPCIHo097zToSoAF+fsnQIgVXjlDHrt+owH0z6u5xuYWnenNuA+RMaWaGcZJNKrekw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":858527},"type":"module","engines":{"node":">=20.11"},"gitHead":"75ce0ccb925dd91566eb6f2418cf6199bee6206d","scripts":{"dev":"tsup --watch","test":"npm run build && node --test 'test/*.test.ts'","build":"tsup","test:only":"node --test 'test/*.test.ts'","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"astrosteveo","email":"stevengmjr@gmail.com"},"repository":{"url":"git+https://github.com/astrosteveo/claudex.git","type":"git"},"_npmVersion":"11.19.0","description":"Give Claude Code a governed second opinion from your authenticated Codex CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.22.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","typescript":"^5.9.2","@types/node":"^22.15.3"},"_npmOperationalInternal":{"tmp":"tmp/claudex_0.1.1_1788212507709_0.819510887027064","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@astrosteveo/claudex","version":"0.1.2","keywords":["claude-code","codex","mcp","ai","code-review","agent"],"license":"MIT","_id":"@astrosteveo/claudex@0.1.2","maintainers":[{"name":"astrosteveo","email":"stevengmjr@gmail.com"}],"homepage":"https://github.com/astrosteveo/claudex#readme","bugs":{"url":"https://github.com/astrosteveo/claudex/issues"},"bin":{"claudex":"dist/cli.js","claudex-mcp":"dist/mcp-server.js"},"dist":{"shasum":"c5b7c0d5909e8aa9fd15f9711d2a81972df75e21","tarball":"https://registry.npmjs.org/@astrosteveo/claudex/-/claudex-0.1.2.tgz","fileCount":8,"integrity":"sha512-qS+DU7bm4SFpttg84zczSQAusXagGExdeq7n6NLWQz+x7zKeQaZQmuMLYvVGsEwCO+q823QBQCdq7ta6iidfpQ==","signatures":[{"sig":"MEUCIGs5nXzcDVm5VZ6gisdvZ2zP0IwOTkuu42B+BpstY438AiEAtaktOfHl2vjIbcWoKRGtkoK+kcUHiQJUjYAjlQI+1lo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":858966},"type":"module","engines":{"node":">=20.11"},"gitHead":"b5cb86547cfd9d9f4ff6bcaadbce0b404c72b83e","scripts":{"dev":"tsup --watch","test":"npm run build && node --test 'test/*.test.ts'","build":"tsup","test:only":"node --test 'test/*.test.ts'","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"astrosteveo","email":"stevengmjr@gmail.com"},"repository":{"url":"git+https://github.com/astrosteveo/claudex.git","type":"git"},"_npmVersion":"11.19.0","description":"Give Claude Code a governed second opinion from your authenticated Codex CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.22.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","typescript":"^5.9.2","@types/node":"^22.15.3"},"_npmOperationalInternal":{"tmp":"tmp/claudex_0.1.2_1788212648523_0.109120327809765","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@astrosteveo/claudex","version":"0.1.4","keywords":["claude-code","codex","mcp","ai","code-review","agent"],"license":"MIT","_id":"@astrosteveo/claudex@0.1.4","maintainers":[{"name":"astrosteveo","email":"stevengmjr@gmail.com"}],"homepage":"https://github.com/astrosteveo/claudex#readme","bugs":{"url":"https://github.com/astrosteveo/claudex/issues"},"bin":{"claudex":"dist/cli.js","claudex-mcp":"dist/mcp-server.js"},"dist":{"shasum":"9207ce540d48a810b8ca47e75589efe73b11a405","tarball":"https://registry.npmjs.org/@astrosteveo/claudex/-/claudex-0.1.4.tgz","fileCount":8,"integrity":"sha512-FyN/MDPA6fVFA/oJa3m9gKfiDmU4EDPi35fADnO3T3HkAudtGh0dTALmLH3z1dKnLWXa43nVg/06pLizDfsO9w==","signatures":[{"sig":"MEYCIQDy1nblzTLTUa9bb50US8nMrpupZ+99DZHbOOQ38MQieQIhAMGblQ4YdnY0A5O1iszFMPSDkGjooj9a9DINbNYo/BSH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":862087},"type":"module","engines":{"node":">=20.11"},"gitHead":"d6740eb07f365c0fed65d936c22a0247dfa53b8a","scripts":{"dev":"tsup --watch","test":"npm run build && node --test 'test/*.test.ts'","build":"tsup","test:only":"node --test 'test/*.test.ts'","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"astrosteveo","email":"stevengmjr@gmail.com"},"repository":{"url":"git+https://github.com/astrosteveo/claudex.git","type":"git"},"_npmVersion":"11.19.0","description":"Give Claude Code a governed second opinion from your authenticated Codex CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.22.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","typescript":"^5.9.2","@types/node":"^22.15.3"},"_npmOperationalInternal":{"tmp":"tmp/claudex_0.1.4_1788214036206_0.7854131062854222","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@astrosteveo/claudex","version":"0.1.5","description":"Give Claude Code a governed second opinion from your authenticated Codex CLI.","type":"module","license":"MIT","repository":{"type":"git","url":"git+https://github.com/astrosteveo/claudex.git"},"homepage":"https://github.com/astrosteveo/claudex#readme","bugs":{"url":"https://github.com/astrosteveo/claudex/issues"},"engines":{"node":">=20.11"},"bin":{"claudex":"dist/cli.js","claudex-mcp":"dist/mcp-server.js"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","test":"npm run build && node --test 'test/*.test.ts'","test:only":"node --test 'test/*.test.ts'","prepublishOnly":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.22.0","zod":"^3.25.76"},"devDependencies":{"@types/node":"^22.15.3","tsup":"^8.5.0","typescript":"^5.9.2"},"keywords":["claude-code","codex","mcp","ai","code-review","agent"],"publishConfig":{"access":"public"},"gitHead":"c37c251bd29ce4e6c28bdfea3bc7a786f0dd5ebe","_id":"@astrosteveo/claudex@0.1.5","_nodeVersion":"26.7.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-76cJpboPmrpSMaNyD2TFOAvdTnxMRt3lgXF85JmtwNh6Rjkmxji2CTwRtJS2255+FcJ5IkypXGowxjbzoHuI6w==","shasum":"cd887016458673b294b64af1dc562229d3511023","tarball":"https://registry.npmjs.org/@astrosteveo/claudex/-/claudex-0.1.5.tgz","fileCount":8,"unpackedSize":862801,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAF8BR2EBDdEqueC9PqV9o3J6aL+QAv0w3L37WTsoL51AiArbEYxzgTqZdxeoFRSOnQTj7s4SgCoS6wG6tnuCk56gQ=="}]},"_npmUser":{"name":"astrosteveo","email":"stevengmjr@gmail.com"},"directories":{},"maintainers":[{"name":"astrosteveo","email":"stevengmjr@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/claudex_0.1.5_1788215100658_0.40961208024000584"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T21:35:18.923Z","modified":"2026-08-31T22:25:00.962Z","0.1.0":"2026-08-31T21:35:19.197Z","0.1.1":"2026-08-31T21:41:47.864Z","0.1.2":"2026-08-31T21:44:08.675Z","0.1.4":"2026-08-31T22:07:16.340Z","0.1.5":"2026-08-31T22:25:00.818Z"},"bugs":{"url":"https://github.com/astrosteveo/claudex/issues"},"license":"MIT","homepage":"https://github.com/astrosteveo/claudex#readme","keywords":["claude-code","codex","mcp","ai","code-review","agent"],"repository":{"type":"git","url":"git+https://github.com/astrosteveo/claudex.git"},"description":"Give Claude Code a governed second opinion from your authenticated Codex CLI.","maintainers":[{"name":"astrosteveo","email":"stevengmjr@gmail.com"}],"readme":"# claudex\n\nGives **Claude Code** a second opinion from **Codex** — and gives you a dial for how often it asks.\n\nIf you pay for both Claude and ChatGPT, you already own two coding agents that were trained\ndifferently and fail differently. The problem is that they don't talk, and the obvious fix —\nwiring them together and letting one call the other whenever it feels like it — quietly spends\nthe second subscription.\n\nclaudex wires them together **and** puts a budget in front of the wire.\n\nThe point is not that one model is better. It is that **the agent reviewing the code is not the\nagent that wrote it**, so it has no sunk cost in the approach it is checking.\n\n---\n\n## Requirements\n\n- An active **Claude** subscription, logged in via `claude`\n- An active **ChatGPT** subscription, logged in via `codex login`\n- Node 20.11+\n\n`claudex doctor` checks all of it, including whether Codex is authenticated against a\nsubscription or an API key — the latter still works, but bills per token.\n\n---\n\n## Install\n\n```bash\nnpm install -g @astrosteveo/claudex\nclaudex doctor      # verify both CLIs are installed, authed, and behaving as claudex assumes\nclaudex install     # register the MCP server with Claude Code, and write the guidance skill\n```\n\nRestart any running Claude Code session afterwards.\n\n`install` records how to launch the server, and the durable form differs by install shape. A\nglobal install records the bare name `claudex-mcp`, resolved from **Claude Code's** PATH at\nlaunch — which is not this shell's, since the host does not initialise your shell environment.\nThat follows a global install migrated to a new Node, which an absolute path cannot. If the\nserver fails to connect from a GUI-launched host, or you want a deterministic version:\n\n```bash\nclaudex install --pinned    # records `npx -p @astrosteveo/claudex@<version> claudex-mcp`\n```\n\nPinned trades PATH independence for a registry dependency on a cold cache, and it stops\nfollowing `npm i -g` upgrades until you re-run `install`.\n\nOr as a Claude Code plugin, which bundles the server and the skill together — replace the path\nwith wherever this repo lives:\n\n```\n/plugin marketplace add astrosteveo/claudex\n/plugin install claudex\n```\n\n---\n\n## What Claude gains\n\nSix tools. All of them default to **read-only** — Codex can inspect the repository but not\nchange it — and every one of them passes through the budget first.\n\n| Tool | What it does |\n|---|---|\n| `ask_codex` | One narrow question. Codex reads the repo itself; you don't paste code at it. |\n| `codex_review` | Adversarial review, defaulting to the uncommitted changes. Returns a verdict. |\n| `codex_reply` | Continue a thread by id. Cheap, and pushing back is the intended use. |\n| `codex_delegate` | Hand Codex a scoped implementation task. **Writes to the working tree.** |\n| `codex_debate` | Two rounds: Codex answers independently, then attacks your answer. |\n| `codex_budget` | Free. How much consultation is left this session. |\n\nEvery answer comes back with a footer telling Claude to treat it as an argument to evaluate,\nnot a verdict to comply with. An agent that defers to its peer has bought nothing.\n\n```\nYou → claude\n  Claude: [reads the code, writes a fix]\n  Claude → ask_codex(\"Is this retry loop safe under concurrent failures?\")\n       Codex: [independently reads the repo] → \"No — two writers can both pass\n              the check at queue.js:41 before either increments.\"\n  Claude: [fixes the race it would not have caught reviewing its own work]\n```\n\n---\n\n## The dial\n\nThis is the part that isn't just \"two agents in a trenchcoat.\"\n\n```bash\nclaudex policy set on-request    # default: Claude asks when it judges it worthwhile\nclaudex policy set assisted      # + automatic review before commits, after repeated failures\nclaudex policy set aggressive    # + any non-trivial design decision\nclaudex policy set off           # installed but dormant\n```\n\nEach policy carries a budget, and the budget is **enforced in the server**, not suggested in a\nprompt:\n\n| Policy | Consults/session | Tokens/session | Cooldown |\n|---|---|---|---|\n| `off` | 0 | 0 | — |\n| `on-request` | 12 | 400k | none |\n| `assisted` | 25 | 900k | 10s |\n| `aggressive` | 60 | unlimited | none |\n\nTimeouts scale with the kind of work, from a 300s base (600s under `aggressive`): a question gets\nthe base, a debate 1.5x, a review or a delegated task 3x. A review reads the whole target and\nwrites structured findings — it is not a slower question, and one flat timeout either truncates\nevery review or lets a wedged question hang for a quarter of an hour.\n\nTune any of it:\n\n```bash\nclaudex policy budget --max-per-session 5 --max-tokens 200000\nclaudex policy budget --timeout-ms 600000               # base, before the per-kind multiplier\nclaudex policy budget --cooldown-ms 30000 --global      # user-level instead of project-level\n```\n\nWhen the budget runs out, the tool doesn't error — it returns a **structured refusal** that\nexplains what was spent and tells Claude not to retry. A language model can plan around that;\nit just retries an exception.\n\nPartial work is never passed off as finished. A consult that hits its timeout comes back with\nwhatever Codex managed to say, prefixed `[INCOMPLETE]`; one that emitted text and then failed is\nprefixed `[FAILED]`. Neither carries the peer footer, and **a review that did not finish never\nyields a verdict** — it reports `unknown`, which reads as changes-requested. Failing open there\nwould approve code the reviewer never finished reading.\n\nConfig layers lowest to highest: policy defaults → `~/.claudex/config.json` →\n`<project>/.claudex/config.json` → environment (`CLAUDEX_POLICY`, `CLAUDEX_MODE`,\n`CLAUDEX_MAX_PER_SESSION`, `CLAUDEX_TIMEOUT_MS`, `CLAUDEX_MODEL`). Project beats user so a repo\ncan tighten spend for everyone in it; environment beats both so one run can be steered without\nediting anything.\n\n`<project>/.claudex/config.json` is meant to be **committed** — that is how a repo binds everyone\nworking in it. The run state beside it (`consults.jsonl`, `sessions/`, `runs/`) is local and\nshould stay ignored.\n\nSee what it actually cost:\n\n```bash\nclaudex status      # consults, denials, failures, peer wall-clock, recent activity\nclaudex log -n 100  # raw records as JSONL\n```\n\n---\n\n## Giving reviewers real evidence\n\n```bash\nclaudex policy verify \"npm test\"\n```\n\nWith this set, `codex_review` runs your test suite **on the host** and hands Codex the result.\n\nThis is not a convenience. Inside Codex's sandbox, Node reports a spurious `EPERM` from every\nchild spawn even when the child runs fine — and `node --test` spawns a process per test file, so\na fully passing suite reports itself as failing. **A sandboxed peer's account of a test run is\nnot evidence.** claudex runs the command itself and hands over the real result.\n\n---\n\n## From the shell\n\nThe same machinery, without going through Claude Code:\n\n```bash\nclaudex ask \"does the cache in src/store.ts invalidate on write?\"\nclaudex review                          # uncommitted changes\nclaudex review \"the last 3 commits\"\n\nclaudex solve \"add retry with backoff to the upload path\" --apply\nclaudex debate \"should the queue be at-least-once or exactly-once here?\"\n```\n\nWithout `--apply`, `solve` stops after planning and prints the plan — the peer is read-only in\nthat mode, so running the review loop could only ever review an unchanged tree.\n\nWith `--apply`, `solve` runs **plan → implement → verify → review → fix**: Claude plans and reviews, Codex\nimplements, your test suite runs on the host between the two, and it loops until the reviewer\napproves or the round budget runs out.\n\n`debate` has both agents answer **independently** — neither sees the other's answer first, so\nagreement afterwards is evidence rather than an artifact of one anchoring the other — then\ncritique each other.\n\nBoth write a full transcript to `.claudex/runs/<n>-<kind>/`.\n\n---\n\n## Developing\n\n```bash\nnpm install\nnpm test                                     # build, then the whole suite\nnpm run test:only                            # suite without rebuilding\nnode --test test/budget.test.ts              # one file\nnode --test --test-name-pattern 'cooldown'   # one test by name\nnpm run typecheck\nnode dist/cli.js doctor                      # check the CLI assumptions still hold\n```\n\nThe sources run directly under Node's strip-only type stripping, so the suite needs no transform —\nwhich is why there are no TypeScript parameter properties or enums in the codebase.\n\n`test/mcp-server.test.ts` runs against `dist/`, so build before running it alone. No test ever\ninvokes a real Codex: the suite is fast, deterministic, and free.\n\n`claudex doctor` is the regression check for the outside world. Both CLIs move their flag surfaces\nbetween releases, and the failures that causes are silent — a sandbox flag that stops applying\ndoes not error, it just stops sandboxing.\n\n---\n\n## Design notes\n\n**One direction, on purpose.** Codex is a service here, not a peer with a session of its own.\nWiring the reverse would only pay off if a spawned `codex exec` called back into Claude — cold\ncontext, a recursion hazard, and real cost for near-zero gain. The agent adapters are symmetric\ninternally, so adding it later is an addition, not a rewrite.\n\n**Built on `codex exec`.** Codex also ships `codex mcp-server`, which would hand us thread\nmanagement for free — but it prints a deprecation warning and is slated for removal, and its\nsuccessor `codex app-server` is still experimental with a generated protocol. For a package\nother people install, `exec` is the interface that will still be there next month.\n\n**Bundled to single files.** The server is launched by an agent CLI, often inside a sandbox,\nwhere a transitive dependency that fails to resolve takes the whole integration down with no\nuseful error. `dist/` has no runtime resolution surprises.\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}