背景:文档长期落后于代码(Tab 数、任务类型、接口示例等多处与现状不符), 且信息分散重复。这次按当前代码状态逐篇重写,并建立统一的文档体系。 新增 - doc/README.md:文档总索引(文档地图 / 推荐阅读路径 / **文档维护约定**) - doc/DATA_MODEL.md:数据模型(7 张模型表 + 5 张非模型表、迁移机制、app_meta 键、 数据目录、备份覆盖清单与双向自检) - doc/AI_CONSOLE.md:AI 控制台机制(会话与 SSE、经验库/动作库蒸馏与召回、巡检、 Markdown 渲染、推理链、token 统计、故障排查) 重写(按现状,去掉过时与重复) - README.md:7 个 Tab、18 种步骤、设备生命周期、调度/窗口语义、常见问题;修掉 「6 个 Tab / 分组为顶级 Tab」等过时内容与损坏的目录树 - doc/ARCHITECTURE.md:补启动装配顺序(import 期副作用、A~G 七阶段)、线程与锁清单、 设备状态机、调度全链路、前端结构与实时通道、设计决策、**已知缺陷与踩坑清单**、扩展点 - doc/API.md:按蓝图重建「接口总索引」(107 条路由含鉴权)+ 分域详细说明 + 非 JSON 响应汇总 + 错误分支速查 - doc/TASK_DEV.md:18 种步骤全表(参数/默认值/语义)、容器与公共参数、 选择器与 XPath 序号语义、抓取器建议规则、新增任务类型骨架 - doc/DEPLOY.md:容器入口 start.sh 三件事、发布流程与检查清单、备份覆盖红线、 按现象分类的故障排查 - doc/DEVELOPMENT.md:流程/红线/本地开发/**测试与写测试的约定**/配置速查/文档同步 - doc/MCP.md:19 个工具的参数级清单、坐标空间、写门控三连、安全与审计 - doc/MCP_DESIGN.md、doc/AI_TASK_GEN.md:标注设计 vs 实现现状,补交叉链接 - doc/backlog/TODO.md:新增「已知缺陷」小节(含复现与影响)+ 已完成留档 - .env.example:按代码实际读取的键重写(补 USB/DISCOVERY/MCP/AGENT,删死配置) 其它 - 项目名统一 auto_control:README/文档/scripts/pack.py 产物名;代码内的 doc 章节引用(templates/admin/monitor.html)同步更新 - 校验:16 篇文档 156 条相对链接全部可解析;文档中的关键数字与代码核对一致 (19 个 MCP 工具 / 18 种步骤 / 12 张备份表 / 1 种任务类型)
9.8 KiB
9.8 KiB
待完成项 / 已知问题(Backlog)
用途:记录已确认但暂缓的功能、优化与已知缺陷,避免丢线索。完成时移出本文件,并按「doc 同步红线」更新对应文档。 维护:新条目写清 背景 / 期望 / 涉及文件 / 验收;缺陷写清 现象 / 复现 / 影响。 相关:doc/README.md(文档索引与维护约定)。
A. 已知缺陷(尚未修)
A1. GET /locate 返回 500(设备定位大字页打不开)
- 现象:访问
/locate?serial=…直接 500。 - 原因:
web/monitor.py的locate_page()用了render_template_string与_esc,但该文件只导入了render_template,也没有_esc定义。 - 复现:
curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:18050/locate?serial=1.2.3.4:5555"→ 500(路由扫描脚本已确认)。 - 影响:「工具 → 设备池管理 → 定位」在设备上打开的大字页不可用(亮屏那半仍生效)。
- 涉及:
web/monitor.py(补 import / 补转义实现,或改用render_template+ 模板文件)。 - 验收:
/locate返回 200 且页面正确显示 serial/IP;纳入回归脚本。
A2. POST /api/device/locate(show=true)失败
- 现象:带
show=true调用时抛异常 → 502。 - 原因:
web/monitor.py用了urllib.parse.quote但未import urllib。 - 影响:无法远程把设备浏览器打开到定位页。
- 涉及:
web/monitor.py。验收:show=true时设备浏览器打开定位页且返回 200。
A3. CSRF 实际未启用
- 现象:
/api/csrf会签发 token、前端所有非 GET 请求都会带X-CSRF-Token,但服务端从不校验。 - 原因:
web_server.py只from web.auth import _csrf_protect,没有注册app.before_request(_csrf_protect);而web/auth.py的 docstring 声称"由 web_server 注册"。 - 影响:CSRF 防护形同虚设(同网段内可伪造写请求)。
- 涉及:
web_server.py(注册钩子)+ 需要回归所有写接口(前端、脚本、MCP 的platform_client都已带 token,风险点是第三方直接调 API)。 - 验收:注册后所有写接口在缺 token 时返回 403,且前端/MCP 全链路正常。
A4. 路由回归脚本在 Windows 上不可用
- 现象:
python scripts/regression_test.py直接报AttributeError: module 'signal' has no attribute 'alarm'退出。 - 原因:脚本用了 Unix 专有的
signal.alarm(第 29 行),docstring 里的示例路径也是.venv/bin/python。 - 影响:本机(Windows)开发时没有"一条命令扫全接口 500"的手段——A1/A2 这类 import 遗漏本可被它第一时间发现。
- 涉及:
scripts/regression_test.py(把signal.alarm换成跨平台超时,或hasattr守卫)。 - 验收:Windows 与 Linux 都能跑;能扫出 A1。
A5. 前端 --card-line 变量未定义
- 现象:AI 控制台的会话/经验/动作模态框边框失效(
border:1px solid var(--card-line)解析为无效值)。 - 原因:该变量只在
templates/admin/wall.html的:root定义,monitor.html的:root里没有,但被引用了 5 处。 - 涉及:
templates/admin/monitor.html(:root补--card-line:#232936)。
A6. monitor.js 引用了未定义变量 countParts
- 现象:进度为 0 的边界分支会抛
ReferenceError(被外层try/catch吞掉,用户无感)。 - 涉及:
static/admin/monitor.js(该分支的进度渲染)。
A7. 其它小问题(低优先)
static/admin/custom.css是死文件(无任何引用)。templates/admin/monitor.html里.agent-shell有完全重复的 CSS 声明(后者覆盖前者的min-height)。- 设备表空态
colspan="11"与实际列数(10)不符。 core/device_worker.py的_u2_connect_remote有两个结构相同的except Exception,后者是死代码。core/ssh_client.py全项目无人 import(STF_SSH_*配置也只被它读取);要么接上用途,要么删除。- 若干按功能域拆包时留下的重复函数定义:
_merged_device_list(web/common.py/apks_api.py/tools_api.py各一份)、tools_api.py的三个辅助函数、monitor.py的屏相关函数、tasks_api.py的_job_next_run(各定义两次)。
B. 设备与连接
-
adb 远程终端加「目标切换」(本机 / 220)
- 背景:终端默认走
.env的ANDROID_ADB_SERVER_ADDRESS=192.168.20.220(adb 客户端生效,非本项目代码读取),因此终端里看不到本机 USB 设备。 - 期望:
/api/adb/devices、/api/adb/cmd支持target=local|remote;前端tools.js加下拉。 - 涉及:
web/tools_api.py、static/admin/tools.js、doc/API.md、doc/DEVELOPMENT.md(配置速查)。 - 验收:切「本机」能列本机 USB + 已连
IP:5555;切「220」列 220 侧设备;adb cmd同样生效。
- 背景:终端默认走
-
.env的 adb 路由键要在文档里说明(或去掉)ANDROID_ADB_SERVER_ADDRESS/HOST/PORT会被.env注入os.environ,adb 客户端据此把所有调用指向 220;ANDROID_ADB_SERVER_HOST是非标准键(adb 不认)。- 期望:在配置速查里写明该行为与取舍,或本地去掉这三行改走本机 adb。
-
.gitignore漏项:data/mcp_audit.log与data/uiauto.pid未被忽略(git status会显示为未跟踪);data/apks/目录无占位文件。 -
220 的 Tailscale / adb server(5037) 可达性巡检(曾出现连不通超时)。
C. 编辑器 / 元素抓取
-
未命中要「明确提示」,别混成「执行了这步」
- 背景(2026-09-10):click/long_click/wait_el/swipe_until/if_el 未命中时只写
[WARNING] ... 未找到元素,前端进度仍按"执行了一步"计数 → 用户看到像"成功",实际没点(db03f16e 案例就是这么误判的)。 - 期望:执行器把未命中作为该步结果(✗)返回并计入统计;前端标红 ✗ 并给出所用选择器;任务结束汇总未命中步骤数。
- 涉及:
tasks/generic/task.py、static/admin/{tasks,monitor}.js、doc/TASK_DEV.md。
- 背景(2026-09-10):click/long_click/wait_el/swipe_until/if_el 未命中时只写
-
元素抓取超时——部分设备 dump 慢于平台超时
- 背景(2026-09-10 实测):
core/uiauto_helper.py的_TIMEOUT=(1,8);某设备 dump ~18s → 平台报「uiauto2 请求超时」,编辑器抓不到元素(设备本身正常)。 - 期望:读超时提到
(2, 30)+ 前端加载中有明确提示;可选"同界面短时缓存"。 - 涉及:
core/uiauto_helper.py、web/tasks_api.py、static/admin/editor.js、doc/ARCHITECTURE.md。
- 背景(2026-09-10 实测):
-
序号型 XPath / 界面就绪 的防呆(2026-09-10 db03f16e 案例)
- 背景:
(//*[@resource-id="…"])[6]依赖"抓取那一刻该属性有 ≥6 个实例";运行时界面不同(App 仍在闪屏页)→ 序号必然失配。 - 期望:①
open_app提示勾选「等待首页」;② 抓取器对带序号的选择器加醒目提示;③ 抓取弹窗提醒"请先把设备停在任务运行到该步时的同一界面再抓"。 - 涉及:
core/uiauto_helper.py、static/admin/editor.js、tasks/generic/task.py、doc/TASK_DEV.md。
- 背景:
-
自定义动作支持
action_ref引用型节点(现状:拖入画布会展开成 group,改动需同步执行器 + 编辑器)。
D. AI 控制台 / 经验与动作
- 「🧠 经验库 / 🎬 动作库」合为一个面板(标签页切换)。
- AI 建任务 P0:平台级 MCP 工具(只读清单
task_types/groups/pool+submit_task(draft)校验)+ 把动作库当作 generic_steps 的预制件复用(见 AI_TASK_GEN.md §9)。 - 新增 MCP
de_screen_text(文本化看屏:前台包名 + screen_state + 可点元素文本 + OCR),并把操作纪律写进工具 description。 - 经验召回改进:现为 bigram +
ORDER BY hits(候选只看 top50、hits 对所有命中行回写 → 马太效应);改为对称相似度 / 更合理候选集,hits仅在真正注入时 +1。 - 经验/动作入库依赖模型蒸馏成功:加失败重试与可视化观测(现在只在日志里)。
E. 工程化 / 文档
- MCP 白名单语义缺口:
MCP_ALLOWED_SERIALS为空时并未按设计限制为"平台设备池内"(当前只校验非空),见 MCP.md;如需收紧需补实现。 MCP_DESIGN.md里的"演进备选"(独立 mcp-server 容器)未落地:已在文中标注,若确定不做可删除该节,避免后续误读。- STF 容器状态确认:
doc/DEVELOPMENT.md(已停用)与doc/STF_REMOVAL.md(待人工确认)说法矛盾,需以 220 实际为准后统一。 DISCOVERY_SUBNETS无 env 支持:config.py里是硬编码列表,其余发现配置走app_meta;若要支持.env覆盖需补实现。
F. 已完成(留档,便于追溯)
platform-tools→auto_control命名统一(2026-09-10:文档/README/scripts/pack.py产物名)。- 删除抖音养号任务类型(
douyin_nurture),平台只保留generic_steps;残留旧类型任务改为启动告警 + 执行时明确报错。 generic_steps去掉默认步骤;空步骤任务执行时明确报错(不再静默空跑)。- 重试耗尽时的
last_error带上真实失败原因(不再只有"重试 N 次失败")。 - 监控页任务卡去掉「编辑/删除」,只留执行/停用 + 显示覆盖设备。
- 备份覆盖清单补
agent_action/app_meta+ 导出/导入双向自检。 - AI 控制台:Markdown 渲染、推理链可折叠、token 用量显示。