butubb
|
2c32c397c8
|
feat(日志): 日志页支持关键字/级别/时间过滤 + 下载(含滚动历史)
「日志」页原来只能 tail 固定行数、且文件下拉写死了 4 项(新增的 notify.log
根本选不到)。本次:
- core/logger.py 新增读取接口:list_log_files()(模块文件 + .1/.2 滚动历史,
白名单)、query_log()(关键字/最低级别/时间过滤,返回结构化行)、
read_log_text()(导出)。
· 时间/级别过滤对**续行**用继承值(traceback 缩进行本身没有前缀),
按 ERROR 筛不会把堆栈拆散;
· 过滤按"最近 N 条命中"返回,保持文件原顺序;
- GET /api/logs 换新协议(rows/files/matched/scanned/truncated),
新增 GET /api/logs/download(附件下载,支持同样过滤;无一条件时整文件);
- 顺带修 **目录穿越**:原实现 os.path.join(_LOG_DIR, file) 可用 ../../ 逃逸,
现在 file 必须命中白名单;
- 顺带修 web/admin_api.py 里 _log 未定义(用户增删改的日志行会 NameError);
- 前端:文件下拉改为按接口渲染、加关键字(命中高亮)/级别/时间范围/下载/重置,
自动刷新时不再把正在上翻的用户拽回底部。
文档:doc/API.md §10.1(参数与返回)、README 日志节。
|
2026-09-16 08:44:19 +08:00 |
|
butubb
|
97cec6e211
|
feat(通知): 系统级 Webhook 通知子系统(事件目录 + 可插拔适配器 + 防刷屏)
平台此前出了问题只能靠人盯页面。现在各组件统一走 `notifier.notify(事件, **字段)`,
推到企业微信 / 自建服务;**所有可通知点都登记进事件目录,默认全关,用户按 webhook 勾选**。
## 架构(`core/notifier.py` + `core/notify_events.py`)
业务线程调 `notify()` → 只做内存操作(读配置快照/匹配订阅/入队)→ 返回;
后台 1 个 dispatcher(聚合 + 每 hook 限流 + 折叠摘要)+ 3 个 sender(真实 HTTP、退避重试)
负责真正发出去。硬约束:**notify 零 DB、零 HTTP、零阻塞、异常不冒泡**——所以任务线程里
可以直接调(不用 app_context、不用 try/except),但**必须放在所有 `with self._lock` 之外**。
- **事件目录 36 条**(任务批次/单设备/设备/Worker/业务/安装/系统/AI),支持 `task.*` 通配订阅;
语义分工避免重复告警:`worker.*` 是单次尝试级,`task.device.success/failed` 是唯一权威结论。
- **适配器可插拔**:`wecom`(markdown,按 4096 **字节**截断、超限不截半个汉字)+
`json`(模板占位符,替换值按 JSON 转义,保存前干跑校验);钉钉/飞书留了插槽(前端置灰)。
- **防打爆四层**:聚合窗口(默认 30s,同批次合并成一条并带样本)→ 令牌桶限流(默认 18/分,
对齐企微硬限 20)→ 被限流的**折叠成摘要不丢弃** → 有界队列背压。取舍:失败通知最多延迟
一个窗口,换来群不被刷屏。
## 安全与存储
- 配置只落 `app_meta.notify_webhooks` 一个键(**不建表** → 不涉及备份覆盖红线)。
- URL 本身就是凭据(企微 `?key=`)→ 接口回显/发送记录/日志一律 `mask_url()/scrub()`;
编辑时留空即不修改;secret 永不回显。DATA_MODEL 的明文凭据告警补上了这一条。
- 发送记录:内存环形缓冲 200 条(重启清空)+ 独立 `logs/notify.log`。
## 接入点(每个都放在锁外、不改 return 顺序)
task_manager(批次开始/结束用新增的 `_BatchTracker` 统一在 finally 计数、单设备成功/失败/
离线/重试/停止/抢占/归还/cron 停止)、device_worker 心跳看门狗、generic 任务选择器连续失效、
apk 安装开始/完成、设备上下线(**状态沿检测**,只报新变化)、备份导出/恢复、经验巡检、
用户登录、服务启停。
## 前端
系统 Tab 新增「通知 / Webhook」子分栏:多条 webhook 列表(URL 打码)+ 编辑弹窗(格式/URL/
密钥/事件勾选树带 ★建议/聚合/限流/自定义模板/预览)+ 发送测试 + 发送记录。
## 自测
- 进程内逻辑 10 组断言全绿:聚合合并、限流+折叠、无配置/全局关静默丢弃、未知事件、
内部异常不外泄、JSON 转义(标题含引号换行仍合法)、URL/异常消息脱敏、配置校验。
- 端到端(假 webhook 接收端)17 项断言全绿:真实事件投递(user.login / task.batch.no_device)、
企微请求体形状、**HTTP 200 + errcode 93000 判为失败**、500 重试 3 次、记录里 URL 打码。
- 韧性:webhook 指向黑洞地址时登录耗时 100~114ms(基线 107~133ms,**异步隔离生效**);
配置写成坏 JSON 服务照常启动、通知静默不发、日志有 error(服务端实测后已复原)。
- 页面:系统 → 通知 面板/弹窗/36 个事件复选框/预览全部正常,无 JS 报错。
- 自测数据已清理(webhook、自建任务、写坏又复原的配置键)。
文档:新增 doc/NOTIFY.md(事件表/配置/格式约束/防刷屏/加事件三步骤/排障)并登记进 doc/README;
API.md §2.11;DATA_MODEL 的 app_meta 键表与明文凭据告警;ARCHITECTURE 线程表/分层/扩展点;
根 README 功能索引与日志表。
|
2026-09-15 13:55:14 +08:00 |
|
butubb
|
5e0a7d5556
|
fix(屏幕): 一键息屏不再唤醒已眠设备 + 「保持亮屏」对不充电的设备生效
用户反馈两条:
1. 监控页「一键息屏」像是把设备**唤醒**了(按钮行为"反");
2. 任务里的「保持亮屏」没用。
根因:
1. `POST /api/device/screen_all` 的 off 分支发 `input keyevent 26`(KEYCODE_POWER)——
那是电源键**开关**:对亮着的设备是熄屏,对**已经息屏的设备反而是唤醒**。
2. `keep_screen` 只发 `svc power stayon true`,它管的是「**充电时**屏幕常亮」
(stay_on_while_plugged_in)。设备走 WiFi 跑任务、没插充电器 → 完全不生效。
修法:
- 息屏改用 `KEYCODE_SLEEP(223)`(单向:只熄不亮)。
- 保持亮屏改成把系统**息屏超时**顶到最大(`settings put system screen_off_timeout
2147483647`)+ 顺带 `svc power stayon true` + 立刻 `KEYCODE_WAKEUP` 唤醒一次;
`mode=off` 时写回原值(进入时读一次记在内存;进程重启丢了记录就写回 10 分钟兜底,
`settings get` 返回 "null" 的机型也走兜底)。
- 文案/文档同步:编辑器里的步骤说明、TASK_DEV 步骤表、API.md 的接口行为。
自测(按用户要求不动机器):py_compile / node --check 通过;用假设备对象断言命令序列——
保持亮屏发 `settings get` → `stayon true` → `put …2147483647` → `keyevent 224` 并记住原值;
恢复写回原值 60000 且清空备份;原值为 null 时兜底 600000。
|
2026-09-15 13:24:28 +08:00 |
|
butubb
|
615f9cf0d5
|
fix(APK 安装): 「推送不完整」是误报——adb 退出 ≠ 设备写完
用户报:安装 APK 显示「推送不完整(设备 3605447 / 本地 5933150 字节)」。
排查(220 现场 + 复现):这不是传输失败,是**检查时机太早**。
`adb exec-in` 把数据交给设备侧(adbd → shell → `cat >`)后,缓冲里的数据还在继续落盘:
同一份 5.9MB 的 APK,adb 刚返回时 stat 读到 3710967,紧接着 4264448,几秒后才是完整的
5933150(逐步实测)。旧实现只量一次就判失败,于是同一份文件在多台设备上"失败"了 8 次,
断点各不相同(2.7M/3.3M/3.6M/3.9M)—— 典型误报指纹。
修法(core/apk_manager.py):
- 新增 `_wait_remote_size()`:收尾**轮询**设备文件大小直到长齐(默认最长 20s);
stat 取不到(机型差异)时返回 None,照旧跳过校验,不误报。
- 只有真不齐才退回 `adb push` 重传(原来直接判失败)。
- `_push_fallback` 也补一次大小校验:adb push 虽同步,但设备空间不足/被并发覆盖时
"1 file pushed" 也可能是残缺的。
影响:这个误报不只是显示难看——它会让整台设备的安装直接失败(明明是好的包)。
|
2026-09-14 09:08:37 +08:00 |
|
butubb
|
ed9e8bacb1
|
feat(AI 建任务): 直接创建 + 草稿沉淀 + MCP de_snapshot;修「建任务页收不到 done」
用户报的"探索完无法点击创建任务"真因:一个 run 的事件原先只有**一条** queue.Queue,
聊天页与建任务页同时开着时两个 EventSource 会**瓜分**它——建任务页的回放卡在中间、
`done` 被聊天页取走 → 永远等不到草稿,页面上自然没有可点的"创建"。
一、修(根因 + 表现)
- `web/agent_api.py` 新增 `_Fanout`:**每个订阅者一个专属队列**,多开页面各看各的,
还带单轮事件缓冲(晚订阅/刷新重连也能补齐回放,终止事件一定送达)。
实测两路订阅者收到完全一致的 1039 条事件(含 done)。
- `static/admin/agent.js`:断线重连的兜底订阅也按 `mode` 让开(此前漏了这一处)。
二、补齐上一批的三项
- **「直接创建」**:`POST /api/agent/task_draft/create`(草稿体只在服务端、创建前再校验一次、
成功后清草稿避免重复建)+ 草稿预览里的「✓ 直接创建任务」按钮 + 「探索完直接创建任务」勾选框。
- **草稿沉淀经验/动作**:designer 轮次也走 `_distill_experience/_distill_actions`,
但**只在草稿通过校验时**(没走通的试错不入库,免得把误点当经验)。
- **MCP `de_snapshot`**(第 20 个工具):截图+元素树一次取齐(省一次来回、不会因界面在动而错位),
附带 `screen_state`/`unstable`;两套提示词都改为优先用它。
平台侧 `/api/uiauto/snapshot` 随之多返回 `screen_state`。
三、文档
- AI_TASK_GEN §10:§10.3 记两个 bug 的真因与修法、§10.4 三项标完成、§10.5 剩余项。
- AI_CONSOLE(扇出语义、多页面同时看一轮)、API(task_draft/create、snapshot 字段)、
MCP/MCP_DESIGN/staffdeck/README/ARCHITECTURE:工具数 19→20 + de_snapshot 条目。
- backlog:记一条新发现的缺陷——`mcp_server/platform_client._login()` 会把"登录页 200"
当成登录成功(现场进程缺 `MCP_PLATFORM_PASS` 时表现为含糊的 platform_unavailable)。
自测:真机浏览器端到端(勾上"探索完直接创建")→ 探索 12 步 → 草稿 → 自动建任务成功;
`de_snapshot` 直连真机校验;校验器 21 条用例、扇出单元用例、本地工具契约用例全绿。
自测产生的任务/草稿已全部清理(未碰用户既有数据)。
|
2026-09-14 08:14:11 +08:00 |
|
butubb
|
46e6ea1f37
|
feat(AI 建任务): AI 自己在真机探索 → 写出可调度任务 → 人工确认入库
AI 控制台下新增子分栏「🧭 AI 建任务」:描述要做什么(例:建一个跑 2 小时的任务、自动刷
某 App、随机点赞),AI 用 de_* 工具自己在设备上探索(看屏/读元素树/点按验证),把走通的
路径写成一条任务草稿,经服务端校验后交人在步骤编辑器里核对/手改/试跑,保存才入库。
链路:POST /api/agent/run{mode:"designer", settings}
→ Agent 自探 → 本地工具 submit_task(draft)
→ core/task_draft 校验(失败把 errors 回灌模型让它改)
→ 只暂存(运行态 + app_meta.agent_task_draft,**不落库**)
→ SSE done{mode,draft,warnings} → 页面草稿预览 → openTaskModal(null, prefill) 预填
关键实现
- core/task_draft.py(新):把执行器的"静默跳过点"(未知 type/空 selector/空 children/
嵌套>5/节点>60/cron 非法/必填缺失)前移成显式 error——POST /api/jobs 对 params 是盲存的,
执行器又静默跳过错误步骤,没有这道闸门就是"任务建好了、跑起来什么都没做"。
归一化兜底任务名/target/schedule/retry/时长;页面填的设置以 overrides 优先于模型。
故意**不比执行器更严**:loop_mode 近义值归一(count→rounds)、缺 max_iterations 补默认 10
(执行器本来就默认)——实测卡太死会把一轮探索耗在改字段上。
有副作用的步骤(评论/发送/购买/删除…)只警告并把触发概率压到 30%(编辑器可改回)。
- mcp_agent/agent.py:双系统提示词(CHAT/DESIGNER)+ 平台级本地工具
(LOCAL_TOOL_SPECS,不进 MCP)+ 每工具调用上限 40 + designer 输出上限 8192 +
**json.loads 容错**(草稿被截断时给模型可读错误,而不是整轮失败)。
- web/agent_api.py:mode/settings 透传、submit_task 处理器(app_context 内校验+暂存)、
done 带 draft、GET /api/agent/task_draft{,+POST,/clear}(草稿走 app_meta,不新建表)。
- 前端:static/admin/taskgen.js + #agent-sub-taskgen 子面板(showSubTab 机制);
tasks.js 的 openTaskModal(jobId, prefill) + 信封归一化 + 唯一 draftKey;
agent.js 按 mode 门控(一个 run 只有一个事件队列,两个 EventSource 会互相瓜分事件)。
顺带修掉一个 chat 也踩的协议 bug:一轮里同时调 de_screenshot 与别的工具时,截图图像会被
插在两条 tool 消息之间 → 模型侧判"工具回应不足"直接 400。改为本轮 tool 消息发完再附图像,
_repair_tool_messages 也改成只数**连续**的 tool 消息。
真机实测(Redmi 22120RN86C,设置页):8 步探索(含 tap_text 验证)→ submit_task 一次通过 →
草稿 8 个顶层步骤(screen_on/open_app/wait_el/click/wait/key_event…)、max_duration 1800、
无 click_xy、3 条 evidence;页面恢复草稿 + 预填编辑器 + 提示块渲染均正常,无 JS 报错。
自测数据已清理(草稿已丢弃、未创建任何任务)。
文档:AI_TASK_GEN.md 状态改「P0 已实现」+ §10 实现记录(差异/护栏/未做项)、AI_CONSOLE.md
(子分栏、designer 分支、SSE done 负载、app_meta 键)、API.md、DATA_MODEL.md、ARCHITECTURE.md、
DEVELOPMENT.md(自测入口)、README.md 索引、backlog 勾掉 P0。
|
2026-09-13 23:08:59 +08:00 |
|
butubb
|
0bc713137d
|
feat(抓取): 选择器优先语义化(同 id 多实例用 @text 限定,而非序号)+ 修掉两类"死选择器"
语义消歧(B 项):主属性在整棵树里重复时,先找第二个属性把目标单独圈出来 ——
//*[@resource-id="x" and @text="我"] (次属性 text > content-desc > class,
单个不够就两两组合)
标 semantic:true + via;只有组合也分不开(列表里同 id 同文字)才退回
(//*[@resource-id="x"])[k] (标 indexed,前端黄标提醒脆弱)
抖音底部导航正是这个场景:tab 个数随灰度版本变(4 个 ↔ 3 个),序号必然错位。
顺带修掉两个结构性缺陷(给上面做验证时逐条 lxml 求值发现的,均非本次引入):
1. 结构步进把 class 当标签名 —— dump 的 XML 标签**一律是 <node>**,class 在
@class 上,所以 //FrameLayout[1]/… 这类路径**永远零命中**;改 *[@class="…"][n]
2. 兜底结构路径用 @index 定位兄弟 —— 实测同级 index 会重复(状态栏/内容区/
导航栏三个兄弟全是 index="0");改按子节点位置 //hierarchy/*[1]/*[2]
前端:抓取列表把 text/content-desc 排到最前并加粗上色(最稳的定位依据);
序号型从蓝标改**黄标 ⚠ 序号 k/n**,语义型给**绿标 ✓ 语义**;属性页新增
「选择器稳定性」一行说明这个选择器靠什么定位、会不会因界面变化失效。
真机实测(192.168.20.100,248 个元素):
精确命中目标 221 → 247 | 死选择器 26 → 0 | 语义型 0 → 26(序号型 141 → 115)
「我」的语义选择器经 /api/steps/test 真机点击 → 命中 ✓
文档:TASK_DEV §5.3/5.4(含两个 XPath 坑)、API §8(suggested 字段表 +
snapshot 行)、research/U2_ELEMENT_SELECTORS §五/§六、backlog ②标记完成。
|
2026-09-13 22:05:47 +08:00 |
|
butubb
|
37a2b1c59b
|
feat(抓取): 元素检查器改成本地版"大图 + 一次取齐"——复刻云检查器的体验
用户要的是 uiauto.dev 那个检查器的体验(左边大图点元素、右边层级树、选完回填),
并希望本地复刻(云页面跨域,拿不到它的选中结果,没法自动回传)。
- core/uiauto_helper.py: 新增 `snapshot(serial)`
* **一个 u2 连接背靠背** dump_hierarchy() + screenshot():截图与元素树同源同刻,
不再像原来那样分两个接口取(中间隔着 dump 本身的 1.3~1.8 秒)
* `_xml_to_node()`:把 u2 的 XML 节点转成 uiautodev 那套结构,直接复用既有的
选择器建议逻辑(不写第二遍)
* **双截图校验**:dump 前后各截一张,差异明显就标 `unstable`,让前端明确提示
"界面在变化中,请停在静止界面再抓",而不是悄悄给一个可能错位的框
- web/tasks_api.py: 新增 `GET /api/uiauto/snapshot`(登录 + 设备权限)
- static/admin/editor.js + templates/admin/monitor.html:
* 抓取弹窗从 900px 加宽到 1280px,预览列从"固定 320px"改为铺满左侧 →
**图片按原始分辨率 1:1 显示**(实测 720x1650 缩放 1.000),元素框严丝合缝;
原来缩到 294px 时框全挤在一起,看着就像错位
* 工具栏显示 `720x1650 · 247 个元素 · 2370ms`;界面在变时顶部弹黄色提示条
* 鼠标在图上移动时高亮"最深命中"的元素框,便于确认真要点哪个
实测:抓取弹窗 1:1 显示、222 个框逐一贴合元素、无 JS 报错;
`unstable` 在静止界面为 false。
|
2026-09-13 21:17:12 +08:00 |
|
butubb
|
3422b4f265
|
feat: 监控页按名称排序 + 按钮改「看屏 / 打开设备端 Agent」;设备名匹配补 USB 设备
用户反馈的三件事:
1) **监控页设备排序**改成按**名称**(A01/A02/…),没名字的排最后按地址。
之前是 adb 返回的顺序,看着像按 IP 排,同型号多台时对不上号。
排序放在 `/api/status`(后端),大屏页一并受益。
2) **操作按钮改名 + 换实现**:
- 「截图」→「**看屏**」(行为不变,就是查看设备实时画面)
- 「定位」→「**打开设备端 Agent**」:改成让设备上的 Agent 弹身份大字页
(名称/IP/平台地址),替代原来"推 HTML 让设备浏览器打开定位页"那套
(那套要设备装浏览器、页面还依赖设备能访问平台,backlog A1/A2 一直没修)
* 新接口 `POST /api/agent/show-info {serial, close?}`;没装 Agent 时明确报出来
* **先点亮屏幕 + 解除锁屏再拉起** —— 设备息屏时 am start 会把大字页开在锁屏后面,
人看到的还是一片黑(实测踩过)
* 平台地址取操作者当前访问地址;若是 localhost 则换成本机局域网地址
(设备上显示 127.0.0.1 毫无意义)
3) **安装应用的选择设备界面仍显示裸序列号**:USB 设备在 adb 里的 serial 就是
`ro.serialno`,等于池里那条网络记录的**指纹** —— 之前只按 serial 匹配,插着 USB
时会冒出一个没名字的 `s8o7nrt8pbzhfadq`。现在按 serial 或指纹任一命中都取名称,
三处(剪贴板注入 / 安装弹窗 / 安装进度表)统一。
顺带修掉几个自己踩出来的坑:
- `device_pool.list_configured()` 返回的是 **serial 字符串列表**,我当成字典用了
(`.get("serial")` 抛异常被 except 吞掉 → 名字全空)→ 改用 `list_devices()`
- `web/device_agent_api.py` 用了 `PERM_DEVICES` 但没导入 → 服务直接起不来(502)
- Agent 自检里的版本号是写死的常量(升到 1.4 还显示 1.0)→ 改成读包信息
- `doc/API.md` 章节编号(插了一节没把后面整体下移,出现两个 §16)
验证:安装弹窗里 USB 那台现在显示「A07」(指纹匹配);监控页按钮为
「看屏 / 打开设备端 Agent」;对装/未装 Agent 的设备分别得到大字页 / 明确报错;
大字页实测显示 A07 + 192.168.20.250:18050 + Agent v1.4。
|
2026-09-13 17:18:30 +08:00 |
|
butubb
|
3f041668ec
|
feat: 设备配置二维码——设备池里出码,Agent 扫一下配好
配合设备端 Agent 新增的「扫码配置」:人在机架前、设备还没接进平台时,
不用插线也不用在手机上打字输地址/令牌(还容易漏指纹)。
- `GET /api/devices/qrcode?serial=`:生成配置二维码(PNG data-url),内容为
{"v":1,"server":…,"token":…,"fingerprint":…,"name":…}
* 前置:设备端商店已启用(令牌从那儿来),否则 400 并说明去哪儿开
* `warn` 非空必须显示:①用 localhost 打开平台时,二维码里的地址手机会连不上
(提示改用局域网地址,_lan_ip() 优先挑 192.168/10.x,**不用** gethostbyname ——
那会返回 Tailscale 的 100.x 或 docker 的 172.17,手机根本连不上)
②设备还没采到指纹 → 扫完平台认不出是哪台
- 设备池每行加「二维码」按钮 → 弹窗显示二维码 + 设备名/地址 + 可展开看原始内容
- requirements 加 qrcode(纯 Python,配合已有的 Pillow 出 PNG,不引前端二维码库)
- 文档:API.md §6.2.2 新增、§6.2.1 名称呈现表补齐(剪贴板/安装弹窗/版本管理/
安装进度四处);DEVICE_AGENT.md §5.3 新增二维码内容格式(设备端契约)
验证:二维码用 cv2.QRCodeDetector 解回来与 payload 完全一致;手机上实测——
扫 A07 的码 → 相机启动 → 解码 → 保存 → 立刻拉清单,平台认出「A07」。
|
2026-09-13 16:42:53 +08:00 |
|
butubb
|
cdf06e1929
|
fix: 大 APK 推送到设备时显示实时进度(原来是整段黑箱干等)
问题(用户反馈):从网页点「安装」到设备,包大的时候(抖音 336MB)只显示
一句「正在推送 APK...」,传了两分多钟全程没有任何进度,像卡死了。
根因:推送用的是 `adb push`,它**只在结束时**吐一行汇总
("1 file pushed, 3.0 MB/s"),中间过程什么都不给。
改法:分块写 + 实时进度
- core/apk_manager.py 新增 `_push_with_progress()`:改用 `adb exec-in "cat > 文件"`
自己按 1MB 分块喂数据,每块更新一次状态(限流 0.8s 一次):
`推送中 62%(211.0/336.1 MB · 2.6 MB/s · 剩约 48s)`
传完校验设备上文件大小;中途断流/exec-in 不可用时**退回原来的 adb push**(保证兼容)
- 代价:实测速度 2.6 vs 3.1 MB/s(慢 17%),换来看得见的进度,划算
- 「正在设备上安装...」补上预期时间说明 —— `pm install` 在设备端解包
(336MB 实测 ~65s),系统没给进度接口,只能给预期值
- static/admin/apps.js:安装进度轮询 3s → 1.5s;表格里再加一条细进度条
(大包要一两分钟,光有文字不够直观)
- doc/API.md:把安装状态机的两段式进度与耗时参考写进接口说明
实测(抖音 v40.4.0 336.1MB → 192.168.20.100,单台):
推送 60%→100% 每 2 秒一档,速度稳定 2.6 MB/s,134s 传完;
设备端安装 65s;端到端 ~200s,全程有进度可看。
全量回归 106 项通过。
|
2026-09-13 15:38:14 +08:00 |
|
butubb
|
dad1af8b0b
|
feat: 设备端应用商店(平台侧)—— Agent 直连拉清单/下载/安装,绕开 MIUI 的 USB 安装拦截
背景:`adb install` 在 MIUI 上被「USB 安装」拦下(USER_RESTRICTED),必须人工点确认;
而**由设备上的 App 自己调系统安装器**走的是普通应用安装流程,不触发那道拦截。
平台侧实现(设备端 Agent APK 在另一个仓库,契约见 doc/DEVICE_AGENT.md):
- web/device_agent_api.py(新):
* 设备侧 `/api/device/agent/{bootstrap,apk/<id>,report}` —— 无登录会话,靠
`X-Device-Token`(常量时间比对)鉴权;`X-Device-Fingerprint` 让平台认出是哪台设备
(换 IP 也认得出,并把平台分配的名称回给它);**默认关闭,关闭时统一 404**,
不暴露接口存在性;只读清单与文件,不返回任何配置/密钥
* 管理侧 `/api/agent-store/{config,logs}` —— 登录 + 应用管理权限;启用时自动生成令牌,
可一键重置(旧令牌立即失效)
- core/models.py:新增 `device_install_log`(下载/安装记录,自动裁剪保留 500 条)
- 应用管理页新增「📱 设备端应用商店」面板:开关 / 接入地址 / 令牌(复制·重置)/ 安装记录;
面板里写明它与「平台批量推送」的分工
- doc/DEVICE_AGENT.md(新):**两个仓库共享的接口契约** —— 接入流程、三个设备接口的
完整规格与错误码、adb 指令协议(剪贴板/身份显示/配置下发)、版本兼容约定、安全须知;
API.md、DATA_MODEL.md、doc/README.md 索引同步
验证:
- 后端 9 组用例:默认关闭 404、无/错令牌 401、指纹认出设备名、清单、下载、上报与失败
原因落库、关闭后重新 404、重置令牌后旧令牌立即失效、未登录管理端被拒 —— 全通过
- 真实浏览器:面板渲染、点开关 → 自动生成令牌 → 设备端带令牌拉到清单且 device.name=A08、
无 JS 报错;测试后已把开关还原为关闭
- 全量回归 105 项通过(42 GET + 62 写探测 + 7 关键业务)
|
2026-09-13 14:40:38 +08:00 |
|
butubb
|
2a3775ffd5
|
docs: 同步 P5 备份机制重写——DEPLOY §5 / API §13 / DATA_MODEL §7 / DEVELOPMENT §4.3
- DEPLOY §5.1: 说明 SQLite 现在是「备份交换格式」,恢复走单事务整库替换,
跨环境导入默认拒绝;§5.2 覆盖清单改为「由 metadata 派生」;§5.3 三个目录
支持环境变量覆盖及原因
- API §13: 导出/预览/应用三个接口的字段补齐(db_backend/deployment_env/
source_db_id/source_env/current_env、force_env_mismatch、pre_restore zip)
- DATA_MODEL §7: pre_restore 改 .zip、补目录可覆盖说明
- DEVELOPMENT §4.3: 补三个备份目录环境变量
|
2026-09-13 10:35:26 +08:00 |
|
butubb
|
79cdf61ed2
|
feat: 自动认领开关 + 全站按设备名称显示
一、指纹匹配自动认领(可选,默认关)
- 发现设置新增「指纹匹配自动认领」勾选(app_meta: discovery_auto_claim,默认 0)
- 打开后:扫描发现某设备指纹与池中已有记录一致(同一台换了 IP)→ 自动迁移记录到新地址
并同步分组/任务引用,零点击;关闭时维持"识别自动 + 人工点一次确认"
- 默认关的原因:认领会改写分组/任务引用(数据结构变动),交人工确认更稳妥
- 扫描结果与状态行会显示本轮自动认领了几台
二、设备名称在界面上呈现(凡选择/展示设备处都显示名称)
- 新增前端 helper `devText(name, serial)`(base.js):有名称→「名称 · serial」
- 监控页设备表:名称加粗为主、地址作副行(未命名显示橙色提醒);任务概况的覆盖设备
chip 也优先显示名称(tooltip 保留完整地址)
- AI 控制台:目标设备下拉、实时画面设备下拉、目标/运行中提示都带名称(serial→name 映射)
- 任务编辑器「指定设备」下拉、分组编辑的设备勾选列表:带名称
- 后端 `/api/devices` 新增 `items`([{serial,name,model}],`devices` 保持兼容);
`/api/agent/devices` 增加 `name` 字段
- MCP `de_list_devices` 返回 `name`,并在工具说明与 Agent 系统提示里要求"汇报用名称、
调工具用 serial"
文档:API.md(items/name/auto_claim + §6.2.1 名称呈现表)、MCP.md(工具返回)
自测(全通过):自动认领端到端(开开关→扫描→自动迁址 + 名称保留 + 分组/任务引用同步 +
待连接池清理 + 开关默认关且可持久化);名称显示浏览器验证(监控页/覆盖设备 chip/AI 目标与
观看下拉/任务编辑器/分组弹窗/发现设置开关);设备指纹与人工认领回归
|
2026-09-11 11:16:24 +08:00 |
|
butubb
|
0a1b4d6122
|
feat: 设备身份改为「名称 + 指纹」——更换 IP 自动认领,分组/任务引用自动同步
背景:设备池原先拿 serial(IP)当身份。设备一换 IP(DHCP 重新分配)旧记录就成了连不上的
僵尸条目(表现为"断联·自动重连中"但设备并没关机),分组与 serial 模式的任务还吊着死地址。
2026-09-11 实际发生:.70 变成 .71、.72 消失,平台两个条目永远连不上。
实现
- **设备名称必填且唯一**:加入设备必须填名称;库层面用部分唯一索引兜底
(ux_device_name / ux_device_fingerprint,WHERE 非空 → 兼容历史空值),管理页可改名
- **设备指纹**(ro.serialno):网络设备添加/确认/扫描/采集型号时自动读取;
身份三层拆分——名称(人可读,稳定)、指纹(机器识别,稳定)、serial(当前地址,可变)
- **自动认领**:添加或确认设备时指纹命中池中已有记录 → 迁移原记录到新地址
(名称/型号/备注/启用状态/添加时间全保留),不新增条目
- **人工认领** `POST /api/devices/pool/relocate`:旧地址已断联、指纹没采过时的兜底——
人工指认"这条就是那台,现在在 X",迁移并同步引用
- **引用同步**:认领/迁址时把 device_group.serials 与 task_job.target.serial 的旧地址
换成新地址。⚠️ 必须同时改**内存**:分组/任务在 TaskManager 里另有内存副本且调度用内存对象,
只改库不重启不生效 → device_pool 迁址后回调 TaskManager.sync_device_serial
(装配层用 set_move_hook 注册;device_pool 不能反向 import task_manager,会循环依赖)
- **前端**:待连接池新增「识别」列(指纹命中时提示"≈ 名称(原 IP)",按钮变「认领为 X」);
设备池新增「名称/指纹」列与「改名/换地址」操作;断联设备表也加「换地址」(用户看到断联就在这里)
- 添加设备接口改用 adb_connect_light(单次短超时),避免不可达 IP 让请求卡 30s+;重名校验提前到 adb 之前
文档:API.md §6 重写(设备身份/认领/新接口)、DATA_MODEL.md(新列 + v5/v6 迁移 + 唯一索引)、
ARCHITECTURE.md §4.0(身份三层与引用同步的内存坑)、DEPLOY.md 排查表加"断联但没关机"条目
自测(全通过):名称必填/唯一/改名/重名拒绝(含库层面约束);指纹采集(真实读到 .71 的
gy7lskwkkvj7c6b6);自动认领(指纹命中→迁址+保留名称+带指纹+未命中不误判);人工认领
(迁址+名称保留+分组与任务引用同步);浏览器验证设备池/断联表/待连接池三个界面
|
2026-09-11 11:03:38 +08:00 |
|
butubb
|
24d57d3b96
|
docs: doc/ 全量重整——按现状重写并建立文档索引;项目统一更名 auto_control
背景:文档长期落后于代码(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 种任务类型)
|
2026-09-10 22:19:18 +08:00 |
|
butubb
|
f4b5316436
|
chore: 去掉 generic_steps 的默认步骤 + 重试失败带上真实原因
- tasks/generic/task.py:DEFAULT_PARAMS 只留 max_duration,**不再内置示例步骤**
(步骤只能由前端编辑器产出;此前默认的"打开抖音→循环看视频"只有后端在用,
编辑器新建任务本来就是空的,等于埋了个和界面不一致的隐性默认值)
- 空步骤不再静默空跑:worker 立即抛错「通用步骤任务没有可执行步骤…」,
设备表「最近错误」能看到(此前会走完 0 步当成功)
- core/task_manager.py:重试耗尽的 last_error 现在带上最后一次的真实失败原因,
不再只有"重试N次失败"(用户看不到为什么失败);max_attempts=1 显示"执行失败"
而非费解的"重试1次失败";长度截断 200 字符
- 文档:TASK_DEV §2.10 说明无默认步骤 + 空步骤会报错;API.md 的 task_types 示例
改 default_params={"max_duration":0},POST /api/jobs 补「steps 要一起传」提示
自测(全通过):default_params 无 steps;无步骤任务真跑一次 → 设备错误信息完整含原因;
有步骤任务(wait 1s)真跑一次 → status=done 无错误;临时任务验完已删,任务集合复原
|
2026-09-10 21:50:18 +08:00 |
|
butubb
|
98cdc39224
|
chore: 删除抖音养号任务类型,平台只保留 generic_steps
tasks/douyin/(task_type=douyin_nurture)整体删除,唯一任务类型是 generic_steps。
所有默认值/文档/接口示例同步改成 generic_steps:
- tasks/:删 douyin 包;__init__ 只注册 generic;base.py/generic 注释改为照 generic 抄
- 默认值:core/models.py(列默认 + 旧 JSON 迁移默认)、core/task_manager.py TaskJob、
web/tasks_api.py 建任务默认、static/admin/tasks.js 新建任务默认
- core/task_manager.py:去掉 douyin 专属的"清理废弃 comment 参数"迁移块,改为**启动时告警**
仍残留已删类型的任务(只告警不改数据);run_job_now 对已删类型直接返回明确错误,
不再"报已触发、线程里静默失败"
- 清理残留:douyin_running 状态位(无任何读取方)、core/__init__、core/actions/*、
core/logger.py 注释里的抖音示例
- 文档:README(特性/目录树/类型表/参数表/示例)、TASK_DEV(目录树/注册说明/模板引用)、
ARCHITECTURE(注册示例/action 注册表示例)、API.md(task_types 与任务 JSON 示例)、
AI_TASK_GEN(P1 去掉 douyin 预设)、DEVELOPMENT
- 注:示例里"抖音"作为**App 名**(MCP 列应用、AI 建任务的需求举例)保留,与任务类型无关
自测(全部通过):类型列表只剩 generic_steps;建任务不传类型默认 generic_steps;传
douyin_nurture 被 400 拒;库里塞残留旧类型任务 → 启动日志告警 + 执行返回明确错误 +
不自动删用户数据;前端新建任务下拉 1 项且默认选中、界面建任务成功;监控页卡片两个按钮 +
覆盖设备正常。临时任务/数据验完已清理,任务集合复原。
|
2026-09-10 21:43:08 +08:00 |
|
butubb
|
86c65236a2
|
fix: 监控页任务概况去掉「编辑/删除」,只留执行/停用 + 显示覆盖设备
监控页的任务卡片原来带「编辑」,但 openTaskModal 依赖 _taskTypes/_groupsList/
_devicesList,这三个列表只在任务 Tab 的 loadTasks() 里加载——从监控页直接点编辑,
下拉框是空的(这就是"编辑有问题")。按需求把编辑/删除从监控页移除(编辑统一去任务 Tab),
每张卡片只留:执行任务 + 停用任务/启用任务。
并给卡片加「覆盖设备」一行:
- 后端 /api/jobs(含 POST/PUT 返回的 job)新增 coverage = {mode, serials, total}:
按 target 定义解析(all=设备池全量 / group=分组∩设备池 / serial=该设备),
不做离线过滤、不写调度日志(该接口每 5s 轮询),与调度用的 resolve_serials 口径差异已写入文档
- 前端用已在手的 /api/status 标注在线状态,渲染成彩色 chip:
在线=蓝、运行中=黄+⏳、离线或不在池=灰划线+✕,完整 serial/型号放 tooltip
- 文档:API.md §5 补 coverage 字段与三种模式口径、ARCHITECTURE §5.1 补卡片说明
自测:coverage 三种模式端到端(含分组过滤池外 serial)全通过;Edge headless 验卡片
(2 个按钮、无编辑/删除、chip 文案/样式/tooltip)全通过;离线分支与任务 Tab 编辑器回归通过
|
2026-09-10 21:15:23 +08:00 |
|
butubb
|
4b5b836d31
|
feat: AI 控制台回答支持 Markdown 渲染 + 推理链可折叠 + token 用量显示
- markdown.js(新增,无 CDN 依赖):轻量 Markdown 渲染(标题/列表含嵌套/表格/
代码块/引用/链接…),先 esc() 转义再套标记,模型输出的 HTML 只当文本显示
- agent.js:回答改走 Markdown;推理链改为 <details> 可折叠(流式时展开、正文开始
自动收起、手动点过后不再自动改);单条消息 token 脚注 + 顶栏「本会话累计」
- monitor.html:消息结构加 .reasoning/.agent-usage、顶栏 token 徽标、md 相关样式,
引入 markdown.js(base.js 之后、agent.js 之前)
- mcp_agent/agent.py:请求带 stream_options.include_usage,按「每次模型调用」累计
usage(末尾 chunk),on_usage 回调吐累计值;网关不认该参数(400/422/点名)时
自动降级重试一次
- web/agent_api.py:SSE 新增 usage 事件、done 带 usage;推理链与用量随会话落库
(_REASONING_KEEP=6000 截断),回灌模型时只取 role/content
- 文档:API.md(usage 事件/done/会话消息字段)、ARCHITECTURE §5.4.1、DEVELOPMENT
前端 JS 清单
自测:假模型端点单测 3/3(正常/降级/多轮累加);Edge headless 全链路 27 项全通过
(真实 Flask+SSE+SQLite,含 XSS 转义、刷新后回看);Markdown 渲染器 18 用例全通过
|
2026-09-10 18:22:20 +08:00 |
|
butubb
|
91b2785c6b
|
feat: 动作库查看/管理(接口 + AI 控制台「🎬 动作库」面板)+ 未沉淀灰卡提示
- 后端:GET /api/agent/actions(列表)、POST /api/agent/actions/delete、
POST /api/agent/actions/save(新增/编辑,steps 走 _sanitize_actions 校验:
type 白名单 + 必填 + **拒绝坐标 click_xy**),均 @admin_required
- 前端:AI 控制台右上角新增「🎬 动作库」按钮与模态框——列出 名称/app/别名/
步骤摘要(含元素定位)/命中次数/更新时间;支持编辑(表单 + steps JSON)、删除、
手动新建;保存失败(如写坐标)即时 toast 原因
- 未沉淀提示:本轮无可沉淀动作时也推送一张 🧠 动作经验 灰卡
「本轮未沉淀动作(步骤以坐标定位为主,缺少可复用的元素定位信息)」
- doc/API.md:登记三个新接口
实测:列表返回自动沉淀的动作;保存合法动作 200;提交 click_xy 步骤被 400 拒绝;
删除生效
|
2026-09-10 13:58:38 +08:00 |
|
butubb
|
104964aa53
|
feat: 动作经验库(agent_action)——成功步骤蒸馏命名动作(带元素定位/禁坐标)+ 执行前召回注入
- 新表 agent_action(name/app/aliases/params/steps/preconditions/hits/时间),
独立于人工维护的 custom_action(2B 决策):AI 自学动作不污染手建动作
- 沉淀:任务成功后从**成功**工具轨迹(_ACTION_TOOLS: open_app/tap_text/tap_element/
type_text/clipboard/swipe/press_key/wake/sleep)用模型蒸馏为命名动作;steps 用
编辑器 schema,**必须元素定位**(xpath/text/resourceId/description…),
**显式剔除 click_xy 等坐标类**;on_tool 记录带 result 的结构化轨迹以判成败
- 兼容模型形状漂移:顶层 {action,params} 自动归一为 {name,steps};宽容 JSON 解析
(围栏/尾逗号/中文引号/坏对象逐条抢救),实测模型常返回带语法错误的 JSON
- 召回:执行前按动作名/别名命中(或相似度≥0.34)取 top3,注入 system prompt
「可复用动作」段(含元素定位),模型可跳过重新探索;hits 回写
- 文档同步:ARCHITECTURE §3.6(agent_action 表)、API.md(🧠 动作经验 伪卡片 + 动作库
说明)、AI_TASK_GEN P1(沉淀进展)
实测:跑「打开抖音,点搜索」→ 沉淀「打开抖音」;下一轮同指令命中并注入;日志
「命中可复用动作 1 个」「动作提炼: 轨迹 5 步, 成功可沉淀 1 步」「动作经验已保存 1 条」
|
2026-09-10 13:53:04 +08:00 |
|
butubb
|
4e71f79a10
|
fix: 经验库命中数算错(单条恒显示 0)+ 蒸馏前缀误杀 + 命中卡片带摘要
- _find_experiences 改为返回 (注入文本, 命中配方列表):此前卡片用
exp_ctx.count('\n- ') 计数,单条恒为 0、两条为 1(永远少 1),用户看到
「命中 0 条」误判为没参考;现用 len(列表) 得真实条数并附配方摘要
- 新增 _clean_recipe():清洗模型可能加的「操作配方:」前缀,替换旧判定
"配方" not in recipe[:50]——该判定与蒸馏提示词(要求以「操作配方」作答)
自相矛盾,模型照做即被整条丢弃(静默),是经验存不下来的主因
- doc/API.md:SSE step 说明补 🧠 伪卡片语义(N 为实际条数 + 摘要)
实测:同一指令由「命中 0 条」变为「命中 1 条同类历史经验,已注入参考:<摘要>」
|
2026-09-10 13:41:10 +08:00 |
|
butubb
|
357fe98e22
|
fix: AI 控制台 MCP 不可达给出明确文案——不再显示 SDK 含糊报错
MCP 客户端(streamable_http)在工具服务不可达/返回非 MCP 响应时只抛
'Server returned an error response',用户无法判断原因。改为:
- 后端 web/agent_api.py:_execute 包裹 _load_tools/run_stream,识别连接类错误
(Server returned an error response/ConnectError/refused 等)后抛明确文案:
'MCP server(8033) 不可达:无法加载设备工具(<url>)。请确认 MCP server 已启动…'
- 前端 static/admin/agent.js 加 _friendlyAgentError() 兜底映射并去掉
'RuntimeError:' 之类前缀,三处错误展示统一使用
- 文档同步:MCP.md(依赖提示+本机启动命令)、API.md(SSE error 文案说明)、
DEPLOY.md(故障排查新增一行)
实测:停掉 MCP 复现 → 前端显示明确文案;启动 MCP 后 AI 控制台正常完成任务
|
2026-09-10 10:28:57 +08:00 |
|
butubb
|
fd829a6063
|
docs: doc/ 全量同步 dev 现状——API 目录补全(AI 控制台/系统备份/自动发现等)、去 STF 过时口径、补 generic_steps 与配置键速查;确立「功能/配置改动须同步文档」红线
- doc/API.md:补方法/路径标题,权限分层修正,新增 AI 控制台(/api/agent/*)、系统备份(/api/system/backup/*)、设备自动发现(/api/devices/discovery/*)、tap_text/summary/health/devices-apps 等整节端点,去 STF 残留
- doc/TASK_DEV.md:STF 时代描述清理;新增 §2.10 generic_steps(18 节点与必填/嵌套/静默跳过语义)、§2.11 自定义动作与单步测试、/api/jobs 盲存校验语义、resolve_serials/抢占语义、模板构造函数签名修正
- doc/DEPLOY.md:数据备份改为推荐「系统→数据备份」功能并说明重启生效目录,端口表 STF7100→MCP8033,补 start.sh 生产链路与 MCP_PLATFORM_PASS 同步,故障排查去 STF
- doc/MCP.md:加「现状边界」(平台级任务 CRUD 未 MCP 化,规划见 AI_TASK_GEN §9),busy/平台会话说明,MCP_ALLOWED_SERIALS 语义纠正
- doc/MCP_DESIGN.md:加实现现状对照、错误码、独立容器改演进备选、里程碑状态、API 映射表按实现重写
- doc/ARCHITECTURE.md:Tab/子分栏/线程模型/数据表/蓝图表去 STF,补 device_discovery/agent/system_backup/经验巡检等
- doc/DEVELOPMENT.md:新增 §5.6「改动必须同步文档」红线、§2.3 配置键速查、蓝图化新增 API 流程、文档索引补登记
- doc/STF_REMOVAL.md:加历史记录状态横幅
- doc/AI_TASK_GEN.md:新增 AI 建任务设计稿(含 §9 需转 MCP 工具分层)
|
2026-09-09 16:05:56 +08:00 |
|
butubb
|
c78f17d72f
|
feat: 监控大屏(/wall 全屏深色控制室风格:设备卡片网格+缩略图轮询+统计+时钟,缩略图 360px/q55 每 2.5s 一帧 20 台仅 ~0.2 核 CPU)+ /api/screen/thumb 接口 + 导航栏大屏入口
|
2026-08-19 14:13:15 +08:00 |
|
butubb
|
5543bad0e6
|
docs: 全面更新——README/API/DEVELOPMENT 摘除 STF 章节(设备池/型号/看屏/新端点文档,技术红线改为共享 transport 表述)
|
2026-08-19 14:07:53 +08:00 |
|
butubb
|
3bd56b4f59
|
feat: 工具Tab新增应用版本管理(按包名并发查询所有设备安装版本)+ 文档同步更新(README/API/ARCHITECTURE/DEPLOY:工具Tab各工具、条件判断if_el+OCR、STF设备管理、.env密钥配置)
|
2026-08-11 10:57:14 +08:00 |
|
butubb
|
de66c6194b
|
feat: 维护页 Tailscale 管理(设备列表/改名/授权/密钥不过期/设置IP/auth key,独立模块 core/tailscale_client.py)+ 密钥迁移 .env(STF_TOKEN/WEB_SECRET_KEY/TAILSCALE_API_KEY 不再入库)+ 修复设备更新端点(/device/{id} 405,改用 /name /authorized /key 专属端点)+ auth key description 仅 ASCII
|
2026-08-11 09:06:59 +08:00 |
|
butubb
|
a0d1a533c6
|
docs: 文档同步(README/API/架构/部署)
|
2026-08-11 08:27:33 +08:00 |
|
butubb
|
468e86f0a9
|
feat: 新增通用步骤任务+元素抓取,完善全部项目文档
- 新增 generic_steps 通用步骤任务(可视化步骤编辑器编排流程,支持 open_app/click/swipe/input_text/wait/loop/group)
- 新增 core/uiauto_helper.py 封装 uiautodev 元素抓取客户端
- web_server 新增元素抓取/截图/设备列表等 API
- monitor.html 新增步骤编辑器、元素抓取模态框、独立关闭逻辑
- 新增 README.md 项目总览(快速上手/架构/配置/FAQ)
- 新增 doc/ARCHITECTURE.md 架构详解、doc/DEPLOY.md 部署指南、doc/API.md 接口文档
- 修复 doc/TASK_DEV.md:移除已删除的 comment 引用,补充 generic 包,更新注册示例
- .gitignore 忽略 .claude/ 工具产物
|
2026-08-08 10:40:06 +08:00 |
|