Skip to content

feat(codex): add Codex support for the CLI and the ChatGPT desktop app - #54

Open
luisiul359 wants to merge 3 commits into
mainfrom
codex
Open

feat(codex): add Codex support for the CLI and the ChatGPT desktop app#54
luisiul359 wants to merge 3 commits into
mainfrom
codex

Conversation

@luisiul359

Copy link
Copy Markdown
Contributor

This PR is for adding Codex as a supported harness, for the CLI and for Codex in the ChatGPT desktop app (macOS), distributed as a plugin.

What was happening

Codex was listed under "other AI assistants (best effort)" in the README and had no install path, no skill doc, and no manifest. Users on Codex got no conventions at all — including the confirm-before-destructive rule.

What was done

New: codex/ plugin + .agents/plugins/marketplace.json. The repo doubles as a Codex marketplace; source.path resolves relative to the marketplace root (the repo root), so the entry is ./codex.

Codex is three surfaces over one ~/.codex/config.toml — CLI, ChatGPT desktop app, IDE extension. The first two take plugins, so a CLI install is a desktop-app install too; there is no separate macOS-app setup. The IDE extension has no plugin support at all, so it gets a skill-as-a-file path instead. Codex discovers skills at .agents/skills/<name>/SKILL.md in repo, user, and admin scope.

Requires Codex 0.147.0 or newer (codex plugin and skill frontmatter landed there), stated in every Codex-facing install doc.

codex/skills/outsystems/SKILL.md is rebuilt from the current lockstepped base, not forked — its shared sections are byte-identical with cursor/skills/outsystems/SKILL.md. Only ## First use / setup and ## Authenticating diverge, per the setup-flow exception.

Plan gating runs the other way from Cursor. Codex needs no paid plan — CLI plugin browser, codex plugin, and codex mcp all work on Free, Go, Plus, Pro, and API-key sign-in. But a managed ChatGPT workspace (Business/Enterprise/Edu) can block the install four ways via requirements.toml: marketplaces.restrict_to_allowed_sources, features.plugins, an mcp_servers allowlist matching name and URL, and workspace plugin controls. All four fail silently — the command reports success and nothing appears — so that's called out in the README, codex/README.md, the troubleshooting table, and the skill itself.

Docs threaded through: README.md (two install sections, three troubleshooting rows, reset + logs), CLAUDE.md (three harness rows, five traps, six-doc lockstep, five-manifest lockstep), CONTRIBUTING.md (structure, prerequisites, verification steps, versioning), .github/pull_request_template.md, cursor/README.md, root SKILL.md.

Test Steps

Verified on Codex CLI 0.148.0, not just read:

  1. codex plugin marketplace add .codex plugin list resolves outsystems@outsystems to <repo>/codex from .agents/plugins/marketplace.json. (Codex would also accept .claude-plugin/marketplace.json as a legacy index; it takes the .agents one here.)
  2. codex plugin add outsystems@outsystemsinstalled, enabled, 0.17.0.
  3. codex exec in a fresh session confirms the skill is offered, resolved from ~/.codex/plugins/cache/outsystems/outsystems/0.17.0/skills/outsystems/SKILL.md.
  4. Both Codex validators pass: validate_plugin.py codex and quick_validate.py codex/skills/outsystems.
  5. codex/mcp.toml parses as TOML with mcp_servers.outsystems present.
  6. Skill-discovery scopes proven empirically by planting probe skills and asking Codex which it could see: $REPO_ROOT/.agents/skills/, ~/.agents/skills/, and ~/.codex/skills/ all resolved.
  7. Local install removed afterwards (codex plugin remove, codex plugin marketplace remove).

Lockstep grep, per CLAUDE.md — a phrase from the lockstepped text and one from the setup clause:

$ PHRASE="Confirm before tenant-state mutations"   -> 1 1 1 1 1 1  (6/6)
$ PHRASE="Which OutSystems tenant should I connect to" -> 1 1 1 1 1 0  (5/6, root SKILL.md at 0 — no setup section)

