feat: drop dim colors, keep only bright variants renamed to base names
test / unit (pull_request) Successful in 38s
test / integration (pull_request) Successful in 21s
lint / lint (push) Successful in 1m40s
test / unit (push) Successful in 34s
test / integration (push) Successful in 19s
Update Quality Badges / update-badges (push) Successful in 1m19s

Remove the 8 non-bright and 1 bright-black colors from all color maps.
Rename the remaining 7 bright-* colors to their base names (e.g.
bright-green → green) so the palette is smaller and always vibrant.

Update _init_color_pairs in tui.py to always apply A_BOLD (all palette
entries are now bright variants), and fix all tests to match.
This commit was merged in pull request #241.
This commit is contained in:
2026-06-22 18:59:51 +00:00
parent 65faa40b9a
commit 609b3ed090
8 changed files with 41 additions and 86 deletions
+7 -16
View File
@@ -12,22 +12,13 @@ import shlex
# uses true/24-bit colors for its own chrome, which would otherwise bypass # uses true/24-bit colors for its own chrome, which would otherwise bypass
# the palette entirely. # the palette entirely.
_COLORS: dict[str, tuple[int, str, int, str, str]] = { _COLORS: dict[str, tuple[int, str, int, str, str]] = {
"black": (0, "#2d2d2d", 8, "#5c5c5c", "#0a0a0a"), "red": (9, "#e74c3c", 1, "#c0392b", "#200808"),
"red": (1, "#c0392b", 9, "#e74c3c", "#1a0707"), "green": (10, "#2ecc71", 2, "#27ae60", "#082008"),
"green": (2, "#27ae60", 10, "#2ecc71", "#071a09"), "yellow": (11, "#f1c40f", 3, "#d4ac0d", "#201808"),
"yellow": (3, "#d4ac0d", 11, "#f1c40f", "#1a1507"), "blue": (12, "#3498db", 4, "#2471a3", "#080820"),
"blue": (4, "#2471a3", 12, "#3498db", "#07071a"), "magenta": (13, "#9b59b6", 5, "#7d3c98", "#160820"),
"magenta": (5, "#7d3c98", 13, "#9b59b6", "#12071a"), "cyan": (14, "#1abc9c", 6, "#148f77", "#082020"),
"cyan": (6, "#148f77", 14, "#1abc9c", "#071a1a"), "white": (15, "#ecf0f1", 7, "#bdc3c7", "#151515"),
"white": (7, "#bdc3c7", 15, "#ecf0f1", "#111111"),
"bright-black": (8, "#5c5c5c", 0, "#2d2d2d", "#111111"),
"bright-red": (9, "#e74c3c", 1, "#c0392b", "#200808"),
"bright-green": (10, "#2ecc71", 2, "#27ae60", "#082008"),
"bright-yellow": (11, "#f1c40f", 3, "#d4ac0d", "#201808"),
"bright-blue": (12, "#3498db", 4, "#2471a3", "#080820"),
"bright-magenta": (13, "#9b59b6", 5, "#7d3c98", "#160820"),
"bright-cyan": (14, "#1abc9c", 6, "#148f77", "#082020"),
"bright-white": (15, "#ecf0f1", 7, "#bdc3c7", "#151515"),
} }
# OSC 104 resets all indexed palette entries; OSC 111 resets default background. # OSC 104 resets all indexed palette entries; OSC 111 resets default background.
+7 -16
View File
@@ -11,22 +11,13 @@ from ..manifest import Manifest
from ._common import PROG, USER_CWD from ._common import PROG, USER_CWD
_ANSI_COLOR_CODES: dict[str, str] = { _ANSI_COLOR_CODES: dict[str, str] = {
"black": "\033[30m", "red": "\033[91m",
"red": "\033[31m", "green": "\033[92m",
"green": "\033[32m", "yellow": "\033[93m",
"yellow": "\033[33m", "blue": "\033[94m",
"blue": "\033[34m", "magenta": "\033[95m",
"magenta": "\033[35m", "cyan": "\033[96m",
"cyan": "\033[36m", "white": "\033[97m",
"white": "\033[37m",
"bright-black": "\033[90m",
"bright-red": "\033[91m",
"bright-green": "\033[92m",
"bright-yellow": "\033[93m",
"bright-blue": "\033[94m",
"bright-magenta": "\033[95m",
"bright-cyan": "\033[96m",
"bright-white": "\033[97m",
} }
_ANSI_RESET = "\033[0m" _ANSI_RESET = "\033[0m"
+3 -9
View File
@@ -226,13 +226,10 @@ def _addstr_safe(screen: Any, row: int, col: int, text: str, attr: int = curses.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
_ANSI_COLORS = [ _ANSI_COLORS = [
"red", "green", "blue", "yellow", "magenta", "cyan", "white", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white",
"bright-red", "bright-green", "bright-blue", "bright-yellow",
"bright-magenta", "bright-cyan", "bright-white", "bright-black",
] ]
_CURSES_COLOR_MAP: dict[str, int] = { _CURSES_COLOR_MAP: dict[str, int] = {
"black": curses.COLOR_BLACK,
"red": curses.COLOR_RED, "red": curses.COLOR_RED,
"green": curses.COLOR_GREEN, "green": curses.COLOR_GREEN,
"yellow": curses.COLOR_YELLOW, "yellow": curses.COLOR_YELLOW,
@@ -379,13 +376,10 @@ def _init_color_pairs() -> dict[str, int]:
curses.use_default_colors() curses.use_default_colors()
pair_idx = 2 # pair 1 reserved for other uses pair_idx = 2 # pair 1 reserved for other uses
for name in _ANSI_COLORS: for name in _ANSI_COLORS:
base = name.replace("bright-", "") fg = _CURSES_COLOR_MAP.get(name, curses.COLOR_WHITE)
fg = _CURSES_COLOR_MAP.get(base, curses.COLOR_WHITE)
try: try:
curses.init_pair(pair_idx, fg, -1) curses.init_pair(pair_idx, fg, -1)
attr = curses.color_pair(pair_idx) attr = curses.color_pair(pair_idx) | curses.A_BOLD
if name.startswith("bright-"):
attr |= curses.A_BOLD
attrs[name] = attr attrs[name] = attr
pair_idx += 1 pair_idx += 1
except curses.error: except curses.error:
+14 -32
View File
@@ -42,41 +42,23 @@ def _prompt_path(guest_home: str) -> str:
_STATUS_LINE_COLORS = { _STATUS_LINE_COLORS = {
"black": "\033[30m", "red": "\033[91m",
"red": "\033[31m", "green": "\033[92m",
"green": "\033[32m", "yellow": "\033[93m",
"yellow": "\033[33m", "blue": "\033[94m",
"blue": "\033[34m", "magenta": "\033[95m",
"magenta": "\033[35m", "cyan": "\033[96m",
"cyan": "\033[36m", "white": "\033[97m",
"white": "\033[37m",
"bright-black": "\033[90m",
"bright-red": "\033[91m",
"bright-green": "\033[92m",
"bright-yellow": "\033[93m",
"bright-blue": "\033[94m",
"bright-magenta": "\033[95m",
"bright-cyan": "\033[96m",
"bright-white": "\033[97m",
} }
_CLAUDE_THEME_COLORS = { _CLAUDE_THEME_COLORS = {
"black": "black", "red": "redBright",
"red": "red", "green": "greenBright",
"green": "green", "yellow": "yellowBright",
"yellow": "yellow", "blue": "blueBright",
"blue": "blue", "magenta": "magentaBright",
"magenta": "magenta", "cyan": "cyanBright",
"cyan": "cyan", "white": "whiteBright",
"white": "white",
"bright-black": "blackBright",
"bright-red": "redBright",
"bright-green": "greenBright",
"bright-yellow": "yellowBright",
"bright-blue": "blueBright",
"bright-magenta": "magentaBright",
"bright-cyan": "cyanBright",
"bright-white": "whiteBright",
} }
+1 -1
View File
@@ -74,7 +74,7 @@ class TestAgentProviderRuntime(unittest.TestCase):
instance_name="bot-bottle-test", instance_name="bot-bottle-test",
prompt_file=prompt_file, prompt_file=prompt_file,
label="review-api", label="review-api",
color="bright-cyan", color="cyan",
) )
prompt = prompt_file.read_text() prompt = prompt_file.read_text()
config = Path(tmp, "codex-config.toml").read_text() config = Path(tmp, "codex-config.toml").read_text()
+7 -10
View File
@@ -11,14 +11,14 @@ class TestPalettePrintf(unittest.TestCase):
def test_known_color_returns_printf(self): def test_known_color_returns_printf(self):
cmd = palette_printf("red") cmd = palette_printf("red")
self.assertTrue(cmd.startswith("printf '")) self.assertTrue(cmd.startswith("printf '"))
self.assertIn("\\033]4;1;", cmd) # normal red self.assertIn("\\033]4;9;", cmd) # bright-red slot
self.assertIn("\\033]4;9;", cmd) # bright red self.assertIn("\\033]4;1;", cmd) # normal-red slot
self.assertIn("\\033]11;", cmd) # default background tint self.assertIn("\\033]11;", cmd) # default background tint
def test_bright_variant_sets_both_slots(self): def test_color_sets_both_palette_slots(self):
cmd = palette_printf("bright-blue") cmd = palette_printf("blue")
self.assertIn("\\033]4;12;", cmd) # bright-blue self.assertIn("\\033]4;12;", cmd) # bright-blue slot
self.assertIn("\\033]4;4;", cmd) # blue self.assertIn("\\033]4;4;", cmd) # normal-blue slot
def test_unknown_color_returns_empty(self): def test_unknown_color_returns_empty(self):
self.assertEqual("", palette_printf("")) self.assertEqual("", palette_printf(""))
@@ -26,10 +26,7 @@ class TestPalettePrintf(unittest.TestCase):
def test_all_named_colors_produce_output(self): def test_all_named_colors_produce_output(self):
colors = [ colors = [
"black", "red", "green", "yellow", "red", "green", "yellow", "blue", "magenta", "cyan", "white",
"blue", "magenta", "cyan", "white",
"bright-black", "bright-red", "bright-green", "bright-yellow",
"bright-blue", "bright-magenta", "bright-cyan", "bright-white",
] ]
for color in colors: for color in colors:
with self.subTest(color=color): with self.subTest(color=color):
+1 -1
View File
@@ -276,7 +276,7 @@ class TestClaudeUiProvision(unittest.TestCase):
instance_name="bot-bottle-demo-abc12", instance_name="bot-bottle-demo-abc12",
prompt_file=prompt_file, prompt_file=prompt_file,
label="research-ui", label="research-ui",
color="bright-cyan", color="cyan",
) )
settings = json.loads((state_dir / "claude-settings.json").read_text()) settings = json.loads((state_dir / "claude-settings.json").read_text())
statusline = (state_dir / "claude-statusline.sh").read_text() statusline = (state_dir / "claude-statusline.sh").read_text()
+1 -1
View File
@@ -158,7 +158,7 @@ class TestCodexProvisionPrompt(unittest.TestCase):
instance_name="bot-bottle-demo-abc12", instance_name="bot-bottle-demo-abc12",
prompt_file=prompt_file, prompt_file=prompt_file,
label="research-ui", label="research-ui",
color="bright-cyan", color="cyan",
) )
config = (state_dir / "codex-config.toml").read_text() config = (state_dir / "codex-config.toml").read_text()
prompt_text = prompt_file.read_text() prompt_text = prompt_file.read_text()