Skip to content

feat(generate): add Codex editor support#72

Merged
rafaelandrade merged 4 commits into
mainfrom
rafaelandrade/-/generate-codex-editor
Jul 14, 2026
Merged

feat(generate): add Codex editor support#72
rafaelandrade merged 4 commits into
mainfrom
rafaelandrade/-/generate-codex-editor

Conversation

@rafaelandrade

@rafaelandrade rafaelandrade commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

O que

Adiciona um quinto editor ao hub generate: Codex (OpenAI CLI), no mesmo padrão de cursor/claude-code/kiro/opencode.

Por quê

O Codex CLI lê AGENTS.md nativamente, mas o hub não tinha generator dedicado para ele — cada workspace precisava traduzir o .mcp.json manualmente pro formato TOML do Codex (.codex/config.toml, [mcp_servers.<id>], snake_case, sem expansão de ${ENV}).

Mudanças

packages/cli/src/commands/generate.ts:

  • generateCodex(config, hubDir) — gera AGENTS.md (reaproveita buildOrchestratorRule + buildSkillsSection, mesma lógica do Claude Code) e .codex/config.toml com os MCP servers de config.mcps
  • buildCodexMcpBlock — traduz cada MCPConfig pro formato TOML do Codex:
    • url[mcp_servers.<id>] com url
    • imagecommand = 'docker' + args
    • packagecommand = 'npx' + args
    • ${env:VAR} no envenv_vars = [...] (Codex não expande ${}; a var do host é encaminhada por nome)
    • MCP sem url/image/package → pulado com warning (em vez de crashar — foi assim que encontrei o bug abaixo)
  • Suporte a proxy MCPs (upstreams) via buildProxyUpstreams, mesmo padrão dos outros editores
  • Registrado codex: { name: "Codex", generate: generateCodex } no mapa generators
  • .codex/rules/persona.md adicionado à seção de persona do .gitignore gerado

Bug encontrado durante o teste manual

Rodei hub generate -e codex contra o hub.config.ts real do arvore-hub (não só testes unitários) e o generator crashava: o MCP bee usa { command: "bee", args: [...] }, campos que não existem em MCPConfig (só package/url/image). Isso já quebrava silenciosamente nos outros generators (gerava args: ["-y", undefined]); no Codex eu fiz falhar de forma explícita e recuperável — loga um warning e pula o MCP, em vez de crashar o generate inteiro.

Como testei

  • pnpm build (tsup) — build OK
  • pnpm lint (eslint) — limpo
  • pnpm test (vitest) — 22/22 passando
  • Teste manual end-to-end: build local copiado para node_modules/@arvoretech/hub/dist do workspace arvore-hub (que tem os 20 MCPs reais, incluindo proxy e o bee quebrado), rodei hub generate -e codex, validei o .codex/config.toml resultante com tomllib.load (Python) — 13/14 servers traduzidos corretamente, bee pulado com warning claro

Summary by CodeRabbit

  • New Features
    • Added Codex as a supported editor option for the hub generate command.
    • Generates Codex configuration for supported MCP servers, including URL-, Docker-, and package-based setups.
    • Automatically handles approved environment variables in Codex configuration.
    • Adds Codex persona rule files to managed ignore settings.

- New generateCodex(): writes AGENTS.md (shared orchestrator+skills logic)
  and .codex/config.toml with MCP servers translated to Codex's TOML format
- Codex does not expand ${env:VAR} inside [mcp_servers.<id>.env] (unlike
  Claude/Cursor); host env vars are forwarded via env_vars instead
- Register 'codex' in the generators map (hub generate -e codex)
- Gracefully skip MCPs with no url/image/package instead of crashing
  (caught via manual testing against a real hub.config.ts)
@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rhm-website Ready Ready Preview, Comment Jul 14, 2026 12:43am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@rafaelandrade, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e31bd432-3094-4a34-a429-9f5651f6cdb8

📥 Commits

Reviewing files that changed from the base of the PR and between 594a9c7 and becdf41.

📒 Files selected for processing (4)
  • packages/cli/src/commands/codex-config.test.ts
  • packages/cli/src/commands/codex-config.ts
  • packages/cli/src/commands/generate.ts
  • packages/cli/src/core/hub-config.ts
📝 Walkthrough

Walkthrough

The hub generate command adds a Codex generator that writes .codex/config.toml, handles MCP environment placeholders, updates AGENTS.md, and ignores the Codex persona file.

Changes

Codex generator

