feat: install the Codex plugin through the codex CLI - #51
Open
camjac251 wants to merge 2 commits into
Open
Conversation
Install removed only the version directory it was about to write, leaving any sibling from an earlier install in place. Codex resolves the active plugin by scanning that directory and taking the highest version it finds, so a directory left behind by a newer install keeps being served after a downgrade: install 0.5.0, downgrade to 0.4.3, and Codex still loads 0.5.0. Install now prunes stale sibling version directories, which is what Codex's own installer does after it stages a new version. Pruning runs after the new version is copied into place so a failed copy cannot empty the cache, and it skips names that are not valid version segments, since Codex would never activate those.
The installer hand-rolled Codex's plugin store: copy the bundled tree into plugins/cache/<marketplace>/<plugin>/<version>, then write the [plugins] config entry. That re-implements internals Codex already owns, and it skipped steps Codex performs itself. Most visibly it never ran the commands migration, so the plugin's commands/ directory produced nothing in Codex; it also copied non-atomically, so a failure could leave a half-written cache. Install now calls `codex plugin add` against the published marketplace, the same source the documentation and the in-app instructions name, so the entry written into the user's config.toml stays portable. The bundled-copy path remains as a fallback for when the codex CLI is missing or cannot install, which also keeps the install working offline, and the report records which model was used. Subagents still install as loose config files because Codex plugins cannot bundle them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The installer hand-rolled Codex's plugin store: copy the bundled tree into
plugins/cache/<marketplace>/<plugin>/<version>, then write the[plugins]config entry. That re-implements internals Codex already owns, and it skipped steps Codex performs itself.Install now calls the CLI:
The bundled-copy path stays as a fallback for a missing
codexCLI or a failed install, which also keeps the install working offline. The report records which model ran viainstall_model.What the hand-rolled copy was missing
migrate_plugin_commandsplugins/goalbuddy/commands/goalbuddy.mdproduced nothing in Codex. It is harness-neutral (readsgoal-execution.md, states the loop invariants), so migrating it gives Codex users an execution entry point, which matters because native/goalis gatedremove_old_plugin_versionsWhy the published marketplace rather than the npm package
A local directory is a valid marketplace source, and pointing at the npm package would have guaranteed the installed content matched the version being run. This uses
tolibear/goalbuddyanyway, because the entry is written into the user'sconfig.tomland it should be portable and match what the docs tell people to run. A path under an npx cache is machine-specific and disappears when that cache is cleared.The consequence is that a Codex install tracks the marketplace's default branch, the same way the Claude Code plugin does. That is one distribution model rather than two.
Notes
~/.codex/agents/*.toml. Codex plugins cannot bundle them: neither manifest format has anagentsfield, and agent roles are read only from config-layeragents/directories.enablePluginConfig()now runs only when the plugin is not already enabled, so the native path does not get itsconfig.tomlrewritten by our formatter.Test plan
npm run checkpasses (113 internal tests).install_model: "codex-cli"and the published marketplace source; the bundled copy is used when it cannot, with a warning, still producing a loadable cache, config, and agents.codex plugin add, so the native path is the default in tests and the fallback is exercised explicitly. That flushed out two pruning tests from fix: prune stale Codex plugin version directories on install #50 that had started passing through the native path where Codex prunes and our code never runs; they are now pointed at the fallback, the only place that code applies.