protocol: answer OSC 4 palette queries from the window's configured palette #159

Closed
opened 2026-10-18 12:46:16 +09:00 by natsukium · 0 comments
Owner

Raised on the GitHub mirror by an embedder that draws its own palette (https://github.com/felis-terminal/felis/issues/3); felis's own window has the same gap.

Problem

OSC 4 ; n ; ? answers a program's own override, else the compiled-in xterm palette (crates/felis-grid/src/osc_dispatch.rs, default_palette_color). A window with [theme.palette] / [theme.palette.indexed] configured draws different colors from the ones the program is told, so a program that reads the palette to pick readable colors (Claude Code does) picks against colors nobody sees.

OSC 10/11/12 ; ? had the same bug and was fixed by the client reporting its resolved fg/bg/cursor in ConfigureTheme, resolved along the window candidate chain (docs/explanation/architecture/session-lifecycle.md "Client-derived presentation state"). The palette was not part of that fix: the report predates [theme.palette] covering all 256 slots, and the later window-chain change did not revisit it.

The recorded stance and why it does not hold

  • docs/explanation/architecture/session-lifecycle.md "Why not the last reporter, or a palette per window" ends "that is also why palette entries stay producer-only". The argument there rejects a per-window palette (each mirror its own view), which the chain does not need: the chain picks one window, exactly as it does for fg/bg.
  • docs/explanation/security-model.md "One named carve-out" keeps the 256-slot query "purely reflective". The palette a window would report is a color set the user configured, from a window attached to this session, in a felis-generated reply: the same containment the carve-out already accepts for fg/bg/cursor.
  • docs/reference/spec.md REQ-900a states "palette entries (OSC 4 / 5) have no client-derived fallback".

Direction

  • ConfigureTheme carries the window's configured palette entries (sparse: only the slots the config sets), added as a field under the minor ledger; it stays one atomic report per window and travels the existing chain.
  • felis-grid gains a palette config default between the program's override and the compiled-in table, the palette counterpart of set_theme_config_default. An embedder without a daemon calls it directly, which is what the GitHub request asks for.
  • OSC 104 and RIS still reset to the layer below the program's overrides, i.e. to the window's palette.
  • OSC 5 special colors stay as they are: no config key sets them, so a window has nothing to report.
  • Docs: the REQ-900a sentence, the security-model carve-out (two facets become three), the session-lifecycle paragraphs, docs/reference/ipc.md ConfigureTheme.
Raised on the GitHub mirror by an embedder that draws its own palette (https://github.com/felis-terminal/felis/issues/3); felis's own window has the same gap. ## Problem `OSC 4 ; n ; ?` answers a program's own override, else the compiled-in xterm palette (`crates/felis-grid/src/osc_dispatch.rs`, `default_palette_color`). A window with `[theme.palette]` / `[theme.palette.indexed]` configured draws different colors from the ones the program is told, so a program that reads the palette to pick readable colors (Claude Code does) picks against colors nobody sees. `OSC 10/11/12 ; ?` had the same bug and was fixed by the client reporting its resolved fg/bg/cursor in `ConfigureTheme`, resolved along the window candidate chain (`docs/explanation/architecture/session-lifecycle.md` "Client-derived presentation state"). The palette was not part of that fix: the report predates `[theme.palette]` covering all 256 slots, and the later window-chain change did not revisit it. ## The recorded stance and why it does not hold - `docs/explanation/architecture/session-lifecycle.md` "Why not the last reporter, or a palette per window" ends "that is also why palette entries stay producer-only". The argument there rejects a *per-window* palette (each mirror its own view), which the chain does not need: the chain picks one window, exactly as it does for fg/bg. - `docs/explanation/security-model.md` "One named carve-out" keeps the 256-slot query "purely reflective". The palette a window would report is a color set the user configured, from a window attached to this session, in a felis-generated reply: the same containment the carve-out already accepts for fg/bg/cursor. - `docs/reference/spec.md` REQ-900a states "palette entries (OSC 4 / 5) have no client-derived fallback". ## Direction - `ConfigureTheme` carries the window's configured palette entries (sparse: only the slots the config sets), added as a field under the minor ledger; it stays one atomic report per window and travels the existing chain. - felis-grid gains a palette config default between the program's override and the compiled-in table, the palette counterpart of `set_theme_config_default`. An embedder without a daemon calls it directly, which is what the GitHub request asks for. - `OSC 104` and RIS still reset to the layer below the program's overrides, i.e. to the window's palette. - OSC 5 special colors stay as they are: no config key sets them, so a window has nothing to report. - Docs: the REQ-900a sentence, the security-model carve-out (two facets become three), the session-lifecycle paragraphs, `docs/reference/ipc.md` `ConfigureTheme`.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
felis-terminal/felis#159
No description provided.