From c68a66f73381b62ddc7abc83a461e1aa98a3e156 Mon Sep 17 00:00:00 2001 From: Kaiyi Date: Fri, 3 Apr 2026 14:02:03 +0800 Subject: [PATCH] fix(shell): override all Rich default markdown.* styles to prevent background color leakage NEUTRAL_MARKDOWN_THEME inherits from Rich's defaults via inherit=True. Rich's built-in "markdown.code" and "markdown.code_block" styles include "on black" backgrounds that leak through on non-black terminals. Override all Rich markdown.* style keys to "none" so the custom _FALLBACK_STYLES control the final appearance. Closes #1681 --- CHANGELOG.md | 2 ++ docs/en/release-notes/changelog.md | 2 ++ docs/zh/release-notes/changelog.md | 2 ++ src/kimi_cli/ui/shell/console.py | 5 +++ tests/ui/test_console_theme.py | 53 ++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+) create mode 100644 tests/ui/test_console_theme.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 50f93a4ea..41aada1c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ Only write entries that are worth mentioning to users. ## Unreleased +- Shell: Fix black background on inline code and code blocks in Markdown rendering — `NEUTRAL_MARKDOWN_THEME` now overrides all Rich default `markdown.*` styles to `"none"`, preventing Rich's built-in `"cyan on black"` from leaking through on non-black terminals + ## 1.30.0 (2026-04-02) - Shell: Refine idle background completion auto-trigger — resumed shell sessions no longer auto-start a foreground turn from stale pending background notifications before the user sends a message, and fresh background completions now wait briefly while the user is actively typing to avoid stealing the prompt or breaking CJK IME composition diff --git a/docs/en/release-notes/changelog.md b/docs/en/release-notes/changelog.md index 4b0e3a2be..b207c1632 100644 --- a/docs/en/release-notes/changelog.md +++ b/docs/en/release-notes/changelog.md @@ -4,6 +4,8 @@ This page documents the changes in each Kimi Code CLI release. ## Unreleased +- Shell: Fix black background on inline code and code blocks in Markdown rendering — `NEUTRAL_MARKDOWN_THEME` now overrides all Rich default `markdown.*` styles to `"none"`, preventing Rich's built-in `"cyan on black"` from leaking through on non-black terminals + ## 1.30.0 (2026-04-02) - Shell: Refine idle background completion auto-trigger — resumed shell sessions no longer auto-start a foreground turn from stale pending background notifications before the user sends a message, and fresh background completions now wait briefly while the user is actively typing to avoid stealing the prompt or breaking CJK IME composition diff --git a/docs/zh/release-notes/changelog.md b/docs/zh/release-notes/changelog.md index e88ceba79..07c687e31 100644 --- a/docs/zh/release-notes/changelog.md +++ b/docs/zh/release-notes/changelog.md @@ -4,6 +4,8 @@ ## 未发布 +- Shell:修复 Markdown 渲染中行内代码和代码块出现黑色背景的问题——`NEUTRAL_MARKDOWN_THEME` 现在将所有 Rich 默认的 `markdown.*` 样式覆盖为 `"none"`,防止 Rich 内置的 `"cyan on black"` 在非黑色背景终端上泄露 + ## 1.30.0 (2026-04-02) - Shell:细化空闲时后台完成的自动触发行为——恢复的 Shell 会话在用户发送消息前,不会因为历史遗留的后台通知而自动启动新的前景轮次;当用户正在输入时,新的后台完成事件也会短暂延后触发,避免抢占提示符或打断 CJK 输入法组合态 diff --git a/src/kimi_cli/ui/shell/console.py b/src/kimi_cli/ui/shell/console.py index 9576260b8..1446b3cb0 100644 --- a/src/kimi_cli/ui/shell/console.py +++ b/src/kimi_cli/ui/shell/console.py @@ -13,6 +13,7 @@ "markdown.paragraph": "none", "markdown.block_quote": "none", "markdown.hr": "none", + "markdown.list": "none", "markdown.item": "none", "markdown.item.bullet": "none", "markdown.item.number": "none", @@ -25,9 +26,13 @@ "markdown.h4": "none", "markdown.h5": "none", "markdown.h6": "none", + "markdown.h7": "none", "markdown.em": "none", + "markdown.emph": "none", "markdown.strong": "none", "markdown.s": "none", + "markdown.code": "none", + "markdown.code_block": "none", "status.spinner": "none", }, inherit=True, diff --git a/tests/ui/test_console_theme.py b/tests/ui/test_console_theme.py new file mode 100644 index 000000000..46dcaad5c --- /dev/null +++ b/tests/ui/test_console_theme.py @@ -0,0 +1,53 @@ +"""Tests for NEUTRAL_MARKDOWN_THEME style overrides.""" + +from __future__ import annotations + +from kimi_cli.ui.shell.console import NEUTRAL_MARKDOWN_THEME + + +class TestNeutralMarkdownThemeNoBgColor: + """markdown.code and markdown.code_block must not inherit Rich's default + black background (``"cyan on black"`` / ``"bold cyan on black"``). + + Rich's built-in default theme defines:: + + "markdown.code": "bold cyan on black" + "markdown.code_block": "cyan on black" + + Because NEUTRAL_MARKDOWN_THEME uses ``inherit=True``, any style key NOT + explicitly listed inherits the Rich default. If we forget to override + ``markdown.code`` and ``markdown.code_block``, inline code and fenced code + blocks will render with an opaque black background that looks wrong on + non-black terminals (the "black code block" bug, see issue #1681). + """ + + def test_markdown_code_has_no_background(self) -> None: + style = NEUTRAL_MARKDOWN_THEME.styles.get("markdown.code") + assert style is not None, "markdown.code must be explicitly set in NEUTRAL_MARKDOWN_THEME" + assert style.bgcolor is None, ( + f"markdown.code should have no background color, got bgcolor={style.bgcolor}" + ) + + def test_markdown_code_block_has_no_background(self) -> None: + style = NEUTRAL_MARKDOWN_THEME.styles.get("markdown.code_block") + assert style is not None, ( + "markdown.code_block must be explicitly set in NEUTRAL_MARKDOWN_THEME" + ) + assert style.bgcolor is None, ( + f"markdown.code_block should have no background color, got bgcolor={style.bgcolor}" + ) + + def test_all_markdown_styles_have_no_background(self) -> None: + """No markdown.* style in NEUTRAL_MARKDOWN_THEME should carry a background color. + + Rich's default theme may assign background colors to markdown styles + (e.g. ``"cyan on black"`` for code). Since NEUTRAL_MARKDOWN_THEME uses + ``inherit=True``, any key we forget to override will inherit the Rich + default. This test catches that for ALL markdown styles, not just the + ones we know about today. + """ + for name, style in NEUTRAL_MARKDOWN_THEME.styles.items(): + if name.startswith("markdown."): + assert style.bgcolor is None, ( + f"{name} should have no background color, got bgcolor={style.bgcolor}" + )