Layer / File(s) Summary
Codex configuration generation
packages/cli/src/commands/generate.ts
Adds TOML serialization, Codex MCP configuration for URL, Docker, and npx sources, environment forwarding, and updates to .codex/config.toml, AGENTS.md, and managed .gitignore content.
Codex CLI registration
packages/cli/src/commands/generate.ts
Registers codex in the shared generator map, lists it in --editor help, and ignores .codex/rules/persona.md.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HubCLI
  participant generateCodex
  participant ProjectFiles
  HubCLI->>generateCodex: invoke Codex generation
  generateCodex->>ProjectFiles: write .codex/config.toml
  generateCodex->>ProjectFiles: update AGENTS.md
  generateCodex->>ProjectFiles: refresh managed .gitignore
Loading

Suggested reviewers: ricardoraposo, joao208

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding Codex support to the generate command.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rafaelandrade/-/generate-codex-editor

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/cli/src/commands/generate.ts (1)

2324-2340: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Docker branch re-implements placeholder logic; reuse splitEnvForCodex.

Lines 2326-2333 re-run ENV_PLACEHOLDER independently to decide -e KEY vs -e KEY=value, duplicating (and inheriting the same cross-name gap as) splitEnvForCodex. Deriving the docker -e flags from the already-computed forwarded/literal sets keeps the two paths consistent.