Harness table accounting (every row):

  • Codex CLI — verified end to end, above.
  • Codex in the ChatGPT desktop app — recorded gap: not launched. It reads the same ~/.codex/config.toml and the same marketplace/plugin state the CLI writes (confirmed present in that file), so the mechanism is verified even though the UI is not.
  • Codex IDE extension — recorded gap: skill-file path verified via the .agents/skills probe, extension UI not exercised.
  • Claude Code, Claude Desktop, Kiro, Copilot (VS Code / CLI / Visual Studio), Cursor App, Cursor CLI — not applicable: no behavioral skill content changed for them. Root SKILL.md gains one clause naming Codex CLI among browser-callback clients; the other four skill docs are untouched.
  • M365 Copilot — not applicable, no custom MCP servers.
  • Other assistants — Codex removed from the best-effort list, since it now has a real path.

Checklist

  • every supported harness accounted for, each one verified, not applicable with the reason, or a recorded gap with a follow-up (every row of the CLAUDE.md harness table)
  • no internal references leaked (stage hostnames, internal Jira projects, team jargon)
  • if skill content or behavior changed: kept in sync across all six docs — skills/outsystems/SKILL.md, kiro/outsystems/steering/skill.md, copilot/skill.md, cursor/skills/outsystems/SKILL.md, codex/skills/outsystems/SKILL.md, and root SKILL.md — plus kiro/outsystems/POWER.md where its ## Conventions carries the same rules
  • if skill content changed: lockstep grep run and the counts stated in this PR (see CLAUDE.md)
  • if releasing: version bumped in all five manifests (.claude-plugin/plugin.json, .claude-plugin/marketplace.json, cursor/.cursor-plugin/plugin.json, .cursor-plugin/marketplace.json, codex/.codex-plugin/plugin.json)

Note for reviewers

An earlier draft of this work carried an Authorization server issuer mismatch known-gap section and an mcp-remote bridge fallback for Codex. That gap has since been fixed and validated server-side, so none of it is in this PR. The mcp-remote content still in README.md is the unrelated Claude Desktop local-proxy fallback and is untouched.

Two pre-existing items surfaced while working, deliberately left alone:

  • skills/outsystems/SKILL.md phrases the callback-port exception as "One exception, at most once per session" where the other five say "One exception" — pre-existing drift in a host-specific Authenticating section. CLAUDE.md documents only the "lazy sign-in" drift. Happy to reconcile or record it in a follow-up.
  • README.md's Claude Desktop fallback uses an unpinned mcp-remote, which differs from the pin-the-version advice elsewhere.

Ships the OutSystems plugin for Codex, distributed through a repo
marketplace at .agents/plugins/marketplace.json whose source.path
resolves relative to the repo root.

Codex is three surfaces over one ~/.codex/config.toml: the CLI, Codex in
the ChatGPT desktop app, and the IDE extension. The first two take
plugins, so installing from the CLI installs for the desktop app too.
The IDE extension has no plugin support at all, so it gets a
skill-as-a-file path instead - Codex discovers skills at
.agents/skills/<name>/SKILL.md in repo, user, and admin scope, all
verified on Codex CLI 0.148.0. Requires Codex 0.147.0 or newer.

codex/skills/outsystems/SKILL.md is rebuilt from the current lockstepped
base rather than forked, so its shared sections are byte-identical with
cursor/skills/outsystems/SKILL.md; only First use / setup and
Authenticating diverge, per the setup-flow exception.

Plan gating goes the other way from Cursor here: Codex needs no paid
plan, but a managed ChatGPT workspace can block the install four ways
through requirements.toml, and all four fail silently.
@luisiul359
luisiul359 requested a review from a team as a code owner August 25, 2026 22:41
`codex mcp login` run from inside a Codex session reports
"Successfully logged in" and stores nothing. The OAuth flow is network
plus a loopback callback so the browser sign-in genuinely succeeds, but
persisting the token needs a write to ~/.codex/, which is outside the
sandbox Codex applies to commands it runs. The write is denied with
"Operation not permitted" and the command does not surface it. The user
finds out a session later, as "requires OAuth reauthentication" and
"MCP startup incomplete (failed: outsystems)".

`codex mcp add` hits the same denial but fails loudly, with a non-zero
exit and an explicit "failed to persist config" error, so it is not the
trap.

Every Codex recipe now hands the sign-in to the user to run in their own
terminal, and verifies with the `Auth` column of `codex mcp list` rather
than `Status` - `Status: enabled` only means the server is registered,
while `Auth: Not logged in` means no token was stored. Reporting setup
complete on `enabled` alone is what masked this.
@luisiul359 luisiul359 added the do not merge This pull request should not be merged even if checks pass label Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge This pull request should not be merged even if checks pass

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant