From 79138c0e700f01dab19e9c105f24cbce7c1fc8aa Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Fri, 28 Aug 2026 12:33:02 -0400 Subject: [PATCH] Follow the active theme in T3 Code T3 Code reads themes an environment publishes into its state directory, so a generated t3code.json carries the palette the same way claude.json and vscode-theme.json already do, and omarchy-theme-set-t3code republishes it on every theme change for the app to pick up live. The template overrides only the roles a theme actually designs -- terminal and code surfaces, text on canvas, borders, selection -- and leaves muted text, placeholders, and status foregrounds to T3 Code, which contrast-solves them against whatever canvas it is given. Overriding those directly cost readability on light themes: White fell to 1.0:1 on placeholder text. Installing from the menu now routes through omarchy-install-ai-t3-code so a fresh install publishes the current palette and opens wearing it. --- bin/omarchy-install-ai-t3-code | 49 ++++++++++++++++++++++++++++++ bin/omarchy-theme-set | 1 + bin/omarchy-theme-set-t3code | 34 +++++++++++++++++++++ default/omarchy/omarchy-menu.jsonc | 2 +- default/themed/t3code.json.tpl | 36 ++++++++++++++++++++++ test/shell.d/theme-staging-test.sh | 2 +- 6 files changed, 122 insertions(+), 2 deletions(-) create mode 100755 bin/omarchy-install-ai-t3-code create mode 100755 bin/omarchy-theme-set-t3code create mode 100644 default/themed/t3code.json.tpl diff --git a/bin/omarchy-install-ai-t3-code b/bin/omarchy-install-ai-t3-code new file mode 100755 index 00000000..1302b7ee --- /dev/null +++ b/bin/omarchy-install-ai-t3-code @@ -0,0 +1,49 @@ +#!/bin/bash + +# omarchy:summary=Install T3 Code and point it at the Omarchy palette +# omarchy:requires-sudo=true + +set -e + +T3CODE_HOME="${T3CODE_HOME:-$HOME/.t3}" +T3CODE_STATE_DIR="$T3CODE_HOME/userdata" +T3CODE_SETTINGS_PATH="$T3CODE_STATE_DIR/settings.json" + +# Ask T3 Code to open on the palette this machine publishes. `t3 theme set` +# is the supported way, but the desktop package ships only the GUI -- the CLI +# is a separate npm distribution -- so fall back to the setting it writes. +# Both run before the first launch, so neither races a running server. +set_default_theme() { + if command -v t3 >/dev/null 2>&1; then + t3 theme set omarchy --base-dir "$T3CODE_HOME" >/dev/null && return + fi + + local tmp + mkdir -p "$T3CODE_STATE_DIR" + [[ -f $T3CODE_SETTINGS_PATH ]] || echo '{}' >"$T3CODE_SETTINGS_PATH" + + tmp=$(mktemp "$T3CODE_SETTINGS_PATH.XXXXXX") + if jq '.defaultTheme = "omarchy"' "$T3CODE_SETTINGS_PATH" >"$tmp"; then + mv "$tmp" "$T3CODE_SETTINGS_PATH" + else + rm -f "$tmp" + echo "Could not set the default theme in $T3CODE_SETTINGS_PATH." >&2 + fi +} + +echo "Installing T3 Code..." +omarchy-pkg-add t3code-bin + +# The palette itself, and the request to open on it, are both first-run +# concerns. `defaultTheme` only decides what a client with no theme of its own +# starts on, so choosing a theme in T3 Code later is never overridden. +echo "Matching T3 Code to the current theme..." +mkdir -p "$T3CODE_STATE_DIR" +omarchy-theme-set-t3code +set_default_theme + +echo "Opening T3 Code..." +setsid uwsm-app -- gtk-launch t3code >/dev/null 2>&1 & + +echo "" +echo "T3 Code has been installed." diff --git a/bin/omarchy-theme-set b/bin/omarchy-theme-set index 614a8a1b..782b4ba7 100755 --- a/bin/omarchy-theme-set +++ b/bin/omarchy-theme-set @@ -372,6 +372,7 @@ post_theme_commands=( omarchy-theme-set-pi omarchy-theme-set-claude omarchy-theme-set-hermes + omarchy-theme-set-t3code omarchy-theme-set-browser omarchy-theme-set-vscode omarchy-theme-set-obsidian diff --git a/bin/omarchy-theme-set-t3code b/bin/omarchy-theme-set-t3code new file mode 100755 index 00000000..7b6f69bf --- /dev/null +++ b/bin/omarchy-theme-set-t3code @@ -0,0 +1,34 @@ +#!/bin/bash + +# omarchy:summary=Sync the generated Omarchy theme to T3 Code +# omarchy:hidden=true + +set -euo pipefail + +T3CODE_SOURCE_PATH="$HOME/.local/state/omarchy/current/theme/t3code.json" +T3CODE_HOME="${T3CODE_HOME:-$HOME/.t3}" +T3CODE_STATE_DIR="$T3CODE_HOME/userdata" +# The filename is the theme id T3 Code shows and `t3 theme set` accepts, and +# it stays stable while the colors change underneath on every theme switch. +T3CODE_THEME_PATH="$T3CODE_STATE_DIR/themes/omarchy.json" + +[[ -f $T3CODE_SOURCE_PATH ]] || exit 0 + +# A theme without an accent or a background leaves its placeholder unresolved. +# Publishing that would only make T3 Code reject the file, so skip instead and +# leave the previous palette in place. +if grep -q '{{' "$T3CODE_SOURCE_PATH"; then + echo "Skipping T3 Code theme: $(basename "$T3CODE_SOURCE_PATH") has unresolved colors." >&2 + exit 0 +fi + +# Only follow an install that already exists. Creating the directory here would +# leave a stray T3 Code state dir on machines that do not run it. +[[ -d $T3CODE_STATE_DIR ]] || exit 0 + +# T3 Code watches this file and retints every connected client on change, so +# the write has to be atomic: a half-written file would read as invalid. +mkdir -p "$(dirname "$T3CODE_THEME_PATH")" +tmp=$(mktemp "$T3CODE_THEME_PATH.XXXXXX") +cp "$T3CODE_SOURCE_PATH" "$tmp" +mv "$tmp" "$T3CODE_THEME_PATH" diff --git a/default/omarchy/omarchy-menu.jsonc b/default/omarchy/omarchy-menu.jsonc index 0e590652..745ec311 100644 --- a/default/omarchy/omarchy-menu.jsonc +++ b/default/omarchy/omarchy-menu.jsonc @@ -248,7 +248,7 @@ "install.ai.ollama": {"icon":"","iconFont":"omarchy","label":"Ollama","disabled":"omarchy-cmd-present ollama","action":"if omarchy-cmd-present nvidia-smi; then ollama_pkg=ollama-cuda; elif omarchy-cmd-present rocminfo; then ollama_pkg=ollama-rocm; else ollama_pkg=ollama; fi; omarchy-install-app Ollama \"$ollama_pkg\""}, "install.ai.openclaw": {"icon":"","iconFont":"omarchy","label":"OpenClaw","disabled":"omarchy-pkg-present openclaw","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-ai-openclaw"}, "install.ai.perplexity": {"icon":"","iconFont":"omarchy","label":"Perplexity","disabled":"omarchy-pkg-present perplexity","action":"omarchy-install-and-launch Perplexity perplexity perplexity"}, - "install.ai.t3-code": {"icon":"","iconFont":"omarchy","label":"T3 Code","disabled":"omarchy-pkg-present t3code-bin","action":"omarchy-install-and-launch 'T3 Code' t3code-bin t3code"}, + "install.ai.t3-code": {"icon":"","iconFont":"omarchy","label":"T3 Code","disabled":"omarchy-pkg-present t3code-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-ai-t3-code"}, "install.gaming.steam": {"icon":"","label":"Steam","disabled":"omarchy-pkg-present steam","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-steam"}, "install.gaming.retroarch": {"icon":"󰯉","label":"RetroArch","disabled":"omarchy-pkg-present retroarch","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-retroarch"}, "install.gaming.minecraft": {"icon":"󰍳","label":"Minecraft","disabled":"omarchy-pkg-present minecraft-launcher","action":"omarchy-install-and-launch Minecraft minecraft-launcher minecraft-launcher"}, diff --git a/default/themed/t3code.json.tpl b/default/themed/t3code.json.tpl new file mode 100644 index 00000000..e420dcc4 --- /dev/null +++ b/default/themed/t3code.json.tpl @@ -0,0 +1,36 @@ +{ + "name": "Omarchy", + "appearance": "{{ mode }}", + "canvas": "{{ background }}", + "accent": "{{ accent }}", + "colors": { + "chrome": "{{ background }}", + "toolbar": "{{ background }}", + "toolbarForeground": "{{ foreground }}", + "toolbarBorder": "{{ muted }}", + + "text": "{{ foreground }}", + "border": "{{ muted }}", + "focus": "{{ accent }}", + + "sidebar": "{{ dark_background }}", + "sidebarForeground": "{{ foreground }}", + "sidebarBorder": "{{ muted }}", + "sidebarRowHover": "{{ mix dark_background foreground 6% }}", + "sidebarRowActive": "{{ mix dark_background accent 18% }}", + "sidebarRowSelected": "{{ selection }}", + + "error": "{{ mix red foreground 35% }}", + "warning": "{{ mix yellow foreground 35% }}", + + "codeBackground": "{{ dark_background }}", + "codeForeground": "{{ foreground }}", + + "terminalBackground": "{{ background }}", + "terminalForeground": "{{ foreground }}", + "terminalCursor": "{{ bright_foreground }}", + "terminalSelection": "{{ selection }}", + "terminalScrollbar": "{{ muted }}", + "terminalScrollbarHover": "{{ dark_foreground }}" + } +} diff --git a/test/shell.d/theme-staging-test.sh b/test/shell.d/theme-staging-test.sh index 9ec3b0f9..1fc7a4a5 100755 --- a/test/shell.d/theme-staging-test.sh +++ b/test/shell.d/theme-staging-test.sh @@ -207,7 +207,7 @@ pass "a theme name cannot climb out of the theme directories" # generates. Every generated theme file is either denied to an installed theme or # recorded here as carrying colour, so a new template fails until it is placed. denied=(alacritty.toml foot.ini ghostty.conf kitty.conf gum_env.lua hyprland.lua neovim.lua vscode.json) -colour_only=(btop.theme chromium.theme claude.json helix.toml hermes.yaml hyprland-preview-share-picker.css keyboard.rgb obsidian.css pi.json shell.toml vscode-theme.json) +colour_only=(btop.theme chromium.theme claude.json helix.toml hermes.yaml hyprland-preview-share-picker.css keyboard.rgb obsidian.css pi.json shell.toml t3code.json vscode-theme.json) for tpl in "$ROOT"/default/themed/*.tpl; do generated=$(basename "$tpl" .tpl)