♻️ Reuse split results for docker -e flags
   if (mcp.image) {
     const args = ["run", "-i", "--rm"];
-    for (const [key, value] of Object.entries(mcp.env ?? {})) {
-      const match = ENV_PLACEHOLDER.exec(value);
-      if (match && match[1] === key) {
-        args.push("-e", key);
-      } else {
-        args.push("-e", `${key}=${value}`);
-      }
-    }
+    for (const key of forwarded) {
+      args.push("-e", key);
+    }
+    for (const [key, value] of Object.entries(literal)) {
+      args.push("-e", `${key}=${value}`);
+    }
     args.push(mcp.image);
     lines.push(`command = 'docker'`, `args = ${tomlArray(args)}`);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/commands/generate.ts` around lines 2324 - 2340, Update the
Docker branch in the MCP command generation flow to derive its `-e` arguments
from the existing `forwarded` and `literal` results produced by
`splitEnvForCodex`, rather than re-running `ENV_PLACEHOLDER` over `mcp.env`.
Preserve `-e KEY` for forwarded variables and `-e KEY=value` for literal
variables so Docker and Codex use consistent environment classification.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/src/commands/generate.ts`:
- Around line 2289-2312: Update splitEnvForCodex to detect any ${env:VAR}
placeholder, including lowercase names and placeholders whose name differs from
the target key, before classifying entries as literal. Warn or reject those
unsupported placeholders instead of writing them into the Codex env map
literally, while preserving forwarding for valid matching placeholders.
- Around line 2317-2320: Update the URL branch in the MCP serialization logic to
emit the configured bearer-token environment variable before returning. Ensure
URL-based MCPs preserve their authentication configuration while retaining the
existing URL output and return behavior.

---

Nitpick comments:
In `@packages/cli/src/commands/generate.ts`:
- Around line 2324-2340: Update the Docker branch in the MCP command generation
flow to derive its `-e` arguments from the existing `forwarded` and `literal`
results produced by `splitEnvForCodex`, rather than re-running `ENV_PLACEHOLDER`
over `mcp.env`. Preserve `-e KEY` for forwarded variables and `-e KEY=value` for
literal variables so Docker and Codex use consistent environment classification.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 949ee15f-7036-4a47-b811-d8618c09264d

📥 Commits

Reviewing files that changed from the base of the PR and between eb1cfb1 and 594a9c7.

📒 Files selected for processing (1)
  • packages/cli/src/commands/generate.ts

Comment thread packages/cli/src/commands/generate.ts Outdated
Comment thread packages/cli/src/commands/generate.ts Outdated
Comment on lines +2317 to +2320
if (mcp.url) {
lines.push(`url = ${tomlString(mcp.url)}`);
return lines.join("\n");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Codex CLI config.toml mcp_servers url streamable http bearer_token_env_var

💡 Result:

In the Codex CLI, support for bearer_token (as a plain-text string) in config.toml has been deprecated and removed in favor of bearer_token_env_var [1][2]. The runtime now rejects the bearer_token field to prevent storing sensitive secrets in clear text on disk [3][4][2]. For streamable HTTP MCP servers, you must use bearer_token_env_var to specify an environment variable name from which the CLI will securely read the token at runtime [5][6]. Configuration Example: [mcp_servers.my-server] url = "https://mcp.example.com/mcp" bearer_token_env_var = "MY_SECRET_TOKEN_ENV_VAR" Key details: - Mechanism: When configured, the CLI reads the value from the specified environment variable and sends it as an Authorization: Bearer <token> header [3][7]. - CLI Usage: When adding a server via the CLI, use the --bearer-token-env-var flag [3][8]: codex mcp add my-server --url https://mcp.example.com --bearer-token-env-var MY_SECRET_TOKEN_ENV_VAR - Troubleshooting: If you are encountering errors, ensure you are not using the bearer_token field in your config.toml, as it is unsupported and will trigger validation errors, even if it appears in some legacy documentation or generated schemas [1][2]. Use mcp_servers (snake_case) for the configuration table [7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the generator and any MCP config/schema definitions
git ls-files | rg '(^|/)(generate|mcp|config).*\.(ts|js|json|md)$|config\.toml|mcp_servers'

# Inspect the relevant area around the cited lines
sed -n '2285,2345p' packages/cli/src/commands/generate.ts

# Search for URL/bearer/env handling in the CLI source
rg -n "bearer_token_env_var|bearerTokenEnvVar|mcp\.env|mcp_servers|url =" packages/cli/src -g '!**/dist/**' -g '!**/build/**'

# Search for schema/docs mentions that might clarify intended behavior
rg -n "bearer_token_env_var|streamable http|mcp_servers|Authorization: Bearer|env" packages/cli -g '!**/dist/**' -g '!**/build/**' -g '!**/node_modules/**'

Repository: arvoreeducacao/rhm

Length of output: 21442


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the exact implementation around the URL branch and any preceding env handling
python3 - <<'PY'
from pathlib import Path
p = Path('packages/cli/src/commands/generate.ts')
text = p.read_text()
for start in [2250, 2290, 2310, 2330]:
    lines = text.splitlines()
    print(f"\n--- {start} ---")
    for i in range(start-1, min(len(lines), start+40)):
        print(f"{i+1}: {lines[i]}")
PY

# Look for the MCP config type/shape if declared in this repo
rg -n "type .*MCP|interface .*MCP|bearer_token_env_var|env:" packages/cli/src packages/cli -g '!**/dist/**' -g '!**/build/**' -g '!**/node_modules/**'

# Find any docs/examples for url-based MCPs
rg -n "mcp_servers.*url|url = \".*mcp|bearer_token_env_var" . -g '!**/dist/**' -g '!**/build/**' -g '!**/node_modules/**'

Repository: arvoreeducacao/rhm

Length of output: 13806


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the MCP config type and any docs/examples around URL-based MCPs
sed -n '1,120p' packages/cli/src/core/hub-config.ts

# Read the part of generate.ts that builds Codex MCP blocks for comparison with other targets
sed -n '2380,2415p' packages/cli/src/commands/generate.ts

# Search for Codex MCP schema references in docs or examples
rg -n "bearer_token_env_var|env_vars|mcp_servers\\.<id>|mcp_servers\\.|streamable http|streamable-http|Authorization: Bearer|MCPConfig" packages/cli website -g '!**/dist/**' -g '!**/build/**' -g '!**/node_modules/**'

Repository: arvoreeducacao/rhm

Length of output: 9481


Emit bearer_token_env_var for URL MCPs. The url branch returns before writing auth config, so streamable HTTP MCPs lose their bearer-token env and won’t authenticate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/commands/generate.ts` around lines 2317 - 2320, Update the
URL branch in the MCP serialization logic to emit the configured bearer-token
environment variable before returning. Ensure URL-based MCPs preserve their
authentication configuration while retaining the existing URL output and return
behavior.

…ate-codex-editor

# Conflicts:
#	packages/cli/src/commands/generate.ts
Addresses CodeRabbit review on PR #72:
- splitEnvForCodex now detects any ${env:...} placeholder (including
  lowercase and name-mismatched) and warns instead of writing a literal
  that Codex won't expand
- url MCPs with auth emit a warning (Codex needs bearer_token_env_var,
  which the hub schema has no source for) instead of silently dropping it
- buildCodexMcpBlock returns { block, warnings }; caller logs warnings
- export both functions and add generate.test.ts (14 unit tests)
The unit tests imported generate.ts, which imports @arvoretech/hub-core
(a workspace dep only present once built). CI runs test:cov before the
build step, so Vite could not resolve the import and the suite failed.

Move the pure helpers (tomlString, tomlArray, splitEnvForCodex,
buildCodexMcpBlock) into commands/codex-config.ts with no heavy deps;
generate.ts imports from there and tests target the module directly.
@rafaelandrade
rafaelandrade merged commit e2888ed into main Jul 14, 2026
6 checks passed
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.

2 participants