fix(tool-hint): handle quoted paths in exec hints

Preserve path folding for quoted exec command paths with spaces so hint previews do not fall back to mid-path truncation. Add regression coverage for quoted Unix and Windows path cases.

Made-with: Cursor
This commit is contained in:
Xubin Ren 2026-04-08 15:04:03 +00:00 committed by Xubin Ren
parent b16865722b
commit c092896922
2 changed files with 28 additions and 5 deletions

View File

@ -19,9 +19,11 @@ _TOOL_FORMATS: dict[str, tuple[list[str], str, bool, bool]] = {
"list_dir": (["path"], "ls {}", True, False),
}
# Matches file paths embedded in shell commands (Windows drive, ~/, or absolute after space)
# Matches file paths embedded in shell commands, including quoted paths with spaces.
_PATH_IN_CMD_RE = re.compile(
r"(?:[A-Za-z]:[/\\]|~/|(?<=\s)/)[^\s;&|<>\"']+"
r'"(?P<double>(?:[A-Za-z]:[/\\]|~/|/)[^"]+)"'
r"|'(?P<single>(?:[A-Za-z]:[/\\]|~/|/)[^']+)'"
r"|(?P<bare>(?:[A-Za-z]:[/\\]|~/|(?<=\s)/)[^\s;&|<>\"']+)"
)
@ -92,9 +94,14 @@ def _fmt_known(tc, fmt: tuple) -> str:
def _abbreviate_command(cmd: str, max_len: int = 40) -> str:
"""Abbreviate paths in a command string, then truncate."""
abbreviated = _PATH_IN_CMD_RE.sub(
lambda m: abbreviate_path(m.group(), max_len=25), cmd
)
def _replace_path(match: re.Match[str]) -> str:
if match.group("double") is not None:
return f'"{abbreviate_path(match.group("double"), max_len=25)}"'
if match.group("single") is not None:
return f"'{abbreviate_path(match.group('single'), max_len=25)}'"
return abbreviate_path(match.group("bare"), max_len=25)
abbreviated = _PATH_IN_CMD_RE.sub(_replace_path, cmd)
if len(abbreviated) <= max_len:
return abbreviated
return abbreviated[:max_len - 1] + "\u2026"

View File

@ -72,6 +72,22 @@ class TestToolHintKnownTools:
result = _hint([_tc("exec", {"command": cmd})])
assert "\u2026/" in result
def test_exec_abbreviates_quoted_linux_paths_with_spaces(self):
"""Quoted Unix paths with spaces should still be folded."""
cmd = 'cd "/home/user/My Documents/project" && pytest tests/'
result = _hint([_tc("exec", {"command": cmd})])
assert "\u2026/" in result
assert '"/home/user/My Documents/project"' not in result
assert '"' in result
def test_exec_abbreviates_quoted_windows_paths_with_spaces(self):
"""Quoted Windows paths with spaces should still be folded."""
cmd = 'cd "C:/Program Files/Git/project" && git status'
result = _hint([_tc("exec", {"command": cmd})])
assert "\u2026/" in result
assert '"C:/Program Files/Git/project"' not in result
assert '"' in result
def test_exec_short_command_unchanged(self):
result = _hint([_tc("exec", {"command": "npm install typescript"})])
assert result == "$ npm install typescript"