fix(configure): patch CoDev Code's config in place, honor its env flags, validate keys via /v1/models - #265
Merged
Conversation
…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
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.
What broke
The hub's CoDev Code configuration no longer fits how the agent works. Investigated against
quickbeard/codev-codemain(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 itCoDev Code is a standalone product now: its TUI connects custom providers (
provider.<id>+ auth-store entry), its desktop app writestheme/keybinds/permissionsettings, users keep comments incodev.jsonc, and its ownConfig.updateGlobaledits the file surgically through jsonc-parser. The hub's writer replaced the whole file and carried onlymcpacross — and it runs on every gateway-key auto-refresh andcodevhub modelswitch, 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.)configureOpenCodeKindnow patches in place (patchOpenCodeConfig, samemodify/applyEditsaslib/codegraph.ts):$schemaseeded only when absent;compaction.auto/compaction.reservedset key-by-key (a user'sprunesurvives).provider.<id>replaced wholesale, so stale models and any inlineapiKeyan older hub wrote are gone; still keyless for CoDev Code.netgateblock lingers besideaigwand 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-levelmodelpin are removed. A user's own provider is never a candidate.readPreservedMcpis deleted — nothing needs carrying over any more.2. Wrong env flag for the agent's self-updater
runAgent("codev")setOPENCODE_DISABLE_AUTOUPDATE, but the fork renamed everyOPENCODE_*variable toCODEV_*(codev-code #41;Flag.CODEV_DISABLE_AUTOUPDATEinpackages/core/src/flag/flag.ts). The agent's updater was never disabled and racedcodevhub update. Both spellings are set now.3. Key validation could never fail
validateApiKeyprobed LiteLLM's/key/infoat 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:So the probe always said "valid": the launch-time refresh in
refresh.tsnever fired on an expired key, andSetupApp'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'sllmcheck reports the same URL.Verified against the real agent
Copied this machine's live
codev.jsonc(duplicatenetgate+aigwblocks, CodeGraphmcpentry) into a fresh HOME, added a comment, athemeand a custom provider, ran the new writer, thencodev models(codev-code 1.18.23-2) under that HOME:netgategone, comment / theme / custom provider /mcpintact,compaction{auto: true, reserved: 40000}.Docs
New
CoDev Code configsection inCLAUDE.mdrecording the three contracts (PATCH not rewrite, convergence, auth store) plus the env-flag and validation rules; the CodeGraph "config-rewrite preservation" paragraph and thefetchModelWindowsnote updated; READMEdoctorcopy updated.Tests
.jsonccomments, in-TUI providers, compaction siblings, existing$schema), legacy-block and pin removal, and the corrupt-file fallback.validateApiKeytests target/v1/modelsand pin the HTML-200 case.runtests assert both autoupdate flags forcodevand 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