From 9bac2b8cdf153b1d8be3ec7507c5327edb32dc0f Mon Sep 17 00:00:00 2001 From: pi-agent Date: Wed, 18 Mar 2026 19:23:42 +0800 Subject: [PATCH 1/3] fix: support empty string literals in textfx - Fix tokenizer to emit empty string token when closing quote on empty buffer - Add force parameter to flush_word() to handle empty quoted strings - Add test case for echo "" and echo '' --- konabot/plugins/handle_text/base.py | 7 ++++--- tests/test_textfx_shell.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/konabot/plugins/handle_text/base.py b/konabot/plugins/handle_text/base.py index b199ae3..d7da900 100644 --- a/konabot/plugins/handle_text/base.py +++ b/konabot/plugins/handle_text/base.py @@ -161,9 +161,9 @@ class PipelineRunner: "'": "'", } - def flush_word(): + def flush_word(force: bool = False): nonlocal buf - if buf: + if buf or force: tokens.append(Token(TokenKind.WORD, buf)) buf = "" @@ -178,6 +178,7 @@ class PipelineRunner: escape = True elif c == quote: quote = None + flush_word(force=True) # 引号闭合时强制 flush,即使是空字符串 else: buf += c i += 1 @@ -188,7 +189,7 @@ class PipelineRunner: i += 1 continue - if c.isspace() or c in "  ": + if c.isspace() or c in " ": flush_word() i += 1 continue diff --git a/tests/test_textfx_shell.py b/tests/test_textfx_shell.py index 5e7def7..10f0636 100644 --- a/tests/test_textfx_shell.py +++ b/tests/test_textfx_shell.py @@ -205,3 +205,21 @@ async def test_while_body_can_use_if(runner: PipelineRunner): assert not isinstance(parsed, str) results = await runner.run_pipeline(parsed, None, TextHandlerEnvironment(False)) assert results[0].code == 1 + + +@pytest.mark.asyncio +async def test_echo_empty_string(runner: PipelineRunner): + """测试 echo 空字符串""" + # 双引号空字符串 + parsed = runner.parse_pipeline('echo ""') + assert not isinstance(parsed, str) + results = await runner.run_pipeline(parsed, None, TextHandlerEnvironment(False)) + assert results[0].code == 0 + assert results[0].ostream == '' + + # 单引号空字符串 + parsed2 = runner.parse_pipeline("echo ''") + assert not isinstance(parsed2, str) + results2 = await runner.run_pipeline(parsed2, None, TextHandlerEnvironment(False)) + assert results2[0].code == 0 + assert results2[0].ostream == '' From 717b7a95e80345e603c72f08e5272e52ec07b00e Mon Sep 17 00:00:00 2001 From: pi-agent Date: Wed, 18 Mar 2026 19:30:55 +0800 Subject: [PATCH 2/3] fix: echo should not read stdin (Unix semantics) --- konabot/plugins/handle_text/handlers/unix_handlers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/konabot/plugins/handle_text/handlers/unix_handlers.py b/konabot/plugins/handle_text/handlers/unix_handlers.py index 16e210d..f9ab5e7 100644 --- a/konabot/plugins/handle_text/handlers/unix_handlers.py +++ b/konabot/plugins/handle_text/handlers/unix_handlers.py @@ -13,10 +13,9 @@ class THEcho(TextHandler): async def handle( self, env: TextHandlerEnvironment, istream: str | None, args: list[str] ) -> TextHandleResult: - if len(args) == 0 and istream is None: + # echo 不读 stdin,只输出参数(Unix 语义) + if len(args) == 0: return TextHandleResult(1, "请在 echo 后面添加需要输出的文本") - if istream is not None: - return TextHandleResult(0, "\n".join([istream] + args)) return TextHandleResult(0, "\n".join(args)) From 5b1c6d446cdbb948443fff8b3dffdd3f6e2cc1c9 Mon Sep 17 00:00:00 2001 From: pi-agent Date: Wed, 18 Mar 2026 19:40:02 +0800 Subject: [PATCH 3/3] fix: remove redundant whitespace check; echo no-arg outputs empty line --- konabot/plugins/handle_text/base.py | 2 +- konabot/plugins/handle_text/handlers/unix_handlers.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/konabot/plugins/handle_text/base.py b/konabot/plugins/handle_text/base.py index d7da900..b9d23c3 100644 --- a/konabot/plugins/handle_text/base.py +++ b/konabot/plugins/handle_text/base.py @@ -189,7 +189,7 @@ class PipelineRunner: i += 1 continue - if c.isspace() or c in " ": + if c.isspace(): flush_word() i += 1 continue diff --git a/konabot/plugins/handle_text/handlers/unix_handlers.py b/konabot/plugins/handle_text/handlers/unix_handlers.py index f9ab5e7..1434e15 100644 --- a/konabot/plugins/handle_text/handlers/unix_handlers.py +++ b/konabot/plugins/handle_text/handlers/unix_handlers.py @@ -14,8 +14,7 @@ class THEcho(TextHandler): self, env: TextHandlerEnvironment, istream: str | None, args: list[str] ) -> TextHandleResult: # echo 不读 stdin,只输出参数(Unix 语义) - if len(args) == 0: - return TextHandleResult(1, "请在 echo 后面添加需要输出的文本") + # 无参数时输出空行(与 Unix echo 行为一致) return TextHandleResult(0, "\n".join(args))