comate-cli 0.1.0__tar.gz → 0.1.3__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.1.0 → comate_cli-0.1.3}/PKG-INFO +2 -2
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/main.py +48 -8
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/app.py +131 -15
- comate_cli-0.1.3/comate_cli/terminal_agent/preflight.py +1054 -0
- comate_cli-0.1.3/comate_cli/terminal_agent/resume_selector.py +288 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/rpc_stdio.py +133 -53
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/selection_menu.py +87 -4
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui.py +76 -10
- {comate_cli-0.1.0 → comate_cli-0.1.3}/pyproject.toml +2 -2
- comate_cli-0.1.3/tests/conftest.py +14 -0
- comate_cli-0.1.3/tests/test_app_preflight_gate.py +32 -0
- comate_cli-0.1.3/tests/test_app_shutdown.py +86 -0
- comate_cli-0.1.3/tests/test_app_usage_line.py +60 -0
- comate_cli-0.1.3/tests/test_cli_project_root.py +31 -0
- comate_cli-0.1.3/tests/test_compact_command_semantics.py +92 -0
- comate_cli-0.1.3/tests/test_completion_status_panel.py +209 -0
- comate_cli-0.1.3/tests/test_context_command.py +94 -0
- comate_cli-0.1.3/tests/test_event_renderer.py +401 -0
- comate_cli-0.1.3/tests/test_history_sync.py +156 -0
- comate_cli-0.1.3/tests/test_input_behavior.py +55 -0
- comate_cli-0.1.3/tests/test_layout_coordinator.py +76 -0
- comate_cli-0.1.3/tests/test_main_args.py +46 -0
- comate_cli-0.1.3/tests/test_mention_completer.py +69 -0
- comate_cli-0.1.3/tests/test_preflight.py +412 -0
- comate_cli-0.1.3/tests/test_question_view.py +423 -0
- comate_cli-0.1.3/tests/test_resume_selector.py +167 -0
- comate_cli-0.1.3/tests/test_rewind_command_semantics.py +129 -0
- comate_cli-0.1.3/tests/test_rewind_store.py +195 -0
- comate_cli-0.1.3/tests/test_rpc_protocol.py +52 -0
- comate_cli-0.1.3/tests/test_rpc_stdio_bridge.py +123 -0
- comate_cli-0.1.3/tests/test_selection_menu.py +103 -0
- comate_cli-0.1.3/tests/test_slash_completer.py +59 -0
- comate_cli-0.1.3/tests/test_slash_registry.py +49 -0
- comate_cli-0.1.3/tests/test_status_bar.py +87 -0
- comate_cli-0.1.3/tests/test_tool_view.py +64 -0
- comate_cli-0.1.3/tests/test_tui_mcp_init_gate.py +88 -0
- comate_cli-0.1.3/tests/test_tui_paste_placeholder.py +364 -0
- comate_cli-0.1.3/tests/test_tui_split_invariance.py +68 -0
- comate_cli-0.1.3/uv.lock +2208 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/.gitignore +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/README.md +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/__init__.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/__main__.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/__init__.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/animations.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/assistant_render.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/env_utils.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/error_display.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/event_renderer.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/fragment_utils.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/history_printer.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/input_geometry.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/layout_coordinator.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/logging_adapter.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/logo.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/markdown_render.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/mention_completer.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/message_style.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/models.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/question_view.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/rewind_store.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/rpc_protocol.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/session_view.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/slash_commands.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/startup.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/status_bar.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/text_effects.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tool_view.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/__init__.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/commands.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/history_sync.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/input_behavior.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/key_bindings.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/render_panels.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/slash_command_registry.py +0 -0
- {comate_cli-0.1.0 → comate_cli-0.1.3}/comate_cli/terminal_agent/tui_parts/ui_mode.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: comate-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
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
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Requires-Python: >=3.11
|
|
17
|
-
Requires-Dist: comate-agent-sdk<1.0.0,>=0.0.
|
|
17
|
+
Requires-Dist: comate-agent-sdk<1.0.0,>=0.0.2
|
|
18
18
|
Requires-Dist: prompt-toolkit>=3.0
|
|
19
19
|
Requires-Dist: rich>=14.0
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
@@ -12,6 +12,10 @@ import threading
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
class _ArgumentError(ValueError):
|
|
16
|
+
"""Raised when CLI arguments are invalid."""
|
|
17
|
+
|
|
18
|
+
|
|
15
19
|
class _TerminalStateGuard:
|
|
16
20
|
"""Best-effort tty restore guard for abnormal shutdown paths."""
|
|
17
21
|
|
|
@@ -88,18 +92,43 @@ class _ShutdownNoiseGuard:
|
|
|
88
92
|
self._orig_unraisablehook(unraisable)
|
|
89
93
|
|
|
90
94
|
|
|
91
|
-
def
|
|
95
|
+
def _usage_text() -> str:
|
|
96
|
+
return (
|
|
97
|
+
"Usage:\n"
|
|
98
|
+
" comate [--rpc-stdio]\n"
|
|
99
|
+
" comate resume [<session_id>] [--rpc-stdio]"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _parse_args(argv: list[str]) -> tuple[bool, str | None, bool]:
|
|
92
104
|
rpc_stdio = False
|
|
93
|
-
|
|
105
|
+
positionals: list[str] = []
|
|
94
106
|
for arg in argv:
|
|
95
107
|
if arg == "--rpc-stdio":
|
|
96
108
|
rpc_stdio = True
|
|
97
109
|
continue
|
|
98
110
|
if arg.startswith("-"):
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
raise _ArgumentError(f"Unknown option: {arg}")
|
|
112
|
+
positionals.append(arg)
|
|
113
|
+
|
|
114
|
+
if not positionals:
|
|
115
|
+
return rpc_stdio, None, False
|
|
116
|
+
|
|
117
|
+
command = positionals[0]
|
|
118
|
+
if command != "resume":
|
|
119
|
+
raise _ArgumentError(f"Unknown command: {command}")
|
|
120
|
+
|
|
121
|
+
if len(positionals) == 1:
|
|
122
|
+
if rpc_stdio:
|
|
123
|
+
raise _ArgumentError(
|
|
124
|
+
"resume without <session_id> does not support --rpc-stdio"
|
|
125
|
+
)
|
|
126
|
+
return rpc_stdio, None, True
|
|
127
|
+
|
|
128
|
+
if len(positionals) == 2:
|
|
129
|
+
return rpc_stdio, positionals[1], False
|
|
130
|
+
|
|
131
|
+
raise _ArgumentError("resume accepts at most one <session_id>")
|
|
103
132
|
|
|
104
133
|
|
|
105
134
|
def main(argv: list[str] | None = None) -> None:
|
|
@@ -114,9 +143,20 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
114
143
|
|
|
115
144
|
from comate_cli.terminal_agent.app import run
|
|
116
145
|
|
|
117
|
-
rpc_stdio, session_id = _parse_args(run_argv)
|
|
118
146
|
try:
|
|
119
|
-
|
|
147
|
+
rpc_stdio, resume_session_id, resume_select = _parse_args(run_argv)
|
|
148
|
+
except _ArgumentError as exc:
|
|
149
|
+
sys.stderr.write(f"{exc}\n{_usage_text()}\n")
|
|
150
|
+
raise SystemExit(2) from exc
|
|
151
|
+
|
|
152
|
+
try:
|
|
153
|
+
asyncio.run(
|
|
154
|
+
run(
|
|
155
|
+
rpc_stdio=rpc_stdio,
|
|
156
|
+
resume_session_id=resume_session_id,
|
|
157
|
+
resume_select=resume_select,
|
|
158
|
+
)
|
|
159
|
+
)
|
|
120
160
|
except KeyboardInterrupt:
|
|
121
161
|
noise_guard.begin_shutdown()
|
|
122
162
|
finally:
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import importlib.metadata
|
|
5
|
+
import locale
|
|
4
6
|
import logging
|
|
5
7
|
import os
|
|
6
8
|
import signal
|
|
7
|
-
import sys
|
|
8
9
|
import threading
|
|
9
10
|
import time
|
|
10
11
|
from collections.abc import Iterator
|
|
@@ -20,6 +21,8 @@ from comate_agent_sdk.tools import tool
|
|
|
20
21
|
|
|
21
22
|
from comate_cli.terminal_agent.event_renderer import EventRenderer
|
|
22
23
|
from comate_cli.terminal_agent.logo import print_logo
|
|
24
|
+
from comate_cli.terminal_agent.preflight import run_preflight_if_needed
|
|
25
|
+
from comate_cli.terminal_agent.resume_selector import select_resume_session_id
|
|
23
26
|
from comate_cli.terminal_agent.rpc_stdio import StdioRPCBridge
|
|
24
27
|
from comate_cli.terminal_agent.status_bar import StatusBar
|
|
25
28
|
from comate_cli.terminal_agent.tui import TerminalAgentTUI
|
|
@@ -28,6 +31,72 @@ console = Console()
|
|
|
28
31
|
logger = logging.getLogger(__name__)
|
|
29
32
|
|
|
30
33
|
|
|
34
|
+
def _resolve_cli_project_root() -> Path:
|
|
35
|
+
"""Resolve project root: always the current working directory."""
|
|
36
|
+
return Path.cwd().expanduser().resolve()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _is_chinese_locale() -> bool:
|
|
40
|
+
"""判断当前系统 locale 是否为中文环境。"""
|
|
41
|
+
# zh_tw(台湾)和 zh_hk(香港)不走清华镜像源
|
|
42
|
+
_CN_PREFIXES = ("zh_cn", "zh_sg", "zh_mo", "zh_hans")
|
|
43
|
+
for env_var in ("LC_ALL", "LC_MESSAGES", "LANG", "LANGUAGE"):
|
|
44
|
+
val = os.environ.get(env_var, "").lower()
|
|
45
|
+
if any(val.startswith(p) for p in _CN_PREFIXES):
|
|
46
|
+
return True
|
|
47
|
+
try:
|
|
48
|
+
lang, _ = locale.getlocale()
|
|
49
|
+
if lang:
|
|
50
|
+
lang_lower = lang.lower()
|
|
51
|
+
if any(lang_lower.startswith(p) for p in _CN_PREFIXES):
|
|
52
|
+
return True
|
|
53
|
+
except Exception:
|
|
54
|
+
pass
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def _check_update() -> str | None:
|
|
59
|
+
"""异步检查 comate-cli 是否有新版本,返回提示字符串或 None。
|
|
60
|
+
|
|
61
|
+
中文 locale 自动使用清华镜像源,其余使用官方 PyPI。
|
|
62
|
+
"""
|
|
63
|
+
package = "comate-cli"
|
|
64
|
+
try:
|
|
65
|
+
current = importlib.metadata.version(package)
|
|
66
|
+
except importlib.metadata.PackageNotFoundError:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
if _is_chinese_locale():
|
|
70
|
+
url = f"https://pypi.tuna.tsinghua.edu.cn/pypi/{package}/json"
|
|
71
|
+
source_label = "tuna"
|
|
72
|
+
else:
|
|
73
|
+
url = f"https://pypi.org/pypi/{package}/json"
|
|
74
|
+
source_label = "pypi"
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
import httpx
|
|
78
|
+
async with httpx.AsyncClient(timeout=3.0) as client:
|
|
79
|
+
resp = await client.get(url)
|
|
80
|
+
resp.raise_for_status()
|
|
81
|
+
latest = resp.json()["info"]["version"]
|
|
82
|
+
except Exception:
|
|
83
|
+
logger.debug(f"update check failed (source={source_label})", exc_info=True)
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
from importlib.metadata import version as _v
|
|
88
|
+
from packaging.version import Version
|
|
89
|
+
if Version(latest) > Version(current):
|
|
90
|
+
return (
|
|
91
|
+
f"[dim]💡 New version available: [bold cyan]{latest}[/] "
|
|
92
|
+
f"(current: {current}) "
|
|
93
|
+
f"Run [bold]uv tool upgrade {package}[/] to upgrade.[/]"
|
|
94
|
+
)
|
|
95
|
+
except Exception:
|
|
96
|
+
pass
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
|
|
31
100
|
def _flush_langfuse_if_configured() -> None:
|
|
32
101
|
"""Flush Langfuse pending events synchronously to prevent atexit thread-join errors on Ctrl+C."""
|
|
33
102
|
try:
|
|
@@ -108,9 +177,10 @@ async def add(a: int, b: int) -> int:
|
|
|
108
177
|
return a + b
|
|
109
178
|
|
|
110
179
|
|
|
111
|
-
def _build_agent() -> Agent:
|
|
180
|
+
def _build_agent(*, project_root: Path | None = None) -> Agent:
|
|
112
181
|
context7_api_key = os.getenv("CONTEXT7_API_KEY")
|
|
113
182
|
exa_api_key = os.getenv("EXA_API_KEY")
|
|
183
|
+
resolved_project_root = project_root or _resolve_cli_project_root()
|
|
114
184
|
|
|
115
185
|
exa_tools = (
|
|
116
186
|
"web_search_exa,"
|
|
@@ -127,6 +197,7 @@ def _build_agent() -> Agent:
|
|
|
127
197
|
return Agent(
|
|
128
198
|
config=AgentConfig(
|
|
129
199
|
role="software_engineering",
|
|
200
|
+
project_root=resolved_project_root,
|
|
130
201
|
env_options=EnvOptions(system_env=True, git_env=True),
|
|
131
202
|
use_streaming_task=True, # 启用流式 Task(实时显示嵌套工具调用)
|
|
132
203
|
mcp_servers={
|
|
@@ -150,10 +221,12 @@ def _build_agent() -> Agent:
|
|
|
150
221
|
)
|
|
151
222
|
|
|
152
223
|
|
|
153
|
-
def _resolve_session(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
224
|
+
def _resolve_session(
|
|
225
|
+
agent: Agent, resume_session_id: str | None, *, cwd: Path | None = None
|
|
226
|
+
) -> tuple[ChatSession, str]:
|
|
227
|
+
if resume_session_id:
|
|
228
|
+
return ChatSession.resume(agent, session_id=resume_session_id, cwd=cwd), "resume"
|
|
229
|
+
return ChatSession(agent, cwd=cwd), "new"
|
|
157
230
|
|
|
158
231
|
|
|
159
232
|
def _format_exit_usage_line(usage: object) -> str:
|
|
@@ -175,6 +248,15 @@ def _format_exit_usage_line(usage: object) -> str:
|
|
|
175
248
|
)
|
|
176
249
|
|
|
177
250
|
|
|
251
|
+
def _format_resume_hint(session_id: str | None) -> str | None:
|
|
252
|
+
if not session_id:
|
|
253
|
+
return None
|
|
254
|
+
return (
|
|
255
|
+
f"[dim]To continue this session, run [bold cyan]comate resume "
|
|
256
|
+
f"{session_id}[/][/]"
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
178
260
|
async def _preload_mcp_in_tui(session: ChatSession, renderer: EventRenderer) -> None:
|
|
179
261
|
"""在 TUI 内部异步加载 MCP,通过 renderer 输出状态消息."""
|
|
180
262
|
if not session._agent.options.mcp_servers:
|
|
@@ -196,11 +278,29 @@ async def _preload_mcp_in_tui(session: ChatSession, renderer: EventRenderer) ->
|
|
|
196
278
|
renderer.append_system_message(f"MCP loaded: {', '.join(aliases)} ({count} tools)")
|
|
197
279
|
|
|
198
280
|
|
|
199
|
-
async def run(
|
|
200
|
-
|
|
201
|
-
|
|
281
|
+
async def run(
|
|
282
|
+
*,
|
|
283
|
+
rpc_stdio: bool = False,
|
|
284
|
+
resume_session_id: str | None = None,
|
|
285
|
+
resume_select: bool = False,
|
|
286
|
+
) -> None:
|
|
287
|
+
project_root = _resolve_cli_project_root()
|
|
288
|
+
preflight_result = await run_preflight_if_needed(
|
|
289
|
+
console=console,
|
|
290
|
+
project_root=project_root,
|
|
291
|
+
interactive=not rpc_stdio,
|
|
292
|
+
)
|
|
293
|
+
if preflight_result.should_abort_launch:
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
agent = _build_agent(project_root=project_root)
|
|
297
|
+
|
|
298
|
+
if rpc_stdio and resume_select and not resume_session_id:
|
|
299
|
+
console.print("[red]`comate resume` does not support `--rpc-stdio` without <session_id>[/]")
|
|
300
|
+
return
|
|
202
301
|
|
|
203
302
|
if rpc_stdio:
|
|
303
|
+
session, _mode = _resolve_session(agent, resume_session_id, cwd=project_root)
|
|
204
304
|
bridge = StdioRPCBridge(session)
|
|
205
305
|
try:
|
|
206
306
|
await bridge.run()
|
|
@@ -209,6 +309,23 @@ async def run(*, rpc_stdio: bool = False, session_id: str | None = None) -> None
|
|
|
209
309
|
return
|
|
210
310
|
|
|
211
311
|
print_logo(console)
|
|
312
|
+
|
|
313
|
+
if resume_select and not resume_session_id:
|
|
314
|
+
selected_session_id = await select_resume_session_id(console, cwd=project_root)
|
|
315
|
+
if not selected_session_id:
|
|
316
|
+
return
|
|
317
|
+
resume_session_id = selected_session_id
|
|
318
|
+
|
|
319
|
+
session, mode = _resolve_session(agent, resume_session_id, cwd=project_root)
|
|
320
|
+
|
|
321
|
+
# 版本检查:带超时,不阻塞启动
|
|
322
|
+
try:
|
|
323
|
+
update_hint = await asyncio.wait_for(_check_update(), timeout=2.0)
|
|
324
|
+
if update_hint:
|
|
325
|
+
console.print(update_hint)
|
|
326
|
+
except (asyncio.TimeoutError, Exception):
|
|
327
|
+
pass
|
|
328
|
+
|
|
212
329
|
# 不再阻塞等待 MCP,改为 TUI 内部异步加载
|
|
213
330
|
status_bar = StatusBar(session)
|
|
214
331
|
status_bar.set_mode(session.get_mode())
|
|
@@ -250,12 +367,11 @@ async def run(*, rpc_stdio: bool = False, session_id: str | None = None) -> None
|
|
|
250
367
|
if usage_line:
|
|
251
368
|
console.print(f"[dim]{usage_line}[/]")
|
|
252
369
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
370
|
+
initialized_session_id = tui.initialized_session_id
|
|
371
|
+
resume_hint = _format_resume_hint(initialized_session_id)
|
|
372
|
+
if resume_hint is not None:
|
|
373
|
+
console.print(resume_hint)
|
|
257
374
|
|
|
258
375
|
|
|
259
376
|
if __name__ == "__main__":
|
|
260
|
-
|
|
261
|
-
asyncio.run(run(session_id=argv_session_id))
|
|
377
|
+
asyncio.run(run())
|