fix(cli): preserve Windows hidden-dir paths in markdown

This commit is contained in:
giwaov 2026-04-27 13:45:35 +01:00 committed by Teknium
parent 3fb35520c6
commit 026a5e47df
2 changed files with 40 additions and 0 deletions

23
cli.py
View file

@ -1226,6 +1226,28 @@ def _strip_markdown_syntax(text: str) -> str:
return plain.strip("\n")
_WINDOWS_PATH_WITH_DOT_SEGMENT_RE = re.compile(
r"(?i)(?:\b[a-z]:\\|\\\\)[^\s`]*\\\.[^\s`]*"
)
def _preserve_windows_dot_segments_for_markdown(text: str) -> str:
r"""Keep Windows path separators before hidden directories in Markdown.
CommonMark treats ``\.`` as an escaped literal dot, so Rich Markdown would
render ``D:\repo\.ai`` as ``D:\repo.ai``. Doubling only that separator
inside Windows path-looking tokens preserves the path without changing
ordinary markdown escapes like ``1\. not a list``.
"""
if "\\." not in text:
return text
def _protect(match: re.Match[str]) -> str:
return re.sub(r"(?<!\\)\\(?=\.)", r"\\\\", match.group(0))
return _WINDOWS_PATH_WITH_DOT_SEGMENT_RE.sub(_protect, text)
def _render_final_assistant_content(text: str, mode: str = "render"):
"""Render final assistant content as markdown, stripped text, or raw text."""
from rich.markdown import Markdown
@ -1237,6 +1259,7 @@ def _render_final_assistant_content(text: str, mode: str = "render"):
return _rich_text_from_ansi(text or "")
plain = _rich_text_from_ansi(text or "").plain
plain = _preserve_windows_dot_segments_for_markdown(plain)
return Markdown(plain)

View file

@ -22,6 +22,23 @@ def test_final_assistant_content_uses_markdown_renderable():
assert "two" in output
def test_final_assistant_content_preserves_windows_hidden_dir_paths():
renderable = _render_final_assistant_content(
r"D:\Projects\SourceCode\hermes-agent\.ai\skills" + "\\"
)
output = _render_to_text(renderable)
assert r"D:\Projects\SourceCode\hermes-agent\.ai\skills" + "\\" in output
def test_final_assistant_content_keeps_non_path_markdown_escapes():
renderable = _render_final_assistant_content(r"1\. Not an ordered list")
output = _render_to_text(renderable)
assert "1. Not an ordered list" in output
assert r"1\." not in output
def test_final_assistant_content_strips_ansi_before_markdown_rendering():
renderable = _render_final_assistant_content("\x1b[31m# Title\x1b[0m")