comate-cli 0.3.7__tar.gz → 0.3.9__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.3.7 → comate_cli-0.3.9}/PKG-INFO +1 -2
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/app.py +1 -1
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/event_renderer.py +23 -3
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/preflight.py +2 -2
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui.py +7 -7
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/render_panels.py +11 -4
- {comate_cli-0.3.7 → comate_cli-0.3.9}/pyproject.toml +1 -2
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_completion_status_panel.py +2 -2
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_event_renderer.py +12 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_task_panel_format.py +3 -3
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_task_panel_rendering.py +1 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/uv.lock +2 -4
- {comate_cli-0.3.7 → comate_cli-0.3.9}/.gitignore +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/README.md +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/__init__.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/__main__.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/main.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/mcp_cli.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/__init__.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/animations.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/assistant_render.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/codenames.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/custom_slash_commands.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/env_utils.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/error_display.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/fragment_utils.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/history_printer.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/input_geometry.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/layout_coordinator.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/logging_adapter.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/logo.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/markdown_render.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/mention_completer.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/message_style.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/models.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/path_context_hint.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/question_view.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/resume_selector.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/rewind_store.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/rpc_protocol.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/rpc_stdio.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/selection_menu.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/session_view.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/slash_commands.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/startup.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/status_bar.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/text_effects.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tips.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tool_view.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/__init__.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/commands.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/history_sync.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/input_behavior.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/key_bindings.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/slash_command_registry.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/ui_mode.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/conftest.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_app_mcp_preload.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_app_preflight_gate.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_app_print_mode.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_app_shutdown.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_app_usage_line.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_cli_project_root.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_compact_command_semantics.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_completion_context_activation.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_context_command.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_custom_slash_commands.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_format_error.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_handle_error.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_history_printer.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_history_sync.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_input_behavior.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_input_history.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_interrupt_exit_semantics.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_layout_coordinator.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_logging_adapter.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_logo.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_main_args.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_mcp_cli.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_mcp_slash_command.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_mention_completer.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_path_context_hint.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_preflight.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_preflight_copilot.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_question_key_bindings.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_question_view.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_resume_selector.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_rewind_command_semantics.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_rewind_store.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_rpc_protocol.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_rpc_stdio_bridge.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_selection_menu.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_skills_slash_command.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_slash_argument_hint.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_slash_completer.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_slash_registry.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_status_bar.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_status_bar_transient.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_task_panel_key_bindings.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_task_poll.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_tool_view.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_tui_elapsed_status.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_tui_mcp_init_gate.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_tui_paste_placeholder.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_tui_split_invariance.py +0 -0
- {comate_cli-0.3.7 → comate_cli-0.3.9}/tests/test_update_check.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: comate-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.9
|
|
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,6 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Requires-Python: >=3.11
|
|
17
17
|
Requires-Dist: comate-agent-sdk<1.0.0,>=0.0.2
|
|
18
|
-
Requires-Dist: packaging>=25.0
|
|
19
18
|
Requires-Dist: prompt-toolkit>=3.0
|
|
20
19
|
Requires-Dist: rich>=14.0
|
|
21
20
|
Description-Content-Type: text/markdown
|
|
@@ -370,7 +370,7 @@ async def run(
|
|
|
370
370
|
if mgr and mgr.failed_servers:
|
|
371
371
|
aliases = [alias for alias, _ in mgr.failed_servers]
|
|
372
372
|
status_bar.show_transient(
|
|
373
|
-
f"
|
|
373
|
+
f"MCP: {', '.join(aliases)} unavailable",
|
|
374
374
|
duration_s=5.0,
|
|
375
375
|
)
|
|
376
376
|
|
|
@@ -112,6 +112,18 @@ def _task_sort_key(task: dict[str, Any]) -> tuple[int, int]:
|
|
|
112
112
|
return rank, numeric_id
|
|
113
113
|
|
|
114
114
|
|
|
115
|
+
def _task_stats_header(tasks: list[dict[str, Any]]) -> str:
|
|
116
|
+
"""生成 task 统计标题,如 '3 tasks (1 done, 2 open)'。"""
|
|
117
|
+
total = len(tasks)
|
|
118
|
+
done = sum(
|
|
119
|
+
1 for t in tasks
|
|
120
|
+
if str(t.get("status", "")).strip().lower() == "completed"
|
|
121
|
+
)
|
|
122
|
+
open_count = total - done
|
|
123
|
+
noun = "task" if total == 1 else "tasks"
|
|
124
|
+
return f"{total} {noun} ({done} done, {open_count} open)"
|
|
125
|
+
|
|
126
|
+
|
|
115
127
|
def _format_task_row(task: dict[str, Any]) -> str:
|
|
116
128
|
"""格式化单条 task 行。
|
|
117
129
|
|
|
@@ -295,6 +307,12 @@ class EventRenderer:
|
|
|
295
307
|
def has_active_todos(self) -> bool:
|
|
296
308
|
return self.has_active_tasks()
|
|
297
309
|
|
|
310
|
+
def has_in_progress_tasks(self) -> bool:
|
|
311
|
+
return any(
|
|
312
|
+
str(t.get("status", "")).strip().lower() == "in_progress"
|
|
313
|
+
for t in self._current_tasks
|
|
314
|
+
)
|
|
315
|
+
|
|
298
316
|
def compute_required_tool_panel_lines(self) -> int:
|
|
299
317
|
"""计算显示所有 running tools 所需的最小行数。"""
|
|
300
318
|
if not self._running_tools:
|
|
@@ -518,7 +536,9 @@ class EventRenderer:
|
|
|
518
536
|
if not tasks:
|
|
519
537
|
return []
|
|
520
538
|
|
|
521
|
-
header = str(self._current_task_title or "").strip()
|
|
539
|
+
header = str(self._current_task_title or "").strip()
|
|
540
|
+
if not header:
|
|
541
|
+
header = _task_stats_header(tasks)
|
|
522
542
|
lines: list[str] = [header]
|
|
523
543
|
for task in sorted(tasks, key=_task_sort_key):
|
|
524
544
|
lines.append(_format_task_row(task))
|
|
@@ -849,7 +869,7 @@ class EventRenderer:
|
|
|
849
869
|
return
|
|
850
870
|
|
|
851
871
|
all_completed = all(str(item.get("status", "")).strip().lower() == "completed" for item in normalized)
|
|
852
|
-
# 标题:显示 ID 最小的 in_progress task 的 subject
|
|
872
|
+
# 标题:显示 ID 最小的 in_progress task 的 subject,否则统计摘要
|
|
853
873
|
in_progress_tasks = [
|
|
854
874
|
t for t in normalized
|
|
855
875
|
if str(t.get("status", "")).strip().lower() == "in_progress"
|
|
@@ -858,7 +878,7 @@ class EventRenderer:
|
|
|
858
878
|
in_progress_tasks.sort(key=lambda t: int(t.get("id", 0)))
|
|
859
879
|
header = str(in_progress_tasks[0].get("subject", "")).strip() or "Tasks"
|
|
860
880
|
else:
|
|
861
|
-
header =
|
|
881
|
+
header = _task_stats_header(normalized)
|
|
862
882
|
if not all_completed:
|
|
863
883
|
if not self._current_tasks:
|
|
864
884
|
self._task_started_at_monotonic = time.monotonic()
|
|
@@ -188,7 +188,7 @@ PROVIDER_PRESETS: tuple[ProviderPreset, ...] = (
|
|
|
188
188
|
models={
|
|
189
189
|
"LOW": "glm-4.7",
|
|
190
190
|
"MID": "glm-4.7",
|
|
191
|
-
"HIGH": "glm-5",
|
|
191
|
+
"HIGH": "glm-5.1",
|
|
192
192
|
},
|
|
193
193
|
),
|
|
194
194
|
ProviderPreset(
|
|
@@ -200,7 +200,7 @@ PROVIDER_PRESETS: tuple[ProviderPreset, ...] = (
|
|
|
200
200
|
models={
|
|
201
201
|
"LOW": "glm-4.7",
|
|
202
202
|
"MID": "glm-4.7",
|
|
203
|
-
"HIGH": "glm-5",
|
|
203
|
+
"HIGH": "glm-5.1",
|
|
204
204
|
},
|
|
205
205
|
),
|
|
206
206
|
ProviderPreset(
|
|
@@ -1305,16 +1305,16 @@ class TerminalAgentTUI(
|
|
|
1305
1305
|
except asyncio.TimeoutError:
|
|
1306
1306
|
logger.debug(
|
|
1307
1307
|
"MCP init timed out after "
|
|
1308
|
-
f"{self._mcp_init_gate_timeout_s:.1f}s;
|
|
1308
|
+
f"{self._mcp_init_gate_timeout_s:.1f}s; continuing in background",
|
|
1309
1309
|
)
|
|
1310
1310
|
self._status_bar.show_transient(
|
|
1311
|
-
"
|
|
1312
|
-
|
|
1313
|
-
await self._cancel_task_with_timeout(
|
|
1314
|
-
init_task,
|
|
1315
|
-
timeout_s=self._mcp_init_cancel_timeout_s,
|
|
1316
|
-
task_name="terminal-mcp-init-worker",
|
|
1311
|
+
"MCP: init timed out, continuing in background…",
|
|
1312
|
+
duration_s=5.0,
|
|
1317
1313
|
)
|
|
1314
|
+
# Don't cancel init_task — let it complete in background.
|
|
1315
|
+
# asyncio.shield above already protects it from wait_for's
|
|
1316
|
+
# auto-cancellation. When it finishes, runtime._mcp_manager
|
|
1317
|
+
# will be set and tools become available for the next turn.
|
|
1318
1318
|
except asyncio.CancelledError:
|
|
1319
1319
|
await self._cancel_task_with_timeout(
|
|
1320
1320
|
init_task,
|
|
@@ -243,9 +243,8 @@ class RenderPanelsMixin:
|
|
|
243
243
|
return max_lines
|
|
244
244
|
|
|
245
245
|
def _should_hide_loading_panel(self) -> bool:
|
|
246
|
-
"""统一 loading
|
|
247
|
-
|
|
248
|
-
return False
|
|
246
|
+
"""统一 loading 显隐逻辑:当 Task 面板存在时始终隐藏 loading 区域,
|
|
247
|
+
loading 语义由 task title 的呼吸圆点承载。"""
|
|
249
248
|
return self._renderer.has_active_todos()
|
|
250
249
|
|
|
251
250
|
def _sync_todo_panel_state(self) -> None:
|
|
@@ -593,7 +592,15 @@ class RenderPanelsMixin:
|
|
|
593
592
|
title_elapsed_suffix = (
|
|
594
593
|
f" ({self._format_run_elapsed(elapsed)} • ctrl+c to interrupt)"
|
|
595
594
|
)
|
|
596
|
-
|
|
595
|
+
# busy 时在 title 前加呼吸圆点,承载 loading 语义
|
|
596
|
+
dot_prefix_width = 0
|
|
597
|
+
if self._busy:
|
|
598
|
+
dot_color = breathing_dot_color(self._loading_frame)
|
|
599
|
+
dot_glyph = breathing_dot_glyph(time.monotonic())
|
|
600
|
+
dot_style = f"fg:{dot_color} bold"
|
|
601
|
+
fragments.append((dot_style, f"{dot_glyph} "))
|
|
602
|
+
dot_prefix_width = 2 # glyph(1) + space(1)
|
|
603
|
+
title_budget = width - 1 - dot_prefix_width - get_cwidth(title_elapsed_suffix)
|
|
597
604
|
clipped_title = fit_single_line(line, max(title_budget, 8))
|
|
598
605
|
fragments.extend(self._todo_title_shimmer_fragments(clipped_title))
|
|
599
606
|
if title_elapsed_suffix:
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "comate-cli"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.9"
|
|
8
8
|
description = "Comate terminal CLI built on comate-agent-sdk"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -25,7 +25,6 @@ dependencies = [
|
|
|
25
25
|
"comate-agent-sdk>=0.0.2,<1.0.0",
|
|
26
26
|
"rich>=14.0",
|
|
27
27
|
"prompt-toolkit>=3.0",
|
|
28
|
-
"packaging>=25.0",
|
|
29
28
|
]
|
|
30
29
|
|
|
31
30
|
[project.urls]
|
|
@@ -248,10 +248,10 @@ class TestCompletionStatusPanel(unittest.TestCase):
|
|
|
248
248
|
self.assertTrue(tui._should_hide_loading_panel())
|
|
249
249
|
self.assertEqual(tui._loading_text(), [("", " ")])
|
|
250
250
|
|
|
251
|
-
# 有 todo 且有工具运行(subagent 执行中)→
|
|
251
|
+
# 有 todo 且有工具运行(subagent 执行中)→ 也隐藏,loading 语义由 task title 承载
|
|
252
252
|
tui._renderer.active_todos = True
|
|
253
253
|
tui._renderer.running_tools = True
|
|
254
|
-
self.
|
|
254
|
+
self.assertTrue(tui._should_hide_loading_panel())
|
|
255
255
|
|
|
256
256
|
# 无 todo,有工具运行 → 不隐藏
|
|
257
257
|
tui._renderer.active_todos = False
|
|
@@ -396,6 +396,18 @@ class TestEventRenderer(unittest.TestCase):
|
|
|
396
396
|
def test_task_completed_appends_summary_and_hides_panel(self) -> None:
|
|
397
397
|
renderer = EventRenderer()
|
|
398
398
|
renderer.start_turn()
|
|
399
|
+
# 先创建 pending tasks,使 _current_tasks 非空
|
|
400
|
+
renderer.handle_event(
|
|
401
|
+
TaskUpdatedEvent(
|
|
402
|
+
list_id="default",
|
|
403
|
+
tasks=[
|
|
404
|
+
{"id": "1", "subject": "a", "status": "pending", "open_blocked_by": []},
|
|
405
|
+
{"id": "2", "subject": "b", "status": "pending", "open_blocked_by": []},
|
|
406
|
+
],
|
|
407
|
+
)
|
|
408
|
+
)
|
|
409
|
+
self.assertTrue(renderer.has_active_todos())
|
|
410
|
+
# 全部完成后应写入 summary 并隐藏面板
|
|
399
411
|
renderer.handle_event(
|
|
400
412
|
TaskUpdatedEvent(
|
|
401
413
|
list_id="default",
|
|
@@ -76,14 +76,14 @@ def test_title_shows_smallest_id_in_progress():
|
|
|
76
76
|
assert renderer._current_task_title == "Task A"
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
def
|
|
79
|
+
def test_title_falls_back_to_stats_when_no_in_progress():
|
|
80
80
|
renderer = _make_renderer_for_title_test()
|
|
81
81
|
tasks = [
|
|
82
82
|
{"id": "1", "subject": "Set up project", "status": "pending", "open_blocked_by": []},
|
|
83
83
|
{"id": "2", "subject": "Write tests", "status": "pending", "open_blocked_by": []},
|
|
84
84
|
]
|
|
85
85
|
renderer._update_tasks(tasks, list_id="default")
|
|
86
|
-
assert renderer._current_task_title == "
|
|
86
|
+
assert renderer._current_task_title == "2 tasks (0 done, 2 open)"
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def test_title_ignores_list_id():
|
|
@@ -92,5 +92,5 @@ def test_title_ignores_list_id():
|
|
|
92
92
|
{"id": "1", "subject": "Task A", "status": "pending", "open_blocked_by": []},
|
|
93
93
|
]
|
|
94
94
|
renderer._update_tasks(tasks, list_id="team-alpha")
|
|
95
|
-
assert renderer._current_task_title == "
|
|
95
|
+
assert renderer._current_task_title == "1 task (0 done, 1 open)"
|
|
96
96
|
assert "team-alpha" not in (renderer._current_task_title or "")
|
|
@@ -364,7 +364,7 @@ wheels = [
|
|
|
364
364
|
|
|
365
365
|
[[package]]
|
|
366
366
|
name = "comate-agent-sdk"
|
|
367
|
-
version = "0.3.
|
|
367
|
+
version = "0.3.8"
|
|
368
368
|
source = { editable = "../../" }
|
|
369
369
|
dependencies = [
|
|
370
370
|
{ name = "aiohttp" },
|
|
@@ -429,11 +429,10 @@ dev = [
|
|
|
429
429
|
|
|
430
430
|
[[package]]
|
|
431
431
|
name = "comate-cli"
|
|
432
|
-
version = "0.3.
|
|
432
|
+
version = "0.3.8"
|
|
433
433
|
source = { editable = "." }
|
|
434
434
|
dependencies = [
|
|
435
435
|
{ name = "comate-agent-sdk" },
|
|
436
|
-
{ name = "packaging" },
|
|
437
436
|
{ name = "prompt-toolkit" },
|
|
438
437
|
{ name = "rich" },
|
|
439
438
|
]
|
|
@@ -446,7 +445,6 @@ dev = [
|
|
|
446
445
|
[package.metadata]
|
|
447
446
|
requires-dist = [
|
|
448
447
|
{ name = "comate-agent-sdk", editable = "../../" },
|
|
449
|
-
{ name = "packaging", specifier = ">=25.0" },
|
|
450
448
|
{ name = "prompt-toolkit", specifier = ">=3.0" },
|
|
451
449
|
{ name = "rich", specifier = ">=14.0" },
|
|
452
450
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{comate_cli-0.3.7 → comate_cli-0.3.9}/comate_cli/terminal_agent/tui_parts/slash_command_registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|