Skip to content

fix(configure): patch CoDev Code's config in place, honor its env flags, validate keys via /v1/models - #265

Merged
quickbeard merged 1 commit into
mainfrom
fix/codev-code-config-mechanism
Sep 10, 2026
Merged

quickbeard merged 1 commit into
mainfrom
fix/codev-code-config-mechanism

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

What broke

The hub's CoDev Code configuration no longer fits how the agent works. Investigated against quickbeard/codev-code main (packages/codev-gateway, packages/opencode/src/config, packages/desktop/src/main/gateway-sso) and the live gateway. Three mismatches, all fixed here.

1. The hub whole-file-replaced codev.json(c); the agent PATCHes it

CoDev Code is a standalone product now: its TUI connects custom providers (provider.<id> + auth-store entry), its desktop app writes theme / keybinds / permission settings, users keep comments in codev.jsonc, and its own Config.updateGlobal edits the file surgically through jsonc-parser. The hub's writer replaced the whole file and carried only mcp across — and it runs on every gateway-key auto-refresh and codevhub model switch, not just at install. Every one of those runs deleted the user's providers and settings. (This machine's agent auth store still holds keys for three in-TUI providers whose config blocks are gone.)

configureOpenCodeKind now patches in place (patchOpenCodeConfig, same modify/applyEdits as lib/codegraph.ts):

  • $schema seeded only when absent; compaction.auto / compaction.reserved set key-by-key (a user's prune survives).
  • provider.<id> replaced wholesale, so stale models and any inline apiKey an older hub wrote are gone; still keyless for CoDev Code.
  • Convergence is the hub's job: the agent's PATCH is a deep merge and cannot delete, so after the AIGW rename a legacy netgate block lingers beside aigw and the picker lists every model twice (codev-code #340 explicitly relies on the hub's next write to converge). Other CoDev provider ids and a CoDev-authored top-level model pin are removed. A user's own provider is never a candidate.
  • Everything else is byte-identical, comments included. Syntax errors or a non-object root still fall back to a fresh file; the backup taken first keeps the original.
  • readPreservedMcp is deleted — nothing needs carrying over any more.

2. Wrong env flag for the agent's self-updater

runAgent("codev") set OPENCODE_DISABLE_AUTOUPDATE, but the fork renamed every OPENCODE_* variable to CODEV_* (codev-code #41; Flag.CODEV_DISABLE_AUTOUPDATE in packages/core/src/flag/flag.ts). The agent's updater was never disabled and raced codevhub update. Both spellings are set now.

3. Key validation could never fail

validateApiKey probed LiteLLM's /key/info at the gateway root. That root is now fronted by a web app whose catch-all answers HTTP 200 + HTML to any bearer — verified against the live gateway with a bogus key:

/key/info   key=bogus  200 text/html
/v1/models  key=bogus  401 application/json

So the probe always said "valid": the launch-time refresh in refresh.ts never fired on an expired key, and SetupApp's "reuse existing key" offered dead keys. The gateway mints short-lived keys now (codev-code #340), which is exactly when this matters. Validation goes through /v1/models (authenticated by the key itself), and a 200 whose body isn't JSON is "can't tell" (throw), never "valid" — so the same failure can't recur behind another catch-all. doctor's llm check reports the same URL.

Verified against the real agent

Copied this machine's live codev.jsonc (duplicate netgate + aigw blocks, CodeGraph mcp entry) into a fresh HOME, added a comment, a theme and a custom provider, ran the new writer, then codev models (codev-code 1.18.23-2) under that HOME:

aigw/MiniMax/MiniMax-M3
aigw/zai-org/GLM-5.3-Flash
mycorp/corp/m

netgate gone, comment / theme / custom provider / mcp intact, compaction {auto: true, reserved: 40000}.

Docs

New CoDev Code config section in CLAUDE.md recording the three contracts (PATCH not rewrite, convergence, auth store) plus the env-flag and validation rules; the CodeGraph "config-rewrite preservation" paragraph and the fetchModelWindows note updated; README doctor copy updated.

Tests

  • Writer tests now assert preservation (settings, .jsonc comments, in-TUI providers, compaction siblings, existing $schema), legacy-block and pin removal, and the corrupt-file fallback.
  • validateApiKey tests target /v1/models and pin the HTML-200 case.
  • run tests assert both autoupdate flags for codev and neither for the other agents.

All checks pass: pnpm fix, pnpm typecheck, pnpm test (84 files, 1492 passed), pnpm build && node dist/index.js --version.

🤖 Generated with Claude Code

https://claude.ai/code/session_0178nPaQqSGVe7Y1fR2ovDTK

…gs, validate keys via /v1/models

The hub's CoDev Code configuration stopped fitting how the agent works.
Three mismatches with codev-code main (packages/codev-gateway, the
config layer, the desktop gateway controller), each fixed here:

1. The writer whole-file-replaced ~/.config/codev/codev.json(c), carrying
   only `mcp` across. CoDev Code is a standalone product now: its TUI
   connects custom providers, its desktop app writes theme/keybind/
   permission settings, users keep comments in codev.jsonc — and the hub
   rewrites this file on every gateway-key auto-refresh and model switch,
   not just at install. All of that was deleted on each run.
   `configureOpenCodeKind` now PATCHes the file through jsonc-parser the
   way the agent's own `Config.updateGlobal` does: `$schema` seeded only
   when absent, `compaction.auto`/`reserved` set key-by-key, the CoDev
   `provider.<id>` block replaced wholesale (stale models and any inline
   apiKey go), everything else byte-identical. The agent's PATCH cannot
   delete, so convergence after the AIGW rename is the hub's job: other
   CoDev provider ids (`netgate`, `aigateway`, …) and a CoDev-authored
   top-level `model` pin are removed; a user's own provider never is.
   Syntax errors or a non-object root still fall back to a fresh file,
   with the backup holding the original. `readPreservedMcp` is gone —
   nothing needs carrying over any more.

2. `runAgent("codev")` set OPENCODE_DISABLE_AUTOUPDATE, but the fork
   renamed every OPENCODE_* env var to CODEV_* (codev-code #41), so the
   agent's self-updater was never disabled and raced `codevhub update`.
   Both spellings are set now.

3. `validateApiKey` probed LiteLLM's /key/info at the gateway ROOT. That
   root is now fronted by a web app whose catch-all answers HTTP 200 +
   HTML to any bearer — verified with a bogus key — so the probe could
   never return false: the launch-time refresh never fired on an expired
   key and SetupApp's "reuse existing key" offered dead keys as valid.
   It now lists /v1/models (authenticated by the key itself, 401s
   properly) and treats a non-JSON 200 as "can't tell", never "valid".
   `doctor` reports the same URL.

Verified against the real agent: patching a copy of a live codev.jsonc
that carried duplicate netgate + aigw blocks, a comment, a theme, a
custom provider and the CodeGraph mcp entry, then running `codev models`
under that HOME, lists each aigw model once plus the custom provider —
with the comment and settings intact.

Tests: writer tests now assert preservation (settings, comments, in-TUI
providers, compaction siblings, $schema), legacy-block and pin removal,
and the corrupt-file fallback; validateApiKey tests target /v1/models
and pin the HTML-200 case; run tests assert both autoupdate flags.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178nPaQqSGVe7Y1fR2ovDTK
@quickbeard
quickbeard merged commit eaac664 into main Sep 10, 2026
2 of 4 checks passed
@quickbeard
quickbeard deleted the fix/codev-code-config-mechanism branch September 10, 2026 04:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant