fix(cli): localize existing-server prompts for Chinese launcher
This commit is contained in:
1 parent
c6d2050ff0
commit
053b482c90
3 files changed
+126
-11
No files matched your search
@@ -15,6 +15,7 @@
|
||||
"""UI Launch and Web Console CLI Command (artemis ui)."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
@@ -34,6 +35,11 @@ import typer
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _launch_text(english: str, chinese: str) -> str:
|
||||
"""Honor the language selected by the Windows launch wrapper."""
|
||||
return chinese if os.environ.get("ARTEMIS_LAUNCH_LANG") == "zh-CN" else english
|
||||
|
||||
|
||||
def running_via_console_script_shim() -> bool:
|
||||
"""Return True when this CLI was launched through a console-script ``.exe`` shim.
|
||||
|
||||
@@ -308,7 +314,12 @@ def ui_command(
|
||||
)
|
||||
|
||||
if restart:
|
||||
console.print(f" [yellow]🔄 Restart requested. Recycling port {port}...[/yellow]")
|
||||
console.print(
|
||||
_launch_text(
|
||||
f" [yellow]🔄 Restart requested. Recycling port {port}...[/yellow]",
|
||||
f" [yellow]🔄 已请求重启,正在释放端口 {port}...[/yellow]",
|
||||
)
|
||||
)
|
||||
load_session_reconciler()
|
||||
stop_server(port=port, timeout=12.0)
|
||||
elif is_port_in_use(port):
|
||||
@@ -316,19 +327,39 @@ def ui_command(
|
||||
pid_str = f" (PID: {', '.join(map(str, pids))})" if pids else ""
|
||||
if sys.stdin.isatty():
|
||||
console.print(
|
||||
f"\n [yellow]⚠ Port {port} is already in use by an active Artemis server{pid_str}.[/yellow]"
|
||||
_launch_text(
|
||||
f"\n [yellow]⚠ Port {port} is already in use by an active Artemis server{pid_str}.[/yellow]",
|
||||
f"\n [yellow]⚠ 检测到 ARTEMIS 服务正在运行,占用端口 {port}{pid_str}。[/yellow]",
|
||||
)
|
||||
)
|
||||
console.print(" [dim]Choose an action:[/dim]")
|
||||
console.print(" [bold]1[/bold] Open browser (default)")
|
||||
console.print(" [bold]2[/bold] Restart server (stop existing and start here)")
|
||||
console.print(" [bold]3[/bold] Cancel")
|
||||
console.print(
|
||||
_launch_text(" [dim]Choose an action:[/dim]", " [dim]请选择操作:[/dim]")
|
||||
)
|
||||
console.print(
|
||||
_launch_text(
|
||||
" [bold]1[/bold] Open browser (default)",
|
||||
" [bold]1[/bold] 打开浏览器(默认)",
|
||||
)
|
||||
)
|
||||
console.print(
|
||||
_launch_text(
|
||||
" [bold]2[/bold] Restart server (stop existing and start here)",
|
||||
" [bold]2[/bold] 重启服务(停止现有服务并在此启动,会中断正在运行的任务)",
|
||||
)
|
||||
)
|
||||
console.print(_launch_text(" [bold]3[/bold] Cancel", " [bold]3[/bold] 取消"))
|
||||
try:
|
||||
choice = input(" Select [1-3, default 1]: ").strip()
|
||||
choice = input(
|
||||
_launch_text(" Select [1-3, default 1]: ", " 请输入选项 [1-3,默认 1]:")
|
||||
).strip()
|
||||
except (KeyboardInterrupt, EOFError):
|
||||
choice = "1"
|
||||
if choice == "2":
|
||||
console.print(
|
||||
f"\n [yellow]🔄 Terminating previous Artemis instance on port {port}...[/yellow]"
|
||||
_launch_text(
|
||||
f"\n [yellow]🔄 Terminating previous Artemis instance on port {port}...[/yellow]",
|
||||
f"\n [yellow]🔄 正在停止端口 {port} 上的现有 ARTEMIS 服务...[/yellow]",
|
||||
)
|
||||
)
|
||||
load_session_reconciler()
|
||||
stop_server(port=port, timeout=12.0)
|
||||
@@ -340,8 +371,12 @@ def ui_command(
|
||||
return
|
||||
else:
|
||||
console.print(
|
||||
f"\n [yellow]⚠ Port {port} is already in use by Artemis{pid_str}. "
|
||||
f"Use '[bold]artemis restart[/bold]' to restart.[/yellow]\n"
|
||||
_launch_text(
|
||||
f"\n [yellow]⚠ Port {port} is already in use by Artemis{pid_str}. "
|
||||
"Use '[bold]artemis restart[/bold]' to restart.[/yellow]\n",
|
||||
f"\n [yellow]⚠ 检测到 ARTEMIS 服务正在运行,占用端口 {port}{pid_str}。"
|
||||
"如需重启,请运行 '[bold]artemis restart[/bold]'。[/yellow]\n",
|
||||
)
|
||||
)
|
||||
if open_browser:
|
||||
webbrowser.open(local_url)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
- 展开后安全渲染 Markdown 正文、列表和表格,并展示已有结论及已记录依据;长正文限高滚动。
|
||||
- 列表摘要优先使用已保存的结论原因,否则使用执行错误首行;展示时移除 FlashRunner 固定技术前缀,原始记录保持不变。
|
||||
- 仅展示已结束任务的已有信息,不新增 AI 复盘或模型请求。展开说明不触发任务切换,列表后台刷新保留展开状态。
|
||||
- `start-cn.bat` 检测到正在运行的服务时,服务占用提示、打开浏览器/重启/取消菜单、输入提示及重启进度均使用中文;非交互启动提示也使用中文。默认仍只打开浏览器,选择重启才停止现有服务。
|
||||
|
||||
本版不改变任务执行、模型重试或批次停止策略,继续保留 2.4.3 的异常输出隔离与参数保护。
|
||||
|
||||
@@ -16,10 +17,13 @@
|
||||
- 前端回归:353 项通过,生产构建通过。
|
||||
- 内置浏览器使用隔离样例验证默认折叠、Markdown 展开、长内容、无错误完成任务、批次布局、浅色/深色与窄视口。
|
||||
- 最终源码 ZIP 的隔离解压、独立空 npm 缓存、官方源与国内镜像安装和生产构建结果随附件 `INSTALL-VERIFICATION.md` 提供。
|
||||
- 未复跑用户业务任务、调用真实模型或进行高并发测试;本次没有 Python 行为变更,未重跑 Python 全量回归。
|
||||
- 启动语言与 Windows 启动脚本定向回归 31 项通过,Ruff 格式与静态检查、质量基线及核心类型检查通过。Python 默认确定性回归结果随安装验证附件提供。
|
||||
- 未复跑用户业务任务、调用真实模型或进行高并发测试。
|
||||
|
||||
## 升级
|
||||
|
||||
已有安装请等待任务结束,运行 `update-cn.bat` 或 `update.bat` 后重启。新安装下载 `artemis-2.4.4-source.zip`,按 `SHA256SUMS.txt` 校验后启动。请勿直接覆盖旧安装目录。
|
||||
|
||||
2026-10-29 撤回首次发布的 2.4.4,补充中文启动提示后重新发布。此前下载过 2.4.4 的用户请重新下载并核对最新校验文件,或使用更新脚本获取最新提交。首次发布包的 SHA256 为 `9a2a678c0cf97b5de140479a3f3946171d20d19efaf3ad249c708ed35a06e67a`,该包已撤回。
|
||||
|
||||
人工评审插件 1.1.0 无需更新。本次发布不构建 Docker,不重启用户服务。
|
||||
@@ -109,6 +109,82 @@ def _recording_console():
|
||||
return Console(file=io.StringIO(), force_terminal=False, width=120)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("language", ["zh-CN", "en"])
|
||||
@pytest.mark.parametrize("choice", ["", "2", "3"])
|
||||
def test_existing_server_prompt_respects_launch_language(monkeypatch, language, choice):
|
||||
from artemis.runtime import server_lifecycle
|
||||
|
||||
console = _recording_console()
|
||||
monkeypatch.setenv("ARTEMIS_LAUNCH_LANG", language)
|
||||
monkeypatch.setattr(ui, "Console", lambda: console)
|
||||
monkeypatch.setattr(ui.sys.stdin, "isatty", lambda: True)
|
||||
monkeypatch.setattr(server_lifecycle, "is_port_in_use", lambda port: True)
|
||||
monkeypatch.setattr(server_lifecycle, "find_server_pids", lambda port: [1234])
|
||||
prompts, opened, stopped = [], [], []
|
||||
monkeypatch.setattr("builtins.input", lambda prompt: prompts.append(prompt) or choice)
|
||||
monkeypatch.setattr(ui.webbrowser, "open", opened.append)
|
||||
monkeypatch.setattr(ui, "load_session_reconciler", lambda: None)
|
||||
|
||||
class RestartSelected(Exception):
|
||||
pass
|
||||
|
||||
def stop_server(**kwargs):
|
||||
stopped.append(kwargs)
|
||||
raise RestartSelected # Never launch or stop a real service.
|
||||
|
||||
monkeypatch.setattr(server_lifecycle, "stop_server", stop_server)
|
||||
if choice == "2":
|
||||
with pytest.raises(RestartSelected):
|
||||
ui.ui_command(port=8123)
|
||||
else:
|
||||
ui.ui_command(port=8123)
|
||||
|
||||
output = console.file.getvalue()
|
||||
assert "8123" in output and "PID: 1234" in output
|
||||
if language == "zh-CN":
|
||||
assert all(
|
||||
text in output
|
||||
for text in ("服务正在运行", "请选择操作", "打开浏览器(默认)", "重启服务", "取消")
|
||||
)
|
||||
assert "请输入选项" in prompts[0]
|
||||
assert "Choose an action" not in output and "Restart server" not in output
|
||||
if choice == "2":
|
||||
assert "正在停止端口 8123" in output
|
||||
else:
|
||||
assert "Choose an action" in output and "Open browser (default)" in output
|
||||
assert "Select [1-3, default 1]" in prompts[0]
|
||||
assert opened == (["http://localhost:8123"] if not choice else [])
|
||||
assert stopped == ([{"port": 8123, "timeout": 12.0}] if choice == "2" else [])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("language", ["zh-CN", None])
|
||||
@pytest.mark.parametrize("open_browser", [True, False])
|
||||
def test_existing_server_noninteractive_does_not_restart(monkeypatch, language, open_browser):
|
||||
from artemis.runtime import server_lifecycle
|
||||
|
||||
console = _recording_console()
|
||||
if language:
|
||||
monkeypatch.setenv("ARTEMIS_LAUNCH_LANG", language)
|
||||
else:
|
||||
monkeypatch.delenv("ARTEMIS_LAUNCH_LANG", raising=False)
|
||||
monkeypatch.setattr(ui, "Console", lambda: console)
|
||||
monkeypatch.setattr(ui.sys.stdin, "isatty", lambda: False)
|
||||
monkeypatch.setattr(server_lifecycle, "is_port_in_use", lambda port: True)
|
||||
monkeypatch.setattr(server_lifecycle, "find_server_pids", lambda port: [])
|
||||
monkeypatch.setattr(
|
||||
server_lifecycle, "stop_server", lambda **kwargs: pytest.fail("Unexpected restart")
|
||||
)
|
||||
opened = []
|
||||
monkeypatch.setattr(ui.webbrowser, "open", opened.append)
|
||||
|
||||
ui.ui_command(port=8123, open_browser=open_browser)
|
||||
|
||||
output = console.file.getvalue()
|
||||
assert "artemis restart" in output
|
||||
assert ("服务正在运行" if language else "already in use") in output
|
||||
assert opened == (["http://localhost:8123"] if open_browser else [])
|
||||
|
||||
|
||||
def test_ensure_showcase_built_skips_install_when_deps_current(monkeypatch):
|
||||
steps = []
|
||||
monkeypatch.setattr(ui, "_showcase_build_required", lambda showcase_dir: True)
|
||||
|
||||
Reference in new issue
Block a user