feat(codex-bridge): hide 9Router combos in Codex, drop the config backup (beta.22)

Combos that come from 9Router, directly or through the gateway's 9router
provider, are no longer added to Codex's model list; the gateway's own combos
keep their plain names. The IDE no longer leaves a config.toml backup behind:
turning the setting off already restores the file byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HRDGW1LiKcDUZYUdKBoWYW
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-09 17:51:10 +03:00
1 parent b560950f82
commit 1e0f2f9aea
8 files changed
+33 -39

No files matched your search

+2 -21
View File
@@ -21,8 +21,7 @@ const PATHS: CodexLinkPaths = {
}
const BRIDGE_JSON = `${PATHS.bridgeHome}\\bridge.json`
const BACKUP = `${PATHS.codexConfig}.aiturk-yedek`
const STATUS_OK = { ok: true, surum: '2', ide_durum: 'tamam', ide_model: 7, ozet: true }
const STATUS_OK = { ok: true, surum: '3', ide_durum: 'tamam', ide_model: 7, ozet: true }
const USER_CONFIG = 'model = "gpt-6"\r\n\r\n[features]\r\nweb = true\r\n'
interface World {
@@ -73,12 +72,6 @@ function createWorld(patch: Partial<World> & { files?: Map<string, string> } = {
world.events.push(`write ${file}`)
world.files.set(file, text)
},
backupOnce: (source, target) => {
if (!world.files.has(target)) {
world.events.push(`backup ${target}`)
world.files.set(target, world.files.get(source) ?? '')
}
},
spawnBridge: (command, args, env) => {
world.events.push(`spawn ${command} ${JSON.stringify(args)} ${JSON.stringify(env)}`)
spawned = true
@@ -212,19 +205,17 @@ describe('applyCodexLink', () => {
hermesHome: PATHS.hermesHome
})
// bridge.json → start → verified answer → config.toml (backed up) → login item
// bridge.json → start → verified answer → config.toml → login item
expect(world.events).toEqual([
`write ${BRIDGE_JSON}`,
`spawn ${PATHS.pythonw} ${JSON.stringify(args)} ${JSON.stringify(env)}`,
'status ok',
`backup ${BACKUP}`,
`write ${PATHS.codexConfig}`,
'autostart set'
])
expect(JSON.parse(world.files.get(BRIDGE_JSON) ?? '')).toEqual(codexBridgeConfig())
expect(world.files.get(PATHS.codexConfig)).toBe(`${CODEX_LINK_LINE}\r\n${USER_CONFIG}`)
expect(world.files.get(BACKUP)).toBe(USER_CONFIG)
expect(world.autostart).toBe(
`"${PATHS.pythonw}" "${PATHS.bridgeScript}" --home "${PATHS.bridgeHome}" --hermes-home "${PATHS.hermesHome}"`
)
@@ -238,7 +229,6 @@ describe('applyCodexLink', () => {
expect(status).toMatchObject({ enabled: true, bridgeRunning: false, lastError: 'bridge-start-failed' })
expect(spawns(world)).toHaveLength(1)
expect(world.files.get(PATHS.codexConfig)).toBe(USER_CONFIG)
expect(world.files.has(BACKUP)).toBe(false)
expect(world.autostart).toBeNull()
expect(writes(world)).toEqual([`write ${BRIDGE_JSON}`])
// The start poll is bounded by its one budget.
@@ -289,15 +279,6 @@ describe('applyCodexLink', () => {
expect(spawns(world)).toEqual([])
})
it('never overwrites the first backup', async () => {
const { link, world } = createWorld({ listening: true })
world.files.set(BACKUP, 'the original original')
await link.apply()
expect(world.files.get(BACKUP)).toBe('the original original')
})
it('falls back to python.exe when pythonw.exe is missing', async () => {
const { link, world } = createWorld()
world.files.delete(PATHS.pythonw)