Skip to content

feat(codex): Add first-class Codex support#79

Open
reneleonhardt wants to merge 4 commits into
JordanCoin:mainfrom
reneleonhardt:feat/codex-first-class
Open

feat(codex): Add first-class Codex support#79
reneleonhardt wants to merge 4 commits into
JordanCoin:mainfrom
reneleonhardt:feat/codex-first-class

Conversation

@reneleonhardt

@reneleonhardt reneleonhardt commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

  • Add first-class Codex project setup, hooks, MCP configuration, plugin installation, upgrades, and diagnostics without replacing Claude integration.
  • Use absolute, versioned executable paths so managed integrations do not depend on a restricted host PATH.
  • Validate Codex hook trust and distinguish CLI and Desktop runtimes independently.
  • Make setup and plugin installation idempotent while preserving unrelated user configuration.
  • Allow hooks-only setup with --no-mcp when the Codex plugin owns MCP.
  • Document the one-time plugin-first setup order and per-project upgrade refresh workflow.
  • Unify codemap mcp and codemap-mcp option parsing and server behavior.

Type of change

  • Bug fix
  • New feature
  • New language support
  • Documentation
  • Other (describe below)

Checklist

  • I've tested this locally with go build && ./codemap .
  • I've read CONTRIBUTING.md (for new language support)
  • I've updated documentation if needed

Additional notes

Codemap was Claude-first. Codex integrations could fail because of restricted host PATHs, stale project overrides, untrusted hooks, and unclear plugin upgrades. This change lets both agents operate independently or together without overwriting existing configuration.

The final MCP commit routes both executable entrypoints through the same runtime-option parser and server constructor. A black-box parity test compares option errors, tool discovery, status guidance, and file-search responses.

Formatting, modules, vet, staticcheck, focused and race tests, debug smoke,
entrypoint parity, repeated plugin/setup, and CLI-less doctor validation pass.

Reviewer setup:

set -euo pipefail

ROOT=$PWD
BRANCH=feat/codex-first-class
REVIEW_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/codemap-codex-review.XXXXXX")
WT="$REVIEW_ROOT/worktree"
DEBUG_BIN="$REVIEW_ROOT/codemap-debug"
COVERAGE_OUT="$REVIEW_ROOT/coverage.out"

cleanup() {
  cd "$ROOT"
  git worktree remove --force "$WT"
  rm -rf "$REVIEW_ROOT"
}
trap cleanup EXIT

git worktree add --detach "$WT" "$BRANCH"
cd "$WT"
go fmt ./...
git diff --exit-code
go mod verify
go vet ./...
staticcheck ./...
go test . ./cmd ./mcp ./plugins ./internal/buildinfo -count=1
go test -race -coverprofile="$COVERAGE_OUT" ./...
go build -gcflags='all=-N -l' -o "$DEBUG_BIN" .
"$DEBUG_BIN" --version
"$DEBUG_BIN" .

REVIEW_HOME="$REVIEW_ROOT/home"
PROJECT="$REVIEW_ROOT/project"
NO_AGENT_PATH="$REVIEW_ROOT/no-agent-bin"
mkdir -p "$REVIEW_HOME" "$PROJECT/.git" "$NO_AGENT_PATH"
printf 'package main\n' > "$PROJECT/main.go"

HOME="$REVIEW_HOME" "$DEBUG_BIN" plugin install --home "$REVIEW_HOME" --no-activate
HOME="$REVIEW_HOME" "$DEBUG_BIN" plugin install --home "$REVIEW_HOME" --no-activate
HOME="$REVIEW_HOME" PATH="$NO_AGENT_PATH" "$DEBUG_BIN" setup --agent codex "$PROJECT"
HOME="$REVIEW_HOME" PATH="$NO_AGENT_PATH" "$DEBUG_BIN" setup --agent codex "$PROJECT"
HOME="$REVIEW_HOME" PATH="$NO_AGENT_PATH" "$DEBUG_BIN" doctor "$PROJECT"
cleanup
trap - EXIT

To test the live MCP integration, run Codex against the generated project, trust the hooks from /hooks in CLI or Settings > Hooks in Desktop, and start a new task. The generated project configuration already points to the exact debug binary.

Developed with carefully directed, manually reviewed AI assistance. Allow edits by maintainers is enabled, so maintainers are welcome to fix wording or make minor cleanup directly; broader review feedback will be incorporated.

Co-Authored-By: GPT-5.6 Sol codex@openai.com

reneleonhardt and others added 3 commits July 13, 2026 00:21
Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
@reneleonhardt
reneleonhardt force-pushed the feat/codex-first-class branch from 55d847c to 14bf9eb Compare July 13, 2026 12:13
Co-Authored-By: GPT-5.6 Sol <codex@openai.com>

@JordanCoin JordanCoin left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Impressive work — this got a deep review, including hands-on verification of the risky parts. The idempotency and config-preservation claims hold up: TOML comments and unrelated tables in .codex/config.toml survive, unknown JSON keys and user hooks are preserved, a second run is a byte-identical no-op, and a codemap MCP entry codemap didn't write is refused rather than clobbered. Hook trust stays read-only (nothing auto-trusts), the process-probe code is bounded and defensive, and pelletier/go-toml/v2 is a good pinned choice. The codemap mcp/codemap-mcp parity test is a nice touch. CI is green.

Requesting changes on four points before merge:

  1. Bug: silent integer corruption in ~/.claude.json. ensureClaudeMCPWithExecutable (cmd/setup.go) round-trips the whole file through map[string]any, so integers > 2^53 get float64-mangled — reproduced locally: "bigInt": 9007199254740993 becomes 9007199254740992 after setup --global. That's Claude Code's monolithic state file. Please use json.Decoder.UseNumber() (same pattern applies to the hooks/marketplace writers), and write via temp-file + rename so a crash can't truncate the file — the whole-file rewrite is currently non-atomic and can race a running Claude Code session.

  2. Default behavior change for every user. Plain codemap setup (default --agent both) now writes .codex/hooks.json, .codex/config.toml, and — notably — a machine-specific absolute path into project .mcp.json, which is conventionally a committed, shared file. Teammates who pull that get broken entries pointing at someone else's filesystem. Suggest defaulting to detected agents (doctor already knows how to detect them) and/or warning when an absolute path is about to land in a committed file.

  3. Test coverage doesn't match the change. Roughly ~860 lines of new branching logic — RunDoctor, validateCodexHookTrust, the TOML surgery (replaceCodexMCPCommand, tomlCommentIndex), migrateOwnedHookCommand, and the session-lease code — have no unit tests. The tricky parts here (line-surgery on user config, stale-lock reclaim) are exactly where regressions will hide; they deserve coverage matching their subtlety.

  4. Consider splitting the MCP entrypoint unification (cmd/mcp.go, the mcp/main.go RuntimeOptions work, internal/buildinfo + goreleaser ldflags, mcp_entrypoints_test.go, launcher-script deletion) into its own PR — it's independently mergeable, and slicing it out would make the Codex-specific remainder much easier to re-review.

One observation for the docs rather than a change request: codemap doctor executes binaries at absolute paths recorded in project-local config (.codex/config.toml / .mcp.json), so running doctor inside an untrusted repo runs a repo-chosen path. The args-shape and absolute-path checks bound this well, but it's worth a note in the doctor docs.

(FYI: the scanner/TestFindBundledAstGrepBinaryPrefersSiblingAstGrep failure you may see in full-suite local runs is a pre-existing timeout flake unrelated to this PR.)

Happy to see this land — the direction is right and the config-handling care really shows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants