feat: MCP backend 运行态完善 + AI 编码 harness + runtime 启动器 + dev skills - #604
feat: MCP backend 运行态完善 + AI 编码 harness + runtime 启动器 + dev skills#604DoctorReid wants to merge 26 commits into
Conversation
Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- one_dragon: 新增 context_notify_event.py 等,对齐 ZZZ 框架层 - one_dragon_qt: 新增 app_notify_setting_interface/flyout、fast_scroll_area,移除 notify_dialog - onnxocr: 新增 inference_engine.py,含 PaddleOCR v6 代码支持 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- 新增 docs/develop/one_dragon/common-package-sync.md:common 三包性质、整包镜像同步法、模型下载机制 - AGENTS.md 架构落点:说明三个 common 包是游戏无关的公共框架 - AGENTS.md 硬约束:模型走运行时下载、不进 git、勿 git add Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
完成 sr_od 业务代码向 application/ 架构的统一:
- app/div_uni → application/div_uni(5 文件)
- app/treasures_lightward → application/treasures_lightward(18 文件)
- 删除 app/sr_application_launcher.py(转发 stub,application/ 已有真实实现)+ 空 app/__init__.py
- 导入路径 sr_od.app.{div_uni,treasures_lightward} → sr_od.application.*
- 清理空 app/ 目录
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- schemas: OcrText/AnalyzeScreenResult/WindowStatus(照搬)
- backend_context: SrBackendContext 收敛层(check_window/capture/analyze/enter_game)
- mcp/app: FastMCP 4 tool(check_game_window/capture_game_screen/analyze_screen/open_and_enter_game)
- http/routes: /game/{window,capture,analyze,enter} 4 端点
- entry/server: uvicorn 入口,端口 24001
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- sr_od_daemon.py: 管理 server daemon,端口 24000,4 个管理 tool(start/stop/restart/status) - start_daemon.ps1: 启 daemon(默认 24000) - create_startup_shortcut.ps1: 开机自启快捷方式 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
照搬 ZZZ docs/develop/zzz/backend(README/architecture/mcp/http/entry/remote-ssh), 命名/端口/文案替换为 sr_od / 24001·24000 / 星穹铁道;ai_coding.md 的 MCP 小节 由「尚未实现」更新为「已实现」并接入启动命令与文档链接。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
从 MCP backend 照搬实战提炼:token 形式多样(包名/模块文件名/类名/文案/路径/端口), 单一 sed/grep pattern 覆盖不全。补完整清单 + sed 顺序 + 验证纪律(grep pattern 须含 zzz/ 路径形式、pyright 兜底、.md 单独通读)。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
SrLauncher(RuntimeLauncher): _do_run_gui→sr_full_app.main、 _do_run_onedragon→sr_application_launcher.main;文案星穹铁道。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
…fest,照搬 ZZZ generate 扫 src/ 生成依赖清单,EXCLUDE_SRCPATHS=sr_od/backend(backend dev-only 不进发布 bundle);hook_path_inject 为 runtime_hook,注入 exe 旁 src/ 到 sys.path。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
入口 src/sr_od/win_exe/runtime_launcher.py;KEEP_TREES=one_dragon.launcher/version; collect_submodules 收集源码包后 excludes 业务(runtime 只含依赖+Python,源码外部加载)。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
build_full 一键打 3 exe + 拼 .runtime + 拷 config/assets/pyproject + 打 zip; 去掉不存在的 uv.toml 行;project.yml 加 manifest_path 启用 runtime 兼容性闸门。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
照搬 ZZZ docs/develop/one_dragon/runtime_launcher.md,命名替换(zzz_od→sr_od、 ZLauncher→SrLauncher、绝区零→星穹铁道、app.py→sr_full_app.py);CI/产物段 适配 SR 现状(无 CI、build_full.bat 产物 StarRailOneDragon*.zip、完整包不含 src)。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- skills/sr-od-dev-{deciding-a-fix,pr-finishing,skill-guide}/(SKILL.md + design.md),从 ZZZ 同步并按 token 清单适配(CodeRabbit 内容保留)
- ai_coding.md:加「推荐安装 superpowers」节、symlink→junction(mklink /J 免管理员)、skill 表更新
- quickstart.md:新建,从 ZZZ 适配(sr_full_app.py / 端口 24001 / sr_od backend / sr-od-test)
- entry_files.md:补 path-scoped rule 说明段(非 always-on 规范在 AGENTS.md 提及并指向 docs)
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- README.md:方向A 补 superpowers+skills/ 方法论;方向B「暂未实施」→「已落地」(SrBackendContext / 4 tool / 端口 24001 / sr_od/backend);A-2/B-1 状态表更新;entry-files 表加 skills/ 行 - settings_scope.md:坑1 例子改 sr_od;表格行「无项目自有 MCP」→ 3 个 mcp__*(context7/sr_od/sr_od_daemon);整体归口补 server 定义落点 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- ZZZ 397b5b22 新增的 one_dragon/base/screen/screen_match.py(ScreenMatch dataclass + find_screen_matches) - SR 的 one_dragon 其余部分已与 ZZZ 对齐,本次实质新增仅此一文件 - 验证:文件数 205、pyright 0 error、GUI 启动 OK、sr_od 零失配 - 解锁 Phase B:sr_od/backend analyze 画面匹配增强 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- schemas: + RunStatusResult、AnalyzeScreenResult +screens(import ScreenMatch) - backend_context: + RunSlot 单跑道(start_run/query_status/stop)+ close_game + analyze 增强画面匹配 - mcp/app: 7 tool 工厂模式(+ get_run_status/stop_run/close_game,enter 加 block) - http/routes: 7 端点(+ status/stop/close,enter 改 start_run) - entry: docstring 勘误 4→7 tool 照搬 ZZZ backend 演进,token 清单适配(enter_game 单→复、sr_od_mcp 等) Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
- README/architecture/mcp/http/entry 更新为运行态版本(7 tool、7 端点、start_run/query_status/stop、close_game) - 新增 design-principles.md(backend 设计原则 P1-P12) - 适配 async-operation 设计 spec(docs/superpowers/specs/,gitignore 不入库) - 通读勘误:README tool 数 4→7;architecture ZPcController→SrPcController;删 SR 不存在的 one_dragon_architecture.md 链接 照搬 ZZZ backend 文档,token 清单适配(sr_od 路径、端口 24001 等) Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
…te-design) final review 发现:B3 sed 集(代码文件)未覆盖 spec 文件名 token, backend_context.py:64 仍指向 ZZZ 的 2026-07-02 spec(SR 已适配为 2026-07-05)。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
…匹配 + 7 tool/7 端点 + docs) - common: 带进 screen_match.py(analyze 画面匹配依赖) - backend: RunSlot 运行态管理(start_run/query_status/stop)+ close_game + analyze 增强 - mcp: 7 tool(+ get_run_status/stop_run/close_game,enter 加 block) - http: 7 端点(+ status/stop/close,enter 改 start_run) - docs: 运行态文档 + design-principles + adapted spec - tests: 74 用例(sr-od-test) 照搬 ZZZ backend 演进,token 清单适配 SR。final opus review clean。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
MCP backend 照搬轮靠通读/final review 抓到 5 类 sed+grep 都漏的 token: - 端口 sed 须用裸形式(不带反引号) - 小写前缀 zzz_backend_run(thread_name_prefix) - Z 前缀业务子类 ZPcController - 英文游戏名字面量 ZenlessZoneZero - 端口片段 :2300(findstr) - spec 文件名引用 §5.2 残留 grep pattern 同步补 Zenless|ZPc|zzz_backend|:2300。 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
Walkthrough本次变更新增了 AI 协作与开发规范文档、PyInstaller 集成打包与 sr_od 后端服务链路,并重构了通知、画面、OCR、日志、下载、YAML、Qt 滚动组件及多个界面交互与基础设施实现。 ChangesAI 协作与开发规范
Estimated code review effort: 5 (Critical) | ~150 minutes 打包、清单与后端服务
Estimated code review effort: 5 (Critical) | ~150 minutes 核心框架、通知、画面、OCR 与 UI
Estimated code review effort: 5 (Critical) | ~180 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant server as sr_od.backend.entry.server
participant backend as SrBackendContext
participant runslot as RunSlot
participant ctx as SrContext
Client->>server: /game/enter 或 open_and_enter_game
server->>backend: start_run(source, op_factory)
backend->>runslot: _start_run(source, op_factory)
runslot->>ctx: run_context.start_running()
runslot->>runslot: 执行 Operation
runslot-->>backend: Future / 运行结果
backend-->>server: 运行状态或结果
server-->>Client: JSON / 文本响应
sequenceDiagram
participant Operation
participant notify as operation_notify
participant config as NotifyConfig
participant pool as NotifyPool
participant channel as 通知渠道
Operation->>notify: send_node_notify(operation, node)
notify->>config: get_app_lifecycle_mode / get_app_detail_mode
config-->>notify: NotifyLifecycleMode, NotifyDetailMode
alt detail_mode = MERGE
notify->>pool: 追加节点消息
else detail_mode = ALL/ERROR_ONLY
notify->>channel: 立即推送节点通知
end
Operation->>notify: send_application_notify(app, result)
notify->>pool: 读取合并消息与图片
notify->>channel: push_merged_async / push_async
Estimated code review effort: 5 (Critical) | ~480 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/one_dragon/base/screen/template_loader.py (1)
45-54: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win恢复按
only_mask区分的存在性校验
need_raw=False会让only_mask=False的get_template()也接受缺少原图的模板;而后续特征匹配、二值化匹配和裁剪匹配都直接依赖TemplateInfo.raw,这会把不完整模板带入运行时并在template.raw.shape/to_binary(template.raw)等路径上出错。🐛 建议恢复原有逻辑
- if not is_template_existed(sub_dir, template_id, need_raw=False): + if not is_template_existed(sub_dir, template_id, need_raw=not only_mask): return None🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/base/screen/template_loader.py` around lines 45 - 54, The existence check in load_template is no longer respecting only_mask, so non-mask loads can admit templates without a raw image. Update load_template to pass need_raw based on only_mask (or equivalent logic) when calling is_template_existed, so get_template and downstream users of TemplateInfo.raw continue to reject incomplete templates. Keep the fix localized to load_template and the template existence validation path.src/one_dragon/base/config/yaml_operator.py (1)
103-131: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win将
file_path回写提前到内容比较之前
_copy_on_write_source_path场景下,save()先把配置复制到可写的write_path,但一旦内容相同就直接返回,self.file_path仍停留在 sample/资源路径。后续is_file_exists、delete()之类的逻辑会继续指向旧路径。
建议在内容比较前先同步self.file_path/old_file_path。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/base/config/yaml_operator.py` around lines 103 - 131, In `YamlOperator.save`, the in-memory path state is updated too late, so when `_copy_on_write_source_path` resolves to a writable `write_path` and the content is unchanged, `self.file_path` and `old_file_path` can remain on the original sample/resource path. Move the `file_path`/`old_file_path` synchronization to happen immediately after `write_path` is determined and before the old/new content comparison, keeping the path state aligned even when `save()` returns early.
🧹 Nitpick comments (22)
src/one_dragon/base/screen/screen_loader.py (2)
165-174: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
load_extra_screen_dir参数建议直接使用Path类型。调用方
_load_plugin_screens中screen_dir本身已经是Path对象,却被str()转换后再传入本函数重新构造为Path,存在不必要的往返转换。♻️ 建议的修复
- def load_extra_screen_dir(self, dir_path: str, default_app_id: str = '') -> None: + def load_extra_screen_dir(self, dir_path: Path, default_app_id: str = '') -> None: """从额外目录加载 screen YAML 并注册(用于插件 screen 注入) 加载后会重新计算路由和全局 screen 集合。 Args: - dir_path: 包含 screen YAML 文件的目录路径 + dir_path: 包含 screen YAML 文件的目录路径(Path) default_app_id: 如果 YAML 中未设置 app_id,使用此默认值 """ - screen_dir = Path(dir_path) + screen_dir = dir_path if not screen_dir.is_dir(): returnAs per coding guidelines,
**/*.{py,pyi}: "路径操作使用 pathlib,字符串格式化使用 f-string。"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/base/screen/screen_loader.py` around lines 165 - 174, `load_extra_screen_dir` is forcing a Path-to-str-to-Path round trip even though `_load_plugin_screens` already has a Path, so update the API to accept and use a Path directly. Change `load_extra_screen_dir` to take a `Path` argument instead of `str`, remove the redundant `Path(...)` conversion inside the method, and adjust the call site in `_load_plugin_screens` to pass the existing `screen_dir` through unchanged.Source: Coding guidelines
244-310: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value插件画面重命名场景下会触发重复 reload。
save_screen在处理普通画面重命名时会先delete_screen(old_id, save=False)(内部已执行一次reload(from_memory=True)),随后又调用self.save(...)(默认reload_after_save=True,内部再执行一次reload(from_memory=True))。两次 reload 都会重算init_screen_route()(Floyd-Warshall,O(n³))和_global_screen_names。该路径仅在管理界面手动重命名/保存画面时触发,频率低,实际影响有限。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/base/screen/screen_loader.py` around lines 244 - 310, save_screen is triggering two reloads during a normal screen rename: delete_screen(..., save=False) already calls reload(from_memory=True), then self.save(...) triggers another reload via its default save flow. Update save_screen to avoid the redundant second reload for the rename path, either by saving without reload or by adding a way to skip reload_after_save in the save call, while keeping _save_extra_screen and delete_screen behavior unchanged.tools/mcp/daemon/create_startup_shortcut.ps1 (1)
33-44: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value建议用 try/finally 包裹 COM 对象生命周期。
若
$ErrorActionPreference = "Stop"触发的异常发生在New-Object之后、ReleaseComObject之前(例如快捷方式保存失败),COM 对象将不会被释放。脚本进程退出时系统通常会回收,实际影响很小。♻️ 建议的修复
-$WshShell = New-Object -ComObject WScript.Shell - -# Create shortcut -$Shortcut = $WshShell.CreateShortcut($ShortcutPath) -$Shortcut.TargetPath = "powershell.exe" -$Shortcut.Arguments = "-ExecutionPolicy Bypass -WindowStyle Hidden -File `"$StartDaemonScript`"" -$Shortcut.WorkingDirectory = $ProjectRoot -$Shortcut.Description = "SR OD MCP Server Daemon - Manages game operation server lifecycle" -$Shortcut.Save() - -# Release COM object -[System.Runtime.Interopservices.Marshal]::ReleaseComObject($WshShell) | Out-Null +$WshShell = New-Object -ComObject WScript.Shell +try { + $Shortcut = $WshShell.CreateShortcut($ShortcutPath) + $Shortcut.TargetPath = "powershell.exe" + $Shortcut.Arguments = "-ExecutionPolicy Bypass -WindowStyle Hidden -File `"$StartDaemonScript`"" + $Shortcut.WorkingDirectory = $ProjectRoot + $Shortcut.Description = "SR OD MCP Server Daemon - Manages game operation server lifecycle" + $Shortcut.Save() +} finally { + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WshShell) | Out-Null +}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/mcp/daemon/create_startup_shortcut.ps1` around lines 33 - 44, Wrap the WScript.Shell COM object lifecycle in a try/finally block in create_startup_shortcut.ps1 so the object is always released even if CreateShortcut, Save, or another step fails under $ErrorActionPreference = "Stop". Keep the shortcut creation logic in the try section around $WshShell, $Shortcut, and $Shortcut.Save(), and move the ReleaseComObject call for $WshShell into the finally section with a null check.src/one_dragon_qt/widgets/app_run_list.py (1)
106-113: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win通知可见性判断逻辑重复三处,建议抽取公共方法。
app.app_id in self.ctx.notify_config.app_map这条表达式在本文件的_update_existing_cards(Line 112)与_create_new_cards(Line 155)中各出现一次,另外在one_dragon_run_interface.py的_update_setting_btn_visibility中也重复出现同样逻辑。三处保持一致依赖人工同步,建议抽取为共享方法(如NotifyConfig.is_app_enabled(app_id)或AppRunList._is_notify_visible(app_id)),减少后续修改遗漏的风险。♻️ 提议的重构方向
+ def _is_notify_visible(self, app_id: str) -> bool: + return app_id in self.ctx.notify_config.app_map + def _update_existing_cards(...): ... - card.set_notify_visible(app.app_id in self.ctx.notify_config.app_map) + card.set_notify_visible(self._is_notify_visible(app.app_id))Also applies to: 129-156
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon_qt/widgets/app_run_list.py` around lines 106 - 113, The notify visibility check is duplicated across AppRunList and the run interface, so extract it into one shared helper and reuse it everywhere. Add a single method such as NotifyConfig.is_app_enabled(app_id) or AppRunList._is_notify_visible(app_id), then replace the repeated app.app_id in self.ctx.notify_config.app_map checks in _update_existing_cards, _create_new_cards, and _update_setting_btn_visibility with that helper to keep behavior consistent.docs/develop/setup/claude-code/commit-trailer.md (1)
131-136: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win补充围栏代码块的语言标注。
markdownlint 提示该处围栏代码块缺少语言声明(MD040)。
📝 修复建议
-``` +```text <你的提交标题>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/develop/setup/claude-code/commit-trailer.md` around lines 131 - 136, The fenced code block in commit-trailer.md is missing a language identifier, triggering markdownlint MD040. Update the fenced block that contains the commit title and Co-Authored-By lines to include an explicit language tag (use the same identifier shown in the review, via the markdown fence in that section) so the block is properly annotated and lint passes.Source: Linters/SAST tools
src/onnxocr/inference_engine.py (2)
157-161: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win路径操作应使用
pathlib。As per coding guidelines,
**/*.{py,pyi}: "路径操作使用 pathlib,字符串格式化使用 f-string。" 此处仍用os.path.exists。♻️ 建议修复
+from pathlib import Path ... - if not os.path.exists(model_path): + if not Path(model_path).exists():🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/onnxocr/inference_engine.py` around lines 157 - 161, The model existence check in `inference_engine.py` still uses `os.path.exists`, which violates the pathlib path-handling guideline. Update the path check in the same block that raises `FileNotFoundError` to use `pathlib.Path`-based operations instead, keeping the existing `model_path` logic and error message behavior intact. Use the relevant `model_path` handling in `inference_engine.py` so the code consistently follows the project’s pathlib convention.Source: Coding guidelines
71-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick windocstring 使用英文,违反中文注释规范。
As per coding guidelines,
**/*.{py,pyi}: "注释与 docstring 必须使用中文,保持现有项目风格。" 这三处 docstring(build_providers_from_engine_cfg、ProviderConfig、_default_session_options)均为英文。Also applies to: 94-96, 139-143
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/onnxocr/inference_engine.py` around lines 71 - 77, 当前多个 docstring 仍使用英文,需按项目规范统一改为中文;请在 build_providers_from_engine_cfg、ProviderConfig 和 _default_session_options 这几个符号对应的 docstring 中,将说明性文本改写为中文,并保持含义一致、风格统一,确保整个 Python 文件的注释与 docstring 都符合中文注释规范。Source: Coding guidelines
src/one_dragon/yolo/onnx_model_loader.py (1)
163-164: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
run_session缺少返回类型注解。As per coding guidelines,
**/*.{py,pyi}: "所有函数签名与类成员变量都必须有类型注解。"input_feed: dict也建议补充泛型参数(如dict[str, Any])。♻️ 建议修复
- def run_session(self, output_names: list[str], input_feed: dict): + def run_session(self, output_names: list[str], input_feed: dict[str, Any]) -> Any: return gpu_executor.run_session(self.session, output_names, input_feed=input_feed)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/yolo/onnx_model_loader.py` around lines 163 - 164, The run_session method in OnnxModelLoader is missing an explicit return type annotation, and its input_feed parameter should use a fully typed mapping instead of a bare dict. Update the run_session signature to include a precise return annotation matching gpu_executor.run_session’s result, and change input_feed to a generic form such as dict[str, Any] (or the most accurate typed mapping used in this module) while keeping the existing output_names annotation intact.Source: Coding guidelines
src/one_dragon_qt/view/code_interface.py (1)
74-79: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value两处
auto_update_code_opt卡片配置重复。
setting_env_interface.py与本文件对同一设置(图标、标题、password_hash、reverse_mode)各写一份完全相同的初始化代码,未来修改密码或文案需要同步两处,存在漂移风险。可考虑抽取共享工厂函数(如build_auto_update_code_card())复用。该模式在force_update_opt上已有先例,非本次新增紧迫问题,优先级较低。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon_qt/view/code_interface.py` around lines 74 - 79, `auto_update_code_opt` is initialized with the same icon, title, password_hash, and reverse_mode in multiple places, creating duplicated configuration that can drift over time. Refactor the setup in `CodeInterface` to reuse a shared factory/helper, similar to the existing `force_update_opt` pattern, so the `auto_update_code_opt` card is built from one source of truth rather than repeated inline initialization.src/one_dragon/base/controller/pc_controller_base.py (1)
528-528: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
pos参数类型标注未使用现代X | Y语法,与同文件其余函数不一致。同文件
_foreground_click(Line 293)、_background_click(Line 355)均为pos: Point | None,此处win_click仍是pos: Point = None。♻️ 建议修复
-def win_click(pos: Point = None, press_time: float = 0.1, primary: bool = True): +def win_click(pos: Point | None = None, press_time: float = 0.1, primary: bool = True):As per coding guidelines,
**/*.{py,pyi}: "优先使用list[str]、X | Y这类现代类型语法。"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/base/controller/pc_controller_base.py` at line 528, Update the win_click function signature to use the modern optional type syntax for pos so it matches _foreground_click and _background_click in pc_controller_base.py; change the annotation from Point = None to Point | None while keeping the same default value and other parameters unchanged.Source: Coding guidelines
deploy/hook_path_inject.py (1)
12-25: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win建议为
_src增加存在性校验,快速失败而非深层晦涩报错。当前若
_src(sys.executable同级src/目录)因打包遗漏或部署路径变化而不存在,import one_dragon.xxx等后续导入会在深层代码处以难以定位的ImportError失败。作为集成启动器的关键引导路径,建议在此提前显式校验并给出清晰报错信息。♻️ 建议的防御性校验
_src = Path(sys.executable).parent / "src" +if not _src.is_dir(): + raise RuntimeError(f"未找到运行时源码目录: {_src},请检查打包产物是否完整") sys.path.insert(0, str(_src))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/hook_path_inject.py` around lines 12 - 25, Add an explicit existence check for _src in hook_path_inject.py before mutating sys.path or importing one_dragon; if the sys.executable-relative src directory is missing, fail fast with a clear error message instead of letting later import one_dragon / one_dragon.launcher calls raise a deeper ImportError. Keep the fix localized around the _src setup block so the startup path clearly reports the missing deployment directory.src/sr_od/backend/mcp/app.py (1)
35-52: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win截图落盘无清理机制,长期运行可能占用磁盘空间。
_save_screenshot每次调用都生成带时间戳的新文件,当前无过期清理或数量上限,长期运行的 daemon/主 server 可能导致.debug/sr_od_mcp/screenshot目录无限增长。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/sr_od/backend/mcp/app.py` around lines 35 - 52, The _save_screenshot helper in app.py always creates a new timestamped file and never removes old screenshots, so the .debug/sr_od_mcp/screenshot directory can grow without bound. Add a cleanup policy inside or alongside _save_screenshot (or in the screenshot directory management path) to enforce either a retention window or a maximum file count, and delete older files before or after writing the new image. Keep the existing screenshot naming and write flow, but make sure the cleanup runs reliably in the long-lived MCP server process.src/sr_od/backend/entry/server.py (1)
57-68: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win建议保留启动/运行期异常的完整上下文。
finally中的backend.shutdown()若自身抛出异常,会覆盖backend.start()/server.serve()的原始异常,不利于日志排障(daemon 场景下用户只能通过日志文件定位,见remote-ssh.md排查小节)。建议在异常路径显式记录原始异常。♻️ 建议的修改
try: log.info("SR 后端:初始化 SrContext(线程池,不阻塞事件循环)……") await backend.start() app = create_app(backend) config = uvicorn.Config(app, host=host, port=port, log_level="info") server = uvicorn.Server(config) log.info(f"SR 后端监听: http://{host}:{port}/mcp 与 /game/*") await server.serve() + except Exception: + log.error("SR 后端异常退出", exc_info=True) + raise finally: await backend.shutdown()🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/sr_od/backend/entry/server.py` around lines 57 - 68, 启动/运行期异常会被最终的 backend.shutdown() 覆盖,导致 backend.start() 或 server.serve() 的原始错误上下文丢失。请在 SrContext/SrBackendContext 的启动流程中,把 shutdown 放到独立的异常处理里,先记录并保留 start/serve 期间的原始异常,再执行清理。重点检查 await backend.start()、await server.serve() 和 finally 中的 await backend.shutdown(),确保 shutdown 失败不会吞掉前一个异常,并在异常路径显式写入日志。tools/mcp/daemon/start_daemon.ps1 (1)
39-44: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick wintry/catch 无法可靠捕获 daemon 启动失败。
原生进程(
uv/python)以非零退出码退出时不会抛出 PowerShell 终止性错误,try/catch大概率捕获不到真实的启动失败,只能捕获类似"命令找不到"这类情况。建议显式检查$LASTEXITCODE。🔧 建议修复
try { uv run --env-file .env python $DaemonScript --host $HostName --port $Port + if ($LASTEXITCODE -ne 0) { + Write-Host "[ERROR] Daemon 进程退出码非零: $LASTEXITCODE" -ForegroundColor Red + exit $LASTEXITCODE + } } catch { Write-Host "[ERROR] Daemon 启动失败: $_" -ForegroundColor Red exit 1 }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/mcp/daemon/start_daemon.ps1` around lines 39 - 44, The daemon launch in start_daemon.ps1 relies on try/catch around uv run, but that won’t reliably catch native process failures from uv/python. Update the startup flow to invoke the existing daemon launch command, then explicitly inspect $LASTEXITCODE after uv run completes and treat any non-zero value as a startup failure. Keep the current error reporting in the daemon-start script, but move the failure handling to the exit-code check so the script reliably reports and exits when the daemon fails to start.src/one_dragon/base/matcher/ocr/onnx_ocr_matcher.py (1)
42-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win新增函数使用
os.path.join,未遵循 pathlib 规范。
get_ocr_model_dict_name与get_final_file_list均为本次新增代码,但仍使用os.path.exists/os.listdir/os.path.join。♻️ 建议改为 pathlib
-def get_ocr_model_dict_name(ocr_model_name: str) -> str | None: - base_dir = get_ocr_model_dir(ocr_model_name) - if os.path.exists(base_dir): - for f in os.listdir(base_dir): - if f.endswith('_dict.txt'): - return f - return None +def get_ocr_model_dict_name(ocr_model_name: str) -> str | None: + base_dir = Path(get_ocr_model_dir(ocr_model_name)) + if base_dir.exists(): + for f in sorted(base_dir.iterdir()): + if f.name.endswith('_dict.txt'): + return f.name + return NoneBased on path instructions: "
**/*.{py,pyi}: ...路径操作使用pathlib,字符串格式化使用 f-string。"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/base/matcher/ocr/onnx_ocr_matcher.py` around lines 42 - 70, The new OCR helper functions `get_ocr_model_dict_name` and `get_final_file_list` are still using `os.path` APIs for directory checks, listing, and path assembly, which violates the pathlib style guideline. Update these helpers to use `Path`-based operations throughout: resolve the model directory with the existing `get_ocr_model_dir` flow, iterate directory contents via `Path.iterdir()` or equivalent, and build the final file list with `Path` joins instead of string-based path concatenation. Keep the function behavior unchanged while aligning the implementation with the project’s pathlib convention.Sources: Coding guidelines, Path instructions
src/one_dragon/devtools/python_launcher.py (2)
297-301: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
app_path参数缺少类型注解。本行在本次改动中被修改(
args类型更新为list[str] | None),但app_path仍未标注类型。As per path instructions, "所有函数签名与类成员变量都必须有类型注解"。建议一并补充(如app_path: str或Path,视实际调用方而定)。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/devtools/python_launcher.py` around lines 297 - 301, The issue is that `run_python` now has a partially typed signature, but `app_path` still lacks a type annotation even though this codebase requires all function parameters to be annotated. Update the `run_python` function signature to add the appropriate type for `app_path` (for example `str` or `Path`, matching its actual use elsewhere) and keep the existing `args: list[str] | None` annotation consistent with the rest of the function.Source: Path instructions
54-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win补充
create_git_progress_callback的返回类型注解。As per path instructions, "所有函数签名与类成员变量都必须有类型注解,优先使用
list[str]、X | Y这类现代类型语法。" 当前函数缺少返回类型标注。♻️ 建议补充类型注解
-def create_git_progress_callback(): +def create_git_progress_callback() -> Callable[[float, str], None]: def _report(_progress: float, message: str) -> None: refresh = message.startswith(gt('拉取对象')) and not message.endswith('(100%)') print_message(message, 'INFO', flush=refresh) return _report(需要
from collections.abc import Callable)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/devtools/python_launcher.py` around lines 54 - 59, The create_git_progress_callback function is missing an explicit return type annotation. Update the function signature to declare that it returns a Callable matching the nested _report callback’s parameter and return types, and make sure the needed Callable import from collections.abc is added or reused. Keep the internal _report logic unchanged and let the annotation clearly reflect the callback shape.Source: Path instructions
src/onnxocr/logger.py (1)
23-41: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value四个方法体几乎完全重复,可提取公共逻辑。
info/debug/warning/error均是"按需.format()+ 前缀 + 转发到od_log"的重复模式,可抽出一个内部_dispatch辅助方法减少重复。♻️ 参考重构
+ def _dispatch(self, level_fn, msg: str, *args: Any, **kwargs: Any) -> None: + if args or kwargs: + msg = str(msg).format(*args, **kwargs) + level_fn(self._format(msg)) + def info(self, msg: str, *args: Any, **kwargs: Any) -> None: - if args or kwargs: - msg = str(msg).format(*args, **kwargs) - od_log.info(self._format(msg)) + self._dispatch(od_log.info, msg, *args, **kwargs)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/onnxocr/logger.py` around lines 23 - 41, The info, debug, warning, and error methods in Logger重复了相同的“按需 format + _format 前缀 + 转发到 od_log”逻辑,建议抽出一个内部辅助方法来统一处理。请在 Logger 类中新增一个私有 dispatch/helper(例如负责接收 level、msg、args、kwargs 并调用 od_log),然后让 info/debug/warning/error 只保留各自的级别入口并复用该公共逻辑,保持现有行为不变。src/one_dragon_qt/widgets/color_channel_dialog.py (1)
132-134: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
channels/channel_names语义上应始终等长,strict=True更能表达意图。三个色彩空间通道与通道名始终是一一对应的三元组,理论上永不会出现长度不一致;用
strict=True既能满足 Ruff B905,又能在未来重构引入不等长数据时及早暴露错误,比strict=False(静默截断)更安全。♻️ 建议调整
- for channel, name in zip(channels, channel_names, strict=False): + for channel, name in zip(channels, channel_names, strict=True):🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon_qt/widgets/color_channel_dialog.py` around lines 132 - 134, The loop in ColorChannelDialog that iterates over channels and channel_names should assume they are always paired, so update the zip call in the widget-building logic to use strict pairing instead of silent truncation. Keep the change in the channel creation path that uses _create_channel_widget and channels_layout.addWidget so any future mismatch between channels and channel_names fails fast and aligns with the intended one-to-one mapping.src/one_dragon/utils/cv2_utils.py (1)
1283-1286: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value清理遗留的调试注释代码
# save_image(img, 'y:\\debug.png')与# is_colorful(img)属于调试遗留代码,建议移除以保持代码整洁。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/utils/cv2_utils.py` around lines 1283 - 1286, Remove the leftover debug-only commented calls in the cv2_utils logic around the confidence logging, specifically the commented save_image and is_colorful lines near the percent/log.debug statements. Keep the functional code that computes percent and logs the gray mask confidence, but delete the unused debug comments so the surrounding utility code stays clean and maintainable.src/one_dragon_qt/widgets/app_setting/app_notify_setting_flyout.py (1)
101-136: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value避免直接读写兄弟类的
_current_tip
这里把“当前弹窗”状态分散在AppNotifySettingFlyout和AppSettingFlyout两个类里,后续新增 flyout 时还要同步改多处。建议抽一个共享管理器或公共基类属性统一维护这份状态。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon_qt/widgets/app_setting/app_notify_setting_flyout.py` around lines 101 - 136, The current flyout state is being duplicated and directly mutated across both AppNotifySettingFlyout and AppSettingFlyout, which makes the shared “current tip” handling fragile. Refactor show_flyout to use a single shared owner for this state, such as a common base class property or a small flyout manager, and update the close/reset logic plus destroyed cleanup to read and write only that shared location instead of touching the sibling class directly.deploy/OneDragon-RuntimeLauncher.spec (1)
15-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value建议改用
SPEC_DIR定位路径deploy/build_full.bat已经先切到脚本目录再调用 PyInstaller,所以当前写法在这条入口下可用;不过Path.cwd()仍依赖工作目录,改成SPEC/SPEC_DIR后更稳妥。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/OneDragon-RuntimeLauncher.spec` around lines 15 - 29, The path resolution in OneDragon-RuntimeLauncher.spec still relies on Path.cwd(), which can break when the spec is invoked from a different working directory. Update the path setup near REPO_ROOT, SRC_DIR, and GEN_PATH to use PyInstaller’s SPEC/SPEC_DIR-based location instead of the current working directory, keeping the existing KEEP_TREES and generate_module_manifest import flow intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@deploy/build_full.bat`:
- Around line 11-28: The build script in build_full.bat copies project.yml into
the config subdirectory, but the config folder is never created first, so the
file may not land in the intended package path. Update the packaging steps
around TARGET_DIR and the final copy of project.yml to ensure
"%TARGET_DIR%\config" exists before copying, so the config file is placed
correctly alongside the other bundled assets.
In `@docs/develop/one_dragon/common-package-sync.md`:
- Line 92: The table row in the documentation contains a bare pipe inside the
example command, which breaks Markdown column parsing. Update the affected table
entry so the `|` in the `netstat | findstr :2300` example is escaped or
otherwise protected, using the existing table row near the port-fragment
guidance to keep the column count consistent and avoid markdownlint errors.
In `@src/one_dragon_qt/view/one_dragon/one_dragon_run_interface.py`:
- Around line 289-301: The helper methods `_find_app_card_setting_btn` and
`_find_app_card_notify_btn` are missing explicit return type annotations, which
violates the project’s typing requirements. Update both method signatures in
`OneDragonRunInterface` to declare the return type as `QWidget | None`, matching
the fact that they either return a button widget from `card.setting_btn` /
`card.more_btn` or `None` when no matching card is found.
In `@src/one_dragon/base/config/yaml_operator.py`:
- Around line 113-118: The old-content read in yaml_operator.py is swallowing
all exceptions with a silent pass, which hides useful diagnostics. In the block
that reads write_path in the old_content flow, keep the try/except but replace
the bare exception handling with at least a debug-level log that records the
failure context and exception details, using the existing logger or logging
pattern in yaml_operator.py. Make the change around the read/compare logic so
future issues in this path can be traced without changing the behavior of
falling back to old_content being None.
In `@src/one_dragon/base/operation/application_base.py`:
- Around line 82-90: `Application.execute()` is clearing the active screen scope
unconditionally, which breaks nested `execute()` calls such as
`OneDragonApp.run_group_app()` invoking `GroupApplication`. Update the scope
management in `Application.execute()` and the related `screen_loader` handling
so nested executions save and restore the previous scope (stack-like behavior)
instead of always calling a plain `exit_scope()`, or limit scope enter/exit to
the top-level entry path only.
In `@src/one_dragon/base/screen/screen_loader.py`:
- Around line 430-447: The early-return comment in enter_scope is inverted
relative to the actual _global_screen_names check. Update the comment to match
the real condition in ScreenLoader.enter_scope: when _global_screen_names is
empty, it means there are no global screens and every screen has an app_id, so
scope should not be enabled. Keep the logic as-is unless you intend to change
behavior, and make the wording consistent with the ScreenInfo/app_id and
_global_screen_names semantics.
In `@src/one_dragon/utils/cv2_utils.py`:
- Around line 1240-1279: Add the same input-shape validation used by is_colorful
to is_in_gray_mask so only 3-channel images are processed; currently grayscale
or other non-RGB inputs can be reduced along the wrong axis and return a
misleading result. Update is_in_gray_mask to check img.shape before the
cond1/cond2 calculations, and return False for non-3-channel inputs so the
crop_image and mask logic only runs on valid RGB data.
In `@src/one_dragon/utils/gpu_executor.py`:
- Around line 56-68: `should_serialize_session` 和 `run_session`
这两个函数缺少完整的参数与返回值类型注解,需要按本文件中 `create_onnx_session`、`should_serialize_providers`
的风格补齐;为 `session`、`output_names`、`input_feed` 以及 `**kwargs` 添加合适的现代类型注解,并显式从
`typing` 导入 `Any` 以标注可变参数/未知类型,保持整个 `gpu_executor.py` 的函数签名一致性。
In `@src/one_dragon/yolo/onnx_model_loader.py`:
- Line 37: The session attribute in OnnxModelLoader has a type/default mismatch
because self.session is initialized to None but annotated as
ort.InferenceSession only. Update the self.session declaration in the
OnnxModelLoader class to use an optional union type such as ort.InferenceSession
| None so it matches the None default and stays consistent with pyright-clean
typing rules.
In `@src/onnxocr/onnx_paddleocr.py`:
- Around line 21-26: `_normalize_ppocrv6_size` currently ignores its
`model_size` argument and always collapses any `ppocrv6` model to `small`, which
makes the size API misleading. Update `_normalize_ppocrv6_size` and
`_build_ppocrv6_defaults` so the returned size is either explicitly restricted
to `small` or mapped from `model_size` to distinct model paths; do not silently
overwrite caller input. Apply the same fix pattern in `OnnxOcrParam.__init__` in
`onnx_ocr_matcher.py`, where the unconditional override should be replaced with
size-aware selection or a clear single-size constraint.
In `@src/onnxocr/predict_base.py`:
- Around line 49-50: `run_onnx_session` is missing required type annotations for
its parameters and return value, unlike `get_onnx_session` in the same class.
Update the `run_onnx_session` signature in `predict_base.py` to annotate
`onnx_session`, `output_names`, and `input_feed`, and add an explicit return
type using modern typing syntax consistent with the rest of `BasePredict`.
In `@src/onnxocr/predict_cls.py`:
- Around line 19-27: The warmup path in predict_cls.py bypasses the new
run_onnx_session wrapper by calling cls_onnx_session.run directly. Update the
classifier warmup in the relevant initializer to use self.run_onnx_session
instead, so it follows the same gpu_executor submission path as normal inference
and avoids keeping a direct session-run entry point. Use the existing symbols
cls_onnx_session and run_onnx_session to locate and align the call site.
In `@src/onnxocr/predict_det.py`:
- Around line 51-59: The warm-up inference in predict_det.py bypasses the shared
ONNX execution wrapper, so update the detection model initialization flow in the
relevant predictor class to use run_onnx_session instead of calling
self.det_onnx_session.run directly. Keep the warm-up dummy input logic, but
route it through the same execution path used by predict_cls.py and
predict_rec.py so the ONNX session is submitted via
one_dragon.utils.gpu_executor.submit and does not directly invoke multiple
sessions concurrently.
In `@src/onnxocr/predict_rec.py`:
- Around line 220-223: The `resize_norm_img_spin` method is passing
`cv2.INTER_CUBIC` as the third positional argument to `cv2.resize`, which binds
it to `dst` instead of `interpolation`; update this call in
`resize_norm_img_spin` to use the `interpolation` keyword argument so the resize
uses cubic interpolation correctly.
- Around line 25-33: The warm-up path in the recognition model bypasses the new
`run_onnx_session` wrapper by calling `self.rec_onnx_session.run(...)` directly,
which skips the `gpu_executor` path used by normal inference. Update the warm-up
logic in `PredictRec` to invoke `run_onnx_session` instead of calling the ONNX
session directly, so both warm-up and regular inference follow the same
execution flow and concurrency handling.
In `@src/sr_od/backend/backend_context.py`:
- Around line 67-70: SrBackendContext.shutdown() currently only runs
after_app_shutdown() and leaves the RunSlot work and its ThreadPoolExecutor
alive, which can keep the process from exiting; update the shutdown path in
SrBackendContext to first stop/cancel any active run_slot operations, then shut
down the executor created in __init__ using shutdown(cancel_futures=True) for
Python 3.11.9+, and keep the cleanup order explicit so backend tasks are
terminated before after_app_shutdown() completes.
In `@tools/mcp/daemon/sr_od_daemon.py`:
- Around line 28-44: `find_sr_od_mcp_server_process` uses a loose substring
check on each argv element, which can misidentify unrelated processes and break
`stop_sr_od_mcp_server`/`restart_sr_od_mcp_server`. Update the matching logic to
look for the exact module-launch argv pattern for `sr_od.backend.entry.server`
(for example, an explicit `-m` plus module name pair, or another exact argv
sequence used by the daemon), and keep the search limited to
`proc.info['cmdline']` in this function so only the intended server process is
returned.
---
Outside diff comments:
In `@src/one_dragon/base/config/yaml_operator.py`:
- Around line 103-131: In `YamlOperator.save`, the in-memory path state is
updated too late, so when `_copy_on_write_source_path` resolves to a writable
`write_path` and the content is unchanged, `self.file_path` and `old_file_path`
can remain on the original sample/resource path. Move the
`file_path`/`old_file_path` synchronization to happen immediately after
`write_path` is determined and before the old/new content comparison, keeping
the path state aligned even when `save()` returns early.
In `@src/one_dragon/base/screen/template_loader.py`:
- Around line 45-54: The existence check in load_template is no longer
respecting only_mask, so non-mask loads can admit templates without a raw image.
Update load_template to pass need_raw based on only_mask (or equivalent logic)
when calling is_template_existed, so get_template and downstream users of
TemplateInfo.raw continue to reject incomplete templates. Keep the fix localized
to load_template and the template existence validation path.
---
Nitpick comments:
In `@deploy/hook_path_inject.py`:
- Around line 12-25: Add an explicit existence check for _src in
hook_path_inject.py before mutating sys.path or importing one_dragon; if the
sys.executable-relative src directory is missing, fail fast with a clear error
message instead of letting later import one_dragon / one_dragon.launcher calls
raise a deeper ImportError. Keep the fix localized around the _src setup block
so the startup path clearly reports the missing deployment directory.
In `@deploy/OneDragon-RuntimeLauncher.spec`:
- Around line 15-29: The path resolution in OneDragon-RuntimeLauncher.spec still
relies on Path.cwd(), which can break when the spec is invoked from a different
working directory. Update the path setup near REPO_ROOT, SRC_DIR, and GEN_PATH
to use PyInstaller’s SPEC/SPEC_DIR-based location instead of the current working
directory, keeping the existing KEEP_TREES and generate_module_manifest import
flow intact.
In `@docs/develop/setup/claude-code/commit-trailer.md`:
- Around line 131-136: The fenced code block in commit-trailer.md is missing a
language identifier, triggering markdownlint MD040. Update the fenced block that
contains the commit title and Co-Authored-By lines to include an explicit
language tag (use the same identifier shown in the review, via the markdown
fence in that section) so the block is properly annotated and lint passes.
In `@src/one_dragon_qt/view/code_interface.py`:
- Around line 74-79: `auto_update_code_opt` is initialized with the same icon,
title, password_hash, and reverse_mode in multiple places, creating duplicated
configuration that can drift over time. Refactor the setup in `CodeInterface` to
reuse a shared factory/helper, similar to the existing `force_update_opt`
pattern, so the `auto_update_code_opt` card is built from one source of truth
rather than repeated inline initialization.
In `@src/one_dragon_qt/widgets/app_run_list.py`:
- Around line 106-113: The notify visibility check is duplicated across
AppRunList and the run interface, so extract it into one shared helper and reuse
it everywhere. Add a single method such as NotifyConfig.is_app_enabled(app_id)
or AppRunList._is_notify_visible(app_id), then replace the repeated app.app_id
in self.ctx.notify_config.app_map checks in _update_existing_cards,
_create_new_cards, and _update_setting_btn_visibility with that helper to keep
behavior consistent.
In `@src/one_dragon_qt/widgets/app_setting/app_notify_setting_flyout.py`:
- Around line 101-136: The current flyout state is being duplicated and directly
mutated across both AppNotifySettingFlyout and AppSettingFlyout, which makes the
shared “current tip” handling fragile. Refactor show_flyout to use a single
shared owner for this state, such as a common base class property or a small
flyout manager, and update the close/reset logic plus destroyed cleanup to read
and write only that shared location instead of touching the sibling class
directly.
In `@src/one_dragon_qt/widgets/color_channel_dialog.py`:
- Around line 132-134: The loop in ColorChannelDialog that iterates over
channels and channel_names should assume they are always paired, so update the
zip call in the widget-building logic to use strict pairing instead of silent
truncation. Keep the change in the channel creation path that uses
_create_channel_widget and channels_layout.addWidget so any future mismatch
between channels and channel_names fails fast and aligns with the intended
one-to-one mapping.
In `@src/one_dragon/base/controller/pc_controller_base.py`:
- Line 528: Update the win_click function signature to use the modern optional
type syntax for pos so it matches _foreground_click and _background_click in
pc_controller_base.py; change the annotation from Point = None to Point | None
while keeping the same default value and other parameters unchanged.
In `@src/one_dragon/base/matcher/ocr/onnx_ocr_matcher.py`:
- Around line 42-70: The new OCR helper functions `get_ocr_model_dict_name` and
`get_final_file_list` are still using `os.path` APIs for directory checks,
listing, and path assembly, which violates the pathlib style guideline. Update
these helpers to use `Path`-based operations throughout: resolve the model
directory with the existing `get_ocr_model_dir` flow, iterate directory contents
via `Path.iterdir()` or equivalent, and build the final file list with `Path`
joins instead of string-based path concatenation. Keep the function behavior
unchanged while aligning the implementation with the project’s pathlib
convention.
In `@src/one_dragon/base/screen/screen_loader.py`:
- Around line 165-174: `load_extra_screen_dir` is forcing a Path-to-str-to-Path
round trip even though `_load_plugin_screens` already has a Path, so update the
API to accept and use a Path directly. Change `load_extra_screen_dir` to take a
`Path` argument instead of `str`, remove the redundant `Path(...)` conversion
inside the method, and adjust the call site in `_load_plugin_screens` to pass
the existing `screen_dir` through unchanged.
- Around line 244-310: save_screen is triggering two reloads during a normal
screen rename: delete_screen(..., save=False) already calls
reload(from_memory=True), then self.save(...) triggers another reload via its
default save flow. Update save_screen to avoid the redundant second reload for
the rename path, either by saving without reload or by adding a way to skip
reload_after_save in the save call, while keeping _save_extra_screen and
delete_screen behavior unchanged.
In `@src/one_dragon/devtools/python_launcher.py`:
- Around line 297-301: The issue is that `run_python` now has a partially typed
signature, but `app_path` still lacks a type annotation even though this
codebase requires all function parameters to be annotated. Update the
`run_python` function signature to add the appropriate type for `app_path` (for
example `str` or `Path`, matching its actual use elsewhere) and keep the
existing `args: list[str] | None` annotation consistent with the rest of the
function.
- Around line 54-59: The create_git_progress_callback function is missing an
explicit return type annotation. Update the function signature to declare that
it returns a Callable matching the nested _report callback’s parameter and
return types, and make sure the needed Callable import from collections.abc is
added or reused. Keep the internal _report logic unchanged and let the
annotation clearly reflect the callback shape.
In `@src/one_dragon/utils/cv2_utils.py`:
- Around line 1283-1286: Remove the leftover debug-only commented calls in the
cv2_utils logic around the confidence logging, specifically the commented
save_image and is_colorful lines near the percent/log.debug statements. Keep the
functional code that computes percent and logs the gray mask confidence, but
delete the unused debug comments so the surrounding utility code stays clean and
maintainable.
In `@src/one_dragon/yolo/onnx_model_loader.py`:
- Around line 163-164: The run_session method in OnnxModelLoader is missing an
explicit return type annotation, and its input_feed parameter should use a fully
typed mapping instead of a bare dict. Update the run_session signature to
include a precise return annotation matching gpu_executor.run_session’s result,
and change input_feed to a generic form such as dict[str, Any] (or the most
accurate typed mapping used in this module) while keeping the existing
output_names annotation intact.
In `@src/onnxocr/inference_engine.py`:
- Around line 157-161: The model existence check in `inference_engine.py` still
uses `os.path.exists`, which violates the pathlib path-handling guideline.
Update the path check in the same block that raises `FileNotFoundError` to use
`pathlib.Path`-based operations instead, keeping the existing `model_path` logic
and error message behavior intact. Use the relevant `model_path` handling in
`inference_engine.py` so the code consistently follows the project’s pathlib
convention.
- Around line 71-77: 当前多个 docstring 仍使用英文,需按项目规范统一改为中文;请在
build_providers_from_engine_cfg、ProviderConfig 和 _default_session_options
这几个符号对应的 docstring 中,将说明性文本改写为中文,并保持含义一致、风格统一,确保整个 Python 文件的注释与 docstring
都符合中文注释规范。
In `@src/onnxocr/logger.py`:
- Around line 23-41: The info, debug, warning, and error methods in
Logger重复了相同的“按需 format + _format 前缀 + 转发到 od_log”逻辑,建议抽出一个内部辅助方法来统一处理。请在 Logger
类中新增一个私有 dispatch/helper(例如负责接收 level、msg、args、kwargs 并调用 od_log),然后让
info/debug/warning/error 只保留各自的级别入口并复用该公共逻辑,保持现有行为不变。
In `@src/sr_od/backend/entry/server.py`:
- Around line 57-68: 启动/运行期异常会被最终的 backend.shutdown() 覆盖,导致 backend.start() 或
server.serve() 的原始错误上下文丢失。请在 SrContext/SrBackendContext 的启动流程中,把 shutdown
放到独立的异常处理里,先记录并保留 start/serve 期间的原始异常,再执行清理。重点检查 await backend.start()、await
server.serve() 和 finally 中的 await backend.shutdown(),确保 shutdown
失败不会吞掉前一个异常,并在异常路径显式写入日志。
In `@src/sr_od/backend/mcp/app.py`:
- Around line 35-52: The _save_screenshot helper in app.py always creates a new
timestamped file and never removes old screenshots, so the
.debug/sr_od_mcp/screenshot directory can grow without bound. Add a cleanup
policy inside or alongside _save_screenshot (or in the screenshot directory
management path) to enforce either a retention window or a maximum file count,
and delete older files before or after writing the new image. Keep the existing
screenshot naming and write flow, but make sure the cleanup runs reliably in the
long-lived MCP server process.
In `@tools/mcp/daemon/create_startup_shortcut.ps1`:
- Around line 33-44: Wrap the WScript.Shell COM object lifecycle in a
try/finally block in create_startup_shortcut.ps1 so the object is always
released even if CreateShortcut, Save, or another step fails under
$ErrorActionPreference = "Stop". Keep the shortcut creation logic in the try
section around $WshShell, $Shortcut, and $Shortcut.Save(), and move the
ReleaseComObject call for $WshShell into the finally section with a null check.
In `@tools/mcp/daemon/start_daemon.ps1`:
- Around line 39-44: The daemon launch in start_daemon.ps1 relies on try/catch
around uv run, but that won’t reliably catch native process failures from
uv/python. Update the startup flow to invoke the existing daemon launch command,
then explicitly inspect $LASTEXITCODE after uv run completes and treat any
non-zero value as a startup failure. Keep the current error reporting in the
daemon-start script, but move the failure handling to the exit-code check so the
script reliably reports and exits when the daemon fails to start.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0f144a30-ea65-46cf-92ff-7a8f6f79f6c3
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (142)
.claude/CLAUDE.md.github/dev.md.gitignoreAGENTS.mdconfig/project.ymldeploy/OneDragon-RuntimeLauncher.specdeploy/build_full.batdeploy/generate_module_manifest.pydeploy/hook_path_inject.pydeploy/module_manifest.pydocs/develop/harness/README.mddocs/develop/harness/ai_tool_rules.mddocs/develop/harness/context_layering.mddocs/develop/harness/entry_files.mddocs/develop/harness/settings_scope.mddocs/develop/one_dragon/common-package-sync.mddocs/develop/one_dragon/runtime_launcher.mddocs/develop/setup/ai_coding.mddocs/develop/setup/claude-code/commit-trailer.mddocs/develop/setup/quickstart.mddocs/develop/sr_od/backend/README.mddocs/develop/sr_od/backend/architecture.mddocs/develop/sr_od/backend/design-principles.mddocs/develop/sr_od/backend/entry.mddocs/develop/sr_od/backend/http.mddocs/develop/sr_od/backend/mcp.mddocs/develop/sr_od/backend/remote-ssh.mdpyproject.tomlskills/sr-od-dev-deciding-a-fix/SKILL.mdskills/sr-od-dev-deciding-a-fix/design.mdskills/sr-od-dev-pr-finishing/SKILL.mdskills/sr-od-dev-pr-finishing/design.mdskills/sr-od-dev-skill-guide/SKILL.mdskills/sr-od-dev-skill-guide/design.mdsrc/one_dragon/base/conditional_operation/state_handler.pysrc/one_dragon/base/config/basic_model_config.pysrc/one_dragon/base/config/game_account_config.pysrc/one_dragon/base/config/notify_config.pysrc/one_dragon/base/config/yaml_operator.pysrc/one_dragon/base/controller/pc_controller_base.pysrc/one_dragon/base/matcher/ocr/onnx_ocr_matcher.pysrc/one_dragon/base/operation/application/application_factory_manager.pysrc/one_dragon/base/operation/application_base.pysrc/one_dragon/base/operation/context_event_bus.pysrc/one_dragon/base/operation/context_notify_event.pysrc/one_dragon/base/operation/notify_pool.pysrc/one_dragon/base/operation/one_dragon_app.pysrc/one_dragon/base/operation/one_dragon_context.pysrc/one_dragon/base/operation/operation_notify.pysrc/one_dragon/base/screen/screen_info.pysrc/one_dragon/base/screen/screen_loader.pysrc/one_dragon/base/screen/screen_match.pysrc/one_dragon/base/screen/screen_utils.pysrc/one_dragon/base/screen/template_info.pysrc/one_dragon/base/screen/template_loader.pysrc/one_dragon/devtools/python_launcher.pysrc/one_dragon/envs/env_config.pysrc/one_dragon/envs/git_service.pysrc/one_dragon/launcher/runtime_launcher.pysrc/one_dragon/utils/app_utils.pysrc/one_dragon/utils/cv2_utils.pysrc/one_dragon/utils/gpu_executor.pysrc/one_dragon/utils/http_utils.pysrc/one_dragon/utils/log_utils.pysrc/one_dragon/yolo/onnx_model_loader.pysrc/one_dragon/yolo/yolov8_onnx_cls.pysrc/one_dragon/yolo/yolov8_onnx_det.pysrc/one_dragon_qt/demo/draggable_list_demo.pysrc/one_dragon_qt/services/app_setting/app_setting_manager.pysrc/one_dragon_qt/view/app_run_interface.pysrc/one_dragon_qt/view/code_interface.pysrc/one_dragon_qt/view/devtools/devtools_image_analysis_interface.pysrc/one_dragon_qt/view/devtools/devtools_screen_manage_interface.pysrc/one_dragon_qt/view/devtools/devtools_template_helper_interface.pysrc/one_dragon_qt/view/one_dragon/one_dragon_run_interface.pysrc/one_dragon_qt/view/setting/app_notify_setting_interface.pysrc/one_dragon_qt/view/setting/resource_download_interface.pysrc/one_dragon_qt/view/setting/setting_env_interface.pysrc/one_dragon_qt/view/setting/setting_instance_interface.pysrc/one_dragon_qt/view/setting/setting_push_interface.pysrc/one_dragon_qt/widgets/app_run_list.pysrc/one_dragon_qt/widgets/app_setting/app_notify_setting_flyout.pysrc/one_dragon_qt/widgets/color_channel_dialog.pysrc/one_dragon_qt/widgets/fast_scroll_area.pysrc/one_dragon_qt/widgets/horizontal_setting_card_group.pysrc/one_dragon_qt/widgets/install_card/code_install_card.pysrc/one_dragon_qt/widgets/notify_dialog.pysrc/one_dragon_qt/widgets/scroll_credits.pysrc/one_dragon_qt/widgets/setting_card/app_run_card.pysrc/one_dragon_qt/widgets/setting_card/password_switch_setting_card.pysrc/one_dragon_qt/widgets/vertical_scroll_interface.pysrc/one_dragon_qt/windows/main_app_window_base.pysrc/onnxocr/inference_engine.pysrc/onnxocr/logger.pysrc/onnxocr/onnx_paddleocr.pysrc/onnxocr/operators.pysrc/onnxocr/predict_base.pysrc/onnxocr/predict_cls.pysrc/onnxocr/predict_det.pysrc/onnxocr/predict_rec.pysrc/onnxocr/predict_system.pysrc/onnxocr/readme.mdsrc/onnxocr/utils.pysrc/sr_od/app/sr_application_launcher.pysrc/sr_od/application/div_uni/__init__.pysrc/sr_od/application/div_uni/operations/__init__.pysrc/sr_od/application/div_uni/operations/choose_oe_file.pysrc/sr_od/application/div_uni/operations/choose_oe_support.pysrc/sr_od/application/div_uni/operations/ornamenet_extraction.pysrc/sr_od/application/trailblaze_power/trailblaze_power_app.pysrc/sr_od/application/treasures_lightward/__init__.pysrc/sr_od/application/treasures_lightward/op/__init__.pysrc/sr_od/application/treasures_lightward/op/challenge_mission.pysrc/sr_od/application/treasures_lightward/op/check_max_unlock_mission.pysrc/sr_od/application/treasures_lightward/op/check_mission_star.pysrc/sr_od/application/treasures_lightward/op/check_star.pysrc/sr_od/application/treasures_lightward/op/choose_character.pysrc/sr_od/application/treasures_lightward/op/forgotten_hall/__init__.pysrc/sr_od/application/treasures_lightward/op/forgotten_hall/choose_mission.pysrc/sr_od/application/treasures_lightward/op/forgotten_hall/choose_team_in_fh.pysrc/sr_od/application/treasures_lightward/op/forgotten_hall/get_reward_in_fh.pysrc/sr_od/application/treasures_lightward/op/tl_battle.pysrc/sr_od/application/treasures_lightward/op/tl_wait.pysrc/sr_od/application/treasures_lightward/treasures_lightward_app.pysrc/sr_od/application/treasures_lightward/treasures_lightward_config.pysrc/sr_od/application/treasures_lightward/treasures_lightward_const.pysrc/sr_od/application/treasures_lightward/treasures_lightward_record.pysrc/sr_od/application/treasures_lightward/treasures_lightward_team_module.pysrc/sr_od/backend/__init__.pysrc/sr_od/backend/backend_context.pysrc/sr_od/backend/entry/__init__.pysrc/sr_od/backend/entry/server.pysrc/sr_od/backend/http/__init__.pysrc/sr_od/backend/http/routes.pysrc/sr_od/backend/mcp/__init__.pysrc/sr_od/backend/mcp/app.pysrc/sr_od/backend/schemas.pysrc/sr_od/win_exe/__init__.pysrc/sr_od/win_exe/runtime_launcher.pytools/mcp/daemon/create_startup_shortcut.ps1tools/mcp/daemon/sr_od_daemon.pytools/mcp/daemon/start_daemon.ps1
💤 Files with no reviewable changes (3)
- src/one_dragon_qt/widgets/notify_dialog.py
- src/sr_od/app/sr_application_launcher.py
- src/one_dragon/base/conditional_operation/state_handler.py
- build_full.bat: copy 前先 mkdir config 目录(原 copy 到不存在的 config/ 会失败,包里缺 config/project.yml;ZZZ 也有此 bug) - common-package-sync.md: 表格内转义 |(markdown 列解析,markdownlint MD056) - backend_context: SrBackendContext.shutdown() 关闭 RunSlot._executor(原漏关致线程泄漏;加 RunSlot.shutdown() 封装) - sr_od_daemon: 主 server 进程检测改精确 argv 匹配(-m sr_od.backend.entry.server),避免子串误匹配;与同文件 --port 解析风格一致 Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
deploy/build_full.bat (1)
7-9: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win构建/拷贝步骤缺少失败检测。
批处理未对
pyinstaller、copy、xcopy的执行结果做errorlevel判断,任一步骤失败(如 PyInstaller 构建报错、源文件缺失)后脚本仍会继续执行并生成不完整的发行包,且不会有明显的失败提示。建议在关键步骤后添加errorlevel检查并在失败时提前退出。♻️ 建议的修复方向
uv run pyinstaller --noconfirm --clean "OneDragon-Installer.spec" +if errorlevel 1 ( + echo Build failed: OneDragon-Installer.spec + exit /b 1 +) uv run pyinstaller --noconfirm --clean "OneDragon-Launcher.spec" +if errorlevel 1 ( + echo Build failed: OneDragon-Launcher.spec + exit /b 1 +) uv run pyinstaller --noconfirm --clean "OneDragon-RuntimeLauncher.spec" +if errorlevel 1 ( + echo Build failed: OneDragon-RuntimeLauncher.spec + exit /b 1 +)Also applies to: 17-32
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/build_full.bat` around lines 7 - 9, The build script’s pyinstaller/copy/xcopy sequence does not stop on failures, so later packaging steps can run after an earlier error. Add errorlevel checks after each critical command in the batch flow around the pyinstaller invocations and the copy/xcopy steps, and exit early with a clear failure message when any command returns non-zero. Keep the checks consistent for all build stages so the script cannot produce a partial release package.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@deploy/build_full.bat`:
- Around line 7-9: The build script’s pyinstaller/copy/xcopy sequence does not
stop on failures, so later packaging steps can run after an earlier error. Add
errorlevel checks after each critical command in the batch flow around the
pyinstaller invocations and the copy/xcopy steps, and exit early with a clear
failure message when any command returns non-zero. Keep the checks consistent
for all build stages so the script cannot produce a partial release package.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 41f9c2fa-24f2-4e59-9f38-26f4a73513a0
📒 Files selected for processing (4)
deploy/build_full.batdocs/develop/one_dragon/common-package-sync.mdsrc/sr_od/backend/backend_context.pytools/mcp/daemon/sr_od_daemon.py
✅ Files skipped from review due to trivial changes (1)
- docs/develop/one_dragon/common-package-sync.md
🚧 Files skipped from review as they are similar to previous changes (2)
- src/sr_od/backend/backend_context.py
- tools/mcp/daemon/sr_od_daemon.py
概述
本会话积累的全部工作(25 commit,6 块),照搬 ZZZ(绝区零一条龙)已验证实现 + 按 token 清单(
common-package-sync.md§5)适配 SR 语境。内容
1. AI 编码 harness 体系(基础)
AGENTS.md+.claude/CLAUDE.md(@import单源)context_layering/entry_files/settings_scope/ai_tool_rules)2. sr_od 重构
app/{div_uni, treasures_lightward}→application/(沿用ApplicationFactory模式)3. MCP server 基础
sr_od/backend(schemas / backend_context / mcp / http / entry),照搬 ZZZtools/mcp/daemon(sr_od_daemon,端口 24000)pyprojectdev 组加 mcp / uvicorn / psutil4. runtime 启动器(可分发完整包)
sr_od/win_exe/runtime_launcher.pygenerate_module_manifest+hook_path_inject+RuntimeLauncher.spec+build_full.bat5. dev skills + harness 勘误
sr-od-dev-*3 个开发 skill(deciding-a-fix/pr-finishing/skill-guide),采纳 superpowers 流程方法论6. MCP backend 运行态完善(本 PR 重点)
start_run/query_status/stop(block同步/异步 + 中断安全语义)close_game+analyze画面匹配增强(依赖 common 的screen_match.py)get_run_status/stop_run/close,enter 加block)design-principles.md+ adapted async-operation spec验证
照搬 token 清单缺口(已补进
common-package-sync.md§5)本轮发现 5 类 sed+grep 都漏的 token:端口须用裸形式 /
zzz_backend_run(小写前缀)/ZPcController(Z 前缀业务子类)/ZenlessZoneZero字面量 /:2300端口片段 / spec 文件名引用。端口约定
主 server 24001、daemon 24000(避与 ZZZ 同机并存冲突)。
🤖 Generated with Claude Code
Summary by CodeRabbit
新功能
Bug 修复/优化
文档