Lightweight theme preference coercion shared by config providers and the UI.
Resolve a user-supplied theme name to a canonical registry key.
Accepts the registry key or the human-readable label, case-insensitive on
both, with surrounding whitespace stripped - config values (especially
[ui.terminal_themes]) and the DEEPAGENTS_CODE_THEME env var are commonly
hand-edited. Also applies the legacy textual-ansi to ansi-light
migration, which predates Textual 8.2.5 and can be dropped once no
supported config can still carry the old name.
Return value as a TOML table when it has the expected runtime shape.
tomllib parses TOML tables as string-keyed dicts, which ty cannot infer
from a runtime dict check. Keep the cast at this boundary so it does not
become a general-purpose escape hatch - now more important, not less, since
the helper became importable from a shared module.
Resolve [ui.terminal_themes][TERM_PROGRAM] to a registered theme.
Centralizes both the lookup and the misconfiguration warnings, which are logged exactly once per call. Three callers now share that contract: the managed and user TOML tiers and the UI.
LangChain brand colors and semantic constants for the app.
Single source of truth for color values used in Python code (Rich markup,
Content.styled, Content.from_markup). CSS-side styling should reference
Textual CSS variables: built-in variables
($primary, $background, $text-muted, $error-muted, etc.) are set via
register_theme() in DeepAgentsApp.__init__, while the few app-specific
variables ($mode-bash, $mode-command, $mode-incognito, $skill,
$skill-hover, $tool, $tool-hover) are backed by these constants via
App.get_theme_variable_defaults().
Code that needs custom CSS variable values should call
get_css_variable_defaults(dark=...). For the full semantic color palette, look
up the ThemeColors instance via get_registry().
Users can define custom themes in ~/.deepagents/config.toml under
[themes.<name>] sections. Each new theme section must include label (str);
dark (bool) defaults to False if omitted (set to True for dark themes).
Color fields are optional and fall back to the built-in dark/light palette based
on the dark flag. Sections whose name matches a built-in theme override its
colors without replacing it. See _load_user_themes() for details.