fix(codex): multi-line TOML args, and sync that can't leave a host CLI broken - #232
Merged
Merged
Conversation
Codex (toml_edit) and `aqe platform setup codex` write MCP `args` as multi-line arrays. Three readers accepted only single-line arrays, so: - rufloCodexMcpStatus saw args=null, reported the canonical `ak x ruflo-mcp` entry as the legacy launcher, and sync re-ran the migration on every invocation; - the AQE embedding TOML editor rejected the project .codex/config.toml as "unsupported AQE arguments encoding", leaving a permanent projection conflict after sync; - codexMcpTopology missed args for recursive-codex / legacy-ruflo tables, hiding duplicate-transport repairs. A shared string-array reader in codex-toml-safety.mjs now handles both forms; comments or non-string elements inside the array stay unsupported. `ak status` also reported an npm-installed host as healthy from its package.json alone. A launcher that fails `--version` (e.g. codex missing @openai/codex-darwin-arm64) now shows as installed but not executable with a reinstall fix, which also explains downstream `codex mcp` failures. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`ak sync`'s versions step upgraded @openai/codex 0.156.0 -> 0.156.1 about eight minutes after OpenAI published it. npm resolved the platform alias (@openai/codex-darwin-arm64 -> @openai/codex@0.156.1-darwin-arm64, published ~5 minutes after the main version), failed to install it, and exited 0: npm silently drops a failed optional dependency. heal.upgradePackage trusted the exit code, reported "upgraded", and left `codex` unable to start, which then broke every later `codex mcp` operation in sync. - installGlobalCli (npm-global-install.mjs): install, prove `bin --version`, and retry once with --prefer-online when the CLI cannot start. installHost and heal.upgradePackage (for host packages, via sync's hostUpgradeOptions) share it, so a broken upgrade is reported and usually repaired in place. - sync `hosts` step: also reinstalls an npm-owned host whose CLI cannot start (external installs untouched), and now runs before the Codex MCP and provider steps that shell out to the host CLIs. - status: the not-executable host row's fix is now `sync reinstalls <pkg>`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Problem
In a Codex-enabled project (reproduced in emailibrium on 4.0.0-alpha.53),
ak synckept failing with:ruflo→codex MCP: migration could not remove the ak-owned legacy registrationstill failing: [aqe-embedding] AQE embedding projection conflicts or missing registrations require reconciliationIt has two ak root causes. Neither needs an upstream fix.
1. Multi-line TOML
argsCodex (
codex mcp add, via toml_edit) andaqe platform setup codexwriteargsas a multi-line array. Three ak readers only accepted a single-line array:rufloCodexMcpStatusak x ruflo-mcpentry reported as the "legacy cwd-only launcher" → sync re-migrated every runaqeTomlEnvironment.codex/config.tomlrejected asunsupported AQE arguments encoding→ permanent projection conflictcodexMcpSections/codexMcpTopologyrecursive-codex/legacy-ruflotables → a real duplicateclaude-flow+rufloregistration stayed hidden2. Sync upgraded codex into a broken state and reported success
The migration's
codex mcp removefailed becausecodexitself could not start (Missing optional dependency @openai/codex-darwin-arm64). Evidence from the machine's npm cache and the registry:@openai/codex@0.156.1at 02:45:25Z and its platform versions (for example0.156.1-darwin-arm64, used as the optional-dependency alias target) 1.5–5 minutes later. The darwin-arm64 build came at 02:50:04Z.ak sync'sversionsstep upgraded codex at 02:53:07Z. npm fetched the main tarball, but the platform tarball was never cached;node_modules/@openaiwas left empty.heal.upgradePackagetrusted the exit code and reported "upgraded".ak statusthen showed✓ codex 0.156.1 (npm), read from package.json alone.Rerunning the same install and upgrade today (fresh prefix, ak's exact args) works, and so does reinstalling over an install with the platform directory removed. So this was a transient failure that ak made permanent and invisible.
Changes
codex-toml-safety.mjs: one shared string-array reader for single- and multi-line arrays. Comments or non-string elements inside the array are still unsupported.mcp.mjsandaqe-embedding-toml.mjsuse it.npm-global-install.mjsinstallGlobalCli: install, provebin --version, and retry once with--prefer-onlinewhen the CLI cannot start.installHostandheal.upgradePackage(for host packages, via sync'shostUpgradeOptions) share it. Non-host packages are unchanged.hostsstep: also reinstalls an npm-owned host whose CLI cannot start (external mise/native/brew installs untouched). It now runs before the Codex MCP and provider steps that shell out to host CLIs.hosts: an npm host that fails--versionshowsinstalled but not executable: <Error line>(fail for the primary host, warn otherwise), with fixsync reinstalls <pkg>.docs/TROUBLESHOOTING.md: row for the new status.Verification
--prefer-online, failure after retry, and no retry when healthy;upgradePackageverification; sync repairing a broken npm host while leaving healthy and external hosts alone; step ordering; the status row.pnpm run check: exit 0. Tests 4312 pass / 0 fail / 6 skipped; coverage 92.2% lines / 81.5% branches. Lint warnings identical tomain(71).ak sync --dry-run --no-upgradefrom this branch in emailibrium now plans[hosts] sync reinstalls @openai/codexand the backed-up duplicate-Ruflo repair. The repair runs after the hosts step.🤖 Generated with Claude Code