From d08c7f20c9e4a1dd70d5a4e7d02be8b49a134fd2 Mon Sep 17 00:00:00 2001 From: kevinwang5658 <20214115+kevinwang5658@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:08:23 +0000 Subject: [PATCH] fix: auto-fix test failures from Test all (MacOS) --- docs/resources/(resources)/codex.mdx | 5 ++--- src/resources/codex/codex.ts | 29 ++++++++++++---------------- test/codex/codex.test.ts | 6 +++--- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/docs/resources/(resources)/codex.mdx b/docs/resources/(resources)/codex.mdx index f1caa76e..b7499d61 100644 --- a/docs/resources/(resources)/codex.mdx +++ b/docs/resources/(resources)/codex.mdx @@ -3,7 +3,7 @@ title: codex description: A reference page for the codex resource --- -The codex resource installs the [Codex CLI](https://developers.openai.com/codex) — OpenAI's terminal-based coding agent — and manages its global configuration. It handles installation via the official installer script and gives you declarative control over `~/.codex/config.toml` settings and global MCP servers. +The codex resource installs the [Codex CLI](https://developers.openai.com/codex) — OpenAI's terminal-based coding agent — and manages its global configuration. It handles installation via OpenAI's official `@openai/codex` npm package and gives you declarative control over `~/.codex/config.toml` settings and global MCP servers. ## Parameters @@ -79,8 +79,7 @@ The codex resource installs the [Codex CLI](https://developers.openai.com/codex) ## Notes -- Codex is installed via the official installer (`curl -fsSL https://chatgpt.com/codex/install.sh | sh`) on both macOS and Linux. The binary is placed at `~/.local/bin/codex`. -- The installer adds `~/.local/bin` to your PATH. This entry remains after destroy — remove it manually if you no longer want it. +- Codex is installed via `npm install --global @openai/codex` on both macOS and Linux, matching OpenAI's officially published npm distribution. - The `config` parameter merges only the declared top-level keys of `~/.codex/config.toml`. Existing keys not in your Codify config (including `mcp_servers`) are left untouched. - MCP servers are stored under `[mcp_servers.]` in `~/.codex/config.toml`. Removing an MCP server from your config removes its table; other servers are untouched. - For per-project configuration (AGENTS.md, project-scoped settings and MCP servers), see [`codex-project`](/docs/resources/codex/codex-project). For the Codex desktop app, see [`codex-app`](/docs/resources/codex/codex-app). diff --git a/src/resources/codex/codex.ts b/src/resources/codex/codex.ts index 15868c10..2eb42ac7 100644 --- a/src/resources/codex/codex.ts +++ b/src/resources/codex/codex.ts @@ -4,6 +4,7 @@ import { ExampleConfig, Resource, ResourceSettings, + SpawnStatus, getPty, z, } from '@codifycli/plugin-core'; @@ -149,31 +150,25 @@ export class CodexResource extends Resource { } async refresh(): Promise | null> { - const codexBin = path.join(os.homedir(), '.local', 'bin', 'codex'); - try { - await fs.access(codexBin); - } catch { - return null; - } - - return {}; + const $ = getPty(); + const { status } = await $.spawnSafe('which codex'); + return status === SpawnStatus.SUCCESS ? {} : null; } async create(_plan: CreatePlan): Promise { const $ = getPty(); - await $.spawn( - 'bash -c "curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh"', - { interactive: true }, - ); - - // Ensure PATH is updated so subsequent lifecycle methods can call `codex` - const localBin = path.join(os.homedir(), '.local', 'bin'); - process.env['PATH'] = `${localBin}:${process.env['PATH'] ?? ''}`; + // Installed via npm (OpenAI's official @openai/codex package) rather than the + // curl | sh installer: the installer's version resolution hits api.github.com + // unauthenticated, which shared CI runner IPs frequently exhaust. + await $.spawn('npm install --global @openai/codex', { interactive: true }); } async destroy(_plan: DestroyPlan): Promise { - // Native uninstall: remove the binary and standalone release artifacts + const $ = getPty(); + await $.spawnSafe('npm uninstall --global @openai/codex', { interactive: true }); + + // Best-effort cleanup of artifacts left by the legacy curl | sh installer await fs.rm(path.join(os.homedir(), '.local', 'bin', 'codex'), { force: true }); await fs.rm(path.join(os.homedir(), '.codex', 'packages', 'standalone'), { recursive: true, force: true }); } diff --git a/test/codex/codex.test.ts b/test/codex/codex.test.ts index 504d72ef..5e80767a 100644 --- a/test/codex/codex.test.ts +++ b/test/codex/codex.test.ts @@ -11,15 +11,14 @@ describe('codex resource integration tests', async () => { const pluginPath = path.resolve('./src/index.ts'); it('Can install codex', { timeout: 300_000 }, async () => { - const codexBin = path.join(os.homedir(), '.local', 'bin', 'codex'); await PluginTester.fullTest( pluginPath, [{ type: 'codex' }], { skipUninstall: true, validateApply: async () => { - const exists = await fs.access(codexBin).then(() => true).catch(() => false); - expect(exists).toBe(true); + const { data } = await testSpawn('which codex'); + expect(data.trim().length).toBeGreaterThan(0); }, }, ); @@ -102,6 +101,7 @@ describe('codex resource integration tests', async () => { afterAll(async () => { // Best-effort cleanup in case tests left codex installed + await testSpawn('npm uninstall --global @openai/codex'); await testSpawn('rm -f ~/.local/bin/codex'); await testSpawn('rm -rf ~/.codex/packages/standalone'); }, 60_000);