From 02cf05a1038e2a673ec07eb3f98e14fc476f53c2 Mon Sep 17 00:00:00 2001 From: Pluviobyte Date: Thu, 28 May 2026 07:41:34 +0000 Subject: [PATCH] fix(tools): preserve shell command headline details Shell tool headlines previously reused the generic key argument shortening, so long commands hid important paths and flags behind a middle ellipsis. Keep Shell command arguments intact while leaving other tool headlines on the existing compact display. Fixes #2142 Co-authored-by: Cursor --- CHANGELOG.md | 2 ++ src/kimi_cli/tools/__init__.py | 3 ++- tests/tools/test_extract_key_argument.py | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73272051f..82f0431a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ Only write entries that are worth mentioning to users. ## Unreleased +- Tools: Shell tool headlines now keep the full command string instead of applying the generic 50-character middle truncation, making long paths and arguments visible when reviewing repeated or failed commands + ## 1.45.0 (2026-05-26) - Shell: `/clear` is now an alias for `/new` — both commands start a new session; previously `/clear` only cleared context without creating a new session diff --git a/src/kimi_cli/tools/__init__.py b/src/kimi_cli/tools/__init__.py index 371a9d498..714733703 100644 --- a/src/kimi_cli/tools/__init__.py +++ b/src/kimi_cli/tools/__init__.py @@ -94,7 +94,8 @@ def extract_key_argument(json_content: str | streamingjson.Lexer, tool_name: str key_argument = "".join(content) else: key_argument = json_content - key_argument = shorten_middle(key_argument, width=50) + if tool_name != "Shell": + key_argument = shorten_middle(key_argument, width=50) return key_argument diff --git a/tests/tools/test_extract_key_argument.py b/tests/tools/test_extract_key_argument.py index 8f726d5fd..fc74938b1 100644 --- a/tests/tools/test_extract_key_argument.py +++ b/tests/tools/test_extract_key_argument.py @@ -15,11 +15,28 @@ def test_shell(self): result = extract_key_argument('{"command": "ls -la"}', "Shell") assert result == "ls -la" + def test_shell_long_command_keeps_path_and_arguments(self): + command = ( + "python scripts/really/deeply/nested/path/for/reproducing/issue_2142.py " + "--input /tmp/moonshot/kimi-cli/very/long/source/file.txt " + "--output /tmp/moonshot/kimi-cli/very/long/result.json" + ) + result = extract_key_argument(f'{{"command": "{command}"}}', "Shell") + assert result == command + assert "..." not in result + def test_readfile(self): result = extract_key_argument('{"path": "foo/bar.py"}', "ReadFile") assert result is not None assert "foo/bar.py" in result + def test_readfile_long_path_still_shortens(self): + long_path = "/workspace/" + "/".join(f"directory_{i:02d}" for i in range(12)) + "/target.py" + result = extract_key_argument(f'{{"path": "{long_path}"}}', "ReadFile") + assert result is not None + assert "..." in result + assert len(result) <= 53 + def test_grep(self): result = extract_key_argument('{"pattern": "hello"}', "Grep") assert result == "hello"