Record the base theme in the .fcast header so recordings render the same everywhere #3

Closed
opened 2026-09-25 12:07:56 +09:00 by natsukium · 1 comment
Owner

Motivation

A .fcast carries no base theme. The header has only format, version, felis_json, grid and meta (docs/reference/format.md:32-48). ConfigureTheme is client→daemon traffic, which v1 does not record. A recording therefore holds only the OSC color overrides, not the colors they override.

For a live replay through serve this is fine, because the attaching client supplies its own theme. For the planned felis-reel (headless .fcast → video), it means the same recording renders with whatever theme the machine converting it has configured. A recording shared with someone else does not look the way it looked to the person who recorded it.

Proposal

record writes the attaching client's base theme into the header, either as a new field or under meta (for example meta.theme { fg, bg, cursor, palette }). Readers already tolerate unknown fields (format.md:50), so this does not break existing readers. Renderers would use it as the default and still let a flag override it.

To decide

  • A normative header field or informational meta. A normative field makes renderers depend on it. meta keeps it optional.
  • Where record gets the theme from. It is a client-core attach, so it would read the user's felis config the same way felis-client does. A --theme flag could override that.
  • Whether this needs an envelope version bump. A meta key does not; a header field probably does.

The owning explanation is docs/explanation/format.md. The decision and the rejected option belong there.

## Motivation A `.fcast` carries no base theme. The header has only `format`, `version`, `felis_json`, `grid` and `meta` (`docs/reference/format.md:32-48`). `ConfigureTheme` is client→daemon traffic, which v1 does not record. A recording therefore holds only the OSC color *overrides*, not the colors they override. For a live replay through `serve` this is fine, because the attaching client supplies its own theme. For the planned felis-reel (headless `.fcast` → video), it means the same recording renders with whatever theme the machine converting it has configured. A recording shared with someone else does not look the way it looked to the person who recorded it. ## Proposal `record` writes the attaching client's base theme into the header, either as a new field or under `meta` (for example `meta.theme { fg, bg, cursor, palette }`). Readers already tolerate unknown fields (`format.md:50`), so this does not break existing readers. Renderers would use it as the default and still let a flag override it. ## To decide - A normative header field or informational `meta`. A normative field makes renderers depend on it. `meta` keeps it optional. - Where `record` gets the theme from. It is a client-core attach, so it would read the user's felis config the same way felis-client does. A `--theme` flag could override that. - Whether this needs an envelope `version` bump. A `meta` key does not; a header field probably does. The owning explanation is `docs/explanation/format.md`. The decision and the rejected option belong there.
Author
Owner

Status after the felis-cast v1 rework (PR #8):

  • The stable envelope (felis-cast v1) lets this land later without a version bump: an unknown header field is ignored by readers, and meta keys are free-form. So this does not block stabilization.
  • It now conflicts with the format explanation, though: docs/explanation/format.md "Out of scope, on purpose" lists theme under player behaviour that belongs to the embedding player. Resolving this issue means picking one:
    1. Close as out of scope. The renderer (felis-reel --theme, felis-web-component's theme attribute) owns the base theme; the explanation already says so.
    2. Record it as optional meta.theme. Informational, renderers may use it as a default; the "out of scope" paragraph is narrowed to say the file may carry the recorder's theme as a hint.
    3. A normative header field. Renderers must honour it; additive under v1's rules, but it makes theme part of the format contract.
  • Recommendation: 2, if a shared recording must look the way it looked to the person who made it; otherwise 1.
Status after the felis-cast v1 rework (PR #8): - The stable envelope (`felis-cast` v1) lets this land later without a version bump: an unknown header field is ignored by readers, and `meta` keys are free-form. So this does not block stabilization. - It now conflicts with the format explanation, though: `docs/explanation/format.md` "Out of scope, on purpose" lists theme under player behaviour that belongs to the embedding player. Resolving this issue means picking one: 1. **Close as out of scope.** The renderer (felis-reel `--theme`, felis-web-component's `theme` attribute) owns the base theme; the explanation already says so. 2. **Record it as optional `meta.theme`.** Informational, renderers may use it as a default; the "out of scope" paragraph is narrowed to say the file may carry the recorder's theme as a hint. 3. **A normative header field.** Renderers must honour it; additive under v1's rules, but it makes theme part of the format contract. - Recommendation: 2, if a shared recording must look the way it looked to the person who made it; otherwise 1.
Sign in to join this conversation.
No labels
No milestone
No project
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
natsukium/felis-fcast#3
No description provided.