Repository navigation
feat(appearance): presets you can save, share and import - #668
Open
Adam-Dalloul wants to merge 1 commit into
Open
Adam-Dalloul wants to merge 1 commit into
Adam-Dalloul wants to merge 1 commit into
Conversation
Route the surfaces that were still hard-coded through theme tokens (message bubbles, the composer box, the status bar, the code font in messages, message text size and density), give code blocks a per-mode Shiki theme, and add a Presets section to Appearance: seven bundled looks, density and text knobs, and JSON import/export. A preset is one strictly validated document of tokens, font ids and code theme ids, with a schema version and a size cap. It cannot carry CSS or script; custom CSS stays a local escape hatch and is never exported. The pre-paint script applies the new tokens like the existing ones, so a preset paints before first paint, and the transcript only re-renders when the code theme itself changes. Every bundled preset passes a WCAG AA contrast check on its text and surface pairs in both modes, measured against globals.css.
xyalter
pushed a commit
to lesscodex/codeg
that referenced
this pull request
Oct 31, 2026
…spacering-net#668) ## Result When a thread continues on another provider, the client now shows what went wrong instead of the raw provider JSON: > The current provider can't read this thread's earlier reasoning, which another provider or account encrypted. This happens after the provider changes in a thread. Switch back to the previous provider or start a new thread. Before, Air showed the whole gateway error body: `{"error":{"message":"Provider returned error","code":400,"metadata":{"raw":"{\n \"error\": {...\"code\": \"invalid_encrypted_content\"...`. ## Cause Codex sends requests with `store: false` and resends the encrypted reasoning of earlier turns with every request. Only the provider (and account) that encrypted it can read it. After `providers/set` moves a thread to another route, the new route rejects the history with `invalid_encrypted_content`, and a retry fails the same way. This is Codex behavior, not an adapter bug: `codex exec resume <id> -c model_provider=<other>` sends the other provider's encrypted reasoning too. Codex has no option to drop it, so the adapter only makes the error readable and does not rewrite the history. ## Changes - `readableServiceErrorMessage` recognizes `invalid_encrypted_content` in three forms: the plain provider error `{error: {code}}`, the Codex service envelope `{type: "error", status, error}`, and a gateway error that carries it in `metadata.provider_error_code` or in the JSON of `metadata.raw`. - Other error text stays unchanged. - The function is already used for every path a provider error reaches the client, so ACP v1 (agent message and Air typed failure) and ACP v2 (agent message and idle error) all get the message. ## Verification - New unit tests in `ServiceErrorMessage.test.ts`, and snapshot tests for ACP v1 (legacy text and typed failure) and ACP v2. All 7 fail without the change. - `npm run typecheck` passes. `npm test`: 1877 passed, 36 skipped. - End to end with real Codex and two local OpenAI-compatible gateways on ACP v1 and v2: two prompts on gateway A, `providers/set` to gateway B, which returns the gateway error above; the client gets the readable message.
xyalter
pushed a commit
to lesscodex/codeg
that referenced
this pull request
Oct 31, 2026
🤖 I have created a release *beep* *boop* --- ## [2.3.0](agentclientprotocol/codex-acp@v2.2.2...v2.3.0) (2026-10-26) ### Features * add ACP v2 support again ([spacering-net#620](agentclientprotocol/codex-acp#620)) ([9e1690f](agentclientprotocol/codex-acp@9e1690f)) * mark session list rows of worktrees Codex made (agentWorktree) ([spacering-net#631](agentclientprotocol/codex-acp#631)) ([aa02d43](agentclientprotocol/codex-acp@aa02d43)) * narrow models to what the providers/set gateway lists ([spacering-net#627](agentclientprotocol/codex-acp#627)) ([3f555f9](agentclientprotocol/codex-acp@3f555f9)) * report the model of each native subagent session ([spacering-net#678](agentclientprotocol/codex-acp#678)) ([51005a6](agentclientprotocol/codex-acp@51005a6)) * return initial ACP v2 session commands ([spacering-net#652](agentclientprotocol/codex-acp#652)) ([5e9b7c5](agentclientprotocol/codex-acp@5e9b7c5)) * support AIR sessionIndex extension ([spacering-net#590](agentclientprotocol/codex-acp#590)) v2 ([spacering-net#622](agentclientprotocol/codex-acp#622)) ([2fd758c](agentclientprotocol/codex-acp@2fd758c)) * support append-mode ACP system prompts ([spacering-net#653](agentclientprotocol/codex-acp#653)) ([5993a12](agentclientprotocol/codex-acp@5993a12)) ### Bug Fixes * disable Codex's Visualize skill, whose output ACP clients show as raw text ([spacering-net#667](agentclientprotocol/codex-acp#667)) ([0ba94f5](agentclientprotocol/codex-acp@0ba94f5)) * display the selected wire provider as JetBrains Air Gateway ([spacering-net#589](agentclientprotocol/codex-acp#589)) ([cc54abf](agentclientprotocol/codex-acp@cc54abf)) * explain Codex config load errors caused by a deleted working directory ([spacering-net#626](agentclientprotocol/codex-acp#626)) ([a636804](agentclientprotocol/codex-acp@a636804)) * explain invalid_encrypted_content errors after a provider change ([spacering-net#668](agentclientprotocol/codex-acp#668)) ([a77829f](agentclientprotocol/codex-acp@a77829f)) * hold a fork back from the session list until its session/fork response is out ([spacering-net#642](agentclientprotocol/codex-acp#642)) ([59974c7](agentclientprotocol/codex-acp@59974c7)) * include subagent edits in the agent file-change report ([spacering-net#632](agentclientprotocol/codex-acp#632)) ([7d07123](agentclientprotocol/codex-acp@7d07123)) * leave codex exec runs out of the session list without sessionIndex ([spacering-net#639](agentclientprotocol/codex-acp#639)) ([df75d2b](agentclientprotocol/codex-acp@df75d2b)) * migrate to ACP SDK 2.0 ([spacering-net#649](agentclientprotocol/codex-acp#649)) ([c8fd166](agentclientprotocol/codex-acp@c8fd166)) * publish the commands when the skills change ([spacering-net#643](agentclientprotocol/codex-acp#643)) ([a62b568](agentclientprotocol/codex-acp@a62b568)) * report structured ACP v2 failures ([spacering-net#651](agentclientprotocol/codex-acp#651)) ([5377bfe](agentclientprotocol/codex-acp@5377bfe)) * show a Codex subagent's follow-up turn in a new subagent session ([spacering-net#634](agentclientprotocol/codex-acp#634)) ([7c761c7](agentclientprotocol/codex-acp@7c761c7)) * synchronize ACP v2 foreground state ([spacering-net#650](agentclientprotocol/codex-acp#650)) ([986955a](agentclientprotocol/codex-acp@986955a)) * update codex to 0.164.0 ([spacering-net#666](agentclientprotocol/codex-acp#666)) ([e227c0e](agentclientprotocol/codex-acp@e227c0e)) * wait for the compact turn to finish ([spacering-net#654](agentclientprotocol/codex-acp#654)) ([ced4c34](agentclientprotocol/codex-acp@ced4c34)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: acp-release-bot[bot] <246668977+acp-release-bot[bot]@users.noreply.github.com>
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.
This lets someone make codeg look like a different app in one click, and hand that look to someone else as a file.
What it adds
Settings > Appearance gets a Presets section: seven bundled looks (the stock one, a warm terminal, a monochrome ink look, a dense IDE, high contrast, a midnight chat client and a warm paper reading surface), a code colour picker per mode (any of Shiki's bundled themes), a density knob, a message text size, and Import / Export. Export writes the current look, including your own token edits, as
<id>.codeg-preset.json. Import validates the file, previews what it changes, then applies it, or lists every problem next to the field it is in.To make that possible, the surfaces that were still hard-coded now read tokens: message bubbles (user and assistant background, text, hairline, radius, padding), the composer box, the status bar, the code font in messages (
--font-mono), message text size and density (--spacing). Their defaults point back at the shadcn tokens, so nothing changes until a preset or the Custom Style editor sets them, and the pre-paint script applies them the way it applies--primarytoday, so there is no flash on launch. Switching presets is CSS variable writes; the transcript only re-renders when the Shiki theme itself changes, and there is a test for that.The format
A preset is one JSON document with
schemaVersion: 1: an id and name, a base palette (one of the twelve), light and dark token overrides (the 31 shadcn colours plus the surface tokens above), shape (radius, bubble and composer radii), density, typography (font ids from the bundled and system list, message size and line height) and code theme ids. Validation is strict: unknown keys anywhere are errors, every value is syntax and range checked, and the file has a 32 KB cap. A newer schema version is refused, an older one migrates forward.Boundary
Tokens only. A preset cannot carry CSS or script, so importing a stranger's file can change colours, fonts and spacing and nothing else. Custom CSS stays what it is, a local per-device escape hatch, and is never written into a preset. All seven bundled presets pass a WCAG AA contrast check on every text and surface pair in both modes; that check runs in the test suite against the real globals.css.
Out of scope: moving panels around. Every visible surface is themeable at the token level, the layout stays as it is.
The same document is what a preset gallery would serve later: an index of these files, checked by this exact validator, is a marketplace.