comate-cli 0.6.2__tar.gz → 0.7.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/.gitignore +3 -0
- comate_cli-0.7.0a1/CHANGELOG.md +22 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/PKG-INFO +2 -2
- comate_cli-0.7.0a1/bash-exit-code-green-dot-bug.md +140 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/main.py +4 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/event_renderer.py +157 -315
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/history_printer.py +18 -28
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/logging_adapter.py +1 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/mention_completer.py +8 -2
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/models.py +3 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/tabs/errors_tab.py +2 -11
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/preflight.py +10 -333
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/question_view.py +24 -0
- comate_cli-0.7.0a1/comate_cli/terminal_agent/resume_picker.py +613 -0
- comate_cli-0.7.0a1/comate_cli/terminal_agent/resume_preview.py +140 -0
- comate_cli-0.7.0a1/comate_cli/terminal_agent/resume_selector.py +87 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/slash_commands.py +6 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tips.py +11 -0
- comate_cli-0.7.0a1/comate_cli/terminal_agent/tool_result_formatters.py +774 -0
- comate_cli-0.7.0a1/comate_cli/terminal_agent/tool_result_store.py +75 -0
- comate_cli-0.7.0a1/comate_cli/terminal_agent/tool_result_viewer.py +214 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tool_view.py +22 -4
- comate_cli-0.7.0a1/comate_cli/terminal_agent/transcript_viewer.py +371 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui.py +142 -105
- comate_cli-0.7.0a1/comate_cli/terminal_agent/tui_parts/btw_view.py +426 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/commands.py +243 -138
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/history_sync.py +2 -1
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/input_behavior.py +20 -1
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/key_bindings.py +88 -28
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/mcp_connecting_view.py +10 -2
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/render_panels.py +10 -99
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/ui_mode.py +1 -0
- comate_cli-0.7.0a1/docs/hooks.md +1047 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/pyproject.toml +7 -2
- comate_cli-0.7.0a1/tests/test_btw_slash_command.py +554 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_completion_status_panel.py +62 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_discover_tab.py +27 -20
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_event_renderer.py +383 -30
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_event_renderer_log_boundary.py +21 -13
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_event_renderer_log_queue.py +37 -12
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_handle_error.py +10 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_history_printer.py +14 -2
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_history_printer_log.py +54 -30
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_history_sync.py +3 -1
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_installed_tab.py +11 -7
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_interrupt_exit_semantics.py +29 -3
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_logging_adapter.py +1 -1
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_main_args.py +16 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_mcp_cli.py +2 -2
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_mcp_slash_command.py +229 -1
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_mention_completer.py +175 -2
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_plugin_tui_components.py +5 -11
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_preflight.py +14 -19
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_preflight_copilot.py +2 -2
- comate_cli-0.7.0a1/tests/test_resume_picker.py +429 -0
- comate_cli-0.7.0a1/tests/test_resume_preview.py +134 -0
- comate_cli-0.7.0a1/tests/test_resume_selector.py +109 -0
- comate_cli-0.7.0a1/tests/test_rewind_command_semantics.py +200 -0
- comate_cli-0.7.0a1/tests/test_session_query_token_summary.py +127 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_task_panel_key_bindings.py +0 -2
- comate_cli-0.7.0a1/tests/test_tool_result_formatters.py +512 -0
- comate_cli-0.7.0a1/tests/test_tool_result_store.py +145 -0
- comate_cli-0.7.0a1/tests/test_tool_result_viewer.py +135 -0
- comate_cli-0.7.0a1/tests/test_tool_result_viewer_key_bindings.py +97 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tool_view.py +22 -1
- comate_cli-0.7.0a1/tests/test_transcript_viewer.py +147 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_esc_queue.py +0 -3
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_team_messages.py +0 -2
- comate_cli-0.7.0a1/tests/test_tui_tool_result_registry_lifecycle.py +96 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/uv.lock +36 -3
- comate_cli-0.6.2/comate_cli/terminal_agent/resume_selector.py +0 -284
- comate_cli-0.6.2/comate_cli/terminal_agent/rewind_store.py +0 -744
- comate_cli-0.6.2/comate_cli/terminal_agent/session_view.py +0 -100
- comate_cli-0.6.2/tests/test_resume_selector.py +0 -167
- comate_cli-0.6.2/tests/test_rewind_command_semantics.py +0 -129
- comate_cli-0.6.2/tests/test_rewind_store.py +0 -309
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/README.md +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/__init__.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/__main__.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/mcp_cli.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/__init__.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/animations.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/app.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/assistant_render.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/codenames.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/custom_slash_commands.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/env_utils.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/error_display.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/figures.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/fragment_utils.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/input_geometry.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/layout_coordinator.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/logo.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/markdown_render.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/message_style.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/path_context_hint.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/__init__.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/components/__init__.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/components/detail_view.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/components/plugin_list.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/components/search_box.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/components/tab_bar.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/marketplace_install_view.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/plugin_picker.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/tabs/__init__.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/tabs/discover_tab.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/tabs/installed_tab.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/plugins/tabs/marketplaces_tab.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/rpc_protocol.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/rpc_stdio.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/selection_menu.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/startup.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/status_bar.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/text_effects.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/__init__.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/comate_cli/terminal_agent/tui_parts/slash_command_registry.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/docs/superpowers/plans/2026-04-03-phrase-shuffle.md +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/docs/superpowers/specs/2026-04-01-conditional-diff-subtitle-design.md +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/docs/superpowers/specs/2026-04-03-phrase-shuffle-design.md +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/conftest.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_animator_shuffle.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_app_mcp_preload.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_app_preflight_gate.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_app_print_mode.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_app_shutdown.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_app_usage_line.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_cli_project_root.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_compact_command_semantics.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_completion_context_activation.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_context_command.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_custom_slash_commands.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_errors_tab.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_event_renderer_boundary.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_event_renderer_e2e.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_event_renderer_streaming.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_format_error.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_input_behavior.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_input_history.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_layout_coordinator.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_logo.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_markdown_render.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_marketplaces_tab.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_path_context_hint.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_plugin_slash_commands.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_question_key_bindings.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_question_view.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_rpc_protocol.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_rpc_stdio_bridge.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_selection_menu.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_skills_slash_command.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_slash_argument_hint.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_slash_completer.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_slash_registry.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_status_bar.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_status_bar_transient.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_task_panel_format.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_task_panel_rendering.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_task_poll.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_elapsed_status.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_mcp_init_gate.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_paste_placeholder.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_queue_preview.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_queue_sdk_source.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_tui_split_invariance.py +0 -0
- {comate_cli-0.6.2 → comate_cli-0.7.0a1}/tests/test_update_check.py +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.7.0a1 - 2026-05-19 (alpha)
|
|
4
|
+
|
|
5
|
+
> 这是一个 **alpha 预发布版本**,用于内部 / 早期测试。
|
|
6
|
+
> `pip install comate-cli` 默认不会安装到本版本,需要显式 `pip install comate-cli==0.7.0a1` 或 `pip install --pre comate-cli`。
|
|
7
|
+
|
|
8
|
+
### Breaking Changes
|
|
9
|
+
|
|
10
|
+
- 依赖 `comate-agent-sdk>=0.8.0a1`,与旧 SDK 不兼容。
|
|
11
|
+
- 旧版本生成的 resume jsonl / context 快照不保证可以正常回放,**建议从空 session 重新开始**。
|
|
12
|
+
|
|
13
|
+
### 累积变更
|
|
14
|
+
|
|
15
|
+
自 0.6.x 起累积大量 TUI 与会话能力改进,涵盖:
|
|
16
|
+
|
|
17
|
+
- Resume picker 重做:搜索、跨 cwd 切换、预览模式、视觉抛光
|
|
18
|
+
- Auto compact 期间显式提示 `Compacting context`
|
|
19
|
+
- Team / subagent 事件透出与渲染统一
|
|
20
|
+
- 与 SDK 0.8.0a1 配套的 tool envelope / token 账本展示
|
|
21
|
+
|
|
22
|
+
详细变更请参考 git log。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: comate-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0a1
|
|
4
4
|
Summary: Comate terminal CLI built on comate-agent-sdk
|
|
5
5
|
Project-URL: Homepage, https://github.com/AndyLee1024/agent-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/AndyLee1024/agent-sdk
|
|
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Requires-Python: >=3.11
|
|
17
17
|
Requires-Dist: charset-normalizer==3.4.7
|
|
18
|
-
Requires-Dist: comate-agent-sdk<
|
|
18
|
+
Requires-Dist: comate-agent-sdk<0.9.0,>=0.8.0a1
|
|
19
19
|
Requires-Dist: concurrent-log-handler>=0.9.25
|
|
20
20
|
Requires-Dist: curl-cffi==0.13.0
|
|
21
21
|
Requires-Dist: packaging>=21.0
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Bug 分析:Bash 工具 exit code 非零时仍显示绿色圆点
|
|
2
|
+
|
|
3
|
+
## 现象
|
|
4
|
+
|
|
5
|
+
在 `/plugin` 页面 scrollback 中,Bash 工具执行失败(exit code != 0)时,工具结果行显示的是**绿色圆点**(代表成功),而不是**红色叉号**(代表失败)。
|
|
6
|
+
|
|
7
|
+
用户日志示例:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
● Bash(timeout=30s command=cd ... && python -m pytest ...)
|
|
11
|
+
⎿ Exit code 1
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
这里 `●` 是绿色圆点,`Exit code 1` 明确表示失败。
|
|
15
|
+
|
|
16
|
+
## 根因
|
|
17
|
+
|
|
18
|
+
Bug 在 **SDK 层** `comate_agent_sdk/system_tools/tools/bash.py`,不在 comate_cli。
|
|
19
|
+
|
|
20
|
+
Bash 工具在命令执行完毕后构造返回 envelope 时,只检查了三种异常情况:
|
|
21
|
+
- `overflowed` → `err("OUTPUT_OVERFLOW", ...)` — ok=False
|
|
22
|
+
- `timed_out` → `err("TIMEOUT", ...)` — ok=False
|
|
23
|
+
- `interrupted` → `err("INTERRUPTED", ...)` — ok=False
|
|
24
|
+
- **否则** → `return ok(data=data, meta=exec_meta)` — **ok=True**
|
|
25
|
+
|
|
26
|
+
当 `exit_code=1`(命令执行失败)时,上述三个条件都不满足,envelope 的 `"ok"` 字段被设为 `True`。
|
|
27
|
+
|
|
28
|
+
## 完整调用链(6 层)
|
|
29
|
+
|
|
30
|
+
### 第 1 层:Bash 工具 envelope 构造(bug 所在)
|
|
31
|
+
|
|
32
|
+
**文件**:`comate_agent_sdk/system_tools/tools/bash.py`(约第 404-431 行)
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
# 当前逻辑(有 bug)
|
|
36
|
+
if overflowed:
|
|
37
|
+
return err("OUTPUT_OVERFLOW", ...)
|
|
38
|
+
if timed_out:
|
|
39
|
+
return err("TIMEOUT", ...)
|
|
40
|
+
if interrupted:
|
|
41
|
+
return err("INTERRUPTED", ...)
|
|
42
|
+
return ok(data=data, meta=exec_meta) # ← exit_code=1 时也走这里
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 第 2 层:OutputFormatter 判定 status
|
|
46
|
+
|
|
47
|
+
**文件**:`comate_agent_sdk/system_tools/output_formatter.py`(第 70-82 行)
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
if not bool(result_dict.get("ok", False)): # ok=True → 不进入 error 分支
|
|
51
|
+
return format_error(...)
|
|
52
|
+
|
|
53
|
+
formatter = _TOOL_FORMATTERS.get(tool_name, format_generic_ok)
|
|
54
|
+
return formatter(...) # → format_bash_result → status="ok"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
因为 `ok=True`,走的是成功格式化路径,`status` 被设为 `"ok"`。
|
|
58
|
+
|
|
59
|
+
### 第 3 层:ToolMessage 的 is_error
|
|
60
|
+
|
|
61
|
+
**文件**:`comate_agent_sdk/agent/tool_exec.py`(第 342 行)
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
is_error = formatted.meta.status == "error" # "ok" != "error" → is_error=False
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 第 4 层:ToolResultEvent 传递给 CLI
|
|
68
|
+
|
|
69
|
+
**文件**:`comate_agent_sdk/agent/runner_engine/execution/tool_execution.py`(第 843 行)
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
yield ToolResultEvent(
|
|
73
|
+
...
|
|
74
|
+
is_error=tool_result.is_error, # False
|
|
75
|
+
...
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 第 5 层:EventRenderer 设置 severity
|
|
80
|
+
|
|
81
|
+
**文件**:`comate_cli/comate_cli/terminal_agent/event_renderer.py`(第 1231 行)
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
sev = "error" if is_error else "info" # is_error=False → severity="info"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
然后写入 `HistoryEntry(severity="info")`。
|
|
88
|
+
|
|
89
|
+
### 第 6 层:history_printer 渲染颜色
|
|
90
|
+
|
|
91
|
+
**文件**:`comate_cli/comate_cli/terminal_agent/history_printer.py`(第 244-246 行)
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
if entry.entry_type == "tool_result":
|
|
95
|
+
prefix_char = HEAVY_MULTIPLICATION if entry.severity == "error" else BLACK_CIRCLE
|
|
96
|
+
prefix_style = "bold red" if entry.severity == "error" else "bold green"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`severity="info"` → 绿色圆点(`BLACK_CIRCLE` + `bold green`)。
|
|
100
|
+
|
|
101
|
+
## 修复建议
|
|
102
|
+
|
|
103
|
+
在 SDK 的 `comate_agent_sdk/system_tools/tools/bash.py` 中,在最终的 `return ok(...)` 之前增加对 exit_code 的检查:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
if overflowed:
|
|
107
|
+
return err("OUTPUT_OVERFLOW", ...)
|
|
108
|
+
if timed_out:
|
|
109
|
+
return err("TIMEOUT", ...)
|
|
110
|
+
if interrupted:
|
|
111
|
+
return err("INTERRUPTED", ...)
|
|
112
|
+
|
|
113
|
+
# 新增:exit_code 非零视为命令执行失败
|
|
114
|
+
if exit_code != 0:
|
|
115
|
+
return err(
|
|
116
|
+
"EXIT_CODE_NON_ZERO",
|
|
117
|
+
f"Command exited with non-zero code: {exit_code}",
|
|
118
|
+
data=data,
|
|
119
|
+
retryable=True,
|
|
120
|
+
meta=exec_meta,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
return ok(data=data, meta=exec_meta)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### comate_cli 侧的防御性补丁(可选)
|
|
127
|
+
|
|
128
|
+
如果 SDK 修复周期较长,可以在 comate_cli 的 `event_renderer.py` 的 `ToolResultEvent` 处理分支中增加防御逻辑:当 `is_error=False` 但 `output` 是 `BashOutput` 且 `exit_code != 0` 时,强制将 `is_error` 修正为 `True`。但这种方式侵入性大且绕过了 SDK 的语义契约,建议仅在无法及时修改 SDK 时使用。
|
|
129
|
+
|
|
130
|
+
## 涉及文件清单
|
|
131
|
+
|
|
132
|
+
| 层级 | 文件 | 说明 |
|
|
133
|
+
|------|------|------|
|
|
134
|
+
| SDK | `comate_agent_sdk/system_tools/tools/bash.py` | **bug 根源**,envelope 构造 |
|
|
135
|
+
| SDK | `comate_agent_sdk/system_tools/tool_result.py` | `ok()` / `err()` envelope 工厂 |
|
|
136
|
+
| SDK | `comate_agent_sdk/system_tools/output_formatter.py` | `OutputFormatter.format()` 判定 status |
|
|
137
|
+
| SDK | `comate_agent_sdk/agent/tool_exec.py` | `_build_tool_result_message()` 设置 is_error |
|
|
138
|
+
| SDK | `comate_agent_sdk/agent/runner_engine/execution/tool_execution.py` | 构造 `ToolResultEvent` |
|
|
139
|
+
| CLI | `comate_cli/terminal_agent/event_renderer.py` | `handle_event()` 设置 HistoryEntry severity |
|
|
140
|
+
| CLI | `comate_cli/terminal_agent/history_printer.py` | `render_history_group()` 渲染颜色 |
|
|
@@ -153,6 +153,10 @@ def _parse_args(argv: list[str]) -> tuple[bool, str | None, bool, str | None]:
|
|
|
153
153
|
def main(argv: list[str] | None = None) -> None:
|
|
154
154
|
run_argv = list(argv) if argv is not None else sys.argv[1:]
|
|
155
155
|
|
|
156
|
+
if run_argv in (["--help"], ["-h"]):
|
|
157
|
+
sys.stdout.write(f"{_usage_text()}\n")
|
|
158
|
+
return
|
|
159
|
+
|
|
156
160
|
if run_argv and run_argv[0] == "mcp":
|
|
157
161
|
from comate_cli.mcp_cli import McpCliError, run_mcp_command
|
|
158
162
|
|