Repository navigation
fix: preserve existing Codex settings during setup #138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -339,7 +339,7 @@ export async function _buildMergedCodexContent( | |
| } | ||
|
|
||
| const dottedEntry = new RegExp( | ||
| `^\\s*${mcpServersKey}\\s*\\.\\s*${codebaseContextKey}\\s*\\.`, | ||
| `^\\s*${mcpServersKey}\\s*\\.\\s*${codebaseContextKey}\\s*(?:\\.|=)`, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an existing Codex config has a multiline string such as Useful? React with 👍 / 👎.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new |
||
| 'm' | ||
| ); | ||
| if (dottedEntry.test(normalizedExisting)) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'; | ||
| import os from 'node:os'; | ||
| import path from 'node:path'; | ||
| import { describe, expect, it, vi } from 'vitest'; | ||
| import { handleInitCli } from '../src/cli-init.js'; | ||
|
|
||
| describe('Codex init with an existing saved config', () => { | ||
| it.each([ | ||
| { | ||
| name: 'bare dotted keys', | ||
| toml: 'mcp_servers.codebase-context = { command = "old", args = [] }\n' | ||
| }, | ||
| { | ||
| name: 'a double-quoted root key', | ||
| toml: '"mcp_servers".codebase-context = { command = "old", args = [] }\n' | ||
| }, | ||
| { | ||
| name: 'a double-quoted server key', | ||
| toml: 'mcp_servers."codebase-context" = { command = "old", args = [] }\n' | ||
| }, | ||
| { | ||
| name: 'double-quoted root and server keys', | ||
| toml: '"mcp_servers"."codebase-context" = { command = "old", args = [] }\n' | ||
| }, | ||
| { | ||
| name: 'single-quoted root and server keys', | ||
| toml: "'mcp_servers'.'codebase-context' = { command = \"old\", args = [] }\n" | ||
| } | ||
| ])('refuses $name without changing the saved file', async ({ toml }) => { | ||
| const projectRoot = await mkdtemp(path.join(os.tmpdir(), 'cbc-codex-init-')); | ||
| const configPath = path.join(projectRoot, '.codex', 'config.toml'); | ||
| const initialBytes = Buffer.from(toml, 'utf8'); | ||
| const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); | ||
| const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); | ||
| const previousExitCode = process.exitCode; | ||
|
|
||
| try { | ||
| await mkdir(path.dirname(configPath), { recursive: true }); | ||
| await writeFile(configPath, initialBytes); | ||
| process.exitCode = undefined; | ||
|
|
||
| await handleInitCli(['--client', 'codex', '--yes', '--root', projectRoot]); | ||
|
|
||
| const persistedBytes = await readFile(configPath); | ||
| expect({ exitCode: process.exitCode, persistedBytes }).toEqual({ | ||
| exitCode: 1, | ||
| persistedBytes: initialBytes | ||
| }); | ||
| expect(errorSpy).toHaveBeenCalledWith( | ||
| expect.stringContaining('already contains a different codebase-context configuration') | ||
| ); | ||
| } finally { | ||
| process.exitCode = previousExitCode; | ||
| errorSpy.mockRestore(); | ||
| logSpy.mockRestore(); | ||
| await rm(projectRoot, { recursive: true, force: true }); | ||
| } | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In interactive mode, answering no to
Apply MCP config?still letshandleInitCliprint the next steps and return successfully without callingwriteFile, so a successful setup run does not necessarily write a config. This sentence should distinguish a successful config application from a successful wizard exit rather than assuring users that the file was written.AGENTS.md reference: AGENTS.md:L112-L112
Useful? React with 👍 / 👎.